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