]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - disk-utils/fdisk-list.c
2 #include <libsmartcols.h>
10 #include "pathnames.h"
11 #include "canonicalize.h"
17 #include "fdisk-list.h"
19 /* see init_fields() */
20 static const char *fields_string
;
21 static int *fields_ids
;
22 static size_t fields_nids
;
23 static const struct fdisk_label
*fields_label
;
25 static int is_ide_cdrom_or_tape(char *device
)
29 if ((fd
= open(device
, O_RDONLY
)) < 0)
31 ret
= blkdev_is_cdrom(fd
);
37 void list_disk_identifier(struct fdisk_context
*cxt
)
39 struct fdisk_label
*lb
= fdisk_get_label(cxt
, NULL
);
42 if (fdisk_has_label(cxt
))
43 fdisk_info(cxt
, _("Disklabel type: %s"),
44 fdisk_label_get_name(lb
));
46 if (!fdisk_is_details(cxt
) && fdisk_get_disklabel_id(cxt
, &id
) == 0 && id
) {
47 fdisk_info(cxt
, _("Disk identifier: %s"), id
);
52 void list_disk_geometry(struct fdisk_context
*cxt
)
54 struct fdisk_label
*lb
= fdisk_get_label(cxt
, NULL
);
55 uint64_t bytes
= fdisk_get_nsectors(cxt
) * fdisk_get_sector_size(cxt
);
56 char *strsz
= size_to_human_string(SIZE_DECIMAL_2DIGITS
58 | SIZE_SUFFIX_3LETTER
, bytes
);
60 color_scheme_enable("header", UL_COLOR_BOLD
);
61 fdisk_info(cxt
, _("Disk %s: %s, %ju bytes, %ju sectors"),
62 fdisk_get_devname(cxt
), strsz
,
63 bytes
, (uintmax_t) fdisk_get_nsectors(cxt
));
67 if (fdisk_get_devmodel(cxt
))
68 fdisk_info(cxt
, _("Disk model: %s"), fdisk_get_devmodel(cxt
));
70 if (lb
&& (fdisk_label_require_geometry(lb
) || fdisk_use_cylinders(cxt
)))
71 fdisk_info(cxt
, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"),
72 fdisk_get_geom_heads(cxt
),
73 fdisk_get_geom_sectors(cxt
),
74 fdisk_get_geom_cylinders(cxt
));
76 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
77 fdisk_get_unit(cxt
, FDISK_PLURAL
),
78 fdisk_get_units_per_sector(cxt
),
79 fdisk_get_sector_size(cxt
),
80 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
82 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
83 fdisk_get_sector_size(cxt
),
84 fdisk_get_physector_size(cxt
));
85 fdisk_info(cxt
, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"),
86 fdisk_get_minimal_iosize(cxt
),
87 fdisk_get_optimal_iosize(cxt
));
88 if (fdisk_get_alignment_offset(cxt
))
89 fdisk_info(cxt
, _("Alignment offset: %lu bytes"),
90 fdisk_get_alignment_offset(cxt
));
92 list_disk_identifier(cxt
);
95 void list_disklabel(struct fdisk_context
*cxt
)
97 struct fdisk_table
*tb
= NULL
;
98 struct fdisk_partition
*pa
= NULL
;
99 struct fdisk_iter
*itr
= NULL
;
100 struct fdisk_label
*lb
;
101 struct libscols_table
*out
= NULL
;
102 const char *bold
= NULL
;
103 int *ids
= NULL
; /* IDs of fdisk_fields */
107 /* print label specific stuff by libfdisk FDISK_ASK_INFO API */
108 fdisk_list_disklabel(cxt
);
110 /* get partitions and generate output */
111 if (fdisk_get_partitions(cxt
, &tb
) || fdisk_table_get_nents(tb
) <= 0)
114 ids
= init_fields(cxt
, NULL
, &nids
);
118 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
120 fdisk_warn(cxt
, _("failed to allocate iterator"));
124 out
= scols_new_table();
126 fdisk_warn(cxt
, _("failed to allocate output table"));
130 if (colors_wanted()) {
131 scols_table_enable_colors(out
, 1);
132 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
135 lb
= fdisk_get_label(cxt
, NULL
);
138 /* define output table columns */
139 for (i
= 0; i
< nids
; i
++) {
141 struct libscols_column
*co
;
142 const struct fdisk_field
*field
=
143 fdisk_label_get_field(lb
, ids
[i
]);
146 if (fdisk_field_is_number(field
))
147 fl
|= SCOLS_FL_RIGHT
;
148 if (fdisk_field_get_id(field
) == FDISK_FIELD_TYPE
)
149 fl
|= SCOLS_FL_TRUNC
;
151 co
= scols_table_new_column(out
,
152 _(fdisk_field_get_name(field
)),
153 fdisk_field_get_width(field
), fl
);
157 /* set column header color */
159 scols_cell_set_color(scols_column_get_header(co
), bold
);
162 /* fill-in output table */
163 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
164 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
167 fdisk_warn(cxt
, _("failed to allocate output line"));
171 for (i
= 0; i
< nids
; i
++) {
174 if (fdisk_partition_to_string(pa
, cxt
, ids
[i
], &data
))
176 if (scols_line_refer_data(ln
, i
, data
)) {
177 fdisk_warn(cxt
, _("failed to add output data"));
184 if (!scols_table_is_empty(out
)) {
185 fdisk_info(cxt
, ""); /* just line break */
186 scols_print_table(out
);
190 fdisk_reset_iter(itr
, FDISK_ITER_FORWARD
);
191 while (itr
&& fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
192 if (!fdisk_partition_has_start(pa
))
194 if (!fdisk_lba_is_phy_aligned(cxt
, fdisk_partition_get_start(pa
))) {
196 fdisk_info(cxt
, ""); /* line break */
197 fdisk_warnx(cxt
, _("Partition %zu does not start on physical sector boundary."),
198 fdisk_partition_get_partno(pa
) + 1);
201 if (fdisk_partition_has_wipe(cxt
, pa
)) {
203 fdisk_info(cxt
, ""); /* line break */
204 fdisk_info(cxt
, _("Filesystem/RAID signature on partition %zu will be wiped."),
205 fdisk_partition_get_partno(pa
) + 1);
210 if (fdisk_table_wrong_order(tb
)) {
212 fdisk_info(cxt
, ""); /* line break */
213 fdisk_info(cxt
, _("Partition table entries are not in disk order."));
216 scols_unref_table(out
);
217 fdisk_unref_table(tb
);
218 fdisk_free_iter(itr
);
221 void list_freespace(struct fdisk_context
*cxt
)
223 struct fdisk_table
*tb
= NULL
;
224 struct fdisk_partition
*pa
= NULL
;
225 struct fdisk_iter
*itr
= NULL
;
226 struct libscols_table
*out
= NULL
;
227 const char *bold
= NULL
;
229 uintmax_t sumsize
= 0, bytes
= 0;
232 static const char *colnames
[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
233 static const int colids
[] = { FDISK_FIELD_START
, FDISK_FIELD_END
, FDISK_FIELD_SECTORS
, FDISK_FIELD_SIZE
};
235 if (fdisk_get_freespaces(cxt
, &tb
))
238 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
240 fdisk_warn(cxt
, _("failed to allocate iterator"));
244 out
= scols_new_table();
246 fdisk_warn(cxt
, _("failed to allocate output table"));
250 if (colors_wanted()) {
251 scols_table_enable_colors(out
, 1);
252 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
255 for (i
= 0; i
< ARRAY_SIZE(colnames
); i
++) {
256 struct libscols_column
*co
= scols_table_new_column(out
, _(colnames
[i
]), 5, SCOLS_FL_RIGHT
);
261 scols_cell_set_color(scols_column_get_header(co
), bold
);
264 /* fill-in output table */
265 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
266 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
270 fdisk_warn(cxt
, _("failed to allocate output line"));
273 for (i
= 0; i
< ARRAY_SIZE(colids
); i
++) {
274 if (fdisk_partition_to_string(pa
, cxt
, colids
[i
], &data
))
276 if (scols_line_refer_data(ln
, i
, data
)) {
277 fdisk_warn(cxt
, _("failed to add output data"));
282 if (fdisk_partition_has_size(pa
))
283 sumsize
+= fdisk_partition_get_size(pa
);
286 bytes
= sumsize
* fdisk_get_sector_size(cxt
);
287 strsz
= size_to_human_string(SIZE_DECIMAL_2DIGITS
289 | SIZE_SUFFIX_3LETTER
, bytes
);
291 color_scheme_enable("header", UL_COLOR_BOLD
);
292 fdisk_info(cxt
, _("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
293 fdisk_get_devname(cxt
), strsz
,
298 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
299 fdisk_get_unit(cxt
, FDISK_PLURAL
),
300 fdisk_get_units_per_sector(cxt
),
301 fdisk_get_sector_size(cxt
),
302 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
304 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
305 fdisk_get_sector_size(cxt
),
306 fdisk_get_physector_size(cxt
));
309 if (!scols_table_is_empty(out
)) {
310 fdisk_info(cxt
, ""); /* line break */
311 scols_print_table(out
);
314 scols_unref_table(out
);
315 fdisk_unref_table(tb
);
316 fdisk_free_iter(itr
);
319 char *next_proc_partition(FILE **f
)
324 *f
= fopen(_PATH_PROC_PARTITIONS
, "r");
326 warn(_("cannot open %s"), _PATH_PROC_PARTITIONS
);
331 while (fgets(line
, sizeof(line
), *f
)) {
332 char buf
[PATH_MAX
], *cn
;
335 if (sscanf(line
, " %*d %*d %*d %128[^\n ]", buf
) != 1)
338 devno
= sysfs_devname_to_devno(buf
);
342 if (sysfs_devno_is_dm_private(devno
, NULL
) ||
343 sysfs_devno_is_wholedisk(devno
) <= 0)
346 if (!sysfs_devno_to_devpath(devno
, buf
, sizeof(buf
)))
349 cn
= canonicalize_path(buf
);
353 if (!is_ide_cdrom_or_tape(cn
))
362 int print_device_pt(struct fdisk_context
*cxt
, char *device
, int warnme
, int verify
)
364 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
365 if (warnme
|| errno
== EACCES
)
366 warn(_("cannot open %s"), device
);
370 list_disk_geometry(cxt
);
372 if (fdisk_has_label(cxt
)) {
375 fdisk_verify_disklabel(cxt
);
377 fdisk_deassign_device(cxt
, 1);
381 int print_device_freespace(struct fdisk_context
*cxt
, char *device
, int warnme
)
383 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
384 if (warnme
|| errno
== EACCES
)
385 warn(_("cannot open %s"), device
);
390 fdisk_deassign_device(cxt
, 1);
394 void print_all_devices_pt(struct fdisk_context
*cxt
, int verify
)
400 while ((dev
= next_proc_partition(&f
))) {
402 fputs("\n\n", stdout
);
403 if (print_device_pt(cxt
, dev
, 0, verify
) == 0)
409 void print_all_devices_freespace(struct fdisk_context
*cxt
)
415 while ((dev
= next_proc_partition(&f
))) {
417 fputs("\n\n", stdout
);
418 if (print_device_freespace(cxt
, dev
, 0) == 0)
424 /* usable for example in usage() */
425 void list_available_columns(FILE *out
)
429 struct fdisk_label
*lb
= NULL
;
430 struct fdisk_context
*cxt
= fdisk_new_context();
435 termwidth
= get_terminal_width(80);
437 fprintf(out
, USAGE_COLUMNS
);
439 while (fdisk_next_label(cxt
, &lb
) == 0) {
440 size_t width
= 6; /* label name and separators */
442 fprintf(out
, " %s:", fdisk_label_get_name(lb
));
443 for (i
= 1; i
< FDISK_NFIELDS
; i
++) {
444 const struct fdisk_field
*fl
= fdisk_label_get_field(lb
, i
);
445 const char *name
= fl
? fdisk_field_get_name(fl
) : NULL
;
450 len
= strlen(name
) + 1;
451 if (width
+ len
> (size_t) termwidth
) {
455 fprintf(out
, " %s", name
);
461 fdisk_unref_context(cxt
);
464 static int fieldname_to_id(const char *name
, size_t namesz
)
466 const struct fdisk_field
*fl
;
467 char buf
[namesz
+ 1];
471 assert(fields_label
);
473 memcpy(buf
, name
, namesz
);
476 fl
= fdisk_label_get_field_by_name(fields_label
, buf
);
478 warnx(_("%s unknown column: %s"),
479 fdisk_label_get_name(fields_label
), buf
);
482 return fdisk_field_get_id(fl
);
486 * Initialize array with output columns (fields_ids[]) according to
487 * comma delimited list of columns (@str). If the list string is not
488 * defined then use library defaults. This function is "-o <list>"
491 * If the columns are already initialized then returns already existing columns.
493 int *init_fields(struct fdisk_context
*cxt
, const char *str
, size_t *n
)
495 int *dflt_ids
= NULL
;
496 struct fdisk_label
*lb
;
503 lb
= fdisk_get_label(cxt
, NULL
);
505 if (!lb
|| fields_label
!= lb
) { /* label changed: reset */
512 if (!fields_label
) /* no label */
515 goto done
; /* already initialized */
517 /* library default */
518 if (fdisk_label_get_fields_ids(NULL
, cxt
, &dflt_ids
, &fields_nids
))
521 fields_ids
= xcalloc(FDISK_NFIELDS
* 2, sizeof(int));
523 /* copy defaults to the list with wanted fields */
524 memcpy(fields_ids
, dflt_ids
, fields_nids
* sizeof(int));
527 /* extend or replace fields_nids[] according to fields_string */
529 string_add_to_idarray(fields_string
, fields_ids
, FDISK_NFIELDS
* 2,
530 &fields_nids
, fieldname_to_id
) < 0)