commit d8b6a43b465f9109bd288d8b216c52fa77bd6aa4 Author: Andriy Gapon Date: Tue May 8 11:23:29 2012 +0300 spar64/zfs boot: try to take advantage of new libzfsboot capabilities diff --git a/sys/boot/Makefile.sparc64 b/sys/boot/Makefile.sparc64 index 5723629..1064a26 100644 --- a/sys/boot/Makefile.sparc64 +++ b/sys/boot/Makefile.sparc64 @@ -1,3 +1,4 @@ # $FreeBSD$ SUBDIR+= ofw +SUBDIR+= zfs diff --git a/sys/boot/ofw/libofw/Makefile b/sys/boot/ofw/libofw/Makefile index 945d650..e207eca 100644 --- a/sys/boot/ofw/libofw/Makefile +++ b/sys/boot/ofw/libofw/Makefile @@ -6,6 +6,7 @@ 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 +SRCS+= ../../zfs/devicename_stubs.c CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ diff --git a/sys/boot/ofw/libofw/devicename.c b/sys/boot/ofw/libofw/devicename.c index c2d9ef1..bbacb84 100644 --- a/sys/boot/ofw/libofw/devicename.c +++ b/sys/boot/ofw/libofw/devicename.c @@ -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, const char *devspec, const char **path) 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); } } diff --git a/sys/boot/ofw/libofw/libofw.h b/sys/boot/ofw/libofw/libofw.h index 5f6d7ad..87e9095 100644 --- a/sys/boot/ofw/libofw/libofw.h +++ b/sys/boot/ofw/libofw/libofw.h @@ -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); diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile index 27359b2..0a3b753 100644 --- a/sys/boot/sparc64/loader/Makefile +++ b/sys/boot/sparc64/loader/Makefile @@ -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 \ diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c index 14cf6d6..3da7ea5 100644 --- a/sys/boot/sparc64/loader/main.c +++ b/sys/boot/sparc64/loader/main.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef LOADER_ZFS_SUPPORT #include +#include "../zfs/libzfs.h" #endif #include @@ -74,7 +75,7 @@ __FBSDID("$FreeBSD$"); #include "libofw.h" #include "dev_net.h" -#define MAXBDDEV 31 +#define MAXDEV 31 extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; @@ -142,11 +143,6 @@ static vm_offset_t heapva; static phandle_t root; -#ifdef LOADER_ZFS_SUPPORT -static int sparc64_zfs_dev_init(void); -#include "zfs.c" -#endif - /* * Machine dependent structures that the machine independent * loader part uses. @@ -159,7 +155,7 @@ struct devsw *devsw[] = { &netdev, #endif #ifdef LOADER_ZFS_SUPPORT - &zfs_dev_compat, + &zfs_dev, #endif 0 }; @@ -733,39 +729,20 @@ tlb_init_sun4u(void) } #ifdef LOADER_ZFS_SUPPORT - -static int -sparc64_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); @@ -783,29 +760,23 @@ sparc64_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 @@ -825,6 +796,9 @@ main(int (*openfirm)(void *)) archsw.arch_copyout = ofw_copyout; archsw.arch_readin = sparc64_readin; archsw.arch_autoload = sparc64_autoload; +#ifdef LOADER_ZFS_SUPPORT + archsw.arch_zfs_probe = sparc64_zfs_probe; +#endif if (init_heap() == (vm_offset_t)-1) OF_exit(); @@ -870,13 +844,6 @@ main(int (*openfirm)(void *)) env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); -#ifdef LOADER_ZFS_SUPPORT - /* - * Patch up ZFS. - */ - zfs_dev_compat.dv_init = sparc64_zfs_dev_init; -#endif - /* * Initialize devices. */ diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c index de8f630..37938d9 100644 --- a/sys/boot/zfs/zfs.c +++ b/sys/boot/zfs/zfs.c @@ -417,16 +417,29 @@ zfs_dev_print(int verbose) * Attempt to open the pool described by (dev) for use by (f). */ static int -zfs_dev_open_spa(struct open_file *f, spa_t *spa, uint64_t root_guid) +zfs_dev_open(struct open_file *f, ...) { + va_list args; + struct zfs_devdesc *dev; struct zfsmount *mount; + spa_t *spa; int rv; + va_start(args, f); + dev = va_arg(args, struct zfs_devdesc *); + va_end(args); + + if (dev->pool_guid == 0) + spa = STAILQ_FIRST(&zfs_pools); + else + 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, root_guid, mount); + rv = zfs_mount(spa, dev->root_guid, mount); if (rv != 0) { free(mount); return (rv); @@ -438,52 +451,6 @@ zfs_dev_open_spa(struct open_file *f, spa_t *spa, uint64_t root_guid) return (EIO); } f->f_devdata = mount; - return (0); -} - -static int -zfs_dev_open(struct open_file *f, ...) -{ - va_list args; - struct zfs_devdesc *dev; - spa_t *spa; - int rv; - - va_start(args, f); - dev = va_arg(args, struct zfs_devdesc *); - va_end(args); - - if (dev->pool_guid == 0) - spa = STAILQ_FIRST(&zfs_pools); - else - spa = spa_find_by_guid(dev->pool_guid); - if (!spa) - return (ENXIO); - rv = zfs_dev_open_spa(f, spa, dev->root_guid); - if (rv != 0) - return (rv); - free(dev); - return (0); -} - -static int -zfs_dev_open_compat(struct open_file *f, ...) -{ - va_list args; - struct devdesc *dev; - spa_t *spa; - int rv; - - va_start(args, f); - dev = va_arg(args, struct devdesc *); - va_end(args); - - spa = spa_find_by_unit(dev->d_unit); - if (!spa) - return (ENXIO); - rv = zfs_dev_open_spa(f, spa, 0); - if (rv != 0) - return (rv); free(dev); return (0); } @@ -516,18 +483,6 @@ struct devsw zfs_dev = { .dv_cleanup = NULL }; -struct devsw zfs_dev_compat = { - .dv_name = "zfs", - .dv_type = DEVT_ZFS, - .dv_init = zfs_dev_init, - .dv_strategy = zfs_dev_strategy, - .dv_open = zfs_dev_open_compat, - .dv_close = zfs_dev_close, - .dv_ioctl = noioctl, - .dv_print = zfs_dev_print, - .dv_cleanup = NULL -}; - int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) { diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index 4bd6800..1ad3057 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -645,38 +645,6 @@ spa_find_by_name(const char *name) return (0); } -#ifndef BOOT2 -static spa_t * -spa_find_by_unit(int unit) -{ - spa_t *spa; - - STAILQ_FOREACH(spa, &zfs_pools, spa_link) { - if (unit == 0) - return (spa); - unit--; - } - - return (0); -} - -static int -zfs_guid_to_unit(uint64_t guid) -{ - spa_t *spa; - int unit; - - unit = 0; - STAILQ_FOREACH(spa, &zfs_pools, spa_link) { - if (spa->spa_guid == guid) - return (unit); - unit++; - } - - return (0); -} -#endif - #ifdef BOOT2 static spa_t * spa_get_primary(void)