svn commit: r237766 - in stable/9/sys: boot boot/common
boot/i386/libi386 boot/i386/loader boot/i386/zfsboot
boot/ofw/libofw boot/sparc64/loader boot/zfs cddl/boot/zfs
Andriy Gapon
avg at FreeBSD.org
Fri Jun 29 10:19:16 UTC 2012
Author: avg
Date: Fri Jun 29 10:19:15 2012
New Revision: 237766
URL: http://svn.freebsd.org/changeset/base/237766
Log:
MFC r235329,235343,235361,235364: zfsboot/zfsloader: support accessing
filesystems within a pool
Added:
stable/9/sys/boot/zfs/devicename_stubs.c
- copied unchanged from r235329, head/sys/boot/zfs/devicename_stubs.c
stable/9/sys/boot/zfs/libzfs.h
- copied unchanged from r235329, head/sys/boot/zfs/libzfs.h
Modified:
stable/9/sys/boot/Makefile.sparc64
stable/9/sys/boot/common/bootstrap.h
stable/9/sys/boot/i386/libi386/Makefile
stable/9/sys/boot/i386/libi386/devicename.c
stable/9/sys/boot/i386/libi386/libi386.h
stable/9/sys/boot/i386/loader/conf.c
stable/9/sys/boot/i386/loader/main.c
stable/9/sys/boot/i386/zfsboot/zfsboot.c
stable/9/sys/boot/ofw/libofw/Makefile
stable/9/sys/boot/ofw/libofw/devicename.c
stable/9/sys/boot/ofw/libofw/libofw.h
stable/9/sys/boot/sparc64/loader/Makefile
stable/9/sys/boot/sparc64/loader/main.c
stable/9/sys/boot/zfs/zfs.c
stable/9/sys/boot/zfs/zfsimpl.c
stable/9/sys/cddl/boot/zfs/zfsimpl.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/dev/e1000/ (props changed)
stable/9/sys/dev/isp/ (props changed)
stable/9/sys/dev/ixgbe/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/sys/boot/Makefile.sparc64
==============================================================================
--- stable/9/sys/boot/Makefile.sparc64 Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/Makefile.sparc64 Fri Jun 29 10:19:15 2012 (r237766)
@@ -1,3 +1,4 @@
# $FreeBSD$
SUBDIR+= ofw
+SUBDIR+= zfs
Modified: stable/9/sys/boot/common/bootstrap.h
==============================================================================
--- stable/9/sys/boot/common/bootstrap.h Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/common/bootstrap.h Fri Jun 29 10:19:15 2012 (r237766)
@@ -317,6 +317,9 @@ struct arch_switch
#else
void (*arch_loadseg)(void *eh, void *ph, uint64_t delta);
#endif
+
+ /* Probe ZFS pool(s), if needed. */
+ void (*arch_zfs_probe)(void);
};
extern struct arch_switch archsw;
Modified: stable/9/sys/boot/i386/libi386/Makefile
==============================================================================
--- stable/9/sys/boot/i386/libi386/Makefile Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/i386/libi386/Makefile Fri Jun 29 10:19:15 2012 (r237766)
@@ -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 spinconsole.c
+.PATH: ${.CURDIR}/../../zfs
+SRCS+= devicename_stubs.c
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
Modified: stable/9/sys/boot/i386/libi386/devicename.c
==============================================================================
--- stable/9/sys/boot/i386/libi386/devicename.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/i386/libi386/devicename.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/i386/libi386/libi386.h
==============================================================================
--- stable/9/sys/boot/i386/libi386/libi386.h Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/i386/libi386/libi386.h Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/i386/loader/conf.c
==============================================================================
--- stable/9/sys/boot/i386/loader/conf.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/i386/loader/conf.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/i386/loader/main.c
==============================================================================
--- stable/9/sys/boot/i386/loader/main.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/i386/loader/main.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/i386/zfsboot/zfsboot.c
==============================================================================
--- stable/9/sys/boot/i386/zfsboot/zfsboot.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/i386/zfsboot/zfsboot.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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;
@@ -529,10 +534,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));
}
@@ -567,11 +574,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))
@@ -607,7 +620,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;
@@ -681,12 +695,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
@@ -738,7 +756,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;
@@ -760,17 +778,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/9/sys/boot/ofw/libofw/Makefile
==============================================================================
--- stable/9/sys/boot/ofw/libofw/Makefile Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/ofw/libofw/Makefile Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/ofw/libofw/devicename.c
==============================================================================
--- stable/9/sys/boot/ofw/libofw/devicename.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/ofw/libofw/devicename.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/ofw/libofw/libofw.h
==============================================================================
--- stable/9/sys/boot/ofw/libofw/libofw.h Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/ofw/libofw/libofw.h Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/sparc64/loader/Makefile
==============================================================================
--- stable/9/sys/boot/sparc64/loader/Makefile Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/sparc64/loader/Makefile Fri Jun 29 10:19:15 2012 (r237766)
@@ -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/9/sys/boot/sparc64/loader/main.c
==============================================================================
--- stable/9/sys/boot/sparc64/loader/main.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/sparc64/loader/main.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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 {
@@ -140,11 +143,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.
@@ -731,39 +729,20 @@ tlb_init_sun4u(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);
@@ -781,29 +760,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
@@ -823,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();
Copied: stable/9/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/9/sys/boot/zfs/devicename_stubs.c Fri Jun 29 10:19:15 2012 (r237766, copy of r235329, head/sys/boot/zfs/devicename_stubs.c)
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg at 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/9/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/9/sys/boot/zfs/libzfs.h Fri Jun 29 10:19:15 2012 (r237766, copy of r235329, head/sys/boot/zfs/libzfs.h)
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg at 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/9/sys/boot/zfs/zfs.c
==============================================================================
--- stable/9/sys/boot/zfs/zfs.c Fri Jun 29 10:18:36 2012 (r237765)
+++ stable/9/sys/boot/zfs/zfs.c Fri Jun 29 10:19:15 2012 (r237766)
@@ -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)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-9
mailing list