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