[PATCH 1/2] ui: new command: align-check TYPE N

Jim Meyering meyering at redhat.com
Fri Nov 27 10:15:53 UTC 2009


e.g.,
  parted -s /dev/sda align-check min 1 && echo partition 1 is min-aligned
  parted -s /dev/sda align-check opt 2 && echo partition 2 is opt-aligned

* parted/parted.c:
* parted/ui.c:
* parted/ui.h:
* NEWS (New features): Mention it.
* doc/parted.texi (align-check): Describe it.
---
 NEWS            |    9 +++++++-
 doc/parted.texi |   28 +++++++++++++++++++++++++++
 parted/parted.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 parted/ui.c     |   46 +++++++++++++++++++++++++++++++++++++++++++++
 parted/ui.h     |    9 +++++++-
 5 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 9c68d7c..5241301 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,14 @@ GNU parted NEWS                                    -*- outline -*-

 * Noteworthy changes in release ?.? (????-??-??) [?]

-** Improvements
+** New features
+
+  new command "align-check TYPE N" to determine whether the starting sector
+  of partition N is TYPE(minimal|optimal)-aligned for the disk.  E.g.,
+      parted -s /dev/sda align-check min 1 && echo partition 1 is min-aligned
+      parted -s /dev/sda align-check opt 2 && echo partition 2 is opt-aligned
+  This is useful only on kernels for which Parted is able to determine
+  a disk's alignment characteristics.

   Add functions to libparted to get minimal and optimal alignment
   information from devices:
diff --git a/doc/parted.texi b/doc/parted.texi
index 499d660..a1d794d 100644
--- a/doc/parted.texi
+++ b/doc/parted.texi
@@ -510,6 +510,7 @@ display the version
 GNU Parted provides the following commands:

 @menu
+* align-check::
 * check::
 * cp::
 * help::
@@ -529,6 +530,33 @@ GNU Parted provides the following commands:
 * unit::
 @end menu

+ at node align-check
+ at subsection align-check
+ at cindex align-check, command description
+ at cindex command description, align-check
+
+ at deffn Command align-check @var{align-type} @var{n}
+
+Determine whether the starting sector of partition @var{n}
+meets the disk's selected alignment criteria.
+ at var{align-type} must be @samp{minimal}, @samp{optimal}
+or an abbreviation.
+When in script mode, if the partition does not meet the alignment
+requirement, exit with status 1;  otherwise (including on older
+kernels for which alignment data is not available), continue processing
+any remaining commands.
+Without @option{--script}, print either @samp{@var{N} aligned}
+or @samp{@var{N} not aligned}.
+
+Example:
+
+ at example
+(parted) @kbd{align-check minimal 1}
+1 aligned
+ at end example
+
+ at end deffn
+
 @node check
 @subsection check
 @cindex check, command description
diff --git a/parted/parted.c b/parted/parted.c
index d9c4333..099bc94 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -113,6 +113,7 @@ static const char* number_msg = N_(
 static const char* label_type_msg_start = N_("LABEL-TYPE is one of: ");
 static const char* flag_msg_start =   N_("FLAG is one of: ");
 static const char* unit_msg_start =   N_("UNIT is one of: ");
+static const char* min_or_opt_msg = N_("desired alignment: minimum or optimal");
 static const char* part_type_msg =    N_("PART-TYPE is one of: primary, logical, "
                                    "extended\n");
 static const char* fs_type_msg_start = N_("FS-TYPE is one of: ");
@@ -1937,6 +1938,49 @@ do_select (PedDevice** dev)
         return 1;
 }

