rework partition table handling
authorDavid Zeuthen <davidz@redhat.com>
Tue, 31 Mar 2009 19:32:48 +0000 (15:32 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Tue, 31 Mar 2009 19:32:48 +0000 (15:32 -0400)
configure.ac
src/95-devkit-disks.rules
src/Makefile.am
src/devkit-disks-device-private.c
src/devkit-disks-device-private.h
src/devkit-disks-device.c
src/job-create-partition.c
src/org.freedesktop.DeviceKit.Disks.Device.xml
src/part-id.c
src/partutil.c
tools/devkit-disks.c

index 6da4ed6..14d178f 100644 (file)
@@ -143,6 +143,10 @@ PKG_CHECK_MODULES(LIBATASMART, [libatasmart >= 0.2])
 AC_SUBST(LIBATASMART_CFLAGS)
 AC_SUBST(LIBATASMART_LIBS)
 
+PKG_CHECK_MODULES(LIBUDEV, [libudev >= 139])
+AC_SUBST(LIBUDEV_CFLAGS)
+AC_SUBST(LIBUDEV_LIBS)
+
 if test "x$GCC" = "xyes"; then
   LDFLAGS="-Wl,--as-needed $LDFLAGS"
 fi
index 9e4b585..8327377 100644 (file)
@@ -17,20 +17,10 @@ KERNEL=="sr*", ENV{ID_CDROM_MEDIA_TRACK_COUNT}!="?*", GOTO="probe_parttable_end"
 
 # scan for partition table only if we're not a partition
 #
-ATTR{range}=="[0-9]*", IMPORT{program}="devkit-disks-part-id $tempnode"
-
-# for partitions, import parent information
-#
-#ATTR{start}=="[0-9]*", IMPORT{parent}="DKD_PART_*"
-
-# However.. right now we're not getting change events on media changes
-# *until* all the partitions are added.. so importing parent information
-# won't work; therefore, probe the partition table for each partition.
-#
-ATTR{start}=="[0-9]*", IMPORT{program}="devkit-disks-part-id $tempnode"
+IMPORT{program}="devkit-disks-part-id $tempnode"
 
 # clear all ID_FS_USAGE, TYPE if we're a partition table
-ATTR{range}=="[0-9]*", ENV{PART_P1_TYPE}!="", ENV{ID_FS_USAGE}="", ENV{ID_FS_TYPE}=""
+ENV{DKD_PART_ID_PARTITION_TABLE_SCHEME}!="", ENV{ID_FS_USAGE}="", ENV{ID_FS_TYPE}=""
 
 LABEL="probe_parttable_end"
 
index 834c01a..81e2901 100644 (file)
@@ -137,8 +137,8 @@ udevhelperdir = $(slashlibdir)/udev
 udevhelper_PROGRAMS = devkit-disks-part-id devkit-disks-dm-export devkit-disks-probe-ata-smart
 
 devkit_disks_part_id_SOURCES = part-id.c
-devkit_disks_part_id_CPPFLAGS = $(AM_CPPFLAGS)
-devkit_disks_part_id_LDADD = $(GLIB_LIBS) libpartutil.la
+devkit_disks_part_id_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUDEV_CFLAGS)
+devkit_disks_part_id_LDADD = $(GLIB_LIBS) $(LIBUDEV_LIBS) libpartutil.la
 
 devkit_disks_dm_export_SOURCES = devkit-disks-dm-export.c
 devkit_disks_dm_export_CPPFLAGS = $(AM_CPPFLAGS) $(DEVMAPPER_CFLAGS)
index 14735dc..9752523 100644 (file)
@@ -103,34 +103,6 @@ ptr_str_array_from_strv (GStrv s)
   return ret;
 }
 
