]>
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
|O_NONBLOCK
)) < 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, %ju sectors/track, %ju cylinders"),
72 fdisk_get_geom_heads(cxt
),
73 (uintmax_t) fdisk_get_geom_sectors(cxt
),
74 (uintmax_t) 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
, "%s", ""); /* 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
, "%s", ""); /* 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
, "%s", ""); /* line break */
205 fdisk_info(cxt
, _("Filesystem/RAID signature on partition %zu will be wiped."),
206 fdisk_partition_get_partno(pa
) + 1);
211 if (fdisk_table_wrong_order(tb
)) {
213 fdisk_info(cxt
, "%s", ""); /* line break */
214 fdisk_info(cxt
, _("Partition table entries are not in disk order."));
217 scols_unref_table(out
);
218 fdisk_unref_table(tb
);
219 fdisk_free_iter(itr
);
222 void list_freespace(struct fdisk_context
*cxt
)
224 struct fdisk_table
*tb
= NULL
;
225 struct fdisk_partition
*pa
= NULL
;
226 struct fdisk_iter
*itr
= NULL
;
227 struct libscols_table
*out
= NULL
;
228 const char *bold
= NULL
;
230 uintmax_t sumsize
= 0, bytes
= 0;
233 static const char *colnames
[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
234 static const int colids
[] = { FDISK_FIELD_START
, FDISK_FIELD_END
, FDISK_FIELD_SECTORS
, FDISK_FIELD_SIZE
};
236 if (fdisk_get_freespaces(cxt
, &tb
))
239 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
241 fdisk_warn(cxt
, _("failed to allocate iterator"));
245 out
= scols_new_table();
247 fdisk_warn(cxt
, _("failed to allocate output table"));
251 if (colors_wanted()) {
252 scols_table_enable_colors(out
, 1);
253 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
256 for (i
= 0; i
< ARRAY_SIZE(colnames
); i
++) {
257 struct libscols_column
*co
= scols_table_new_column(out
, _(colnames
[i
]), 5, SCOLS_FL_RIGHT
);
262 scols_cell_set_color(scols_column_get_header(co
), bold
);
265 /* fill-in output table */
266 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
267 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
271 fdisk_warn(cxt
, _("failed to allocate output line"));
274 for (i
= 0; i
< ARRAY_SIZE(colids
); i
++) {
275 if (fdisk_partition_to_string(pa
, cxt
, colids
[i
], &data
))
277 if (scols_line_refer_data(ln
, i
, data
)) {
278 fdisk_warn(cxt
, _("failed to add output data"));
283 if (fdisk_partition_has_size(pa
))
284 sumsize
+= fdisk_partition_get_size(pa
);
287 bytes
= sumsize
* fdisk_get_sector_size(cxt
);
288 strsz
= size_to_human_string(SIZE_DECIMAL_2DIGITS
290 | SIZE_SUFFIX_3LETTER
, bytes
);
292 color_scheme_enable("header", UL_COLOR_BOLD
);
293 fdisk_info(cxt
, _("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
294 fdisk_get_devname(cxt
), strsz
,
299 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
300 fdisk_get_unit(cxt
, FDISK_PLURAL
),
301 fdisk_get_units_per_sector(cxt
),
302 fdisk_get_sector_size(cxt
),
303 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
305 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
306 fdisk_get_sector_size(cxt
),
307 fdisk_get_physector_size(cxt
));
310 if (!scols_table_is_empty(out
)) {
311 fdisk_info(cxt
, "%s", ""); /* line break */
312 scols_print_table(out
);
315 scols_unref_table(out
);
316 fdisk_unref_table(tb
);
317 fdisk_free_iter(itr
);
320 char *next_proc_partition(FILE **f
)
325 *f
= fopen(_PATH_PROC_PARTITIONS
, "r");
327 warn(_("cannot open %s"), _PATH_PROC_PARTITIONS
);
332 while (fgets(line
, sizeof(line
), *f
)) {
333 char buf
[PATH_MAX
], *cn
;
336 if (sscanf(line
, " %*d %*d %*d %128[^\n ]", buf
) != 1)
339 devno
= sysfs_devname_to_devno(buf
);
343 if (sysfs_devno_is_dm_private(devno
, NULL
) ||
344 sysfs_devno_is_wholedisk(devno
) <= 0)
347 if (!sysfs_devno_to_devpath(devno
, buf
, sizeof(buf
)))
350 cn
= canonicalize_path(buf
);
354 if (!is_ide_cdrom_or_tape(cn
))
363 int print_device_pt(struct fdisk_context
*cxt
, char *device
, int warnme
,
364 int verify
, int separator
)
366 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
367 if (warnme
|| errno
== EACCES
)
368 warn(_("cannot open %s"), device
);
373 fputs("\n\n", stdout
);
375 list_disk_geometry(cxt
);
377 if (fdisk_has_label(cxt
)) {
380 fdisk_verify_disklabel(cxt
);
382 fdisk_deassign_device(cxt
, 1);
386 int print_device_freespace(struct fdisk_context
*cxt
, char *device
, int warnme
,
389 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
390 if (warnme
|| errno
== EACCES
)
391 warn(_("cannot open %s"), device
);
396 fputs("\n\n", stdout
);
399 fdisk_deassign_device(cxt
, 1);
403 void print_all_devices_pt(struct fdisk_context
*cxt
, int verify
)
409 while ((dev
= next_proc_partition(&f
))) {
410 print_device_pt(cxt
, dev
, 0, verify
, sep
);
416 void print_all_devices_freespace(struct fdisk_context
*cxt
)
422 while ((dev
= next_proc_partition(&f
))) {
423 print_device_freespace(cxt
, dev
, 0, sep
);
429 /* usable for example in usage() */
430 void list_available_columns(FILE *out
)
434 struct fdisk_label
*lb
= NULL
;
435 struct fdisk_context
*cxt
= fdisk_new_context();
440 termwidth
= get_terminal_width(80);
442 fprintf(out
, USAGE_COLUMNS
);
444 while (fdisk_next_label(cxt
, &lb
) == 0) {
445 size_t width
= 6; /* label name and separators */
447 fprintf(out
, " %s:", fdisk_label_get_name(lb
));
448 for (i
= 1; i
< FDISK_NFIELDS
; i
++) {
449 const struct fdisk_field
*fl
= fdisk_label_get_field(lb
, i
);
450 const char *name
= fl
? fdisk_field_get_name(fl
) : NULL
;
455 len
= strlen(name
) + 1;
456 if (width
+ len
> (size_t) termwidth
) {
460 fprintf(out
, " %s", name
);
466 fdisk_unref_context(cxt
);
469 static int fieldname_to_id(const char *name
, size_t namesz
)
471 const struct fdisk_field
*fl
;
476 assert(fields_label
);
478 buf
= strndup(name
, namesz
);
482 fl
= fdisk_label_get_field_by_name(fields_label
, buf
);
484 warnx(_("%s unknown column: %s"),
485 fdisk_label_get_name(fields_label
), buf
);
490 return fdisk_field_get_id(fl
);
494 * Initialize array with output columns (fields_ids[]) according to
495 * comma delimited list of columns (@str). If the list string is not
496 * defined then use library defaults. This function is "-o <list>"
499 * If the columns are already initialized then returns already existing columns.
501 int *init_fields(struct fdisk_context
*cxt
, const char *str
, size_t *n
)
503 int *dflt_ids
= NULL
;
504 struct fdisk_label
*lb
;
511 lb
= fdisk_get_label(cxt
, NULL
);
513 if (!lb
|| fields_label
!= lb
) { /* label changed: reset */
520 if (!fields_label
) /* no label */
523 goto done
; /* already initialized */
525 /* library default */
526 if (fdisk_label_get_fields_ids(NULL
, cxt
, &dflt_ids
, &fields_nids
))
529 fields_ids
= xcalloc(FDISK_NFIELDS
* 2, sizeof(int));
531 /* copy defaults to the list with wanted fields */
532 memcpy(fields_ids
, dflt_ids
, fields_nids
* sizeof(int));
535 /* extend or replace fields_nids[] according to fields_string */
537 string_add_to_idarray(fields_string
, fields_ids
, FDISK_NFIELDS
* 2,
538 &fields_nids
, fieldname_to_id
) < 0)