]>
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_SUFFIX_SPACE
57 | SIZE_SUFFIX_3LETTER
, bytes
);
59 color_scheme_enable("header", UL_COLOR_BOLD
);
60 fdisk_info(cxt
, _("Disk %s: %s, %ju bytes, %ju sectors"),
61 fdisk_get_devname(cxt
), strsz
,
62 bytes
, (uintmax_t) fdisk_get_nsectors(cxt
));
66 if (lb
&& (fdisk_label_require_geometry(lb
) || fdisk_use_cylinders(cxt
)))
67 fdisk_info(cxt
, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"),
68 fdisk_get_geom_heads(cxt
),
69 fdisk_get_geom_sectors(cxt
),
70 fdisk_get_geom_cylinders(cxt
));
72 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
73 fdisk_get_unit(cxt
, FDISK_PLURAL
),
74 fdisk_get_units_per_sector(cxt
),
75 fdisk_get_sector_size(cxt
),
76 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
78 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
79 fdisk_get_sector_size(cxt
),
80 fdisk_get_physector_size(cxt
));
81 fdisk_info(cxt
, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"),
82 fdisk_get_minimal_iosize(cxt
),
83 fdisk_get_optimal_iosize(cxt
));
84 if (fdisk_get_alignment_offset(cxt
))
85 fdisk_info(cxt
, _("Alignment offset: %lu bytes"),
86 fdisk_get_alignment_offset(cxt
));
88 list_disk_identifier(cxt
);
91 void list_disklabel(struct fdisk_context
*cxt
)
93 struct fdisk_table
*tb
= NULL
;
94 struct fdisk_partition
*pa
= NULL
;
95 struct fdisk_iter
*itr
= NULL
;
96 struct fdisk_label
*lb
;
97 struct libscols_table
*out
= NULL
;
98 const char *bold
= NULL
;
99 int *ids
= NULL
; /* IDs of fdisk_fields */
103 /* print label specific stuff by libfdisk FDISK_ASK_INFO API */
104 fdisk_list_disklabel(cxt
);
106 /* get partitions and generate output */
107 if (fdisk_get_partitions(cxt
, &tb
) || fdisk_table_get_nents(tb
) <= 0)
110 ids
= init_fields(cxt
, NULL
, &nids
);
114 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
116 fdisk_warn(cxt
, _("failed to allocate iterator"));
120 out
= scols_new_table();
122 fdisk_warn(cxt
, _("failed to allocate output table"));
126 if (colors_wanted()) {
127 scols_table_enable_colors(out
, 1);
128 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
131 lb
= fdisk_get_label(cxt
, NULL
);
134 /* define output table columns */
135 for (i
= 0; i
< nids
; i
++) {
137 struct libscols_column
*co
;
138 const struct fdisk_field
*field
=
139 fdisk_label_get_field(lb
, ids
[i
]);
142 if (fdisk_field_is_number(field
))
143 fl
|= SCOLS_FL_RIGHT
;
144 if (fdisk_field_get_id(field
) == FDISK_FIELD_TYPE
)
145 fl
|= SCOLS_FL_TRUNC
;
147 co
= scols_table_new_column(out
,
148 _(fdisk_field_get_name(field
)),
149 fdisk_field_get_width(field
), fl
);
153 /* set column header color */
155 scols_cell_set_color(scols_column_get_header(co
), bold
);
158 /* fill-in output table */
159 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
160 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
163 fdisk_warn(cxt
, _("failed to allocate output line"));
167 for (i
= 0; i
< nids
; i
++) {
170 if (fdisk_partition_to_string(pa
, cxt
, ids
[i
], &data
))
172 if (scols_line_refer_data(ln
, i
, data
)) {
173 fdisk_warn(cxt
, _("failed to add output data"));
180 if (!scols_table_is_empty(out
)) {
181 fdisk_info(cxt
, ""); /* just line break */
182 scols_print_table(out
);
186 fdisk_reset_iter(itr
, FDISK_ITER_FORWARD
);
187 while (itr
&& fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
188 if (!fdisk_partition_has_start(pa
))
190 if (!fdisk_lba_is_phy_aligned(cxt
, fdisk_partition_get_start(pa
))) {
192 fdisk_info(cxt
, ""); /* line break */
193 fdisk_warnx(cxt
, _("Partition %zu does not start on physical sector boundary."),
194 fdisk_partition_get_partno(pa
) + 1);
197 if (fdisk_partition_has_wipe(cxt
, pa
)) {
199 fdisk_info(cxt
, ""); /* line break */
200 fdisk_info(cxt
, _("Filesystem/RAID signature on partition %zu will be wiped."),
201 fdisk_partition_get_partno(pa
) + 1);
206 if (fdisk_table_wrong_order(tb
)) {
208 fdisk_info(cxt
, ""); /* line break */
209 fdisk_info(cxt
, _("Partition table entries are not in disk order."));
212 scols_unref_table(out
);
213 fdisk_unref_table(tb
);
214 fdisk_free_iter(itr
);
217 void list_freespace(struct fdisk_context
*cxt
)
219 struct fdisk_table
*tb
= NULL
;
220 struct fdisk_partition
*pa
= NULL
;
221 struct fdisk_iter
*itr
= NULL
;
222 struct libscols_table
*out
= NULL
;
223 const char *bold
= NULL
;
225 uintmax_t sumsize
= 0, bytes
= 0;
228 static const char *colnames
[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
229 static const int colids
[] = { FDISK_FIELD_START
, FDISK_FIELD_END
, FDISK_FIELD_SECTORS
, FDISK_FIELD_SIZE
};
231 if (fdisk_get_freespaces(cxt
, &tb
))
234 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
236 fdisk_warn(cxt
, _("failed to allocate iterator"));
240 out
= scols_new_table();
242 fdisk_warn(cxt
, _("failed to allocate output table"));
246 if (colors_wanted()) {
247 scols_table_enable_colors(out
, 1);
248 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
251 for (i
= 0; i
< ARRAY_SIZE(colnames
); i
++) {
252 struct libscols_column
*co
= scols_table_new_column(out
, _(colnames
[i
]), 5, SCOLS_FL_RIGHT
);
257 scols_cell_set_color(scols_column_get_header(co
), bold
);
260 /* fill-in output table */
261 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
262 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
266 fdisk_warn(cxt
, _("failed to allocate output line"));
269 for (i
= 0; i
< ARRAY_SIZE(colids
); i
++) {
270 if (fdisk_partition_to_string(pa
, cxt
, colids
[i
], &data
))
272 if (scols_line_refer_data(ln
, i
, data
)) {
273 fdisk_warn(cxt
, _("failed to add output data"));
278 if (fdisk_partition_has_size(pa
))
279 sumsize
+= fdisk_partition_get_size(pa
);
282 bytes
= sumsize
* fdisk_get_sector_size(cxt
);
283 strsz
= size_to_human_string(SIZE_SUFFIX_SPACE
284 | SIZE_SUFFIX_3LETTER
, bytes
);
286 color_scheme_enable("header", UL_COLOR_BOLD
);
287 fdisk_info(cxt
, _("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
288 fdisk_get_devname(cxt
), strsz
,
293 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
294 fdisk_get_unit(cxt
, FDISK_PLURAL
),
295 fdisk_get_units_per_sector(cxt
),
296 fdisk_get_sector_size(cxt
),
297 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
299 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
300 fdisk_get_sector_size(cxt
),
301 fdisk_get_physector_size(cxt
));
304 if (!scols_table_is_empty(out
)) {
305 fdisk_info(cxt
, ""); /* line break */
306 scols_print_table(out
);
309 scols_unref_table(out
);
310 fdisk_unref_table(tb
);
311 fdisk_free_iter(itr
);
314 char *next_proc_partition(FILE **f
)
319 *f
= fopen(_PATH_PROC_PARTITIONS
, "r");
321 warn(_("cannot open %s"), _PATH_PROC_PARTITIONS
);
326 while (fgets(line
, sizeof(line
), *f
)) {
327 char buf
[PATH_MAX
], *cn
;
330 if (sscanf(line
, " %*d %*d %*d %128[^\n ]", buf
) != 1)
333 devno
= sysfs_devname_to_devno(buf
, NULL
);
337 if (sysfs_devno_is_lvm_private(devno
) ||
338 sysfs_devno_is_wholedisk(devno
) <= 0)
341 if (!sysfs_devno_to_devpath(devno
, buf
, sizeof(buf
)))
344 cn
= canonicalize_path(buf
);
348 if (!is_ide_cdrom_or_tape(cn
))
357 int print_device_pt(struct fdisk_context
*cxt
, char *device
, int warnme
, int verify
)
359 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
360 if (warnme
|| errno
== EACCES
)
361 warn(_("cannot open %s"), device
);
365 list_disk_geometry(cxt
);
367 if (fdisk_has_label(cxt
)) {
370 fdisk_verify_disklabel(cxt
);
372 fdisk_deassign_device(cxt
, 1);
376 int print_device_freespace(struct fdisk_context
*cxt
, char *device
, int warnme
)
378 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
379 if (warnme
|| errno
== EACCES
)
380 warn(_("cannot open %s"), device
);
385 fdisk_deassign_device(cxt
, 1);
389 void print_all_devices_pt(struct fdisk_context
*cxt
, int verify
)
395 while ((dev
= next_proc_partition(&f
))) {
397 fputs("\n\n", stdout
);
398 if (print_device_pt(cxt
, dev
, 0, verify
) == 0)
404 void print_all_devices_freespace(struct fdisk_context
*cxt
)
410 while ((dev
= next_proc_partition(&f
))) {
412 fputs("\n\n", stdout
);
413 if (print_device_freespace(cxt
, dev
, 0) == 0)
419 /* usable for example in usage() */
420 void list_available_columns(FILE *out
)
424 struct fdisk_label
*lb
= NULL
;
425 struct fdisk_context
*cxt
= fdisk_new_context();
430 termwidth
= get_terminal_width(80);
432 fprintf(out
, _("\nAvailable columns (for -o):\n"));
434 while (fdisk_next_label(cxt
, &lb
) == 0) {
435 size_t width
= 6; /* label name and separators */
437 fprintf(out
, " %s:", fdisk_label_get_name(lb
));
438 for (i
= 1; i
< FDISK_NFIELDS
; i
++) {
439 const struct fdisk_field
*fl
= fdisk_label_get_field(lb
, i
);
440 const char *name
= fl
? fdisk_field_get_name(fl
) : NULL
;
445 len
= strlen(name
) + 1;
446 if (width
+ len
> (size_t) termwidth
) {
450 fprintf(out
, " %s", name
);
456 fdisk_unref_context(cxt
);
459 static int fieldname_to_id(const char *name
, size_t namesz
)
461 const struct fdisk_field
*fl
;
462 char buf
[namesz
+ 1];
466 assert(fields_label
);
468 memcpy(buf
, name
, namesz
);
471 fl
= fdisk_label_get_field_by_name(fields_label
, buf
);
473 warnx(_("%s unknown column: %s"),
474 fdisk_label_get_name(fields_label
), buf
);
477 return fdisk_field_get_id(fl
);
481 * Initialize array with output columns (fields_ids[]) according to
482 * comma delimited list of columns (@str). If the list string is not
483 * defined then use library defaults. This function is "-o <list>"
486 * If the columns are already initialized then returns already existing columns.
488 int *init_fields(struct fdisk_context
*cxt
, const char *str
, size_t *n
)
490 int *dflt_ids
= NULL
;
491 struct fdisk_label
*lb
;
498 lb
= fdisk_get_label(cxt
, NULL
);
500 if (!lb
|| fields_label
!= lb
) { /* label changed: reset */
507 if (!fields_label
) /* no label */
510 goto done
; /* already initialized */
512 /* library default */
513 if (fdisk_label_get_fields_ids(NULL
, cxt
, &dflt_ids
, &fields_nids
))
516 fields_ids
= xcalloc(FDISK_NFIELDS
* 2, sizeof(int));
518 /* copy defaults to the list with wanted fields */
519 memcpy(fields_ids
, dflt_ids
, fields_nids
* sizeof(int));
522 /* extend or replace fields_nids[] according to fields_string */
524 string_add_to_idarray(fields_string
, fields_ids
, FDISK_NFIELDS
* 2,
525 &fields_nids
, fieldname_to_id
) < 0)