From 79e941f44b699fcd9a600935325fe51134eae9aa Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Mon, 10 Oct 2011 16:25:01 -0400 Subject: [PATCH] Support PC-style floppy drives This is achieved by introducing properties MediaAvailable MediaChangeDetected on the Drive interface. Signed-off-by: David Zeuthen --- data/org.freedesktop.UDisks2.xml | 21 +++++++++++++--- doc/udisks2-sections.txt | 8 ++++-- src/udisksdaemonutil.c | 54 ++++++++++++++++++++++++++-------------- src/udisksdaemonutil.h | 4 ++- src/udiskslinuxblock.c | 13 +++++++++- src/udiskslinuxblockobject.c | 23 ++++++++++++++++- src/udiskslinuxdrive.c | 22 ++++++++++++++-- src/udiskslinuxdriveobject.c | 7 ++++++ 8 files changed, 124 insertions(+), 28 deletions(-) diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml index fe7a606..305de42 100644 --- a/data/org.freedesktop.UDisks2.xml +++ b/data/org.freedesktop.UDisks2.xml @@ -83,9 +83,6 @@ --> - - - @@ -134,6 +131,24 @@ + + + + + + + + + diff --git a/doc/udisks2-sections.txt b/doc/udisks2-sections.txt index e456f37..e497d63 100644 --- a/doc/udisks2-sections.txt +++ b/doc/udisks2-sections.txt @@ -498,6 +498,9 @@ udisks_drive_get_connection_bus udisks_drive_get_media udisks_drive_get_media_compatibility udisks_drive_get_media_removable +udisks_drive_get_media_available +udisks_drive_get_media_change_detected +udisks_drive_get_size udisks_drive_get_optical udisks_drive_get_optical_blank udisks_drive_get_optical_num_tracks @@ -508,7 +511,6 @@ udisks_drive_get_model udisks_drive_get_revision udisks_drive_get_rotation_rate udisks_drive_get_serial -udisks_drive_get_size udisks_drive_get_vendor udisks_drive_get_wwn udisks_drive_get_sort_key @@ -525,6 +527,9 @@ udisks_drive_set_connection_bus udisks_drive_set_media udisks_drive_set_media_compatibility udisks_drive_set_media_removable +udisks_drive_set_media_available +udisks_drive_set_media_change_detected +udisks_drive_set_size udisks_drive_set_optical udisks_drive_set_optical_blank udisks_drive_set_optical_num_tracks @@ -535,7 +540,6 @@ udisks_drive_set_model udisks_drive_set_revision udisks_drive_set_rotation_rate udisks_drive_set_serial -udisks_drive_set_size udisks_drive_set_vendor udisks_drive_set_wwn udisks_drive_set_sort_key diff --git a/src/udisksdaemonutil.c b/src/udisksdaemonutil.c index a00ae22..9667eb4 100644 --- a/src/udisksdaemonutil.c +++ b/src/udisksdaemonutil.c @@ -149,28 +149,46 @@ udisks_safe_append_to_object_path (GString *str, /** * udisks_daemon_util_block_get_size: * @device: A #GUdevDevice for a top-level block device. + * @out_media_available: (out): Return location for whether media is available or %NULL. + * @out_media_change_detected: (out): Return location for whether media change is detected or %NULL. * * Gets the size of the @device top-level block device, checking for media in the process * - * Returns: The size of @device or 0 if no media is available. + * Returns: The size of @device or 0 if no media is available or if unknown. */ guint64 -udisks_daemon_util_block_get_size (GUdevDevice *device) +udisks_daemon_util_block_get_size (GUdevDevice *device, + gboolean *out_media_available, + gboolean *out_media_change_detected) { - gboolean media_available; + gboolean media_available = FALSE; + gboolean media_change_detected = TRUE; + guint64 size = 0; /* figuring out if media is available is a bit tricky */ - media_available = FALSE; if (g_udev_device_get_sysfs_attr_as_boolean (device, "removable")) { /* never try to open optical drives (might cause the door to close) or * floppy drives (makes noise) */ - media_available = FALSE; - if (!(g_udev_device_get_property_as_boolean (device, "ID_CDROM") || - g_udev_device_get_property_as_boolean (device, "ID_DRIVE_FLOPPY"))) + if (g_udev_device_get_property_as_boolean (device, "ID_DRIVE_FLOPPY")) + { + /* assume media available */ + media_available = TRUE; + media_change_detected = FALSE; + } + else if (g_udev_device_get_property_as_boolean (device, "ID_CDROM")) + { + /* Rely on (careful) work already done by udev's cdrom_id prober */ + if (g_udev_device_get_property_as_boolean (device, "ID_CDROM_MEDIA")) + media_available = TRUE; + } + else { gint fd; + /* For the general case, just rely on open(2) failing with + * ENOMEDIUM if no medium is inserted + */ fd = open (g_udev_device_get_device_file (device), O_RDONLY); if (fd >= 0) { @@ -178,23 +196,23 @@ udisks_daemon_util_block_get_size (GUdevDevice *device) close (fd); } } - else - { - if (g_udev_device_get_property_as_boolean (device, "ID_CDROM_MEDIA")) - media_available = TRUE; - else - media_available = FALSE; - } } else { + /* not removable, so media is implicitly available */ media_available = TRUE; } - if (media_available) - return g_udev_device_get_sysfs_attr_as_uint64 (device, "size") * 512; - else - return 0; + if (media_available && size == 0 && media_change_detected) + size = g_udev_device_get_sysfs_attr_as_uint64 (device, "size") * 512; + + if (out_media_available != NULL) + *out_media_available = media_available; + + if (out_media_change_detected != NULL) + *out_media_change_detected = media_change_detected; + + return size; } diff --git a/src/udisksdaemonutil.h b/src/udisksdaemonutil.h index 6bc7eee..e0c63bd 100644 --- a/src/udisksdaemonutil.h +++ b/src/udisksdaemonutil.h @@ -30,7 +30,9 @@ gchar *udisks_decode_udev_string (const gchar *str); void udisks_safe_append_to_object_path (GString *str, const gchar *s); -guint64 udisks_daemon_util_block_get_size (GUdevDevice *device); +guint64 udisks_daemon_util_block_get_size (GUdevDevice *device, + gboolean *out_media_available, + gboolean *out_media_change_detected); gchar *udisks_daemon_util_resolve_link (const gchar *path, const gchar *name); diff --git a/src/udiskslinuxblock.c b/src/udiskslinuxblock.c index 6b0c3e4..e3f3128 100644 --- a/src/udiskslinuxblock.c +++ b/src/udiskslinuxblock.c @@ -270,6 +270,11 @@ update_hints (UDisksLinuxBlock *block, hint_auto = TRUE; } } + else + { + if (g_str_has_prefix (device_file, "/dev/fd")) + hint_system = FALSE; + } /* TODO: set ignore to TRUE for physical paths belonging to a drive with multiple paths */ @@ -590,6 +595,9 @@ udisks_linux_block_update (UDisksLinuxBlock *block, const gchar *device_file; const gchar *const *symlinks; const gchar *preferred_device_file; + guint64 size; + gboolean media_available; + gboolean media_change_detected; drive = NULL; @@ -608,7 +616,10 @@ udisks_linux_block_update (UDisksLinuxBlock *block, udisks_block_set_symlinks (iface, symlinks); udisks_block_set_major (iface, major (dev)); udisks_block_set_minor (iface, minor (dev)); - udisks_block_set_size (iface, udisks_daemon_util_block_get_size (device)); + size = udisks_daemon_util_block_get_size (device, + &media_available, + &media_change_detected); + udisks_block_set_size (iface, size); /* dm-crypt * diff --git a/src/udiskslinuxblockobject.c b/src/udiskslinuxblockobject.c index 576177a..b173045 100644 --- a/src/udiskslinuxblockobject.c +++ b/src/udiskslinuxblockobject.c @@ -405,13 +405,34 @@ block_device_update (UDisksLinuxBlockObject *object, /* org.freedesktop.UDisks.Filesystem */ static gboolean +drive_does_not_detect_media_change (UDisksLinuxBlockObject *object) +{ + gboolean ret = FALSE; + UDisksObject *drive_object; + + drive_object = udisks_daemon_find_object (object->daemon, udisks_block_get_drive (object->iface_block_device)); + if (drive_object != NULL) + { + UDisksDrive *drive = udisks_object_get_drive (drive_object); + if (drive != NULL) + { + ret = ! udisks_drive_get_media_change_detected (drive); + g_object_unref (drive); + } + g_object_unref (drive_object); + } + return ret; +} + +static gboolean filesystem_check (UDisksLinuxBlockObject *object) { gboolean ret; UDisksMountType mount_type; ret = FALSE; - if (g_strcmp0 (udisks_block_get_id_usage (object->iface_block_device), "filesystem") == 0 || + if (drive_does_not_detect_media_change (object) || + g_strcmp0 (udisks_block_get_id_usage (object->iface_block_device), "filesystem") == 0 || (udisks_mount_monitor_is_dev_in_use (object->mount_monitor, g_udev_device_get_device_number (object->device), &mount_type) && diff --git a/src/udiskslinuxdrive.c b/src/udiskslinuxdrive.c index 8ca3080..0a77ae3 100644 --- a/src/udiskslinuxdrive.c +++ b/src/udiskslinuxdrive.c @@ -214,7 +214,7 @@ set_media (UDisksDrive *iface, g_ptr_array_add (media_compat_array, NULL); media_in_drive = ""; - if (udisks_drive_get_size (iface) > 0) + if (udisks_drive_get_media_available (iface)) { for (n = 0; media_mapping[n].udev_property != NULL; n++) { @@ -320,6 +320,9 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive, UDisksDrive *iface = UDISKS_DRIVE (drive); GUdevDevice *device; gchar *sort_key; + guint64 size; + gboolean media_available; + gboolean media_change_detected; device = udisks_linux_drive_object_get_device (object, TRUE /* get_hw */); if (device == NULL) @@ -415,6 +418,11 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive, { udisks_drive_set_vendor (iface, vendor); } + /* workaround for missing ID_VENDOR for floppy drives */ + else if (g_str_has_prefix (name, "fd")) + { + udisks_drive_set_vendor (iface, ""); + } /* workaround for missing ID_VENDOR on virtio-blk */ else if (g_str_has_prefix (name, "vd")) { @@ -439,6 +447,11 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive, { udisks_drive_set_model (iface, model); } + /* workaround for missing ID_MODEL for floppy drives */ + else if (g_str_has_prefix (name, "fd")) + { + udisks_drive_set_model (iface, "Floppy Drive"); + } /* workaround for missing ID_MODEL on virtio-blk */ else if (g_str_has_prefix (name, "vd")) { @@ -459,7 +472,12 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive, /* common bits go here */ udisks_drive_set_media_removable (iface, g_udev_device_get_sysfs_attr_as_boolean (device, "removable")); - udisks_drive_set_size (iface, udisks_daemon_util_block_get_size (device)); + size = udisks_daemon_util_block_get_size (device, + &media_available, + &media_change_detected); + udisks_drive_set_size (iface, size); + udisks_drive_set_media_available (iface, media_available); + udisks_drive_set_media_change_detected (iface, media_change_detected); set_media (iface, device); set_rotation_rate (iface, device); set_connection_bus (iface, device); diff --git a/src/udiskslinuxdriveobject.c b/src/udiskslinuxdriveobject.c index 3cec14a..d67b9f1 100644 --- a/src/udiskslinuxdriveobject.c +++ b/src/udiskslinuxdriveobject.c @@ -728,6 +728,13 @@ udisks_linux_drive_object_should_include_device (GUdevClient *client, name = g_udev_device_get_name (device); + /* workaround for floppy devices */ + if (g_str_has_prefix (name, "fd")) + { + vpd = g_strdup_printf ("pcfloppy_%s", name); + goto found; + } + /* workaround for missing serial/wwn on virtio-blk */ if (g_str_has_prefix (name, "vd")) { -- 2.7.4