introduce a new property device-is-busy
authorDavid Zeuthen <davidz@redhat.com>
Mon, 24 Mar 2008 23:25:59 +0000 (19:25 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Mon, 24 Mar 2008 23:25:59 +0000 (19:25 -0400)
src/devkit-disks-device-private.h
src/devkit-disks-device.c
src/devkit-disks-device.h
src/org.freedesktop.DeviceKit.Disks.Device.xml
tools/devkit-disks.c

index 38420f9..53e5ec2 100644 (file)
@@ -94,8 +94,10 @@ struct DevkitDisksDevicePrivate
 
                 char *crypto_cleartext_slave;
 
-                /* not exported */
+                /* the following properties are not (yet) exported */
                 char *dm_name;
+                GPtrArray *slaves_objpath;
+                GPtrArray *holders_objpath;
         } info;
 };
 
index 55a8ae5..45d46cb 100644 (file)
@@ -110,6 +110,7 @@ enum
         PROP_DEVICE_SIZE,
         PROP_DEVICE_BLOCK_SIZE,
         PROP_DEVICE_IS_MOUNTED,
+        PROP_DEVICE_IS_BUSY,
         PROP_DEVICE_MOUNT_PATH,
 
         PROP_JOB_IN_PROGRESS,
@@ -281,6 +282,10 @@ get_property (GObject         *object,
        case PROP_DEVICE_IS_MOUNTED:
                g_value_set_boolean (value, device->priv->info.device_is_mounted);
                break;
+       case PROP_DEVICE_IS_BUSY:
+                /* this property is special; it's value is computed on demand */
+               g_value_set_boolean (value, devkit_disks_device_local_is_busy (device));
+               break;
        case PROP_DEVICE_MOUNT_PATH:
                g_value_set_string (value, device->priv->info.device_mount_path);
                break;
@@ -496,6 +501,10 @@ devkit_disks_device_class_init (DevkitDisksDeviceClass *klass)
                 g_param_spec_boolean ("device-is-mounted", NULL, NULL, FALSE, G_PARAM_READABLE));
         g_object_class_install_property (
                 object_class,
+                PROP_DEVICE_IS_BUSY,
+                g_param_spec_boolean ("device-is-busy", NULL, NULL, FALSE, G_PARAM_READABLE));
+        g_object_class_install_property (
+                object_class,
                 PROP_DEVICE_MOUNT_PATH,
                 g_param_spec_string ("device-mount-path", NULL, NULL, NULL, G_PARAM_READABLE));
 
@@ -839,6 +848,10 @@ free_info (DevkitDisksDevice *device)
         g_free (device->priv->info.drive_serial);
 
         g_free (device->priv->info.dm_name);
+        g_ptr_array_foreach (device->priv->info.slaves_objpath, (GFunc) g_free, NULL);
+        g_ptr_array_free (device->priv->info.slaves_objpath, TRUE);
+        g_ptr_array_foreach (device->priv->info.holders_objpath, (GFunc) g_free, NULL);
+        g_ptr_array_free (device->priv->info.holders_objpath, TRUE);
 }
 
 static void
@@ -850,6 +863,8 @@ init_info (DevkitDisksDevice *device)
         device->priv->info.partition_flags = g_ptr_array_new ();
         device->priv->info.partition_table_offsets = g_array_new (FALSE, TRUE, sizeof (guint64));
         device->priv->info.partition_table_sizes = g_array_new (FALSE, TRUE, sizeof (guint64));
+        device->priv->info.slaves_objpath = g_ptr_array_new ();
+        device->priv->info.holders_objpath = g_ptr_array_new ();
 }
 
 
