summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/org.freedesktop.UDisks2.xml21
-rw-r--r--doc/udisks2-sections.txt8
-rw-r--r--src/udisksdaemonutil.c54
-rw-r--r--src/udisksdaemonutil.h4
-rw-r--r--src/udiskslinuxblock.c13
-rw-r--r--src/udiskslinuxblockobject.c23
-rw-r--r--src/udiskslinuxdrive.c22
-rw-r--r--src/udiskslinuxdriveobject.c7
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 @@
-->
<property name="WWN" type="s" access="read"/>
- <!-- Size: The size of the drive. Is set to 0 if, and only if, no media is inserted. -->
- <property name="Size" type="t" access="read"/>
-
<!-- Media: The kind of media currently in the drive or blank if unknown.
See the #org.freedesktop.UDisks2.Drive:MediaCompatibility property for known values.
-->
@@ -134,6 +131,24 @@
<!-- MediaRemovable: Whether the media can be removed from the drive. -->
<property name="MediaRemovable" type="b" access="read"/>
+ <!-- MediaAvailable: Set to %FALSE if no medium is available.
+ This is always %TRUE if #org.freedesktop.UDisks2.Block.MediaChangeDetected is %FALSE.
+ -->
+ <property name="MediaAvailable" type="b" access="read"/>
+
+ <!-- MediaChangeDetected: Set to %TRUE only if media changes are detected.
+ Media changes are detected on all modern disk drives through
+ either polling or an asynchronous notification mechanism. The
+ only known disk drives that cannot report media changes are
+ PC floppy drives.
+ -->
+ <property name="MediaChangeDetected" type="b" access="read"/>
+
+ <!-- Size: The size of the drive (or the media currently in the drive).
+ This is always 0 if #org.freedesktop.UDisks2.Block.MediaChangeDetected is %FALSE.
+ -->
+ <property name="Size" type="t" access="read"/>
+
<!-- Optical: %TRUE if the drive contains an optical disc. -->
<property name="Optical" type="b" access="read"/>
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"))
{