[Parted-commits] GNU Parted Official Repository: Changes to 'master'

Jim Meyering meyering at alioth.debian.org
Mon Nov 30 18:04:27 UTC 2009


 NEWS                       |    9 +++++-
 doc/parted.texi            |   28 ++++++++++++++++++++
 parted/parted.c            |   56 ++++++++++++++++++++++++++++++++++++++++
 parted/ui.c                |   46 ++++++++++++++++++++++++++++++++
 parted/ui.h                |    9 +++++-
 tests/Makefile.am          |    3 +-
 tests/t9030-align-check.sh |   63 +++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 211 insertions(+), 3 deletions(-)

New commits:
commit 69b68819c3c4a183a0f44046facdb989abd850ed
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Nov 27 12:30:21 2009 +0100

    tests: exercise new align-check command
    
    * tests/t9030-align-check.sh: New file.
    * tests/Makefile.am (TESTS): Add it.

diff --git a/tests/Makefile.am b/tests/Makefile.am
index f47a6e2..b6d8ca2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -30,7 +30,8 @@ TESTS = \
   t7000-scripting.sh \
   t8000-loop.sh \
   t9010-big-sector.sh \
-  t9020-alignment.sh
+  t9020-alignment.sh \
+  t9030-align-check.sh
 
 EXTRA_DIST = \
   $(TESTS) test-lib.sh t-lib.sh lvm-utils.sh t-local.sh t-lvm.sh
diff --git a/tests/t9030-align-check.sh b/tests/t9030-align-check.sh
new file mode 100644
index 0000000..12c6c77
--- /dev/null
+++ b/tests/t9030-align-check.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+# exercise the new align-check command
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  parted --version
+fi
+
+: ${srcdir=.}
+. $srcdir/t-lib.sh
+
+require_root_
+require_scsi_debug_module_
+
+# check for scsi_debug module
+modprobe -n scsi_debug ||
+  skip_test_ "you lack the scsi_debug kernel module"
+
+grep '^#define USE_BLKID 1' "$CONFIG_HEADER" > /dev/null ||
+  skip_test_ 'this system lacks a new-enough libblkid'
+
+# create memory-backed device
+scsi_debug_setup_ dev_size_mb=550 physblk_exp=3 lowest_aligned=7 > dev-name ||
+  skip_test_ 'failed to create scsi_debug device'
+scsi_dev=$(cat dev-name)
+p1=${scsi_dev}1
+
+fail=0
+
+parted -s $scsi_dev mklabel gpt || fail=1
+
+i=60
+while :; do
+  parted -s $scsi_dev mkpart p1 ext2 ${i}s 80000s || fail=1
+  wait_for_dev_to_appear_ $p1 || fail=1
+  parted -s $scsi_dev align-check min 1 > out 2>&1
+  result=$?
+
+  test $(expr $i % 8) = 7 && exp_result=0 || exp_result=1
+  test $result = $exp_result || fail=1
+  compare out /dev/null || fail=1
+
+  parted -s $scsi_dev rm 1
+  i=$(expr $i + 1)
+  test $i = 70 && break
+done
+
+Exit $fail

commit b925eaf8f068994b573fe8b0e7356094a6aaeb52
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Nov 27 11:15:53 2009 +0100

    ui: new command: align-check TYPE N
    
    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.

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 */



More information about the Parted-commits mailing list