]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fdisk: add 'F' command to list free unpartitioned space
authorKarel Zak <kzak@redhat.com>
Tue, 28 Jul 2015 13:53:42 +0000 (15:53 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 28 Jul 2015 13:53:42 +0000 (15:53 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/fdisk-list.c
disk-utils/fdisk-list.h
disk-utils/fdisk-menu.c

index 5ef92b13c6d37883f0b9fab1ea9ec37cf9eb95e4..7d3c219db17c33dc8e1f514e564451cf3fcaf00c 100644 (file)
@@ -195,6 +195,100 @@ done:
        fdisk_free_iter(itr);
 }
 
+void list_freespace(struct fdisk_context *cxt)
+{
+       struct fdisk_table *tb = NULL;
+       struct fdisk_partition *pa = NULL;
+       struct fdisk_iter *itr = NULL;
+       struct libscols_table *out = NULL;
+       const char *bold = NULL;
+       size_t i;
+       uintmax_t sumsize = 0, bytes = 0;
+       char *strsz;
+
+       static const char *colnames[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
+       static const int colids[] = { FDISK_FIELD_START, FDISK_FIELD_END, FDISK_FIELD_SECTORS, FDISK_FIELD_SIZE };
+
+       if (fdisk_get_freespaces(cxt, &tb))
+               goto done;
+
+       itr = fdisk_new_iter(FDISK_ITER_FORWARD);
+       if (!itr) {
+               fdisk_warn(cxt, _("failed to allocate iterator"));
+               goto done;
+       }
+
+       out = scols_new_table();
+       if (!out) {
+               fdisk_warn(cxt, _("failed to allocate output table"));
+               goto done;
+       }
+
+       if (colors_wanted()) {
+               scols_table_enable_colors(out, 1);
+               bold = color_scheme_get_sequence("header", UL_COLOR_BOLD);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(colnames); i++) {
+               struct libscols_column *co = scols_table_new_column(out, _(colnames[i]), 5, SCOLS_FL_RIGHT);
+
+               if (!co)
+                       goto done;
+               if (bold)
+                       scols_cell_set_color(scols_column_get_header(co), bold);
+       }
+
+       /* fill-in output table */
+       while (fdisk_table_next_partition(tb, itr, &pa) == 0) {
+               struct libscols_line *ln = scols_table_new_line(out, NULL);
+               char *data;
+
+               if (!ln) {
+                       fdisk_warn(cxt, _("failed to allocate output line"));
+                       goto done;
+               }
+               for (i = 0; i < ARRAY_SIZE(colids); i++) {
+                       if (fdisk_partition_to_string(pa, cxt, colids[i], &data))
+                               continue;
+                       scols_line_refer_data(ln, i, data);
+               }
+
+               if (fdisk_partition_has_size(pa))
+                       sumsize += fdisk_partition_get_size(pa);
+       }
+
+       bytes = sumsize * fdisk_get_sector_size(cxt);
+       strsz = size_to_human_string(SIZE_SUFFIX_SPACE
+                                          | SIZE_SUFFIX_3LETTER, bytes);
+
+       color_scheme_enable("header", UL_COLOR_BOLD);
+       fdisk_info(cxt, _("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
+                       fdisk_get_devname(cxt), strsz,
+                       bytes, sumsize);
+       color_disable();
+       free(strsz);
+
+       fdisk_info(cxt, _("Units: %s of %d * %ld = %ld bytes"),
+              fdisk_get_unit(cxt, FDISK_PLURAL),
+              fdisk_get_units_per_sector(cxt),
+              fdisk_get_sector_size(cxt),
+              fdisk_get_units_per_sector(cxt) * fdisk_get_sector_size(cxt));
+
+       fdisk_info(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
+                               fdisk_get_sector_size(cxt),
+                               fdisk_get_physector_size(cxt));
+
+       /* print */
+       if (!scols_table_is_empty(out)) {
+               fputc('\n', stdout);
+               scols_print_table(out);
+       }
+done:
+       scols_unref_table(out);
+       fdisk_unref_table(tb);
+       fdisk_free_iter(itr);
+}
+
 char *next_proc_partition(FILE **f)
 {
        char line[128 + 1];
@@ -257,6 +351,19 @@ int print_device_pt(struct fdisk_context *cxt, char *device, int warnme, int ver
        return 0;
 }
 
+int print_device_freespace(struct fdisk_context *cxt, char *device, int warnme)
+{
+       if (fdisk_assign_device(cxt, device, 1) != 0) { /* read-only */
+               if (warnme || errno == EACCES)
+                       warn(_("cannot open %s"), device);
+               return -1;
+       }
+
+       list_freespace(cxt);
+       fdisk_deassign_device(cxt, 1);
+       return 0;
+}
+
 void print_all_devices_pt(struct fdisk_context *cxt, int verify)
 {
        FILE *f = NULL;
@@ -272,6 +379,21 @@ void print_all_devices_pt(struct fdisk_context *cxt, int verify)
        }
 }
 
+void print_all_devices_freespace(struct fdisk_context *cxt)
+{
+       FILE *f = NULL;
+       int ct = 0;
+       char *dev;
+
+       while ((dev = next_proc_partition(&f))) {
+               if (ct)
+                       fputs("\n\n", stdout);
+               if (print_device_freespace(cxt, dev, 0) == 0)
+                       ct++;
+               free(dev);
+       }
+}
+
 /* usable for example in usage() */
 void list_available_columns(FILE *out)
 {
index 9dbdbadd15610d4ffccf02569ce529ca17403e00..c24c4ddcc0b9468f65623980a6fd3169efefdbe0 100644 (file)
@@ -3,10 +3,14 @@
 
 extern void list_disklabel(struct fdisk_context *cxt);
 extern void list_disk_geometry(struct fdisk_context *cxt);
+extern void list_freespace(struct fdisk_context *cxt);
 
 extern char *next_proc_partition(FILE **f);
 extern int print_device_pt(struct fdisk_context *cxt, char *device, int warnme, int verify);
+extern int print_device_freespace(struct fdisk_context *cxt, char *device, int warnme);
+
 extern void print_all_devices_pt(struct fdisk_context *cxt, int verify);
+extern void print_all_devices_freespace(struct fdisk_context *cxt);
 
 extern void list_available_columns(FILE *out);
 extern int *init_fields(struct fdisk_context *cxt, const char *str, size_t *n);
index 6c7f583207428259f678db1b05408c78dd098ddc..ea12ac74ee2031ed146a0bf94e6366372bd0510d 100644 (file)
@@ -94,6 +94,7 @@ struct menu menu_generic = {
        .entries        = {
                MENU_BSEP(N_("Generic")),
                MENU_ENT  ('d', N_("delete a partition")),
+               MENU_ENT  ('F', N_("list free unpartitioned space")),
                MENU_ENT  ('l', N_("list known partition types")),
                MENU_ENT  ('n', N_("add a new partition")),
                MENU_BENT ('p', N_("print the partition table")),
@@ -561,6 +562,9 @@ static int generic_menu_cb(struct fdisk_context **cxt0,
        case 'i':
                rc = print_partition_info(cxt);
                break;
+       case 'F':
+               list_freespace(cxt);
+               break;
        }
 
        /* expert mode */