[PATCH 1/2] libparted: add disk flag functions and PED_DISK_CYLINDER_ALIGNMENT flag

Hans de Goede hdegoede at redhat.com
Wed Dec 9 14:38:00 UTC 2009


Sometimes we want to be able to set flags at the disk level rather then
at the parition level, to influence how new partitions will be created
for example.  This patch adds functions to do this (modelled after the
partition flag functions), and adds a PED_DISK_CYLINDER_ALIGNMENT flag.

This flag (which defaults to true) controls if disk types for which
cylinder alignment is optional do cylinder alignment when a new
partition gets added. This flag is available for msdos and sun
disklabels (for sun labels it only controls the aligning of the end of
the partition).
* include/parted/disk.h (PedDiskFlag): New type
* include/parted/disk.h (ped_disk_set_flag, ped_disk_get_flag,
ped_disk_is_flag_available): new functions and PedDiskOps members
* include/parted/disk.h (ped_disk_flag_get_name,
ped_disk_flag_get_by_name, ped_disk_flag_next): new functions
* libparted/disk.c (ped_disk_set_flag, ped_disk_get_flag,
ped_disk_is_flag_available, ped_disk_flag_get_name,
ped_disk_flag_get_by_name, ped_disk_flag_next): new functions
---
 include/parted/disk.h |   33 +++++++++++++
 libparted/disk.c      |  124 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/include/parted/disk.h b/include/parted/disk.h
