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 /* 27*9160SSherry.Moore@Sun.COM * This file contains all the functions that implement the following 28*9160SSherry.Moore@Sun.COM * GRUB commands: 29*9160SSherry.Moore@Sun.COM * kernel, kernel$, module, module$, findroot, bootfs 30*9160SSherry.Moore@Sun.COM * Return 0 on success, errno on failure. 31*9160SSherry.Moore@Sun.COM */ 32*9160SSherry.Moore@Sun.COM #include <stdio.h> 33*9160SSherry.Moore@Sun.COM #include <stdlib.h> 34*9160SSherry.Moore@Sun.COM #include <assert.h> 35*9160SSherry.Moore@Sun.COM #include <alloca.h> 36*9160SSherry.Moore@Sun.COM #include <errno.h> 37*9160SSherry.Moore@Sun.COM #include <strings.h> 38*9160SSherry.Moore@Sun.COM #include <unistd.h> 39*9160SSherry.Moore@Sun.COM #include <fcntl.h> 40*9160SSherry.Moore@Sun.COM #include <sys/types.h> 41*9160SSherry.Moore@Sun.COM #include <sys/fs/ufs_mount.h> 42*9160SSherry.Moore@Sun.COM #include <sys/dktp/fdisk.h> 43*9160SSherry.Moore@Sun.COM #if defined(__i386) 44*9160SSherry.Moore@Sun.COM #include <sys/x86_archext.h> 45*9160SSherry.Moore@Sun.COM #endif /* __i386 */ 46*9160SSherry.Moore@Sun.COM 47*9160SSherry.Moore@Sun.COM #include "libgrub_impl.h" 48*9160SSherry.Moore@Sun.COM 49*9160SSherry.Moore@Sun.COM #define RESET_MODULE(barg) ((barg)->gb_module[0] = 0) 50*9160SSherry.Moore@Sun.COM 51*9160SSherry.Moore@Sun.COM #if defined(__i386) 52*9160SSherry.Moore@Sun.COM static const char cpuid_dev[] = "/dev/cpu/self/cpuid"; 53*9160SSherry.Moore@Sun.COM 54*9160SSherry.Moore@Sun.COM /* 55*9160SSherry.Moore@Sun.COM * Return 1 if the system supports 64-bit mode, 0 if it doesn't, 56*9160SSherry.Moore@Sun.COM * or -1 on failure. 57*9160SSherry.Moore@Sun.COM */ 58*9160SSherry.Moore@Sun.COM static int 59*9160SSherry.Moore@Sun.COM cpuid_64bit_capable(void) 60*9160SSherry.Moore@Sun.COM { 61*9160SSherry.Moore@Sun.COM int fd, ret = -1; 62*9160SSherry.Moore@Sun.COM struct { 63*9160SSherry.Moore@Sun.COM uint32_t cp_eax, cp_ebx, cp_ecx, cp_edx; 64*9160SSherry.Moore@Sun.COM } cpuid_regs; 65*9160SSherry.Moore@Sun.COM 66*9160SSherry.Moore@Sun.COM if ((fd = open(cpuid_dev, O_RDONLY)) == -1) 67*9160SSherry.Moore@Sun.COM return (ret); 68*9160SSherry.Moore@Sun.COM 69*9160SSherry.Moore@Sun.COM if (pread(fd, &cpuid_regs, sizeof (cpuid_regs), 0x80000001) == 70*9160SSherry.Moore@Sun.COM sizeof (cpuid_regs)) 71*9160SSherry.Moore@Sun.COM ret = ((CPUID_AMD_EDX_LM & cpuid_regs.cp_edx) != 0); 72*9160SSherry.Moore@Sun.COM 73*9160SSherry.Moore@Sun.COM (void) close(fd); 74*9160SSherry.Moore@Sun.COM return (ret); 75*9160SSherry.Moore@Sun.COM } 76*9160SSherry.Moore@Sun.COM #endif /* __i386 */ 77*9160SSherry.Moore@Sun.COM 78*9160SSherry.Moore@Sun.COM 79*9160SSherry.Moore@Sun.COM /* 80*9160SSherry.Moore@Sun.COM * Expand $ISAIDR 81*9160SSherry.Moore@Sun.COM */ 82*9160SSherry.Moore@Sun.COM #if !defined(__i386) 83*9160SSherry.Moore@Sun.COM /* ARGSUSED */ 84*9160SSherry.Moore@Sun.COM #endif /* __i386 */ 85*9160SSherry.Moore@Sun.COM static size_t 86*9160SSherry.Moore@Sun.COM barg_isadir_var(char *var, int sz) 87*9160SSherry.Moore@Sun.COM { 88*9160SSherry.Moore@Sun.COM #if defined(__i386) 89*9160SSherry.Moore@Sun.COM if (cpuid_64bit_capable() == 1) 90*9160SSherry.Moore@Sun.COM return (strlcpy(var, "amd64", sz)); 91*9160SSherry.Moore@Sun.COM #endif /* __i386 */ 92*9160SSherry.Moore@Sun.COM 93*9160SSherry.Moore@Sun.COM var[0] = 0; 94*9160SSherry.Moore@Sun.COM return (0); 95*9160SSherry.Moore@Sun.COM } 96*9160SSherry.Moore@Sun.COM 97*9160SSherry.Moore@Sun.COM /* 98*9160SSherry.Moore@Sun.COM * Expand $ZFS-BOOTFS 99*9160SSherry.Moore@Sun.COM */ 100*9160SSherry.Moore@Sun.COM static size_t 101*9160SSherry.Moore@Sun.COM barg_bootfs_var(const grub_barg_t *barg, char *var, int sz) 102*9160SSherry.Moore@Sun.COM { 103*9160SSherry.Moore@Sun.COM int n; 104*9160SSherry.Moore@Sun.COM 105*9160SSherry.Moore@Sun.COM assert(barg); 106*9160SSherry.Moore@Sun.COM if (strcmp(barg->gb_root.gr_fstyp, MNTTYPE_ZFS) == 0) { 107*9160SSherry.Moore@Sun.COM n = snprintf(var, sz, "zfs-bootfs=%s,bootpath=\"%s\"", 108*9160SSherry.Moore@Sun.COM barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev, 109*9160SSherry.Moore@Sun.COM barg->gb_root.gr_physpath); 110*9160SSherry.Moore@Sun.COM } else { 111*9160SSherry.Moore@Sun.COM var[0] = 0; 112*9160SSherry.Moore@Sun.COM n = 0; 113*9160SSherry.Moore@Sun.COM } 114*9160SSherry.Moore@Sun.COM return (n); 115*9160SSherry.Moore@Sun.COM } 116*9160SSherry.Moore@Sun.COM 117*9160SSherry.Moore@Sun.COM /* 118*9160SSherry.Moore@Sun.COM * Expand all the variables without appending them more than once. 119*9160SSherry.Moore@Sun.COM */ 120*9160SSherry.Moore@Sun.COM static int 121*9160SSherry.Moore@Sun.COM expand_var(char *arg, size_t argsz, const char *var, size_t varsz, 122*9160SSherry.Moore@Sun.COM char *val, size_t valsz) 123*9160SSherry.Moore@Sun.COM { 124*9160SSherry.Moore@Sun.COM char *sp = arg; 125*9160SSherry.Moore@Sun.COM size_t sz = argsz, len; 126*9160SSherry.Moore@Sun.COM char *buf, *dst, *src; 127*9160SSherry.Moore@Sun.COM int ret = 0; 128*9160SSherry.Moore@Sun.COM 129*9160SSherry.Moore@Sun.COM buf = alloca(argsz); 130*9160SSherry.Moore@Sun.COM dst = buf; 131*9160SSherry.Moore@Sun.COM 132*9160SSherry.Moore@Sun.COM while ((src = strstr(sp, var)) != NULL) { 133*9160SSherry.Moore@Sun.COM 134*9160SSherry.Moore@Sun.COM len = src - sp; 135*9160SSherry.Moore@Sun.COM 136*9160SSherry.Moore@Sun.COM if (len + valsz > sz) { 137*9160SSherry.Moore@Sun.COM ret = E2BIG; 138*9160SSherry.Moore@Sun.COM break; 139*9160SSherry.Moore@Sun.COM } 140*9160SSherry.Moore@Sun.COM 141*9160SSherry.Moore@Sun.COM (void) bcopy(sp, dst, len); 142*9160SSherry.Moore@Sun.COM (void) bcopy(val, dst + len, valsz); 143*9160SSherry.Moore@Sun.COM dst += len + valsz; 144*9160SSherry.Moore@Sun.COM sz -= len + valsz; 145*9160SSherry.Moore@Sun.COM sp = src + varsz; 146*9160SSherry.Moore@Sun.COM } 147*9160SSherry.Moore@Sun.COM 148*9160SSherry.Moore@Sun.COM if (strlcpy(dst, sp, sz) >= sz) 149*9160SSherry.Moore@Sun.COM ret = E2BIG; 150*9160SSherry.Moore@Sun.COM 151*9160SSherry.Moore@Sun.COM if (ret == 0) 152*9160SSherry.Moore@Sun.COM bcopy(buf, arg, argsz); 153*9160SSherry.Moore@Sun.COM return (ret); 154*9160SSherry.Moore@Sun.COM } 155*9160SSherry.Moore@Sun.COM 156*9160SSherry.Moore@Sun.COM static int 157*9160SSherry.Moore@Sun.COM match_bootfs(zfs_handle_t *zfh, void *data) 158*9160SSherry.Moore@Sun.COM { 159*9160SSherry.Moore@Sun.COM int ret; 160*9160SSherry.Moore@Sun.COM const char *zfn; 161*9160SSherry.Moore@Sun.COM grub_barg_t *barg = (grub_barg_t *)data; 162*9160SSherry.Moore@Sun.COM 163*9160SSherry.Moore@Sun.COM ret = (zfs_get_type(zfh) == ZFS_TYPE_FILESYSTEM && 164*9160SSherry.Moore@Sun.COM (zfn = zfs_get_name(zfh)) != NULL && 165*9160SSherry.Moore@Sun.COM strcmp(barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev, zfn) == 0); 166*9160SSherry.Moore@Sun.COM 167*9160SSherry.Moore@Sun.COM if (ret != 0) 168*9160SSherry.Moore@Sun.COM barg->gb_walkret = 0; 169*9160SSherry.Moore@Sun.COM else 170*9160SSherry.Moore@Sun.COM (void) zfs_iter_filesystems(zfh, match_bootfs, barg); 171*9160SSherry.Moore@Sun.COM 172*9160SSherry.Moore@Sun.COM zfs_close(zfh); 173*9160SSherry.Moore@Sun.COM return (barg->gb_walkret == 0); 174*9160SSherry.Moore@Sun.COM } 175*9160SSherry.Moore@Sun.COM 176*9160SSherry.Moore@Sun.COM static void 177*9160SSherry.Moore@Sun.COM reset_root(grub_barg_t *barg) 178*9160SSherry.Moore@Sun.COM { 179*9160SSherry.Moore@Sun.COM (void) memset(&barg->gb_root, 0, sizeof (barg->gb_root)); 180*9160SSherry.Moore@Sun.COM barg->gb_bootsign[0] = 0; 181*9160SSherry.Moore@Sun.COM barg->gb_kernel[0] = 0; 182*9160SSherry.Moore@Sun.COM RESET_MODULE(barg); 183*9160SSherry.Moore@Sun.COM } 184*9160SSherry.Moore@Sun.COM 185*9160SSherry.Moore@Sun.COM /* ARGSUSED */ 186*9160SSherry.Moore@Sun.COM int 187*9160SSherry.Moore@Sun.COM skip_line(const grub_line_t *lp, grub_barg_t *barg) 188*9160SSherry.Moore@Sun.COM { 189*9160SSherry.Moore@Sun.COM return (0); 190*9160SSherry.Moore@Sun.COM } 191*9160SSherry.Moore@Sun.COM 192*9160SSherry.Moore@Sun.COM /* ARGSUSED */ 193*9160SSherry.Moore@Sun.COM int 194*9160SSherry.Moore@Sun.COM error_line(const grub_line_t *lp, grub_barg_t *barg) 195*9160SSherry.Moore@Sun.COM { 196*9160SSherry.Moore@Sun.COM return (EG_INVALIDLINE); 197*9160SSherry.Moore@Sun.COM } 198*9160SSherry.Moore@Sun.COM 199*9160SSherry.Moore@Sun.COM int 200*9160SSherry.Moore@Sun.COM kernel(const grub_line_t *lp, grub_barg_t *barg) 201*9160SSherry.Moore@Sun.COM { 202*9160SSherry.Moore@Sun.COM RESET_MODULE(barg); 203*9160SSherry.Moore@Sun.COM if (strlcpy(barg->gb_kernel, lp->gl_arg, sizeof (barg->gb_kernel)) >= 204*9160SSherry.Moore@Sun.COM sizeof (barg->gb_kernel)) 205*9160SSherry.Moore@Sun.COM return (E2BIG); 206*9160SSherry.Moore@Sun.COM 207*9160SSherry.Moore@Sun.COM return (0); 208*9160SSherry.Moore@Sun.COM } 209*9160SSherry.Moore@Sun.COM 210*9160SSherry.Moore@Sun.COM int 211*9160SSherry.Moore@Sun.COM module(const grub_line_t *lp, grub_barg_t *barg) 212*9160SSherry.Moore@Sun.COM { 213*9160SSherry.Moore@Sun.COM if (strlcpy(barg->gb_module, lp->gl_arg, sizeof (barg->gb_module)) >= 214*9160SSherry.Moore@Sun.COM sizeof (barg->gb_module)) 215*9160SSherry.Moore@Sun.COM return (E2BIG); 216*9160SSherry.Moore@Sun.COM 217*9160SSherry.Moore@Sun.COM return (0); 218*9160SSherry.Moore@Sun.COM } 219*9160SSherry.Moore@Sun.COM 220*9160SSherry.Moore@Sun.COM int 221*9160SSherry.Moore@Sun.COM dollar_kernel(const grub_line_t *lp, grub_barg_t *barg) 222*9160SSherry.Moore@Sun.COM { 223*9160SSherry.Moore@Sun.COM int ret; 224*9160SSherry.Moore@Sun.COM size_t bfslen, isalen; 225*9160SSherry.Moore@Sun.COM char isadir[32]; 226*9160SSherry.Moore@Sun.COM char bootfs[BOOTARGS_MAX]; 227*9160SSherry.Moore@Sun.COM 228*9160SSherry.Moore@Sun.COM RESET_MODULE(barg); 229*9160SSherry.Moore@Sun.COM if (strlcpy(barg->gb_kernel, lp->gl_arg, sizeof (barg->gb_kernel)) >= 230*9160SSherry.Moore@Sun.COM sizeof (barg->gb_kernel)) 231*9160SSherry.Moore@Sun.COM return (E2BIG); 232*9160SSherry.Moore@Sun.COM 233*9160SSherry.Moore@Sun.COM bfslen = barg_bootfs_var(barg, bootfs, sizeof (bootfs)); 234*9160SSherry.Moore@Sun.COM isalen = barg_isadir_var(isadir, sizeof (isadir)); 235*9160SSherry.Moore@Sun.COM 236*9160SSherry.Moore@Sun.COM if (bfslen >= sizeof (bootfs) || isalen >= sizeof (isadir)) 237*9160SSherry.Moore@Sun.COM return (EINVAL); 238*9160SSherry.Moore@Sun.COM 239*9160SSherry.Moore@Sun.COM if ((ret = expand_var(barg->gb_kernel, sizeof (barg->gb_kernel), 240*9160SSherry.Moore@Sun.COM ZFS_BOOT_VAR, strlen(ZFS_BOOT_VAR), bootfs, bfslen)) != 0) 241*9160SSherry.Moore@Sun.COM return (ret); 242*9160SSherry.Moore@Sun.COM 243*9160SSherry.Moore@Sun.COM ret = expand_var(barg->gb_kernel, sizeof (barg->gb_kernel), 244*9160SSherry.Moore@Sun.COM ISADIR_VAR, strlen(ISADIR_VAR), isadir, isalen); 245*9160SSherry.Moore@Sun.COM 246*9160SSherry.Moore@Sun.COM return (ret); 247*9160SSherry.Moore@Sun.COM } 248*9160SSherry.Moore@Sun.COM 249*9160SSherry.Moore@Sun.COM int 250*9160SSherry.Moore@Sun.COM dollar_module(const grub_line_t *lp, grub_barg_t *barg) 251*9160SSherry.Moore@Sun.COM { 252*9160SSherry.Moore@Sun.COM int ret; 253*9160SSherry.Moore@Sun.COM size_t isalen; 254*9160SSherry.Moore@Sun.COM char isadir[32]; 255*9160SSherry.Moore@Sun.COM 256*9160SSherry.Moore@Sun.COM if (strlcpy(barg->gb_module, lp->gl_arg, sizeof (barg->gb_module)) >= 257*9160SSherry.Moore@Sun.COM sizeof (barg->gb_module)) 258*9160SSherry.Moore@Sun.COM return (E2BIG); 259*9160SSherry.Moore@Sun.COM 260*9160SSherry.Moore@Sun.COM if ((isalen = barg_isadir_var(isadir, sizeof (isadir))) >= sizeof 261*9160SSherry.Moore@Sun.COM (isadir)) 262*9160SSherry.Moore@Sun.COM return (EINVAL); 263*9160SSherry.Moore@Sun.COM 264*9160SSherry.Moore@Sun.COM ret = expand_var(barg->gb_module, sizeof (barg->gb_module), 265*9160SSherry.Moore@Sun.COM ISADIR_VAR, strlen(ISADIR_VAR), isadir, isalen); 266*9160SSherry.Moore@Sun.COM 267*9160SSherry.Moore@Sun.COM return (ret); 268*9160SSherry.Moore@Sun.COM } 269*9160SSherry.Moore@Sun.COM 270*9160SSherry.Moore@Sun.COM 271*9160SSherry.Moore@Sun.COM int 272*9160SSherry.Moore@Sun.COM findroot(const grub_line_t *lp, grub_barg_t *barg) 273*9160SSherry.Moore@Sun.COM { 274*9160SSherry.Moore@Sun.COM size_t sz, bsz; 275*9160SSherry.Moore@Sun.COM const char *sign; 276*9160SSherry.Moore@Sun.COM 277*9160SSherry.Moore@Sun.COM reset_root(barg); 278*9160SSherry.Moore@Sun.COM 279*9160SSherry.Moore@Sun.COM sign = lp->gl_arg; 280*9160SSherry.Moore@Sun.COM barg->gb_prtnum = (uint_t)PRTNUM_INVALID; 281*9160SSherry.Moore@Sun.COM barg->gb_slcnum = (uint_t)SLCNUM_WHOLE_DISK; 282*9160SSherry.Moore@Sun.COM 283*9160SSherry.Moore@Sun.COM if (sign[0] == '(') { 284*9160SSherry.Moore@Sun.COM const char *pos; 285*9160SSherry.Moore@Sun.COM 286*9160SSherry.Moore@Sun.COM ++sign; 287*9160SSherry.Moore@Sun.COM if ((pos = strchr(sign, ',')) == NULL || (sz = pos - sign) == 0) 288*9160SSherry.Moore@Sun.COM return (EG_FINDROOTFMT); 289*9160SSherry.Moore@Sun.COM 290*9160SSherry.Moore@Sun.COM ++pos; 291*9160SSherry.Moore@Sun.COM if (!IS_PRTNUM_VALID(barg->gb_prtnum = pos[0] - '0')) 292*9160SSherry.Moore@Sun.COM return (EG_FINDROOTFMT); 293*9160SSherry.Moore@Sun.COM 294*9160SSherry.Moore@Sun.COM ++pos; 295*9160SSherry.Moore@Sun.COM if (pos[0] != ',' || 296*9160SSherry.Moore@Sun.COM !IS_SLCNUM_VALID(barg->gb_slcnum = pos[1]) || 297*9160SSherry.Moore@Sun.COM pos[2] != ')') 298*9160SSherry.Moore@Sun.COM return (EG_FINDROOTFMT); 299*9160SSherry.Moore@Sun.COM } else { 300*9160SSherry.Moore@Sun.COM sz = strlen(sign); 301*9160SSherry.Moore@Sun.COM } 302*9160SSherry.Moore@Sun.COM 303*9160SSherry.Moore@Sun.COM bsz = strlen(BOOTSIGN_DIR "/"); 304*9160SSherry.Moore@Sun.COM if (bsz + sz + 1 > sizeof (barg->gb_bootsign)) 305*9160SSherry.Moore@Sun.COM return (E2BIG); 306*9160SSherry.Moore@Sun.COM 307*9160SSherry.Moore@Sun.COM bcopy(BOOTSIGN_DIR "/", barg->gb_bootsign, bsz); 308*9160SSherry.Moore@Sun.COM bcopy(sign, barg->gb_bootsign + bsz, sz); 309*9160SSherry.Moore@Sun.COM barg->gb_bootsign [bsz + sz] = 0; 310*9160SSherry.Moore@Sun.COM 311*9160SSherry.Moore@Sun.COM return (grub_find_bootsign(barg)); 312*9160SSherry.Moore@Sun.COM } 313*9160SSherry.Moore@Sun.COM 314*9160SSherry.Moore@Sun.COM int 315*9160SSherry.Moore@Sun.COM bootfs(const grub_line_t *lp, grub_barg_t *barg) 316*9160SSherry.Moore@Sun.COM { 317*9160SSherry.Moore@Sun.COM zfs_handle_t *zfh; 318*9160SSherry.Moore@Sun.COM grub_menu_t *mp = barg->gb_entry->ge_menu; 319*9160SSherry.Moore@Sun.COM char *gfs_devp; 320*9160SSherry.Moore@Sun.COM size_t gfs_dev_len; 321*9160SSherry.Moore@Sun.COM 322*9160SSherry.Moore@Sun.COM /* Check if root is zfs */ 323*9160SSherry.Moore@Sun.COM if (strcmp(barg->gb_root.gr_fstyp, MNTTYPE_ZFS) != 0) 324*9160SSherry.Moore@Sun.COM return (EG_NOTZFS); 325*9160SSherry.Moore@Sun.COM 326*9160SSherry.Moore@Sun.COM gfs_devp = barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev; 327*9160SSherry.Moore@Sun.COM gfs_dev_len = sizeof (barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev); 328*9160SSherry.Moore@Sun.COM 329*9160SSherry.Moore@Sun.COM /* 330*9160SSherry.Moore@Sun.COM * If the bootfs value is the same as the bootfs for the pool, 331*9160SSherry.Moore@Sun.COM * do nothing. 332*9160SSherry.Moore@Sun.COM */ 333*9160SSherry.Moore@Sun.COM if (strcmp(lp->gl_arg, gfs_devp) == 0) 334*9160SSherry.Moore@Sun.COM return (0); 335*9160SSherry.Moore@Sun.COM 336*9160SSherry.Moore@Sun.COM if (strlcpy(gfs_devp, lp->gl_arg, gfs_dev_len) >= gfs_dev_len) 337*9160SSherry.Moore@Sun.COM return (E2BIG); 338*9160SSherry.Moore@Sun.COM 339*9160SSherry.Moore@Sun.COM /* check if specified bootfs belongs to the root pool */ 340*9160SSherry.Moore@Sun.COM if ((zfh = zfs_open(mp->gm_fs.gf_lzfh, 341*9160SSherry.Moore@Sun.COM barg->gb_root.gr_fs[GRBM_ZFS_TOPFS].gfs_dev, 342*9160SSherry.Moore@Sun.COM ZFS_TYPE_FILESYSTEM)) == NULL) 343*9160SSherry.Moore@Sun.COM return (EG_OPENZFS); 344*9160SSherry.Moore@Sun.COM 345*9160SSherry.Moore@Sun.COM barg->gb_walkret = EG_UNKBOOTFS; 346*9160SSherry.Moore@Sun.COM (void) zfs_iter_filesystems(zfh, match_bootfs, barg); 347*9160SSherry.Moore@Sun.COM zfs_close(zfh); 348*9160SSherry.Moore@Sun.COM 349*9160SSherry.Moore@Sun.COM if (barg->gb_walkret == 0) 350*9160SSherry.Moore@Sun.COM (void) grub_fsd_get_mountp(barg->gb_root.gr_fs + 351*9160SSherry.Moore@Sun.COM GRBM_ZFS_BOOTFS, MNTTYPE_ZFS); 352*9160SSherry.Moore@Sun.COM 353*9160SSherry.Moore@Sun.COM return (barg->gb_walkret); 354*9160SSherry.Moore@Sun.COM } 355