[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Enhancements to parted's partition table printing
From: |
Colin Watson |
Subject: |
[PATCH] Enhancements to parted's partition table printing |
Date: |
Tue, 22 Nov 2005 20:46:22 +0000 |
User-agent: |
Mutt/1.5.9i |
At present, the 'parted' command-line tool is really more useful for
interactive use than anything else. The particular deficiency that's
biting me is that there's no really good way to use it to dump out a
list of all the partitions on the system and their properties in a way
that can be read by scripts such as those in the Debian installer. While
it's certainly possible to write small programs using libparted that do
what we need (and indeed we already have a couple of those), these then
require their own packaging in the installer, live CDs, and suchlike,
and I've been thinking recently that it might be better to take the
small step required to make the parted program usable for this purpose.
The following patch implements a few features that I think would help.
It's a strawman patch in that I'm not very attached to the particular
details of the implementation, as long as the output format is stable so
that we don't have to update scripts all the time (the human-readable
output of parted changed not that long ago, breaking one or two scripts
in d-i that were unwisely trying to parse it). Anyway, this patch adds
the following:
* A -c/--colons option which causes the 'print' command to output
information about each partition in an easily-parseable
colon-separated format rather than the default human-friendly style.
* A new 'print-all' command, which prints information about all
devices rather than just the first. This is best used in conjunction
with ...
* An -f/--first option which automatically selects the first probed
device rather than making you provide one (scripts in an installer
can't hardcode any particular device, and since parted can already
trivially find out what the first device in the PedDevice chain is
then it might as well expose that); I found it awkward to make the
command-line syntax work well for 'print-all' without this.
The result of the above is that instead of this:
# ./parted -s /dev/hda print
Disk geometry for /dev/hda: 0kB - 165GB
Disk label type: msdos
Number Start End Size Type File system Flags
1 32kB 214MB 214MB primary
2 214MB 5585MB 5371MB primary ext3
3 5585MB 165GB 159GB extended
5 5585MB 38GB 32GB logical lvm
6 38GB 70GB 32GB logical lvm
7 70GB 70GB 403MB logical linux-swap
8 70GB 103GB 32GB logical lvm
9 103GB 135GB 32GB logical lvm
10 135GB 165GB 30GB logical lvm
# ./parted -s /dev/hdc print
Disk geometry for /dev/hdc: 0kB - 40GB
Disk label type: msdos
Number Start End Size Type File system Flags
1 32kB 40GB 40GB extended
5 65kB 10GB 10GB logical lvm
6 10GB 20GB 10GB logical lvm
7 20GB 30GB 10GB logical lvm
8 30GB 40GB 10GB logical lvm
... I can now do this:
# ./parted -cfs print-all
/dev/hda1:32kB:214MB:214MB:primary:::
/dev/hda2:214MB:5585MB:5371MB:primary:ext3::
/dev/hda3:5585MB:165GB:159GB:extended:::
/dev/hda5:5585MB:38GB:32GB:logical:::lvm
/dev/hda6:38GB:70GB:32GB:logical:::lvm
/dev/hda7:70GB:70GB:403MB:logical:linux-swap::
/dev/hda8:70GB:103GB:32GB:logical:::lvm
/dev/hda9:103GB:135GB:32GB:logical:::lvm
/dev/hda10:135GB:165GB:30GB:logical:::lvm
/dev/hdc1:32kB:40GB:40GB:extended:::
/dev/hdc5:65kB:10GB:10GB:logical:::lvm
/dev/hdc6:10GB:20GB:10GB:logical:::lvm
/dev/hdc7:20GB:30GB:10GB:logical:::lvm
/dev/hdc8:30GB:40GB:10GB:logical:::lvm
... which is much easier to parse and I think provides most of the
information we generally need in the Debian installer (though perhaps we
should invent a machine-parseable way to get the geometry and disk label
type too). What do you think?
--- parted-1.6.25.1.orig/parted/ui.h
+++ parted-1.6.25.1/parted/ui.h
@@ -73,6 +73,7 @@
extern void print_using_dev (PedDevice* dev);
/* in parted.c */
+extern int opt_colons;
extern int opt_script_mode;
extern void print_options_help ();
--- parted-1.6.25.1.orig/parted/parted.c
+++ parted-1.6.25.1/parted/parted.c
@@ -62,6 +62,8 @@
static struct option options[] = {
/* name, has-arg, string-return-val, char-return-val */
+ {"colons", 0, NULL, 'c'},
+ {"first", 0, NULL, 'f'},
{"help", 0, NULL, 'h'},
{"interactive", 0, NULL, 'i'},
{"script", 0, NULL, 's'},
@@ -71,6 +73,8 @@
#endif
static char* options_help [][2] = {
+ {"colons", N_("use colon-separated print output style")},
+ {"first", N_("automatically select first probed device")},
{"help", N_("displays this help message")},
{"interactive", N_("where necessary, prompts for user intervention")},
{"script", N_("never prompts for user intervention")},
@@ -78,6 +82,8 @@
{NULL, NULL}
};
+int opt_colons = 0;
+int opt_first_device = 0;
int opt_script_mode;
static char* number_msg = N_(
@@ -883,6 +889,8 @@
if (ped_partition_get_flag (part, flag)) {
if (first_flag)
first_flag = 0;
+ else if (opt_colons)
+ printf (" ");
else
printf (", ");
printf (_(ped_partition_flag_get_name (flag)));
@@ -956,6 +964,8 @@
char* start;
char* end;
char* size;
+ const char* partition_type;
+ const char* fs_type;
disk = ped_disk_new (*dev);
if (!disk)
@@ -978,45 +988,51 @@
return status;
}
- start = ped_unit_format (*dev,0 );
- end = ped_unit_format (*dev, (*dev)->length - 1);
- printf (_("Disk geometry for %s: %s - %s\n"), (*dev)->path, start, end);
- ped_free (start);
- ped_free (end);
-
- if (ped_unit_get_default () == PED_UNIT_CHS
- || ped_unit_get_default () == PED_UNIT_CYLINDER) {
- PedCHSGeometry* chs = &(*dev)->bios_geom;
- char* cyl_size = ped_unit_format_custom (*dev,
- chs->heads * chs->sectors,
- PED_UNIT_KILOBYTE);
- printf (_("BIOS cylinder,head,sector geometry: %d,%d,%d. "
- "Each cylinder is %s.\n"),
- chs->cylinders, chs->heads, chs->sectors, cyl_size);
- ped_free (cyl_size);
- }
+ if (!opt_colons) {
+ start = ped_unit_format (*dev,0 );
+ end = ped_unit_format (*dev, (*dev)->length - 1);
+ printf (_("Disk geometry for %s: %s - %s\n"),
+ (*dev)->path, start, end);
+ ped_free (start);
+ ped_free (end);
+
+ if (ped_unit_get_default () == PED_UNIT_CHS
+ || ped_unit_get_default () == PED_UNIT_CYLINDER) {
+ PedCHSGeometry* chs = &(*dev)->bios_geom;
+ char* cyl_size = ped_unit_format_custom (*dev,
+ chs->heads * chs->sectors,
+ PED_UNIT_KILOBYTE);
+ printf (_("BIOS cylinder,head,sector geometry:
%d,%d,%d. "
+ "Each cylinder is %s.\n"),
+ chs->cylinders, chs->heads, chs->sectors,
+ cyl_size);
+ ped_free (cyl_size);
+ }
- printf (_("Disk label type: %s\n"), disk->type->name);
+ printf (_("Disk label type: %s\n"), disk->type->name);
+ }
has_extended = ped_disk_type_check_feature (disk->type,
PED_DISK_TYPE_EXTENDED);
has_name = ped_disk_type_check_feature (disk->type,
PED_DISK_TYPE_PARTITION_NAME);
- if (ped_unit_get_default() == PED_UNIT_CHS) {
- printf ("%-7s %-11s %-11s ", _("Number"), _("Start"),
- _("End"));
- } else {
- printf ("%-7s %-7s %-7s %-7s ", _("Number"), _("Start"),
- _("End"), _("Size"));
- }
- if (has_extended)
- printf ("%-9s ", _("Type"));
- printf ("%-12s ", _("File system"));
- if (has_name)
- printf ("%-21s ", _("Name"));
- printf (_("Flags"));
- printf ("\n");
+ if (!opt_colons) {
+ if (ped_unit_get_default() == PED_UNIT_CHS) {
+ printf ("%-7s %-11s %-11s ", _("Number"), _("Start"),
+ _("End"));
+ } else {
+ printf ("%-7s %-7s %-7s %-7s ", _("Number"), _("Start"),
+ _("End"), _("Size"));
+ }
+ if (has_extended)
+ printf ("%-9s ", _("Type"));
+ printf ("%-12s ", _("File system"));
+ if (has_name)
+ printf ("%-21s ", _("Name"));
+ printf (_("Flags"));
+ printf ("\n");
+ }
for (part = ped_disk_next_partition (disk, NULL); part;
part = ped_disk_next_partition (disk, part)) {
@@ -1024,27 +1040,61 @@
if (!ped_partition_is_active (part))
continue;
- printf ("%-7d ", part->num);
+ /* The --colons output is parsed by scripts. Please make
+ * sure only ever to extend the format by adding new fields
+ * to the end of each line; don't insert fields in the
+ * middle!
+ */
+ if (opt_colons)
+ /* Print the path rather than the number, since we
+ * don't print the header with the disk path in
+ * --colons mode.
+ */
+ printf ("%s:", ped_partition_get_path (part));
+ else
+ printf ("%-7d ", part->num);
start = ped_unit_format (*dev, part->geom.start);
end = ped_unit_format (*dev, part->geom.end);
size = ped_unit_format (*dev, part->geom.length);
- if (ped_unit_get_default() == PED_UNIT_CHS)
- printf ("%-11s %-11s ", start, end);
- else
- printf ("%-7s %-7s %-7s ", start, end, size);
+ if (ped_unit_get_default() == PED_UNIT_CHS) {
+ if (opt_colons)
+ printf ("%s:%s::", start, end);
+ else
+ printf ("%-11s %-11s ", start, end);
+ } else {
+ if (opt_colons)
+ printf ("%s:%s:%s:", start, end, size);
+ else
+ printf ("%-7s %-7s %-7s ", start, end, size);
+ }
ped_free (start);
ped_free (end);
ped_free (size);
- if (has_extended)
- printf ("%-9s ",
- _(ped_partition_type_get_name (part->type)));
-
- printf ("%-12s ", part->fs_type ? part->fs_type->name : "");
+ if (has_extended) {
+ partition_type =
+ _(ped_partition_type_get_name (part->type));
+ if (opt_colons)
+ printf ("%s:", partition_type);
+ else
+ printf ("%-9s ", partition_type);
+ } else if (opt_colons)
+ printf (":");
+
+ fs_type = part->fs_type ? part->fs_type->name : "";
+ if (opt_colons)
+ printf ("%s:", fs_type);
+ else
+ printf ("%-12s ", fs_type);
- if (has_name)
- printf ("%-21s ", ped_partition_get_name (part));
+ if (has_name) {
+ if (opt_colons)
+ printf ("%s:", ped_partition_get_name (part));
+ else
+ printf ("%-21s ", ped_partition_get_name
(part));
+ } else if (opt_colons)
+ printf (":");
partition_print_flags (part);
printf ("\n");
@@ -1060,6 +1110,27 @@
}
static int
+do_print_all (PedDevice** dev)
+{
+ int first_device;
+ PedDevice *walk_dev;
+
+ first_device = 0;
+ walk_dev = *dev;
+ while (walk_dev) {
+ if (do_print (&walk_dev))
+ return 1;
+ if (first_device)
+ first_device = 0;
+ else if (!opt_colons)
+ printf ("\n");
+ walk_dev = ped_device_get_next (walk_dev);
+ }
+
+ return 0;
+}
+
+static int
do_quit (PedDevice** dev)
{
_done (*dev);
@@ -1643,6 +1714,17 @@
NULL)));
command_register (commands, command_create (
+ str_list_create_unique ("print-all", _("print-all"), NULL),
+ do_print_all,
+ str_list_create (
+_("print-all display partition tables of all devices"),
+NULL),
+ str_list_create (
+_("print-all displays the entire partition tables of all devices, in the\n"
+ "same format used by print.\n"),
+NULL)));
+
+ command_register (commands, command_create (
str_list_create_unique ("quit", _("quit"), NULL),
do_quit,
str_list_create (
@@ -1738,15 +1820,17 @@
while (1)
{
#ifdef HAVE_GETOPT_H
- opt = getopt_long (*argc_ptr, *argv_ptr, "hisv",
+ opt = getopt_long (*argc_ptr, *argv_ptr, "cfhisv",
options, NULL);
#else
- opt = getopt (*argc_ptr, *argv_ptr, "hisv");
+ opt = getopt (*argc_ptr, *argv_ptr, "cfhisv");
#endif
if (opt == -1)
break;
switch (opt) {
+ case 'c': opt_colons = 1; break;
+ case 'f': opt_first_device = 1; break;
case 'h': help_msg (); break;
case 'i': opt_script_mode = 0; break;
case 's': opt_script_mode = 1; break;
@@ -1768,7 +1852,7 @@
PedDevice* dev;
/* specified on comand line? */
- if (*argc_ptr) {
+ if (*argc_ptr && !opt_first_device) {
dev = ped_device_get ((*argv_ptr) [0]);
if (!dev)
return NULL;
--- parted-1.6.25.1.orig/parted/ui.c
+++ parted-1.6.25.1/parted/ui.c
@@ -75,6 +75,7 @@
static char* usage_msg = N_(
"Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...]\n"
+" parted -f [OPTION]... [COMMAND [PARAMETERS]...]\n"
"Apply COMMANDs with PARAMETERS to DEVICE. If no COMMAND(s) are given, runs
in\n"
"interactive mode.\n");
Thanks,
--
Colin Watson address@hidden
signature.asc
Description: Digital signature
- [PATCH] Enhancements to parted's partition table printing,
Colin Watson <=