]>
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
);
38 void list_disk_geometry(struct fdisk_context
*cxt
)
41 struct fdisk_label
*lb
= fdisk_get_label(cxt
, NULL
);
42 uint64_t bytes
= fdisk_get_nsectors(cxt
) * fdisk_get_sector_size(cxt
);
43 char *strsz
= size_to_human_string(SIZE_SUFFIX_SPACE
44 | SIZE_SUFFIX_3LETTER
, bytes
);
46 color_scheme_enable("header", UL_COLOR_BOLD
);
47 fdisk_info(cxt
, _("Disk %s: %s, %ju bytes, %ju sectors"),
48 fdisk_get_devname(cxt
), strsz
,
49 bytes
, (uintmax_t) fdisk_get_nsectors(cxt
));
53 if (lb
&& (fdisk_label_require_geometry(lb
) || fdisk_use_cylinders(cxt
)))
54 fdisk_info(cxt
, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"),
55 fdisk_get_geom_heads(cxt
),
56 fdisk_get_geom_sectors(cxt
),
57 fdisk_get_geom_cylinders(cxt
));
59 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
60 fdisk_get_unit(cxt
, FDISK_PLURAL
),
61 fdisk_get_units_per_sector(cxt
),
62 fdisk_get_sector_size(cxt
),
63 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
65 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
66 fdisk_get_sector_size(cxt
),
67 fdisk_get_physector_size(cxt
));
68 fdisk_info(cxt
, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"),
69 fdisk_get_minimal_iosize(cxt
),
70 fdisk_get_optimal_iosize(cxt
));
71 if (fdisk_get_alignment_offset(cxt
))
72 fdisk_info(cxt
, _("Alignment offset: %lu bytes"),
73 fdisk_get_alignment_offset(cxt
));
74 if (fdisk_has_label(cxt
))
75 fdisk_info(cxt
, _("Disklabel type: %s"),
76 fdisk_label_get_name(lb
));
78 if (!fdisk_is_details(cxt
) && fdisk_get_disklabel_id(cxt
, &id
) == 0 && id
)
79 fdisk_info(cxt
, _("Disk identifier: %s"), id
);
82 void list_disklabel(struct fdisk_context
*cxt
)
84 struct fdisk_table
*tb
= NULL
;
85 struct fdisk_partition
*pa
= NULL
;
86 struct fdisk_iter
*itr
= NULL
;
87 struct fdisk_label
*lb
;
88 struct libscols_table
*out
= NULL
;
89 const char *bold
= NULL
;
90 int *ids
= NULL
; /* IDs of fdisk_fields */
94 /* print label specific stuff by libfdisk FDISK_ASK_INFO API */
95 fdisk_list_disklabel(cxt
);
97 /* get partitions and generate output */
98 if (fdisk_get_partitions(cxt
, &tb
) || fdisk_table_get_nents(tb
) <= 0)
101 ids
= init_fields(cxt
, NULL
, &nids
);
105 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
107 fdisk_warn(cxt
, _("failed to allocate iterator"));
111 out
= scols_new_table();
113 fdisk_warn(cxt
, _("failed to allocate output table"));
117 if (colors_wanted()) {
118 scols_table_enable_colors(out
, 1);
119 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
122 lb
= fdisk_get_label(cxt
, NULL
);
125 /* define output table columns */
126 for (i
= 0; i
< nids
; i
++) {
128 struct libscols_column
*co
;
129 const struct fdisk_field
*field
=
130 fdisk_label_get_field(lb
, ids
[i
]);
133 if (fdisk_field_is_number(field
))
134 fl
|= SCOLS_FL_RIGHT
;
135 if (fdisk_field_get_id(field
) == FDISK_FIELD_TYPE
)
136 fl
|= SCOLS_FL_TRUNC
;
138 co
= scols_table_new_column(out
,
139 _(fdisk_field_get_name(field
)),
140 fdisk_field_get_width(field
), fl
);
144 /* set colum header color */
146 scols_cell_set_color(scols_column_get_header(co
), bold
);
149 /* fill-in output table */
150 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
151 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
154 fdisk_warn(cxt
, _("failed to allocate output line"));
158 for (i
= 0; i
< nids
; i
++) {
161 if (fdisk_partition_to_string(pa
, cxt
, ids
[i
], &data
))
163 scols_line_refer_data(ln
, i
, data
);
168 if (!scols_table_is_empty(out
)) {
170 scols_print_table(out
);
174 fdisk_reset_iter(itr
, FDISK_ITER_FORWARD
);
175 while (itr
&& fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
176 if (!fdisk_partition_has_start(pa
))
178 if (!fdisk_lba_is_phy_aligned(cxt
, fdisk_partition_get_start(pa
))) {
181 fdisk_warnx(cxt
, _("Partition %zu does not start on physical sector boundary."),
182 fdisk_partition_get_partno(pa
) + 1);
187 if (fdisk_table_wrong_order(tb
)) {
190 fdisk_info(cxt
, _("Partition table entries are not in disk order."));
193 scols_unref_table(out
);
194 fdisk_unref_table(tb
);
195 fdisk_free_iter(itr
);
198 void list_freespace(struct fdisk_context
*cxt
)
200 struct fdisk_table
*tb
= NULL
;
201 struct fdisk_partition
*pa
= NULL
;
202 struct fdisk_iter
*itr
= NULL
;
203 struct libscols_table
*out
= NULL
;
204 const char *bold
= NULL
;
206 uintmax_t sumsize
= 0, bytes
= 0;
209 static const char *colnames
[] = { N_("Start"), N_("End"), N_("Sectors"), N_("Size") };
210 static const int colids
[] = { FDISK_FIELD_START
, FDISK_FIELD_END
, FDISK_FIELD_SECTORS
, FDISK_FIELD_SIZE
};
212 if (fdisk_get_freespaces(cxt
, &tb
))
215 itr
= fdisk_new_iter(FDISK_ITER_FORWARD
);
217 fdisk_warn(cxt
, _("failed to allocate iterator"));
221 out
= scols_new_table();
223 fdisk_warn(cxt
, _("failed to allocate output table"));
227 if (colors_wanted()) {
228 scols_table_enable_colors(out
, 1);
229 bold
= color_scheme_get_sequence("header", UL_COLOR_BOLD
);
232 for (i
= 0; i
< ARRAY_SIZE(colnames
); i
++) {
233 struct libscols_column
*co
= scols_table_new_column(out
, _(colnames
[i
]), 5, SCOLS_FL_RIGHT
);
238 scols_cell_set_color(scols_column_get_header(co
), bold
);
241 /* fill-in output table */
242 while (fdisk_table_next_partition(tb
, itr
, &pa
) == 0) {
243 struct libscols_line
*ln
= scols_table_new_line(out
, NULL
);
247 fdisk_warn(cxt
, _("failed to allocate output line"));
250 for (i
= 0; i
< ARRAY_SIZE(colids
); i
++) {
251 if (fdisk_partition_to_string(pa
, cxt
, colids
[i
], &data
))
253 scols_line_refer_data(ln
, i
, data
);
256 if (fdisk_partition_has_size(pa
))
257 sumsize
+= fdisk_partition_get_size(pa
);
260 bytes
= sumsize
* fdisk_get_sector_size(cxt
);
261 strsz
= size_to_human_string(SIZE_SUFFIX_SPACE
262 | SIZE_SUFFIX_3LETTER
, bytes
);
264 color_scheme_enable("header", UL_COLOR_BOLD
);
265 fdisk_info(cxt
, _("Unpartitioned space %s: %s, %ju bytes, %ju sectors"),
266 fdisk_get_devname(cxt
), strsz
,
271 fdisk_info(cxt
, _("Units: %s of %d * %ld = %ld bytes"),
272 fdisk_get_unit(cxt
, FDISK_PLURAL
),
273 fdisk_get_units_per_sector(cxt
),
274 fdisk_get_sector_size(cxt
),
275 fdisk_get_units_per_sector(cxt
) * fdisk_get_sector_size(cxt
));
277 fdisk_info(cxt
, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
278 fdisk_get_sector_size(cxt
),
279 fdisk_get_physector_size(cxt
));
282 if (!scols_table_is_empty(out
)) {
284 scols_print_table(out
);
287 scols_unref_table(out
);
288 fdisk_unref_table(tb
);
289 fdisk_free_iter(itr
);
292 char *next_proc_partition(FILE **f
)
297 *f
= fopen(_PATH_PROC_PARTITIONS
, "r");
299 warn(_("cannot open %s"), _PATH_PROC_PARTITIONS
);
304 while (fgets(line
, sizeof(line
), *f
)) {
305 char buf
[PATH_MAX
], *cn
;
308 if (sscanf(line
, " %*d %*d %*d %128[^\n ]", buf
) != 1)
311 devno
= sysfs_devname_to_devno(buf
, NULL
);
315 if (sysfs_devno_is_lvm_private(devno
) ||
316 sysfs_devno_is_wholedisk(devno
) <= 0)
319 if (!sysfs_devno_to_devpath(devno
, buf
, sizeof(buf
)))
322 cn
= canonicalize_path(buf
);
326 if (!is_ide_cdrom_or_tape(cn
))
335 int print_device_pt(struct fdisk_context
*cxt
, char *device
, int warnme
, int verify
)
337 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
338 if (warnme
|| errno
== EACCES
)
339 warn(_("cannot open %s"), device
);
343 list_disk_geometry(cxt
);
345 if (fdisk_has_label(cxt
)) {
348 fdisk_verify_disklabel(cxt
);
350 fdisk_deassign_device(cxt
, 1);
354 int print_device_freespace(struct fdisk_context
*cxt
, char *device
, int warnme
)
356 if (fdisk_assign_device(cxt
, device
, 1) != 0) { /* read-only */
357 if (warnme
|| errno
== EACCES
)
358 warn(_("cannot open %s"), device
);
363 fdisk_deassign_device(cxt
, 1);
367 void print_all_devices_pt(struct fdisk_context
*cxt
, int verify
)
373 while ((dev
= next_proc_partition(&f
))) {
375 fputs("\n\n", stdout
);
376 if (print_device_pt(cxt
, dev
, 0, verify
) == 0)
382 void print_all_devices_freespace(struct fdisk_context
*cxt
)
388 while ((dev
= next_proc_partition(&f
))) {
390 fputs("\n\n", stdout
);
391 if (print_device_freespace(cxt
, dev
, 0) == 0)
397 /* usable for example in usage() */
398 void list_available_columns(FILE *out
)
402 struct fdisk_label
*lb
= NULL
;
403 struct fdisk_context
*cxt
= fdisk_new_context();
408 termwidth
= get_terminal_width();
412 fprintf(out
, _("\nAvailable columns (for -o):\n"));
414 while (fdisk_next_label(cxt
, &lb
) == 0) {
415 size_t width
= 6; /* label name and separators */
417 fprintf(out
, " %s:", fdisk_label_get_name(lb
));
418 for (i
= 1; i
< FDISK_NFIELDS
; i
++) {
419 const struct fdisk_field
*fl
= fdisk_label_get_field(lb
, i
);
420 const char *name
= fl
? fdisk_field_get_name(fl
) : NULL
;
425 len
= strlen(name
) + 1;
426 if (width
+ len
> (size_t) termwidth
) {
430 fprintf(out
, " %s", name
);
436 fdisk_unref_context(cxt
);
439 static int fieldname_to_id(const char *name
, size_t namesz
)
441 const struct fdisk_field
*fl
;
442 char buf
[namesz
+ 1];
446 assert(fields_label
);
448 memcpy(buf
, name
, namesz
);
451 fl
= fdisk_label_get_field_by_name(fields_label
, buf
);
453 warnx(_("%s unknown column: %s"),
454 fdisk_label_get_name(fields_label
), buf
);
457 return fdisk_field_get_id(fl
);
461 * Initialize array with output columns (fields_ids[]) according to
462 * comma delimited list of columns (@str). If the list string is not
463 * defined then use library defaults. This function is "-o <list>"
466 * If the columns are already initialized then returns already existing columns.
468 int *init_fields(struct fdisk_context
*cxt
, const char *str
, size_t *n
)
470 int *dflt_ids
= NULL
;
471 struct fdisk_label
*lb
;
478 lb
= fdisk_get_label(cxt
, NULL
);
480 if (!lb
|| fields_label
!= lb
) { /* label changed: reset */
487 if (!fields_label
) /* no label */
490 goto done
; /* already initialized */
492 /* library default */
493 if (fdisk_label_get_fields_ids(NULL
, cxt
, &dflt_ids
, &fields_nids
))
496 fields_ids
= xcalloc(FDISK_NFIELDS
* 2, sizeof(int));
498 /* copy defaults to the list with wanted fields */
499 memcpy(fields_ids
, dflt_ids
, fields_nids
* sizeof(int));
502 /* extend or replace fields_nids[] according to fields_string */
504 string_add_to_idarray(fields_string
, fields_ids
, FDISK_NFIELDS
* 2,
505 &fields_nids
, fieldname_to_id
) < 0)