Rework UDISKS_* udev properties
authorDavid Zeuthen <davidz@redhat.com>
Tue, 19 Jul 2011 18:27:08 +0000 (14:27 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Tue, 19 Jul 2011 18:27:08 +0000 (14:27 -0400)
Signed-off-by: David Zeuthen <davidz@redhat.com>
data/80-udisks2.rules
data/org.freedesktop.UDisks2.xml
doc/man/udisks.xml
doc/udisks2-sections.txt
policy/org.freedesktop.udisks2.policy.in
src/udisksdaemonutil.c
src/udiskslinuxblock.c
src/udiskslinuxencrypted.c
src/udiskslinuxfilesystem.c

index 09438d7..14accc9 100644 (file)
@@ -23,3 +23,6 @@ ENV{ID_VENDOR}=="*IOMEGA*", ENV{ID_MODEL}=="*ZIP*", ENV{ID_DRIVE_FLOPPY_ZIP}="1"
 KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ENV{DEVTYPE}=="disk", ENV{ID_DRIVE_FLASH_SD}="1", ENV{ID_DRIVE_MEDIA_FLASH_SD}="1"
 # ditto for memstick
 KERNEL=="mspblk[0-9]", SUBSYSTEMS=="memstick", ENV{DEVTYPE}=="disk", ENV{ID_DRIVE_FLASH_MS}="1", ENV{ID_DRIVE_MEDIA_FLASH_MS}="1"
+
+# TODO: maybe automatically convert udisks1 properties to udisks2 ones?
+# (e.g. UDISKS_PRESENTATION_HIDE -> UDISKS_IGNORE)
index fdf36ab..ceb33be 100644 (file)
     -->
     <property name="LoopBackingFile" type="ay" access="read"/>
 
+    <!-- HintSystem: If %TRUE, the device is considered a <emphasis>system device</emphasis>.
+         System devices are devices that require additional permissions to access.
+    -->
+    <property name="HintSystem" type="b" access="read"/>
+
+    <!-- HintIgnore: If %TRUE, the device should be hidden from users. -->
+    <property name="HintIgnore" type="b" access="read"/>
+
+    <!-- HintAuto: If %TRUE, the device should be automatically started (e.g. mounted, unlocked etc.). -->
+    <property name="HintAuto" type="b" access="read"/>
+
+    <!-- HintName: If not blank, the name to use when presenting the device. -->
+    <property name="HintName" type="s" access="read"/>
+
+    <!-- HintIconName: If not blank, the icon name to use when presenting the device.
+         The name must adhere to the
+         <ulink url="http://www.freedesktop.org/wiki/Specifications/icon-theme-spec">freedesktop.org icon theme specification</ulink>.
+    -->
+    <property name="HintIconName" type="s" access="read"/>
+
     <!-- PartTable: Set to %TRUE if a partition table signature was detected on the device. -->
     <property name="PartTable" type="b" access="read"/>
     <!-- PartTableScheme: The type of partition table detected.
index 1b1b583..28dbbf5 100644 (file)
     </para>
   </refsect1>
 
-  <refsect1><title>DEVICE INFORMATION</title>
+  <refsect1>
+    <title>DEVICE INFORMATION</title>
     <para>
       On Linux, udisks relies on recent versions of
       <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
       and the Linux kernel. Influential device properties in the udev
       database include:
     </para>
-    <!-- TODO: need to revisit all of these variables -->
     <variablelist>
       <varlistentry>
-        <term><option>UDISKS_PRESENTATION_HIDE</option></term>
-        <listitem><para>If set to 1 this is a hint to presentation
-            level software that the device should not be shown to the
-            user.
-        </para></listitem>
+        <term><option>UDISKS_SYSTEM</option></term>
+        <listitem>
+          <para>
+            If set, this overrides the value of the
+            <link linkend="gdbus-property-org-freedesktop-UDisks2-BlockDevice.HintSystem">HintSystem</link> property.
+          </para>
+        </listitem>
       </varlistentry>
-
       <varlistentry>
-        <term><option>UDISKS_PRESENTATION_NOPOLICY</option></term>
-        <listitem><para>If set to 1 this is a hint to presentation
-            level software that the device should not be automounted
-            or autoassembled (for e.g. components of a multi-disk device).
-        </para></listitem>
+        <term><option>UDISKS_IGNORE</option></term>
+        <listitem>
+          <para>
+            If set, this overrides the value of the
+            <link linkend="gdbus-property-org-freedesktop-UDisks2-BlockDevice.HintIgnore">HintIgnore</link> property.
+          </para>
+        </listitem>
       </varlistentry>
-
       <varlistentry>
-        <term><option>UDISKS_DISABLE_POLLING</option></term>
-        <listitem><para>If set to 1 this will disable the polling of drives
-           for media changes, for devices which do not send out media
-           notifications by themselves (this mostly affects CD drives).
-           Some CD drives cause bad effects such as very high CPU usage when
-           being polled.
-        </para></listitem>
+        <term><option>UDISKS_AUTO</option></term>
+        <listitem>
+          <para>
+            If set, this overrides the value of the
+            <link linkend="gdbus-property-org-freedesktop-UDisks2-BlockDevice.HintAuto">HintAuto</link> property.
+          </para>
+        </listitem>
       </varlistentry>
-
       <varlistentry>
-        <term><option>UDISKS_PRESENTATION_NAME</option></term>
-        <listitem><para>The name to user for the device when
-        presenting it to the user.
-        </para></listitem>
+        <term><option>UDISKS_NAME</option></term>
+        <listitem>
+          <para>
+            The name to use for the device when presenting it in an user interface.
+            This corresponds to the
+            <link linkend="gdbus-property-org-freedesktop-UDisks2-BlockDevice.HintName">HintName</link> property.
+          </para>
+        </listitem>
       </varlistentry>
-
       <varlistentry>
-        <term><option>UDISKS_PRESENTATION_ICON_NAME</option></term>
-        <listitem><para>The icon to use when presenting the device to
-        the user. If set, the name must follow the freedesktop.org
-        icon theme specification.
-        </para></listitem>
+        <term><option>UDISKS_ICON_NAME</option></term>
+        <listitem>
+          <para>
+            The icon to use for the device when presenting it in an user interface. If
+            set, the name must adhere to the
+            <ulink url="http://www.freedesktop.org/wiki/Specifications/icon-theme-spec">freedesktop.org icon theme specification</ulink>.
+            This corresponds to the
+            <link linkend="gdbus-property-org-freedesktop-UDisks2-BlockDevice.HintIconName">HintIconName</link> property.
+          </para>
+        </listitem>
       </varlistentry>
     </variablelist>
+
     <para>
-      The <option>ID_DRIVE_*</option> properties are used to describe what
-      kind of physical media can be used in a device. These are typically
-      set on the main block device (e.g. <literal>/dev/sdb</literal>) and
-      more than one these properties can be set if the device supports
-      multiple kinds of media.
+      For media and drive identification, the output of the probers
+      supplied by
+      <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+      (such as <command>cdrom_id</command>, <command>ata_id</command> and
+      <command>scsi_id</command>) are used in addition to the
+      following properties:
     </para>
     <variablelist>
       <varlistentry>
-        <term><option>ID_DRIVE_EJECTABLE</option></term>
-        <listitem><para>Whether the media in the drive is physically ejectable. Only
-            set this to 1 (or 0) if the drive truly uses (or doesn't) ejectable media.
-            In particular, it is not necessary to set this for e.g. iPod or Kindle
-            devices where it is necessary to send a command via
-            <citerefentry>
-              <refentrytitle>eject</refentrytitle><manvolnum>1</manvolnum>
-            </citerefentry>
-            since the desktop user session will offer this option for
-            removable devices regardless of whether they are
-            ejectable.  If this property is not set, a heuristic will
-            be used to determine if the media is ejectable (drives
-            using optical, Zip or Jaz media are considered ejectable).
-        </para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>ID_DRIVE_DETACHABLE</option></term>
-        <listitem><para> Whether the device is detachable. It is only meaningful
-            to set this to 0 (to avoid marking a device as detachable) since the
-            code for detaching the device is part of udisks itself.
-            If this property is not set, a heuristic will be used to determine if the
-            drive is detachable (currently only devices connected through USB are
-            detachable).
-        </para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>ID_DRIVE_CAN_SPINDOWN</option></term>
-        <listitem><para> Whether the device can spin down. It is only meaningful
-            to set this to 0 (to avoid marking a device as being capable of spinning down)
-            since the code for spinning down the device is part of udisks itself.
-            If this property is not set, a heuristic will be used to determine if the
-            drive can spin down (currently only ATA devices, including those USB
-            devices with a SAT layer) can be spun down).
-        </para></listitem>
-      </varlistentry>
-      <varlistentry>
         <term><option>ID_DRIVE_FLASH</option></term>
         <listitem><para>The device is compatible with flash.
         </para></listitem>
       </varlistentry>
       <varlistentry>
         <term><option>ID_DRIVE_FLASH_SDHC</option></term>
-        <listitem><para>The device is compatible with High-Capicity SecureDigital.
+        <listitem><para>The device is compatible with High-Capacity SecureDigital.
+        </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>ID_DRIVE_FLASH_SDXC</option></term>
+        <listitem><para>The device is compatible with Extended-Capacity SecureDigital.
         </para></listitem>
       </varlistentry>
       <varlistentry>
         <listitem><para>The device is compatible with Jaz.
         </para></listitem>
       </varlistentry>
-
     </variablelist>
     <para>
-      The <option>ID_DRIVE_MEDIA_*</option> properties describe the
-      current media in a device. As with
-      the <option>ID_DRIVE_*</option> properties, these properties are
-      typically set on the main block device
-      (e.g. <literal>/dev/sdb</literal>). Typically only one of these
-      properties are set.
+      While the <literal>ID_DRIVE_*</literal> properties describe what
+      kind of media the drive accepts (more than one property can be
+      set) and correspond to the <link
+      linkend="gdbus-property-org-freedesktop-UDisks2-Drive.MediaCompatibility">MediaCompatibility</link>
+      property, the <option>ID_DRIVE_MEDIA_*</option> properties
+      describe the current media in a device (typically only one of
+      these properties are set) and correspond to the <link
+      linkend="gdbus-property-org-freedesktop-UDisks2-Drive.Media">Media</link>
+      property:
     </para>
     <variablelist>
       <varlistentry>
       </varlistentry>
       <varlistentry>
         <term><option>ID_DRIVE_MEDIA_FLASH_SDHC</option></term>
-        <listitem><para>The physical media currently inserted into the device is High-Capicity SecureDigital.
+        <listitem><para>The physical media currently inserted into the device is High-Capacity SecureDigital.
+        </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>ID_DRIVE_MEDIA_FLASH_SDXC</option></term>
+        <listitem><para>The physical media currently inserted into the device is Extended-Capacity SecureDigital.
         </para></listitem>
       </varlistentry>
       <varlistentry>
index 944bc7c..e6e2c8f 100644 (file)
@@ -697,6 +697,11 @@ udisks_block_device_get_part_table_scheme
 udisks_block_device_get_preferred_device
 udisks_block_device_get_size
 udisks_block_device_get_symlinks
+udisks_block_device_get_hint_system
+udisks_block_device_get_hint_ignore
+udisks_block_device_get_hint_auto
+udisks_block_device_get_hint_name
+udisks_block_device_get_hint_icon_name
 udisks_block_device_set_crypto_backing_device
 udisks_block_device_set_device
 udisks_block_device_set_drive
@@ -723,6 +728,11 @@ udisks_block_device_set_part_table_scheme
 udisks_block_device_set_preferred_device
 udisks_block_device_set_size
 udisks_block_device_set_symlinks
+udisks_block_device_set_hint_system
+udisks_block_device_set_hint_ignore
+udisks_block_device_set_hint_auto
+udisks_block_device_set_hint_name
+udisks_block_device_set_hint_icon_name
 UDisksBlockDeviceProxy
 UDisksBlockDeviceProxyClass
 udisks_block_device_proxy_new
index 481139b..eeff1b2 100644 (file)
     </defaults>
   </action>
 
+  <action id="org.freedesktop.udisks2.filesystem-mount-system">
+    <_description>Mount a filesystem on a system device</_description>
+    <_message>Authentication is required to mount the filesystem</_message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>auth_admin_keep</allow_active>
+    </defaults>
+  </action>
+
   <action id="org.freedesktop.udisks2.filesystem-unmount-others">
     <_description>Stop a device started by another user</_description>
     <_message>Authentication is required to unmount a filesystem mounted by another user</_message>
     </defaults>
   </action>
 
+  <action id="org.freedesktop.udisks2.encrypted-unlock-system">
+    <_description>Unlock an encrypted system device</_description>
+    <_message>Authentication is required to unlock an encrypted device</_message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>yes</allow_active>
+    </defaults>
+  </action>
+
   <action id="org.freedesktop.udisks2.encrypted-lock-others">
     <_description>Lock an encrypted device unlocked by another user</_description>
     <_message>Authentication is required to lock an encrypted device unlocked by another user</_message>
     <defaults>
       <allow_any>auth_admin</allow_any>
       <allow_inactive>auth_admin</allow_inactive>
-      <allow_active>auth_admin_keep</allow_active>
+      <allow_active>yes</allow_active>
     </defaults>
   </action>
 
-  <!-- Work with devices considered to be at the system-level (for example, SAS devices) -->
-  <action id="org.freedesktop.udisks2.system-devices">
-    <_description>Work with system devices</_description>
-    <_message>Authentication is work with system devices</_message>
+  <action id="org.freedesktop.udisks2.modify-device-system">
+    <_description>Modify a system device</_description>
+    <_message>Authentication is required to modify a device</_message>
     <defaults>
       <allow_any>auth_admin</allow_any>
       <allow_inactive>auth_admin</allow_inactive>
index 4e4664f..ce8d164 100644 (file)
@@ -326,8 +326,6 @@ udisks_daemon_util_check_authorization_sync (UDisksDaemon          *daemon,
   UDisksBlockDevice *block;
   gboolean auth_no_user_interaction;
 
-  /* TODO: also check for org.freedesktop.udisks2.system-devices (if applicable) */
-
   ret = FALSE;
   subject = NULL;
   details = NULL;
index 4050be2..4ed6119 100644 (file)
@@ -379,8 +379,9 @@ block_device_connect (UDisksLinuxBlock *block)
 }
 
 static gchar *
-find_drive (GDBusObjectManagerServer *object_manager,
-            GUdevDevice              *block_device)
+find_drive (GDBusObjectManagerServer  *object_manager,
+            GUdevDevice               *block_device,
+            UDisksDrive              **out_drive)
 {
   const gchar *block_device_sysfs_path;
   gchar *ret;
@@ -413,6 +414,8 @@ find_drive (GDBusObjectManagerServer *object_manager,
           drive_sysfs_path = g_udev_device_get_sysfs_path (drive_device);
           if (g_str_has_prefix (block_device_sysfs_path, drive_sysfs_path))
             {
+              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);
@@ -484,6 +487,71 @@ get_sysfs_attr (GUdevDevice *device,
 }
 
 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 void
 block_device_update (UDisksLinuxBlock *block,
                      const gchar      *uevent_action,
                      GDBusInterface   *_iface)
@@ -492,6 +560,7 @@ block_device_update (UDisksLinuxBlock *block,
   GUdevDeviceNumber dev;
   GDBusObjectManagerServer *object_manager;
   gchar *drive_object_path;
+  UDisksDrive *drive;
   gchar *s;
   gboolean is_partition_table;
   gboolean is_partition_entry;
@@ -499,6 +568,8 @@ block_device_update (UDisksLinuxBlock *block,
   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);
@@ -616,7 +687,7 @@ block_device_update (UDisksLinuxBlock *block,
    * 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_object_path = find_drive (object_manager, block->device, &drive);
   if (drive_object_path != NULL)
     {
       udisks_block_device_set_drive (iface, drive_object_path);
@@ -740,6 +811,11 @@ block_device_update (UDisksLinuxBlock *block,
       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);
+
+  if (drive != NULL)
+    g_object_unref (drive);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
index c89ec42..a10d5fa 100644 (file)
@@ -141,6 +141,7 @@ handle_unlock (UDisksEncrypted        *encrypted,
   GUdevDevice *udev_cleartext_device;
   GError *error;
   uid_t caller_uid;
+  const gchar *action_id;
 
   object = NULL;
   error_message = NULL;
@@ -201,12 +202,13 @@ handle_unlock (UDisksEncrypted        *encrypted,
     }
 
   /* Now, check that the user is actually authorized to unlock the device.
-   *
-   * TODO: want nicer authentication message + special treatment for system-internal
    */
+  action_id = "org.freedesktop.udisks2.encrypted-unlock";
+  if (udisks_block_device_get_hint_system (block))
+    action_id = "org.freedesktop.udisks2.encrypted-unlock-system";
   if (!udisks_daemon_util_check_authorization_sync (daemon,
                                                     object,
-                                                    "org.freedesktop.udisks2.encrypted-unlock",
+                                                    action_id,
                                                     options,
                                                     N_("Authentication is required to unlock the encrypted device $(udisks2.device)"),
                                                     invocation))
index 01205b1..e14a64a 100644 (file)
@@ -668,6 +668,7 @@ handle_mount (UDisksFilesystem       *filesystem,
   gchar *escaped_mount_point_to_use;
   gchar *error_message;
   GError *error;
+  const gchar *action_id;
 
   object = NULL;
   error_message = NULL;
@@ -773,12 +774,13 @@ handle_mount (UDisksFilesystem       *filesystem,
   /* Now, check that the user is actually authorized to mount the
    * device. Need to do this before calculating a mount point since we
    * may be racing with other threads...
-   *
-   * TODO: want nicer authentication message + special treatment for system-internal
    */
+  action_id = "org.freedesktop.udisks2.filesystem-mount";
+  if (udisks_block_device_get_hint_system (block))
+    action_id = "org.freedesktop.udisks2.filesystem-mount-system";
   if (!udisks_daemon_util_check_authorization_sync (daemon,
                                                     object,
-                                                    "org.freedesktop.udisks2.filesystem-mount",
+                                                    action_id,
                                                     options,
                                                     N_("Authentication is required to mount $(udisks2.device)"),
                                                     invocation))
@@ -1122,6 +1124,7 @@ handle_set_label (UDisksFilesystem       *filesystem,
   gboolean supports_online;
   UDisksBaseJob *job;
   gchar *escaped_label;
+  const gchar *action_id;
 
   object = NULL;
   daemon = NULL;
@@ -1170,12 +1173,16 @@ handle_set_label (UDisksFilesystem       *filesystem,
         }
     }
 
+  action_id = "org.freedesktop.udisks2.modify-device";
+  if (udisks_block_device_get_hint_system (block))
+    action_id = "org.freedesktop.udisks2.modify-device-system";
+
   /* Check that the user is actually authorized to change the
    * filesystem label.
    */
   if (!udisks_daemon_util_check_authorization_sync (daemon,
                                                     object,
-                                                    "org.freedesktop.udisks2.modify-device",
+                                                    action_id,
                                                     options,
                                                     N_("Authentication is required to change the filesystem label on $(udisks2.device)"),
                                                     invocation))