]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libfdisk/src/fdiskP.h
libfdisk: rename fdisk_column to fdisk_field
[thirdparty/util-linux.git] / libfdisk / src / fdiskP.h
1 /*
2 * fdiskP.h - private library header file
3 *
4 * Copyright (C) 2012 Karel Zak <kzak@redhat.com>
5 *
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
8 */
9
10 #ifndef _LIBFDISK_PRIVATE_H
11 #define _LIBFDISK_PRIVATE_H
12
13 #include <errno.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19
20
21 #include "c.h"
22 #include "libfdisk.h"
23
24 #include "nls.h" /* temporary before dialog API will be implamented */
25 #include "list.h"
26 #include "debug.h"
27 #include <stdio.h>
28 #include <stdarg.h>
29
30 /* features */
31 #define CONFIG_LIBFDISK_ASSERT
32
33 #ifdef CONFIG_LIBFDISK_ASSERT
34 #include <assert.h>
35 #endif
36
37 /*
38 * Debug
39 */
40 #define FDISK_DEBUG_INIT (1 << 1)
41 #define FDISK_DEBUG_CXT (1 << 2)
42 #define FDISK_DEBUG_LABEL (1 << 3)
43 #define FDISK_DEBUG_ASK (1 << 4)
44 #define FDISK_DEBUG_FRONTEND (1 << 5)
45 #define FDISK_DEBUG_PART (1 << 6)
46 #define FDISK_DEBUG_PARTTYPE (1 << 7)
47 #define FDISK_DEBUG_TAB (1 << 8)
48 #define FDISK_DEBUG_ALL 0xFFFF
49
50 UL_DEBUG_DECLARE_MASK(libfdisk);
51 #define DBG(m, x) __UL_DBG(libfdisk, FDISK_DEBUG_, m, x)
52 #define ON_DBG(m, x) __UL_DBG_CALL(libfdisk, FDISK_DEBUG_, m, x)
53 #define DBG_FLUSH __UL_DBG_FLUSH(libfdisk, FDISK_DEBUG_)
54
55 #ifdef TEST_PROGRAM
56 struct fdisk_test {
57 const char *name;
58 int (*body)(struct fdisk_test *ts, int argc, char *argv[]);
59 const char *usage;
60 };
61
62 /* test.c */
63 extern int fdisk_run_test(struct fdisk_test *tests, int argc, char *argv[]);
64 #endif
65
66
67 typedef unsigned long long sector_t;
68
69
70 /*
71 * Generic iterator
72 */
73 struct fdisk_iter {
74 struct list_head *p; /* current position */
75 struct list_head *head; /* start position */
76 int direction; /* FDISK_ITER_{FOR,BACK}WARD */
77 };
78
79 #define IS_ITER_FORWARD(_i) ((_i)->direction == FDISK_ITER_FORWARD)
80 #define IS_ITER_BACKWARD(_i) ((_i)->direction == FDISK_ITER_BACKWARD)
81
82 #define FDISK_ITER_INIT(itr, list) \
83 do { \
84 (itr)->p = IS_ITER_FORWARD(itr) ? \
85 (list)->next : (list)->prev; \
86 (itr)->head = (list); \
87 } while(0)
88
89 #define FDISK_ITER_ITERATE(itr, res, restype, member) \
90 do { \
91 res = list_entry((itr)->p, restype, member); \
92 (itr)->p = IS_ITER_FORWARD(itr) ? \
93 (itr)->p->next : (itr)->p->prev; \
94 } while(0)
95
96 /*
97 * Partition types
98 */
99 struct fdisk_parttype {
100 unsigned int type; /* type as number or zero */
101 const char *name; /* description */
102 char *typestr; /* type as string or NULL */
103
104 unsigned int flags; /* FDISK_PARTTYPE_* flags */
105 };
106
107 enum {
108 FDISK_PARTTYPE_UNKNOWN = (1 << 1),
109 FDISK_PARTTYPE_INVISIBLE = (1 << 2),
110 FDISK_PARTTYPE_ALLOCATED = (1 << 3)
111 };
112
113 #define fdisk_parttype_is_unknown(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_UNKNONW))
114 #define fdisk_parttype_is_invisible(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE))
115 #define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED))
116
117 struct fdisk_partition {
118 int refcount; /* reference counter */
119 size_t partno; /* partition number */
120 size_t parent_partno; /* for logical partitions */
121
122 uint64_t start; /* first sectors */
123 uint64_t end; /* last sector */
124 uint64_t size; /* size in sectors */
125
126 char *name; /* partition name */
127 char *uuid; /* partition UUID */
128 char *attrs; /* partition flags/attributes converted to string */
129 struct fdisk_parttype *type; /* partition type */
130
131 struct list_head parts; /* list of partitions */
132
133 /* extra fields for partition_to_string() */
134 char start_post; /* start postfix (e.g. '+') */
135 char end_post; /* end postfix */
136 char size_post; /* size postfix */
137
138 uint64_t fsize; /* bsd junk */
139 uint64_t bsize;
140 uint64_t cpg;
141
142 char boot; /* is bootable (MBS only) */
143 char *start_addr; /* start C/H/S in string */
144 char *end_addr; /* end C/H/S in string */
145
146 unsigned int partno_follow_default : 1, /* use default partno */
147 start_follow_default : 1, /* use default start */
148 end_follow_default : 1, /* use default end */
149 freespace : 1, /* this is free space */
150 container : 1, /* container partition (e.g. extended partition) */
151 wholedisk : 1, /* special system partition */
152 used : 1; /* partition already used */
153 };
154
155 #define FDISK_EMPTY_PARTNO ((size_t) -1)
156 #define FDISK_EMPTY_PARTITION { .partno = FDISK_EMPTY_PARTNO }
157
158 struct fdisk_table {
159 struct list_head parts; /* partitions */
160 int refcount;
161 size_t nents; /* number of partitions */
162 };
163
164 /*
165 * Legacy CHS based geometry
166 */
167 struct fdisk_geometry {
168 unsigned int heads;
169 sector_t sectors;
170 sector_t cylinders;
171 };
172
173 /*
174 * Label specific operations
175 */
176 struct fdisk_label_operations {
177 /* probe disk label */
178 int (*probe)(struct fdisk_context *cxt);
179 /* write in-memory changes to disk */
180 int (*write)(struct fdisk_context *cxt);
181 /* verify the partition table */
182 int (*verify)(struct fdisk_context *cxt);
183 /* create new disk label */
184 int (*create)(struct fdisk_context *cxt);
185 /* list disklabel details */
186 int (*list)(struct fdisk_context *cxt);
187 /* returns offset and size of the 'n' part of the PT */
188 int (*locate)(struct fdisk_context *cxt, int n, const char **name, off_t *offset, size_t *size);
189 /* reorder partitions */
190 int (*reorder)(struct fdisk_context *cxt);
191
192 /* get disk label ID */
193 int (*get_id)(struct fdisk_context *cxt, char **id);
194 /* set disk label ID */
195 int (*set_id)(struct fdisk_context *cxt);
196
197 /* new partition */
198 int (*add_part)(struct fdisk_context *cxt, struct fdisk_partition *pa);
199
200 /* delete partition */
201 int (*part_delete)(struct fdisk_context *cxt,
202 size_t partnum);
203 /* get partition type */
204 struct fdisk_parttype *(*part_get_type)(struct fdisk_context *cxt,
205 size_t partnum);
206 /* set partition type */
207 int (*part_set_type)(struct fdisk_context *cxt,
208 size_t partnum,
209 struct fdisk_parttype *t);
210
211 /* return state of the partition */
212 int (*part_is_used)(struct fdisk_context *cxt, size_t partnum);
213
214 /* fill in partition struct */
215 int (*get_part)(struct fdisk_context *cxt,
216 size_t n,
217 struct fdisk_partition *pa);
218
219 int (*part_toggle_flag)(struct fdisk_context *cxt, size_t i, unsigned long flag);
220
221 /* refresh alignment setting */
222 int (*reset_alignment)(struct fdisk_context *cxt);
223
224 /* free in-memory label stuff */
225 void (*free)(struct fdisk_label *lb);
226
227 /* deinit in-memory label stuff */
228 void (*deinit)(struct fdisk_label *lb);
229 };
230
231 /*
232 * The fields describes how to display libfdisk_partition
233 */
234 struct fdisk_field {
235 int id; /* FDISK_FIELD_* */
236 const char *name; /* field name */
237 double width; /* field width (compatible with libsmartcols whint) */
238 int flags; /* FDISK_FIELDFL_* */
239 };
240
241 /* note that the defauls is to display a column always */
242 enum {
243 FDISK_FIELDFL_DETAIL = (1 << 1), /* only display if fdisk_context_display_details() */
244 FDISK_FIELDFL_EYECANDY = (1 << 2), /* don't display if fdisk_context_display_details() */
245 FDISK_FIELDFL_NUMBER = (1 << 3), /* column display numbers */
246 };
247
248 /*
249 * Generic label
250 */
251 struct fdisk_label {
252 const char *name; /* label name */
253 enum fdisk_labeltype id; /* FDISK_DISKLABEL_* */
254 struct fdisk_parttype *parttypes; /* supported partitions types */
255 size_t nparttypes; /* number of items in parttypes[] */
256
257 size_t nparts_max; /* maximal number of partitions */
258 size_t nparts_cur; /* number of currently used partitions */
259
260 int flags; /* FDISK_LABEL_FL_* flags */
261
262 unsigned int changed:1, /* label has been modified */
263 disabled:1; /* this driver is disabled at all */
264
265 const struct fdisk_field *fields; /* all possible fields */
266 size_t nfields;
267
268 const struct fdisk_label_operations *op;
269 };
270
271
272 /* label driver flags */
273 enum {
274 FDISK_LABEL_FL_REQUIRE_GEOMETRY = (1 << 2),
275 FDISK_LABEL_FL_INCHARS_PARTNO = (1 << 3)
276 };
277
278 /* label allocators */
279 extern struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt);
280 extern struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt);
281 extern struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt);
282 extern struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt);
283 extern struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt);
284
285
286 struct ask_menuitem {
287 char key;
288 const char *name;
289 const char *desc;
290
291 struct ask_menuitem *next;
292 };
293
294 /* fdisk dialog -- note that nothing from this stuff will be directly exported,
295 * we will have get/set() function for everything.
296 */
297 struct fdisk_ask {
298 int type; /* FDISK_ASKTYPE_* */
299 char *query;
300 unsigned int flags;
301
302 union {
303 /* FDISK_ASKTYPE_{NUMBER,OFFSET} */
304 struct ask_number {
305 uint64_t hig; /* high limit */
306 uint64_t low; /* low limit */
307 uint64_t dfl; /* default */
308 uint64_t result;
309 uint64_t base; /* for relative results */
310 uint64_t unit; /* unit for offsets */
311 const char *range; /* by library generated list */
312 unsigned int relative :1,
313 inchars :1;
314 } num;
315 /* FDISK_ASKTYPE_{WARN,WARNX,..} */
316 struct ask_print {
317 const char *mesg;
318 int errnum; /* errno */
319 } print;
320 /* FDISK_ASKTYPE_YESNO */
321 struct ask_yesno {
322 int result; /* TRUE or FALSE */
323 } yesno;
324 /* FDISK_ASKTYPE_STRING */
325 struct ask_string {
326 char *result; /* allocated */
327 } str;
328 /* FDISK_ASKTYPE_MENU */
329 struct ask_menu {
330 int dfl; /* default meni item */
331 int result;
332 struct ask_menuitem *first;
333 } menu;
334 } data;
335 };
336
337 struct fdisk_context {
338 int dev_fd; /* device descriptor */
339 char *dev_path; /* device path */
340
341 unsigned char *firstsector; /* buffer with master boot record */
342 unsigned long firstsector_bufsz;
343
344 /* topology */
345 unsigned long io_size; /* I/O size used by fdisk */
346 unsigned long optimal_io_size; /* optional I/O returned by device */
347 unsigned long min_io_size; /* minimal I/O size */
348 unsigned long phy_sector_size; /* physical size */
349 unsigned long sector_size; /* logical size */
350 unsigned long alignment_offset;
351
352 unsigned int readonly : 1, /* don't write to the device */
353 display_in_cyl_units : 1, /* for obscure labels */
354 display_details : 1, /* expert display mode */
355 listonly : 1; /* list partition, nothing else */
356
357 /* alignment */
358 unsigned long grain; /* alignment unit */
359 sector_t first_lba; /* recommended begin of the first partition */
360 sector_t last_lba; /* recomennded end of last partition */
361
362 /* geometry */
363 sector_t total_sectors; /* in logical sectors */
364 struct fdisk_geometry geom;
365
366 /* user setting to overwrite device default */
367 struct fdisk_geometry user_geom;
368 unsigned long user_pyh_sector;
369 unsigned long user_log_sector;
370
371 struct fdisk_label *label; /* current label, pointer to labels[] */
372
373 size_t nlabels; /* number of initialized label drivers */
374 struct fdisk_label *labels[8]; /* all supported labels,
375 * FIXME: use any enum rather than hardcoded number */
376
377 int (*ask_cb)(struct fdisk_context *, struct fdisk_ask *, void *); /* fdisk dialogs callback */
378 void *ask_data; /* ask_cb() data */
379
380 struct fdisk_context *parent; /* for nested PT */
381 };
382
383 /* context.c */
384 extern int __fdisk_context_switch_label(struct fdisk_context *cxt,
385 struct fdisk_label *lb);
386
387 extern int fdisk_context_enable_listonly(struct fdisk_context *cxt, int enable);
388 extern int fdisk_context_listonly(struct fdisk_context *cxt);
389
390
391 /* alignment.c */
392 extern sector_t fdisk_scround(struct fdisk_context *cxt, sector_t num);
393 extern sector_t fdisk_cround(struct fdisk_context *cxt, sector_t num);
394
395 extern sector_t fdisk_topology_get_first_lba(struct fdisk_context *cxt);
396 extern unsigned long fdisk_topology_get_grain(struct fdisk_context *cxt);
397
398 extern void fdisk_warn_alignment(struct fdisk_context *cxt,
399 sector_t lba, int partition);
400
401
402 #define FDISK_ALIGN_UP 1
403 #define FDISK_ALIGN_DOWN 2
404 #define FDISK_ALIGN_NEAREST 3
405
406 extern sector_t fdisk_align_lba(struct fdisk_context *cxt, sector_t lba, int direction);
407 extern sector_t fdisk_align_lba_in_range(struct fdisk_context *cxt, sector_t lba,
408 sector_t start, sector_t stop);
409
410
411 extern int fdisk_override_geometry(struct fdisk_context *cxt,
412 unsigned int cylinders, unsigned int heads,
413 unsigned int sectors);
414
415 extern int fdisk_discover_geometry(struct fdisk_context *cxt);
416 extern int fdisk_discover_topology(struct fdisk_context *cxt);
417
418 extern int fdisk_apply_user_device_properties(struct fdisk_context *cxt);
419 extern void fdisk_zeroize_device_properties(struct fdisk_context *cxt);
420
421 /* utils.c */
422 extern int fdisk_init_firstsector_buffer(struct fdisk_context *cxt);
423 extern int fdisk_read_firstsector(struct fdisk_context *cxt);
424 extern char *fdisk_partname(const char *dev, size_t partno);
425
426 /* label.c */
427 extern int fdisk_probe_labels(struct fdisk_context *cxt);
428 extern void fdisk_deinit_label(struct fdisk_label *lb);
429
430 /* ask.c */
431 extern int fdisk_ask_partnum(struct fdisk_context *cxt, size_t *partnum, int wantnew);
432
433 extern int fdisk_info_new_partition(
434 struct fdisk_context *cxt,
435 int num, sector_t start, sector_t stop,
436 struct fdisk_parttype *t);
437
438 #endif /* _LIBFDISK_PRIVATE_H */