]>
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 (fdisk_get_devmodel(cxt
))
67 fdisk_info(cxt
, _("Disk model: %s"), fdisk_get_devmodel(cxt
));
69 if (lb
&& (fdisk_label_require_geometry(lb
) || fdisk_use_cylinders(cxt
)))
70 fdisk_info(cxt
, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"),
71 fdisk_get_geom_heads(cxt
),
72 fdisk_get_geom_sectors(cxt
),
73 fdisk_get_geom_cylinders(cxt
));
75 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
76 fdisk_get_unit(cxt
, FDISK_PLURAL
),
77 fdisk_get_units_per_sector(cxt
),
78 fdisk_get_sector_size(cxt
),
79 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
81 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
82 fdisk_get_sector_size(cxt
),
83 fdisk_get_physector_size(cxt
));
84 fdisk_info(cxt
, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"),
85 fdisk_get_minimal_iosize(cxt
),
86 fdisk_get_optimal_iosize(cxt
));
87 if (fdisk_get_alignment_offset(cxt
))
88 fdisk_info(cxt
, _("Alignment offset: %lu bytes"),
89 fdisk_get_alignment_offset(cxt
));
91 list_disk_identifier(cxt
);
94 void list_disklabel(struct fdisk_context
*cxt
)
96 struct fdisk_table
*tb
= NULL
;
97 struct fdisk_partition
*pa
= NULL
;
98 struct fdisk_iter
*itr
= NULL
;
99 struct fdisk_label
*lb
;
100 struct libscols_table
*out
= NULL
;
101 const char *bold
= NULL
;
102 int *ids
= NULL
; /* IDs of fdisk_fields */
106 /* print label specific stuff by libfdisk FDISK_ASK_INFO API */
107 fdisk_list_disklabel(cxt
);
109 /* get partitions and generate output */
110 if (fdisk_get_partitions(cxt
, &tb
) || fdisk_table_get_nents(tb
) <= 0)
113 ids
= init_fields(cxt
, NULL
, &nids
);
117 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
119 fdisk_warn(cxt
, _("failed to allocate iterator"));
123 out
= scols_new_table();
125 fdisk_warn(cxt
, _("failed to allocate output table"));
129 if (colors_wanted()) {
130 scols_table_enable_colors(out
, 1);
131 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
134 lb
= fdisk_get_label(cxt
, NULL
);
137 /* define output table columns */
138 for (i
= 0; i
< nids
; i
++) {
140 struct libscols_column
*co
;
141 const struct fdisk_field
*field
=
142 fdisk_label_get_field(lb
, ids
[i
]);
145 if (fdisk_field_is_number(field
))
146 fl
|= SCOLS_FL_RIGHT
;
147 if (fdisk_field_get_id(field
) == FDISK_FIELD_TYPE
)
148 fl
|= SCOLS_FL_TRUNC
;
150 co
= scols_table_new_column(out
,
151 _(fdisk_field_get_name(field
)),
152 fdisk_field_get_width(field
), fl
);
156 /* set column header color */
158 scols_cell_set_color(scols_column_get_header(co
), bold
);
161 /* fill-in output table */
162 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
163 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
166 fdisk_warn(cxt
, _("failed to allocate output line"));
170 for (i
= 0; i
< nids
; i
++) {
173 if (fdisk_partition_to_string(pa
, cxt
, ids
[i
], &data
))
175 if (scols_line_refer_data(ln
, i
, data
)) {
176 fdisk_warn(cxt
, _("failed to add output data"));
183 if (!scols_table_is_empty(out
)) {
184 fdisk_info(cxt
, ""); /* just line break */
185 scols_print_table(out
);
189 fdisk_reset_iter(itr
, FDISK_ITER_FORWARD
);
190 while (itr
&& fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
191 if (!fdisk_partition_has_start(pa
))
193 if (!fdisk_lba_is_phy_aligned(cxt
, fdisk_partition_get_start(pa
))) {
195 fdisk_info(cxt
, ""); /* line break */
196 fdisk_warnx(cxt
, _("Partition %zu does not start on physical sector boundary."),
197 fdisk_partition_get_partno(pa
) + 1);
200 if (fdisk_partition_has_wipe(cxt
, pa
)) {
202 fdisk_info(cxt
, ""); /* line break */
203 fdisk_info(cxt
, _("Filesystem/RAID signature on partition %zu will be wiped."),
204 fdisk_partition_get_partno(pa
) + 1);
209 if (fdisk_table_wrong_order(tb
)) {
211 fdisk_info(cxt
, ""); /* line break */
212 fdisk_info(cxt
, _("Partition table entries are not in disk order."));
215 scols_unref_table(out
);
216 fdisk_unref_table(tb
);
217 fdisk_free_iter(itr
);
220 void list_freespace(struct fdisk_context
*cxt
)
222 struct fdisk_table
*tb
= NULL
;
223 struct fdisk_partition
*pa
= NULL
;
224 struct fdisk_iter
*itr
= NULL
;
225 struct libscols_table
*out
= NULL
;
226 const char *bold
= NULL
;
228 uintmax_t sumsize
= 0, bytes
= 0;
231 static const char *colnames
[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
232 static const int colids
[] = { FDISK_FIELD_START
, FDISK_FIELD_END
, FDISK_FIELD_SECTORS
, FDISK_FIELD_SIZE
};
234 if (fdisk_get_freespaces(cxt
, &tb
))
237 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
239 fdisk_warn(cxt
, _("failed to allocate iterator"));
243 out
= scols_new_table();
245 fdisk_warn(cxt
, _("failed to allocate output table"));
249 if (colors_wanted()) {
250 scols_table_enable_colors(out
, 1);
251 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
254 for (i
= 0; i
< ARRAY_SIZE(colnames
); i
++) {
255 struct libscols_column
*co
= scols_table_new_column(out
, _(colnames
[i
]), 5, SCOLS_FL_RIGHT
);
260 scols_cell_set_color(scols_column_get_header(co
), bold
);
263 /* fill-in output table */
264 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
265 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
269 fdisk_warn(cxt
, _("failed to allocate output line"));
272 for (i
= 0; i
< ARRAY_SIZE(colids
); i
++) {
273 if (fdisk_partition_to_string(pa
, cxt
, colids
[i
], &data
))
275 if (scols_line_refer_data(ln
, i
, data
)) {
276 fdisk_warn(cxt
, _("failed to add output data"));
281 if (fdisk_partition_has_size(pa
))
282 sumsize
+= fdisk_partition_get_size(pa
);
285 bytes
= sumsize
* fdisk_get_sector_size(cxt
);
286 strsz
= size_to_human_string(SIZE_SUFFIX_SPACE
287 | SIZE_SUFFIX_3LETTER
, bytes
);
289 color_scheme_enable("header", UL_COLOR_BOLD
);
290 fdisk_info(cxt
, _("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
291 fdisk_get_devname(cxt
), strsz
,
296 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
297 fdisk_get_unit(cxt
, FDISK_PLURAL
),
298 fdisk_get_units_per_sector(cxt
),
299 fdisk_get_sector_size(cxt
),
300 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
302 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
303 fdisk_get_sector_size(cxt
),
304 fdisk_get_physector_size(cxt
));
307 if (!scols_table_is_empty(out
)) {
308 fdisk_info(cxt
, ""); /* line break */
309 scols_print_table(out
);
312 scols_unref_table(out
);
313 fdisk_unref_table(tb
);
314 fdisk_free_iter(itr
);
317 char *next_proc_partition(FILE **f
)
322 *f
= fopen(_PATH_PROC_PARTITIONS
, "r");
324 warn(_("cannot open %s"), _PATH_PROC_PARTITIONS
);
329 while (fgets(line
, sizeof(line
), *f
)) {
330 char buf
[PATH_MAX
], *cn
;
333 if (sscanf(line
, " %*d %*d %*d %128[^\n ]", buf
) != 1)
336 devno
= sysfs_devname_to_devno(buf
);
340 if (sysfs_devno_is_dm_private(devno
, NULL
) ||
341 sysfs_devno_is_wholedisk(devno
) <= 0)
344 if (!sysfs_devno_to_devpath(devno
, buf
, sizeof(buf
)))
347 cn
= canonicalize_path(buf
);
351 if (!is_ide_cdrom_or_tape(cn
))
360 int print_device_pt(struct fdisk_context
*cxt
, char *device
, int warnme
, int verify
)
362 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
363 if (warnme
|| errno
== EACCES
)
364 warn(_("cannot open %s"), device
);
368 list_disk_geometry(cxt
);
370 if (fdisk_has_label(cxt
)) {
373 fdisk_verify_disklabel(cxt
);
375 fdisk_deassign_device(cxt
, 1);
379 int print_device_freespace(struct fdisk_context
*cxt
, char *device
, int warnme
)
381 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
382 if (warnme
|| errno
== EACCES
)
383 warn(_("cannot open %s"), device
);
388 fdisk_deassign_device(cxt
, 1);
392 void print_all_devices_pt(struct fdisk_context
*cxt
, int verify
)
398 while ((dev
= next_proc_partition(&f
))) {
400 fputs("\n\n", stdout
);
401 if (print_device_pt(cxt
, dev
, 0, verify
) == 0)
407 void print_all_devices_freespace(struct fdisk_context
*cxt
)
413 while ((dev
= next_proc_partition(&f
))) {
415 fputs("\n\n", stdout
);
416 if (print_device_freespace(cxt
, dev
, 0) == 0)
422 /* usable for example in usage() */
423 void list_available_columns(FILE *out
)
427 struct fdisk_label
*lb
= NULL
;
428 struct fdisk_context
*cxt
= fdisk_new_context();
433 termwidth
= get_terminal_width(80);
435 fprintf(out
, USAGE_COLUMNS
);
437 while (fdisk_next_label(cxt
, &lb
) == 0) {
438 size_t width
= 6; /* label name and separators */
440 fprintf(out
, " %s:", fdisk_label_get_name(lb
));
441 for (i
= 1; i
< FDISK_NFIELDS
; i
++) {
442 const struct fdisk_field
*fl
= fdisk_label_get_field(lb
, i
);
443 const char *name
= fl
? fdisk_field_get_name(fl
) : NULL
;
448 len
= strlen(name
) + 1;
449 if (width
+ len
> (size_t) termwidth
) {
453 fprintf(out
, " %s", name
);
459 fdisk_unref_context(cxt
);
462 static int fieldname_to_id(const char *name
, size_t namesz
)
464 const struct fdisk_field
*fl
;
465 char buf
[namesz
+ 1];
469 assert(fields_label
);
471 memcpy(buf
, name
, namesz
);
474 fl
= fdisk_label_get_field_by_name(fields_label
, buf
);
476 warnx(_("%s unknown column: %s"),
477 fdisk_label_get_name(fields_label
), buf
);
480 return fdisk_field_get_id(fl
);
484 * Initialize array with output columns (fields_ids[]) according to
485 * comma delimited list of columns (@str). If the list string is not
486 * defined then use library defaults. This function is "-o <list>"
489 * If the columns are already initialized then returns already existing columns.
491 int *init_fields(struct fdisk_context
*cxt
, const char *str
, size_t *n
)
493 int *dflt_ids
= NULL
;
494 struct fdisk_label
*lb
;
501 lb
= fdisk_get_label(cxt
, NULL
);
503 if (!lb
|| fields_label
!= lb
) { /* label changed: reset */
510 if (!fields_label
) /* no label */
513 goto done
; /* already initialized */
515 /* library default */
516 if (fdisk_label_get_fields_ids(NULL
, cxt
, &dflt_ids
, &fields_nids
))
519 fields_ids
= xcalloc(FDISK_NFIELDS
* 2, sizeof(int));
521 /* copy defaults to the list with wanted fields */
522 memcpy(fields_ids
, dflt_ids
, fields_nids
* sizeof(int));
525 /* extend or replace fields_nids[] according to fields_string */
527 string_add_to_idarray(fields_string
, fields_ids
, FDISK_NFIELDS
* 2,
528 &fields_nids
, fieldname_to_id
) < 0)