Hi

I've added another change which makes the mapping of mount options to the
associated mount point more clear and robust (this was the result of an internal
review):

> [Patch 0001] extends the DBUS interface by the MountOptions property, which
> holds the mounts options corresponding to the MountPoints property.
> It also allows an application to be notified by DBUS PropertiesChanged signal
> when the mount options of an mounted FS have changed (e.g. FS remounted
> read-only).
> 
> [Patch 0002] adds support for the mount -o remount option allowing to remount 
> a
> already mounted FS via DBUS (and udisksctl).

[Patch 0003] changes type of MountOptions property to path-options-pairs.

Regards
Daniel
From da7cf8535ca488808c56c13a5a0b37a96f61e45e Mon Sep 17 00:00:00 2001
From: Daniel Mueller <daniel.muel...@karlstorz.com>
Date: Wed, 4 Nov 2015 10:04:55 +0100
Subject: [PATCH 1/3] Extend DBUS interface by MountOptions property

Additionally monitor mount options instead of mount points only and add
MountOptions property to the DBUS interface.
---
 data/org.freedesktop.UDisks2.xml |  6 ++++++
 src/udiskslinuxfilesystem.c      | 11 ++++++++++-
 src/udisksmount.c                | 26 ++++++++++++++++++++++++++
 src/udisksmount.h                | 13 +++++++------
 src/udisksmountmonitor.c         | 14 ++++++++++----
 src/udisksprivate.h              |  1 +
 6 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml
index bd72795..bc77e8a 100644
--- a/data/org.freedesktop.UDisks2.xml
+++ b/data/org.freedesktop.UDisks2.xml
@@ -1510,6 +1510,12 @@
     -->
     <property name="MountPoints" type="aay" access="read"/>
 
+    <!-- MountOptions:
+         An array of mount option strings corresponding to the mount
+         points. If the device is not mounted, this array is empty.
+    -->
+    <property name="MountOptions" type="aay" access="read"/>
+
     <!--
         Mount:
         @options: Options - known options (in addition to <link linkend="udisks-std-options">standard options</link>) includes <parameter>fstype</parameter> (of type 's') and <parameter>options</parameter> (of type 's').
diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
index 4db3745..c88d7ed 100644
--- a/src/udiskslinuxfilesystem.c
+++ b/src/udiskslinuxfilesystem.c
@@ -145,6 +145,7 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem  *filesystem,
   UDisksMountMonitor *mount_monitor;
   UDisksLinuxDevice *device;
   GPtrArray *p;
+  GPtrArray *o;
   GList *mounts;
   GList *l;
 
@@ -152,6 +153,7 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem  *filesystem,
   device = udisks_linux_block_object_get_device (object);
 
   p = g_ptr_array_new ();