+/* Return true if partition PART is consistent with DISK's selected
+   offset and alignment requirements.  Also return true if there is
+   insufficient kernel support to determine DISK's alignment requirements.
+   Otherwise, return false.  A_TYPE selects whether to check for minimal
+   or optimal alignment requirements.  */
+static bool
+partition_align_check (PedDisk const *disk, PedPartition const *part,
+		       enum AlignmentType a_type)
+{
+  PED_ASSERT (part->disk == disk, return false);
+  PedDevice const *dev = disk->dev;
+
+  PedAlignment *pa = (a_type == PA_MINIMUM
+		      ? ped_device_get_minimum_alignment (dev)
+		      : ped_device_get_optimum_alignment (dev));
+  if (pa == NULL)
+    return true;
+
+  PED_ASSERT (pa->grain_size != 0, return false);
+  bool ok = (part->geom.start % pa->grain_size == pa->offset);
+  free (pa);
+  return ok;
+}
+
+static int
+do_align_check (PedDevice **dev)
+{
+  PedDisk *disk = ped_disk_new (*dev);
+  if (!disk)
+    return 0;
+
+  enum AlignmentType align_type;
+  PedPartition *part = NULL;
+  bool aligned =
+    (command_line_get_align_type (_("alignment type(min/opt)"), &align_type)
+     && command_line_get_partition (_("Partition number?"), disk, &part)
+     && partition_align_check (disk, part, align_type));
+
+  ped_disk_destroy (disk);
+
+  return aligned ? 1 : 0;
+}
+
 static int
 do_set (PedDevice** dev)
 {
@@ -2172,6 +2216,18 @@ _done_messages ()
 static void
 _init_commands ()
 {
+  command_register (commands,
+    command_create ( str_list_create_unique ("align-check",
+					     _("align-check"), NULL),
+		     do_align_check,
+		     str_list_create (
+				      _("align-check TYPE N"
+					"                        "
+					"check partition N for"
+					" TYPE(min|opt) alignment"), NULL),
+
+		     str_list_create (_(number_msg), _(min_or_opt_msg),
+				      NULL), 1));
         command_register (commands, command_create (
                 str_list_create_unique ("check", _("check"), NULL),
                 do_check,
diff --git a/parted/ui.c b/parted/ui.c
index 58fb80c..bb8222d 100644
--- a/parted/ui.c
+++ b/parted/ui.c
@@ -193,6 +193,11 @@ static StrList*     ex_opt_str [64];
 static StrList*     on_list;
 static StrList*     off_list;
 static StrList*     on_off_list;
+
+static StrList*     align_opt_list;
+static StrList*     align_min_list;
+static StrList*     align_opt_min_list;
+
 static StrList*     fs_type_list;
 static StrList*     disk_type_list;

@@ -1260,6 +1265,27 @@ command_line_get_ex_opt (const char* prompt, PedExceptionOption options)
 }

 int
+command_line_get_align_type (const char *prompt, enum AlignmentType *align_type)
+{
+  char*    def_word;
+  char*    input;
+
+  if (*align_type)
+    def_word = str_list_convert_node (align_opt_list);
+  else
+    def_word = str_list_convert_node (align_min_list);
+  input = command_line_get_word (prompt, def_word, align_opt_min_list, 1);
+  free (def_word);
+  if (!input)
+    return 0;
+  *align_type = (str_list_match_any (align_opt_list, input)
+	     ? PA_OPTIMUM
+	     : PA_MINIMUM);
+  free (input);
+  return 1;
+}
+
+int
 command_line_get_unit (const char* prompt, PedUnit* unit)
 {
         StrList*       opts = NULL;
@@ -1347,6 +1373,24 @@ done_state_str ()
 }

 static int
+init_alignment_type_str ()
+{
+        align_opt_list = str_list_create_unique (_("optimal"), "optimal", NULL);
+        align_min_list = str_list_create_unique (_("minimal"), "minimal", NULL);
+        align_opt_min_list = str_list_join (str_list_duplicate (align_opt_list),
+					    str_list_duplicate (align_min_list));
+        return 1;
+}
+
+static void
+done_alignment_type_str ()
+{
+        str_list_destroy (align_opt_list);
+        str_list_destroy (align_min_list);
+        str_list_destroy (align_opt_min_list);
+}
+
+static int
 init_fs_type_str ()
 {
         PedFileSystemType*    walk;
@@ -1409,6 +1453,7 @@ init_ui ()
 {
         if (!init_ex_opt_str ()
             || !init_state_str ()
+            || !init_alignment_type_str ()
             || !init_fs_type_str ()
             || !init_disk_type_str ())
                 return 0;
@@ -1453,6 +1498,7 @@ done_ui ()
         ped_exception_set_handler (NULL);
         done_ex_opt_str ();
         done_state_str ();
+        done_alignment_type_str ();
         str_list_destroy (fs_type_list);
         str_list_destroy (disk_type_list);
 }
diff --git a/parted/ui.h b/parted/ui.h
index e5358e5..d5b3fc0 100644
--- a/parted/ui.h
+++ b/parted/ui.h
@@ -21,6 +21,12 @@

 #include "strlist.h"

+enum AlignmentType
+  {
+    PA_MINIMUM = 1,
+    PA_OPTIMUM
+  };
+
 extern const char *prog_name;

 extern int init_ui ();
@@ -65,6 +71,8 @@ extern int command_line_get_part_type (const char* prompt, const PedDisk* disk,
 extern PedExceptionOption command_line_get_ex_opt (const char* prompt,
 						   PedExceptionOption options);
 extern int command_line_get_unit (const char* prompt, PedUnit* unit);
+extern int command_line_get_align_type (const char *prompt,
+					enum AlignmentType *align_type);

 extern int command_line_is_integer ();
 extern int command_line_is_sector ();
@@ -80,5 +88,4 @@ extern int	pretend_input_tty;
 extern void print_options_help ();
 extern void print_commands_help ();

-
 #endif /* UI_H_INCLUDED */
--
1.6.6.rc0.285.g73651




More information about the parted-devel mailing list