(root)/
util-linux-2.39/
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  #include <uuid.h>
      20  
      21  #include "c.h"
      22  #include "libfdisk.h"
      23  
      24  #include "list.h"
      25  #include "debug.h"
      26  #include <stdio.h>
      27  #include <stdarg.h>
      28  
      29  /*
      30   * Debug
      31   */
      32  #define LIBFDISK_DEBUG_HELP	(1 << 0)
      33  #define LIBFDISK_DEBUG_INIT	(1 << 1)
      34  #define LIBFDISK_DEBUG_CXT	(1 << 2)
      35  #define LIBFDISK_DEBUG_LABEL    (1 << 3)
      36  #define LIBFDISK_DEBUG_ASK      (1 << 4)
      37  #define LIBFDISK_DEBUG_PART	(1 << 6)
      38  #define LIBFDISK_DEBUG_PARTTYPE	(1 << 7)
      39  #define LIBFDISK_DEBUG_TAB	(1 << 8)
      40  #define LIBFDISK_DEBUG_SCRIPT	(1 << 9)
      41  #define LIBFDISK_DEBUG_WIPE	(1 << 10)
      42  #define LIBFDISK_DEBUG_ITEM	(1 << 11)
      43  #define LIBFDISK_DEBUG_GPT	(1 << 12)
      44  #define LIBFDISK_DEBUG_ALL	0xFFFF
      45  
      46  UL_DEBUG_DECLARE_MASK(libfdisk);
      47  #define DBG(m, x)	__UL_DBG(libfdisk, LIBFDISK_DEBUG_, m, x)
      48  #define ON_DBG(m, x)	__UL_DBG_CALL(libfdisk, LIBFDISK_DEBUG_, m, x)
      49  #define DBG_FLUSH	__UL_DBG_FLUSH(libfdisk, LIBFDISK_DEBUG_)
      50  
      51  #define UL_DEBUG_CURRENT_MASK	UL_DEBUG_MASK(libfdisk)
      52  #include "debugobj.h"
      53  
      54  /*
      55   * NLS -- the library has to be independent on main program, so define
      56   * UL_TEXTDOMAIN_EXPLICIT before you include nls.h.
      57   *
      58   * Now we use util-linux.po (=PACKAGE), rather than maintain the texts
      59   * in the separate libfdisk.po file.
      60   */
      61  #define LIBFDISK_TEXTDOMAIN	PACKAGE
      62  #define UL_TEXTDOMAIN_EXPLICIT	LIBFDISK_TEXTDOMAIN
      63  #include "nls.h"
      64  
      65  
      66  #ifdef TEST_PROGRAM
      67  struct fdisk_test {
      68  	const char	*name;
      69  	int		(*body)(struct fdisk_test *ts, int argc, char *argv[]);
      70  	const char	*usage;
      71  };
      72  
      73  /* test.c */
      74  extern int fdisk_run_test(struct fdisk_test *tests, int argc, char *argv[]);
      75  #endif
      76  
      77  #define FDISK_GPT_NPARTITIONS_DEFAULT	128
      78  
      79  /*
      80   * Generic iterator
      81   */
      82  struct fdisk_iter {
      83          struct list_head        *p;		/* current position */
      84          struct list_head        *head;		/* start position */
      85  	int			direction;	/* FDISK_ITER_{FOR,BACK}WARD */
      86  };
      87  
      88  #define IS_ITER_FORWARD(_i)	((_i)->direction == FDISK_ITER_FORWARD)
      89  #define IS_ITER_BACKWARD(_i)	((_i)->direction == FDISK_ITER_BACKWARD)
      90  
      91  #define FDISK_ITER_INIT(itr, list) \
      92  	do { \
      93  		(itr)->p = IS_ITER_FORWARD(itr) ? \
      94  				(list)->next : (list)->prev; \
      95  		(itr)->head = (list); \
      96  	} while(0)
      97  
      98  #define FDISK_ITER_ITERATE(itr, res, restype, member) \
      99  	do { \
     100  		res = list_entry((itr)->p, restype, member); \
     101  		(itr)->p = IS_ITER_FORWARD(itr) ? \
     102  				(itr)->p->next : (itr)->p->prev; \
     103  	} while(0)
     104  
     105  /*
     106   * Partition types
     107   */
     108  struct fdisk_parttype {
     109  	unsigned int	code;		/* type as number or zero */
     110  	char		*name;		/* description */
     111  	char		*typestr;	/* type as string or NULL */
     112  
     113  	unsigned int	flags;		/* FDISK_PARTTYPE_* flags */
     114  	int		refcount;	/* reference counter for allocated types */
     115  };
     116  
     117  enum {
     118  	FDISK_PARTTYPE_UNKNOWN		= (1 << 1),
     119  	FDISK_PARTTYPE_INVISIBLE	= (1 << 2),
     120  	FDISK_PARTTYPE_ALLOCATED	= (1 << 3)
     121  };
     122  
     123  #define fdisk_parttype_is_invisible(_x)	((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE))
     124  #define fdisk_parttype_is_allocated(_x)	((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED))
     125  
     126  /*
     127   * Shortcut (used for partition types)
     128   */
     129  struct fdisk_shortcut {
     130  	const char	*shortcut;	/* shortcut, usually one letter (e.h. "H") */
     131  	const char	*alias;		/* human readable alias (e.g. "home") */
     132  	const char	*data;		/* for example partition type */
     133  
     134  	unsigned int    deprecated : 1;
     135  };
     136  
     137  struct fdisk_partition {
     138  	int		refcount;		/* reference counter */
     139  
     140  	size_t		partno;			/* partition number */
     141  	size_t		parent_partno;		/* for logical partitions */
     142  
     143  	fdisk_sector_t	start;			/* first sectors */
     144  	fdisk_sector_t	size;			/* size in sectors */
     145  
     146  	int		movestart;		/* FDISK_MOVE_* (scripts only) */
     147  	int		resize;			/* FDISK_RESIZE_* (scripts only) */
     148  
     149  	char		*name;			/* partition name */
     150  	char		*uuid;			/* partition UUID */
     151  	char		*attrs;			/* partition flags/attributes converted to string */
     152  	struct fdisk_parttype	*type;		/* partition type */
     153  
     154  	char		*fstype;		/* filesystem type */
     155  	char		*fsuuid;		/* filesystem uuid  */
     156  	char		*fslabel;		/* filesystem label */
     157  
     158  	struct list_head	parts;		/* list of partitions */
     159  
     160  	/* extra fields for partition_to_string() */
     161  	char		start_post;		/* start postfix  (e.g. '+') */
     162  	char		end_post;		/* end postfix */
     163  	char		size_post;		/* size postfix */
     164  
     165  	uint64_t	fsize;			/* bsd junk */
     166  	uint64_t	bsize;
     167  	uint64_t	cpg;
     168  
     169  	char		*start_chs;		/* start C/H/S in string */
     170  	char		*end_chs;		/* end C/H/S in string */
     171  
     172  	unsigned int	boot;			/* MBR: bootable */
     173  
     174  	unsigned int	container : 1,			/* container partition (e.g. extended partition) */
     175  			end_follow_default : 1,		/* use default end */
     176  			freespace : 1,			/* this is free space */
     177  			partno_follow_default : 1,	/* use default partno */
     178  			size_explicit : 1,		/* don't align the size */
     179  			start_follow_default : 1,	/* use default start */
     180  			fs_probed : 1,			/* already probed by blkid */
     181  			used : 1,			/* partition already used */
     182  			wholedisk : 1;			/* special system partition */
     183  };
     184  
     185  enum {
     186  	FDISK_MOVE_NONE = 0,
     187  	FDISK_MOVE_DOWN = -1,
     188  	FDISK_MOVE_UP = 1
     189  };
     190  
     191  enum {
     192  	FDISK_RESIZE_NONE = 0,
     193  	FDISK_RESIZE_REDUCE = -1,
     194  	FDISK_RESIZE_ENLARGE = 1
     195  };
     196  
     197  #define FDISK_INIT_UNDEF(_x)	((_x) = (__typeof__(_x)) -1)
     198  #define FDISK_IS_UNDEF(_x)	((_x) == (__typeof__(_x)) -1)
     199  
     200  struct fdisk_table {
     201  	struct list_head	parts;		/* partitions */
     202  	int			refcount;
     203  	size_t			nents;		/* number of partitions */
     204  };
     205  
     206  /*
     207   * Legacy CHS based geometry
     208   */
     209  struct fdisk_geometry {
     210  	unsigned int heads;
     211  	fdisk_sector_t sectors;
     212  	fdisk_sector_t cylinders;
     213  };
     214  
     215  /*
     216   * Label specific operations
     217   */
     218  struct fdisk_label_operations {
     219  	/* probe disk label */
     220  	int (*probe)(struct fdisk_context *cxt);
     221  	/* write in-memory changes to disk */
     222  	int (*write)(struct fdisk_context *cxt);
     223  	/* verify the partition table */
     224  	int (*verify)(struct fdisk_context *cxt);
     225  	/* create new disk label */
     226  	int (*create)(struct fdisk_context *cxt);
     227  	/* returns offset and size of the 'n' part of the PT */
     228  	int (*locate)(struct fdisk_context *cxt, int n, const char **name,
     229  		      uint64_t *offset, size_t *size);
     230  	/* reorder partitions */
     231  	int (*reorder)(struct fdisk_context *cxt);
     232  	/* get details from label */
     233  	int (*get_item)(struct fdisk_context *cxt, struct fdisk_labelitem *item);
     234  	/* set disk label ID */
     235  	int (*set_id)(struct fdisk_context *cxt, const char *str);
     236  
     237  
     238  	/* new partition */
     239  	int (*add_part)(struct fdisk_context *cxt, struct fdisk_partition *pa,
     240  						size_t *partno);
     241  	/* delete partition */
     242  	int (*del_part)(struct fdisk_context *cxt, size_t partnum);
     243  
     244  	/* fill in partition struct */
     245  	int (*get_part)(struct fdisk_context *cxt, size_t n,
     246  						struct fdisk_partition *pa);
     247  	/* modify partition */
     248  	int (*set_part)(struct fdisk_context *cxt, size_t n,
     249  						struct fdisk_partition *pa);
     250  
     251  	/* return state of the partition */
     252  	int (*part_is_used)(struct fdisk_context *cxt, size_t partnum);
     253  
     254  	int (*part_toggle_flag)(struct fdisk_context *cxt, size_t i, unsigned long flag);
     255  
     256  	/* refresh alignment setting */
     257  	int (*reset_alignment)(struct fdisk_context *cxt);
     258  
     259  	/* free in-memory label stuff */
     260  	void (*free)(struct fdisk_label *lb);
     261  
     262  	/* deinit in-memory label stuff */
     263  	void (*deinit)(struct fdisk_label *lb);
     264  };
     265  
     266  /*
     267   * The fields describes how to display libfdisk_partition
     268   */
     269  struct fdisk_field {
     270  	int		id;		/* FDISK_FIELD_* */
     271  	const char	*name;		/* field name */
     272  	double		width;		/* field width (compatible with libsmartcols whint) */
     273  	int		flags;		/* FDISK_FIELDFL_* */
     274  };
     275  
     276  /* note that the defaults is to display a column always */
     277  enum {
     278  	FDISK_FIELDFL_DETAIL	= (1 << 1),	/* only display if fdisk_is_details() */
     279  	FDISK_FIELDFL_EYECANDY	= (1 << 2),	/* don't display if fdisk_is_details() */
     280  	FDISK_FIELDFL_NUMBER	= (1 << 3),	/* column display numbers */
     281  };
     282  
     283  /*
     284   * Generic label
     285   */
     286  struct fdisk_label {
     287  	const char		*name;		/* label name */
     288  	enum fdisk_labeltype	id;		/* FDISK_DISKLABEL_* */
     289  	struct fdisk_parttype	*parttypes;	/* supported partitions types */
     290  	size_t			nparttypes;	/* number of items in parttypes[] */
     291  
     292  	const struct fdisk_shortcut *parttype_cuts;	/* partition type shortcuts */
     293  	size_t			nparttype_cuts;	/* number of items in parttype_cuts */
     294  
     295  	size_t			nparts_max;	/* maximal number of partitions */
     296  	size_t			nparts_cur;	/* number of currently used partitions */
     297  
     298  	int			flags;		/* FDISK_LABEL_FL_* flags */
     299  
     300  	struct fdisk_geometry	geom_min;	/* minimal geometry */
     301  	struct fdisk_geometry	geom_max;	/* maximal geometry */
     302  
     303  	unsigned int		changed:1,	/* label has been modified */
     304  				disabled:1;	/* this driver is disabled at all */
     305  
     306  	const struct fdisk_field *fields;	/* all possible fields */
     307  	size_t			nfields;
     308  
     309  	const struct fdisk_label_operations *op;
     310  };
     311  
     312  
     313  /* label driver flags */
     314  enum {
     315  	FDISK_LABEL_FL_REQUIRE_GEOMETRY = (1 << 2),
     316  	FDISK_LABEL_FL_INCHARS_PARTNO   = (1 << 3)
     317  };
     318  
     319  /* label allocators */
     320  extern struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt);
     321  extern struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt);
     322  extern struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt);
     323  extern struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt);
     324  extern struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt);
     325  
     326  
     327  struct ask_menuitem {
     328  	char	key;
     329  	const char	*name;
     330  	const char	*desc;
     331  
     332  	struct ask_menuitem *next;
     333  };
     334  
     335  /* fdisk dialog -- note that nothing from this stuff will be directly exported,
     336   * we will have get/set() function for everything.
     337   */
     338  struct fdisk_ask {
     339  	int		type;		/* FDISK_ASKTYPE_* */
     340  	char		*query;
     341  
     342  	int		refcount;
     343  
     344  	union {
     345  		/* FDISK_ASKTYPE_{NUMBER,OFFSET} */
     346  		struct ask_number {
     347  			uint64_t	hig;		/* high limit */
     348  			uint64_t	low;		/* low limit */
     349  			uint64_t	dfl;		/* default */
     350  			uint64_t	result;
     351  			uint64_t	base;		/* for relative results */
     352  			uint64_t	unit;		/* unit for offsets */
     353  			const char	*range;		/* by library generated list */
     354  			unsigned int	relative :1,
     355  					inchars  :1,
     356  					wrap_negative	:1;
     357  		} num;
     358  		/* FDISK_ASKTYPE_{WARN,WARNX,..} */
     359  		struct ask_print {
     360  			const char	*mesg;
     361  			int		errnum;		/* errno */
     362  		} print;
     363  		/* FDISK_ASKTYPE_YESNO */
     364  		struct ask_yesno {
     365  			int		result;		/* TRUE or FALSE */
     366  		} yesno;
     367  		/* FDISK_ASKTYPE_STRING */
     368  		struct ask_string {
     369  			char		*result;	/* allocated */
     370  		} str;
     371  		/* FDISK_ASKTYPE_MENU */
     372  		struct ask_menu {
     373  			int		dfl;		/* default menu item */
     374  			int		result;
     375  			struct ask_menuitem *first;
     376  		} menu;
     377  	} data;
     378  };
     379  
     380  struct fdisk_context {
     381  	int dev_fd;         /* device descriptor */
     382  	char *dev_path;     /* device path */
     383  	char *dev_model;    /* on linux /sys/block/<name>/device/model or NULL */
     384  	struct stat dev_st; /* stat(2) result */
     385  
     386  	int refcount;
     387  
     388  	unsigned char *firstsector; /* buffer with master boot record */
     389  	unsigned long firstsector_bufsz;
     390  
     391  
     392  	/* topology */
     393  	unsigned long io_size;		/* I/O size used by fdisk */
     394  	unsigned long optimal_io_size;	/* optional I/O returned by device */
     395  	unsigned long min_io_size;	/* minimal I/O size */
     396  	unsigned long phy_sector_size;	/* physical size */
     397  	unsigned long sector_size;	/* logical size */
     398  	unsigned long alignment_offset;
     399  
     400  	unsigned int readonly : 1,		/* don't write to the device */
     401  		     display_in_cyl_units : 1,	/* for obscure labels */
     402  		     display_details : 1,	/* expert display mode */
     403  		     protect_bootbits : 1,	/* don't zeroize first sector */
     404  		     pt_collision : 1,		/* another PT detected by libblkid */
     405  		     no_disalogs : 1,		/* disable dialog-driven partititoning */
     406  		     dev_model_probed : 1,	/* tried to read from sys */
     407  		     is_priv : 1,		/* open by libfdisk */
     408  		     is_excl : 1,		/* open with O_EXCL */
     409  		     listonly : 1;		/* list partition, nothing else */
     410  
     411  	char *collision;			/* name of already existing FS/PT */
     412  	struct list_head wipes;			/* list of areas to wipe before write */
     413  
     414  	int sizeunit;				/* SIZE fields, FDISK_SIZEUNIT_* */
     415  
     416  	/* alignment */
     417  	unsigned long grain;		/* alignment unit */
     418  	fdisk_sector_t first_lba;		/* recommended begin of the first partition */
     419  	fdisk_sector_t last_lba;		/* recommended end of last partition */
     420  
     421  	/* geometry */
     422  	fdisk_sector_t total_sectors;	/* in logical sectors */
     423  	struct fdisk_geometry geom;
     424  
     425  	/* user setting to overwrite device default */
     426  	struct fdisk_geometry user_geom;
     427  	unsigned long user_pyh_sector;
     428  	unsigned long user_log_sector;
     429  	unsigned long user_grain;
     430  
     431  	struct fdisk_label *label;	/* current label, pointer to labels[] */
     432  
     433  	size_t nlabels;			/* number of initialized label drivers */
     434  	struct fdisk_label *labels[8];	/* all supported labels,
     435  					 * FIXME: use any enum rather than hardcoded number */
     436  
     437  	int	(*ask_cb)(struct fdisk_context *, struct fdisk_ask *, void *);	/* fdisk dialogs callback */
     438  	void	*ask_data;		/* ask_cb() data */
     439  
     440  	struct fdisk_context	*parent;	/* for nested PT */
     441  	struct fdisk_script	*script;	/* what we want to follow */
     442  };
     443  
     444  /* table */
     445  enum {
     446  	FDISK_DIFF_UNCHANGED = 0,
     447  	FDISK_DIFF_REMOVED,
     448  	FDISK_DIFF_ADDED,
     449  	FDISK_DIFF_MOVED,
     450  	FDISK_DIFF_RESIZED
     451  };
     452  extern int fdisk_diff_tables(struct fdisk_table *a, struct fdisk_table *b,
     453  				struct fdisk_iter *itr,
     454  				struct fdisk_partition **res, int *change);
     455  extern void fdisk_debug_print_table(struct fdisk_table *tb);
     456  
     457  
     458  /* context.c */
     459  extern int __fdisk_switch_label(struct fdisk_context *cxt,
     460  				    struct fdisk_label *lb);
     461  extern int fdisk_missing_geometry(struct fdisk_context *cxt);
     462  
     463  /* alignment.c */
     464  fdisk_sector_t fdisk_scround(struct fdisk_context *cxt, fdisk_sector_t num);
     465  fdisk_sector_t fdisk_cround(struct fdisk_context *cxt, fdisk_sector_t num);
     466  
     467  extern int fdisk_discover_geometry(struct fdisk_context *cxt);
     468  extern int fdisk_discover_topology(struct fdisk_context *cxt);
     469  
     470  extern int fdisk_has_user_device_geometry(struct fdisk_context *cxt);
     471  extern int fdisk_apply_user_device_properties(struct fdisk_context *cxt);
     472  extern int fdisk_apply_label_device_properties(struct fdisk_context *cxt);
     473  extern void fdisk_zeroize_device_properties(struct fdisk_context *cxt);
     474  
     475  /* utils.c */
     476  extern int fdisk_init_firstsector_buffer(struct fdisk_context *cxt,
     477  			unsigned int protect_off, unsigned int protect_size);
     478  extern int fdisk_read_firstsector(struct fdisk_context *cxt);
     479  
     480  /* label.c */
     481  extern int fdisk_probe_labels(struct fdisk_context *cxt);
     482  extern void fdisk_deinit_label(struct fdisk_label *lb);
     483  
     484  struct fdisk_labelitem {
     485  	int		refcount;	/* reference counter */
     486  	int		id;		/* <label>_ITEM_* */
     487  	char		type;		/* s = string, j = uint64 */
     488  	const char	*name;		/* human readable name */
     489  
     490  	union {
     491  		char		*str;
     492  		uint64_t	num64;
     493  	} data;
     494  };
     495  
     496  /* Use only internally for non-allocated items, never use
     497   * refcouting for such items!
     498   */
     499  #define FDISK_LABELITEM_INIT	{ .type = 0, .refcount = 0 }
     500  
     501  /* ask.c */
     502  struct fdisk_ask *fdisk_new_ask(void);
     503  void fdisk_reset_ask(struct fdisk_ask *ask);
     504  int fdisk_ask_set_query(struct fdisk_ask *ask, const char *str);
     505  int fdisk_ask_set_type(struct fdisk_ask *ask, int type);
     506  int fdisk_do_ask(struct fdisk_context *cxt, struct fdisk_ask *ask);
     507  int fdisk_ask_number_set_range(struct fdisk_ask *ask, const char *range);
     508  int fdisk_ask_number_set_default(struct fdisk_ask *ask, uint64_t dflt);
     509  int fdisk_ask_number_set_low(struct fdisk_ask *ask, uint64_t low);
     510  int fdisk_ask_number_set_high(struct fdisk_ask *ask, uint64_t high);
     511  int fdisk_ask_number_set_base(struct fdisk_ask *ask, uint64_t base);
     512  int fdisk_ask_number_set_unit(struct fdisk_ask *ask, uint64_t unit);
     513  int fdisk_ask_number_is_relative(struct fdisk_ask *ask);
     514  int fdisk_ask_number_set_wrap_negative(struct fdisk_ask *ask, int wrap_negative);
     515  int fdisk_ask_menu_set_default(struct fdisk_ask *ask, int dfl);
     516  int fdisk_ask_menu_add_item(struct fdisk_ask *ask, int key,
     517  			const char *name, const char *desc);
     518  int fdisk_ask_print_set_errno(struct fdisk_ask *ask, int errnum);
     519  int fdisk_ask_print_set_mesg(struct fdisk_ask *ask, const char *mesg);
     520  int fdisk_info_new_partition(
     521  			struct fdisk_context *cxt,
     522  			int num, fdisk_sector_t start, fdisk_sector_t stop,
     523  			struct fdisk_parttype *t);
     524  
     525  /* dos.c */
     526  extern struct dos_partition *fdisk_dos_get_partition(
     527  				struct fdisk_context *cxt,
     528  				size_t i);
     529  
     530  /* wipe.c */
     531  void fdisk_free_wipe_areas(struct fdisk_context *cxt);
     532  int fdisk_set_wipe_area(struct fdisk_context *cxt, uint64_t start, uint64_t size, int enable);
     533  int fdisk_do_wipe(struct fdisk_context *cxt);
     534  int fdisk_has_wipe_area(struct fdisk_context *cxt, uint64_t start, uint64_t size);
     535  int fdisk_check_collisions(struct fdisk_context *cxt);
     536  
     537  /* parttype.c */
     538  const char *fdisk_label_translate_type_shortcut(const struct fdisk_label *lb, char *cut);
     539  
     540  #endif /* _LIBFDISK_PRIVATE_H */