#ifndef _GRBMIMPL_H
#define _GRBMIMPL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mntent.h>
#include <sys/uadmin.h>
#include <sys/dktp/fdisk.h>
#include <libzfs.h>
#include <libdevinfo.h>
#include "libgrubmgmt.h"
#include "libgrub_errno.h"
#define GRUB_MENU "/boot/grub/menu.lst"
#define BOOTSIGN_DIR "/boot/grub/bootsign"
#define BOOTSIGN_LEN (2 * MAXNAMELEN)
#define ZFS_BOOT_VAR "$ZFS-BOOTFS"
#define ISADIR_VAR "$ISADIR"
#define PRTNUM_INVALID -1
#define SLCNUM_INVALID -1
#define SLCNUM_FIRST 'a'
#define SLCNUM_WHOLE_DISK 'q'
#define IS_SLCNUM_VALID(x) ((x) >= SLCNUM_FIRST && (x) < SLCNUM_WHOLE_DISK)
#define IS_PRTNUM_VALID(x) ((uint_t)(x) < FD_NUMPART + MAX_EXT_PARTS)
#define GRBM_VALID_FLAG ((uint_t)1 << 31)
#define GRBM_MAXLINE 8192
#define IS_ENTRY_VALID(ent) ((ent) && ((ent)->ge_flags & GRBM_VALID_FLAG))
#define IS_BARG_VALID(barg) ((barg)->gb_flags & GRBM_VALID_FLAG)
#define IS_ENTRY_BARG_VALID(ent) \
(IS_ENTRY_VALID(ent) && IS_BARG_VALID(&(ent)->ge_barg))
#define IS_LINE2BIG(buf, bfsz, len) \
((len = strlen(buf)) == (bfsz) - 1 && (buf)[len - 1] != '\n')
#define IS_STR_NULL(x) ((x) == NULL ? "NULL" : (x))
#define GRUB_ENTRY_IS_XVM(fbarg) \
(strstr(fbarg.gba_kernel, "xen.gz") != NULL)
enum {
#define menu_cmd(cmd, num, flags, parsef) num,
#define menu_cmd_end(num) num
#include "libgrub_cmd.def"
};
typedef struct _grub_fs {
di_node_t gf_diroot;
di_devlink_handle_t gf_dvlh;
libzfs_handle_t *gf_lzfh;
} grub_fs_t;
typedef struct _grub_cmd_desc {
const char *gcd_cmd;
uint_t gcd_num;
int gcd_flags;
} grub_cmd_desc_t;
enum {
GRBM_UFS = 0,
GRBM_ZFS_TOPFS = 0,
GRBM_FS_TOP = 0,
GRBM_ZFS_BOOTFS,
GRBM_FS_MAX
};
typedef struct _grub_root {
char gr_fstyp[MNTMAXSTR];
char gr_physpath[MAXPATHLEN];
grub_fsdesc_t gr_fs[GRBM_FS_MAX];
} grub_root_t;
typedef struct _grub_barg {
grub_entry_t *gb_entry;
grub_line_t *gb_errline;
int gb_walkret;
uint_t gb_flags;
uint_t gb_prtnum;
uint_t gb_slcnum;
grub_root_t gb_root;
char gb_bootsign[BOOTSIGN_LEN];
char gb_kernel[BOOTARGS_MAX];
char gb_module[BOOTARGS_MAX];
} grub_barg_t;
enum {
GRUB_LINE_INVALID = 0,
GRUB_LINE_EMPTY,
GRUB_LINE_COMMENT,
GRUB_LINE_GLOBAL,
GRUB_LINE_ENTRY,
GRUB_LINE_TITLE
};
struct grub_line {
grub_line_t *gl_next;
grub_line_t *gl_prev;
int gl_line_num;
int gl_entry_num;
int gl_flags;
uint_t gl_cmdtp;
char *gl_cmd;
char *gl_sep;
char *gl_arg;
char *gl_line;
};
struct grub_entry {
grub_menu_t *ge_menu;
grub_entry_t *ge_next;
grub_entry_t *ge_prev;
grub_line_t *ge_start;
grub_line_t *ge_end;
int ge_entry_num;
uint_t ge_flags;
uint_t ge_emask;
grub_barg_t ge_barg;
};
struct grub_menu {
grub_line_t *gm_start;
grub_line_t *gm_end;
grub_line_t *gm_curdefault;
grub_entry_t *gm_ent_start;
grub_entry_t *gm_ent_end;
grub_entry_t *gm_ent_default;
uint_t gm_line_num;
uint_t gm_entry_num;
char gm_path[MAXPATHLEN];
grub_fs_t gm_fs;
grub_root_t gm_root;
};
int grub_current_root(grub_fs_t *, grub_root_t *);
grub_fsdesc_t *grub_get_rootfsd(const grub_root_t *);
int grub_fsd_mount_tmp(grub_fsdesc_t *, const char *);
void grub_fsd_umount_tmp(grub_fsdesc_t *);
int grub_fsd_get_mountp(grub_fsdesc_t *fsd, char *fstyp);
int grub_find_bootsign(grub_barg_t *barg);
int skip_line(const grub_line_t *lp, grub_barg_t *barg);
int error_line(const grub_line_t *lp, grub_barg_t *barg);
int kernel(const grub_line_t *lp, grub_barg_t *barg);
int module(const grub_line_t *lp, grub_barg_t *barg);
int dollar_kernel(const grub_line_t *lp, grub_barg_t *barg);
int dollar_module(const grub_line_t *lp, grub_barg_t *barg);
int findroot(const grub_line_t *lp, grub_barg_t *barg);
int bootfs(const grub_line_t *lp, grub_barg_t *barg);
size_t clean_path(char *path);
int grub_entry_construct_barg(grub_entry_t *ent);
const char *grub_entry_get_fstyp(const grub_entry_t *ent);
const char *grub_entry_get_kernel(const grub_entry_t *ent);
const char *grub_entry_get_module(const grub_entry_t *ent);
const grub_fsdesc_t *grub_entry_get_rootfs(const grub_entry_t *ent);
size_t grub_entry_get_cmdline(grub_entry_t *ent, char *cmdline, size_t size);
int grub_menu_init(const char *grub_menu_path, grub_menu_t **menup);
void grub_menu_fini(grub_menu_t *);
grub_entry_t *grub_menu_get_entry(const grub_menu_t *menu, int num);
grub_entry_t *grub_menu_next_entry(const grub_menu_t *menu,
const grub_entry_t *current);
grub_entry_t *grub_menu_prev_entry(const grub_menu_t *menu,
const grub_entry_t *current);
grub_line_t *grub_menu_next_line(const grub_menu_t *menu,
const grub_line_t *current);
grub_line_t *grub_menu_prev_line(const grub_menu_t *menu,
const grub_line_t *current);
#ifdef __cplusplus
}
#endif
#endif