+  o = g_ptr_array_new ();
   mounts = udisks_mount_monitor_get_mounts_for_dev (mount_monitor, g_udev_device_get_device_number (device->udev_device));
   /* we are guaranteed that the list is sorted so if there are
    * multiple mounts we'll always get the same order
@@ -160,12 +162,19 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem  *filesystem,
     {
       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, (gpointer) udisks_mount_get_mount_path (mount));
+          g_ptr_array_add (o, (gpointer) udisks_mount_get_mount_options (mount));
+        }
     }
   g_ptr_array_add (p, NULL);
+  g_ptr_array_add (o, NULL);
   udisks_filesystem_set_mount_points (UDISKS_FILESYSTEM (filesystem),
                                       (const gchar *const *) p->pdata);
+  udisks_filesystem_set_mount_options (UDISKS_FILESYSTEM (filesystem),
+                                       (const gchar *const *) o->pdata);
   g_ptr_array_free (p, TRUE);
+  g_ptr_array_free (o, TRUE);
   g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
   g_list_free (mounts);
   g_object_unref (device);
diff --git a/src/udisksmount.c b/src/udisksmount.c
index b91cc2e..2ea5e88 100644
--- a/src/udisksmount.c
+++ b/src/udisksmount.c
@@ -48,6 +48,7 @@ struct _UDisksMount
 
   gchar *mount_path;
   dev_t dev;
+  gchar *mount_options;
   UDisksMountType type;
 };
 
@@ -66,6 +67,7 @@ udisks_mount_finalize (GObject *object)
   UDisksMount *mount = UDISKS_MOUNT (object);
 
   g_free (mount->mount_path);
+  g_free (mount->mount_options);
 
   if (G_OBJECT_CLASS (udisks_mount_parent_class)->finalize)
     G_OBJECT_CLASS (udisks_mount_parent_class)->finalize (object);
@@ -88,6 +90,7 @@ udisks_mount_class_init (UDisksMountClass *klass)
 UDisksMount *
 _udisks_mount_new (dev_t dev,
                    const gchar *mount_path,
+                   const gchar *mount_options,
                    UDisksMountType type)
 {
   UDisksMount *mount;
@@ -95,6 +98,7 @@ _udisks_mount_new (dev_t dev,
   mount = UDISKS_MOUNT (g_object_new (UDISKS_TYPE_MOUNT, NULL));
   mount->dev = dev;
   mount->mount_path = g_strdup (mount_path);
+  mount->mount_options = g_strdup (mount_options);
   mount->type = type;
 
   return mount;
@@ -119,6 +123,24 @@ udisks_mount_get_mount_path (UDisksMount *mount)
 }
 
 /**
+ * udisks_mount_get_mount_options:
+ * @mount: A #UDisksMount
+ *
+ * Gets the mount options for a #UDISKS_MOUNT_TYPE_FILESYSTEM<!-- -->-type mount.
+ *
+ * It is a programming error to call this on any other type of #UDisksMount.
+ *
+ * Returns: A string owned by @mount. Do not free.
+ */
+const gchar *
+udisks_mount_get_mount_options (UDisksMount *mount)
+{
+  g_return_val_if_fail (UDISKS_IS_MOUNT (mount), NULL);
+  g_return_val_if_fail (mount->type == UDISKS_MOUNT_TYPE_FILESYSTEM, NULL);
+  return mount->mount_options;
+}
+
+/**
  * udisks_mount_get_dev:
  * @mount: A #UDisksMount.
  *
@@ -160,6 +182,10 @@ udisks_mount_compare (UDisksMount  *mount,
     goto out;
 
   ret = other_mount->type - mount->type;
+  if (ret != 0)
+    goto out;
+
+  ret = g_strcmp0 (mount->mount_options, other_mount->mount_options);
 
  out:
   return ret;
diff --git a/src/udisksmount.h b/src/udisksmount.h
index 0beaf32..308c956 100644
--- a/src/udisksmount.h
+++ b/src/udisksmount.h
@@ -29,12 +29,13 @@ G_BEGIN_DECLS
 #define UDISKS_MOUNT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), UDISKS_TYPE_MOUNT, UDisksMount))
 #define UDISKS_IS_MOUNT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), UDISKS_TYPE_MOUNT))
 
-GType            udisks_mount_get_type       (void) G_GNUC_CONST;
-UDisksMountType  udisks_mount_get_mount_type (UDisksMount *mount);
-const gchar     *udisks_mount_get_mount_path (UDisksMount *mount);
-dev_t            udisks_mount_get_dev        (UDisksMount *mount);
-gint             udisks_mount_compare        (UDisksMount *mount,
-                                              UDisksMount *other_mount);
+GType            udisks_mount_get_type          (void) G_GNUC_CONST;
+UDisksMountType  udisks_mount_get_mount_type    (UDisksMount *mount);
+const gchar     *udisks_mount_get_mount_path    (UDisksMount *mount);
+const gchar     *udisks_mount_get_mount_options (UDisksMount *mount);
+dev_t            udisks_mount_get_dev           (UDisksMount *mount);
+gint             udisks_mount_compare           (UDisksMount *mount,
+                                                 UDisksMount *other_mount);
 
 G_END_DECLS
 
diff --git a/src/udisksmountmonitor.c b/src/udisksmountmonitor.c
index 891d118..a6e783d 100644
--- a/src/udisksmountmonitor.c
+++ b/src/udisksmountmonitor.c
@@ -423,26 +423,30 @@ udisks_mount_monitor_get_mountinfo (UDisksMountMonitor  *monitor,
       guint major, minor;
       gchar encoded_root[PATH_MAX + 1];
       gchar encoded_mount_point[PATH_MAX + 1];
+      gchar encoded_mount_options[PATH_MAX + 1];
       gchar *mount_point;
+      gchar *mount_options;
       dev_t dev;
 
       if (strlen (lines[n]) == 0)
         continue;
 
       if (sscanf (lines[n],
-                  "%u %u %u:%u " PATH_MAX_FMT " " PATH_MAX_FMT,
+                  "%u %u %u:%u " PATH_MAX_FMT " " PATH_MAX_FMT " " PATH_MAX_FMT,
                   &mount_id,
                   &parent_id,
                   &major,
                   &minor,
                   encoded_root,
-                  encoded_mount_point) != 6)
+                  encoded_mount_point,
+                  encoded_mount_options) != 7)
         {
           udisks_warning ("Error parsing line '%s'", lines[n]);
           continue;
         }
       encoded_root[sizeof encoded_root - 1] = '\0';
       encoded_mount_point[sizeof encoded_mount_point - 1] = '\0';
+      encoded_mount_options[sizeof encoded_mount_options - 1] = '\0';
 
       /* Temporary work-around for btrfs, see
        *
@@ -500,16 +504,18 @@ udisks_mount_monitor_get_mountinfo (UDisksMountMonitor  *monitor,
         }
 
       mount_point = g_strcompress (encoded_mount_point);
+      mount_options = g_strcompress (encoded_mount_options);
 
       /* TODO: we can probably use a hash table or something if this turns out to be slow */
       if (!have_mount (monitor, dev, mount_point))
         {
           UDisksMount *mount;
-          mount = _udisks_mount_new (dev, mount_point, UDISKS_MOUNT_TYPE_FILESYSTEM);
+          mount = _udisks_mount_new (dev, mount_point, mount_options, UDISKS_MOUNT_TYPE_FILESYSTEM);
           monitor->mounts = g_list_prepend (monitor->mounts, mount);
         }
 
       g_free (mount_point);
