1753a6d45SSherry Moore /* 2753a6d45SSherry Moore * CDDL HEADER START 3753a6d45SSherry Moore * 4753a6d45SSherry Moore * The contents of this file are subject to the terms of the 5753a6d45SSherry Moore * Common Development and Distribution License (the "License"). 6753a6d45SSherry Moore * You may not use this file except in compliance with the License. 7753a6d45SSherry Moore * 8753a6d45SSherry Moore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9753a6d45SSherry Moore * or http://www.opensolaris.org/os/licensing. 10753a6d45SSherry Moore * See the License for the specific language governing permissions 11753a6d45SSherry Moore * and limitations under the License. 12753a6d45SSherry Moore * 13753a6d45SSherry Moore * When distributing Covered Code, include this CDDL HEADER in each 14753a6d45SSherry Moore * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15753a6d45SSherry Moore * If applicable, add the following below this CDDL HEADER, with the 16753a6d45SSherry Moore * fields enclosed by brackets "[]" replaced with your own identifying 17753a6d45SSherry Moore * information: Portions Copyright [yyyy] [name of copyright owner] 18753a6d45SSherry Moore * 19753a6d45SSherry Moore * CDDL HEADER END 20753a6d45SSherry Moore */ 21753a6d45SSherry Moore /* 22753a6d45SSherry Moore * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23753a6d45SSherry Moore * Use is subject to license terms. 24753a6d45SSherry Moore */ 25*01f9868aSMarcel Telka /* 26*01f9868aSMarcel Telka * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 27*01f9868aSMarcel Telka */ 28753a6d45SSherry Moore 29753a6d45SSherry Moore #ifndef _GRBMIMPL_H 30753a6d45SSherry Moore #define _GRBMIMPL_H 31753a6d45SSherry Moore 32753a6d45SSherry Moore #ifdef __cplusplus 33753a6d45SSherry Moore extern "C" { 34753a6d45SSherry Moore #endif 35753a6d45SSherry Moore 36753a6d45SSherry Moore #include <sys/types.h> 37753a6d45SSherry Moore #include <sys/param.h> 38753a6d45SSherry Moore #include <sys/mntent.h> 39753a6d45SSherry Moore #include <sys/uadmin.h> 40*01f9868aSMarcel Telka #include <sys/dktp/fdisk.h> 41753a6d45SSherry Moore #include <libzfs.h> 42753a6d45SSherry Moore #include <libdevinfo.h> 43753a6d45SSherry Moore #include "libgrubmgmt.h" 44753a6d45SSherry Moore #include "libgrub_errno.h" 45753a6d45SSherry Moore 46753a6d45SSherry Moore /* 47753a6d45SSherry Moore * Macros for processing the GRUB menu. 48753a6d45SSherry Moore */ 49753a6d45SSherry Moore #define GRUB_MENU "/boot/grub/menu.lst" 50753a6d45SSherry Moore #define BOOTSIGN_DIR "/boot/grub/bootsign" 51753a6d45SSherry Moore #define BOOTSIGN_LEN (2 * MAXNAMELEN) 52753a6d45SSherry Moore #define ZFS_BOOT_VAR "$ZFS-BOOTFS" /* ZFS boot option */ 53753a6d45SSherry Moore #define ISADIR_VAR "$ISADIR" /* ISADIR option */ 54753a6d45SSherry Moore 55753a6d45SSherry Moore #define PRTNUM_INVALID -1 /* Partition number invlaid */ 56753a6d45SSherry Moore #define SLCNUM_INVALID -1 /* Slice number invalid */ 57753a6d45SSherry Moore 58753a6d45SSherry Moore #define SLCNUM_FIRST 'a' 59753a6d45SSherry Moore #define SLCNUM_WHOLE_DISK 'q' 60753a6d45SSherry Moore 61753a6d45SSherry Moore #define IS_SLCNUM_VALID(x) ((x) >= SLCNUM_FIRST && (x) < SLCNUM_WHOLE_DISK) 62*01f9868aSMarcel Telka #define IS_PRTNUM_VALID(x) ((uint_t)(x) < FD_NUMPART + MAX_EXT_PARTS) 63753a6d45SSherry Moore 64753a6d45SSherry Moore #define GRBM_VALID_FLAG ((uint_t)1 << 31) 65753a6d45SSherry Moore #define GRBM_MAXLINE 8192 66753a6d45SSherry Moore #define IS_ENTRY_VALID(ent) ((ent) && ((ent)->ge_flags & GRBM_VALID_FLAG)) 67753a6d45SSherry Moore #define IS_BARG_VALID(barg) ((barg)->gb_flags & GRBM_VALID_FLAG) 68753a6d45SSherry Moore #define IS_ENTRY_BARG_VALID(ent) \ 69753a6d45SSherry Moore (IS_ENTRY_VALID(ent) && IS_BARG_VALID(&(ent)->ge_barg)) 70753a6d45SSherry Moore #define IS_LINE2BIG(buf, bfsz, len) \ 71753a6d45SSherry Moore ((len = strlen(buf)) == (bfsz) - 1 && (buf)[len - 1] != '\n') 72753a6d45SSherry Moore #define IS_STR_NULL(x) ((x) == NULL ? "NULL" : (x)) 73753a6d45SSherry Moore #define GRUB_ENTRY_IS_XVM(fbarg) \ 74753a6d45SSherry Moore (strstr(fbarg.gba_kernel, "xen.gz") != NULL) 75753a6d45SSherry Moore 76753a6d45SSherry Moore enum { 77753a6d45SSherry Moore #define menu_cmd(cmd, num, flags, parsef) num, 78753a6d45SSherry Moore #define menu_cmd_end(num) num 79753a6d45SSherry Moore #include "libgrub_cmd.def" 80753a6d45SSherry Moore }; 81753a6d45SSherry Moore 82753a6d45SSherry Moore typedef struct _grub_fs { 83753a6d45SSherry Moore di_node_t gf_diroot; 84753a6d45SSherry Moore di_devlink_handle_t gf_dvlh; 85753a6d45SSherry Moore libzfs_handle_t *gf_lzfh; 86753a6d45SSherry Moore } grub_fs_t; 87753a6d45SSherry Moore 88753a6d45SSherry Moore 89753a6d45SSherry Moore typedef struct _grub_cmd_desc { 90753a6d45SSherry Moore const char *gcd_cmd; 91753a6d45SSherry Moore uint_t gcd_num; 92753a6d45SSherry Moore int gcd_flags; 93753a6d45SSherry Moore } grub_cmd_desc_t; 94753a6d45SSherry Moore 95753a6d45SSherry Moore 96753a6d45SSherry Moore enum { 97753a6d45SSherry Moore GRBM_UFS = 0, 98753a6d45SSherry Moore GRBM_ZFS_TOPFS = 0, 99753a6d45SSherry Moore GRBM_FS_TOP = 0, 100753a6d45SSherry Moore GRBM_ZFS_BOOTFS, 101753a6d45SSherry Moore GRBM_FS_MAX 102753a6d45SSherry Moore }; 103753a6d45SSherry Moore 104753a6d45SSherry Moore typedef struct _grub_root { 105753a6d45SSherry Moore char gr_fstyp[MNTMAXSTR]; 106753a6d45SSherry Moore char gr_physpath[MAXPATHLEN]; 107753a6d45SSherry Moore grub_fsdesc_t gr_fs[GRBM_FS_MAX]; 108753a6d45SSherry Moore } grub_root_t; 109753a6d45SSherry Moore 110753a6d45SSherry Moore /* 111753a6d45SSherry Moore * Data struct for the boot argument constructed from a GRUB menu entry 112753a6d45SSherry Moore */ 113753a6d45SSherry Moore typedef struct _grub_barg { 114753a6d45SSherry Moore grub_entry_t *gb_entry; 115753a6d45SSherry Moore grub_line_t *gb_errline; 116753a6d45SSherry Moore int gb_walkret; /* set to 0 when match found */ 117753a6d45SSherry Moore uint_t gb_flags; 118753a6d45SSherry Moore uint_t gb_prtnum; 119753a6d45SSherry Moore uint_t gb_slcnum; 120753a6d45SSherry Moore grub_root_t gb_root; 121753a6d45SSherry Moore char gb_bootsign[BOOTSIGN_LEN]; 122753a6d45SSherry Moore char gb_kernel[BOOTARGS_MAX]; 123753a6d45SSherry Moore char gb_module[BOOTARGS_MAX]; 124753a6d45SSherry Moore } grub_barg_t; 125753a6d45SSherry Moore 126753a6d45SSherry Moore 127753a6d45SSherry Moore /* GRUB menu per-line classification */ 128753a6d45SSherry Moore enum { 129753a6d45SSherry Moore GRUB_LINE_INVALID = 0, 130753a6d45SSherry Moore GRUB_LINE_EMPTY, 131753a6d45SSherry Moore GRUB_LINE_COMMENT, 132753a6d45SSherry Moore GRUB_LINE_GLOBAL, 133753a6d45SSherry Moore GRUB_LINE_ENTRY, 134753a6d45SSherry Moore GRUB_LINE_TITLE 135753a6d45SSherry Moore }; 136753a6d45SSherry Moore 137753a6d45SSherry Moore /* 138753a6d45SSherry Moore * Data structures for menu.lst contents 139753a6d45SSherry Moore */ 140753a6d45SSherry Moore struct grub_line { 141753a6d45SSherry Moore grub_line_t *gl_next; 142753a6d45SSherry Moore grub_line_t *gl_prev; 143753a6d45SSherry Moore int gl_line_num; /* Line number in menu.lst */ 144753a6d45SSherry Moore int gl_entry_num; /* menu boot entry #. */ 145753a6d45SSherry Moore /* GRUB_ENTRY_DEFAULT if none */ 146753a6d45SSherry Moore int gl_flags; 147753a6d45SSherry Moore uint_t gl_cmdtp; /* recognized command type */ 148753a6d45SSherry Moore char *gl_cmd; 149753a6d45SSherry Moore char *gl_sep; 150753a6d45SSherry Moore char *gl_arg; 151753a6d45SSherry Moore char *gl_line; 152753a6d45SSherry Moore }; 153753a6d45SSherry Moore 154753a6d45SSherry Moore struct grub_entry { 155753a6d45SSherry Moore grub_menu_t *ge_menu; /* grub_menu_t it belongs to */ 156753a6d45SSherry Moore grub_entry_t *ge_next; 157753a6d45SSherry Moore grub_entry_t *ge_prev; 158753a6d45SSherry Moore grub_line_t *ge_start; 159753a6d45SSherry Moore grub_line_t *ge_end; 160753a6d45SSherry Moore int ge_entry_num; 161753a6d45SSherry Moore uint_t ge_flags; 162753a6d45SSherry Moore uint_t ge_emask; /* invalid lines mask */ 163753a6d45SSherry Moore grub_barg_t ge_barg; 164753a6d45SSherry Moore }; 165753a6d45SSherry Moore 166753a6d45SSherry Moore struct grub_menu { 167753a6d45SSherry Moore grub_line_t *gm_start; 168753a6d45SSherry Moore grub_line_t *gm_end; 169753a6d45SSherry Moore grub_line_t *gm_curdefault; /* line containing default */ 170753a6d45SSherry Moore grub_entry_t *gm_ent_start; /* os entries */ 171753a6d45SSherry Moore grub_entry_t *gm_ent_end; 172753a6d45SSherry Moore grub_entry_t *gm_ent_default; /* default entry */ 173753a6d45SSherry Moore uint_t gm_line_num; /* number of lines processed */ 174753a6d45SSherry Moore uint_t gm_entry_num; /* number of entries processed */ 175753a6d45SSherry Moore char gm_path[MAXPATHLEN]; 176753a6d45SSherry Moore grub_fs_t gm_fs; 177753a6d45SSherry Moore grub_root_t gm_root; 178753a6d45SSherry Moore }; 179753a6d45SSherry Moore 180753a6d45SSherry Moore /* File system helper functions */ 181753a6d45SSherry Moore int grub_current_root(grub_fs_t *, grub_root_t *); 182753a6d45SSherry Moore grub_fsdesc_t *grub_get_rootfsd(const grub_root_t *); 183753a6d45SSherry Moore int grub_fsd_mount_tmp(grub_fsdesc_t *, const char *); 184753a6d45SSherry Moore void grub_fsd_umount_tmp(grub_fsdesc_t *); 185753a6d45SSherry Moore int grub_fsd_get_mountp(grub_fsdesc_t *fsd, char *fstyp); 186753a6d45SSherry Moore int grub_find_bootsign(grub_barg_t *barg); 187753a6d45SSherry Moore 188753a6d45SSherry Moore 189753a6d45SSherry Moore /* GRUB menu parse functions */ 190753a6d45SSherry Moore int skip_line(const grub_line_t *lp, grub_barg_t *barg); 191753a6d45SSherry Moore int error_line(const grub_line_t *lp, grub_barg_t *barg); 192753a6d45SSherry Moore int kernel(const grub_line_t *lp, grub_barg_t *barg); 193753a6d45SSherry Moore int module(const grub_line_t *lp, grub_barg_t *barg); 194753a6d45SSherry Moore int dollar_kernel(const grub_line_t *lp, grub_barg_t *barg); 195753a6d45SSherry Moore int dollar_module(const grub_line_t *lp, grub_barg_t *barg); 196753a6d45SSherry Moore int findroot(const grub_line_t *lp, grub_barg_t *barg); 197753a6d45SSherry Moore int bootfs(const grub_line_t *lp, grub_barg_t *barg); 198753a6d45SSherry Moore size_t clean_path(char *path); 199753a6d45SSherry Moore 200753a6d45SSherry Moore 201753a6d45SSherry Moore /* GRUB entry functions */ 202753a6d45SSherry Moore int grub_entry_construct_barg(grub_entry_t *ent); 203753a6d45SSherry Moore const char *grub_entry_get_fstyp(const grub_entry_t *ent); 204753a6d45SSherry Moore const char *grub_entry_get_kernel(const grub_entry_t *ent); 205753a6d45SSherry Moore const char *grub_entry_get_module(const grub_entry_t *ent); 206753a6d45SSherry Moore const grub_fsdesc_t *grub_entry_get_rootfs(const grub_entry_t *ent); 207753a6d45SSherry Moore size_t grub_entry_get_cmdline(grub_entry_t *ent, char *cmdline, size_t size); 208753a6d45SSherry Moore 209753a6d45SSherry Moore /* 210753a6d45SSherry Moore * GRUB menu parse/access funcions. 211753a6d45SSherry Moore * 212753a6d45SSherry Moore * Callers must call grub_menu_init() to to obtain a handle to the menu before 213753a6d45SSherry Moore * calling any of the other functions, and call grub_menu_fini() to close. 214753a6d45SSherry Moore * 215753a6d45SSherry Moore * grub_menu_init: 216753a6d45SSherry Moore * Reads and parses GRUB menu file into a grub_menu_t data structure. 217753a6d45SSherry Moore * If grub_menu_path file path is NULL, will use 'currently active' 218753a6d45SSherry Moore * GRUB menu file. 219753a6d45SSherry Moore * grub_menu_fini: 220753a6d45SSherry Moore * Frees all resources allocated by grub_menu_init(). 221753a6d45SSherry Moore * 222753a6d45SSherry Moore * grub_menu_get_entry: 223753a6d45SSherry Moore * Returns a particular entry from the menu. 224753a6d45SSherry Moore * grub_menu_next_entry: 225753a6d45SSherry Moore * grub_menu_prev_entry: 226753a6d45SSherry Moore * Returns next or previous entry in the menu. 227753a6d45SSherry Moore * If current entry is NULL, return first or last entry. 228753a6d45SSherry Moore * 229753a6d45SSherry Moore * grub_menu_next_line: 230753a6d45SSherry Moore * grub_menu_prev_line: 231753a6d45SSherry Moore * Returns next/prev (to the current) line in the menu. 232753a6d45SSherry Moore * If current line is NULL, returns first or last line. 233753a6d45SSherry Moore * grub_menu_get_line: 234753a6d45SSherry Moore * Returns the specified line in the menu (line counter starts from one). 235753a6d45SSherry Moore */ 236753a6d45SSherry Moore int grub_menu_init(const char *grub_menu_path, grub_menu_t **menup); 237753a6d45SSherry Moore void grub_menu_fini(grub_menu_t *); 238753a6d45SSherry Moore grub_entry_t *grub_menu_get_entry(const grub_menu_t *menu, int num); 239753a6d45SSherry Moore grub_entry_t *grub_menu_next_entry(const grub_menu_t *menu, 240753a6d45SSherry Moore const grub_entry_t *current); 241753a6d45SSherry Moore grub_entry_t *grub_menu_prev_entry(const grub_menu_t *menu, 242753a6d45SSherry Moore const grub_entry_t *current); 243753a6d45SSherry Moore grub_line_t *grub_menu_next_line(const grub_menu_t *menu, 244753a6d45SSherry Moore const grub_line_t *current); 245753a6d45SSherry Moore grub_line_t *grub_menu_prev_line(const grub_menu_t *menu, 246753a6d45SSherry Moore const grub_line_t *current); 247753a6d45SSherry Moore 248753a6d45SSherry Moore #ifdef __cplusplus 249753a6d45SSherry Moore } 250753a6d45SSherry Moore #endif 251753a6d45SSherry Moore 252753a6d45SSherry Moore #endif /* _GRBMIMPL_H */ 253