blob: b169a9ffb2a12035910bf9f96d1971567d34c219 [file] [log] [blame]
bigbiff7b4c7a62015-01-01 19:44:14 -05001/*
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 LIBFDISK_DEBUG_HELP (1 << 0)
41#define LIBFDISK_DEBUG_INIT (1 << 1)
42#define LIBFDISK_DEBUG_CXT (1 << 2)
43#define LIBFDISK_DEBUG_LABEL (1 << 3)
44#define LIBFDISK_DEBUG_ASK (1 << 4)
45#define LIBFDISK_DEBUG_PART (1 << 6)
46#define LIBFDISK_DEBUG_PARTTYPE (1 << 7)
47#define LIBFDISK_DEBUG_TAB (1 << 8)
48#define LIBFDISK_DEBUG_SCRIPT (1 << 9)
49#define LIBFDISK_DEBUG_ALL 0xFFFF
50
51UL_DEBUG_DECLARE_MASK(libfdisk);
52#define DBG(m, x) __UL_DBG(libfdisk, LIBFDISK_DEBUG_, m, x)
53#define ON_DBG(m, x) __UL_DBG_CALL(libfdisk, LIBFDISK_DEBUG_, m, x)
54#define DBG_FLUSH __UL_DBG_FLUSH(libfdisk, LIBFDISK_DEBUG_)
55
56#ifdef TEST_PROGRAM
57struct fdisk_test {
58 const char *name;
59 int (*body)(struct fdisk_test *ts, int argc, char *argv[]);
60 const char *usage;
61};
62
63/* test.c */
64extern int fdisk_run_test(struct fdisk_test *tests, int argc, char *argv[]);
65#endif
66
67
68/*
69 * Generic iterator
70 */
71struct fdisk_iter {
72 struct list_head *p; /* current position */
73 struct list_head *head; /* start position */
74 int direction; /* FDISK_ITER_{FOR,BACK}WARD */
75};
76
77#define IS_ITER_FORWARD(_i) ((_i)->direction == FDISK_ITER_FORWARD)
78#define IS_ITER_BACKWARD(_i) ((_i)->direction == FDISK_ITER_BACKWARD)
79
80#define FDISK_ITER_INIT(itr, list) \
81 do { \
82 (itr)->p = IS_ITER_FORWARD(itr) ? \
83 (list)->next : (list)->prev; \
84 (itr)->head = (list); \
85 } while(0)
86
87#define FDISK_ITER_ITERATE(itr, res, restype, member) \
88 do { \
89 res = list_entry((itr)->p, restype, member); \
90 (itr)->p = IS_ITER_FORWARD(itr) ? \
91 (itr)->p->next : (itr)->p->prev; \
92 } while(0)
93
94/*
95 * Partition types
96 */
97struct fdisk_parttype {
98 unsigned int code; /* type as number or zero */
99 char *name; /* description */
100 char *typestr; /* type as string or NULL */
101
102 unsigned int flags; /* FDISK_PARTTYPE_* flags */
103 int refcount; /* reference counter for allocated types */
104};
105
106enum {
107 FDISK_PARTTYPE_UNKNOWN = (1 << 1),
108 FDISK_PARTTYPE_INVISIBLE = (1 << 2),
109 FDISK_PARTTYPE_ALLOCATED = (1 << 3)
110};
111
112#define fdisk_parttype_is_invisible(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE))
113#define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED))
114
115struct fdisk_partition {
116 int refcount; /* reference counter */
117
118 size_t partno; /* partition number */
119 size_t parent_partno; /* for logical partitions */
120
121 fdisk_sector_t start; /* first sectors */
122 fdisk_sector_t size; /* size in sectors */
123
124 char *name; /* partition name */
125 char *uuid; /* partition UUID */
126 char *attrs; /* partition flags/attributes converted to string */
127 struct fdisk_parttype *type; /* partition type */
128
129 struct list_head parts; /* list of partitions */
130
131 /* extra fields for partition_to_string() */
132 char start_post; /* start postfix (e.g. '+') */
133 char end_post; /* end postfix */
134 char size_post; /* size postfix */
135
136 uint64_t fsize; /* bsd junk */
137 uint64_t bsize;
138 uint64_t cpg;
139
140 char *start_chs; /* start C/H/S in string */
141 char *end_chs; /* end C/H/S in string */
142
143 unsigned int boot; /* MBR: bootable */
144
145 unsigned int container : 1, /* container partition (e.g. extended partition) */
146 end_follow_default : 1, /* use default end */
147 freespace : 1, /* this is free space */
148 partno_follow_default : 1, /* use default partno */
149 size_explicit : 1, /* don't align the size */
150 start_follow_default : 1, /* use default start */
151 used : 1, /* partition already used */
152 wholedisk : 1; /* special system partition */
153};
154
155#define FDISK_INIT_UNDEF(_x) ((_x) = (__typeof__(_x)) -1)
156#define FDISK_IS_UNDEF(_x) ((_x) == (__typeof__(_x)) -1)
157
158struct 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 */
167struct fdisk_geometry {
168 unsigned int heads;
169 fdisk_sector_t sectors;
170 fdisk_sector_t cylinders;
171};
172
173/*
174 * Label specific operations
175 */
176struct 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
198 /* new partition */
199 int (*add_part)(struct fdisk_context *cxt, struct fdisk_partition *pa,
200 size_t *partno);
201 /* delete partition */
202 int (*del_part)(struct fdisk_context *cxt, size_t partnum);
203
204 /* fill in partition struct */
205 int (*get_part)(struct fdisk_context *cxt, size_t n,
206 struct fdisk_partition *pa);
207 /* modify partition */
208 int (*set_part)(struct fdisk_context *cxt, size_t n,
209 struct fdisk_partition *pa);
210
211 /* return state of the partition */
212 int (*part_is_used)(struct fdisk_context *cxt, size_t partnum);
213
214 int (*part_toggle_flag)(struct fdisk_context *cxt, size_t i, unsigned long flag);
215
216 /* refresh alignment setting */
217 int (*reset_alignment)(struct fdisk_context *cxt);
218
219 /* free in-memory label stuff */
220 void (*free)(struct fdisk_label *lb);
221
222 /* deinit in-memory label stuff */
223 void (*deinit)(struct fdisk_label *lb);
224};
225
226/*
227 * The fields describes how to display libfdisk_partition
228 */
229struct fdisk_field {
230 int id; /* FDISK_FIELD_* */
231 const char *name; /* field name */
232 double width; /* field width (compatible with libsmartcols whint) */
233 int flags; /* FDISK_FIELDFL_* */
234};
235
236/* note that the defauls is to display a column always */
237enum {
238 FDISK_FIELDFL_DETAIL = (1 << 1), /* only display if fdisk_is_details() */
239 FDISK_FIELDFL_EYECANDY = (1 << 2), /* don't display if fdisk_is_details() */
240 FDISK_FIELDFL_NUMBER = (1 << 3), /* column display numbers */
241};
242
243/*
244 * Generic label
245 */
246struct fdisk_label {
247 const char *name; /* label name */
248 enum fdisk_labeltype id; /* FDISK_DISKLABEL_* */
249 struct fdisk_parttype *parttypes; /* supported partitions types */
250 size_t nparttypes; /* number of items in parttypes[] */
251
252 size_t nparts_max; /* maximal number of partitions */
253 size_t nparts_cur; /* number of currently used partitions */
254
255 int flags; /* FDISK_LABEL_FL_* flags */
256
257 unsigned int changed:1, /* label has been modified */
258 disabled:1; /* this driver is disabled at all */
259
260 const struct fdisk_field *fields; /* all possible fields */
261 size_t nfields;
262
263 const struct fdisk_label_operations *op;
264};
265
266
267/* label driver flags */
268enum {
269 FDISK_LABEL_FL_REQUIRE_GEOMETRY = (1 << 2),
270 FDISK_LABEL_FL_INCHARS_PARTNO = (1 << 3)
271};
272
273/* label allocators */
274extern struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt);
275extern struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt);
276extern struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt);
277extern struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt);
278extern struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt);
279
280
281struct ask_menuitem {
282 char key;
283 const char *name;
284 const char *desc;
285
286 struct ask_menuitem *next;
287};
288
289/* fdisk dialog -- note that nothing from this stuff will be directly exported,
290 * we will have get/set() function for everything.
291 */
292struct fdisk_ask {
293 int type; /* FDISK_ASKTYPE_* */
294 char *query;
295
296 int refcount;
297
298 union {
299 /* FDISK_ASKTYPE_{NUMBER,OFFSET} */
300 struct ask_number {
301 uint64_t hig; /* high limit */
302 uint64_t low; /* low limit */
303 uint64_t dfl; /* default */
304 uint64_t result;
305 uint64_t base; /* for relative results */
306 uint64_t unit; /* unit for offsets */
307 const char *range; /* by library generated list */
308 unsigned int relative :1,
309 inchars :1;
310 } num;
311 /* FDISK_ASKTYPE_{WARN,WARNX,..} */
312 struct ask_print {
313 const char *mesg;
314 int errnum; /* errno */
315 } print;
316 /* FDISK_ASKTYPE_YESNO */
317 struct ask_yesno {
318 int result; /* TRUE or FALSE */
319 } yesno;
320 /* FDISK_ASKTYPE_STRING */
321 struct ask_string {
322 char *result; /* allocated */
323 } str;
324 /* FDISK_ASKTYPE_MENU */
325 struct ask_menu {
326 int dfl; /* default meni item */
327 int result;
328 struct ask_menuitem *first;
329 } menu;
330 } data;
331};
332
333struct fdisk_context {
334 int dev_fd; /* device descriptor */
335 char *dev_path; /* device path */
336 int refcount;
337
338 unsigned char *firstsector; /* buffer with master boot record */
339 unsigned long firstsector_bufsz;
340
341 /* topology */
342 unsigned long io_size; /* I/O size used by fdisk */
343 unsigned long optimal_io_size; /* optional I/O returned by device */
344 unsigned long min_io_size; /* minimal I/O size */
345 unsigned long phy_sector_size; /* physical size */
346 unsigned long sector_size; /* logical size */
347 unsigned long alignment_offset;
348
349 unsigned int readonly : 1, /* don't write to the device */
350 display_in_cyl_units : 1, /* for obscure labels */
351 display_details : 1, /* expert display mode */
352 listonly : 1; /* list partition, nothing else */
353
354 /* alignment */
355 unsigned long grain; /* alignment unit */
356 fdisk_sector_t first_lba; /* recommended begin of the first partition */
357 fdisk_sector_t last_lba; /* recomennded end of last partition */
358
359 /* geometry */
360 fdisk_sector_t total_sectors; /* in logical sectors */
361 struct fdisk_geometry geom;
362
363 /* user setting to overwrite device default */
364 struct fdisk_geometry user_geom;
365 unsigned long user_pyh_sector;
366 unsigned long user_log_sector;
367
368 struct fdisk_label *label; /* current label, pointer to labels[] */
369
370 size_t nlabels; /* number of initialized label drivers */
371 struct fdisk_label *labels[8]; /* all supported labels,
372 * FIXME: use any enum rather than hardcoded number */
373
374 int (*ask_cb)(struct fdisk_context *, struct fdisk_ask *, void *); /* fdisk dialogs callback */
375 void *ask_data; /* ask_cb() data */
376
377 struct fdisk_context *parent; /* for nested PT */
378 struct fdisk_script *script; /* what we want to follow */
379};
380
381/* partition.c */
382int fdisk_partition_next_partno(struct fdisk_partition *pa,
383 struct fdisk_context *cxt,
384 size_t *n);
385
386/* context.c */
387extern int __fdisk_switch_label(struct fdisk_context *cxt,
388 struct fdisk_label *lb);
389extern int fdisk_missing_geometry(struct fdisk_context *cxt);
390
391/* alignment.c */
392fdisk_sector_t fdisk_scround(struct fdisk_context *cxt, fdisk_sector_t num);
393fdisk_sector_t fdisk_cround(struct fdisk_context *cxt, fdisk_sector_t num);
394
395extern int fdisk_discover_geometry(struct fdisk_context *cxt);
396extern int fdisk_discover_topology(struct fdisk_context *cxt);
397
398extern int fdisk_apply_user_device_properties(struct fdisk_context *cxt);
399extern void fdisk_zeroize_device_properties(struct fdisk_context *cxt);
400
401/* utils.c */
402extern int fdisk_init_firstsector_buffer(struct fdisk_context *cxt);
403extern int fdisk_read_firstsector(struct fdisk_context *cxt);
404extern char *fdisk_partname(const char *dev, size_t partno);
405
406/* label.c */
407extern int fdisk_probe_labels(struct fdisk_context *cxt);
408extern void fdisk_deinit_label(struct fdisk_label *lb);
409
410/* ask.c */
411struct fdisk_ask *fdisk_new_ask(void);
412void fdisk_reset_ask(struct fdisk_ask *ask);
413int fdisk_ask_set_query(struct fdisk_ask *ask, const char *str);
414int fdisk_ask_set_type(struct fdisk_ask *ask, int type);
415int fdisk_do_ask(struct fdisk_context *cxt, struct fdisk_ask *ask);
416int fdisk_ask_number_set_range(struct fdisk_ask *ask, const char *range);
417int fdisk_ask_number_set_default(struct fdisk_ask *ask, uint64_t dflt);
418int fdisk_ask_number_set_low(struct fdisk_ask *ask, uint64_t low);
419int fdisk_ask_number_set_high(struct fdisk_ask *ask, uint64_t high);
420int fdisk_ask_number_set_base(struct fdisk_ask *ask, uint64_t base);
421int fdisk_ask_number_set_unit(struct fdisk_ask *ask, uint64_t unit);
422int fdisk_ask_number_is_relative(struct fdisk_ask *ask);
423int fdisk_ask_menu_set_default(struct fdisk_ask *ask, int dfl);
424int fdisk_ask_menu_add_item(struct fdisk_ask *ask, int key,
425 const char *name, const char *desc);
426int fdisk_ask_print_set_errno(struct fdisk_ask *ask, int errnum);
427int fdisk_ask_print_set_mesg(struct fdisk_ask *ask, const char *mesg);
428int fdisk_info_new_partition(
429 struct fdisk_context *cxt,
430 int num, fdisk_sector_t start, fdisk_sector_t stop,
431 struct fdisk_parttype *t);
432
433/* dos.c */
434extern struct dos_partition *fdisk_dos_get_partition(
435 struct fdisk_context *cxt,
436 size_t i);
437
438#endif /* _LIBFDISK_PRIVATE_H */