Date: Fri, 29 Jun 2012 10:18:36 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r237765 - in stable/8/sys: boot/common boot/i386/libi386 boot/i386/loader boot/i386/zfsboot boot/ofw/libofw boot/sparc64/loader boot/zfs cddl/boot/zfs Message-ID: <201206291018.q5TAIaIL039322@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Fri Jun 29 10:18:36 2012 New Revision: 237765 URL: http://svn.freebsd.org/changeset/base/237765 Log: MFC r235329,235343,235361,235364: zfsboot/zfsloader: support accessing filesystems within a pool Added: stable/8/sys/boot/zfs/devicename_stubs.c - copied unchanged from r235329, head/sys/boot/zfs/devicename_stubs.c stable/8/sys/boot/zfs/libzfs.h - copied unchanged from r235329, head/sys/boot/zfs/libzfs.h Modified: stable/8/sys/boot/common/bootstrap.h stable/8/sys/boot/i386/libi386/Makefile stable/8/sys/boot/i386/libi386/devicename.c stable/8/sys/boot/i386/libi386/libi386.h stable/8/sys/boot/i386/loader/conf.c stable/8/sys/boot/i386/loader/main.c stable/8/sys/boot/i386/zfsboot/zfsboot.c stable/8/sys/boot/ofw/libofw/Makefile stable/8/sys/boot/ofw/libofw/devicename.c stable/8/sys/boot/ofw/libofw/libofw.h stable/8/sys/boot/sparc64/loader/Makefile stable/8/sys/boot/sparc64/loader/main.c stable/8/sys/boot/zfs/zfs.c stable/8/sys/boot/zfs/zfsimpl.c stable/8/sys/cddl/boot/zfs/zfsimpl.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/boot/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/e1000/ (props changed) Modified: stable/8/sys/boot/common/bootstrap.h ============================================================================== --- stable/8/sys/boot/common/bootstrap.h Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/common/bootstrap.h Fri Jun 29 10:18:36 2012 (r237765) @@ -301,6 +301,9 @@ struct arch_switch void (*arch_isaoutb)(int port, int value); /* Pass in initial kernel memory size */ void (*arch_maphint)(vm_offset_t va, size_t len); + + /* Probe ZFS pool(s), if needed. */ + void (*arch_zfs_probe)(void); }; extern struct arch_switch archsw; Modified: stable/8/sys/boot/i386/libi386/Makefile ============================================================================== --- stable/8/sys/boot/i386/libi386/Makefile Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/i386/libi386/Makefile Fri Jun 29 10:18:36 2012 (r237765) @@ -9,6 +9,8 @@ SRCS= biosacpi.c bioscd.c biosdisk.c bio elf64_freebsd.c \ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \ smbios.c time.c vidconsole.c amd64_tramp.S +.PATH: ${.CURDIR}/../../zfs +SRCS+= devicename_stubs.c # Enable PXE TFTP or NFS support, not both. .if defined(LOADER_TFTP_SUPPORT) Modified: stable/8/sys/boot/i386/libi386/devicename.c ============================================================================== --- stable/8/sys/boot/i386/libi386/devicename.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/i386/libi386/devicename.c Fri Jun 29 10:18:36 2012 (r237765) @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <sys/disklabel.h> #include "bootstrap.h" #include "libi386.h" +#include "../zfs/libzfs.h" static int i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path); @@ -171,7 +172,6 @@ i386_parsedev(struct i386_devdesc **dev, case DEVT_CD: case DEVT_NET: - case DEVT_ZFS: unit = 0; if (*np && (*np != ':')) { @@ -192,7 +192,11 @@ i386_parsedev(struct i386_devdesc **dev, if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; break; - + case DEVT_ZFS: + err = zfs_parsedev((struct zfs_devdesc *)idev, np, path); + if (err != 0) + goto fail; + break; default: err = EINVAL; goto fail; @@ -247,9 +251,10 @@ i386_fmtdev(void *vdev) break; case DEVT_NET: - case DEVT_ZFS: sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); break; + case DEVT_ZFS: + return(zfs_fmtdev(vdev)); } return(buf); } Modified: stable/8/sys/boot/i386/libi386/libi386.h ============================================================================== --- stable/8/sys/boot/i386/libi386/libi386.h Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/i386/libi386/libi386.h Fri Jun 29 10:18:36 2012 (r237765) @@ -30,7 +30,8 @@ /* * i386 fully-qualified device descriptor. * Note, this must match the 'struct devdesc' declaration - * in bootstrap.h. + * in bootstrap.h and also with struct zfs_devdesc for zfs + * support. */ struct i386_devdesc { @@ -49,6 +50,12 @@ struct i386_devdesc { void *data; } bioscd; + struct + { + void *data; + uint64_t pool_guid; + uint64_t root_guid; + } zfs; } d_kind; }; Modified: stable/8/sys/boot/i386/loader/conf.c ============================================================================== --- stable/8/sys/boot/i386/loader/conf.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/i386/loader/conf.c Fri Jun 29 10:18:36 2012 (r237765) @@ -30,6 +30,9 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include <bootstrap.h> #include "libi386/libi386.h" +#if defined(LOADER_ZFS_SUPPORT) +#include "../zfs/libzfs.h" +#endif /* * We could use linker sets for some or all of these, but @@ -50,10 +53,6 @@ __FBSDID("$FreeBSD$"); extern struct devsw fwohci; #endif -#if defined(LOADER_ZFS_SUPPORT) -extern struct devsw zfs_dev; -#endif - /* Exported for libstand */ struct devsw *devsw[] = { &bioscd, @@ -70,10 +69,6 @@ struct devsw *devsw[] = { NULL }; -#if defined(LOADER_ZFS_SUPPORT) -extern struct fs_ops zfs_fsops; -#endif - struct fs_ops *file_system[] = { &ufs_fsops, &ext2fs_fsops, Modified: stable/8/sys/boot/i386/loader/main.c ============================================================================== --- stable/8/sys/boot/i386/loader/main.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/i386/loader/main.c Fri Jun 29 10:18:36 2012 (r237765) @@ -44,6 +44,10 @@ __FBSDID("$FreeBSD$"); #include "libi386/libi386.h" #include "btxv86.h" +#ifdef LOADER_ZFS_SUPPORT +#include "../zfs/libzfs.h" +#endif + CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE); CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO); CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS); @@ -62,6 +66,9 @@ static void extract_currdev(void); static int isa_inb(int port); static void isa_outb(int port, int value); void exit(int code); +#ifdef LOADER_ZFS_SUPPORT +static void i386_zfs_probe(void); +#endif /* from vers.c */ extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; @@ -153,6 +160,9 @@ main(void) archsw.arch_readin = i386_readin; archsw.arch_isainb = isa_inb; archsw.arch_isaoutb = isa_outb; +#ifdef LOADER_ZFS_SUPPORT + archsw.arch_zfs_probe = i386_zfs_probe; +#endif /* * March through the device switch probing for things. @@ -196,8 +206,11 @@ main(void) static void extract_currdev(void) { - struct i386_devdesc new_currdev; - int biosdev = -1; + struct i386_devdesc new_currdev; +#ifdef LOADER_ZFS_SUPPORT + struct zfs_boot_args *zargs; +#endif + int biosdev = -1; /* Assume we are booting from a BIOS disk by default */ new_currdev.d_dev = &biosdisk; @@ -218,6 +231,24 @@ extract_currdev(void) new_currdev.d_kind.biosdisk.partition = 0; biosdev = -1; } +#ifdef LOADER_ZFS_SUPPORT + } else if ((kargs->bootflags & KARGS_FLAGS_ZFS) != 0) { + zargs = NULL; + /* check for new style extended argument */ + if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0) + zargs = (struct zfs_boot_args *)(kargs + 1); + + if (zargs != NULL && zargs->size >= sizeof(*zargs)) { + /* sufficient data is provided */ + new_currdev.d_kind.zfs.pool_guid = zargs->pool; + new_currdev.d_kind.zfs.root_guid = zargs->root; + } else { + /* old style zfsboot block */ + new_currdev.d_kind.zfs.pool_guid = kargs->zfspool; + new_currdev.d_kind.zfs.root_guid = 0; + } + new_currdev.d_dev = &zfs_dev; +#endif } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) { /* The passed-in boot device is bad */ new_currdev.d_kind.biosdisk.slice = -1; @@ -238,7 +269,7 @@ extract_currdev(void) biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */ } new_currdev.d_type = new_currdev.d_dev->dv_type; - + /* * If we are booting off of a BIOS disk and we didn't succeed in determining * which one we booted off of, just use disk0: as a reasonable default. @@ -249,33 +280,11 @@ extract_currdev(void) "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev); new_currdev.d_unit = 0; } + env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev), i386_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset, env_nounset); - -#ifdef LOADER_ZFS_SUPPORT - /* - * If we were started from a ZFS-aware boot2, we can work out - * which ZFS pool we are booting from. - */ - if (kargs->bootflags & KARGS_FLAGS_ZFS) { - /* - * Dig out the pool guid and convert it to a 'unit number' - */ - uint64_t guid; - int unit; - char devname[32]; - extern int zfs_guid_to_unit(uint64_t); - - guid = kargs->zfspool; - unit = zfs_guid_to_unit(guid); - if (unit >= 0) { - sprintf(devname, "zfs%d", unit); - setenv("currdev", devname, 1); - } - } -#endif } COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); @@ -342,3 +351,30 @@ isa_outb(int port, int value) } } +#ifdef LOADER_ZFS_SUPPORT +static void +i386_zfs_probe(void) +{ + char devname[32]; + int unit, slice; + + /* + * Open all the disks we can find and see if we can reconstruct + * ZFS pools from them. Bogusly assumes that the disks are named + * diskN, diskNpM or diskNsM. + */ + for (unit = 0; unit < MAXBDDEV; unit++) { + sprintf(devname, "disk%d:", unit); + if (zfs_probe_dev(devname, NULL) == ENXIO) + continue; + for (slice = 1; slice <= 128; slice++) { + sprintf(devname, "disk%dp%d:", unit, slice); + zfs_probe_dev(devname, NULL); + } + for (slice = 1; slice <= 4; slice++) { + sprintf(devname, "disk%ds%d:", unit, slice); + zfs_probe_dev(devname, NULL); + } + } +} +#endif Modified: stable/8/sys/boot/i386/zfsboot/zfsboot.c ============================================================================== --- stable/8/sys/boot/i386/zfsboot/zfsboot.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/i386/zfsboot/zfsboot.c Fri Jun 29 10:18:36 2012 (r237765) @@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$"); #include "cons.h" #include "bootargs.h" +#include "libzfs.h" + #define PATH_DOTCONFIG "/boot.config" #define PATH_CONFIG "/boot/config" #define PATH_BOOT3 "/boot/zfsloader" @@ -91,9 +93,12 @@ static const unsigned char dev_maj[NDEV] static char cmd[512]; static char cmddup[512]; static char kname[1024]; +static char rootname[256]; static int comspeed = SIOSPD; static struct bootinfo bootinfo; static uint32_t bootdev; +static struct zfs_boot_args zfsargs; +static struct zfsmount zfsmount; vm_offset_t high_heap_base; uint32_t bios_basemem, bios_extmem, high_heap_size; @@ -170,7 +175,7 @@ zfs_read(spa_t *spa, const dnode_phys_t /* * Current ZFS pool */ -spa_t *spa; +static spa_t *spa; /* * A wrapper for dskread that doesn't have to worry about whether the @@ -209,7 +214,7 @@ static int xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte) { if ((size_t)zfs_read(spa, dnode, offp, buf, nbyte) != nbyte) { - printf("Invalid %s\n", "format"); + printf("Invalid format\n"); return -1; } return 0; @@ -524,10 +529,12 @@ main(void) } } - zfs_mount_pool(spa); - - if (zfs_lookup(spa, PATH_CONFIG, &dn) == 0 || - zfs_lookup(spa, PATH_DOTCONFIG, &dn) == 0) { + if (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0) { + printf("%s: failed to mount default pool %s\n", + BOOTPROG, spa->spa_name); + autoboot = 0; + } else if (zfs_lookup(&zfsmount, PATH_CONFIG, &dn) == 0 || + zfs_lookup(&zfsmount, PATH_DOTCONFIG, &dn) == 0) { off = 0; zfs_read(spa, &dn, &off, cmd, sizeof(cmd)); } @@ -562,11 +569,17 @@ main(void) /* Present the user with the boot2 prompt. */ for (;;) { - if (!autoboot || !OPT_CHECK(RBX_QUIET)) - printf("\nFreeBSD/x86 boot\n" - "Default: %s:%s\n" - "boot: ", - spa->spa_name, kname); + if (!autoboot || !OPT_CHECK(RBX_QUIET)) { + printf("\nFreeBSD/x86 boot\n"); + if (zfs_rlookup(spa, zfsmount.rootobj, rootname) != 0) + printf("Default: %s:<0x%llx>:%s\n" + "boot: ", + spa->spa_name, zfsmount.rootobj, kname); + else + printf("Default: %s:%s:%s\n" + "boot: ", + spa->spa_name, rootname, kname); + } if (ioctrl & IO_SERIAL) sio_flush(); if (!autoboot || keyhit(5)) @@ -602,7 +615,8 @@ load(void) uint32_t addr, x; int fmt, i, j; - if (zfs_lookup(spa, kname, &dn)) { + if (zfs_lookup(&zfsmount, kname, &dn)) { + printf("\nCan't find %s\n", kname); return; } off = 0; @@ -676,12 +690,16 @@ load(void) } bootinfo.bi_esymtab = VTOP(p); bootinfo.bi_kernelname = VTOP(kname); + zfsargs.size = sizeof(zfsargs); + zfsargs.pool = zfsmount.spa->spa_guid; + zfsargs.root = zfsmount.rootobj; __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), bootdev, - KARGS_FLAGS_ZFS, + KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, (uint32_t) spa->spa_guid, (uint32_t) (spa->spa_guid >> 32), - VTOP(&bootinfo)); + VTOP(&bootinfo), + zfsargs); } static int @@ -733,7 +751,7 @@ parse(void) } if (c == '?') { dnode_phys_t dn; - if (zfs_lookup(spa, arg, &dn) == 0) { + if (zfs_lookup(&zfsmount, arg, &dn) == 0) { zap_list(spa, &dn); } return -1; @@ -755,17 +773,32 @@ parse(void) q = (char *) strchr(arg, ':'); if (q) { spa_t *newspa; + uint64_t newroot; *q++ = 0; newspa = spa_find_by_name(arg); if (newspa) { + arg = q; spa = newspa; - zfs_mount_pool(spa); + newroot = 0; + q = (char *) strchr(arg, ':'); + if (q) { + *q++ = 0; + if (zfs_lookup_dataset(spa, arg, &newroot)) { + printf("\nCan't find dataset %s in ZFS pool %s\n", + arg, spa->spa_name); + return -1; + } + arg = q; + } + if (zfs_mount(spa, newroot, &zfsmount)) { + printf("\nCan't mount ZFS dataset\n"); + return -1; + } } else { printf("\nCan't find ZFS pool %s\n", arg); return -1; } - arg = q; } if ((i = ep - arg)) { if ((size_t)i >= sizeof(kname)) Modified: stable/8/sys/boot/ofw/libofw/Makefile ============================================================================== --- stable/8/sys/boot/ofw/libofw/Makefile Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/ofw/libofw/Makefile Fri Jun 29 10:18:36 2012 (r237765) @@ -6,6 +6,8 @@ INTERNALLIB= SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ ofw_time.c openfirm.c +.PATH: ${.CURDIR}/../../zfs +SRCS+= devicename_stubs.c CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ Modified: stable/8/sys/boot/ofw/libofw/devicename.c ============================================================================== --- stable/8/sys/boot/ofw/libofw/devicename.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/ofw/libofw/devicename.c Fri Jun 29 10:18:36 2012 (r237765) @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "libofw.h" +#include "../zfs/libzfs.h" static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **); @@ -81,6 +82,7 @@ ofw_parsedev(struct ofw_devdesc **dev, c char *ep; char name[256]; char type[64]; + int err; int len; int i; @@ -114,14 +116,11 @@ found: idev->d_dev = dv; idev->d_type = dv->dv_type; if (idev->d_type == DEVT_ZFS) { - idev->d_unit = 0; - p = name + strlen(dv->dv_name); - if (*p && (*p != ':')) { - idev->d_unit = strtol(p, &ep, 0); - if (ep == p) { - free(idev); - return (EUNIT); - } + p = devspec + strlen(dv->dv_name); + err = zfs_parsedev((struct zfs_devdesc *)idev, p, path); + if (err != 0) { + free(idev); + return (err); } } Modified: stable/8/sys/boot/ofw/libofw/libofw.h ============================================================================== --- stable/8/sys/boot/ofw/libofw/libofw.h Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/ofw/libofw/libofw.h Fri Jun 29 10:18:36 2012 (r237765) @@ -33,7 +33,13 @@ struct ofw_devdesc { int d_type; int d_unit; ihandle_t d_handle; - char d_path[256]; + union { + char d_path[256]; + struct { + uint64_t pool_guid; + uint64_t root_guid; + }; + }; }; extern int ofw_getdev(void **vdev, const char *devspec, const char **path); Modified: stable/8/sys/boot/sparc64/loader/Makefile ============================================================================== --- stable/8/sys/boot/sparc64/loader/Makefile Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/sparc64/loader/Makefile Fri Jun 29 10:18:36 2012 (r237765) @@ -37,6 +37,7 @@ CFLAGS+= -DLOADER_CD9660_SUPPORT CFLAGS+= -DLOADER_ZFS_SUPPORT CFLAGS+= -I${.CURDIR}/../../zfs CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs +LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a .endif .if ${LOADER_GZIP_SUPPORT} == "yes" CFLAGS+= -DLOADER_GZIP_SUPPORT @@ -83,8 +84,8 @@ CFLAGS+= -I${.CURDIR}/../../ofw/libofw/ # where to get libstand from CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ -DPADD= ${LIBFICL} ${LIBOFW} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBOFW} -lstand +DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} -lstand vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version \ Modified: stable/8/sys/boot/sparc64/loader/main.c ============================================================================== --- stable/8/sys/boot/sparc64/loader/main.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/sparc64/loader/main.c Fri Jun 29 10:18:36 2012 (r237765) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #ifdef LOADER_ZFS_SUPPORT #include <sys/vtoc.h> +#include "../zfs/libzfs.h" #endif #include <vm/vm.h> @@ -74,6 +75,8 @@ __FBSDID("$FreeBSD$"); #include "libofw.h" #include "dev_net.h" +#define MAXDEV 31 + extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; enum { @@ -154,11 +157,6 @@ static vm_offset_t heapva; static phandle_t root; -#ifdef LOADER_ZFS_SUPPORT -static int zfs_dev_init(void); -#include "zfs.c" -#endif - /* * Machine dependent structures that the machine independent * loader part uses. @@ -838,39 +836,20 @@ tlb_init_sun4v(void) } #ifdef LOADER_ZFS_SUPPORT - -static int -zfs_dev_init(void) +static void +sparc64_zfs_probe(void) { struct vtoc8 vtoc; - char devname[512]; - spa_t *spa; - vdev_t *vdev; + struct zfs_devdesc zfs_currdev; + char devname[32]; uint64_t guid; int fd, part, unit; - zfs_init(); - - guid = 0; /* Get the GUID of the ZFS pool on the boot device. */ - fd = open(getenv("currdev"), O_RDONLY); - if (fd != -1) { - if (vdev_probe(vdev_read, (void *)(uintptr_t) fd, &spa) == 0) - guid = spa->spa_guid; - close(fd); - } - - /* Clean up the environment to let ZFS work. */ - while ((vdev = STAILQ_FIRST(&zfs_vdevs)) != NULL) { - STAILQ_REMOVE_HEAD(&zfs_vdevs, v_alllink); - free(vdev); - } - while ((spa = STAILQ_FIRST(&zfs_pools)) != NULL) { - STAILQ_REMOVE_HEAD(&zfs_pools, spa_link); - free(spa); - } + guid = 0; + zfs_probe_dev(getenv("currdev"), &guid); - for (unit = 0; unit < MAXBDDEV; unit++) { + for (unit = 0; unit < MAXDEV; unit++) { /* Find freebsd-zfs slices in the VTOC. */ sprintf(devname, "disk%d:", unit); fd = open(devname, O_RDONLY); @@ -888,29 +867,23 @@ zfs_dev_init(void) VTOC_TAG_FREEBSD_ZFS) continue; sprintf(devname, "disk%d:%c", unit, part + 'a'); - fd = open(devname, O_RDONLY); - if (fd == -1) + if (zfs_probe_dev(devname, NULL) == ENXIO) break; - - if (vdev_probe(vdev_read, (void*)(uintptr_t) fd, 0)) - close(fd); } } if (guid != 0) { - unit = zfs_guid_to_unit(guid); - if (unit >= 0) { - /* Update the environment for ZFS. */ - sprintf(devname, "zfs%d", unit); - env_setenv("currdev", EV_VOLATILE, devname, - ofw_setcurrdev, env_nounset); - env_setenv("loaddev", EV_VOLATILE, devname, - env_noset, env_nounset); - } + zfs_currdev.pool_guid = guid; + zfs_currdev.root_guid = 0; + zfs_currdev.d_dev = &zfs_dev; + zfs_currdev.d_type = zfs_currdev.d_dev->dv_type; + /* Update the environment for ZFS. */ + env_setenv("currdev", EV_VOLATILE, zfs_fmtdev(&zfs_currdev), + ofw_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, zfs_fmtdev(&zfs_currdev), + env_noset, env_nounset); } - return (0); } - #endif /* LOADER_ZFS_SUPPORT */ int @@ -931,6 +904,9 @@ main(int (*openfirm)(void *)) archsw.arch_readin = sparc64_readin; archsw.arch_autoload = sparc64_autoload; archsw.arch_maphint = sparc64_maphint; +#ifdef LOADER_ZFS_SUPPORT + archsw.arch_zfs_probe = sparc64_zfs_probe; +#endif if (init_heap() == (vm_offset_t)-1) OF_exit(); Copied: stable/8/sys/boot/zfs/devicename_stubs.c (from r235329, head/sys/boot/zfs/devicename_stubs.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/8/sys/boot/zfs/devicename_stubs.c Fri Jun 29 10:18:36 2012 (r237765, copy of r235329, head/sys/boot/zfs/devicename_stubs.c) @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include "libzfs.h" + +__attribute__((weak)) +int +zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) +{ + return (EINVAL); +} + +__attribute__((weak)) +char * +zfs_fmtdev(void *vdev) +{ + static char buf[128]; + + return (buf); +} Copied: stable/8/sys/boot/zfs/libzfs.h (from r235329, head/sys/boot/zfs/libzfs.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/8/sys/boot/zfs/libzfs.h Fri Jun 29 10:18:36 2012 (r237765, copy of r235329, head/sys/boot/zfs/libzfs.h) @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _BOOT_LIBZFS_H_ +#define _BOOT_LIBZFS_H_ + +#define ZFS_MAXNAMELEN 256 + +/* + * ZFS fully-qualified device descriptor. + * Note, this must match the 'struct devdesc' declaration in bootstrap.h. + * Arch-specific device descriptors should be binary compatible with this + * structure if they are to support ZFS. + */ +struct zfs_devdesc +{ + struct devsw *d_dev; + int d_type; + int d_unit; + void *d_opendata; + uint64_t pool_guid; + uint64_t root_guid; +}; + +struct zfs_boot_args +{ + uint32_t size; + uint32_t reserved; + uint64_t pool; + uint64_t root; +}; + +int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, + const char **path); +char *zfs_fmtdev(void *vdev); +int zfs_probe_dev(const char *devname, uint64_t *pool_guid); + +extern struct devsw zfs_dev; +extern struct fs_ops zfs_fsops; + +#endif /*_BOOT_LIBZFS_H_*/ Modified: stable/8/sys/boot/zfs/zfs.c ============================================================================== --- stable/8/sys/boot/zfs/zfs.c Fri Jun 29 10:12:27 2012 (r237764) +++ stable/8/sys/boot/zfs/zfs.c Fri Jun 29 10:18:36 2012 (r237765) @@ -43,9 +43,9 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include <bootstrap.h> -#include "zfsimpl.c" +#include "libzfs.h" -#define MAXBDDEV 31 +#include "zfsimpl.c" static int zfs_open(const char *path, struct open_file *f); static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); @@ -56,6 +56,7 @@ static int zfs_stat(struct open_file *f, static int zfs_readdir(struct open_file *f, struct dirent *d); struct devsw zfs_dev; +struct devsw zfs_dev_compat; struct fs_ops zfs_fsops = { "zfs", @@ -85,35 +86,20 @@ struct file { static int zfs_open(const char *upath, struct open_file *f) { - spa_t *spa = (spa_t *) f->f_devdata; + struct zfsmount *mount = (struct zfsmount *)f->f_devdata; struct file *fp; int rc; - if (f->f_dev != &zfs_dev) + if (f->f_dev != &zfs_dev && f->f_dev != &zfs_dev_compat) return (EINVAL); - rc = zfs_mount_pool(spa); - if (rc) - return (rc); - /* allocate file system specific data structure */ fp = malloc(sizeof(struct file)); bzero(fp, sizeof(struct file)); f->f_fsdata = (void *)fp; - if (spa->spa_root_objset.os_type != DMU_OST_ZFS) { - printf("Unexpected object set type %llu\n", - spa->spa_root_objset.os_type); - rc = EIO; - goto out; - } - - rc = zfs_lookup(spa, upath, &fp->f_dnode); - if (rc) - goto out; - + rc = zfs_lookup(mount, upath, &fp->f_dnode); fp->f_seekp = 0; -out: if (rc) { f->f_fsdata = NULL; free(fp); @@ -142,7 +128,7 @@ zfs_close(struct open_file *f) static int zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */) { - spa_t *spa = (spa_t *) f->f_devdata; + spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; struct file *fp = (struct file *)f->f_fsdata; struct stat sb; size_t n; @@ -216,7 +202,7 @@ zfs_seek(struct open_file *f, off_t offs static int zfs_stat(struct open_file *f, struct stat *sb) { - spa_t *spa = (spa_t *) f->f_devdata; + spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; struct file *fp = (struct file *)f->f_fsdata; return (zfs_dnode_stat(spa, &fp->f_dnode, sb)); @@ -225,7 +211,7 @@ zfs_stat(struct open_file *f, struct sta static int zfs_readdir(struct open_file *f, struct dirent *d) { - spa_t *spa = (spa_t *) f->f_devdata; + spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; struct file *fp = (struct file *)f->f_fsdata; mzap_ent_phys_t mze; struct stat sb; @@ -381,68 +367,33 @@ vdev_read(vdev_t *vdev, void *priv, off_ } } -/* - * Convert a pool guid to a 'unit number' suitable for use with zfs_dev_open. - */ -int -zfs_guid_to_unit(uint64_t guid) +static int +zfs_dev_init(void) { - spa_t *spa; - int unit; - - unit = 0; - STAILQ_FOREACH(spa, &zfs_pools, spa_link) { - if (spa->spa_guid == guid) - return unit; - unit++; - } - return (-1); + zfs_init(); + if (archsw.arch_zfs_probe == NULL) + return (ENXIO); + archsw.arch_zfs_probe(); + return (0); } -#if defined(__amd64__) || defined(__i386__) -static int -zfs_dev_init(void) +int +zfs_probe_dev(const char *devname, uint64_t *pool_guid) { - char devname[512]; - int unit, slice; + spa_t *spa; int fd; + int ret; - /* - * Open all the disks we can find and see if we can reconstruct - * ZFS pools from them. Bogusly assumes that the disks are named - * diskN, diskNpM or diskNsM. - */ - zfs_init(); - for (unit = 0; unit < MAXBDDEV; unit++) { - sprintf(devname, "disk%d:", unit); - fd = open(devname, O_RDONLY); - if (fd == -1) - continue; - - /* - * If we find a vdev, the zfs code will eat the fd, otherwise - * we close it. - */ - if (vdev_probe(vdev_read, (void*) (uintptr_t) fd, 0)) - close(fd); - - for (slice = 1; slice <= 128; slice++) { - sprintf(devname, "disk%dp%d:", unit, slice); - fd = open(devname, O_RDONLY); - if (fd == -1) { - sprintf(devname, "disk%ds%d:", unit, slice); - fd = open(devname, O_RDONLY); - if (fd == -1) - continue; - } - if (vdev_probe(vdev_read, (void*) (uintptr_t) fd, 0)) - close(fd); - } - } - + fd = open(devname, O_RDONLY); + if (fd == -1) + return (ENXIO); + ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa); + if (ret != 0) + close(fd); + else if (pool_guid != NULL) + *pool_guid = spa->spa_guid; return (0); } -#endif /* * Print information about ZFS pools @@ -452,54 +403,52 @@ zfs_dev_print(int verbose) { spa_t *spa; char line[80]; - int unit; if (verbose) { spa_all_status(); return; } - unit = 0; STAILQ_FOREACH(spa, &zfs_pools, spa_link) { - sprintf(line, " zfs%d: %s\n", unit, spa->spa_name); + sprintf(line, " zfs:%s\n", spa->spa_name); pager_output(line); - unit++; } } /* * Attempt to open the pool described by (dev) for use by (f). */ -static int +static int zfs_dev_open(struct open_file *f, ...) { va_list args; - struct devdesc *dev; - int unit, i; + struct zfs_devdesc *dev; + struct zfsmount *mount; spa_t *spa; + int rv; va_start(args, f); - dev = va_arg(args, struct devdesc*); + dev = va_arg(args, struct zfs_devdesc *); va_end(args); - /* - * We mostly ignore the stuff that devopen sends us. For now, - * use the unit to find a pool - later we will override the - * devname parsing so that we can name a pool and a fs within - * the pool. - */ - unit = dev->d_unit; - - i = 0; - STAILQ_FOREACH(spa, &zfs_pools, spa_link) { - if (i == unit) - break; - i++; - } - if (!spa) { + spa = spa_find_by_guid(dev->pool_guid); + if (!spa) return (ENXIO); + rv = zfs_spa_init(spa); + if (rv != 0) + return (rv); + mount = malloc(sizeof(*mount)); + rv = zfs_mount(spa, dev->root_guid, mount); + if (rv != 0) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206291018.q5TAIaIL039322>