libgrub_cmd.c revision 753a6d457b330b1b29b2d3eefcd0831116ce950d
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * CDDL HEADER START
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * The contents of this file are subject to the terms of the
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Common Development and Distribution License (the "License").
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * You may not use this file except in compliance with the License.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * See the License for the specific language governing permissions
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * and limitations under the License.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * When distributing Covered Code, include this CDDL HEADER in each
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * If applicable, add the following below this CDDL HEADER, with the
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * fields enclosed by brackets "[]" replaced with your own identifying
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * information: Portions Copyright [yyyy] [name of copyright owner]
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * CDDL HEADER END
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Use is subject to license terms.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * This file contains all the functions that implement the following
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * GRUB commands:
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * kernel, kernel$, module, module$, findroot, bootfs
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Return 0 on success, errno on failure.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore#endif /* __i386 */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore#define RESET_MODULE(barg) ((barg)->gb_module[0] = 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorestatic const char cpuid_dev[] = "/dev/cpu/self/cpuid";
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Return 1 if the system supports 64-bit mode, 0 if it doesn't,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * or -1 on failure.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (pread(fd, &cpuid_regs, sizeof (cpuid_regs), 0x80000001) ==
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ret = ((CPUID_AMD_EDX_LM & cpuid_regs.cp_edx) != 0);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore#endif /* __i386 */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Expand $ISAIDR
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore/* ARGSUSED */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore#endif /* __i386 */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore#endif /* __i386 */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Expand $ZFS-BOOTFS
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorebarg_bootfs_var(const grub_barg_t *barg, char *var, int sz)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strcmp(barg->gb_root.gr_fstyp, MNTTYPE_ZFS) == 0) {
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore n = snprintf(var, sz, "zfs-bootfs=%s,bootpath=\"%s\"",
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Expand all the variables without appending them more than once.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooreexpand_var(char *arg, size_t argsz, const char *var, size_t varsz,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore const char *zfn;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ret = (zfs_get_type(zfh) == ZFS_TYPE_FILESYSTEM &&
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore strcmp(barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev, zfn) == 0);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore (void) zfs_iter_filesystems(zfh, match_bootfs, barg);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore (void) memset(&barg->gb_root, 0, sizeof (barg->gb_root));
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore/* ARGSUSED */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooreskip_line(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore/* ARGSUSED */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooreerror_line(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorekernel(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strlcpy(barg->gb_kernel, lp->gl_arg, sizeof (barg->gb_kernel)) >=
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooremodule(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strlcpy(barg->gb_module, lp->gl_arg, sizeof (barg->gb_module)) >=
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooredollar_kernel(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strlcpy(barg->gb_kernel, lp->gl_arg, sizeof (barg->gb_kernel)) >=
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore bfslen = barg_bootfs_var(barg, bootfs, sizeof (bootfs));
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore isalen = barg_isadir_var(isadir, sizeof (isadir));
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (bfslen >= sizeof (bootfs) || isalen >= sizeof (isadir))
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if ((ret = expand_var(barg->gb_kernel, sizeof (barg->gb_kernel),
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ZFS_BOOT_VAR, strlen(ZFS_BOOT_VAR), bootfs, bfslen)) != 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ret = expand_var(barg->gb_kernel, sizeof (barg->gb_kernel),
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ISADIR_VAR, strlen(ISADIR_VAR), isadir, isalen);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooredollar_module(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strlcpy(barg->gb_module, lp->gl_arg, sizeof (barg->gb_module)) >=
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if ((isalen = barg_isadir_var(isadir, sizeof (isadir))) >= sizeof
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ret = expand_var(barg->gb_module, sizeof (barg->gb_module),
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore ISADIR_VAR, strlen(ISADIR_VAR), isadir, isalen);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorefindroot(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore const char *sign;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore const char *pos;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if ((pos = strchr(sign, ',')) == NULL || (sz = pos - sign) == 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (!IS_PRTNUM_VALID(barg->gb_prtnum = pos[0] - '0'))
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore bcopy(BOOTSIGN_DIR "/", barg->gb_bootsign, bsz);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorebootfs(const grub_line_t *lp, grub_barg_t *barg)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore /* Check if root is zfs */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strcmp(barg->gb_root.gr_fstyp, MNTTYPE_ZFS) != 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore gfs_devp = barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore gfs_dev_len = sizeof (barg->gb_root.gr_fs[GRBM_ZFS_BOOTFS].gfs_dev);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * If the bootfs value is the same as the bootfs for the pool,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * do nothing.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strlcpy(gfs_devp, lp->gl_arg, gfs_dev_len) >= gfs_dev_len)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore /* check if specified bootfs belongs to the root pool */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore (void) zfs_iter_filesystems(zfh, match_bootfs, barg);