static void update_progress_for_device (StoragedDaemon *daemon, const gchar *operation, const gchar *dev, double progress) { GDBusObjectManager *object_manager; GList *objects, *l; object_manager = G_DBUS_OBJECT_MANAGER (storaged_daemon_get_object_manager (daemon)); objects = g_dbus_object_manager_get_objects (object_manager); for (l = objects; l; l = l->next) { StoragedObject *object = STORAGED_OBJECT (l->data); StoragedJob *job; const gchar *const *job_objects; int i; job = storaged_object_peek_job (object); if (job == NULL) continue; if (g_strcmp0 (storaged_job_get_operation (job), operation) != 0) continue; job_objects = storaged_job_get_objects (job); for (i = 0; job_objects[i]; i++) { StoragedBlock *block = STORAGED_BLOCK (g_dbus_object_manager_get_interface (object_manager, job_objects[i], "org.storaged.Storaged.Block")); if (block) { const gchar *const *symlinks; int j; if (g_strcmp0 (storaged_block_get_device (block), dev) == 0) goto found; symlinks = storaged_block_get_symlinks (block); for (j = 0; symlinks[j]; j++) if (g_strcmp0 (symlinks[j], dev) == 0) goto found; continue; found: storaged_job_set_progress (job, progress); storaged_job_set_progress_valid (job, TRUE); } } } g_list_free_full (objects, g_object_unref); }
static gboolean have_partition_in_range (StoragedPartitionTable *table, StoragedObject *object, guint64 start, guint64 end, gboolean ignore_container) { gboolean ret = FALSE; StoragedDaemon *daemon = NULL; GDBusObjectManager *object_manager = NULL; const gchar *table_object_path; GList *objects = NULL, *l; daemon = storaged_linux_block_object_get_daemon (STORAGED_LINUX_BLOCK_OBJECT (object)); object_manager = G_DBUS_OBJECT_MANAGER (storaged_daemon_get_object_manager (daemon)); table_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); objects = g_dbus_object_manager_get_objects (object_manager); for (l = objects; l != NULL; l = l->next) { StoragedObject *i_object = STORAGED_OBJECT (l->data); StoragedPartition *i_partition = NULL; i_partition = storaged_object_get_partition (i_object); if (i_partition == NULL) goto cont; if (g_strcmp0 (storaged_partition_get_table (i_partition), table_object_path) != 0) goto cont; if (ignore_container && storaged_partition_get_is_container (i_partition)) goto cont; if (!ranges_overlap (start, end - start, storaged_partition_get_offset (i_partition), storaged_partition_get_size (i_partition))) goto cont; ret = TRUE; g_clear_object (&i_partition); goto out; cont: g_clear_object (&i_partition); } out: g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); return ret; }
void storaged_linux_volume_group_object_destroy (StoragedLinuxVolumeGroupObject *object) { GHashTableIter volume_iter; gpointer key, value; g_hash_table_iter_init (&volume_iter, object->logical_volumes); while (g_hash_table_iter_next (&volume_iter, &key, &value)) { StoragedLinuxLogicalVolumeObject *volume = value; g_dbus_object_manager_server_unexport (storaged_daemon_get_object_manager (object->daemon), g_dbus_object_get_object_path (G_DBUS_OBJECT (volume))); } }
/** * storaged_linux_drive_object_get_block: * @object: A #StoragedLinuxDriveObject. * @get_hw: If the drive is multipath, set to %TRUE to get a path device instead of the multipath device. * * Gets a #StoragedLinuxBlockObject representing a block device associated with @object. * * Returns: A #StoragedLinuxBlockObject or %NULL. The returned object * must be freed with g_object_unref(). */ StoragedLinuxBlockObject * storaged_linux_drive_object_get_block (StoragedLinuxDriveObject *object, gboolean get_hw) { GDBusObjectManagerServer *object_manager; StoragedLinuxBlockObject *ret; GList *objects; GList *l; /* TODO: actually look at @get_hw */ ret = NULL; object_manager = storaged_daemon_get_object_manager (object->daemon); objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); for (l = objects; l != NULL; l = l->next) { GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data); StoragedBlock *block; StoragedLinuxDevice *device; gboolean is_disk; if (!STORAGED_IS_LINUX_BLOCK_OBJECT (iter_object)) continue; device = storaged_linux_block_object_get_device (STORAGED_LINUX_BLOCK_OBJECT (iter_object)); is_disk = (g_strcmp0 (g_udev_device_get_devtype (device->udev_device), "disk") == 0); g_object_unref (device); if (!is_disk) continue; block = storaged_object_peek_block (STORAGED_OBJECT (iter_object)); if (g_strcmp0 (storaged_block_get_drive (block), g_dbus_object_get_object_path (G_DBUS_OBJECT (object))) == 0) { ret = g_object_ref (iter_object); goto out; } } out: g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); return ret; }
/** * storaged_linux_drive_object_get_siblings: * @object: A #StoragedLinuxDriveObject. * * Gets the siblings for @object, if any. * * Returns: (transfer full) (element-type StoragedLinuxDriveObject): A list of #StoragedLinuxDriveObject * instances. The returned list should be freed with g_list_free() after each element has been * freed with g_object_unref(). */ GList * storaged_linux_drive_object_get_siblings (StoragedLinuxDriveObject *object) { GDBusObjectManagerServer *object_manager; GList *ret = NULL; GList *objects = NULL; GList *l; gchar *sibling_id = NULL; if (object->iface_drive == NULL) goto out; sibling_id = storaged_drive_dup_sibling_id (object->iface_drive); if (sibling_id == NULL || strlen (sibling_id) == 0) goto out; object_manager = storaged_daemon_get_object_manager (object->daemon); objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); for (l = objects; l != NULL; l = l->next) { GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data); StoragedLinuxDriveObject *iter_linux_drive_object; if (!STORAGED_IS_LINUX_DRIVE_OBJECT (iter_object)) continue; iter_linux_drive_object = STORAGED_LINUX_DRIVE_OBJECT (iter_object); if (iter_linux_drive_object->iface_drive != NULL && g_strcmp0 (storaged_drive_get_sibling_id (iter_linux_drive_object->iface_drive), sibling_id) == 0) { ret = g_list_prepend (ret, g_object_ref (iter_object)); } } out: ret = g_list_reverse (ret); g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); g_free (sibling_id); return ret; }
/** * storaged_linux_drive_object_is_not_in_use: * @object: A #StoragedLinuxDriveObject. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: A #GError or %NULL. * * Checks if the drive represented by @object is in use and sets * @error if so. * * Returns: %TRUE if @object is not is use, %FALSE if @error is set. */ gboolean storaged_linux_drive_object_is_not_in_use (StoragedLinuxDriveObject *object, GCancellable *cancellable, GError **error) { GDBusObjectManagerServer *object_manager; const gchar *drive_object_path; gboolean ret = TRUE; GList *objects = NULL; GList *l; g_return_val_if_fail (STORAGED_IS_LINUX_DRIVE_OBJECT (object), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); drive_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); object_manager = storaged_daemon_get_object_manager (object->daemon); objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); /* Visit all block devices related to the drive... */ for (l = objects; l != NULL; l = l->next) { GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data); StoragedBlock *block; StoragedFilesystem *filesystem; if (!STORAGED_IS_LINUX_BLOCK_OBJECT (iter_object)) continue; block = storaged_object_peek_block (STORAGED_OBJECT (iter_object)); filesystem = storaged_object_peek_filesystem (STORAGED_OBJECT (iter_object)); if (g_strcmp0 (storaged_block_get_drive (block), drive_object_path) != 0) continue; /* bail if block device is mounted */ if (filesystem != NULL) { if (g_strv_length ((gchar **) storaged_filesystem_get_mount_points (filesystem)) > 0) { g_set_error (error, STORAGED_ERROR, STORAGED_ERROR_DEVICE_BUSY, "Device %s is mounted", storaged_block_get_preferred_device (block)); ret = FALSE; goto out; } } /* bail if block device is unlocked (LUKS) */ if (is_block_unlocked (objects, g_dbus_object_get_object_path (G_DBUS_OBJECT (iter_object)))) { g_set_error (error, STORAGED_ERROR, STORAGED_ERROR_DEVICE_BUSY, "Encrypted device %s is unlocked", storaged_block_get_preferred_device (block)); ret = FALSE; goto out; } } out: g_list_free_full (objects, g_object_unref); return ret; }
static void update_with_variant (GPid pid, GVariant *info, GError *error, gpointer user_data) { StoragedLinuxVolumeGroupObject *object = user_data; StoragedDaemon *daemon; GDBusObjectManagerServer *manager; GVariantIter *iter; GHashTableIter volume_iter; gpointer key, value; GHashTable *new_lvs; GHashTable *new_pvs; GList *objects, *l; gboolean needs_polling = FALSE; daemon = storaged_linux_volume_group_object_get_daemon (object); manager = storaged_daemon_get_object_manager (daemon); if (error) { storaged_warning ("Failed to update LVM volume group %s: %s", storaged_linux_volume_group_object_get_name (object), error->message); g_object_unref (object); return; } storaged_linux_volume_group_update (STORAGED_LINUX_VOLUME_GROUP (object->iface_volume_group), info, &needs_polling); if (!g_dbus_object_manager_server_is_exported (manager, G_DBUS_OBJECT_SKELETON (object))) g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (object)); new_lvs = g_hash_table_new (g_str_hash, g_str_equal); if (g_variant_lookup (info, "lvs", "aa{sv}", &iter)) { GVariant *lv_info = NULL; while (g_variant_iter_loop (iter, "@a{sv}", &lv_info)) { const gchar *name; StoragedLinuxLogicalVolumeObject *volume; g_variant_lookup (lv_info, "name", "&s", &name); update_operations (daemon, name, lv_info, &needs_polling); if (lv_is_pvmove_volume (name)) needs_polling = TRUE; if (storaged_daemon_util_lvm2_name_is_reserved (name)) continue; volume = g_hash_table_lookup (object->logical_volumes, name); if (volume == NULL) { volume = storaged_linux_logical_volume_object_new (daemon, object, name); storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling); storaged_linux_logical_volume_object_update_etctabs (volume); g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (volume)); g_hash_table_insert (object->logical_volumes, g_strdup (name), g_object_ref (volume)); } else storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling); g_hash_table_insert (new_lvs, (gchar *)name, volume); } g_variant_iter_free (iter); } g_hash_table_iter_init (&volume_iter, object->logical_volumes); while (g_hash_table_iter_next (&volume_iter, &key, &value)) { const gchar *name = key; StoragedLinuxLogicalVolumeObject *volume = value; if (!g_hash_table_contains (new_lvs, name)) { g_dbus_object_manager_server_unexport (manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (volume))); g_hash_table_iter_remove (&volume_iter); g_object_unref (G_OBJECT (volume)); } } storaged_volume_group_set_needs_polling (STORAGED_VOLUME_GROUP (object->iface_volume_group), needs_polling); /* Update block objects. */ new_pvs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_variant_unref); if (g_variant_lookup (info, "pvs", "aa{sv}", &iter)) { const gchar *name; GVariant *pv_info; while (g_variant_iter_next (iter, "@a{sv}", &pv_info)) { if (g_variant_lookup (pv_info, "device", "&s", &name)) g_hash_table_insert (new_pvs, (gchar *)name, pv_info); else g_variant_unref (pv_info); } } objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager)); for (l = objects; l != NULL; l = l->next) { if (STORAGED_IS_LINUX_BLOCK_OBJECT (l->data)) update_block (STORAGED_LINUX_BLOCK_OBJECT (l->data), object, new_lvs, new_pvs); } g_list_free_full (objects, g_object_unref); g_hash_table_destroy (new_lvs); g_hash_table_destroy (new_pvs); g_object_unref (object); }