@@ -1029,22 +1044,12 @@ update_info_properties_cb (DevKitInfo *info, const char *key, void *user_data)
 
         } else if (strcmp (key, "DM_TARGET_TYPES") == 0) {
                 if (strcmp (devkit_info_property_get_string (info, key), "crypt") == 0) {
-                        char *slaves_path;
-                        GDir *slaves_dir;
-                        const char *slave_name;
-
-                        /* we're a dm-crypt target, find our slave */
-                        slaves_path = g_build_filename (device->priv->native_path, "slaves", NULL);
-                        if((slaves_dir = g_dir_open (slaves_path, 0, NULL)) != NULL) {
-                                while ((slave_name = g_dir_read_name (slaves_dir)) != NULL) {
-                                        device->priv->info.device_is_crypto_cleartext = TRUE;
-                                        device->priv->info.crypto_cleartext_slave =
-                                                compute_object_path_from_basename (slave_name);
-                                }
-                                g_dir_close (slaves_dir);
+                        /* we're a dm-crypt target and can, by design, then only have one slave */
+                        if (device->priv->info.slaves_objpath->len == 1) {
+                                device->priv->info.device_is_crypto_cleartext = TRUE;
+                                device->priv->info.crypto_cleartext_slave =
+                                        g_strdup (g_ptr_array_index (device->priv->info.slaves_objpath, 0));
                         }
-                        g_free (slaves_path);
-
                 }
 
         } else if (strcmp (key, "MEDIA_AVAILABLE") == 0) {
@@ -1074,10 +1079,17 @@ update_info_symlinks_cb (DevKitInfo *info, const char *value, void *user_data)
 static gboolean
 update_info (DevkitDisksDevice *device)
 {
+        guint64 start, size;
+        char *s;
+        char *p;
+        int n;
         gboolean ret;
         int fd;
         int block_size;
         DevKitInfo *info;
+        char *path;
+        GDir *dir;
+        const char *name;
 
         ret = FALSE;
         info = NULL;
@@ -1132,10 +1144,6 @@ update_info (DevkitDisksDevice *device)
 
         /* figure out if we're a partition and, if so, who our slave is */
         if (sysfs_file_exists (device->priv->native_path, "start")) {
-                guint64 start, size;
-                char *s;
-                char *p;
-                int n;
 
                 /* we're partitioned by the kernel */
                 device->priv->info.device_is_partition = TRUE;
@@ -1166,6 +1174,33 @@ update_info (DevkitDisksDevice *device)
                 /* TODO: handle partitions created by kpartx / dm-linear */
         }
 
+        /* Maintain (non-exported) properties holders and slaves for the holders resp. slaves
+         * directories in sysfs. The entries in these arrays are object paths (that may not
+         * exist; we just compute the name).
+         */
+        path = g_build_filename (device->priv->native_path, "slaves", NULL);
+        if((dir = g_dir_open (path, 0, NULL)) != NULL) {
+                while ((name = g_dir_read_name (dir)) != NULL) {
+                        s = compute_object_path_from_basename (name);
+                        g_ptr_array_add (device->priv->info.slaves_objpath, s);
+                        g_warning ("slave='%s'", s);
+                }
+                g_dir_close (dir);
+        }
+        g_free (path);
+
+        path = g_build_filename (device->priv->native_path, "holders", NULL);
+        if((dir = g_dir_open (path, 0, NULL)) != NULL) {
+                while ((name = g_dir_read_name (dir)) != NULL) {
+                        s = compute_object_path_from_basename (name);
+                        g_ptr_array_add (device->priv->info.holders_objpath, s);
+                        g_warning ("holder='%s'", s);
+                }
+                g_dir_close (dir);
+        }
+        g_free (path);
+
+
         if (devkit_info_property_foreach (info, update_info_properties_cb, device)) {
                 goto out;
         }
@@ -1178,6 +1213,31 @@ out:
         return ret;
 }
 
+gboolean
+devkit_disks_device_local_is_busy (DevkitDisksDevice *device)
+{
+        gboolean ret;
+
+        ret = TRUE;
+
+        /* busy if a job is pending */
+        if (device->priv->job != NULL)
+                goto out;
+
+        /* or if we're mounted */
+        if (device->priv->info.device_is_mounted)
+                goto out;
+
+        /* or if another block device is using/holding us (e.g. if holders/ is non-empty in sysfs) */
+        if (device->priv->info.holders_objpath->len > 0)
+                goto out;
+
+        ret = FALSE;
+
+out:
+        return ret;
+}
+
 DevkitDisksDevice *
 devkit_disks_device_new (DevkitDisksDaemon *daemon, const char *native_path)
 {
index 44c9308..6fc19fd 100644 (file)
@@ -97,6 +97,8 @@ const char        *devkit_disks_device_local_get_mount_path (DevkitDisksDevice *
 void               devkit_disks_device_local_set_mounted (DevkitDisksDevice *device, const char *mount_path);
 void               devkit_disks_device_local_set_unmounted (DevkitDisksDevice *device);
 
+gboolean           devkit_disks_device_local_is_busy (DevkitDisksDevice *device);
+
 /* exported methods */
 
 gboolean devkit_disks_device_cancel_job (DevkitDisksDevice     *device,
index 6d6cd89..b28a13b 100644 (file)
          "/" to mean "not set" for object paths. -->
 
     <!-- The 'native-path' property is the OS native path for the
-         device; on Linux this is the sysfs path. -->
+         device; on Linux this is the sysfs path.
+
+         The 'device-is-busy' property is set if the device is
+         in use; this can hapen if it's mounted, if another
+         block device is claiming it or if a job initiated from
+         DeviceKit-disks is pending.
+      -->
     <property name="native-path" type="s" access="read"/>
     <property name="device-file" type="s" access="read"/>
     <property name="device-file-by-id" type="as" access="read"/>
     <property name="device-is-drive" type="b" access="read"/>
     <property name="device-is-mounted" type="b" access="read"/>
     <property name="device-is-crypto-cleartext" type="b" access="read"/>
+    <property name="device-is-busy" type="b" access="read"/>
     <property name="device-mount-path" type="s" access="read"/>
     <property name="device-size" type="t" access="read"/>
     <property name="device-block-size" type="t" access="read"/>
          e.g. 'Erase', 'CreateFilesystem' and so on.
 
          Note that the 'job-cur-task' percentage starts at 0.  The
-         percentage is a number between -1 and 100. If set to -1 it
-         means the progress of the current is unknown. The task id is
+         percentage is normally a number between 0 and 100. If set to -1
+         it means the progress of the current is unknown. The task id is
          a well-defined name defining the current subtask of the job;
          known tasks id's are
 
index f04b5b6..4372702 100644 (file)
@@ -450,6 +450,7 @@ typedef struct
         gboolean device_is_drive;
         gboolean device_is_crypto_cleartext;
         gboolean device_is_mounted;
+        gboolean device_is_busy;
         char    *device_mount_path;
         guint64  device_size;
         guint64  device_block_size;
@@ -520,6 +521,8 @@ collect_props (const char *key, const GValue *value, DeviceProperties *props)
                 props->device_is_crypto_cleartext = g_value_get_boolean (value);
         else if (strcmp (key, "device-is-mounted") == 0)
                 props->device_is_mounted = g_value_get_boolean (value);
+        else if (strcmp (key, "device-is-busy") == 0)
+                props->device_is_busy = g_value_get_boolean (value);
         else if (strcmp (key, "device-mount-path") == 0)
                 props->device_mount_path = g_strdup (g_value_get_string (value));
         else if (strcmp (key, "device-size") == 0)
@@ -729,6 +732,7 @@ do_show_info (const char *object_path)
         g_print ("  removable:     %d\n", props->device_is_removable);
         g_print ("  has media:     %d\n", props->device_is_media_available);
         g_print ("  is mounted:    %d\n", props->device_is_mounted);
+        g_print ("  is busy:       %d\n", props->device_is_busy);
         g_print ("  mount path:    %s\n", props->device_mount_path);
         g_print ("  size:          %lld\n", props->device_size);
         g_print ("  block size:    %lld\n", props->device_block_size);