-
-static gboolean
-array_equals (GArray * a, GArray * b, guint elem_size)
-{
-  if (a == NULL && b == NULL)
-    return TRUE;
-  if (a == NULL || b == NULL)
-    return FALSE;
-  if (a->len != b->len)
-    return FALSE;
-  if (a->len == 0)
-    return TRUE;
-  if (memcmp (a->data, b->data, a->len * elem_size) == 0)
-    return TRUE;
-  return FALSE;
-}
-
-static GArray *
-array_dup (GArray * a, guint elem_size)
-{
-  GArray *ret;
-
-  ret = g_array_sized_new (FALSE, FALSE, elem_size, a->len);
-  g_array_append_vals (ret, a->data, a->len);
-
-  return ret;
-}
-
 void
 devkit_disks_device_set_job_in_progress (DevkitDisksDevice *device, gboolean value)
 {
@@ -652,38 +624,6 @@ devkit_disks_device_set_partition_table_count (DevkitDisksDevice *device, gint v
 }
 
 void
-devkit_disks_device_set_partition_table_max_number (DevkitDisksDevice *device, gint value)
-{
-  if (G_UNLIKELY (device->priv->partition_table_max_number != value))
-    {
-      device->priv->partition_table_max_number = value;
-      emit_changed (device, "partition_table_max_number");
-    }
-}
-
-void
-devkit_disks_device_set_partition_table_offsets (DevkitDisksDevice *device, GArray * value)
-{
-  if (G_UNLIKELY (!array_equals (device->priv->partition_table_offsets, value, sizeof (guint64))))
-    {
-      g_array_free (device->priv->partition_table_offsets, TRUE);
-      device->priv->partition_table_offsets = array_dup (value, sizeof (guint64));
-      emit_changed (device, "partition_table_offsets");
-    }
-}
-
-void
-devkit_disks_device_set_partition_table_sizes (DevkitDisksDevice *device, GArray * value)
-{
-  if (G_UNLIKELY (!array_equals (device->priv->partition_table_sizes, value, sizeof (guint64))))
-    {
-      g_array_free (device->priv->partition_table_sizes, TRUE);
-      device->priv->partition_table_sizes = array_dup (value, sizeof (guint64));
-      emit_changed (device, "partition_table_sizes");
-    }
-}
-
-void
 devkit_disks_device_set_drive_vendor (DevkitDisksDevice *device, const gchar *value)
 {
   if (G_UNLIKELY (g_strcmp0 (device->priv->drive_vendor, value) != 0))
index 6774ad5..9bd3f10 100644 (file)
@@ -144,9 +144,6 @@ struct DevkitDisksDevicePrivate
 
         char *partition_table_scheme;
         int partition_table_count;
-        int partition_table_max_number;
-        GArray *partition_table_offsets;
-        GArray *partition_table_sizes;
 
         char *drive_vendor;
         char *drive_model;
@@ -277,9 +274,6 @@ void devkit_disks_device_set_partition_size (DevkitDisksDevice *device, guint64
 
 void devkit_disks_device_set_partition_table_scheme (DevkitDisksDevice *device, const gchar *value);
 void devkit_disks_device_set_partition_table_count (DevkitDisksDevice *device, gint value);
-void devkit_disks_device_set_partition_table_max_number (DevkitDisksDevice *device, gint value);
-void devkit_disks_device_set_partition_table_offsets (DevkitDisksDevice *device, GArray * value);
-void devkit_disks_device_set_partition_table_sizes (DevkitDisksDevice *device, GArray * value);
 
 void devkit_disks_device_set_drive_vendor (DevkitDisksDevice *device, const gchar *value);
 void devkit_disks_device_set_drive_model (DevkitDisksDevice *device, const gchar *value);
index d2200b3..fb7cd49 100644 (file)
@@ -186,9 +186,6 @@ enum
 
         PROP_PARTITION_TABLE_SCHEME,
         PROP_PARTITION_TABLE_COUNT,
-        PROP_PARTITION_TABLE_MAX_NUMBER,
-        PROP_PARTITION_TABLE_OFFSETS,
-        PROP_PARTITION_TABLE_SIZES,
 
         PROP_LUKS_HOLDER,
 
@@ -461,15 +458,6 @@ get_property (GObject         *object,
        case PROP_PARTITION_TABLE_COUNT:
                g_value_set_int (value, device->priv->partition_table_count);
                break;
-       case PROP_PARTITION_TABLE_MAX_NUMBER:
-               g_value_set_int (value, device->priv->partition_table_max_number);
-               break;
-       case PROP_PARTITION_TABLE_OFFSETS:
-               g_value_set_boxed (value, device->priv->partition_table_offsets);
-               break;
-       case PROP_PARTITION_TABLE_SIZES:
-               g_value_set_boxed (value, device->priv->partition_table_sizes);
-               break;
 
        case PROP_LUKS_HOLDER:
                 if (device->priv->luks_holder != NULL)
@@ -928,22 +916,6 @@ devkit_disks_device_class_init (DevkitDisksDeviceClass *klass)
                 object_class,
                 PROP_PARTITION_TABLE_COUNT,
                 g_param_spec_int ("partition-table-count", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE));
-        g_object_class_install_property (
-                object_class,
-                PROP_PARTITION_TABLE_MAX_NUMBER,
-                g_param_spec_int ("partition-table-max-number", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE));
-        g_object_class_install_property (
-                object_class,
-                PROP_PARTITION_TABLE_OFFSETS,
-                g_param_spec_boxed ("partition-table-offsets", NULL, NULL,
-                                    dbus_g_type_get_collection ("GArray", G_TYPE_UINT64),
-                                    G_PARAM_READABLE));
-        g_object_class_install_property (
-                object_class,
-                PROP_PARTITION_TABLE_SIZES,
-                g_param_spec_boxed ("partition-table-sizes", NULL, NULL,
-                                    dbus_g_type_get_collection ("GArray", G_TYPE_UINT64),
-                                    G_PARAM_READABLE));
 
         g_object_class_install_property (
                 object_class,
@@ -1206,8 +1178,6 @@ devkit_disks_device_init (DevkitDisksDevice *device)
         device->priv->device_file_by_id = g_ptr_array_new ();
         device->priv->device_file_by_path = g_ptr_array_new ();
         device->priv->partition_flags = g_ptr_array_new ();
-        device->priv->partition_table_offsets = g_array_new (FALSE, TRUE, sizeof (guint64));
-        device->priv->partition_table_sizes = g_array_new (FALSE, TRUE, sizeof (guint64));
         device->priv->drive_media_compatibility = g_ptr_array_new ();
         device->priv->linux_md_component_state = g_ptr_array_new ();
         device->priv->linux_md_slaves = g_ptr_array_new ();
@@ -1274,8 +1244,6 @@ devkit_disks_device_finalize (GObject *object)
         g_free (device->priv->partition_uuid);
         g_ptr_array_foreach (device->priv->partition_flags, (GFunc) g_free, NULL);
         g_ptr_array_free (device->priv->partition_flags, TRUE);
-        g_array_free (device->priv->partition_table_offsets, TRUE);
-        g_array_free (device->priv->partition_table_sizes, TRUE);
 
         g_free (device->priv->partition_table_scheme);
 
@@ -1450,12 +1418,11 @@ sysfs_get_uint64 (const char *dir, const char *attribute)
         result = 0;
         filename = g_build_filename (dir, attribute, NULL);
         if (g_file_get_contents (filename, &contents, NULL, NULL)) {
-                result = atoll (contents);
+                result = strtoll (contents, NULL, 0);
                 g_free (contents);
         }
         g_free (filename);
 
-
         return result;
 }
 
@@ -1707,63 +1674,17 @@ update_info_id (DevkitDisksDevice *device)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-/* update device_is_partition_table and partition_table_* properties */
+/* update partition_table_* properties */
 static gboolean
 update_info_partition_table (DevkitDisksDevice *device)
 {
-        guint n;
-
-        if (!device->priv->device_is_partition && devkit_device_has_property (device->priv->d, "DKD_PART_SCHEME")) {
-                GArray *offsets;
-                GArray *sizes;
+        if (!device->priv->device_is_partition &&
+            devkit_device_has_property (device->priv->d, "DKD_PARTITION_TABLE")) {
 
                 devkit_disks_device_set_device_is_partition_table (device, TRUE);
-                devkit_disks_device_set_partition_table_scheme (device, devkit_device_get_property (device->priv->d, "DKD_PART_SCHEME"));
-                devkit_disks_device_set_partition_table_count (device, devkit_device_get_property_as_int (device->priv->d, "DKD_PART_COUNT"));
-                devkit_disks_device_set_partition_table_max_number (device, devkit_device_get_property_as_int (device->priv->d, "DKD_PART_MAX_NUMBER"));
-
-                offsets = g_array_sized_new (FALSE, TRUE, sizeof (guint64), device->priv->partition_table_max_number);
-                sizes = g_array_sized_new (FALSE, TRUE, sizeof (guint64), device->priv->partition_table_max_number);
-                g_array_set_size (offsets, device->priv->partition_table_max_number);
-                g_array_set_size (sizes, device->priv->partition_table_max_number);
-
-                for (n = 0; n < (guint) device->priv->partition_table_max_number; n++) {
-                        gchar *part_key;
-                        guint64 offset;
-                        guint64 size;
-
-                        part_key = g_strdup_printf ("DKD_PART_P%d_OFFSET", n + 1);
-                        if (devkit_device_has_property (device->priv->d, part_key))
-                                offset = devkit_device_get_property_as_uint64 (device->priv->d, part_key);
-                        else
-                                offset = 0;
-                        g_free (part_key);
-
-                        part_key = g_strdup_printf ("DKD_PART_P%d_SIZE", n + 1);
-                        if (devkit_device_has_property (device->priv->d, part_key))
-                                size = devkit_device_get_property_as_uint64 (device->priv->d, part_key);
-                        else
-                                size = 0;
-                        g_free (part_key);
-
-                        g_array_index (offsets, guint64, n) = offset;
-                        g_array_index (sizes, guint64, n) = size;
-                }
-
-                devkit_disks_device_set_partition_table_offsets (device, offsets);
-                devkit_disks_device_set_partition_table_sizes (device, sizes);
-                g_array_free (offsets, TRUE);
-                g_array_free (sizes, TRUE);
+                devkit_disks_device_set_partition_table_scheme (device, devkit_device_get_property (device->priv->d, "DKD_PARTITION_TABLE_SCHEME"));
         } else {
-                GArray *empty_array;
-                devkit_disks_device_set_device_is_partition_table (device, FALSE);
-                empty_array = g_array_new (FALSE, TRUE, sizeof (guint64));
                 devkit_disks_device_set_partition_table_scheme (device, NULL);
-                devkit_disks_device_set_partition_table_count (device, 0);
-                devkit_disks_device_set_partition_table_max_number (device, 0);
-                devkit_disks_device_set_partition_table_offsets (device, empty_array);
-                devkit_disks_device_set_partition_table_sizes (device, empty_array);
-                g_array_free (empty_array, TRUE);
         }
 
         return TRUE;
@@ -1775,51 +1696,28 @@ update_info_partition_table (DevkitDisksDevice *device)
 static gboolean
 update_info_partition (DevkitDisksDevice *device)
 {
-        if (device->priv->device_is_partition) {
-                gchar *part_key;
-                guint64 offset;
+        guint64 offset;
+
+        offset = sysfs_get_uint64 (device->priv->native_path, "start") * device->priv->device_block_size;
+        devkit_disks_device_set_partition_offset (device, offset);
+
+        if (device->priv->device_is_partition &&
+            devkit_device_has_property (device->priv->d, "DKD_PARTITION")) {
                 guint64 size;
+                const gchar *scheme;
                 const gchar *type;
                 const gchar *label;
                 const gchar *uuid;
                 gchar **flags;
 
-                devkit_disks_device_set_partition_scheme (device, devkit_device_get_property (device->priv->d, "DKD_PART_SCHEME"));
-
-                part_key = g_strdup_printf ("DKD_PART_P%d_OFFSET", device->priv->partition_number);
-                if (devkit_device_has_property (device->priv->d, part_key))
-                        offset = devkit_device_get_property_as_uint64 (device->priv->d, part_key);
-                else
-                        offset = 0;
-                g_free (part_key);
-
-                part_key = g_strdup_printf ("DKD_PART_P%d_SIZE", device->priv->partition_number);
-                if (devkit_device_has_property (device->priv->d, part_key))
-                        size = devkit_device_get_property_as_uint64 (device->priv->d, part_key);
-                else
-                        size = 0;
-                g_free (part_key);
-
-                part_key = g_strdup_printf ("DKD_PART_P%d_TYPE", device->priv->partition_number);
-                type = devkit_device_get_property (device->priv->d, part_key);
-                g_free (part_key);
-
-                part_key = g_strdup_printf ("DKD_PART_P%d_LABEL", device->priv->partition_number);
-                label = devkit_device_get_property (device->priv->d, part_key);
-                g_free (part_key);
-
-                part_key = g_strdup_printf ("DKD_PART_P%d_UUID", device->priv->partition_number);
-                uuid = devkit_device_get_property (device->priv->d, part_key);
-                g_free (part_key);
-
-                part_key = g_strdup_printf ("DKD_PART_P%d_FLAGS", device->priv->partition_number);
-                if (devkit_device_has_property (device->priv->d, part_key))
-                        flags = devkit_device_dup_property_as_strv (device->priv->d, part_key);
-                else
-                        flags = NULL;
-                g_free (part_key);
+                scheme = devkit_device_get_property (device->priv->d, "DKD_PARTITION_SCHEME");
+                size = devkit_device_get_property_as_uint64 (device->priv->d, "DKD_PARTITION_SIZE");
+                type = devkit_device_get_property (device->priv->d, "DKD_PARTITION_TYPE");
+                label = devkit_device_get_property (device->priv->d, "DKD_PARTITION_LABEL");
+                uuid = devkit_device_get_property (device->priv->d, "DKD_PARTITION_UUID");
+                flags = devkit_device_dup_property_as_strv (device->priv->d, "DKD_PARTITION_FLAGS");
 
-                devkit_disks_device_set_partition_offset (device, offset);
+                devkit_disks_device_set_partition_scheme (device, scheme);
                 devkit_disks_device_set_partition_size (device, size);
                 devkit_disks_device_set_partition_type (device, type);
                 devkit_disks_device_set_partition_label (device, label);
@@ -1828,8 +1726,9 @@ update_info_partition (DevkitDisksDevice *device)
 
                 g_strfreev (flags);
         } else {
-                devkit_disks_device_set_partition_offset (device, 0);
-                devkit_disks_device_set_partition_size (device, 0);
+                /* if we don't have info from part_id, set the partition size to the same as the block device */
+                devkit_disks_device_set_partition_scheme (device, NULL);
+                devkit_disks_device_set_partition_size (device, device->priv->device_size);
                 devkit_disks_device_set_partition_type (device, NULL);
                 devkit_disks_device_set_partition_label (device, NULL);
                 devkit_disks_device_set_partition_uuid (device, NULL);
@@ -3023,15 +2922,35 @@ update_info (DevkitDisksDevice *device)
                 devkit_disks_device_set_partition_slave (device, compute_object_path_from_basename (p));
                 g_free (p);
                 g_free (s);
-
-                /* since the env from the parent is imported, we'll
-                 * add partition table information from enclosing
-                 * device by matching on partition number
-                 */
         } else {
                 /* TODO: handle partitions created by kpartx / dm-linear */
         }
 
+        /* Figure out if we are a partition table - we don't want to rely on devkit-disks-part-id
+         * for this; it might not detect all partition table formats that the kernel supports.
+         *
+         * The kernel guarantees that all childs are created before the uevent for the parent
+         * is created. So if we have childs, we must be a partition table.
+         *
+         * To detect a child we check for the existance of a subdir that has the parents
+         * name as a prefix (e.g. for parent sda then sda1, sda2, sdap1 etc. will work).
+         */
+        s = g_path_get_basename (device->priv->native_path);
+        if ((dir = g_dir_open (device->priv->native_path, 0, NULL)) != NULL) {
+                guint partition_count;
+                partition_count = 0;
+                while ((name = g_dir_read_name (dir)) != NULL) {
+                        if (g_str_has_prefix (name, s)) {
+                                partition_count++;
+                        }
+                }
+                g_dir_close (dir);
+                devkit_disks_device_set_partition_table_count (device, partition_count);
+                devkit_disks_device_set_device_is_partition_table (device, (partition_count > 0));
+        }
+        g_free (s);
+
+
         /* Maintain (non-exported) properties holders and slaves for the holders resp. slaves
          * directories in sysfs. The entries in these arrays are object paths - we ignore
          * an entry unless it corresponds to an device in our local database.
@@ -3103,6 +3022,7 @@ update_info (DevkitDisksDevice *device)
          *  - device_is_drive
          *  - device_is_media_available
          *  - device_is_partition
+         *  - device_is_partition_table
          *  - slaves_objpath
          *  - holders_objpath
          *
@@ -3119,7 +3039,7 @@ update_info (DevkitDisksDevice *device)
         if (!update_info_id (device))
                 goto out;
 
-        /* device_is_partition_table and partition_table_* properties */
+        /* partition_table_* properties */
         if (!update_info_partition_table (device))
                 goto out;
 
@@ -6085,12 +6005,10 @@ devkit_disks_device_partition_create (DevkitDisksDevice     *device,
         PolKitCaller *pk_caller;
         char *offset_as_string;
         char *size_as_string;
-        char *max_number_as_string;
         char *flags_as_string;
 
         offset_as_string = NULL;
         size_as_string = NULL;
-        max_number_as_string = NULL;
         flags_as_string = NULL;
 
         if ((pk_caller = devkit_disks_damon_local_get_caller_for_context (device->priv->daemon, context)) == NULL)
@@ -6119,16 +6037,8 @@ devkit_disks_device_partition_create (DevkitDisksDevice     *device,
                                                   context))
                 goto out;
 
-        if (strlen (type) == 0) {
-                throw_error (context,
-                             DEVKIT_DISKS_ERROR_FAILED,
-                             "type not specified");
-                goto out;
-        }
-
         offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", offset);
         size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", size);
-        max_number_as_string = g_strdup_printf ("%d", device->priv->partition_table_max_number);
         /* TODO: check that neither of the flags include ',' */
         flags_as_string = g_strjoinv (",", flags);
 
@@ -6137,7 +6047,6 @@ devkit_disks_device_partition_create (DevkitDisksDevice     *device,
         argv[n++] = device->priv->device_file;;
         argv[n++] = offset_as_string;
         argv[n++] = size_as_string;
-        argv[n++] = max_number_as_string;
         argv[n++] = (char *) type;
         argv[n++] = (char *) label;
         argv[n++] = (char *) flags_as_string;
@@ -6170,7 +6079,6 @@ devkit_disks_device_partition_create (DevkitDisksDevice     *device,
 out:
         g_free (offset_as_string);
         g_free (size_as_string);
-        g_free (max_number_as_string);
         g_free (flags_as_string);
         if (pk_caller != NULL)
                 polkit_caller_unref (pk_caller);
index f955e56..7b7d017 100644 (file)
@@ -56,12 +56,11 @@ main (int argc, char **argv)
         guint64 out_start;
         guint64 out_size;
         char *endp;
-        int max_number;
 
         ret = 1;
         flags = NULL;
 
-        if (argc < 8) {
+        if (argc < 7) {
                 g_printerr ("wrong usage\n");
                 goto out;
         }
@@ -76,15 +75,10 @@ main (int argc, char **argv)
                 g_printerr ("malformed size '%s'\n", argv[3]);
                 goto out;
         }
-        max_number = strtol (argv[4], &endp, 10);
-        if (*endp != '\0') {
-                g_printerr ("malformed max number '%s'\n", argv[4]);
-                goto out;
-        }
-        type = argv[5];
-        label = argv[6];
-        flags_as_string = argv[7];
-        options = argv + 8;
+        type = argv[4];
+        label = argv[5];
+        flags_as_string = argv[6];
+        options = argv + 7;
 
         flags = g_strsplit (flags_as_string, ",", 0);
 
index 842e662..3a87285 100644 (file)
             is TRUE.
       </doc:para></doc:description></doc:doc>
     </property>
-    <property name="partition-table-max-number" type="i" access="read">
-      <doc:doc><doc:description><doc:para>
-            The maximum value for
-            <doc:ref type="property" to="Device:partition-number">partition-number</doc:ref>
-            of the enclosed partitions (partitions may not be sequentially numbered).
-            This property is only valid if
-            <doc:ref type="property" to="Device:device-is-partition-table">device-is-partition-table</doc:ref>
-            is TRUE.
-      </doc:para></doc:description></doc:doc>
-    </property>
-    <property name="partition-table-offsets" type="at" access="read">
-      <doc:doc><doc:description><doc:para>
-            An array of size
-            <doc:ref type="property" to="Device:partition-table-max-number">partition-table-max-number</doc:ref>
-            that contains the offsets (in bytes) of each partition.
-            The property
-            <doc:ref type="property" to="Device:partition-number">partition-number</doc:ref>
-            on enclosed partitions can be used as an index in this array.
-            This property is only valid if
-            <doc:ref type="property" to="Device:device-is-partition-table">device-is-partition-table</doc:ref>
-            is TRUE.
-      </doc:para></doc:description></doc:doc>
-    </property>
-    <property name="partition-table-sizes" type="at" access="read">
-      <doc:doc><doc:description><doc:para>
-            An array of size
-            <doc:ref type="property" to="Device:partition-table-max-number">partition-table-max-number</doc:ref>
-            that contains the size (in bytes) of each partition.
-            The property
-            <doc:ref type="property" to="Device:partition-number">partition-number</doc:ref>
-            on enclosed partitions can be used as an index in this array.
-            This property is only valid if
-            <doc:ref type="property" to="Device:device-is-partition-table">device-is-partition-table</doc:ref>
-            is TRUE.
-      </doc:para></doc:description></doc:doc>
-    </property>
 
     <property name="drive-vendor" type="s" access="read">
       <doc:doc><doc:description><doc:para>
index 3708d98..b37d48e 100644 (file)
@@ -1,3 +1,22 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
+#include <libudev.h>
+
 #include "partutil.h"
 
 static void
 usage (int argc, char *argv[])
 {
         execlp ("man", "man", "part_id", NULL);
-        fprintf (stderr, "Cannot show man page: %m\n");
+        g_printerr ("Cannot show man page: %m\n");
         exit (1);
 }
 
+#if 0
 static void
 print_entry (PartitionTable *p, int entry, int print_number)
 {
@@ -52,11 +75,106 @@ print_entry (PartitionTable *p, int entry, int print_number)
         g_free (flags_combined);
 }
 
+static GString *e_types;
+static GString *e_offsets;
+static GString *e_sizes;
+static GString *e_labels;
+static GString *e_uuids;
+static GString *e_flags;
+
+static void
+entries_begin (void)
+{
+        e_types = g_string_new (NULL);
+        e_offsets = g_string_new (NULL);
+        e_sizes = g_string_new (NULL);
+        e_labels = g_string_new (NULL);
+        e_uuids = g_string_new (NULL);
+        e_flags = g_string_new (NULL);
+}
+
+static void
+entries_add (PartitionTable *p, int entry, int print_number)
+{
+        char *type;
+        char *label;
+        char *uuid;
+        char **flags;
+        char *flags_combined;
+        guint64 offset;
+        guint64 size;
+
+        type = part_table_entry_get_type (p, entry);
+        label = part_table_entry_get_label (p, entry);
+        uuid = part_table_entry_get_uuid (p, entry);
+        flags = part_table_entry_get_flags (p, entry);
+        offset = part_table_entry_get_offset (p, entry);
+        size = part_table_entry_get_size (p, entry);
+
+        flags_combined = g_strjoinv (" ", flags);
+
+        if (e_types->len != 0)
+                g_string_append_c (e_types, ' ');
+        if (e_offsets->len != 0)
+                g_string_append_c (e_offsets, ' ');
+        if (e_sizes->len != 0)
+                g_string_append_c (e_sizes, ' ');
+        if (e_labels->len != 0)
+                g_string_append_c (e_labels, ' ');
+        if (e_uuids->len != 0)
+                g_string_append_c (e_uuids, ' ');
+        if (e_flags->len != 0)
+                g_string_append_c (e_flags, ' ');
+
+        /* TODO: escape label */
+
+        g_string_append_printf (e_types, "%s", type != NULL ? type : "");
+        g_string_append_printf (e_offsets, "%" G_GINT64_FORMAT, offset);
+        g_string_append_printf (e_sizes, "%" G_GINT64_FORMAT, size);
+        g_string_append_printf (e_labels, "%s", label != NULL ? label : "");
+        g_string_append_printf (e_uuids, "%s", uuid != NULL ? uuid : "");
+        g_string_append_printf (e_flags, "%s", flags_combined);
+
+        g_free (type);
+        g_free (label);
+        g_free (uuid);
+        g_strfreev (flags);
+        g_free (flags_combined);
+}
+
+static void
+entries_print (void)
+{
+        printf ("DKD_PART_TYPES=%s\n", e_types->str);
+        printf ("DKD_PART_OFFSETS=%s\n", e_offsets->str);
+        printf ("DKD_PART_SIZES=%s\n", e_sizes->str);
+        printf ("DKD_PART_LABELS=%s\n", e_labels->str);
+        printf ("DKD_PART_UUIDS=%s\n", e_uuids->str);
+        printf ("DKD_PART_FLAGS=%s\n", e_flags->str);
+}
+
+static void
+entries_end (void)
+{
+        g_string_free (e_types, TRUE);
+        g_string_free (e_offsets, TRUE);
+        g_string_free (e_sizes, TRUE);
+        g_string_free (e_labels, TRUE);
+        g_string_free (e_uuids, TRUE);
+        g_string_free (e_flags, TRUE);
+        e_types = NULL;
+        e_offsets = NULL;
+        e_sizes = NULL;
+        e_labels = NULL;
+        e_uuids = NULL;
+        e_flags = NULL;
+}
+
 static void
 do_table (int fd)
 {
-        int n;
-        guint max_number;
+        gint n;
+        gint max_number;
         PartitionTable *table;
         PartitionTable *nested_table;
         int num_entries;
@@ -99,21 +217,28 @@ do_table (int fd)
         printf ("DKD_PART_SCHEME=%s\n", part_get_scheme_name (part_table_get_scheme (table)));
         printf ("DKD_PART_COUNT=%d\n", num_used_entries + num_nested_entries);
 
+        entries_begin ();
+
         max_number = 0;
         for (n = 0; n < num_entries; n++) {
                 if (!part_table_entry_is_in_use (table, n))
                         continue;
                 print_entry (table, n, n + 1);
+                entries_add (table, n, n + 1);
                 if (n + 1 >= max_number)
                          max_number = n + 1;
         }
 
         for (n = 0; n < num_nested_entries; n++) {
                 print_entry (nested_table, n, n + 5);
+                entries_add (table, n, n + 1);
                 if (n + 5 >= max_number)
                          max_number = n + 5;
         }
 
+        //entries_print ();
+        entries_end ();
+
         printf ("DKD_PART_MAX_NUMBER=%d\n", max_number);
 out:
         if (table != NULL)
@@ -167,17 +292,17 @@ get_devpath (const char *device)
 
                 /* ok, so this means we're not invoked from udev; do
                  * some lipservice, because we're such nice and
-                 * gullibe guys..  we run udevinfo to determine the
+                 * gullibe guys..  we run udevadm to determine the
                  * devpath
                  */
                 error = NULL;
-                command_line = g_strdup_printf ("udevinfo -q path --name %s",device);
+                command_line = g_strdup_printf ("udevadm info -q path --name %s", device);
                 if (!g_spawn_command_line_sync (command_line,
                                                 &standard_output,
                                                 NULL,
                                                 &exit_status,
                                                 &error)) {
-                        fprintf (stderr, "couldn't run udevinfo to determine node: %s", error->message);
+                        fprintf (stderr, "error running udevadm to determine node: %s", error->message);
                         g_error_free (error);
                         g_free (command_line);
                         goto out;
@@ -284,17 +409,70 @@ not_part:
         }
         return fd;
 }
+#endif
+
+static int
+sysfs_get_int (const char *dir, const char *attribute)
+{
+        int result;
+        char *contents;
+        char *filename;
+
+        result = 0;
+        filename = g_build_filename (dir, attribute, NULL);
+        if (g_file_get_contents (filename, &contents, NULL, NULL)) {
+                result = strtol (contents, NULL, 0);
+                g_free (contents);
+        }
+        g_free (filename);
+
+
+        return result;
+}
+
+static guint64
+sysfs_get_uint64 (const char *dir, const char *attribute)
+{
+        guint64 result;
+        char *contents;
+        char *filename;
+
+        result = 0;
+        filename = g_build_filename (dir, attribute, NULL);
+        if (g_file_get_contents (filename, &contents, NULL, NULL)) {
+                result = strtoll (contents, NULL, 0);
+                g_free (contents);
+        }
+        g_free (filename);
+
+        return result;
+}
 
 int
 main (int argc, char *argv[])
 {
-        int n;
-        int fd;
-        char *device_file;
-        gboolean is_part;
+        guint n;
+        gint fd;
+        gint partition_number;
+        gchar *devpath;
+        const gchar *device_file;
+        gchar *partition_table_device_file;
+        struct udev *udev;
+        PartitionTable *partition_table;
+
+        udev = NULL;
+        devpath = NULL;
+        partition_table_device_file = NULL;
+        partition_table = NULL;
+
+        udev = udev_new ();
+        if (udev == NULL) {
+                g_printerr ("Error initializing libudev: %m\n");
+                goto out;
+        }
 
         device_file = NULL;
-        for (n = 1; n < argc; n++) {
+        for (n = 1; n < (guint) argc; n++) {
                 if (strcmp (argv[n], "--help") == 0) {
                         usage (argc, argv);
                         return 0;
@@ -306,30 +484,144 @@ main (int argc, char *argv[])
        }
 
         if (device_file == NULL) {
-                fprintf (stderr, "no device\n");
+                g_printerr ("no device\n");
                 goto out;
         }
 
-        fd = open_device (device_file, &is_part);
-        if (fd >= 0) {
-                char *usage;
-
-                if (!is_part) {
-                        /* we currently errornously detect a vfat fs on the whole disk as a partition table.
-                         * Avoid doing that.
-                         */
-                        usage = getenv ("ID_FS_USAGE");
-                        if (usage != NULL && strcmp (usage, "filesystem") == 0) {
-                                close (fd);
-                                goto out;
-                        }
+        devpath = getenv ("DEVPATH");
+        if (devpath != NULL) {
+                devpath = g_build_filename ("/sys", devpath, NULL);
+        } else {
+                struct udev_device *device;
+                struct stat statbuf;
+
+                if (stat (device_file, &statbuf) != 0) {
+                        g_printerr ("Error statting %s: %m\n", device_file);
+                        goto out;
+                }
+
+                device = udev_device_new_from_devnum (udev, 'b', statbuf.st_rdev);
+                if (device == NULL) {
+                        g_printerr ("Error getting udev device for %s: %m\n", device_file);
+                        goto out;
+                }
+                devpath = g_strdup (udev_device_get_syspath (device));
+                udev_device_unref (device);
+        }
+
+        partition_number = sysfs_get_int (devpath, "partition");
+
+        /* find device file for partition table device */
+        if (partition_number > 0) {
+                struct udev_device *device;
+                gchar *partition_table_devpath;
+
+                /* partition */
+                partition_table_devpath = g_strdup (devpath);
+                for (n = strlen (partition_table_devpath) - 1; partition_table_devpath[n] != '/'; n--)
+                        partition_table_devpath[n] = '\0';
+                partition_table_devpath[n] = '\0';
+
+                device = udev_device_new_from_syspath (udev, partition_table_devpath);
+                if (device == NULL) {
+                        g_printerr ("Error getting udev device for syspath %s: %m\n", partition_table_devpath);
+                        goto out;
+                }
+                partition_table_device_file = g_strdup (udev_device_get_devnode (device));
+                udev_device_unref (device);
+                g_free (partition_table_devpath);
+        } else {
+                /* not partition */
+                partition_table_device_file = g_strdup (device_file);
+        }
+
+        fd = open (partition_table_device_file, O_RDONLY);
+
+        /* TODO: right now we also use part_id to determine if media is available or not. This
+         *       should probably be done elsewhere
+         */
+        if (partition_number == 0) {
+                if (fd < 0) {
+                        g_print ("DKD_MEDIA_AVAILABLE=0\n");
+                } else {
+                        g_print ("DKD_MEDIA_AVAILABLE=1\n");
                 }
+        }
 
-                do_table (fd);
-                close (fd);
+        if (fd < 0) {
+                g_printerr ("Error opening %s: %m\n", partition_table_device_file);
+                goto out;
+        }
+        partition_table = part_table_load_from_disk (fd);
+        if (partition_table == NULL) {
+                g_printerr ("No partition table found on %s: %m\n", partition_table_device_file);
+                goto out;
+        }
+        close (fd);
+
+        if (partition_number > 0) {
+                guint64 partition_offset;
+                PartitionTable *partition_table_for_entry;
+                gint entry_num;
+                gchar *type;
+                gchar *label;
+                gchar *uuid;
+                gchar **flags;
+                gchar *flags_combined;
+                guint64 offset;
+                guint64 size;
+
+                /* partition */
+                partition_offset = sysfs_get_uint64 (devpath, "start") * 512;
+                part_table_find (partition_table,
+                                 partition_offset,
+                                 &partition_table_for_entry,
+                                 &entry_num);
+                if (entry_num == -1) {
+                        g_printerr ("Error finding partition at offset %" G_GUINT64_FORMAT " on %s\n",
+                                    partition_offset,
+                                    partition_table_device_file);
+                        goto out;
+                }
+
+                type = part_table_entry_get_type (partition_table_for_entry, entry_num);
+                label = part_table_entry_get_label (partition_table_for_entry, entry_num);
+                uuid = part_table_entry_get_uuid (partition_table_for_entry, entry_num);
+                flags = part_table_entry_get_flags (partition_table_for_entry, entry_num);
+                offset = part_table_entry_get_offset (partition_table_for_entry, entry_num);
+                size = part_table_entry_get_size (partition_table_for_entry, entry_num);
+
+                flags_combined = g_strjoinv (" ", flags);
+
+                g_print ("DKD_PARTITION=1\n");
+                g_print ("DKD_PARTITION_SCHEME=%s\n",
+                         part_get_scheme_name (part_table_get_scheme (partition_table_for_entry)));
+                g_print ("DKD_PARTITION_NUMBER=%d\n", partition_number);
+                g_print ("DKD_PARTITION_TYPE=%s\n", type != NULL ? type : "");
+                g_print ("DKD_PARTITION_SIZE=%" G_GINT64_FORMAT "\n", size);
+                g_print ("DKD_PARTITION_LABEL=%s\n", label != NULL ? label : "");
+                g_print ("DKD_PARTITION_UUID=%s\n", uuid != NULL ? uuid : "");
+                g_print ("DKD_PARTITION_FLAGS=%s\n", flags_combined);
+
+                g_free (type);
+                g_free (label);
+                g_free (uuid);
+                g_strfreev (flags);
+                g_free (flags_combined);
+        } else {
+                g_print ("DKD_PARTITION_TABLE=1\n");
+                g_print ("DKD_PARTITION_TABLE_SCHEME=%s\n",
+                         part_get_scheme_name (part_table_get_scheme (partition_table)));
         }
 
 out:
+        g_free (devpath);
+        g_free (partition_table_device_file);
+        if (partition_table != NULL)
+                part_table_free (partition_table);
+        if (udev != NULL)
+                udev_unref (udev);
+
         return 0;
 }
 
index 795b896..8b5663c 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
 /***************************************************************************
  *
  * part.c : library for reading and writing partition tables - uses
@@ -1278,9 +1280,6 @@ part_add_change_partition (char *device_file,
        guint64 end_sector;
        guint64 new_start_sector;
        guint64 new_end_sector;
-       PartitionTable *p;
-       PartitionTable *container_p;
-       int container_entry;
        PartitionScheme scheme;
        guint8 mbr_flags = 0;
        guint8 mbr_part_type = 0;
@@ -1301,51 +1300,63 @@ part_add_change_partition (char *device_file,
                DEBUG ("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type);
        }
 
-       /* first, find the kind of (embedded) partition table the new partition is going to be part of */
-       p = part_table_load_from_disk_from_file (device_file);
-       if (p == NULL) {
-               DEBUG ("Cannot load partition table from %s", device_file);
-               goto out;
-       }
+        scheme = -1;
+       if (is_change) {
+                PartitionTable *p;
+                PartitionTable *container_p;
+                int container_entry;
 
-       part_table_find (p, start + 512, &container_p, &container_entry);
-       scheme = part_table_get_scheme (container_p);
+                /* if changing something, make sure the partition to change actually exists */
+
+                p = part_table_load_from_disk_from_file (device_file);
+                if (p == NULL) {
+                        DEBUG ("Cannot load partition table from %s", device_file);
+                        goto out;
+                }
+                part_table_find (p, start + 512, &container_p, &container_entry);
+                scheme = part_table_get_scheme (container_p);
+                DEBUG ("containing partition table scheme = %d", scheme);
+                part_table_free (p);
 
-       if (is_change) {
-               /* if changing, make sure there is a partition to change */
                if (container_entry < 0) {
                        DEBUG ("Couldn't find partition to change");
                        goto out;
                }
        } else {
-               /* if adding, make sure there is no partition in the way... */
-               if (container_entry >= 0) {
-                       char *part_type;
-
-                       /* this might be Apple_Free if we're on PART_TYPE_APPLE */
-                       part_type = part_table_entry_get_type (p, container_entry);
-                       if (! (p->scheme == PART_TYPE_APPLE && part_type != NULL && (strcmp (part_type, "Apple_Free") == 0))) {
-                               part_table_free (p);
-                               DEBUG ("There is a partition in the way on %s", device_file);
-                               goto out;
-                       }
-               }
-       }
+                PartitionTable *p;
+                PartitionTable *container_p;
+                int container_entry;
+
+                /* if adding, try to find the scheme of the partition table.. don't error out if we can't find it */
+                p = part_table_load_from_disk_from_file (device_file);
+                if (p != NULL) {
+                        part_table_find (p, start + 512, &container_p, &container_entry);
+                        scheme = part_table_get_scheme (container_p);
+                        DEBUG ("containing partition table scheme = %d", scheme);
+                        part_table_free (p);
+                }
+        }
 
-       DEBUG ("containing partition table scheme = %d", scheme);
+       /* now that we know the partitoning scheme, sanity check type and flags */
+       switch (scheme) {
+        case -1:
+                /* unknown partition table format; error out if any type, label or flags are given */
+                if ((flags != NULL && flags[0] != NULL)) {
+                        DEBUG ("unknown partition table format and flags is not empty");
+                        goto out;
+                }
 
-       part_table_free (p);
-       p = NULL;
+                if (type != NULL && strlen (type) > 0) {
+                        DEBUG ("unknown partition table format and type is not empty");
+                        goto out;
+                }
 
-       if (!is_change) {
-               if (type == NULL) {
-                       DEBUG ("No type specified");
-                       goto out;
-               }
-       }
+                if (label != NULL && strlen (label) > 0) {
+                        DEBUG ("unknown partition table format and label is not empty");
+                        goto out;
+                }
+                break;
 
-       /* now that we know the partitoning scheme, sanity check type and flags */
-       switch (scheme) {
        case PART_TYPE_MSDOS:
        case PART_TYPE_MSDOS_EXTENDED:
                mbr_flags = 0;
@@ -1730,7 +1741,7 @@ part_del_partition (char *device_file, guint64 offset, gboolean poke_kernel)
        PedDevice *device;
        PedDisk *disk;
        PedPartition *part;
-       PartitionTable *p;
+        PartitionTable *p;
        gboolean is_extended;
        int n;
 
@@ -1749,21 +1760,19 @@ part_del_partition (char *device_file, guint64 offset, gboolean poke_kernel)
         */
        is_extended = FALSE;
        p = part_table_load_from_disk_from_file (device_file);
-       if (p == NULL) {
-               DEBUG ("Cannot load partition table from %s", device_file);
-               goto out;
-       }
-       for (n = 0; n < part_table_get_num_entries (p); n++) {
-               PartitionTable *nested;
-               nested = part_table_entry_get_nested (p, n);
-               if (nested != NULL) {
-                       if (part_table_get_offset (nested) == offset) {
-                               DEBUG ("partition to delete is an extended partition");
-                               is_extended = TRUE;
-                       }
-               }
-       }
-       part_table_free (p);
+       if (p != NULL) {
+                for (n = 0; n < part_table_get_num_entries (p); n++) {
+                        PartitionTable *nested;
+                        nested = part_table_entry_get_nested (p, n);
+                        if (nested != NULL) {
+                                if (part_table_get_offset (nested) == offset) {
+                                        DEBUG ("partition to delete is an extended partition");
+                                        is_extended = TRUE;
+                                }
+                        }
+                }
+                part_table_free (p);
+        }
 
        device = ped_device_get (device_file);
        if (device == NULL) {
@@ -1791,13 +1800,21 @@ part_del_partition (char *device_file, guint64 offset, gboolean poke_kernel)
        }
 
        DEBUG ("got partition - part->type=%d", part->type);
-       /* allow only to delete primary, logical and extended partitions */
-       if (! ((part->type == PED_PARTITION_NORMAL) ||
-              (part->type == PED_PARTITION_LOGICAL) ||
-              (part->type == PED_PARTITION_EXTENDED))) {
-               DEBUG ("no data partition at given offset %lld for device %s", offset, device_file);
-               goto out_ped_disk;
-       }
+
+        if (part->type & PED_PARTITION_METADATA) {
+                DEBUG ("refusing to delete a metadata partition");
+                goto out_ped_disk;
+        }
+
+        if (part->type & PED_PARTITION_PROTECTED) {
+                DEBUG ("refusing to delete a protected partition");
+                goto out_ped_disk;
+        }
+
+        if (part->type & PED_PARTITION_FREESPACE) {
+                DEBUG ("refusing to delete a protected partition");
+                goto out_ped_disk;
+        }
 
        if (ped_disk_delete_partition (disk, part) == 0) {
                DEBUG ("ped_disk_delete_partition() failed");
index c0508bd..47ebe9f 100644 (file)
@@ -302,18 +302,18 @@ device_removed_signal_handler (DBusGProxy *proxy, const char *object_path, gpoin
   g_print ("removed:   %s\n", object_path);
 }
 
-#define ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
-                                                                      G_TYPE_UINT, \
-                                                                      G_TYPE_STRING, \
-                                                                      G_TYPE_UINT, \
-                                                                      G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
-                                                                      G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
-                                                                      G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
-                                                                      G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
-                                                                      G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
-                                                                      G_TYPE_UINT, G_TYPE_UINT64, \
-                                                                      dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), \
-                                                                      G_TYPE_INVALID))
+#define ATA_SMART_ATTRIBUTE_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
+                                                                 G_TYPE_UINT, \
+                                                                 G_TYPE_STRING, \
+                                                                 G_TYPE_UINT, \
+                                                                 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
+                                                                 G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
+                                                                 G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
+                                                                 G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
+                                                                 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
+                                                                 G_TYPE_UINT, G_TYPE_UINT64, \
+                                                                 dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), \
+                                                                 G_TYPE_INVALID))
 
 #define ATA_SMART_HISTORICAL_SMART_DATA_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray",   \
                                                                              G_TYPE_UINT64, \
@@ -400,9 +400,6 @@ typedef struct
 
         char    *partition_table_scheme;
         int      partition_table_count;
-        int      partition_table_max_number;
-        GArray  *partition_table_offsets;
-        GArray  *partition_table_sizes;
 
         char    *luks_holder;
 
@@ -585,19 +582,6 @@ collect_props (const char *key, const GValue *value, DeviceProperties *props)
                 props->partition_table_scheme = g_strdup (g_value_get_string (value));
         else if (strcmp (key, "partition-table-count") == 0)
                 props->partition_table_count = g_value_get_int (value);
-        else if (strcmp (key, "partition-table-max-number") == 0)
-                props->partition_table_max_number = g_value_get_int (value);
-        else if (strcmp (key, "partition-table-offsets") == 0) {
-                GValue dest_value = {0,};
-                g_value_init (&dest_value, dbus_g_type_get_collection ("GArray", G_TYPE_UINT64));
-                g_value_copy (value, &dest_value);
-                props->partition_table_offsets = g_value_get_boxed (&dest_value);
-        } else if (strcmp (key, "partition-table-sizes") == 0) {
-                GValue dest_value = {0,};
-                g_value_init (&dest_value, dbus_g_type_get_collection ("GArray", G_TYPE_UINT64));
-                g_value_copy (value, &dest_value);
-                props->partition_table_sizes = g_value_get_boxed (&dest_value);
-        }
 
         else if (strcmp (key, "luks-holder") == 0)
                 props->luks_holder = g_strdup (g_value_get_boxed (value));
@@ -764,10 +748,6 @@ device_properties_free (DeviceProperties *props)
         g_free (props->partition_uuid);
         g_strfreev (props->partition_flags);
         g_free (props->partition_table_scheme);
-        if (props->partition_table_offsets != NULL)
-                g_array_free (props->partition_table_offsets, TRUE);
-        if (props->partition_table_sizes != NULL)
-                g_array_free (props->partition_table_sizes, TRUE);
         g_free (props->luks_holder);
         g_free (props->luks_cleartext_slave);
         g_free (props->drive_model);
@@ -811,7 +791,7 @@ device_properties_get (DBusGConnection *bus,
 
         props = g_new0 (DeviceProperties, 1);
         g_value_init (&(props->drive_ata_smart_attributes),
-                      dbus_g_type_get_collection ("GPtrArray", ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE));
+                      dbus_g_type_get_collection ("GPtrArray", ATA_SMART_ATTRIBUTE_STRUCT_TYPE));
 
        prop_proxy = dbus_g_proxy_new_for_name (bus,
                                                 "org.freedesktop.DeviceKit.Disks",
@@ -1089,7 +1069,6 @@ do_show_info (const char *object_path)
                 g_print ("  partition table:\n");
                 g_print ("    scheme:                %s\n", props->partition_table_scheme);
                 g_print ("    count:                 %d\n", props->partition_table_count);
-                g_print ("    max number:            %d\n", props->partition_table_max_number);
         }
         if (props->device_is_partition) {
                 g_print ("  partition:\n");
@@ -1251,7 +1230,7 @@ do_show_info (const char *object_path)
                                 gboolean do_highlight;
                                 GArray *raw_data;
 
-                                g_value_init (&elem, ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE);
+                                g_value_init (&elem, ATA_SMART_ATTRIBUTE_STRUCT_TYPE);
                                 g_value_set_static_boxed (&elem, p->pdata[m]);
 
                                 dbus_g_type_struct_get (&elem,