summaryrefslogtreecommitdiff
path: root/src/udiskslinuxblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/udiskslinuxblock.c')
-rw-r--r--src/udiskslinuxblock.c2022
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;
}
-
-/* ---------------------------------------------------------------------------------------------------- */