index cb5d179..eb8e37b 100644
--- a/include/parted/disk.h
+++ b/include/parted/disk.h
@@ -27,6 +27,20 @@
 #define PED_DISK_H_INCLUDED

 /**
+ * Disk flags
+ */
+enum _PedDiskFlag {
+        /* This flag (which defaults to true) controls if disk types for
+           which cylinder alignment is optional do cylinder alignment when a
+           new partition gets added.
+           This flag is available for msdos and sun disklabels (for sun labels
+           it only controls the aligning of the end of the partition) */
+        PED_DISK_CYLINDER_ALIGNMENT=1,
+};
+#define PED_DISK_FIRST_FLAG             PED_DISK_CYLINDER_ALIGNMENT
+#define PED_DISK_LAST_FLAG              PED_DISK_CYLINDER_ALIGNMENT
+
+/**
  * Partition types
  */
 enum _PedPartitionType {
@@ -71,6 +85,7 @@ struct _PedDiskOps;
 struct _PedDiskType;
 struct _PedDiskArchOps;

+typedef enum _PedDiskFlag               PedDiskFlag;
 typedef enum _PedPartitionType          PedPartitionType;
 typedef enum _PedPartitionFlag          PedPartitionFlag;
 typedef enum _PedDiskTypeFeature        PedDiskTypeFeature;
@@ -179,6 +194,16 @@ struct _PedDiskOps {
         void (*free) (PedDisk* disk);
         int (*read) (PedDisk* disk);
         int (*write) (const PedDisk* disk);
+        int (*disk_set_flag) (
+                PedDisk *disk,
+                PedDiskFlag flag,
+                int state);
+        int (*disk_get_flag) (
+                const PedDisk *disk,
+                PedDiskFlag flag);
+        int (*disk_is_flag_available) (
+                const PedDisk *disk,
+                PedDiskFlag flag);
         /** \todo add label guessing op here */

         /* partition operations */
@@ -266,6 +291,14 @@ extern bool ped_disk_get_max_supported_partition_count(const PedDisk* disk,
                                                        int* supported);
 extern PedAlignment *ped_disk_get_partition_alignment(const PedDisk *disk);

+extern int ped_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state);
+extern int ped_disk_get_flag(const PedDisk *disk, PedDiskFlag flag);
+extern int ped_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag);
+
+extern const char *ped_disk_flag_get_name(PedDiskFlag flag);
+extern PedDiskFlag ped_disk_flag_get_by_name(const char *name);
+extern PedDiskFlag ped_disk_flag_next(PedDiskFlag flag);
+
 /** @} */

 /**
diff --git a/libparted/disk.c b/libparted/disk.c
index a615d36..e8014d1 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -738,6 +738,130 @@ ped_disk_get_max_primary_partition_count (const PedDisk* disk)
 }

 /**
+ * Set the state (\c 1 or \c 0) of a flag on a disk.
+ *
+ * \note It is an error to call this on an unavailable flag -- use
+ * ped_disk_is_flag_available() to determine which flags are available
+ * for a given disk label.
+ *
+ * \throws PED_EXCEPTION_ERROR if the requested flag is not available for this
+ *      label.
+ */
+int
+ped_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state)
+{
+        PED_ASSERT (disk != NULL, return 0);
+
+        PedDiskOps *ops = disk->type->ops;
+
+        if (!ped_disk_is_flag_available(disk, flag)) {
+                ped_exception_throw (
+                        PED_EXCEPTION_ERROR,
+                        PED_EXCEPTION_CANCEL,
+                        "The flag '%s' is not available for %s disk labels.",
+                        ped_disk_flag_get_name(flag),
+                        disk->type->name);
+                return 0;
+        }
+
+        return ops->disk_set_flag(disk, flag, state);
+}
+
+/**
+ * Get the state (\c 1 or \c 0) of a flag on a disk.
+ */
+int
+ped_disk_get_flag(const PedDisk *disk, PedDiskFlag flag)
+{
+        PED_ASSERT (disk != NULL, return 0);
+
+        PedDiskOps *ops = disk->type->ops;
+
+        if (!ped_disk_is_flag_available(disk, flag))
+                return 0;
+
+        return ops->disk_get_flag(disk, flag);
+}
+
+/**
+ * Check whether a given flag is available on a disk.
+ *
+ * \return \c 1 if the flag is available.
+ */
+int
+ped_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag)
+{
+        PED_ASSERT (disk != NULL, return 0);
+
+        PedDiskOps *ops = disk->type->ops;
+
+        if (!ops->disk_is_flag_available)
+                return 0;
+
+        return ops->disk_is_flag_available(disk, flag);
+}
+
+/**
+ * Returns a name for a \p flag, e.g. PED_DISK_CYLINDER_ALIGNMENT will return
+ * "cylinder_alignment".
+ *
+ * \note The returned string will be in English.  However,
+ * translations are provided, so the caller can call
+ * dgettext("parted", RESULT) on the result.
+ */
+const char *
+ped_disk_flag_get_name(PedDiskFlag flag)
+{
+        switch (flag) {
+        case PED_DISK_CYLINDER_ALIGNMENT:
+                return N_("cylinder_alignment");
+
+        default:
+                ped_exception_throw (
+                        PED_EXCEPTION_BUG,
+                        PED_EXCEPTION_CANCEL,
+                        _("Unknown disk flag, %d."),
+                        flag);
+                return NULL;
+        }
+}
+
+/**
+ * Returns the flag associated with \p name.
+ *
+ * \p name can be the English
+ * string, or the translation for the native language.
+ */
+PedDiskFlag
+ped_disk_flag_get_by_name(const char *name)
+{
+        PedDiskFlag flag;
+
+        for (flag = ped_disk_flag_next(0); flag;
+             flag = ped_disk_flag_next(flag)) {
+                const char *flag_name = ped_disk_flag_get_name(flag);
+                if (strcasecmp(name, flag_name) == 0
+                    || strcasecmp(name, _(flag_name)) == 0)
+                        return flag;
+        }
+
+        return 0;
+}
+
+/**
+ * Iterates through all disk flags.
+ *
+ * ped_disk_flag_next(0) returns the first flag
+ *
+ * \return the next flag, or 0 if there are no more flags
+ */
+PedDiskFlag
+ped_disk_flag_next(PedDiskFlag flag)
+{
+        return (flag + 1) % (PED_DISK_LAST_FLAG + 1);
+}
+
+/**
  * \internal We turned a really nasty bureaucracy problem into an elegant maths
  * problem :-)  Basically, there are some constraints to a partition's
  * geometry:
--
1.6.6.rc1.319.g9b57d




More information about the parted-devel mailing list