static void update_block (StoragedLinuxBlockObject *block_object, StoragedLinuxVolumeGroupObject *group_object, GHashTable *new_lvs, GHashTable *new_pvs) { StoragedBlock *block; GVariant *pv_info; block = storaged_object_peek_block (STORAGED_OBJECT (block_object)); if (block == NULL) return; // XXX - move this elsewhere? { StoragedLinuxDevice *device; StoragedLinuxLogicalVolumeObject *lv_object; const gchar *block_vg_name; const gchar *block_lv_name; device = storaged_linux_block_object_get_device (block_object); if (device) { block_vg_name = g_udev_device_get_property (device->udev_device, "DM_VG_NAME"); block_lv_name = g_udev_device_get_property (device->udev_device, "DM_LV_NAME"); if (g_strcmp0 (block_vg_name, storaged_linux_volume_group_object_get_name (group_object)) == 0 && (lv_object = g_hash_table_lookup (new_lvs, block_lv_name))) { block_object_update_lvm_iface (block_object, g_dbus_object_get_object_path (G_DBUS_OBJECT (lv_object))); } } } pv_info = g_hash_table_lookup (new_pvs, storaged_block_get_device (block)); if (!pv_info) { const gchar *const *symlinks; int i; symlinks = storaged_block_get_symlinks (block); for (i = 0; symlinks[i]; i++) { pv_info = g_hash_table_lookup (new_pvs, symlinks[i]); if (pv_info) break; } } if (pv_info) { storaged_linux_block_object_update_lvm_pv (block_object, group_object, pv_info); } else { StoragedPhysicalVolume *pv = storaged_object_peek_physical_volume (STORAGED_OBJECT (block_object)); if (pv && g_strcmp0 (storaged_physical_volume_get_volume_group (pv), g_dbus_object_get_object_path (G_DBUS_OBJECT (group_object))) == 0) storaged_linux_block_object_update_lvm_pv (block_object, NULL, NULL); } }
static StoragedObject * lookup_object_for_block (StoragedClient *client, dev_t block_device) { StoragedObject *ret; GList *objects; GList *l; ret = NULL; objects = g_dbus_object_manager_get_objects (storaged_client_get_object_manager (client)); for (l = objects; l != NULL; l = l->next) { StoragedObject *object = STORAGED_OBJECT (l->data); StoragedBlock *block; block = storaged_object_peek_block (object); if (block != NULL) { if (block_device == storaged_block_get_device_number (block)) { ret = g_object_ref (object); goto out; } } } out: g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); return ret; }
/** * 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; }
static gboolean is_block_unlocked (GList *objects, const gchar *crypto_object_path) { gboolean ret = FALSE; GList *l; for (l = objects; l != NULL; l = l->next) { StoragedObject *object = STORAGED_OBJECT (l->data); StoragedBlock *block; block = storaged_object_peek_block (object); if (block != NULL) { if (g_strcmp0 (storaged_block_get_crypto_backing_device (block), crypto_object_path) == 0) { ret = TRUE; goto out; } } } out: return ret; }
static gboolean handle_create_partition_and_format (StoragedPartitionTable *table, GDBusMethodInvocation *invocation, guint64 offset, guint64 size, const gchar *type, const gchar *name, GVariant *options, const gchar *format_type, GVariant *format_options) { StoragedObject *partition_object = storaged_linux_partition_table_handle_create_partition (table, invocation, offset, size, type, name, options); if (partition_object) { struct FormatCompleteData data; data.table = table; data.invocation = invocation; data.partition_object = partition_object; storaged_linux_block_handle_format (storaged_object_peek_block (partition_object), invocation, format_type, format_options, handle_format_complete, &data); g_object_unref (partition_object); } return TRUE; /* returning TRUE means that we handled the method invocation */ }
/** * 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 StoragedObject * wait_for_loop_object (StoragedDaemon *daemon, gpointer user_data) { WaitForLoopData *data = user_data; StoragedObject *ret = NULL; StoragedObject *object = NULL; StoragedBlock *block; StoragedLoop *loop; StoragedLinuxDevice *device = NULL; GDir *dir; /* First see if we have the right loop object */ object = storaged_daemon_find_block_by_device_file (daemon, data->loop_device); if (object == NULL) goto out; block = storaged_object_peek_block (object); loop = storaged_object_peek_loop (object); if (block == NULL || loop == NULL) goto out; if (g_strcmp0 (storaged_loop_get_backing_file (loop), data->path) != 0) goto out; /* We also need to wait for all partitions to be in place in case * the loop device is partitioned... we can do it like this because * we are guaranteed that partitions are in sysfs when receiving the * uevent for the main block device... */ device = storaged_linux_block_object_get_device (STORAGED_LINUX_BLOCK_OBJECT (object)); if (device == NULL) goto out; dir = g_dir_open (g_udev_device_get_sysfs_path (device->udev_device), 0 /* flags */, NULL /* GError */); if (dir != NULL) { const gchar *name; const gchar *device_name; device_name = g_udev_device_get_name (device->udev_device); while ((name = g_dir_read_name (dir)) != NULL) { if (g_str_has_prefix (name, device_name)) { gchar *sysfs_path; StoragedObject *partition_object; sysfs_path = g_strconcat (g_udev_device_get_sysfs_path (device->udev_device), "/", name, NULL); partition_object = storaged_daemon_find_block_by_sysfs_path (daemon, sysfs_path); if (partition_object == NULL) { /* nope, not there, bail */ g_free (sysfs_path); g_dir_close (dir); goto out; } g_object_unref (partition_object); g_free (sysfs_path); } } g_dir_close (dir); } /* all, good return the loop object */ ret = g_object_ref (object); out: g_clear_object (&object); g_clear_object (&device); return ret; }