diff options
Diffstat (limited to 'src/udiskslinuxblock.c')
-rw-r--r-- | src/udiskslinuxblock.c | 2022 |
1 files changed, 763 insertions, 1259 deletions
diff --git a/src/udiskslinuxblock.c b/src/udiskslinuxblock.c index b6b13a7..41a950e 100644 --- a/src/udiskslinuxblock.c +++ b/src/udiskslinuxblock.c @@ -24,29 +24,22 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include <unistd.h> -#include <errno.h> #include <pwd.h> #include <grp.h> -#include <mntent.h> - #include <string.h> #include <stdlib.h> +#include <errno.h> +#include <mntent.h> + #include <glib/gstdio.h> #include "udiskslogging.h" -#include "udisksdaemon.h" -#include "udisksdaemonutil.h" #include "udiskslinuxblock.h" -#include "udisksmount.h" -#include "udisksmountmonitor.h" +#include "udiskslinuxblockobject.h" #include "udiskslinuxdriveobject.h" -#include "udiskslinuxdrive.h" -#include "udiskslinuxfilesystem.h" -#include "udiskslinuxencrypted.h" -#include "udiskslinuxswapspace.h" -#include "udiskslinuxloop.h" -#include "udiskspersistentstore.h" +#include "udisksdaemon.h" +#include "udiskscleanup.h" +#include "udisksdaemonutil.h" #include "udiskslinuxprovider.h" #include "udisksfstabmonitor.h" #include "udisksfstabentry.h" @@ -56,9 +49,10 @@ /** * SECTION:udiskslinuxblock * @title: UDisksLinuxBlock - * @short_description: Linux block devices + * @short_description: Block devices on Linux * - * Object corresponding to a Linux block device. + * This type provides an implementation of the #UDisksBlock + * interface on Linux. */ typedef struct _UDisksLinuxBlockClass UDisksLinuxBlockClass; @@ -66,341 +60,792 @@ typedef struct _UDisksLinuxBlockClass UDisksLinuxBlockClass; /** * UDisksLinuxBlock: * - * The #UDisksLinuxBlock structure contains only private data and - * should only be accessed using the provided API. + * The #UDisksLinuxBlock structure contains only private data and should + * only be accessed using the provided API. */ struct _UDisksLinuxBlock { - UDisksObjectSkeleton parent_instance; - - UDisksDaemon *daemon; - UDisksMountMonitor *mount_monitor; - - GUdevDevice *device; - - /* interface */ - UDisksBlockDevice *iface_block_device; - UDisksFilesystem *iface_filesystem; - UDisksSwapspace *iface_swapspace; - UDisksEncrypted *iface_encrypted; - UDisksLoop *iface_loop; + UDisksBlockDeviceSkeleton parent_instance; }; struct _UDisksLinuxBlockClass { - UDisksObjectSkeletonClass parent_class; + UDisksBlockDeviceSkeletonClass parent_class; }; -enum -{ - PROP_0, - PROP_DAEMON, - PROP_DEVICE -}; +static void block_iface_init (UDisksBlockDeviceIface *iface); -G_DEFINE_TYPE (UDisksLinuxBlock, udisks_linux_block, UDISKS_TYPE_OBJECT_SKELETON); +G_DEFINE_TYPE_WITH_CODE (UDisksLinuxBlock, udisks_linux_block, UDISKS_TYPE_BLOCK_DEVICE_SKELETON, + G_IMPLEMENT_INTERFACE (UDISKS_TYPE_BLOCK_DEVICE, block_iface_init)); -static void on_mount_monitor_mount_added (UDisksMountMonitor *monitor, - UDisksMount *mount, - gpointer user_data); -static void on_mount_monitor_mount_removed (UDisksMountMonitor *monitor, - UDisksMount *mount, - gpointer user_data); +/* ---------------------------------------------------------------------------------------------------- */ static void -udisks_linux_block_finalize (GObject *object) +udisks_linux_block_init (UDisksLinuxBlock *block) { - UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (object); - - /* note: we don't hold a ref to block->daemon or block->mount_monitor */ - g_signal_handlers_disconnect_by_func (block->mount_monitor, on_mount_monitor_mount_added, block); - g_signal_handlers_disconnect_by_func (block->mount_monitor, on_mount_monitor_mount_removed, block); - - g_object_unref (block->device); - - if (block->iface_block_device != NULL) - g_object_unref (block->iface_block_device); - if (block->iface_filesystem != NULL) - g_object_unref (block->iface_filesystem); - if (block->iface_swapspace != NULL) - g_object_unref (block->iface_swapspace); - if (block->iface_encrypted != NULL) - g_object_unref (block->iface_encrypted); - if (block->iface_loop != NULL) - g_object_unref (block->iface_loop); - - if (G_OBJECT_CLASS (udisks_linux_block_parent_class)->finalize != NULL) - G_OBJECT_CLASS (udisks_linux_block_parent_class)->finalize (object); + g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (block), + G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); } static void -udisks_linux_block_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +udisks_linux_block_class_init (UDisksLinuxBlockClass *klass) +{ +} + +/** + * udisks_linux_block_new: + * + * Creates a new #UDisksLinuxBlock instance. + * + * Returns: A new #UDisksLinuxBlock. Free with g_object_unref(). + */ +UDisksBlockDevice * +udisks_linux_block_new (void) +{ + return UDISKS_BLOCK_DEVICE (g_object_new (UDISKS_TYPE_LINUX_BLOCK, + NULL)); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +get_sysfs_attr (GUdevDevice *device, + const gchar *attr) +{ + gchar *filename; + gchar *value; + filename = g_strconcat (g_udev_device_get_sysfs_path (device), + "/", + attr, + NULL); + value = NULL; + /* don't care about errors */ + g_file_get_contents (filename, + &value, + NULL, + NULL); + g_free (filename); + return value; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +find_block_device_by_sysfs_path (GDBusObjectManagerServer *object_manager, + const gchar *sysfs_path) { - UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (object); + gchar *ret; + GList *objects; + GList *l; + + ret = NULL; - switch (prop_id) + objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); + for (l = objects; l != NULL; l = l->next) { - case PROP_DAEMON: - g_value_set_object (value, udisks_linux_block_get_daemon (block)); - break; + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (l->data); + GUdevDevice *device; - case PROP_DEVICE: - g_value_set_object (value, udisks_linux_block_get_device (block)); - break; + if (!UDISKS_IS_LINUX_BLOCK_OBJECT (object)) + continue; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + device = udisks_linux_block_object_get_device (UDISKS_LINUX_BLOCK_OBJECT (object)); + if (g_strcmp0 (sysfs_path, g_udev_device_get_sysfs_path (device)) == 0) + { + ret = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); + g_object_unref (device); + goto out; + } + g_object_unref (device); } + + out: + g_list_foreach (objects, (GFunc) g_object_unref, NULL); + g_list_free (objects); + return ret; } -static void -udisks_linux_block_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +find_drive (GDBusObjectManagerServer *object_manager, + GUdevDevice *block_device, + UDisksDrive **out_drive) { - UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (object); + GUdevDevice *whole_disk_block_device; + const gchar *whole_disk_block_device_sysfs_path; + gchar *ret; + GList *objects; + GList *l; + + ret = NULL; - switch (prop_id) + if (g_strcmp0 (g_udev_device_get_devtype (block_device), "disk") == 0) + whole_disk_block_device = g_object_ref (block_device); + else + whole_disk_block_device = g_udev_device_get_parent_with_subsystem (block_device, "block", "disk"); + whole_disk_block_device_sysfs_path = g_udev_device_get_sysfs_path (whole_disk_block_device); + + objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); + for (l = objects; l != NULL; l = l->next) { - case PROP_DAEMON: - g_assert (block->daemon == NULL); - /* we don't take a reference to the daemon */ - block->daemon = g_value_get_object (value); - break; - - case PROP_DEVICE: - g_assert (block->device == NULL); - block->device = g_value_dup_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (l->data); + GList *drive_devices; + GList *j; + + if (!UDISKS_IS_LINUX_DRIVE_OBJECT (object)) + continue; + + drive_devices = udisks_linux_drive_object_get_devices (UDISKS_LINUX_DRIVE_OBJECT (object)); + for (j = drive_devices; j != NULL; j = j->next) + { + GUdevDevice *drive_device = G_UDEV_DEVICE (j->data); + const gchar *drive_sysfs_path; + + drive_sysfs_path = g_udev_device_get_sysfs_path (drive_device); + if (g_strcmp0 (whole_disk_block_device_sysfs_path, drive_sysfs_path) == 0) + { + if (out_drive != NULL) + *out_drive = udisks_object_get_drive (UDISKS_OBJECT (object)); + ret = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); + g_list_foreach (drive_devices, (GFunc) g_object_unref, NULL); + g_list_free (drive_devices); + goto out; + } + } + g_list_foreach (drive_devices, (GFunc) g_object_unref, NULL); + g_list_free (drive_devices); } + + out: + g_list_foreach (objects, (GFunc) g_object_unref, NULL); + g_list_free (objects); + g_object_unref (whole_disk_block_device); + return ret; } +/* ---------------------------------------------------------------------------------------------------- */ static void -udisks_linux_block_init (UDisksLinuxBlock *block) +update_hints (UDisksLinuxBlock *block, + GUdevDevice *device, + UDisksDrive *drive) { + UDisksBlockDevice *iface = UDISKS_BLOCK_DEVICE (block); + gboolean hint_system; + gboolean hint_ignore; + gboolean hint_auto; + const gchar *hint_name; + const gchar *hint_icon_name; + const gchar *device_file; + + /* very conservative defaults */ + hint_system = TRUE; + hint_ignore = FALSE; + hint_auto = FALSE; + hint_name = NULL; + hint_icon_name = NULL; + + device_file = g_udev_device_get_device_file (device); + + /* Provide easy access to _only_ the following devices + * + * - anything connected via known local buses (e.g. USB or Firewire, MMC or MemoryStick) + * - any device with removable media + * + * Be careful when extending this list as we don't want to automount + * the world when (inadvertently) connecting to a SAN. + */ + if (drive != NULL) + { + const gchar *connection_bus; + gboolean removable; + connection_bus = udisks_drive_get_connection_bus (drive); + removable = udisks_drive_get_media_removable (drive); + if (removable || + (g_strcmp0 (connection_bus, "usb") == 0 || g_strcmp0 (connection_bus, "firewire") == 0) || + (g_str_has_prefix (device_file, "/dev/mmcblk") || g_str_has_prefix (device_file, "/dev/mspblk"))) + { + hint_system = FALSE; + hint_auto = TRUE; + } + } + + /* TODO: set ignore to TRUE for physical paths belonging to a drive with multiple paths */ + + /* override from udev properties */ + if (g_udev_device_has_property (device, "UDISKS_SYSTEM")) + hint_system = g_udev_device_get_property_as_boolean (device, "UDISKS_SYSTEM"); + if (g_udev_device_has_property (device, "UDISKS_IGNORE")) + hint_ignore = g_udev_device_get_property_as_boolean (device, "UDISKS_IGNORE"); + if (g_udev_device_has_property (device, "UDISKS_AUTO")) + hint_auto = g_udev_device_get_property_as_boolean (device, "UDISKS_AUTO"); + if (g_udev_device_has_property (device, "UDISKS_NAME")) + hint_name = g_udev_device_get_property (device, "UDISKS_NAME"); + if (g_udev_device_has_property (device, "UDISKS_ICON_NAME")) + hint_icon_name = g_udev_device_get_property (device, "UDISKS_ICON_NAME"); + + /* ... and scene! */ + udisks_block_device_set_hint_system (iface, hint_system); + udisks_block_device_set_hint_ignore (iface, hint_ignore); + udisks_block_device_set_hint_auto (iface, hint_auto); + udisks_block_device_set_hint_name (iface, hint_name); + udisks_block_device_set_hint_icon_name (iface, hint_icon_name); } -static void -udisks_linux_block_constructed (GObject *object) +/* ---------------------------------------------------------------------------------------------------- */ + +static GList * +find_fstab_entries_for_device (UDisksLinuxBlock *block, + UDisksDaemon *daemon) { - UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (object); - GString *str; + GList *entries; + GList *l; + GList *ret; + + ret = NULL; + + /* if this is too slow, we could add lookup methods to UDisksFstabMonitor... */ + entries = udisks_fstab_monitor_get_entries (udisks_daemon_get_fstab_monitor (daemon)); + for (l = entries; l != NULL; l = l->next) + { + UDisksFstabEntry *entry = UDISKS_FSTAB_ENTRY (l->data); + const gchar *const *symlinks; + const gchar *fsname; + gchar *device; + guint n; + + fsname = udisks_fstab_entry_get_fsname (entry); + device = NULL; + if (g_str_has_prefix (fsname, "UUID=")) + { + device = g_strdup_printf ("/dev/disk/by-uuid/%s", fsname + 5); + } + else if (g_str_has_prefix (fsname, "LABEL=")) + { + device = g_strdup_printf ("/dev/disk/by-label/%s", fsname + 6); + } + else if (g_str_has_prefix (fsname, "/dev")) + { + device = g_strdup (fsname); + } + else + { + /* ignore non-device entries */ + goto continue_loop; + } + + if (g_strcmp0 (device, udisks_block_device_get_device (UDISKS_BLOCK_DEVICE (block))) == 0) + { + ret = g_list_prepend (ret, g_object_ref (entry)); + } + else + { + symlinks = udisks_block_device_get_symlinks (UDISKS_BLOCK_DEVICE (block)); + if (symlinks != NULL) + { + for (n = 0; symlinks[n] != NULL; n++) + { + if (g_strcmp0 (device, symlinks[n]) == 0) + { + ret = g_list_prepend (ret, g_object_ref (entry)); + } + } + } + } - block->mount_monitor = udisks_daemon_get_mount_monitor (block->daemon); - g_signal_connect (block->mount_monitor, - "mount-added", - G_CALLBACK (on_mount_monitor_mount_added), - block); - g_signal_connect (block->mount_monitor, - "mount-removed", - G_CALLBACK (on_mount_monitor_mount_removed), - block); - - /* initial coldplug */ - udisks_linux_block_uevent (block, "add", NULL); - - /* compute the object path */ - str = g_string_new ("/org/freedesktop/UDisks2/block_devices/"); - udisks_safe_append_to_object_path (str, g_udev_device_get_name (block->device)); - g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (block), str->str); - g_string_free (str, TRUE); - - if (G_OBJECT_CLASS (udisks_linux_block_parent_class)->constructed != NULL) - G_OBJECT_CLASS (udisks_linux_block_parent_class)->constructed (object); + continue_loop: + g_free (device); + } + + g_list_foreach (entries, (GFunc) g_object_unref, NULL); + g_list_free (entries); + return ret; } -static void -udisks_linux_block_class_init (UDisksLinuxBlockClass *klass) +static GList * +find_crypttab_entries_for_device (UDisksLinuxBlock *block, + UDisksDaemon *daemon) { - GObjectClass *gobject_class; + GList *entries; + GList *l; + GList *ret; - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = udisks_linux_block_finalize; - gobject_class->constructed = udisks_linux_block_constructed; - gobject_class->set_property = udisks_linux_block_set_property; - gobject_class->get_property = udisks_linux_block_get_property; + ret = NULL; - /** - * UDisksLinuxBlock:daemon: - * - * The #UDisksDaemon the object is for. - */ - g_object_class_install_property (gobject_class, - PROP_DAEMON, - g_param_spec_object ("daemon", - "Daemon", - "The daemon the object is for", - UDISKS_TYPE_DAEMON, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * UDisksLinuxBlock:device: - * - * The #GUdevDevice for the object. Connect to the #GObject::notify - * signal to get notified whenever this is updated. - */ - g_object_class_install_property (gobject_class, - PROP_DEVICE, - g_param_spec_object ("device", - "Device", - "The device for the object", - G_UDEV_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + /* if this is too slow, we could add lookup methods to UDisksCrypttabMonitor... */ + entries = udisks_crypttab_monitor_get_entries (udisks_daemon_get_crypttab_monitor (daemon)); + for (l = entries; l != NULL; l = l->next) + { + UDisksCrypttabEntry *entry = UDISKS_CRYPTTAB_ENTRY (l->data); + const gchar *const *symlinks; + const gchar *device_in_entry; + gchar *device; + guint n; + + device_in_entry = udisks_crypttab_entry_get_device (entry); + device = NULL; + if (g_str_has_prefix (device_in_entry, "UUID=")) + { + device = g_strdup_printf ("/dev/disk/by-uuid/%s", device_in_entry + 5); + } + else if (g_str_has_prefix (device_in_entry, "LABEL=")) + { + device = g_strdup_printf ("/dev/disk/by-label/%s", device_in_entry + 6); + } + else if (g_str_has_prefix (device_in_entry, "/dev")) + { + device = g_strdup (device_in_entry); + } + else + { + /* ignore non-device entries */ + goto continue_loop; + } + + if (g_strcmp0 (device, udisks_block_device_get_device (UDISKS_BLOCK_DEVICE (block))) == 0) + { + ret = g_list_prepend (ret, g_object_ref (entry)); + } + else + { + symlinks = udisks_block_device_get_symlinks (UDISKS_BLOCK_DEVICE (block)); + if (symlinks != NULL) + { + for (n = 0; symlinks[n] != NULL; n++) + { + if (g_strcmp0 (device, symlinks[n]) == 0) + { + ret = g_list_prepend (ret, g_object_ref (entry)); + } + } + } + } + + continue_loop: + g_free (device); + } + g_list_foreach (entries, (GFunc) g_object_unref, NULL); + g_list_free (entries); + return ret; } -/** - * udisks_linux_block_new: - * @daemon: A #UDisksDaemon. - * @device: The #GUdevDevice for the sysfs block device. - * - * Create a new block object. - * - * Returns: A #UDisksLinuxBlock object. Free with g_object_unref(). - */ -UDisksLinuxBlock * -udisks_linux_block_new (UDisksDaemon *daemon, - GUdevDevice *device) +/* returns a floating GVariant */ +static GVariant * +calculate_configuration (UDisksLinuxBlock *block, + UDisksDaemon *daemon, + gboolean include_secrets, + GError **error) { - g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL); - return UDISKS_LINUX_BLOCK (g_object_new (UDISKS_TYPE_LINUX_BLOCK, - "daemon", daemon, - "device", device, - NULL)); + GList *entries; + GList *l; + GVariantBuilder builder; + GVariant *ret; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = NULL; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa{sv})")); + /* First the /etc/fstab entries */ + entries = find_fstab_entries_for_device (block, daemon); + for (l = entries; l != NULL; l = l->next) + { + UDisksFstabEntry *entry = UDISKS_FSTAB_ENTRY (l->data); + GVariantBuilder dict_builder; + g_variant_builder_init (&dict_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&dict_builder, "{sv}", "fsname", + g_variant_new_bytestring (udisks_fstab_entry_get_fsname (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "dir", + g_variant_new_bytestring (udisks_fstab_entry_get_dir (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "type", + g_variant_new_bytestring (udisks_fstab_entry_get_fstype (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "opts", + g_variant_new_bytestring (udisks_fstab_entry_get_opts (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "freq", + g_variant_new_int32 (udisks_fstab_entry_get_freq (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "passno", + g_variant_new_int32 (udisks_fstab_entry_get_passno (entry))); + g_variant_builder_add (&builder, + "(sa{sv})", + "fstab", &dict_builder); + } + g_list_foreach (entries, (GFunc) g_object_unref, NULL); + g_list_free (entries); + + /* Then the /etc/crypttab entries */ + entries = find_crypttab_entries_for_device (block, daemon); + for (l = entries; l != NULL; l = l->next) + { + UDisksCrypttabEntry *entry = UDISKS_CRYPTTAB_ENTRY (l->data); + GVariantBuilder dict_builder; + const gchar *passphrase_path; + const gchar *options; + gchar *passphrase_contents; + gsize passphrase_contents_length; + + passphrase_path = udisks_crypttab_entry_get_passphrase_path (entry); + if (passphrase_path == NULL || g_strcmp0 (passphrase_path, "none") == 0) + passphrase_path = ""; + passphrase_contents = NULL; + if (!(g_strcmp0 (passphrase_path, "") == 0 || g_str_has_prefix (passphrase_path, "/dev"))) + { + if (include_secrets) + { + if (!g_file_get_contents (passphrase_path, + &passphrase_contents, + &passphrase_contents_length, + error)) + { + g_prefix_error (error, + "Error loading secrets from file `%s' referenced in /etc/crypttab entry: ", + passphrase_path); + g_variant_builder_clear (&builder); + g_list_foreach (entries, (GFunc) g_object_unref, NULL); + g_list_free (entries); + goto out; + } + } + } + + options = udisks_crypttab_entry_get_options (entry); + if (options == NULL) + options = ""; + + g_variant_builder_init (&dict_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&dict_builder, "{sv}", "name", + g_variant_new_bytestring (udisks_crypttab_entry_get_name (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "device", + g_variant_new_bytestring (udisks_crypttab_entry_get_device (entry))); + g_variant_builder_add (&dict_builder, "{sv}", "passphrase-path", + g_variant_new_bytestring (passphrase_path)); + if (passphrase_contents != NULL) + { + g_variant_builder_add (&dict_builder, "{sv}", "passphrase-contents", + g_variant_new_bytestring (passphrase_contents)); + } + g_variant_builder_add (&dict_builder, "{sv}", "options", + g_variant_new_bytestring (options)); + g_variant_builder_add (&builder, + "(sa{sv})", + "crypttab", &dict_builder); + if (passphrase_contents != NULL) + { + memset (passphrase_contents, '\0', passphrase_contents_length); + g_free (passphrase_contents); + } + } + g_list_foreach (entries, (GFunc) g_object_unref, NULL); + g_list_free (entries); + + ret = g_variant_builder_end (&builder); + + out: + return ret; } -/** - * udisks_linux_block_get_daemon: - * @block: A #UDisksLinuxBlock. - * - * Gets the daemon used by @block. - * - * Returns: A #UDisksDaemon. Do not free, the object is owned by @block. - */ -UDisksDaemon * -udisks_linux_block_get_daemon (UDisksLinuxBlock *block) +static void +update_configuration (UDisksLinuxBlock *block, + UDisksDaemon *daemon) { - g_return_val_if_fail (UDISKS_IS_LINUX_BLOCK (block), NULL); - return block->daemon; + GVariant *configuration; + GError *error; + + error = NULL; + configuration = calculate_configuration (block, daemon, FALSE, &error); + if (configuration == NULL) + { + udisks_warning ("Error loading configuration: %s (%s, %d)", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + configuration = g_variant_new ("a(sa{sv})", NULL); + } + udisks_block_device_set_configuration (UDISKS_BLOCK_DEVICE (block), configuration); } +/* ---------------------------------------------------------------------------------------------------- */ + /** - * udisks_linux_block_get_device: + * udisks_linux_block_update: * @block: A #UDisksLinuxBlock. + * @object: The enclosing #UDisksLinuxBlockObject instance. * - * Gets the current #GUdevDevice for @block. Connect to - * #GObject::notify to track changes to the #UDisksLinuxBlock:device - * property. - * - * Returns: A #GUdevDevice. Free with g_object_unref(). + * Updates the interface. */ -GUdevDevice * -udisks_linux_block_get_device (UDisksLinuxBlock *block) +void +udisks_linux_block_update (UDisksLinuxBlock *block, + UDisksLinuxBlockObject *object) { - g_return_val_if_fail (UDISKS_IS_LINUX_BLOCK (block), NULL); - return g_object_ref (block->device); -} + UDisksBlockDevice *iface = UDISKS_BLOCK_DEVICE (block); + UDisksDaemon *daemon; + GDBusObjectManagerServer *object_manager; + GUdevDevice *device; + GUdevDeviceNumber dev; + gchar *drive_object_path; + UDisksDrive *drive; + gchar *s; + gboolean is_partition_table; + gboolean is_partition_entry; + const gchar *device_file; + const gchar *const *symlinks; + const gchar *preferred_device_file; -/* ---------------------------------------------------------------------------------------------------- */ + drive = NULL; -typedef gboolean (*HasInterfaceFunc) (UDisksLinuxBlock *block); -typedef void (*ConnectInterfaceFunc) (UDisksLinuxBlock *block); -typedef void (*UpdateInterfaceFunc) (UDisksLinuxBlock *block, - const gchar *uevent_action, - GDBusInterface *interface); + device = udisks_linux_block_object_get_device (object); + if (device == NULL) + goto out; -static void -update_iface (UDisksLinuxBlock *block, - const gchar *uevent_action, - HasInterfaceFunc has_func, - ConnectInterfaceFunc connect_func, - UpdateInterfaceFunc update_func, - GType skeleton_type, - gpointer _interface_pointer) -{ - gboolean has; - gboolean add; - GDBusInterface **interface_pointer = _interface_pointer; - - g_return_if_fail (block != NULL); - g_return_if_fail (has_func != NULL); - g_return_if_fail (update_func != NULL); - g_return_if_fail (g_type_is_a (skeleton_type, G_TYPE_OBJECT)); - g_return_if_fail (g_type_is_a (skeleton_type, G_TYPE_DBUS_INTERFACE)); - g_return_if_fail (interface_pointer != NULL); - g_return_if_fail (*interface_pointer == NULL || G_IS_DBUS_INTERFACE (*interface_pointer)); - - add = FALSE; - has = has_func (block); - if (*interface_pointer == NULL) + daemon = udisks_linux_block_object_get_daemon (object); + object_manager = udisks_daemon_get_object_manager (daemon); + + dev = g_udev_device_get_device_number (device); + device_file = g_udev_device_get_device_file (device); + symlinks = g_udev_device_get_device_file_symlinks (device); + + udisks_block_device_set_device (iface, device_file); + udisks_block_device_set_symlinks (iface, symlinks); + udisks_block_device_set_major (iface, major (dev)); + udisks_block_device_set_minor (iface, minor (dev)); + udisks_block_device_set_size (iface, udisks_daemon_util_block_get_size (device)); + + /* dm-crypt + * + * TODO: this might not be the best way to determine if the device-mapper device + * is a dm-crypt device.. but unfortunately device-mapper keeps all this stuff + * in user-space and wants you to use libdevmapper to obtain it... + */ + udisks_block_device_set_crypto_backing_device (iface, "/"); + if (g_str_has_prefix (g_udev_device_get_name (device), "dm-")) { - if (has) + gchar *dm_uuid; + dm_uuid = get_sysfs_attr (device, "dm/uuid"); + if (dm_uuid != NULL && g_str_has_prefix (dm_uuid, "CRYPT-LUKS1")) { - *interface_pointer = g_object_new (skeleton_type, NULL); - if (connect_func != NULL) - connect_func (block); - add = TRUE; + gchar **slaves; + slaves = udisks_daemon_util_resolve_links (g_udev_device_get_sysfs_path (device), + "slaves"); + if (g_strv_length (slaves) == 1) + { + gchar *slave_object_path; + slave_object_path = find_block_device_by_sysfs_path (object_manager, slaves[0]); + if (slave_object_path != NULL) + { + udisks_block_device_set_crypto_backing_device (iface, slave_object_path); + } + g_free (slave_object_path); + } + g_strfreev (slaves); } + g_free (dm_uuid); } - else + + /* Sort out preferred device... this is what UI shells should + * display. We default to the block device name. + * + * This is mostly for things like device-mapper where device file is + * a name of the form dm-%d and a symlink name conveys more + * information. + */ + preferred_device_file = NULL; + if (g_str_has_prefix (device_file, "/dev/dm-")) { - if (!has) + guint n; + const gchar *dm_name; + gchar *dm_name_dev_file = NULL; + const gchar *dm_name_dev_file_as_symlink = NULL; + + dm_name = g_udev_device_get_property (device, "DM_NAME"); + if (dm_name != NULL) + dm_name_dev_file = g_strdup_printf ("/dev/mapper/%s", dm_name); + for (n = 0; symlinks != NULL && symlinks[n] != NULL; n++) { - g_dbus_object_skeleton_remove_interface (G_DBUS_OBJECT_SKELETON (block), G_DBUS_INTERFACE_SKELETON (*interface_pointer)); - g_object_unref (*interface_pointer); - *interface_pointer = NULL; + if (g_str_has_prefix (symlinks[n], "/dev/vg_")) + { + /* LVM2 */ + preferred_device_file = symlinks[n]; + break; + } + else if (g_strcmp0 (symlinks[n], dm_name_dev_file) == 0) + { + dm_name_dev_file_as_symlink = symlinks[n]; + } } + /* fall back to /dev/mapper/$DM_NAME, if available as a symlink */ + if (preferred_device_file == NULL && dm_name_dev_file_as_symlink != NULL) + preferred_device_file = dm_name_dev_file_as_symlink; + g_free (dm_name_dev_file); + } + /* fallback to the device name */ + if (preferred_device_file == NULL) + preferred_device_file = g_udev_device_get_device_file (device); + udisks_block_device_set_preferred_device (iface, preferred_device_file); + + /* Determine the drive this block device belongs to + * + * TODO: if this is slow we could have a cache or ensure that we + * only do this once or something else + */ + drive_object_path = find_drive (object_manager, device, &drive); + if (drive_object_path != NULL) + { + udisks_block_device_set_drive (iface, drive_object_path); + g_free (drive_object_path); + } + else + { + udisks_block_device_set_drive (iface, "/"); + } + + udisks_block_device_set_id_usage (iface, g_udev_device_get_property (device, "ID_FS_USAGE")); + udisks_block_device_set_id_type (iface, g_udev_device_get_property (device, "ID_FS_TYPE")); + s = udisks_decode_udev_string (g_udev_device_get_property (device, "ID_FS_VERSION")); + udisks_block_device_set_id_version (iface, s); + g_free (s); + s = udisks_decode_udev_string (g_udev_device_get_property (device, "ID_FS_LABEL_ENC")); + udisks_block_device_set_id_label (iface, s); + g_free (s); + s = udisks_decode_udev_string (g_udev_device_get_property (device, "ID_FS_UUID_ENC")); + udisks_block_device_set_id_uuid (iface, s); + g_free (s); + + /* TODO: port this to blkid properties */ + + /* Update the partition table and partition entry properties */ + is_partition_table = FALSE; + is_partition_entry = FALSE; + if (g_strcmp0 (g_udev_device_get_devtype (device), "partition") == 0 || + g_udev_device_get_property_as_boolean (device, "UDISKS_PARTITION")) + { + is_partition_entry = TRUE; + } + else if (g_udev_device_get_property_as_boolean (device, "UDISKS_PARTITION_TABLE")) + { + is_partition_table = TRUE; + } + + /* partition table */ + if (is_partition_table) + { + udisks_block_device_set_part_table (iface, TRUE); + udisks_block_device_set_part_table_scheme (iface, + g_udev_device_get_property (device, + "UDISKS_PARTITION_TABLE_SCHEME")); + } + else + { + udisks_block_device_set_part_table (iface, FALSE); + udisks_block_device_set_part_table_scheme (iface, ""); } - if (*interface_pointer != NULL) + /* partition entry */ + if (is_partition_entry) + { + gchar *slave_sysfs_path; + udisks_block_device_set_part_entry (iface, TRUE); + udisks_block_device_set_part_entry_scheme (iface, + g_udev_device_get_property (device, + "UDISKS_PARTITION_SCHEME")); + udisks_block_device_set_part_entry_number (iface, + g_udev_device_get_property_as_int (device, + "UDISKS_PARTITION_NUMBER")); + udisks_block_device_set_part_entry_type (iface, + g_udev_device_get_property (device, + "UDISKS_PARTITION_TYPE")); + udisks_block_device_set_part_entry_flags (iface, + g_udev_device_get_property (device, + "UDISKS_PARTITION_FLAGS")); + udisks_block_device_set_part_entry_label (iface, + g_udev_device_get_property (device, + "UDISKS_PARTITION_LABEL")); + udisks_block_device_set_part_entry_uuid (iface, + g_udev_device_get_property (device, + "UDISKS_PARTITION_UUID")); + slave_sysfs_path = g_strdup (g_udev_device_get_property (device, "UDISKS_PARTITION_SLAVE")); + if (slave_sysfs_path == NULL) + { + if (g_strcmp0 (g_udev_device_get_devtype (device), "partition") == 0) + { + GUdevDevice *parent; + parent = g_udev_device_get_parent (device); + slave_sysfs_path = g_strdup (g_udev_device_get_sysfs_path (parent)); + g_object_unref (parent); + } + else + { + g_warning ("No UDISKS_PARTITION_SLAVE property and DEVTYPE is not partition for block device %s", + g_udev_device_get_sysfs_path (device)); + } + } + if (slave_sysfs_path != NULL) + { + gchar *slave_object_path; + slave_object_path = find_block_device_by_sysfs_path (object_manager, slave_sysfs_path); + if (slave_object_path != NULL) + udisks_block_device_set_part_entry_table (iface, slave_object_path); + else + udisks_block_device_set_part_entry_table (iface, "/"); + g_free (slave_object_path); + g_free (slave_sysfs_path); + } + else + { + udisks_block_device_set_part_entry_table (iface, "/"); + } + udisks_block_device_set_part_entry_offset (iface, + g_udev_device_get_property_as_uint64 (device, + "UDISKS_PARTITION_OFFSET")); + udisks_block_device_set_part_entry_size (iface, + g_udev_device_get_property_as_uint64 (device, + "UDISKS_PARTITION_SIZE")); + } + else { - update_func (block, uevent_action, G_DBUS_INTERFACE (*interface_pointer)); - if (add) - g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (block), G_DBUS_INTERFACE_SKELETON (*interface_pointer)); + udisks_block_device_set_part_entry (iface, FALSE); + udisks_block_device_set_part_entry_scheme (iface, ""); + udisks_block_device_set_part_entry_type (iface, ""); + udisks_block_device_set_part_entry_flags (iface, ""); + udisks_block_device_set_part_entry_table (iface, "/"); + udisks_block_device_set_part_entry_offset (iface, 0); + udisks_block_device_set_part_entry_size (iface, 0); } + + update_hints (block, device, drive); + update_configuration (block, daemon); + + out: + if (device != NULL) + g_object_unref (device); + if (drive != NULL) + g_object_unref (drive); } /* ---------------------------------------------------------------------------------------------------- */ -static GVariant *calculate_configuration (UDisksLinuxBlock *block, - gboolean include_secrets, - GError **error); - static gboolean -on_get_secret_configuration (UDisksBlockDevice *block, - GDBusMethodInvocation *invocation, - GVariant *options, - gpointer user_data) +handle_get_secret_configuration (UDisksBlockDevice *_block, + GDBusMethodInvocation *invocation, + GVariant *options) { - UDisksLinuxBlock *object = UDISKS_LINUX_BLOCK (user_data); + UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (_block); + UDisksLinuxBlockObject *object; + UDisksDaemon *daemon; GVariant *configuration; GError *error; + object = UDISKS_LINUX_BLOCK_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))); + daemon = udisks_linux_block_object_get_daemon (object); + error = NULL; - configuration = calculate_configuration (object, TRUE, &error); + configuration = calculate_configuration (block, daemon, TRUE, &error); if (configuration == NULL) { g_dbus_method_invocation_take_error (invocation, error); goto out; } - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.read-system-configuration-secrets", options, @@ -411,7 +856,8 @@ on_get_secret_configuration (UDisksBlockDevice *block, goto out; } - udisks_block_device_complete_get_secret_configuration (object->iface_block_device, invocation, + udisks_block_device_complete_get_secret_configuration (UDISKS_BLOCK_DEVICE (block), + invocation, configuration); /* consumes floating ref */ out: @@ -1002,22 +1448,25 @@ add_remove_crypttab_entry (GVariant *remove, /* ---------------------------------------------------------------------------------------------------- */ static gboolean -on_add_configuration_item (UDisksBlockDevice *block, - GDBusMethodInvocation *invocation, - GVariant *item, - GVariant *options, - gpointer user_data) +handle_add_configuration_item (UDisksBlockDevice *_block, + GDBusMethodInvocation *invocation, + GVariant *item, + GVariant *options) { - UDisksLinuxBlock *object = UDISKS_LINUX_BLOCK (user_data); + UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (_block); + UDisksLinuxBlockObject *object; + UDisksDaemon *daemon; const gchar *type; GVariant *details; GError *error; - g_variant_get (item, "(&s@a{sv})", &type, &details); + object = UDISKS_LINUX_BLOCK_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))); + daemon = udisks_linux_block_object_get_daemon (object); + g_variant_get (item, "(&s@a{sv})", &type, &details); if (g_strcmp0 (type, "fstab") == 0) { - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.modify-system-configuration", options, @@ -1030,11 +1479,11 @@ on_add_configuration_item (UDisksBlockDevice *block, g_dbus_method_invocation_take_error (invocation, error); goto out; } - udisks_block_device_complete_add_configuration_item (block, invocation); + udisks_block_device_complete_add_configuration_item (UDISKS_BLOCK_DEVICE (block), invocation); } else if (g_strcmp0 (type, "crypttab") == 0) { - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.modify-system-configuration", options, @@ -1047,7 +1496,7 @@ on_add_configuration_item (UDisksBlockDevice *block, g_dbus_method_invocation_take_error (invocation, error); goto out; } - udisks_block_device_complete_add_configuration_item (block, invocation); + udisks_block_device_complete_add_configuration_item (UDISKS_BLOCK_DEVICE (block), invocation); } else { @@ -1063,23 +1512,28 @@ on_add_configuration_item (UDisksBlockDevice *block, return TRUE; /* returning TRUE means that we handled the method invocation */ } +/* ---------------------------------------------------------------------------------------------------- */ + static gboolean -on_remove_configuration_item (UDisksBlockDevice *block, - GDBusMethodInvocation *invocation, - GVariant *item, - GVariant *options, - gpointer user_data) +handle_remove_configuration_item (UDisksBlockDevice *_block, + GDBusMethodInvocation *invocation, + GVariant *item, + GVariant *options) { - UDisksLinuxBlock *object = UDISKS_LINUX_BLOCK (user_data); + UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (_block); + UDisksLinuxBlockObject *object; + UDisksDaemon *daemon; const gchar *type; GVariant *details; GError *error; - g_variant_get (item, "(&s@a{sv})", &type, &details); + object = UDISKS_LINUX_BLOCK_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))); + daemon = udisks_linux_block_object_get_daemon (object); + g_variant_get (item, "(&s@a{sv})", &type, &details); if (g_strcmp0 (type, "fstab") == 0) { - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.modify-system-configuration", options, @@ -1092,11 +1546,11 @@ on_remove_configuration_item (UDisksBlockDevice *block, g_dbus_method_invocation_take_error (invocation, error); goto out; } - udisks_block_device_complete_add_configuration_item (block, invocation); + udisks_block_device_complete_add_configuration_item (UDISKS_BLOCK_DEVICE (block), invocation); } else if (g_strcmp0 (type, "crypttab") == 0) { - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.modify-system-configuration", options, @@ -1109,7 +1563,7 @@ on_remove_configuration_item (UDisksBlockDevice *block, g_dbus_method_invocation_take_error (invocation, error); goto out; } - udisks_block_device_complete_add_configuration_item (block, invocation); + udisks_block_device_complete_add_configuration_item (UDISKS_BLOCK_DEVICE (block), invocation); } else { @@ -1125,21 +1579,27 @@ on_remove_configuration_item (UDisksBlockDevice *block, return TRUE; /* returning TRUE means that we handled the method invocation */ } +/* ---------------------------------------------------------------------------------------------------- */ + static gboolean -on_update_configuration_item (UDisksBlockDevice *block, - GDBusMethodInvocation *invocation, - GVariant *old_item, - GVariant *new_item, - GVariant *options, - gpointer user_data) +handle_update_configuration_item (UDisksBlockDevice *_block, + GDBusMethodInvocation *invocation, + GVariant *old_item, + GVariant *new_item, + GVariant *options) { - UDisksLinuxBlock *object = UDISKS_LINUX_BLOCK (user_data); + UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (_block); + UDisksLinuxBlockObject *object; + UDisksDaemon *daemon; const gchar *old_type; const gchar *new_type; GVariant *old_details; GVariant *new_details; GError *error; + object = UDISKS_LINUX_BLOCK_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))); + daemon = udisks_linux_block_object_get_daemon (object); + g_variant_get (old_item, "(&s@a{sv})", &old_type, &old_details); g_variant_get (new_item, "(&s@a{sv})", &new_type, &new_details); if (g_strcmp0 (old_type, new_type) != 0) @@ -1153,7 +1613,7 @@ on_update_configuration_item (UDisksBlockDevice *block, if (g_strcmp0 (old_type, "fstab") == 0) { - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.modify-system-configuration", options, @@ -1166,11 +1626,11 @@ on_update_configuration_item (UDisksBlockDevice *block, g_dbus_method_invocation_take_error (invocation, error); goto out; } - udisks_block_device_complete_add_configuration_item (block, invocation); + udisks_block_device_complete_add_configuration_item (UDISKS_BLOCK_DEVICE (block), invocation); } else if (g_strcmp0 (old_type, "crypttab") == 0) { - if (!udisks_daemon_util_check_authorization_sync (object->daemon, + if (!udisks_daemon_util_check_authorization_sync (daemon, NULL, "org.freedesktop.udisks2.modify-system-configuration", options, @@ -1183,7 +1643,7 @@ on_update_configuration_item (UDisksBlockDevice *block, g_dbus_method_invocation_take_error (invocation, error); goto out; } - udisks_block_device_complete_add_configuration_item (block, invocation); + udisks_block_device_complete_add_configuration_item (UDISKS_BLOCK_DEVICE (block), invocation); } else { @@ -1201,968 +1661,12 @@ on_update_configuration_item (UDisksBlockDevice *block, } /* ---------------------------------------------------------------------------------------------------- */ -/* org.freedesktop.UDisks.BlockDevice */ - -static gboolean -block_device_check (UDisksLinuxBlock *block) -{ - return TRUE; -} - -static void -block_device_connect (UDisksLinuxBlock *block) -{ - g_signal_connect (block->iface_block_device, - "handle-get-secret-configuration", - G_CALLBACK (on_get_secret_configuration), - block); - g_signal_connect (block->iface_block_device, - "handle-add-configuration-item", - G_CALLBACK (on_add_configuration_item), - block); - g_signal_connect (block->iface_block_device, - "handle-remove-configuration-item", - G_CALLBACK (on_remove_configuration_item), - block); - g_signal_connect (block->iface_block_device, - "handle-update-configuration-item", - G_CALLBACK (on_update_configuration_item), - block); -} - -static gchar * -find_drive (GDBusObjectManagerServer *object_manager, - GUdevDevice *block_device, - UDisksDrive **out_drive) -{ - GUdevDevice *whole_disk_block_device; - const gchar *whole_disk_block_device_sysfs_path; - gchar *ret; - GList *objects; - GList *l; - - ret = NULL; - - if (g_strcmp0 (g_udev_device_get_devtype (block_device), "disk") == 0) - whole_disk_block_device = g_object_ref (block_device); - else - whole_disk_block_device = g_udev_device_get_parent_with_subsystem (block_device, "block", "disk"); - whole_disk_block_device_sysfs_path = g_udev_device_get_sysfs_path (whole_disk_block_device); - - objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); - for (l = objects; l != NULL; l = l->next) - { - GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (l->data); - GList *drive_devices; - GList *j; - - if (!UDISKS_IS_LINUX_DRIVE_OBJECT (object)) - continue; - - drive_devices = udisks_linux_drive_object_get_devices (UDISKS_LINUX_DRIVE_OBJECT (object)); - for (j = drive_devices; j != NULL; j = j->next) - { - GUdevDevice *drive_device = G_UDEV_DEVICE (j->data); - const gchar *drive_sysfs_path; - - drive_sysfs_path = g_udev_device_get_sysfs_path (drive_device); - if (g_strcmp0 (whole_disk_block_device_sysfs_path, drive_sysfs_path) == 0) - { - if (out_drive != NULL) - *out_drive = udisks_object_get_drive (UDISKS_OBJECT (object)); - ret = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); - g_list_foreach (drive_devices, (GFunc) g_object_unref, NULL); - g_list_free (drive_devices); - goto out; - } - } - g_list_foreach (drive_devices, (GFunc) g_object_unref, NULL); - g_list_free (drive_devices); - } - - out: - g_list_foreach (objects, (GFunc) g_object_unref, NULL); - g_list_free (objects); - g_object_unref (whole_disk_block_device); - return ret; -} - -static gchar * -find_block_device_by_sysfs_path (GDBusObjectManagerServer *object_manager, - const gchar *sysfs_path) -{ - gchar *ret; - GList *objects; - GList *l; - - ret = NULL; - - objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager)); - for (l = objects; l != NULL; l = l->next) - { - GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (l->data); - UDisksLinuxBlock *block; - - if (!UDISKS_IS_LINUX_BLOCK (object)) - continue; - - block = UDISKS_LINUX_BLOCK (object); - - if (g_strcmp0 (sysfs_path, g_udev_device_get_sysfs_path (block->device)) == 0) - { - ret = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); - goto out; - } - } - - out: - g_list_foreach (objects, (GFunc) g_object_unref, NULL); - g_list_free (objects); - return ret; -} - -static gchar * -get_sysfs_attr (GUdevDevice *device, - const gchar *attr) -{ - gchar *filename; - gchar *value; - filename = g_strconcat (g_udev_device_get_sysfs_path (device), - "/", - attr, - NULL); - value = NULL; - /* don't care about errors */ - g_file_get_contents (filename, - &value, - NULL, - NULL); - g_free (filename); - return value; -} - -static void -block_device_update_hints (UDisksLinuxBlock *block, - const gchar *uevent_action, - UDisksBlockDevice *iface, - const gchar *device_file, - UDisksDrive *drive) -{ - gboolean hint_system; - gboolean hint_ignore; - gboolean hint_auto; - const gchar *hint_name; - const gchar *hint_icon_name; - - /* very conservative defaults */ - hint_system = TRUE; - hint_ignore = FALSE; - hint_auto = FALSE; - hint_name = NULL; - hint_icon_name = NULL; - - /* Provide easy access to _only_ the following devices - * - * - anything connected via known local buses (e.g. USB or Firewire, MMC or MemoryStick) - * - any device with removable media - * - * Be careful when extending this list as we don't want to automount - * the world when (inadvertently) connecting to a SAN. - */ - if (drive != NULL) - { - const gchar *connection_bus; - gboolean removable; - connection_bus = udisks_drive_get_connection_bus (drive); - removable = udisks_drive_get_media_removable (drive); - if (removable || - (g_strcmp0 (connection_bus, "usb") == 0 || g_strcmp0 (connection_bus, "firewire") == 0) || - (g_str_has_prefix (device_file, "/dev/mmcblk") || g_str_has_prefix (device_file, "/dev/mspblk"))) - { - hint_system = FALSE; - hint_auto = TRUE; - } - } - - /* TODO: set ignore to TRUE for physical paths belonging to a drive with multiple paths */ - - /* override from udev properties */ - if (g_udev_device_has_property (block->device, "UDISKS_SYSTEM")) - hint_system = g_udev_device_get_property_as_boolean (block->device, "UDISKS_SYSTEM"); - if (g_udev_device_has_property (block->device, "UDISKS_IGNORE")) - hint_ignore = g_udev_device_get_property_as_boolean (block->device, "UDISKS_IGNORE"); - if (g_udev_device_has_property (block->device, "UDISKS_AUTO")) - hint_auto = g_udev_device_get_property_as_boolean (block->device, "UDISKS_AUTO"); - if (g_udev_device_has_property (block->device, "UDISKS_NAME")) - hint_name = g_udev_device_get_property (block->device, "UDISKS_NAME"); - if (g_udev_device_has_property (block->device, "UDISKS_ICON_NAME")) - hint_icon_name = g_udev_device_get_property (block->device, "UDISKS_ICON_NAME"); - - /* ... and scene! */ - udisks_block_device_set_hint_system (iface, hint_system); - udisks_block_device_set_hint_ignore (iface, hint_ignore); - udisks_block_device_set_hint_auto (iface, hint_auto); - udisks_block_device_set_hint_name (iface, hint_name); - udisks_block_device_set_hint_icon_name (iface, hint_icon_name); -} - -static GList * -find_fstab_entries_for_device (UDisksLinuxBlock *block) -{ - GList *entries; - GList *l; - GList *ret; - - ret = NULL; - - /* if this is too slow, we could add lookup methods to UDisksFstabMonitor... */ - entries = udisks_fstab_monitor_get_entries (udisks_daemon_get_fstab_monitor (block->daemon)); - for (l = entries; l != NULL; l = l->next) - { - UDisksFstabEntry *entry = UDISKS_FSTAB_ENTRY (l->data); - const gchar *const *symlinks; - const gchar *fsname; - gchar *device; - guint n; - - fsname = udisks_fstab_entry_get_fsname (entry); - device = NULL; - if (g_str_has_prefix (fsname, "UUID=")) - { - device = g_strdup_printf ("/dev/disk/by-uuid/%s", fsname + 5); - } - else if (g_str_has_prefix (fsname, "LABEL=")) - { - device = g_strdup_printf ("/dev/disk/by-label/%s", fsname + 6); - } - else if (g_str_has_prefix (fsname, "/dev")) - { - device = g_strdup (fsname); - } - else - { - /* ignore non-device entries */ - goto continue_loop; - } - - if (g_strcmp0 (device, udisks_block_device_get_device (block->iface_block_device)) == 0) - { - ret = g_list_prepend (ret, g_object_ref (entry)); - } - else - { - symlinks = udisks_block_device_get_symlinks (block->iface_block_device); - if (symlinks != NULL) - { - for (n = 0; symlinks[n] != NULL; n++) - { - if (g_strcmp0 (device, symlinks[n]) == 0) - { - ret = g_list_prepend (ret, g_object_ref (entry)); - } - } - } - } - - continue_loop: - g_free (device); - } - - g_list_foreach (entries, (GFunc) g_object_unref, NULL); - g_list_free (entries); - return ret; -} - -static GList * -find_crypttab_entries_for_device (UDisksLinuxBlock *block) -{ - GList *entries; - GList *l; - GList *ret; - - ret = NULL; - - /* if this is too slow, we could add lookup methods to UDisksCrypttabMonitor... */ - entries = udisks_crypttab_monitor_get_entries (udisks_daemon_get_crypttab_monitor (block->daemon)); - for (l = entries; l != NULL; l = l->next) - { - UDisksCrypttabEntry *entry = UDISKS_CRYPTTAB_ENTRY (l->data); - const gchar *const *symlinks; - const gchar *device_in_entry; - gchar *device; - guint n; - - device_in_entry = udisks_crypttab_entry_get_device (entry); - device = NULL; - if (g_str_has_prefix (device_in_entry, "UUID=")) - { - device = g_strdup_printf ("/dev/disk/by-uuid/%s", device_in_entry + 5); - } - else if (g_str_has_prefix (device_in_entry, "LABEL=")) - { - device = g_strdup_printf ("/dev/disk/by-label/%s", device_in_entry + 6); - } - else if (g_str_has_prefix (device_in_entry, "/dev")) - { - device = g_strdup (device_in_entry); - } - else - { - /* ignore non-device entries */ - goto continue_loop; - } - - if (g_strcmp0 (device, udisks_block_device_get_device (block->iface_block_device)) == 0) - { - ret = g_list_prepend (ret, g_object_ref (entry)); - } - else - { - symlinks = udisks_block_device_get_symlinks (block->iface_block_device); - if (symlinks != NULL) - { - for (n = 0; symlinks[n] != NULL; n++) - { - if (g_strcmp0 (device, symlinks[n]) == 0) - { - ret = g_list_prepend (ret, g_object_ref (entry)); - } - } - } - } - - continue_loop: - g_free (device); - } - - g_list_foreach (entries, (GFunc) g_object_unref, NULL); - g_list_free (entries); - return ret; -} - -/* returns a floating GVariant */ -static GVariant * -calculate_configuration (UDisksLinuxBlock *block, - gboolean include_secrets, - GError **error) -{ - GList *entries; - GList *l; - GVariantBuilder builder; - GVariant *ret; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - ret = NULL; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa{sv})")); - /* First the /etc/fstab entries */ - entries = find_fstab_entries_for_device (block); - for (l = entries; l != NULL; l = l->next) - { - UDisksFstabEntry *entry = UDISKS_FSTAB_ENTRY (l->data); - GVariantBuilder dict_builder; - g_variant_builder_init (&dict_builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&dict_builder, "{sv}", "fsname", - g_variant_new_bytestring (udisks_fstab_entry_get_fsname (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "dir", - g_variant_new_bytestring (udisks_fstab_entry_get_dir (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "type", - g_variant_new_bytestring (udisks_fstab_entry_get_fstype (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "opts", - g_variant_new_bytestring (udisks_fstab_entry_get_opts (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "freq", - g_variant_new_int32 (udisks_fstab_entry_get_freq (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "passno", - g_variant_new_int32 (udisks_fstab_entry_get_passno (entry))); - g_variant_builder_add (&builder, - "(sa{sv})", - "fstab", &dict_builder); - } - g_list_foreach (entries, (GFunc) g_object_unref, NULL); - g_list_free (entries); - - /* Then the /etc/crypttab entries */ - entries = find_crypttab_entries_for_device (block); - for (l = entries; l != NULL; l = l->next) - { - UDisksCrypttabEntry *entry = UDISKS_CRYPTTAB_ENTRY (l->data); - GVariantBuilder dict_builder; - const gchar *passphrase_path; - const gchar *options; - gchar *passphrase_contents; - gsize passphrase_contents_length; - - passphrase_path = udisks_crypttab_entry_get_passphrase_path (entry); - if (passphrase_path == NULL || g_strcmp0 (passphrase_path, "none") == 0) - passphrase_path = ""; - passphrase_contents = NULL; - if (!(g_strcmp0 (passphrase_path, "") == 0 || g_str_has_prefix (passphrase_path, "/dev"))) - { - if (include_secrets) - { - if (!g_file_get_contents (passphrase_path, - &passphrase_contents, - &passphrase_contents_length, - error)) - { - g_prefix_error (error, - "Error loading secrets from file `%s' referenced in /etc/crypttab entry: ", - passphrase_path); - g_variant_builder_clear (&builder); - g_list_foreach (entries, (GFunc) g_object_unref, NULL); - g_list_free (entries); - goto out; - } - } - } - - options = udisks_crypttab_entry_get_options (entry); - if (options == NULL) - options = ""; - - g_variant_builder_init (&dict_builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&dict_builder, "{sv}", "name", - g_variant_new_bytestring (udisks_crypttab_entry_get_name (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "device", - g_variant_new_bytestring (udisks_crypttab_entry_get_device (entry))); - g_variant_builder_add (&dict_builder, "{sv}", "passphrase-path", - g_variant_new_bytestring (passphrase_path)); - if (passphrase_contents != NULL) - { - g_variant_builder_add (&dict_builder, "{sv}", "passphrase-contents", - g_variant_new_bytestring (passphrase_contents)); - } - g_variant_builder_add (&dict_builder, "{sv}", "options", - g_variant_new_bytestring (options)); - g_variant_builder_add (&builder, - "(sa{sv})", - "crypttab", &dict_builder); - if (passphrase_contents != NULL) - { - memset (passphrase_contents, '\0', passphrase_contents_length); - g_free (passphrase_contents); - } - } - g_list_foreach (entries, (GFunc) g_object_unref, NULL); - g_list_free (entries); - - ret = g_variant_builder_end (&builder); - - out: - return ret; -} - -static void -block_device_update_configuration (UDisksLinuxBlock *block, - const gchar *uevent_action, - UDisksBlockDevice *iface, - const gchar *device_file, - UDisksDrive *drive) -{ - GVariant *configuration; - GError *error; - - error = NULL; - configuration = calculate_configuration (block, FALSE, &error); - if (configuration == NULL) - { - udisks_warning ("Error loading configuration: %s (%s, %d)", - error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - configuration = g_variant_new ("a(sa{sv})", NULL); - } - udisks_block_device_set_configuration (block->iface_block_device, configuration); -} - -static void -block_device_update (UDisksLinuxBlock *block, - const gchar *uevent_action, - GDBusInterface *_iface) -{ - UDisksBlockDevice *iface = UDISKS_BLOCK_DEVICE (_iface); - GUdevDeviceNumber dev; - GDBusObjectManagerServer *object_manager; - gchar *drive_object_path; - UDisksDrive *drive; - gchar *s; - gboolean is_partition_table; - gboolean is_partition_entry; - const gchar *device_file; - const gchar *const *symlinks; - const gchar *preferred_device_file; - - drive = NULL; - - dev = g_udev_device_get_device_number (block->device); - device_file = g_udev_device_get_device_file (block->device); - symlinks = g_udev_device_get_device_file_symlinks (block->device); - - udisks_block_device_set_device (iface, device_file); - udisks_block_device_set_symlinks (iface, symlinks); - udisks_block_device_set_major (iface, major (dev)); - udisks_block_device_set_minor (iface, minor (dev)); - udisks_block_device_set_size (iface, udisks_daemon_util_block_get_size (block->device)); - - /* dm-crypt - * - * TODO: this might not be the best way to determine if the device-mapper device - * is a dm-crypt device.. but unfortunately device-mapper keeps all this stuff - * in user-space and wants you to use libdevmapper to obtain it... - */ - udisks_block_device_set_crypto_backing_device (iface, "/"); - if (g_str_has_prefix (g_udev_device_get_name (block->device), "dm-")) - { - gchar *dm_uuid; - dm_uuid = get_sysfs_attr (block->device, "dm/uuid"); - if (dm_uuid != NULL && g_str_has_prefix (dm_uuid, "CRYPT-LUKS1")) - { - gchar **slaves; - slaves = udisks_daemon_util_resolve_links (g_udev_device_get_sysfs_path (block->device), - "slaves"); - if (g_strv_length (slaves) == 1) - { - gchar *slave_object_path; - slave_object_path = find_block_device_by_sysfs_path (udisks_daemon_get_object_manager (block->daemon), - slaves[0]); - if (slave_object_path != NULL) - { - udisks_block_device_set_crypto_backing_device (iface, slave_object_path); - } - g_free (slave_object_path); - } - g_strfreev (slaves); - } - g_free (dm_uuid); - } - - /* Sort out preferred device... this is what UI shells should - * display. We default to the block device name. - * - * This is mostly for things like device-mapper where device file is - * a name of the form dm-%d and a symlink name conveys more - * information. - */ - preferred_device_file = NULL; - if (g_str_has_prefix (device_file, "/dev/dm-")) - { - guint n; - const gchar *dm_name; - gchar *dm_name_dev_file = NULL; - const gchar *dm_name_dev_file_as_symlink = NULL; - - dm_name = g_udev_device_get_property (block->device, "DM_NAME"); - if (dm_name != NULL) - dm_name_dev_file = g_strdup_printf ("/dev/mapper/%s", dm_name); - for (n = 0; symlinks != NULL && symlinks[n] != NULL; n++) - { - if (g_str_has_prefix (symlinks[n], "/dev/vg_")) - { - /* LVM2 */ - preferred_device_file = symlinks[n]; - break; - } - else if (g_strcmp0 (symlinks[n], dm_name_dev_file) == 0) - { - dm_name_dev_file_as_symlink = symlinks[n]; - } - } - /* fall back to /dev/mapper/$DM_NAME, if available as a symlink */ - if (preferred_device_file == NULL && dm_name_dev_file_as_symlink != NULL) - preferred_device_file = dm_name_dev_file_as_symlink; - g_free (dm_name_dev_file); - } - /* fallback to the device name */ - if (preferred_device_file == NULL) - preferred_device_file = g_udev_device_get_device_file (block->device); - udisks_block_device_set_preferred_device (iface, preferred_device_file); - - /* Determine the drive this block device belongs to - * - * TODO: if this is slow we could have a cache or ensure that we - * only do this once or something else - */ - object_manager = udisks_daemon_get_object_manager (block->daemon); - drive_object_path = find_drive (object_manager, block->device, &drive); - if (drive_object_path != NULL) - { - udisks_block_device_set_drive (iface, drive_object_path); - g_free (drive_object_path); - } - else - { - udisks_block_device_set_drive (iface, "/"); - } - - udisks_block_device_set_id_usage (iface, g_udev_device_get_property (block->device, "ID_FS_USAGE")); - udisks_block_device_set_id_type (iface, g_udev_device_get_property (block->device, "ID_FS_TYPE")); - s = udisks_decode_udev_string (g_udev_device_get_property (block->device, "ID_FS_VERSION")); - udisks_block_device_set_id_version (iface, s); - g_free (s); - s = udisks_decode_udev_string (g_udev_device_get_property (block->device, "ID_FS_LABEL_ENC")); - udisks_block_device_set_id_label (iface, s); - g_free (s); - s = udisks_decode_udev_string (g_udev_device_get_property (block->device, "ID_FS_UUID_ENC")); - udisks_block_device_set_id_uuid (iface, s); - g_free (s); - - /* TODO: port this to blkid properties */ - - /* Update the partition table and partition entry properties */ - is_partition_table = FALSE; - is_partition_entry = FALSE; - if (g_strcmp0 (g_udev_device_get_devtype (block->device), "partition") == 0 || - g_udev_device_get_property_as_boolean (block->device, "UDISKS_PARTITION")) - { - is_partition_entry = TRUE; - } - else if (g_udev_device_get_property_as_boolean (block->device, "UDISKS_PARTITION_TABLE")) - { - is_partition_table = TRUE; - } - - /* partition table */ - if (is_partition_table) - { - udisks_block_device_set_part_table (iface, TRUE); - udisks_block_device_set_part_table_scheme (iface, - g_udev_device_get_property (block->device, - "UDISKS_PARTITION_TABLE_SCHEME")); - } - else - { - udisks_block_device_set_part_table (iface, FALSE); - udisks_block_device_set_part_table_scheme (iface, ""); - } - - /* partition entry */ - if (is_partition_entry) - { - gchar *slave_sysfs_path; - udisks_block_device_set_part_entry (iface, TRUE); - udisks_block_device_set_part_entry_scheme (iface, - g_udev_device_get_property (block->device, - "UDISKS_PARTITION_SCHEME")); - udisks_block_device_set_part_entry_number (iface, - g_udev_device_get_property_as_int (block->device, - "UDISKS_PARTITION_NUMBER")); - udisks_block_device_set_part_entry_type (iface, - g_udev_device_get_property (block->device, - "UDISKS_PARTITION_TYPE")); - udisks_block_device_set_part_entry_flags (iface, - g_udev_device_get_property (block->device, - "UDISKS_PARTITION_FLAGS")); - udisks_block_device_set_part_entry_label (iface, - g_udev_device_get_property (block->device, - "UDISKS_PARTITION_LABEL")); - udisks_block_device_set_part_entry_uuid (iface, - g_udev_device_get_property (block->device, - "UDISKS_PARTITION_UUID")); - slave_sysfs_path = g_strdup (g_udev_device_get_property (block->device, "UDISKS_PARTITION_SLAVE")); - if (slave_sysfs_path == NULL) - { - if (g_strcmp0 (g_udev_device_get_devtype (block->device), "partition") == 0) - { - GUdevDevice *parent; - parent = g_udev_device_get_parent (block->device); - slave_sysfs_path = g_strdup (g_udev_device_get_sysfs_path (parent)); - g_object_unref (parent); - } - else - { - g_warning ("No UDISKS_PARTITION_SLAVE property and DEVTYPE is not partition for block device %s", - g_udev_device_get_sysfs_path (block->device)); - } - } - if (slave_sysfs_path != NULL) - { - gchar *slave_object_path; - slave_object_path = find_block_device_by_sysfs_path (udisks_daemon_get_object_manager (block->daemon), - slave_sysfs_path); - if (slave_object_path != NULL) - udisks_block_device_set_part_entry_table (iface, slave_object_path); - else - udisks_block_device_set_part_entry_table (iface, "/"); - g_free (slave_object_path); - g_free (slave_sysfs_path); - } - else - { - udisks_block_device_set_part_entry_table (iface, "/"); - } - udisks_block_device_set_part_entry_offset (iface, - g_udev_device_get_property_as_uint64 (block->device, - "UDISKS_PARTITION_OFFSET")); - udisks_block_device_set_part_entry_size (iface, - g_udev_device_get_property_as_uint64 (block->device, - "UDISKS_PARTITION_SIZE")); - } - else - { - udisks_block_device_set_part_entry (iface, FALSE); - udisks_block_device_set_part_entry_scheme (iface, ""); - udisks_block_device_set_part_entry_type (iface, ""); - udisks_block_device_set_part_entry_flags (iface, ""); - udisks_block_device_set_part_entry_table (iface, "/"); - udisks_block_device_set_part_entry_offset (iface, 0); - udisks_block_device_set_part_entry_size (iface, 0); - } - - block_device_update_hints (block, uevent_action, iface, device_file, drive); - block_device_update_configuration (block, uevent_action, iface, device_file, drive); - - if (drive != NULL) - g_object_unref (drive); -} - -/* ---------------------------------------------------------------------------------------------------- */ -/* org.freedesktop.UDisks.Filesystem */ - -static gboolean -filesystem_check (UDisksLinuxBlock *block) -{ - gboolean ret; - UDisksMountType mount_type; - - ret = FALSE; - if (g_strcmp0 (udisks_block_device_get_id_usage (block->iface_block_device), "filesystem") == 0 || - (udisks_mount_monitor_is_dev_in_use (block->mount_monitor, - g_udev_device_get_device_number (block->device), - &mount_type) && - mount_type == UDISKS_MOUNT_TYPE_FILESYSTEM)) - ret = TRUE; - - return ret; -} - -static void -filesystem_update (UDisksLinuxBlock *block, - const gchar *uevent_action, - GDBusInterface *_iface) -{ - UDisksFilesystem *iface = UDISKS_FILESYSTEM (_iface); - GPtrArray *p; - GList *mounts; - GList *l; - - p = g_ptr_array_new (); - mounts = udisks_mount_monitor_get_mounts_for_dev (block->mount_monitor, - g_udev_device_get_device_number (block->device)); - /* we are guaranteed that the list is sorted so if there are - * multiple mounts we'll always get the same order - */ - for (l = mounts; l != NULL; l = l->next) - { - UDisksMount *mount = UDISKS_MOUNT (l->data); - if (udisks_mount_get_mount_type (mount) == UDISKS_MOUNT_TYPE_FILESYSTEM) - g_ptr_array_add (p, (gpointer) udisks_mount_get_mount_path (mount)); - } - g_ptr_array_add (p, NULL); - udisks_filesystem_set_mount_points (iface, (const gchar *const *) p->pdata); - g_ptr_array_free (p, TRUE); - g_list_foreach (mounts, (GFunc) g_object_unref, NULL); - g_list_free (mounts); -} - -/* ---------------------------------------------------------------------------------------------------- */ -/* org.freedesktop.UDisks.Swapspace */ - -static gboolean -swapspace_check (UDisksLinuxBlock *block) -{ - gboolean ret; - UDisksMountType mount_type; - - ret = FALSE; - if ((g_strcmp0 (udisks_block_device_get_id_usage (block->iface_block_device), "other") == 0 && - g_strcmp0 (udisks_block_device_get_id_type (block->iface_block_device), "swap") == 0) - || (udisks_mount_monitor_is_dev_in_use (block->mount_monitor, - g_udev_device_get_device_number (block->device), - &mount_type) - && mount_type == UDISKS_MOUNT_TYPE_SWAP)) - ret = TRUE; - - return ret; -} - -static void -swapspace_connect (UDisksLinuxBlock *block) -{ - /* do nothing */ -} - -static void -swapspace_update (UDisksLinuxBlock *block, - const gchar *uevent_action, - GDBusInterface *_iface) -{ - UDisksSwapspace *iface = UDISKS_SWAPSPACE (_iface); - UDisksMountType mount_type; - gboolean active; - - active = FALSE; - if (udisks_mount_monitor_is_dev_in_use (block->mount_monitor, - g_udev_device_get_device_number (block->device), - &mount_type) - && mount_type == UDISKS_MOUNT_TYPE_SWAP) - active = TRUE; - udisks_swapspace_set_active (iface, active); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -encrypted_check (UDisksLinuxBlock *block) -{ - gboolean ret; - - ret = FALSE; - if (g_strcmp0 (udisks_block_device_get_id_usage (block->iface_block_device), "crypto") == 0 && - g_strcmp0 (udisks_block_device_get_id_type (block->iface_block_device), "crypto_LUKS") == 0) - ret = TRUE; - - return ret; -} - -static void -encrypted_connect (UDisksLinuxBlock *block) -{ - /* do nothing */ -} - -static void -encrypted_update (UDisksLinuxBlock *block, - const gchar *uevent_action, - GDBusInterface *_iface) -{ - /* do nothing */ -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -loop_check (UDisksLinuxBlock *block) -{ - gboolean ret; - - ret = FALSE; - if (g_str_has_prefix (g_udev_device_get_name (block->device), "loop")) - ret = TRUE; - - return ret; -} - -static void -loop_connect (UDisksLinuxBlock *block) -{ - /* do nothing */ -} - -static void -loop_update (UDisksLinuxBlock *block, - const gchar *uevent_action, - GDBusInterface *_iface) -{ - UDisksLoop *iface = UDISKS_LOOP (_iface); - - if (g_str_has_prefix (g_udev_device_get_name (block->device), "loop")) - { - gchar *filename; - gchar *backing_file; - GError *error; - filename = g_strconcat (g_udev_device_get_sysfs_path (block->device), - "/loop/backing_file", - NULL); - error = NULL; - if (!g_file_get_contents (filename, - &backing_file, - NULL, - &error)) - { - /* ENOENT is not unexpected */ - if (!(error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)) - { - udisks_warning ("Error loading %s: %s (%s, %d)", - filename, - error->message, - g_quark_to_string (error->domain), - error->code); - } - g_error_free (error); - udisks_loop_set_backing_file (iface, ""); - } - else - { - /* TODO: validate UTF-8 */ - g_strstrip (backing_file); - udisks_loop_set_backing_file (iface, backing_file); - g_free (backing_file); - } - g_free (filename); - } - else - { - udisks_loop_set_backing_file (iface, ""); - } -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * udisks_linux_block_uevent: - * @block: A #UDisksLinuxBlock. - * @action: Uevent action or %NULL - * @device: A new #GUdevDevice device object or %NULL if the device hasn't changed. - * - * Updates all information on interfaces on @block. - */ -void -udisks_linux_block_uevent (UDisksLinuxBlock *block, - const gchar *action, - GUdevDevice *device) -{ - g_return_if_fail (UDISKS_IS_LINUX_BLOCK (block)); - g_return_if_fail (device == NULL || G_UDEV_IS_DEVICE (device)); - - if (device != NULL) - { - g_object_unref (block->device); - block->device = g_object_ref (device); - g_object_notify (G_OBJECT (block), "device"); - } - - update_iface (block, action, block_device_check, block_device_connect, block_device_update, - UDISKS_TYPE_BLOCK_DEVICE_SKELETON, &block->iface_block_device); - update_iface (block, action, filesystem_check, NULL, filesystem_update, - UDISKS_TYPE_LINUX_FILESYSTEM, &block->iface_filesystem); - update_iface (block, action, swapspace_check, swapspace_connect, swapspace_update, - UDISKS_TYPE_LINUX_SWAPSPACE, &block->iface_swapspace); - update_iface (block, action, encrypted_check, encrypted_connect, encrypted_update, - UDISKS_TYPE_LINUX_ENCRYPTED, &block->iface_encrypted); - update_iface (block, action, loop_check, loop_connect, loop_update, - UDISKS_TYPE_LINUX_LOOP, &block->iface_loop); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -on_mount_monitor_mount_added (UDisksMountMonitor *monitor, - UDisksMount *mount, - gpointer user_data) -{ - UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (user_data); - if (udisks_mount_get_dev (mount) == g_udev_device_get_device_number (block->device)) - udisks_linux_block_uevent (block, NULL, NULL); -} static void -on_mount_monitor_mount_removed (UDisksMountMonitor *monitor, - UDisksMount *mount, - gpointer user_data) +block_iface_init (UDisksBlockDeviceIface *iface) { - UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (user_data); - if (udisks_mount_get_dev (mount) == g_udev_device_get_device_number (block->device)) - udisks_linux_block_uevent (block, NULL, NULL); + iface->handle_get_secret_configuration = handle_get_secret_configuration; + iface->handle_add_configuration_item = handle_add_configuration_item; + iface->handle_remove_configuration_item = handle_remove_configuration_item; + iface->handle_update_configuration_item = handle_update_configuration_item; } - -/* ---------------------------------------------------------------------------------------------------- */ |