[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