]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/fdisk-list.c
fdisk: refactor /proc/partitions usage
[thirdparty/util-linux.git] / disk-utils / fdisk-list.c
CommitLineData
152788aa
KZ
1#include <libfdisk.h>
2#include <libsmartcols.h>
3#include <assert.h>
4
5#include "c.h"
6#include "xalloc.h"
7#include "nls.h"
8#include "blkdev.h"
9#include "mbsalign.h"
10#include "pathnames.h"
11#include "canonicalize.h"
12#include "strutils.h"
13#include "sysfs.h"
14#include "colors.h"
15
16#include "fdisk-list.h"
17
18static int is_ide_cdrom_or_tape(char *device)
19{
20 int fd, ret;
21
22 if ((fd = open(device, O_RDONLY)) < 0)
23 return 0;
24 ret = blkdev_is_cdrom(fd);
25
26 close(fd);
27 return ret;
28}
29
30
31void list_disk_geometry(struct fdisk_context *cxt)
32{
33 char *id = NULL;
34 struct fdisk_label *lb = fdisk_get_label(cxt, NULL);
35 uint64_t bytes = fdisk_get_nsectors(cxt) * fdisk_get_sector_size(cxt);
36 char *strsz = size_to_human_string(SIZE_SUFFIX_SPACE
37 | SIZE_SUFFIX_3LETTER, bytes);
38
39 color_scheme_enable("header", UL_COLOR_BOLD);
40 fdisk_info(cxt, _("Disk %s: %s, %ju bytes, %ju sectors"),
41 fdisk_get_devname(cxt), strsz,
42 bytes, (uintmax_t) fdisk_get_nsectors(cxt));
43 color_disable();
44 free(strsz);
45
46 if (lb && (fdisk_label_require_geometry(lb) || fdisk_use_cylinders(cxt)))
47 fdisk_info(cxt, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"),
48 fdisk_get_geom_heads(cxt),
49 fdisk_get_geom_sectors(cxt),
50 fdisk_get_geom_cylinders(cxt));
51
52 fdisk_info(cxt, _("Units: %s of %d * %ld = %ld bytes"),
53 fdisk_get_unit(cxt, FDISK_PLURAL),
54 fdisk_get_units_per_sector(cxt),
55 fdisk_get_sector_size(cxt),
56 fdisk_get_units_per_sector(cxt) * fdisk_get_sector_size(cxt));
57
58 fdisk_info(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
59 fdisk_get_sector_size(cxt),
60 fdisk_get_physector_size(cxt));
61 fdisk_info(cxt, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"),
62 fdisk_get_minimal_iosize(cxt),
63 fdisk_get_optimal_iosize(cxt));
64 if (fdisk_get_alignment_offset(cxt))
65 fdisk_info(cxt, _("Alignment offset: %lu bytes"),
66 fdisk_get_alignment_offset(cxt));
67 if (fdisk_has_label(cxt))
68 fdisk_info(cxt, _("Disklabel type: %s"),
69 fdisk_label_get_name(lb));
70
71 if (fdisk_get_disklabel_id(cxt, &id) == 0 && id)
72 fdisk_info(cxt, _("Disk identifier: %s"), id);
73}
74
75void list_disklabel(struct fdisk_context *cxt)
76{
77 struct fdisk_table *tb = NULL;
78 struct fdisk_partition *pa = NULL;
79 struct fdisk_iter *itr = NULL;
80 struct fdisk_label *lb;
81 struct libscols_table *out = NULL;
82 const char *bold = NULL;
83 int *ids = NULL; /* IDs of fdisk_fields */
84 size_t nids = 0, i;
85
86 /* print label specific stuff by libfdisk FDISK_ASK_INFO API */
87 fdisk_list_disklabel(cxt);
88
89 /* get partitions and generate output */
90 if (fdisk_get_partitions(cxt, &tb) || fdisk_table_get_nents(tb) <= 0)
91 goto done;
92
93 if (fdisk_label_get_fields_ids(NULL, cxt, &ids, &nids))
94 goto done;
95
96 itr = fdisk_new_iter(FDISK_ITER_FORWARD);
97 if (!itr) {
98 fdisk_warn(cxt, _("faild to allocate iterator"));
99 goto done;
100 }
101
102 out = scols_new_table();
103 if (!out) {
104 fdisk_warn(cxt, _("faild to allocate output table"));
105 goto done;
106 }
107
108 if (colors_wanted()) {
109 scols_table_enable_colors(out, 1);
110 bold = color_scheme_get_sequence("header", UL_COLOR_BOLD);
111 }
112
113 lb = fdisk_get_label(cxt, NULL);
114 assert(lb);
115
116 /* define output table columns */
117 for (i = 0; i < nids; i++) {
118 int fl = 0;
119 struct libscols_column *co;
120 const struct fdisk_field *field =
121 fdisk_label_get_field(lb, ids[i]);
122 if (!field)
123 goto done;
124 if (fdisk_field_is_number(field))
125 fl |= SCOLS_FL_RIGHT;
126 if (fdisk_field_get_id(field) == FDISK_FIELD_TYPE)
127 fl |= SCOLS_FL_TRUNC;
128
129 co = scols_table_new_column(out,
130 fdisk_field_get_name(field),
131 fdisk_field_get_width(field), fl);
132 if (!co)
133 goto done;
134
135 /* set colum header color */
136 if (bold)
137 scols_cell_set_color(scols_column_get_header(co), bold);
138 }
139
140 /* fill-in output table */
141 while (fdisk_table_next_partition(tb, itr, &pa) == 0) {
142 struct libscols_line *ln = scols_table_new_line(out, NULL);
143
144 if (!ln) {
145 fdisk_warn(cxt, _("faild to allocate output line"));
146 goto done;
147 }
148
149 for (i = 0; i < nids; i++) {
150 char *data = NULL;
151
152 if (fdisk_partition_to_string(pa, cxt, ids[i], &data))
153 continue;
154 scols_line_refer_data(ln, i, data);
155 }
156 }
157
158 /* print */
159 if (!scols_table_is_empty(out)) {
160 fputc('\n', stdout);
161 scols_print_table(out);
162 }
163
164 /* print warnings */
165 while (itr && fdisk_table_next_partition(tb, itr, &pa) == 0) {
166 if (!fdisk_lba_is_phy_aligned(cxt, fdisk_partition_get_start(pa)))
167 fdisk_warnx(cxt, _("Partition %zu does not start on physical sector boundary."),
168 fdisk_partition_get_partno(pa) + 1);
169 }
170
171 if (fdisk_table_wrong_order(tb))
172 fdisk_info(cxt, _("Partition table entries are not in disk order."));
173done:
174 free(ids);
175 scols_unref_table(out);
176 fdisk_unref_table(tb);
177 fdisk_free_iter(itr);
178}
179
d464e2f0 180char *next_proc_partition(FILE **f)
152788aa 181{
152788aa 182 char line[128 + 1];
152788aa 183
d464e2f0
KZ
184 if (!*f) {
185 *f = fopen(_PATH_PROC_PARTITIONS, "r");
186 if (!*f) {
187 warn(_("cannot open %s"), _PATH_PROC_PARTITIONS);
188 return NULL;
189 }
152788aa
KZ
190 }
191
d464e2f0 192 while (fgets(line, sizeof(line), *f)) {
152788aa
KZ
193 char buf[PATH_MAX], *cn;
194 dev_t devno;
195
196 if (sscanf(line, " %*d %*d %*d %128[^\n ]", buf) != 1)
197 continue;
198
199 devno = sysfs_devname_to_devno(buf, NULL);
200 if (devno <= 0)
201 continue;
202
203 if (sysfs_devno_is_lvm_private(devno) ||
204 sysfs_devno_is_wholedisk(devno) <= 0)
205 continue;
206
207 if (!sysfs_devno_to_devpath(devno, buf, sizeof(buf)))
208 continue;
209
210 cn = canonicalize_path(buf);
211 if (!cn)
212 continue;
213
d464e2f0
KZ
214 if (!is_ide_cdrom_or_tape(cn))
215 return cn;
216 }
217 fclose(*f);
218 *f = NULL;
219
220 return NULL;
221}
222
223int print_device_pt(struct fdisk_context *cxt, char *device, int warnme)
224{
225 if (fdisk_assign_device(cxt, device, 1) != 0) { /* read-only */
226 if (warnme || errno == EACCES)
227 warn(_("cannot open %s"), device);
228 return -1;
229 }
230
231 list_disk_geometry(cxt);
232
233 if (fdisk_has_label(cxt))
234 list_disklabel(cxt);
235
236 fdisk_deassign_device(cxt, 1);
237 return 0;
238}
239
240void print_all_devices_pt(struct fdisk_context *cxt)
241{
242 FILE *f = NULL;
243 int ct = 0;
244 char *dev;
245
246 while ((dev = next_proc_partition(&f))) {
247 if (ct)
248 fputs("\n\n", stdout);
249 if (print_device_pt(cxt, dev, 0) == 0)
250 ct++;
251 free(dev);
152788aa 252 }
152788aa
KZ
253}
254