+      g_free (mount_options);
     }
 
   ret = TRUE;
@@ -584,7 +590,7 @@ udisks_mount_monitor_get_swaps (UDisksMountMonitor  *monitor,
       if (!have_mount (monitor, dev, NULL))
         {
           UDisksMount *mount;
-          mount = _udisks_mount_new (dev, NULL, UDISKS_MOUNT_TYPE_SWAP);
+          mount = _udisks_mount_new (dev, NULL, NULL, UDISKS_MOUNT_TYPE_SWAP);
           monitor->mounts = g_list_prepend (monitor->mounts, mount);
         }
     }
diff --git a/src/udisksprivate.h b/src/udisksprivate.h
index 5dfd77e..a61002c 100644
--- a/src/udisksprivate.h
+++ b/src/udisksprivate.h
@@ -28,6 +28,7 @@ G_BEGIN_DECLS
 
 UDisksMount *_udisks_mount_new (dev_t dev,
                                 const gchar *mount_path,
+                                const gchar *mount_options,
                                 UDisksMountType type);
 
 UDisksFstabEntry *_udisks_fstab_entry_new (const struct mntent *mntent);
-- 
2.4.0

From 594e733c9344175ea05f5002468679d798be5eba Mon Sep 17 00:00:00 2001
From: Daniel Mueller <daniel.muel...@karlstorz.com>
Date: Wed, 4 Nov 2015 11:23:03 +0100
Subject: [PATCH 2/3] Add support for mount's remount option.

