static gboolean handle_add_device (LvmVolumeGroup *group, GDBusMethodInvocation *invocation, const gchar *new_member_device_objpath, GVariant *options) { StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group); StorageJob *job; StorageDaemon *daemon; StorageManager *manager; GError *error = NULL; StorageBlock *new_member_device = NULL; daemon = storage_daemon_get (); manager = storage_daemon_get_manager (daemon); new_member_device = storage_manager_find_block (manager, new_member_device_objpath); if (new_member_device == NULL) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "The given object is not a valid block"); } else if (!storage_block_is_unused (new_member_device, &error)) { g_dbus_method_invocation_take_error (invocation, error); } else if (!storage_util_wipe_block (storage_block_get_device (new_member_device), &error)) { g_dbus_method_invocation_take_error (invocation, error); } else { job = storage_daemon_launch_spawned_job (daemon, self, "lvm-vg-add-device", storage_invocation_get_caller_uid (invocation), NULL, /* GCancellable */ 0, /* uid_t run_as_uid */ 0, /* uid_t run_as_euid */ NULL, /* input_string */ "vgextend", storage_volume_group_get_name (self), storage_block_get_device (new_member_device), NULL); g_signal_connect_data (job, "completed", G_CALLBACK (on_adddev_complete), g_object_ref (invocation), (GClosureNotify)g_object_unref, 0); } g_clear_object (&new_member_device); return TRUE; /* returning TRUE means that we handled the method invocation */ }
void storage_volume_group_update_block (StorageVolumeGroup *self, StorageBlock *block) { GUdevDevice *device; StorageLogicalVolume *volume; const gchar *block_vg_name; const gchar *block_lv_name; GVariant *pv_info; device = storage_block_get_udev (block); if (device) { block_vg_name = g_udev_device_get_property (device, "DM_VG_NAME"); block_lv_name = g_udev_device_get_property (device, "DM_LV_NAME"); if (g_strcmp0 (block_vg_name, storage_volume_group_get_name (self)) == 0) { volume = g_hash_table_lookup (self->logical_volumes, block_lv_name); storage_block_update_lv (block, volume); } g_object_unref (device); } pv_info = g_hash_table_lookup (self->physical_volumes, storage_block_get_device (block)); if (!pv_info) { const gchar *const *symlinks; int i; symlinks = storage_block_get_symlinks (block); for (i = 0; symlinks[i]; i++) { pv_info = g_hash_table_lookup (self->physical_volumes, symlinks[i]); if (pv_info) break; } } if (pv_info) { storage_block_update_pv (block, self, pv_info); } else { LvmPhysicalVolumeBlock *pv = storage_block_get_physical_volume_block (block); if (pv && g_strcmp0 (lvm_physical_volume_block_get_volume_group (pv), storage_volume_group_get_object_path (self)) == 0) storage_block_update_pv (block, NULL, NULL); } }
static gboolean handle_delete (LvmVolumeGroup *group, GDBusMethodInvocation *invocation, gboolean arg_wipe, GVariant *arg_options) { StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group); VolumeGroupDeleteJobData *data; StorageDaemon *daemon; StorageJob *job; GList *l; daemon = storage_daemon_get (); data = g_new0 (VolumeGroupDeleteJobData, 1); data->vgname = g_strdup (storage_volume_group_get_name (self)); /* Find physical volumes to wipe. */ if (arg_wipe) { GPtrArray *devices = g_ptr_array_new (); GList *blocks = storage_manager_get_blocks (storage_daemon_get_manager (daemon)); for (l = blocks; l; l = l->next) { LvmPhysicalVolumeBlock *physical_volume; physical_volume = storage_block_get_physical_volume_block (l->data); if (physical_volume && g_strcmp0 (lvm_physical_volume_block_get_volume_group (physical_volume), storage_volume_group_get_object_path (self)) == 0) g_ptr_array_add (devices, g_strdup (storage_block_get_device (l->data))); } g_list_free_full (blocks, g_object_unref); g_ptr_array_add (devices, NULL); data->devices = (gchar **)g_ptr_array_free (devices, FALSE); } job = storage_daemon_launch_threaded_job (daemon, self, "lvm-vg-delete", storage_invocation_get_caller_uid (invocation), volume_group_delete_job_thread, data, volume_group_delete_job_free, NULL); g_signal_connect_data (job, "completed", G_CALLBACK (on_delete_complete), g_object_ref (invocation), (GClosureNotify)g_object_unref, 0); return TRUE; }
static gboolean handle_remove_device (LvmVolumeGroup *group, GDBusMethodInvocation *invocation, const gchar *member_device_objpath, gboolean wipe, GVariant *options) { StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group); VolumeGroupRemdevJobData *data; StorageDaemon *daemon; StorageManager *manager; StorageBlock *member_device; StorageJob *job; daemon = storage_daemon_get (); manager = storage_daemon_get_manager (daemon); member_device = storage_manager_find_block (manager, member_device_objpath); if (member_device == NULL) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "The given object is not a valid block"); return TRUE; } data = g_new0 (VolumeGroupRemdevJobData, 1); data->wipe = wipe; data->vgname = g_strdup (storage_volume_group_get_name (self)); data->pvname = g_strdup (storage_block_get_device (member_device)); job = storage_daemon_launch_threaded_job (daemon, self, "lvm-vg-rem-device", storage_invocation_get_caller_uid (invocation), volume_group_remdev_job_thread, data, volume_group_remdev_job_free, NULL); g_signal_connect_data (job, "completed", G_CALLBACK (on_remdev_complete), g_object_ref (invocation), (GClosureNotify)g_object_unref, 0); g_object_unref (member_device); return TRUE; /* returning TRUE means that we handled the method invocation */ }
static gboolean handle_empty_device (LvmVolumeGroup *group, GDBusMethodInvocation *invocation, const gchar *member_device_objpath, GVariant *options) { StorageJob *job; StorageDaemon *daemon; StorageManager *manager; const gchar *member_device_file = NULL; StorageBlock *member_device = NULL; daemon = storage_daemon_get (); manager = storage_daemon_get_manager (daemon); member_device = storage_manager_find_block (manager, member_device_objpath); if (member_device == NULL) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "The given object is not a valid block"); return TRUE; } member_device_file = storage_block_get_device (member_device); job = storage_daemon_launch_spawned_job (daemon, member_device, "lvm-vg-empty-device", storage_invocation_get_caller_uid (invocation), NULL, /* GCancellable */ 0, /* uid_t run_as_uid */ 0, /* uid_t run_as_euid */ NULL, /* input_string */ "pvmove", member_device_file, NULL); g_signal_connect_data (job, "completed", G_CALLBACK (on_empty_complete), g_object_ref (invocation), (GClosureNotify)g_object_unref, 0); g_object_unref (member_device); return TRUE; /* returning TRUE means that we handled the method invocation */ }
gboolean storage_block_is_unused (StorageBlock *self, GError **error) { const gchar *device_file; int fd; g_return_val_if_fail (STORAGE_IS_BLOCK (self), FALSE); device_file = storage_block_get_device (self); fd = open (device_file, O_RDONLY | O_EXCL); if (fd < 0) { g_set_error (error, UDISKS_ERROR, UDISKS_ERROR_FAILED, "Error opening device %s: %m", device_file); return FALSE; } close (fd); return TRUE; }
static void update_progress_for_device (const gchar *operation, const gchar *dev, double progress) { StorageDaemon *daemon; StorageManager *manager; GList *jobs, *l; daemon = storage_daemon_get (); manager = storage_daemon_get_manager (daemon); jobs = storage_daemon_get_jobs (daemon); for (l = jobs; l; l = g_list_next (l)) { UDisksJob *job = l->data; const gchar *const *job_objects; int i; if (g_strcmp0 (udisks_job_get_operation (job), operation) != 0) continue; job_objects = udisks_job_get_objects (job); for (i = 0; job_objects[i]; i++) { StorageBlock *block; gboolean found = FALSE; block = storage_manager_find_block (manager, job_objects[i]); if (block) { if (g_strcmp0 (storage_block_get_device (block), dev) == 0) { found = TRUE; } else { const gchar **symlinks; int j; symlinks = storage_block_get_symlinks (block); for (j = 0; symlinks[j]; j++) { if (g_strcmp0 (symlinks[j], dev) == 0) { found = TRUE; break; } } } } if (found) { udisks_job_set_progress (job, progress); udisks_job_set_progress_valid (job, TRUE); } } } g_list_free_full (jobs, g_object_unref); }