xref: /onnv-gate/usr/src/lib/libgrubmgmt/common/libgrub_impl.h (revision 9160:1517e6edbc6f)
1*9160SSherry.Moore@Sun.COM /*
2*9160SSherry.Moore@Sun.COM  * CDDL HEADER START
3*9160SSherry.Moore@Sun.COM  *
4*9160SSherry.Moore@Sun.COM  * The contents of this file are subject to the terms of the
5*9160SSherry.Moore@Sun.COM  * Common Development and Distribution License (the "License").
6*9160SSherry.Moore@Sun.COM  * You may not use this file except in compliance with the License.
7*9160SSherry.Moore@Sun.COM  *
8*9160SSherry.Moore@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9160SSherry.Moore@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9160SSherry.Moore@Sun.COM  * See the License for the specific language governing permissions
11*9160SSherry.Moore@Sun.COM  * and limitations under the License.
12*9160SSherry.Moore@Sun.COM  *
13*9160SSherry.Moore@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9160SSherry.Moore@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9160SSherry.Moore@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9160SSherry.Moore@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9160SSherry.Moore@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9160SSherry.Moore@Sun.COM  *
19*9160SSherry.Moore@Sun.COM  * CDDL HEADER END
20*9160SSherry.Moore@Sun.COM  */
21*9160SSherry.Moore@Sun.COM /*
22*9160SSherry.Moore@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*9160SSherry.Moore@Sun.COM  * Use is subject to license terms.
24*9160SSherry.Moore@Sun.COM  */
25*9160SSherry.Moore@Sun.COM 
26*9160SSherry.Moore@Sun.COM #ifndef	_GRBMIMPL_H
27*9160SSherry.Moore@Sun.COM #define	_GRBMIMPL_H
28*9160SSherry.Moore@Sun.COM 
29*9160SSherry.Moore@Sun.COM #ifdef	__cplusplus
30*9160SSherry.Moore@Sun.COM extern "C" {
31*9160SSherry.Moore@Sun.COM #endif
32*9160SSherry.Moore@Sun.COM 
33*9160SSherry.Moore@Sun.COM #include <sys/types.h>
34*9160SSherry.Moore@Sun.COM #include <sys/param.h>
35*9160SSherry.Moore@Sun.COM #include <sys/mntent.h>
36*9160SSherry.Moore@Sun.COM #include <sys/uadmin.h>
37*9160SSherry.Moore@Sun.COM #include <libzfs.h>
38*9160SSherry.Moore@Sun.COM #include <libdevinfo.h>
39*9160SSherry.Moore@Sun.COM #include "libgrubmgmt.h"
40*9160SSherry.Moore@Sun.COM #include "libgrub_errno.h"
41*9160SSherry.Moore@Sun.COM 
42*9160SSherry.Moore@Sun.COM /*
43*9160SSherry.Moore@Sun.COM  * Macros for processing the GRUB menu.
44*9160SSherry.Moore@Sun.COM  */
45*9160SSherry.Moore@Sun.COM #define	GRUB_MENU	"/boot/grub/menu.lst"
46*9160SSherry.Moore@Sun.COM #define	BOOTSIGN_DIR	"/boot/grub/bootsign"
47*9160SSherry.Moore@Sun.COM #define	BOOTSIGN_LEN	(2 * MAXNAMELEN)
48*9160SSherry.Moore@Sun.COM #define	ZFS_BOOT_VAR	"$ZFS-BOOTFS"	/* ZFS boot option */
49*9160SSherry.Moore@Sun.COM #define	ISADIR_VAR	"$ISADIR"	/* ISADIR option */
50*9160SSherry.Moore@Sun.COM 
51*9160SSherry.Moore@Sun.COM #define	PRTNUM_INVALID	-1	/* Partition number invlaid */
52*9160SSherry.Moore@Sun.COM #define	SLCNUM_INVALID	-1	/* Slice number invalid */
53*9160SSherry.Moore@Sun.COM 
54*9160SSherry.Moore@Sun.COM #define	SLCNUM_FIRST		'a'
55*9160SSherry.Moore@Sun.COM #define	SLCNUM_WHOLE_DISK	'q'
56*9160SSherry.Moore@Sun.COM 
57*9160SSherry.Moore@Sun.COM #define	IS_SLCNUM_VALID(x)	((x) >= SLCNUM_FIRST && (x) < SLCNUM_WHOLE_DISK)
58*9160SSherry.Moore@Sun.COM #define	IS_PRTNUM_VALID(x)	((uint_t)(x) < FD_NUMPART)
59*9160SSherry.Moore@Sun.COM 
60*9160SSherry.Moore@Sun.COM #define	GRBM_VALID_FLAG		((uint_t)1 << 31)
61*9160SSherry.Moore@Sun.COM #define	GRBM_MAXLINE		8192
62*9160SSherry.Moore@Sun.COM #define	IS_ENTRY_VALID(ent)	((ent) && ((ent)->ge_flags & GRBM_VALID_FLAG))
63*9160SSherry.Moore@Sun.COM #define	IS_BARG_VALID(barg)	((barg)->gb_flags & GRBM_VALID_FLAG)
64*9160SSherry.Moore@Sun.COM #define	IS_ENTRY_BARG_VALID(ent) \
65*9160SSherry.Moore@Sun.COM 	(IS_ENTRY_VALID(ent) && IS_BARG_VALID(&(ent)->ge_barg))
66*9160SSherry.Moore@Sun.COM #define	IS_LINE2BIG(buf, bfsz, len) \
67*9160SSherry.Moore@Sun.COM 	((len = strlen(buf)) == (bfsz) - 1 && (buf)[len - 1] != '\n')
68*9160SSherry.Moore@Sun.COM #define	IS_STR_NULL(x)	((x) == NULL ? "NULL" : (x))
69*9160SSherry.Moore@Sun.COM #define	GRUB_ENTRY_IS_XVM(fbarg) \
70*9160SSherry.Moore@Sun.COM 	(strstr(fbarg.gba_kernel, "xen.gz") != NULL)
71*9160SSherry.Moore@Sun.COM 
72*9160SSherry.Moore@Sun.COM enum {
73*9160SSherry.Moore@Sun.COM #define	menu_cmd(cmd, num, flags, parsef)	num,
74*9160SSherry.Moore@Sun.COM #define	menu_cmd_end(num)			num
75*9160SSherry.Moore@Sun.COM #include "libgrub_cmd.def"
76*9160SSherry.Moore@Sun.COM };
77*9160SSherry.Moore@Sun.COM 
78*9160SSherry.Moore@Sun.COM typedef struct _grub_fs {
79*9160SSherry.Moore@Sun.COM 	di_node_t		gf_diroot;
80*9160SSherry.Moore@Sun.COM 	di_devlink_handle_t	gf_dvlh;
81*9160SSherry.Moore@Sun.COM 	libzfs_handle_t		*gf_lzfh;
82*9160SSherry.Moore@Sun.COM } grub_fs_t;
83*9160SSherry.Moore@Sun.COM 
84*9160SSherry.Moore@Sun.COM 
85*9160SSherry.Moore@Sun.COM typedef struct _grub_cmd_desc {
86*9160SSherry.Moore@Sun.COM 	const char	*gcd_cmd;
87*9160SSherry.Moore@Sun.COM 	uint_t		gcd_num;
88*9160SSherry.Moore@Sun.COM 	int		gcd_flags;
89*9160SSherry.Moore@Sun.COM } grub_cmd_desc_t;
90*9160SSherry.Moore@Sun.COM 
91*9160SSherry.Moore@Sun.COM 
92*9160SSherry.Moore@Sun.COM enum {
93*9160SSherry.Moore@Sun.COM 	GRBM_UFS = 0,
94*9160SSherry.Moore@Sun.COM 	GRBM_ZFS_TOPFS = 0,
95*9160SSherry.Moore@Sun.COM 	GRBM_FS_TOP = 0,
96*9160SSherry.Moore@Sun.COM 	GRBM_ZFS_BOOTFS,
97*9160SSherry.Moore@Sun.COM 	GRBM_FS_MAX
98*9160SSherry.Moore@Sun.COM };
99*9160SSherry.Moore@Sun.COM 
100*9160SSherry.Moore@Sun.COM typedef struct _grub_root {
101*9160SSherry.Moore@Sun.COM 	char		gr_fstyp[MNTMAXSTR];
102*9160SSherry.Moore@Sun.COM 	char		gr_physpath[MAXPATHLEN];
103*9160SSherry.Moore@Sun.COM 	grub_fsdesc_t	gr_fs[GRBM_FS_MAX];
104*9160SSherry.Moore@Sun.COM } grub_root_t;
105*9160SSherry.Moore@Sun.COM 
106*9160SSherry.Moore@Sun.COM /*
107*9160SSherry.Moore@Sun.COM  * Data struct for the boot argument constructed from a GRUB menu entry
108*9160SSherry.Moore@Sun.COM  */
109*9160SSherry.Moore@Sun.COM typedef struct _grub_barg {
110*9160SSherry.Moore@Sun.COM 	grub_entry_t	*gb_entry;
111*9160SSherry.Moore@Sun.COM 	grub_line_t	*gb_errline;
112*9160SSherry.Moore@Sun.COM 	int		gb_walkret;	/* set to 0 when match found */
113*9160SSherry.Moore@Sun.COM 	uint_t		gb_flags;
114*9160SSherry.Moore@Sun.COM 	uint_t		gb_prtnum;
115*9160SSherry.Moore@Sun.COM 	uint_t		gb_slcnum;
116*9160SSherry.Moore@Sun.COM 	grub_root_t	gb_root;
117*9160SSherry.Moore@Sun.COM 	char		gb_bootsign[BOOTSIGN_LEN];
118*9160SSherry.Moore@Sun.COM 	char		gb_kernel[BOOTARGS_MAX];
119*9160SSherry.Moore@Sun.COM 	char		gb_module[BOOTARGS_MAX];
120*9160SSherry.Moore@Sun.COM } grub_barg_t;
121*9160SSherry.Moore@Sun.COM 
122*9160SSherry.Moore@Sun.COM 
123*9160SSherry.Moore@Sun.COM /* GRUB menu per-line classification */
124*9160SSherry.Moore@Sun.COM enum {
125*9160SSherry.Moore@Sun.COM 	GRUB_LINE_INVALID = 0,
126*9160SSherry.Moore@Sun.COM 	GRUB_LINE_EMPTY,
127*9160SSherry.Moore@Sun.COM 	GRUB_LINE_COMMENT,
128*9160SSherry.Moore@Sun.COM 	GRUB_LINE_GLOBAL,
129*9160SSherry.Moore@Sun.COM 	GRUB_LINE_ENTRY,
130*9160SSherry.Moore@Sun.COM 	GRUB_LINE_TITLE
131*9160SSherry.Moore@Sun.COM };
132*9160SSherry.Moore@Sun.COM 
133*9160SSherry.Moore@Sun.COM /*
134*9160SSherry.Moore@Sun.COM  * Data structures for menu.lst contents
135*9160SSherry.Moore@Sun.COM  */
136*9160SSherry.Moore@Sun.COM struct grub_line {
137*9160SSherry.Moore@Sun.COM 	grub_line_t	*gl_next;
138*9160SSherry.Moore@Sun.COM 	grub_line_t	*gl_prev;
139*9160SSherry.Moore@Sun.COM 	int		gl_line_num;	/* Line number in menu.lst */
140*9160SSherry.Moore@Sun.COM 	int		gl_entry_num;	/* menu boot entry #. */
141*9160SSherry.Moore@Sun.COM 					/* GRUB_ENTRY_DEFAULT if none */
142*9160SSherry.Moore@Sun.COM 	int		gl_flags;
143*9160SSherry.Moore@Sun.COM 	uint_t		gl_cmdtp;	/* recognized command type */
144*9160SSherry.Moore@Sun.COM 	char		*gl_cmd;
145*9160SSherry.Moore@Sun.COM 	char		*gl_sep;
146*9160SSherry.Moore@Sun.COM 	char		*gl_arg;
147*9160SSherry.Moore@Sun.COM 	char		*gl_line;
148*9160SSherry.Moore@Sun.COM };
149*9160SSherry.Moore@Sun.COM 
150*9160SSherry.Moore@Sun.COM struct grub_entry {
151*9160SSherry.Moore@Sun.COM 	grub_menu_t	*ge_menu;	/* grub_menu_t it belongs to */
152*9160SSherry.Moore@Sun.COM 	grub_entry_t	*ge_next;
153*9160SSherry.Moore@Sun.COM 	grub_entry_t	*ge_prev;
154*9160SSherry.Moore@Sun.COM 	grub_line_t	*ge_start;
155*9160SSherry.Moore@Sun.COM 	grub_line_t	*ge_end;
156*9160SSherry.Moore@Sun.COM 	int		ge_entry_num;
157*9160SSherry.Moore@Sun.COM 	uint_t		ge_flags;
158*9160SSherry.Moore@Sun.COM 	uint_t		ge_emask;	/* invalid lines mask */
159*9160SSherry.Moore@Sun.COM 	grub_barg_t	ge_barg;
160*9160SSherry.Moore@Sun.COM };
161*9160SSherry.Moore@Sun.COM 
162*9160SSherry.Moore@Sun.COM struct grub_menu {
163*9160SSherry.Moore@Sun.COM 	grub_line_t	*gm_start;
164*9160SSherry.Moore@Sun.COM 	grub_line_t	*gm_end;
165*9160SSherry.Moore@Sun.COM 	grub_line_t	*gm_curdefault;	/* line containing default */
166*9160SSherry.Moore@Sun.COM 	grub_entry_t	*gm_ent_start;	/* os entries */
167*9160SSherry.Moore@Sun.COM 	grub_entry_t	*gm_ent_end;
168*9160SSherry.Moore@Sun.COM 	grub_entry_t	*gm_ent_default;	/* default entry */
169*9160SSherry.Moore@Sun.COM 	uint_t		gm_line_num;	/* number of lines processed */
170*9160SSherry.Moore@Sun.COM 	uint_t		gm_entry_num;	/* number of entries processed */
171*9160SSherry.Moore@Sun.COM 	char		gm_path[MAXPATHLEN];
172*9160SSherry.Moore@Sun.COM 	grub_fs_t	gm_fs;
173*9160SSherry.Moore@Sun.COM 	grub_root_t	gm_root;
174*9160SSherry.Moore@Sun.COM };
175*9160SSherry.Moore@Sun.COM 
176*9160SSherry.Moore@Sun.COM /* File system helper functions */
177*9160SSherry.Moore@Sun.COM int grub_current_root(grub_fs_t *, grub_root_t *);
178*9160SSherry.Moore@Sun.COM grub_fsdesc_t *grub_get_rootfsd(const grub_root_t *);
179*9160SSherry.Moore@Sun.COM int grub_fsd_mount_tmp(grub_fsdesc_t *, const char *);
180*9160SSherry.Moore@Sun.COM void grub_fsd_umount_tmp(grub_fsdesc_t *);
181*9160SSherry.Moore@Sun.COM int grub_fsd_get_mountp(grub_fsdesc_t *fsd, char *fstyp);
182*9160SSherry.Moore@Sun.COM int grub_find_bootsign(grub_barg_t *barg);
183*9160SSherry.Moore@Sun.COM 
184*9160SSherry.Moore@Sun.COM 
185*9160SSherry.Moore@Sun.COM /* GRUB menu parse functions */
186*9160SSherry.Moore@Sun.COM int skip_line(const grub_line_t *lp, grub_barg_t *barg);
187*9160SSherry.Moore@Sun.COM int error_line(const grub_line_t *lp, grub_barg_t *barg);
188*9160SSherry.Moore@Sun.COM int kernel(const grub_line_t *lp, grub_barg_t *barg);
189*9160SSherry.Moore@Sun.COM int module(const grub_line_t *lp, grub_barg_t *barg);
190*9160SSherry.Moore@Sun.COM int dollar_kernel(const grub_line_t *lp, grub_barg_t *barg);
191*9160SSherry.Moore@Sun.COM int dollar_module(const grub_line_t *lp, grub_barg_t *barg);
192*9160SSherry.Moore@Sun.COM int findroot(const grub_line_t *lp, grub_barg_t *barg);
193*9160SSherry.Moore@Sun.COM int bootfs(const grub_line_t *lp, grub_barg_t *barg);
194*9160SSherry.Moore@Sun.COM size_t clean_path(char *path);
195*9160SSherry.Moore@Sun.COM 
196*9160SSherry.Moore@Sun.COM 
197*9160SSherry.Moore@Sun.COM /* GRUB entry functions */
198*9160SSherry.Moore@Sun.COM int grub_entry_construct_barg(grub_entry_t *ent);
199*9160SSherry.Moore@Sun.COM const char *grub_entry_get_fstyp(const grub_entry_t *ent);
200*9160SSherry.Moore@Sun.COM const char *grub_entry_get_kernel(const grub_entry_t *ent);
201*9160SSherry.Moore@Sun.COM const char *grub_entry_get_module(const grub_entry_t *ent);
202*9160SSherry.Moore@Sun.COM const grub_fsdesc_t *grub_entry_get_rootfs(const grub_entry_t *ent);
203*9160SSherry.Moore@Sun.COM size_t grub_entry_get_cmdline(grub_entry_t *ent, char *cmdline, size_t size);
204*9160SSherry.Moore@Sun.COM 
205*9160SSherry.Moore@Sun.COM /*
206*9160SSherry.Moore@Sun.COM  * GRUB menu parse/access funcions.
207*9160SSherry.Moore@Sun.COM  *
208*9160SSherry.Moore@Sun.COM  * Callers must call grub_menu_init() to to obtain a handle to the menu before
209*9160SSherry.Moore@Sun.COM  * calling any of the other functions, and call grub_menu_fini() to close.
210*9160SSherry.Moore@Sun.COM  *
211*9160SSherry.Moore@Sun.COM  * grub_menu_init:
212*9160SSherry.Moore@Sun.COM  *	Reads and parses GRUB menu file into a grub_menu_t data structure.
213*9160SSherry.Moore@Sun.COM  *	If grub_menu_path file path is NULL, will use 'currently active'
214*9160SSherry.Moore@Sun.COM  *	GRUB menu file.
215*9160SSherry.Moore@Sun.COM  * grub_menu_fini:
216*9160SSherry.Moore@Sun.COM  *	Frees all resources allocated by grub_menu_init().
217*9160SSherry.Moore@Sun.COM  *
218*9160SSherry.Moore@Sun.COM  * grub_menu_get_entry:
219*9160SSherry.Moore@Sun.COM  *	Returns a particular entry from the menu.
220*9160SSherry.Moore@Sun.COM  * grub_menu_next_entry:
221*9160SSherry.Moore@Sun.COM  * grub_menu_prev_entry:
222*9160SSherry.Moore@Sun.COM  *      Returns next or previous entry in the menu.
223*9160SSherry.Moore@Sun.COM  *      If current entry is NULL, return first or last entry.
224*9160SSherry.Moore@Sun.COM  *
225*9160SSherry.Moore@Sun.COM  * grub_menu_next_line:
226*9160SSherry.Moore@Sun.COM  * grub_menu_prev_line:
227*9160SSherry.Moore@Sun.COM  *      Returns next/prev (to the current) line in the menu.
228*9160SSherry.Moore@Sun.COM  *      If current line is NULL, returns first or last line.
229*9160SSherry.Moore@Sun.COM  * grub_menu_get_line:
230*9160SSherry.Moore@Sun.COM  *      Returns the specified line in the menu (line counter starts from one).
231*9160SSherry.Moore@Sun.COM  */
232*9160SSherry.Moore@Sun.COM int grub_menu_init(const char *grub_menu_path, grub_menu_t **menup);
233*9160SSherry.Moore@Sun.COM void grub_menu_fini(grub_menu_t *);
234*9160SSherry.Moore@Sun.COM grub_entry_t *grub_menu_get_entry(const grub_menu_t *menu, int num);
235*9160SSherry.Moore@Sun.COM grub_entry_t *grub_menu_next_entry(const grub_menu_t *menu,
236*9160SSherry.Moore@Sun.COM     const grub_entry_t *current);
237*9160SSherry.Moore@Sun.COM grub_entry_t *grub_menu_prev_entry(const grub_menu_t *menu,
238*9160SSherry.Moore@Sun.COM     const grub_entry_t *current);
239*9160SSherry.Moore@Sun.COM grub_line_t *grub_menu_next_line(const grub_menu_t *menu,
240*9160SSherry.Moore@Sun.COM     const grub_line_t *current);
241*9160SSherry.Moore@Sun.COM grub_line_t *grub_menu_prev_line(const grub_menu_t *menu,
242*9160SSherry.Moore@Sun.COM     const grub_line_t *current);
243*9160SSherry.Moore@Sun.COM 
244*9160SSherry.Moore@Sun.COM #ifdef __cplusplus
245*9160SSherry.Moore@Sun.COM }
246*9160SSherry.Moore@Sun.COM #endif
247*9160SSherry.Moore@Sun.COM 
248*9160SSherry.Moore@Sun.COM #endif	/* _GRBMIMPL_H */
249