Allow filesystems being remounted via udisksctl.
---
 src/udiskslinuxfilesystem.c | 158 ++++++++++++++++++++++++++++++++------------
 1 file changed, 116 insertions(+), 42 deletions(-)

diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
index c88d7ed..d9093f0 100644
--- a/src/udiskslinuxfilesystem.c
+++ b/src/udiskslinuxfilesystem.c
@@ -328,7 +328,7 @@ static const gchar *exfat_allow_gid_self[] = { "gid=", NULL };
 /* ------------------------------------------------ */
 /* TODO: support context= */
 
-static const gchar *any_allow[] = { "exec", "noexec", "nodev", "nosuid", "atime", "noatime", "nodiratime", "ro", "rw", "sync", "dirsync", NULL };
+static const gchar *any_allow[] = { "exec", "noexec", "nodev", "nosuid", "atime", "noatime", "nodiratime", "ro", "rw", "sync", "dirsync", "remount", NULL };
 
 static const FSMountOptions fs_mount_options[] =
   {
@@ -1035,6 +1035,28 @@ has_option (const gchar *options,
 }
 
 static gboolean
+has_variant_option (GVariant    *options,
+                    const gchar *option)
+{
+  const gchar *option_string;
+  gboolean ret;
+
+  option_string = NULL;
+  ret = FALSE;
+  if (g_variant_lookup (options,
+                        "options",
+                        "&s", &option_string))
+    {
+      if (has_option (option_string, option))
+        {
+          ret = TRUE;
+        }
+    }
+
+  return ret;
+}
+
+static gboolean
 is_in_fstab (UDisksBlock        *block,
              const gchar        *fstab_path,
              gchar             **out_mount_point,
@@ -1172,6 +1194,7 @@ handle_mount (UDisksFilesystem       *filesystem,
   const gchar *message;
   gboolean system_managed;
   gchar *escaped_device = NULL;
+  gboolean remount_requested;
 
   object = NULL;
   error_message = NULL;
@@ -1184,6 +1207,7 @@ handle_mount (UDisksFilesystem       *filesystem,
   escaped_mount_point_to_use = NULL;
   caller_user_name = NULL;
   system_managed = FALSE;
+  remount_requested = FALSE;
 
   /* only allow a single call at a time */
   g_mutex_lock (&UDISKS_LINUX_FILESYSTEM (filesystem)->lock);
@@ -1206,27 +1230,49 @@ handle_mount (UDisksFilesystem       *filesystem,
       system_managed = TRUE;
     }
 
+  /* Check if remount requested. */
+  if (has_variant_option (options, "remount"))
+    {
+      remount_requested = TRUE;
+    }
+
   /* First, fail if the device is already mounted */
   existing_mount_points = udisks_filesystem_get_mount_points (filesystem);
   if (existing_mount_points != NULL && g_strv_length ((gchar **) existing_mount_points) > 0)
     {
-      GString *str;
-      guint n;
-      str = g_string_new (NULL);
-      for (n = 0; existing_mount_points[n] != NULL; n++)
+      if (!remount_requested)
         {
-          if (n > 0)
-            g_string_append (str, ", ");
-          g_string_append_printf (str, "`%s'", existing_mount_points[n]);
+          GString *str;
+          guint n;
+          str = g_string_new (NULL);
+          for (n = 0; existing_mount_points[n] != NULL; n++)
+            {
+              if (n > 0)
+                g_string_append (str, ", ");
+              g_string_append_printf (str, "`%s'", existing_mount_points[n]);
+            }
+          g_dbus_method_invocation_return_error (invocation,
+                                                 UDISKS_ERROR,
+                                                 UDISKS_ERROR_ALREADY_MOUNTED,
+                                                 "Device %s is already mounted at %s.\n",
+                                                 udisks_block_get_device (block),
+                                                 str->str);
+          g_string_free (str, TRUE);
+          goto out;
+        }
+    }
+  /* Fail if the device is not mounted and remount requested. */
+  else
+    {
+      if (remount_requested)
+        {
+          g_dbus_method_invocation_return_error (invocation,
+                                                 UDISKS_ERROR,
+                                                 UDISKS_ERROR_NOT_MOUNTED,
+                                                 "Device %s is not mounted.\n",
+                                                 udisks_block_get_device (block));
+          goto out;
         }
-      g_dbus_method_invocation_return_error (invocation,
-                                             UDISKS_ERROR,
-                                             UDISKS_ERROR_ALREADY_MOUNTED,
-                                             "Device %s is already mounted at %s.\n",
-                                             udisks_block_get_device (block),
-                                             str->str);
-      g_string_free (str, TRUE);
-      goto out;
     }
 
   error = NULL;
@@ -1473,32 +1519,60 @@ handle_mount (UDisksFilesystem       *filesystem,
   escaped_device               = udisks_daemon_util_escape_and_quote (udisks_block_get_device (block));
 
   /* run mount(8) */
-  if (!udisks_daemon_launch_spawned_job_sync (daemon,
-                                              object,
-                                              "filesystem-mount", caller_uid,
-                                              NULL, /* GCancellable */
-                                              0,    /* uid_t run_as_uid */
-                                              0,    /* uid_t run_as_euid */
-                                              NULL, /* gint *out_status */
-                                              &error_message,
-                                              NULL,  /* input_string */
-                                              "mount -t %s -o %s %s %s",
-                                              escaped_fs_type_to_use,
-                                              escaped_mount_options_to_use,
-                                              escaped_device,
-                                              escaped_mount_point_to_use))
-    {
-      /* ugh, something went wrong.. we need to clean up the created mount point */
-      if (g_rmdir (mount_point_to_use) != 0)
-        udisks_warning ("Error removing directory %s: %m", mount_point_to_use);
-      g_dbus_method_invocation_return_error (invocation,
-                                             UDISKS_ERROR,
-                                             UDISKS_ERROR_FAILED,
-                                             "Error mounting %s at %s: %s",
-                                             udisks_block_get_device (block),
-                                             mount_point_to_use,
-                                             error_message);
-      goto out;
+  if (!remount_requested)
+    {
+      if (!udisks_daemon_launch_spawned_job_sync (daemon,
+                                                  object,
+                                                  "filesystem-mount", caller_uid,
+                                                  NULL, /* GCancellable */
+                                                  0,    /* uid_t run_as_uid */
+                                                  0,    /* uid_t run_as_euid */
+                                                  NULL, /* gint *out_status */
+                                                  &error_message,
+                                                  NULL,  /* input_string */
+                                                  "mount -t %s -o %s %s %s",
+                                                  escaped_fs_type_to_use,
+                                                  escaped_mount_options_to_use,
+                                                  escaped_device,
+                                                  escaped_mount_point_to_use))
+        {
+          /* ugh, something went wrong.. we need to clean up the created mount point */
+          if (g_rmdir (mount_point_to_use) != 0)
+            udisks_warning ("Error removing directory %s: %m", mount_point_to_use);
+          g_dbus_method_invocation_return_error (invocation,
+                                                 UDISKS_ERROR,
+                                                 UDISKS_ERROR_FAILED,
+                                                 "Error mounting %s at %s: %s",
+                                                 udisks_block_get_device (block),
+                                                 mount_point_to_use,
+                                                 error_message);
+          goto out;
+        }
+    }
+  else
+    {
+      if (!udisks_daemon_launch_spawned_job_sync (daemon,
+                                                  object,
+                                                  "filesystem-mount", caller_uid,
+                                                  NULL, /* GCancellable */
+                                                  0,    /* uid_t run_as_uid */
+                                                  0,    /* uid_t run_as_euid */
+                                                  NULL, /* gint *out_status */
+                                                  &error_message,
+                                                  NULL,  /* input_string */
+                                                  "mount -t %s -o %s %s",
+                                                  escaped_fs_type_to_use,
+                                                  escaped_mount_options_to_use,
+                                                  escaped_device))
+        {
+          g_dbus_method_invocation_return_error (invocation,
+                                                 UDISKS_ERROR,
+                                                 UDISKS_ERROR_FAILED,
+                                                 "Error remounting %s: %s",
+                                                 mount_point_to_use,
+                                                 error_message);
+          goto out;
+        }
     }
 
   /* update the mounted-fs file */
-- 
2.4.0

From 18e73eb35c914f32a96d6753274c64101a77d326 Mon Sep 17 00:00:00 2001
From: Daniel Mueller <daniel.muel...@karlstorz.com>
Date: Mon, 9 Nov 2015 17:40:44 +0100
Subject: [PATCH 3/3] Handle MountOptions property as path/options pairs.

---
 data/org.freedesktop.UDisks2.xml |  7 ++++---
 src/udiskslinuxfilesystem.c      | 12 ++++++------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml
index bc77e8a..3ac418e 100644
--- a/data/org.freedesktop.UDisks2.xml
+++ b/data/org.freedesktop.UDisks2.xml
@@ -1511,10 +1511,11 @@
     <property name="MountPoints" type="aay" access="read"/>
 
     <!-- MountOptions:
-         An array of mount option strings corresponding to the mount
-         points. If the device is not mounted, this array is empty.
+         An array of mount path/options-pairs for each mount path where
+         the device is mounted. If the device is not mounted, this array
+         is empty.
     -->
-    <property name="MountOptions" type="aay" access="read"/>
+    <property name="MountOptions" type="a(ayay)" access="read"/>
 
     <!--
         Mount:
diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
index d9093f0..775f079 100644
--- a/src/udiskslinuxfilesystem.c
+++ b/src/udiskslinuxfilesystem.c
@@ -145,7 +145,7 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem  *filesystem,
   UDisksMountMonitor *mount_monitor;
   UDisksLinuxDevice *device;
   GPtrArray *p;
-  GPtrArray *o;
+  GVariantBuilder options_builder;
   GList *mounts;
   GList *l;
 
@@ -153,7 +153,7 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem  *filesystem,
   device = udisks_linux_block_object_get_device (object);
 
   p = g_ptr_array_new ();
-  o = g_ptr_array_new ();
+  g_variant_builder_init (&options_builder, G_VARIANT_TYPE ("a(ayay)"));
   mounts = udisks_mount_monitor_get_mounts_for_dev (mount_monitor, g_udev_device_get_device_number (device->udev_device));
   /* we are guaranteed that the list is sorted so if there are
    * multiple mounts we'll always get the same order
@@ -164,17 +164,17 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem  *filesystem,
       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 (o, (gpointer) udisks_mount_get_mount_options (mount));
+          g_variant_builder_add (&options_builder, "(^ay^ay)",
+                                 (const gchar *const *) udisks_mount_get_mount_path (mount),
+                                 (const gchar *const *) udisks_mount_get_mount_options (mount));
         }
     }
   g_ptr_array_add (p, NULL);
-  g_ptr_array_add (o, NULL);
   udisks_filesystem_set_mount_points (UDISKS_FILESYSTEM (filesystem),
                                       (const gchar *const *) p->pdata);
   udisks_filesystem_set_mount_options (UDISKS_FILESYSTEM (filesystem),
-                                       (const gchar *const *) o->pdata);
+                                       g_variant_new ("a(ayay)", &options_builder));
   g_ptr_array_free (p, TRUE);
-  g_ptr_array_free (o, TRUE);
   g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
   g_list_free (mounts);
   g_object_unref (device);
-- 
2.4.0

_______________________________________________
devkit-devel mailing list
devkit-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/devkit-devel

Reply via email to