/** * udisks_daemon_util_on_user_seat: * @daemon: A #UDisksDaemon. * @object: The #GDBusObject that the call is on or %NULL. * @user: The user to check for. * * Checks whether the device represented by @object (if any) is plugged into * a seat where the caller represented by @user is logged in and active. * * This works if @object is a drive or a block object. * * Returns: %TRUE if @object is on the same seat as one of @user's * active sessions, %FALSE otherwise. */ gboolean udisks_daemon_util_on_user_seat (UDisksDaemon *daemon, UDisksObject *object, uid_t user) { #if !defined(HAVE_LIBSYSTEMD_LOGIN) /* if we don't have systemd, assume it's always the same seat */ return TRUE; #else gboolean ret = FALSE; char *session = NULL; char *seat = NULL; const gchar *drive_seat; UDisksObject *drive_object = NULL; UDisksDrive *drive = NULL; /* if we don't have logind, assume it's always the same seat */ if (!LOGIND_AVAILABLE()) return TRUE; if (UDISKS_IS_LINUX_BLOCK_OBJECT (object)) { UDisksLinuxBlockObject *linux_block_object; UDisksBlock *block; linux_block_object = UDISKS_LINUX_BLOCK_OBJECT (object); block = udisks_object_get_block (UDISKS_OBJECT (linux_block_object)); if (block != NULL) { drive_object = udisks_daemon_find_object (daemon, udisks_block_get_drive (block)); g_object_unref (block); } } else if (UDISKS_IS_LINUX_DRIVE_OBJECT (object)) { drive_object = g_object_ref (object); } if (drive_object == NULL) goto out; drive = udisks_object_get_drive (UDISKS_OBJECT (drive_object)); if (drive == NULL) goto out; drive_seat = udisks_drive_get_seat (drive); if (drive_seat != NULL && sd_uid_is_on_seat (user, TRUE, drive_seat) > 0) { ret = TRUE; goto out; } out: free (seat); free (session); g_clear_object (&drive_object); g_clear_object (&drive); return ret; #endif /* HAVE_LIBSYSTEMD_LOGIN */ }
static UDisksBlock * peek_block_for_logical_volume (UDisksLogicalVolume *volume, UDisksDaemon *daemon) { UDisksBlock *ret = NULL; GDBusObject *object; GList *l, *objects = NULL; UDisksBlockLVM2 *block_lvm2; object = g_dbus_interface_get_object (G_DBUS_INTERFACE (volume)); if (object == NULL) goto out; objects = udisks_daemon_get_objects (daemon); for (l = objects; l != NULL; l = l->next) { block_lvm2 = udisks_object_peek_block_lvm2 (UDISKS_OBJECT(l->data)); if (block_lvm2 && g_strcmp0 (udisks_block_lvm2_get_logical_volume (block_lvm2), g_dbus_object_get_object_path (object)) == 0) { ret = udisks_object_peek_block (UDISKS_OBJECT(l->data)); goto out; } } out: g_list_free_full (objects, g_object_unref); return ret; }
static gboolean handle_delete (UDisksLogicalVolume *_volume, GDBusMethodInvocation *invocation, GVariant *options) { GError *error = NULL; UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume); UDisksLinuxLogicalVolumeObject *object = NULL; UDisksDaemon *daemon = NULL; uid_t caller_uid; gboolean teardown_flag = FALSE; UDisksLinuxVolumeGroupObject *group_object; LVJobData data; g_variant_lookup (options, "tear-down", "b", &teardown_flag); if (!common_setup (volume, invocation, options, N_("Authentication is required to delete a logical volume"), &object, &daemon, &caller_uid, NULL)) goto out; if (teardown_flag && !teardown_logical_volume (_volume, daemon, invocation, options, &error)) { g_dbus_method_invocation_take_error (invocation, error); goto out; } group_object = udisks_linux_logical_volume_object_get_volume_group (object); data.vg_name = udisks_linux_volume_group_object_get_name (group_object); data.lv_name = udisks_linux_logical_volume_object_get_name (object); if (!udisks_daemon_launch_threaded_job_sync (daemon, UDISKS_OBJECT (object), "lvm-lvol-delete", caller_uid, lvremove_job_func, &data, NULL, /* user_data_free_func */ NULL, /* GCancellable */ &error)) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "Error deleting logical volume: %s", error->message); goto out; } udisks_logical_volume_complete_delete (_volume, invocation); out: g_clear_object (&object); return TRUE; }
UDisksBlock * udisks_client_get_block_for_dev (UDisksClient *client, dev_t block_device_number) { UDisksBlock *ret = NULL; GList *l, *object_proxies = NULL; g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL); object_proxies = g_dbus_object_manager_get_objects (client->object_manager); for (l = object_proxies; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); UDisksBlock *block; block = udisks_object_get_block (object); if (block == NULL) continue; if (udisks_block_get_device_number (block) == block_device_number) { ret = block; goto out; } g_object_unref (block); } out: g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL); g_list_free (object_proxies); return ret; }
static UDisksObject * lookup_object_for_block (UDisksClient *client, dev_t block_device) { UDisksObject *ret; GList *objects; GList *l; ret = NULL; objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (client)); for (l = objects; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); UDisksBlock *block; block = udisks_object_peek_block (object); if (block != NULL) { if (block_device == udisks_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; }
static gboolean handle_cache_detach_or_split (UDisksLogicalVolume *volume_, GDBusMethodInvocation *invocation, GVariant *options, gboolean destroy) { #ifndef HAVE_LVMCACHE g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, N_("LVMCache not enabled at compile time.")); return TRUE; #else GError *error = NULL; UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (volume_); UDisksLinuxLogicalVolumeObject *object = NULL; UDisksDaemon *daemon; uid_t caller_uid; UDisksLinuxVolumeGroupObject *group_object; LVJobData data; if (!common_setup (volume, invocation, options, N_("Authentication is required to split cache pool LV off of a cache LV"), &object, &daemon, &caller_uid, NULL)) goto out; group_object = udisks_linux_logical_volume_object_get_volume_group (object); data.vg_name = udisks_linux_volume_group_object_get_name (group_object); data.lv_name = udisks_linux_logical_volume_object_get_name (object); data.destroy = destroy; if (!udisks_daemon_launch_threaded_job_sync (daemon, UDISKS_OBJECT (object), "lvm-lv-split-cache", caller_uid, lvcache_detach_job_func, &data, NULL, /* user_data_free_func */ NULL, /* GCancellable */ &error)) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, N_("Error converting volume: %s"), error->message); goto out; } udisks_logical_volume_complete_cache_split (volume_, invocation); out: g_clear_object (&object); return TRUE; #endif /* HAVE_LVMCACHE */ }
static void on_udisks_object_added (GDBusObjectManager *manager, GDBusObject *object, gpointer user_data) { FormatData *data = user_data; if (data->invocation == NULL) return; UDisksObject *udisks_object = UDISKS_OBJECT (object); UDisksJob *udisks_job = udisks_object_peek_job (udisks_object); if (udisks_job) { const gchar *us = g_dbus_proxy_get_object_path (G_DBUS_PROXY (data->block)); const gchar *const *them = udisks_job_get_objects (udisks_job); for (int i = 0; them[i]; i++) { if (strcmp (them[i], us) == 0) { g_dbus_method_invocation_return_value (data->invocation, g_variant_new ("()")); g_clear_object (&data->invocation); break; } } } }
static UDisksObject * wait_for_logical_volume_block_object (UDisksDaemon *daemon, gpointer user_data) { UDisksLinuxLogicalVolumeObject *volume_object = user_data; const gchar *volume_objpath; GList *objects, *l; UDisksObject *ret = NULL; volume_objpath = g_dbus_object_get_object_path (G_DBUS_OBJECT (volume_object)); objects = udisks_daemon_get_objects (daemon); for (l = objects; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); UDisksBlockLVM2 *block; block = udisks_object_peek_block_lvm2 (object); if (block == NULL) continue; if (g_strcmp0 (udisks_block_lvm2_get_logical_volume (block), volume_objpath) == 0) { ret = g_object_ref (object); goto out; } } out: g_list_free_full (objects, g_object_unref); return ret; }
static gboolean handle_rename (UDisksLogicalVolume *_volume, GDBusMethodInvocation *invocation, const gchar *new_name, GVariant *options) { GError *error = NULL; UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume); UDisksLinuxLogicalVolumeObject *object = NULL; UDisksDaemon *daemon; uid_t caller_uid; UDisksLinuxVolumeGroupObject *group_object; const gchar *lv_objpath; LVJobData data; if (!common_setup (volume, invocation, options, N_("Authentication is required to rename a logical volume"), &object, &daemon, &caller_uid, NULL)) goto out; group_object = udisks_linux_logical_volume_object_get_volume_group (object); data.vg_name = udisks_linux_volume_group_object_get_name (group_object); data.lv_name = udisks_linux_logical_volume_object_get_name (object); data.new_lv_name = new_name; if (!udisks_daemon_launch_threaded_job_sync (daemon, UDISKS_OBJECT (object), "lvm-lvol-rename", caller_uid, lvrename_job_func, &data, NULL, /* user_data_free_func */ NULL, /* GCancellable */ &error)) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "Error renaming logical volume: %s", error->message); goto out; } lv_objpath = wait_for_logical_volume_path (group_object, new_name, &error); if (lv_objpath == NULL) { g_prefix_error (&error, "Error waiting for logical volume object for %s", new_name); g_dbus_method_invocation_take_error (invocation, error); goto out; } udisks_logical_volume_complete_rename (_volume, invocation, lv_objpath); out: g_clear_object (&object); return TRUE; }
static UDisksObject * wait_for_logical_volume_object (UDisksDaemon *daemon, gpointer user_data) { struct WaitData *data = user_data; return UDISKS_OBJECT (udisks_linux_volume_group_object_find_logical_volume_object (data->group_object, data->name)); }
static void update_problems (GduSdMonitor *monitor, GList **problem_list, CheckProblemFunc check_func) { GList *want = NULL; GList *added = NULL; GList *removed = NULL; GList *objects; GList *l; objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (monitor->client)); for (l = objects; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); if (check_func (monitor, object)) want = g_list_prepend (want, object); } want = g_list_sort (want, ptr_compare); *problem_list = g_list_sort (*problem_list, ptr_compare); diff_sorted_lists (*problem_list, want, ptr_compare, &added, &removed); for (l = removed; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); *problem_list = g_list_remove (*problem_list, object); g_object_unref (object); } for (l = added; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); *problem_list = g_list_prepend (*problem_list, g_object_ref (object)); } g_list_free (removed); g_list_free (added); g_list_free (want); g_list_free_full (objects, g_object_unref); }
static void on_examine_action_clicked (NotifyNotification *notification, const gchar *action, gpointer user_data) { GduSdMonitor *monitor = GDU_SD_MONITOR (user_data); const gchar *device_file = NULL; gchar *command_line = NULL; GAppInfo *app_info = NULL; GError *error = NULL; if (g_strcmp0 (action, "examine-smart") == 0) { if (monitor->ata_smart_problems != NULL) { UDisksObject *object = UDISKS_OBJECT (monitor->ata_smart_problems->data); if (object != NULL) { UDisksDrive *drive = udisks_object_peek_drive (object); if (drive != NULL) { UDisksBlock *block = udisks_client_get_block_for_drive (monitor->client, drive, TRUE); /* get_physical */ if (block != NULL) { device_file = udisks_block_get_device (block); g_object_ref (block); } } } } } else { g_assert_not_reached (); } if (device_file != NULL) command_line = g_strdup_printf ("gnome-disks --block-device %s", device_file); else command_line = g_strdup_printf ("gnome-disks"); app_info = g_app_info_create_from_commandline (command_line, NULL, /* application name */ G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION, NULL); if (!g_app_info_launch (app_info, NULL, NULL, &error)) { g_warning ("Error launching gnome-disks: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); } g_clear_object (&app_info); g_free (command_line); }
static gboolean handle_resize (UDisksLogicalVolume *_volume, GDBusMethodInvocation *invocation, guint64 new_size, GVariant *options) { GError *error = NULL; UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume); UDisksLinuxLogicalVolumeObject *object = NULL; UDisksDaemon *daemon; uid_t caller_uid; UDisksLinuxVolumeGroupObject *group_object; LVJobData data; if (!common_setup (volume, invocation, options, N_("Authentication is required to resize a logical volume"), &object, &daemon, &caller_uid, NULL)) goto out; group_object = udisks_linux_logical_volume_object_get_volume_group (object); data.vg_name = udisks_linux_volume_group_object_get_name (group_object); data.lv_name = udisks_linux_logical_volume_object_get_name (object); data.new_lv_size = new_size; data.resize_fs = FALSE; data.force = FALSE; g_variant_lookup (options, "resize_fsys", "b", &(data.resize_fs)); g_variant_lookup (options, "force", "b", &(data.force)); if (!udisks_daemon_launch_threaded_job_sync (daemon, UDISKS_OBJECT (object), "lvm-lvol-resize", caller_uid, lvresize_job_func, &data, NULL, /* user_data_free_func */ NULL, /* GCancellable */ &error)) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "Error resizing logical volume: %s", error->message); goto out; } udisks_logical_volume_complete_resize (_volume, invocation); out: g_clear_object (&object); return TRUE; }
static gboolean cleanup_block_walker (UDisksClient *client, UDisksBlock *block, gboolean is_leaf, gpointer user_data, GError **error) { StorageProvider *provider = user_data; UDisksObject *object = UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))); UDisksEncrypted *enc = udisks_object_peek_encrypted (object); if (enc) { UDisksBlock *cleartext = udisks_client_get_cleartext_block (client, block); if (cleartext) { /* The crypto backing device is unlocked and the cleartext device has been cleaned up. Lock the backing device so that we can format or wipe it later. */ if (enc && !udisks_encrypted_call_lock_sync (enc, g_variant_new ("a{sv}", NULL), NULL, error)) return FALSE; } else { /* The crypto backing device is locked and the cleartext device has not been cleaned up (since it doesn't exist). Remove its remembered configs. */ GList *remembered_configs = storage_provider_get_and_forget_remembered_configs (provider, g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); for (GList *l = remembered_configs; l; l = l->next) { GVariant *config = l->data; storage_remove_config (provider, block, config); } g_list_free_full (remembered_configs, (GDestroyNotify)g_variant_unref); } } storage_remove_config (provider, block, udisks_block_get_configuration (block)); return TRUE; }
/** * udisks_linux_drive_object_get_block: * @object: A #UDisksLinuxDriveObject. * @get_hw: If the drive is multipath, set to %TRUE to get a path device instead of the multipath device. * * Gets a #UDisksLinuxBlockObject representing a block device associated with @object. * * Returns: A #UDisksLinuxBlockObject or %NULL. The returned object * must be freed with g_object_unref(). */ UDisksLinuxBlockObject * udisks_linux_drive_object_get_block (UDisksLinuxDriveObject *object, gboolean get_hw) { GDBusObjectManagerServer *object_manager; UDisksLinuxBlockObject *ret; GList *objects; GList *l; /* TODO: actually look at @get_hw */ ret = NULL; object_manager = udisks_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); UDisksBlock *block; UDisksLinuxDevice *device; gboolean is_disk; if (!UDISKS_IS_LINUX_BLOCK_OBJECT (iter_object)) continue; device = udisks_linux_block_object_get_device (UDISKS_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 = udisks_object_peek_block (UDISKS_OBJECT (iter_object)); if (g_strcmp0 (udisks_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 common_setup (UDisksLinuxLogicalVolume *volume, GDBusMethodInvocation *invocation, GVariant *options, const gchar *auth_err_msg, UDisksLinuxLogicalVolumeObject **object, UDisksDaemon **daemon, uid_t *out_uid, gid_t *out_gid) { gboolean rc = FALSE; GError *error = NULL; *object = udisks_daemon_util_dup_object (volume, &error); if (*object == NULL) { g_dbus_method_invocation_take_error (invocation, error); goto out; } *daemon = udisks_linux_logical_volume_object_get_daemon (*object); if (!udisks_daemon_util_get_caller_uid_sync (*daemon, invocation, NULL /* GCancellable */, out_uid, out_gid, NULL, &error)) { g_dbus_method_invocation_return_gerror (invocation, error); g_clear_error (&error); goto out; } /* Policy check. */ UDISKS_DAEMON_CHECK_AUTHORIZATION (*daemon, UDISKS_OBJECT (*object), lvm2_policy_action_id, options, auth_err_msg, invocation); rc = TRUE; out: return rc; }
UDisksManager * udisks_client_get_manager (UDisksClient *client) { UDisksManager *ret = NULL; GDBusObject *obj; g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL); obj = g_dbus_object_manager_get_object (client->object_manager, "/org/freedesktop/UDisks2/Manager"); if (obj == NULL) goto out; ret = udisks_object_peek_manager (UDISKS_OBJECT (obj)); g_object_unref (obj); out: 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) { UDisksObject *object = UDISKS_OBJECT (l->data); UDisksBlock *block; block = udisks_object_peek_block (object); if (block != NULL) { if (g_strcmp0 (udisks_block_get_crypto_backing_device (block), crypto_object_path) == 0) { ret = TRUE; goto out; } } } out: return ret; }
static void update_drive_with_id (UDisksLinuxProvider *provider, const gchar *id) { GHashTableIter iter; UDisksLinuxDriveObject *drive_object; /* TODO: could have a GHashTable from id to UDisksLinuxDriveObject */ g_hash_table_iter_init (&iter, provider->sysfs_path_to_drive); while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &drive_object)) { UDisksDrive *drive = udisks_object_get_drive (UDISKS_OBJECT (drive_object)); if (drive != NULL) { if (g_strcmp0 (udisks_drive_get_id (drive), id) == 0) { //udisks_debug ("synthesizing change event on drive with id %s", id); udisks_linux_drive_object_uevent (drive_object, "change", NULL); } g_object_unref (drive); } } }
static gboolean handle_activate (UDisksLogicalVolume *_volume, GDBusMethodInvocation *invocation, GVariant *options) { GError *error = NULL; UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume); UDisksLinuxLogicalVolumeObject *object = NULL; UDisksDaemon *daemon; uid_t caller_uid; UDisksLinuxVolumeGroupObject *group_object; UDisksObject *block_object = NULL; LVJobData data; if (!common_setup (volume, invocation, options, N_("Authentication is required to activate a logical volume"), &object, &daemon, &caller_uid, NULL)) goto out; group_object = udisks_linux_logical_volume_object_get_volume_group (object); data.vg_name = udisks_linux_volume_group_object_get_name (group_object); data.lv_name = udisks_linux_logical_volume_object_get_name (object); if (!udisks_daemon_launch_threaded_job_sync (daemon, UDISKS_OBJECT (object), "lvm-lvol-activate", caller_uid, lvactivate_job_func, &data, NULL, /* user_data_free_func */ NULL, /* GCancellable */ &error)) { g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, "Error activating logical volume: %s", error->message); goto out; } block_object = udisks_daemon_wait_for_object_sync (daemon, wait_for_logical_volume_block_object, object, NULL, 10, /* timeout_seconds */ &error); if (block_object == NULL) { g_prefix_error (&error, "Error waiting for block object for %s", udisks_logical_volume_get_name (_volume)); g_dbus_method_invocation_take_error (invocation, error); goto out; } udisks_logical_volume_complete_activate (_volume, invocation, g_dbus_object_get_object_path (G_DBUS_OBJECT (block_object))); out: g_clear_object (&block_object); g_clear_object (&object); return TRUE; }
void storage_block_update (StorageBlock *block) { CockpitStorageBlock *iface = COCKPIT_STORAGE_BLOCK (block); StorageProvider *provider; UDisksClient *udisks_client; UDisksObject *udisks_object; UDisksBlock *udisks_block; UDisksPartition *udisks_partition = NULL; UDisksPartitionTable *udisks_partition_table = NULL; UDisksFilesystem *udisks_filesystem = NULL; UDisksPhysicalVolume *udisks_physical_volume = NULL; provider = storage_object_get_provider (block->object); udisks_client = storage_provider_get_udisks_client (provider); udisks_block = block->udisks_block; udisks_object = (UDisksObject *)g_dbus_interface_get_object (G_DBUS_INTERFACE (udisks_block)); if (udisks_object != NULL) { udisks_partition = udisks_object_peek_partition (udisks_object); udisks_partition_table = udisks_object_peek_partition_table (udisks_object); udisks_filesystem = udisks_object_peek_filesystem (udisks_object); udisks_physical_volume = udisks_object_peek_physical_volume (udisks_object); } { gs_free gchar *d = g_filename_display_name (udisks_block_get_preferred_device (udisks_block)); cockpit_storage_block_set_device (iface, d); } cockpit_storage_block_set_size (iface, udisks_block_get_size (udisks_block)); cockpit_storage_block_set_id_usage (iface, udisks_block_get_id_usage (udisks_block)); cockpit_storage_block_set_id_type (iface, udisks_block_get_id_type (udisks_block)); cockpit_storage_block_set_id_version (iface, udisks_block_get_id_version (udisks_block)); cockpit_storage_block_set_id_label (iface, udisks_block_get_id_label (udisks_block)); cockpit_storage_block_set_id_uuid (iface, udisks_block_get_id_uuid (udisks_block)); if (udisks_partition == NULL) { cockpit_storage_block_set_partition_number (iface, 0); cockpit_storage_block_set_partition_table (iface, "/"); } else { UDisksPartitionTable *table_for_partition; const gchar *objpath = "/"; GDBusObject *o; UDisksBlock *b; StorageObject *so; table_for_partition = udisks_client_get_partition_table (udisks_client, udisks_partition); if (table_for_partition != NULL) { o = g_dbus_interface_get_object (G_DBUS_INTERFACE (table_for_partition)); if (o != NULL) { b = udisks_object_peek_block (UDISKS_OBJECT (o)); if (b != NULL) { so = storage_provider_lookup_for_udisks_block (provider, b); if (so != NULL) { objpath = g_dbus_object_get_object_path (G_DBUS_OBJECT (so)); } } } } cockpit_storage_block_set_partition_table (iface, objpath); cockpit_storage_block_set_partition_number (iface, udisks_partition_get_number (udisks_partition)); } GVariantBuilder partitions; g_variant_builder_init (&partitions, G_VARIANT_TYPE ("a(otts)")); if (udisks_partition_table != NULL) { GList *ps, *l; ps = udisks_client_get_partitions (udisks_client, udisks_partition_table); for (l = ps; l != NULL; l = l->next) { UDisksPartition *p = UDISKS_PARTITION (l->data); GDBusObject *o; UDisksBlock *b; StorageObject *so; o = g_dbus_interface_get_object (G_DBUS_INTERFACE (p)); if (o != NULL) { b = udisks_object_peek_block (UDISKS_OBJECT (o)); if (b != NULL) { so = storage_provider_lookup_for_udisks_block (provider, b); if (so != NULL) { const gchar *type = "p"; if (udisks_partition_get_is_container (p)) type = "x"; else if (udisks_partition_get_is_contained (p)) type = "l"; g_variant_builder_add (&partitions, "(otts)", g_dbus_object_get_object_path (G_DBUS_OBJECT (so)), udisks_partition_get_offset (p), udisks_partition_get_size (p), type); } } } } g_list_free_full (ps, g_object_unref); const gchar *type = udisks_partition_table_get_type_ (udisks_partition_table); if (type == NULL || type[0] == '\0') type = "unknown"; cockpit_storage_block_set_partition_table_type (iface, type); } else cockpit_storage_block_set_partition_table_type (iface, ""); cockpit_storage_block_set_partitions (iface, g_variant_builder_end (&partitions)); cockpit_storage_block_set_drive (iface, storage_provider_translate_path (provider, udisks_block_get_drive (udisks_block))); cockpit_storage_block_set_crypto_backing_device (iface, storage_provider_translate_path (provider, udisks_block_get_crypto_backing_device (udisks_block))); cockpit_storage_block_set_mdraid (iface, storage_provider_translate_path (provider, udisks_block_get_mdraid (udisks_block))); cockpit_storage_block_set_mdraid_member (iface, storage_provider_translate_path (provider, udisks_block_get_mdraid_member (udisks_block))); if (udisks_filesystem) { const gchar *const *p = udisks_filesystem_get_mount_points (udisks_filesystem); gchar *u[g_strv_length ((gchar **)p) + 1]; int i; for (i = 0; p[i]; i++) u[i] = g_filename_display_name (p[i]); u[i] = NULL; cockpit_storage_block_set_mounted_at (iface, (const gchar *const *)u); for (i = 0; u[i]; i++) g_free (u[i]); } GVariantIter iter; g_variant_iter_init (&iter, udisks_block_get_configuration (udisks_block)); const gchar *type; GVariant *details; gboolean got_fstab = FALSE, got_crypttab = FALSE; while (g_variant_iter_next (&iter, "(&s*)", &type, &details)) { if (strcmp (type, "fstab") == 0 && !got_fstab) { got_fstab = TRUE; const gchar *dir = variant_lookup (details, "dir"); if (dir) { gs_free gchar *dir_display = g_filename_display_name (dir); cockpit_storage_block_set_mount_point (iface, dir_display); } const gchar *opts = variant_lookup (details, "opts"); if (opts) { gs_free gchar *opts_locale = g_locale_to_utf8 (opts, -1, NULL, NULL, NULL); if (opts_locale) cockpit_storage_block_set_mount_options (iface, opts_locale); else g_warning ("Can't convert fstab options into UTF8"); } } else if (strcmp (type, "crypttab") == 0 && !got_crypttab) { got_crypttab = TRUE; const gchar *opts = variant_lookup (details, "options"); if (opts) { gs_free gchar *opts_locale = g_locale_to_utf8 (opts, -1, NULL, NULL, NULL); if (opts_locale) cockpit_storage_block_set_crypto_options (iface, opts_locale); else g_warning ("Can't convert crypttab options into UTF8"); } } g_variant_unref (details); } cockpit_storage_block_set_logical_volume (iface, storage_provider_translate_path (provider, udisks_block_get_logical_volume (udisks_block))); if (udisks_physical_volume) { cockpit_storage_block_set_pv_group (iface, storage_provider_translate_path (provider, udisks_physical_volume_get_volume_group (udisks_physical_volume))); cockpit_storage_block_set_pv_size (iface, udisks_physical_volume_get_size (udisks_physical_volume)); cockpit_storage_block_set_pv_free_size (iface, udisks_physical_volume_get_free_size (udisks_physical_volume)); } else cockpit_storage_block_set_pv_group (iface, "/"); }
static void udisks_client_get_object_info_for_drive (UDisksClient *client, UDisksDrive *drive, UDisksPartition *partition, UDisksObjectInfo *info) { const gchar *vendor; const gchar *model; const gchar *media; const gchar *const *media_compat; gboolean media_available; gboolean media_removable; gint rotation_rate; guint64 size; gchar *size_str; guint n; GString *desc_str; DriveType desc_type; gchar *hyphenated_connection_bus; const gchar *connection_bus; UDisksBlock *block = NULL; gchar *s; const gchar *cs; UDisksBlock *block_for_partition = NULL; g_return_if_fail (UDISKS_IS_DRIVE (drive)); size_str = NULL; vendor = udisks_drive_get_vendor (drive); model = udisks_drive_get_model (drive); size = udisks_drive_get_size (drive); media_removable = udisks_drive_get_media_removable (drive); media_available = udisks_drive_get_media_available (drive); rotation_rate = udisks_drive_get_rotation_rate (drive); if (size > 0) size_str = udisks_client_get_size_for_display (client, size, FALSE, FALSE); media = udisks_drive_get_media (drive); media_compat = udisks_drive_get_media_compatibility (drive); connection_bus = udisks_drive_get_connection_bus (drive); if (strlen (connection_bus) > 0) hyphenated_connection_bus = g_strdup_printf ("-%s", connection_bus); else hyphenated_connection_bus = g_strdup (""); /* Name is easy - that's just "$vendor $model" */ if (strlen (vendor) == 0) vendor = NULL; if (strlen (model) == 0) model = NULL; info->name = g_strdup_printf ("%s%s%s", vendor != NULL ? vendor : "", vendor != NULL ? " " : "", model != NULL ? model : ""); desc_type = DRIVE_TYPE_UNSET; desc_str = g_string_new (NULL); for (n = 0; n < G_N_ELEMENTS (media_data) - 1; n++) { /* media_compat */ if (strv_has (media_compat, media_data[n].id)) { if (info->icon == NULL) info->icon = g_themed_icon_new_with_default_fallbacks (media_data[n].drive_icon); if (info->icon_symbolic == NULL) info->icon_symbolic = g_themed_icon_new_with_default_fallbacks (media_data[n].drive_icon_symbolic); if (strstr (desc_str->str, media_data[n].media_family) == NULL) { if (desc_str->len > 0) g_string_append (desc_str, "/"); g_string_append (desc_str, g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_family)); } desc_type = media_data[n].media_type; } if (media_removable && media_available) { /* media */ if (g_strcmp0 (media, media_data[n].id) == 0) { if (info->media_description == NULL) { switch (media_data[n].media_type) { case DRIVE_TYPE_UNSET: g_assert_not_reached (); break; case DRIVE_TYPE_DRIVE: /* Translators: Used to describe drive without removable media. The %s is the type, e.g. 'Thumb' */ info->media_description = g_strdup_printf (C_("drive-with-fixed-media", "%s Drive"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name)); break; case DRIVE_TYPE_DISK: /* Translators: Used to describe generic media. The %s is the type, e.g. 'Zip' or 'Floppy' */ info->media_description = g_strdup_printf (C_("drive-with-generic-media", "%s Disk"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name)); break; case DRIVE_TYPE_CARD: /* Translators: Used to describe flash media. The %s is the type, e.g. 'SD' or 'CompactFlash' */ info->media_description = g_strdup_printf (C_("flash-media", "%s Card"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name)); break; case DRIVE_TYPE_DISC: /* Translators: Used to describe optical discs. The %s is the type, e.g. 'CD-R' or 'DVD-ROM' */ info->media_description = g_strdup_printf (C_("optical-media", "%s Disc"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name)); break; } } if (info->media_icon == NULL) info->media_icon = g_themed_icon_new_with_default_fallbacks (media_data[n].media_icon); if (info->media_icon_symbolic == NULL) info->media_icon_symbolic = g_themed_icon_new_with_default_fallbacks (media_data[n].media_icon_symbolic); } } } switch (desc_type) { case DRIVE_TYPE_UNSET: if (media_removable) { if (size_str != NULL) { /* Translators: Used to describe a drive. The %s is the size, e.g. '20 GB' */ info->description = g_strdup_printf (C_("drive-with-size", "%s Drive"), size_str); } else { /* Translators: Used to describe a drive we know very little about (removable media or size not known) */ info->description = g_strdup (C_("generic-drive", "Drive")); } } else { if (rotation_rate == 0) { if (size_str != NULL) { /* Translators: Used to describe a non-rotating drive (rotation rate either unknown * or it's a solid-state drive). The %s is the size, e.g. '20 GB'. */ info->description = g_strdup_printf (C_("disk-non-rotational", "%s Disk"), size_str); } else { /* Translators: Used to describe a non-rotating drive (rotation rate either unknown * or it's a solid-state drive). The drive is either using removable media or its * size not known. */ info->description = g_strdup (C_("disk-non-rotational", "Disk")); } } else { if (size_str != NULL) { /* Translators: Used to describe a hard-disk drive (HDD). The %s is the size, e.g. '20 GB'. */ info->description = g_strdup_printf (C_("disk-hdd", "%s Hard Disk"), size_str); } else { /* Translators: Used to describe a hard-disk drive (HDD) (removable media or size not known) */ info->description = g_strdup (C_("disk-hdd", "Hard Disk")); } } } break; case DRIVE_TYPE_CARD: /* Translators: Used to describe a card reader. The %s is the card type e.g. 'CompactFlash'. */ info->description = g_strdup_printf (C_("drive-card-reader", "%s Card Reader"), desc_str->str); break; case DRIVE_TYPE_DRIVE: /* explicit fall-through */ case DRIVE_TYPE_DISK: /* explicit fall-through */ case DRIVE_TYPE_DISC: if (!media_removable && size_str != NULL) { /* Translators: Used to describe drive. The first %s is the size e.g. '20 GB' and the * second %s is the drive type e.g. 'Thumb'. */ info->description = g_strdup_printf (C_("drive-with-size-and-type", "%s %s Drive"), size_str, desc_str->str); } else { /* Translators: Used to describe drive. The first %s is the drive type e.g. 'Thumb'. */ info->description = g_strdup_printf (C_("drive-with-type", "%s Drive"), desc_str->str); } break; } g_string_free (desc_str, TRUE); /* fallback for icon */ if (info->icon == NULL) { if (media_removable) { s = g_strdup_printf ("drive-removable-media%s", hyphenated_connection_bus); } else { if (rotation_rate == 0) s = g_strdup_printf ("drive-harddisk-solidstate%s", hyphenated_connection_bus); else s = g_strdup_printf ("drive-harddisk%s", hyphenated_connection_bus); } info->icon = g_themed_icon_new_with_default_fallbacks (s); g_free (s); } /* fallback for icon_symbolic */ if (info->icon_symbolic == NULL) { if (media_removable) { s = g_strdup_printf ("drive-removable-media%s-symbolic", hyphenated_connection_bus); } else { if (rotation_rate == 0) s = g_strdup_printf ("drive-harddisk-solidstate%s-symbolic", hyphenated_connection_bus); else s = g_strdup_printf ("drive-harddisk%s-symbolic", hyphenated_connection_bus); } info->icon_symbolic = g_themed_icon_new_with_default_fallbacks (s); g_free (s); } /* fallback for media_icon */ if (media_removable && media_available && info->media_icon == NULL) { if (media_removable) { s = g_strdup_printf ("drive-removable-media%s", hyphenated_connection_bus); } else { if (rotation_rate == 0) s = g_strdup_printf ("drive-harddisk-solidstate%s", hyphenated_connection_bus); else s = g_strdup_printf ("drive-harddisk%s", hyphenated_connection_bus); } info->media_icon = g_themed_icon_new_with_default_fallbacks (s); g_free (s); } /* fallback for media_icon_symbolic */ if (media_removable && media_available && info->media_icon_symbolic == NULL) { if (media_removable) { s = g_strdup_printf ("drive-removable-media%s-symbolic", hyphenated_connection_bus); } else { if (rotation_rate == 0) s = g_strdup_printf ("drive-harddisk-solidstate%s-symbolic", hyphenated_connection_bus); else s = g_strdup_printf ("drive-harddisk%s-symbolic", hyphenated_connection_bus); } info->media_icon_symbolic = g_themed_icon_new_with_default_fallbacks (s); g_free (s); } /* prepend a qualifier to the media description, based on the disc state */ if (udisks_drive_get_optical_blank (drive)) { /* Translators: String used for a blank disc. The %s is the disc type e.g. "CD-RW Disc" */ s = g_strdup_printf (C_("optical-media", "Blank %s"), info->media_description); g_free (info->media_description); info->media_description = s; } else if (udisks_drive_get_optical_num_audio_tracks (drive) > 0 && udisks_drive_get_optical_num_data_tracks (drive) > 0) { /* Translators: String used for a mixed disc. The %s is the disc type e.g. "CD-ROM Disc" */ s = g_strdup_printf (C_("optical-media", "Mixed %s"), info->media_description); g_free (info->media_description); info->media_description = s; } else if (udisks_drive_get_optical_num_audio_tracks (drive) > 0 && udisks_drive_get_optical_num_data_tracks (drive) == 0) { /* Translators: String used for an audio disc. The %s is the disc type e.g. "CD-ROM Disc" */ s = g_strdup_printf (C_("optical-media", "Audio %s"), info->media_description); g_free (info->media_description); info->media_description = s; } /* Apply UDISKS_NAME, UDISKS_ICON_NAME, UDISKS_SYMBOLIC_ICON_NAME hints, if available */ block = udisks_client_get_block_for_drive (client, drive, TRUE); if (block != NULL) { cs = udisks_block_get_hint_name (block); if (cs != NULL && strlen (cs) > 0) { g_free (info->description); g_free (info->media_description); info->description = g_strdup (cs); info->media_description = g_strdup (cs); } cs = udisks_block_get_hint_icon_name (block); if (cs != NULL && strlen (cs) > 0) { g_clear_object (&info->icon); g_clear_object (&info->media_icon); info->icon = g_themed_icon_new_with_default_fallbacks (cs); info->media_icon = g_themed_icon_new_with_default_fallbacks (cs); } cs = udisks_block_get_hint_symbolic_icon_name (block); if (cs != NULL && strlen (cs) > 0) { g_clear_object (&info->icon_symbolic); g_clear_object (&info->media_icon_symbolic); info->icon_symbolic = g_themed_icon_new_with_default_fallbacks (cs); info->media_icon_symbolic = g_themed_icon_new_with_default_fallbacks (cs); } } if (partition != NULL) { GDBusObject *object_for_partition; object_for_partition = g_dbus_interface_get_object (G_DBUS_INTERFACE (partition)); if (object_for_partition != NULL) block_for_partition = udisks_object_peek_block (UDISKS_OBJECT (object_for_partition)); } if (block_for_partition == NULL) block_for_partition = block; if (partition != NULL) { /* Translators: Used to describe a partition of a drive. * The %d is the partition number. * The %s is the description for the drive (e.g. "2 GB Thumb Drive"). */ s = g_strdup_printf (C_("part-drive", "Partition %d of %s"), udisks_partition_get_number (partition), info->description); g_free (info->description); info->description = s; } /* calculate and set one-liner */ if (block != NULL) { const gchar *drive_revision = udisks_drive_get_revision (drive); if (strlen (drive_revision) > 0) { /* Translators: String used for one-liner description of drive. * The first %s is the description of the object (e.g. "80 GB Disk" or "Partition 2 of 2 GB Thumb Drive"). * The second %s is the name of the object (e.g. "INTEL SSDSA2MH080G1GC"). * The third %s is the fw revision (e.g "45ABX21"). * The fourth %s is the special device file (e.g. "/dev/sda"). */ info->one_liner = g_strdup_printf (C_("one-liner-drive", "%s — %s [%s] (%s)"), info->description, info->name, drive_revision, udisks_block_get_preferred_device (block_for_partition)); } else { /* Translators: String used for one-liner description of drive w/o known fw revision. * The first %s is the description of the object (e.g. "80 GB Disk"). * The second %s is the name of the object (e.g. "INTEL SSDSA2MH080G1GC"). * The third %s is the special device file (e.g. "/dev/sda"). */ info->one_liner = g_strdup_printf (C_("one-liner-drive", "%s — %s (%s)"), info->description, info->name, udisks_block_get_preferred_device (block_for_partition)); } } g_free (hyphenated_connection_bus); g_free (size_str); info->sort_key = g_strdup_printf ("00_drive_%s", udisks_drive_get_sort_key (drive)); g_clear_object (&block); }
/** * udisks_daemon_util_on_same_seat: * @daemon: A #UDisksDaemon. * @object: The #GDBusObject that the call is on or %NULL. * @process: The process to check for. * * Checks whether the device represented by @object (if any) is plugged into * a seat where the caller represented by @process is logged in. * * This works if @object is a drive or a block object. * * Returns: %TRUE if @object and @process is on the same seat, %FALSE otherwise. */ gboolean udisks_daemon_util_on_same_seat (UDisksDaemon *daemon, UDisksObject *object, pid_t process) { #if !defined(HAVE_LIBSYSTEMD_LOGIN) /* if we don't have systemd, assume it's always the same seat */ return TRUE; #else gboolean ret = FALSE; char *session = NULL; char *seat = NULL; const gchar *drive_seat; UDisksObject *drive_object = NULL; UDisksDrive *drive = NULL; /* if we don't have logind, assume it's always the same seat */ if (!LOGIND_AVAILABLE()) return TRUE; if (UDISKS_IS_LINUX_BLOCK_OBJECT (object)) { UDisksLinuxBlockObject *linux_block_object; UDisksBlock *block; linux_block_object = UDISKS_LINUX_BLOCK_OBJECT (object); block = udisks_object_get_block (UDISKS_OBJECT (linux_block_object)); if (block != NULL) { drive_object = udisks_daemon_find_object (daemon, udisks_block_get_drive (block)); g_object_unref (block); } } else if (UDISKS_IS_LINUX_DRIVE_OBJECT (object)) { drive_object = g_object_ref (object); } if (drive_object == NULL) goto out; drive = udisks_object_get_drive (UDISKS_OBJECT (drive_object)); if (drive == NULL) goto out; /* It's not unexpected to not find a session, nor a seat associated with @process */ if (sd_pid_get_session (process, &session) == 0) sd_session_get_seat (session, &seat); /* If we don't know the seat of the caller, we assume the device is always on another seat */ if (seat == NULL) goto out; drive_seat = udisks_drive_get_seat (drive); if (g_strcmp0 (seat, drive_seat) == 0) { ret = TRUE; goto out; } out: free (seat); free (session); g_clear_object (&drive_object); g_clear_object (&drive); return ret; #endif /* HAVE_LIBSYSTEMD_LOGIN */ }
static void provider_update_objects (StorageProvider *provider) { GDBusObjectManagerServer *object_manager; GList *udisks_objects; GList *lvm_objects; GList *wanted; GList *added, *removed; GList *l; object_manager = G_DBUS_OBJECT_MANAGER_SERVER (daemon_get_object_manager (provider->daemon)); udisks_objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (provider->udisks_client)); lvm_objects = g_dbus_object_manager_get_objects (provider->lvm_objman); wanted = NULL; for (l = udisks_objects; l != NULL; l = l->next) { GDBusInterface *iface = get_udisk_iface (UDISKS_OBJECT (l->data)); if (iface == NULL) continue; wanted = g_list_prepend (wanted, g_object_ref (iface)); } for (l = lvm_objects; l != NULL; l = l->next) { if (!LVM_IS_OBJECT (l->data)) continue; GDBusInterface *iface = get_lvm_iface (LVM_OBJECT (l->data)); if (iface == NULL) continue; wanted = g_list_prepend (wanted, g_object_ref (iface)); } wanted = g_list_sort (wanted, (GCompareFunc)udisks_iface_compare_func); provider->ifaces = g_list_sort (provider->ifaces, (GCompareFunc)udisks_iface_compare_func); diff_sorted_lists (provider->ifaces, wanted, (GCompareFunc)udisks_iface_compare_func, &added, &removed, NULL); for (l = removed; l != NULL; l = l->next) { GDBusInterface *iface = G_DBUS_INTERFACE (l->data); StorageObject *object; object = g_hash_table_lookup (provider->hash_interface_to_storage_object, iface); g_warn_if_fail (object != NULL); if (object) { g_warn_if_fail (g_dbus_object_manager_server_unexport (object_manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)))); } g_hash_table_remove (provider->hash_interface_to_storage_object, iface); provider->ifaces = g_list_remove (provider->ifaces, iface); g_object_unref (iface); } for (l = added; l != NULL; l = l->next) { GDBusInterface *iface = G_DBUS_INTERFACE (l->data); StorageObject *object = make_storage_object (provider, iface); g_warn_if_fail (g_hash_table_lookup (provider->hash_interface_to_storage_object, iface) == NULL); g_hash_table_insert (provider->hash_interface_to_storage_object, g_object_ref (iface), object); gs_free gchar *object_path = storage_object_make_object_path (object); g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); provider->ifaces = g_list_prepend (provider->ifaces, g_object_ref (iface)); } g_list_free (added); g_list_free (removed); g_list_free_full (udisks_objects, g_object_unref); g_list_free_full (lvm_objects, g_object_unref); g_list_free_full (wanted, g_object_unref); }
/** * udisks_linux_drive_object_is_not_in_use: * @object: A #UDisksLinuxDriveObject. * @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 udisks_linux_drive_object_is_not_in_use (UDisksLinuxDriveObject *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 (UDISKS_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 = udisks_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); UDisksBlock *block; UDisksFilesystem *filesystem; if (!UDISKS_IS_LINUX_BLOCK_OBJECT (iter_object)) continue; block = udisks_object_peek_block (UDISKS_OBJECT (iter_object)); filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (iter_object)); if (g_strcmp0 (udisks_block_get_drive (block), drive_object_path) != 0) continue; /* bail if block device is mounted */ if (filesystem != NULL) { if (g_strv_length ((gchar **) udisks_filesystem_get_mount_points (filesystem)) > 0) { g_set_error (error, UDISKS_ERROR, UDISKS_ERROR_DEVICE_BUSY, "Device %s is mounted", udisks_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, UDISKS_ERROR, UDISKS_ERROR_DEVICE_BUSY, "Encrypted device %s is unlocked", udisks_block_get_preferred_device (block)); ret = FALSE; goto out; } } out: g_list_free_full (objects, g_object_unref); return ret; }
static void provider_update_jobs (StorageProvider *provider) { GDBusObjectManagerServer *object_manager; GList *udisks_objects; GList *lvm_objects; GList *all_objects; GList *wanted; GList *added, *removed; GList *l; object_manager = G_DBUS_OBJECT_MANAGER_SERVER (daemon_get_object_manager (provider->daemon)); udisks_objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (provider->udisks_client)); lvm_objects = g_dbus_object_manager_get_objects (provider->lvm_objman); all_objects = g_list_concat (udisks_objects, lvm_objects); wanted = NULL; for (l = all_objects; l != NULL; l = l->next) { if (!UDISKS_IS_OBJECT (l->data)) continue; UDisksObject *object = UDISKS_OBJECT (l->data); UDisksJob *job; job = udisks_object_peek_job (object); if (job == NULL) continue; const gchar *operation = udisks_job_get_operation (job); if (strcmp (operation, "format-mkfs") != 0 && strcmp (operation, "format-erase") != 0 && strcmp (operation, "lvm-vg-empty-device") != 0) continue; wanted = g_list_prepend (wanted, g_object_ref (job)); } wanted = g_list_sort (wanted, (GCompareFunc)_udisks_job_compare_func); provider->jobs = g_list_sort (provider->jobs, (GCompareFunc)_udisks_job_compare_func); diff_sorted_lists (provider->jobs, wanted, (GCompareFunc)_udisks_job_compare_func, &added, &removed, NULL); for (l = removed; l != NULL; l = l->next) { UDisksJob *job = UDISKS_JOB (l->data); CockpitJob *object; object = g_hash_table_lookup (provider->hash_job_to_storage_job, job); if (object == NULL) { g_warning ("No object for job %p", job); } else { g_warn_if_fail (g_dbus_object_manager_server_unexport (object_manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)))); g_hash_table_remove (provider->hash_job_to_storage_job, job); } provider->jobs = g_list_remove (provider->jobs, job); g_object_unref (job); } for (l = added; l != NULL; l = l->next) { UDisksJob *job = UDISKS_JOB (l->data); CockpitObjectSkeleton *object; CockpitJob *cockpit_job; gchar *object_path; object_path = utils_generate_object_path ("/com/redhat/Cockpit/Jobs", udisks_job_get_operation (job)); cockpit_job = storage_job_new (provider, job); object = cockpit_object_skeleton_new (object_path); cockpit_object_skeleton_set_job (object, cockpit_job); g_object_unref (cockpit_job); g_free (object_path); g_warn_if_fail (g_hash_table_lookup (provider->hash_job_to_storage_job, job) == NULL); g_hash_table_insert (provider->hash_job_to_storage_job, g_object_ref (job), object); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); provider->jobs = g_list_prepend (provider->jobs, g_object_ref (job)); } g_list_free (added); g_list_free (removed); g_list_free_full (all_objects, g_object_unref); g_list_free_full (wanted, g_object_unref); }