summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-07-20 22:54:03 +0000
committerjhb <jhb@FreeBSD.org>2014-07-20 22:54:03 +0000
commit25b41d088263e9d1574521319b2e37df9842fd2f (patch)
tree04e404b73937ec33991b2d714889ca71f09f1394 /sys/boot
parent9822066797603d4d23201ae909b4fe3ff8c85fb2 (diff)
downloadFreeBSD-src-25b41d088263e9d1574521319b2e37df9842fd2f.zip
FreeBSD-src-25b41d088263e9d1574521319b2e37df9842fd2f.tar.gz
MFC 262331,262487,262495,262523:
ZFS boot support for bhyveload.
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/userboot/Makefile2
-rw-r--r--sys/boot/userboot/userboot/Makefile9
-rw-r--r--sys/boot/userboot/userboot/conf.c10
-rw-r--r--sys/boot/userboot/userboot/devicename.c22
-rw-r--r--sys/boot/userboot/userboot/main.c89
-rw-r--r--sys/boot/userboot/zfs/Makefile18
6 files changed, 135 insertions, 15 deletions
diff --git a/sys/boot/userboot/Makefile b/sys/boot/userboot/Makefile
index f15c905..ebacf64 100644
--- a/sys/boot/userboot/Makefile
+++ b/sys/boot/userboot/Makefile
@@ -2,7 +2,7 @@
.include <bsd.own.mk>
-SUBDIR= ficl libstand test userboot
+SUBDIR= ficl libstand test zfs userboot
.include <bsd.subdir.mk>
diff --git a/sys/boot/userboot/userboot/Makefile b/sys/boot/userboot/userboot/Makefile
index 076b4b2..aad2e0f 100644
--- a/sys/boot/userboot/userboot/Makefile
+++ b/sys/boot/userboot/userboot/Makefile
@@ -51,12 +51,17 @@ LIBFICL= ${.OBJDIR}/../ficl/libficl.a
LIBSTAND= ${.OBJDIR}/../libstand/libstand.a
.endif
+.if ${MK_ZFS} != "no"
+CFLAGS+= -DUSERBOOT_ZFS_SUPPORT
+LIBZFSBOOT= ${.OBJDIR}/../zfs/libzfsboot.a
+.endif
+
# Always add MI sources
.PATH: ${.CURDIR}/../../common
.include "${.CURDIR}/../../common/Makefile.inc"
CFLAGS+= -I${.CURDIR}/../../common
CFLAGS+= -I.
-DPADD= ${LIBFICL} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBSTAND}
+DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSTAND}
+LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSTAND}
.include <bsd.lib.mk>
diff --git a/sys/boot/userboot/userboot/conf.c b/sys/boot/userboot/userboot/conf.c
index 2a98434..5eac87da 100644
--- a/sys/boot/userboot/userboot/conf.c
+++ b/sys/boot/userboot/userboot/conf.c
@@ -38,6 +38,10 @@ __FBSDID("$FreeBSD$");
#include "libuserboot.h"
+#if defined(USERBOOT_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+#endif
+
/*
* We could use linker sets for some or all of these, but
* then we would have to control what ended up linked into
@@ -51,6 +55,9 @@ __FBSDID("$FreeBSD$");
struct devsw *devsw[] = {
&host_dev,
&userboot_disk,
+#if defined(USERBOOT_ZFS_SUPPORT)
+ &zfs_dev,
+#endif
NULL
};
@@ -59,6 +66,9 @@ struct fs_ops *file_system[] = {
&ufs_fsops,
&cd9660_fsops,
&gzipfs_fsops,
+#if defined(USERBOOT_ZFS_SUPPORT)
+ &zfs_fsops,
+#endif
NULL
};
diff --git a/sys/boot/userboot/userboot/devicename.c b/sys/boot/userboot/userboot/devicename.c
index d54d023..8569ed4 100644
--- a/sys/boot/userboot/userboot/devicename.c
+++ b/sys/boot/userboot/userboot/devicename.c
@@ -34,6 +34,10 @@ __FBSDID("$FreeBSD$");
#include "disk.h"
#include "libuserboot.h"
+#if defined(USERBOOT_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+#endif
+
static int userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **path);
/*
@@ -119,7 +123,6 @@ userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **p
case DEVT_CD:
case DEVT_NET:
- case DEVT_ZFS:
unit = 0;
if (*np && (*np != ':')) {
@@ -141,6 +144,16 @@ userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **p
*path = (*cp == 0) ? cp : cp + 1;
break;
+ case DEVT_ZFS:
+#if defined(USERBOOT_ZFS_SUPPORT)
+ err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
+#else
+ /* FALLTHROUGH */
+#endif
+
default:
err = EINVAL;
goto fail;
@@ -179,8 +192,15 @@ userboot_fmtdev(void *vdev)
return (disk_fmtdev(vdev));
case DEVT_NET:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+
case DEVT_ZFS:
+#if defined(USERBOOT_ZFS_SUPPORT)
+ return (zfs_fmtdev(vdev));
+#else
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+#endif
break;
}
return(buf);
diff --git a/sys/boot/userboot/userboot/main.c b/sys/boot/userboot/userboot/main.c
index 39f6012..c9353ab 100644
--- a/sys/boot/userboot/userboot/main.c
+++ b/sys/boot/userboot/userboot/main.c
@@ -36,8 +36,17 @@ __FBSDID("$FreeBSD$");
#include "disk.h"
#include "libuserboot.h"
+#if defined(USERBOOT_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+
+static void userboot_zfs_probe(void);
+static int userboot_zfs_found;
+#endif
+
#define USERBOOT_VERSION USERBOOT_VERSION_3
+#define MALLOCSZ (10*1024*1024)
+
struct loader_callbacks *callbacks;
void *callbacks_arg;
@@ -69,7 +78,7 @@ exit(int v)
void
loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks)
{
- static char malloc[1024*1024];
+ static char mallocbuf[MALLOCSZ];
const char *var;
int i;
@@ -82,23 +91,15 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks)
/*
* initialise the heap as early as possible. Once this is done,
- * alloc() is usable. The stack is buried inside us, so this is
- * safe.
+ * alloc() is usable.
*/
- setheap((void *)malloc, (void *)(malloc + 1024*1024));
+ setheap((void *)mallocbuf, (void *)(mallocbuf + sizeof(mallocbuf)));
/*
* Hook up the console
*/
cons_probe();
- /*
- * March through the device switch probing for things.
- */
- for (i = 0; devsw[i] != NULL; i++)
- if (devsw[i]->dv_init != NULL)
- (devsw[i]->dv_init)();
-
printf("\n");
printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
@@ -124,6 +125,16 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks)
archsw.arch_copyin = userboot_copyin;
archsw.arch_copyout = userboot_copyout;
archsw.arch_readin = userboot_readin;
+#if defined(USERBOOT_ZFS_SUPPORT)
+ archsw.arch_zfs_probe = userboot_zfs_probe;
+#endif
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
extract_currdev();
@@ -146,6 +157,19 @@ extract_currdev(void)
//bzero(&dev, sizeof(dev));
+#if defined(USERBOOT_ZFS_SUPPORT)
+ if (userboot_zfs_found) {
+ struct zfs_devdesc zdev;
+
+ /* Leave the pool/root guid's unassigned */
+ bzero(&zdev, sizeof(zdev));
+ zdev.d_dev = &zfs_dev;
+ zdev.d_type = zdev.d_dev->dv_type;
+
+ dev = *(struct disk_devdesc *)&zdev;
+ } else
+#endif
+
if (userboot_disk_maxunit > 0) {
dev.d_dev = &userboot_disk;
dev.d_type = dev.d_dev->dv_type;
@@ -172,6 +196,49 @@ extract_currdev(void)
env_noset, env_nounset);
}
+#if defined(USERBOOT_ZFS_SUPPORT)
+static void
+userboot_zfs_probe(void)
+{
+ char devname[32];
+ uint64_t pool_guid;
+ int unit;
+
+ /*
+ * Open all the disks we can find and see if we can reconstruct
+ * ZFS pools from them. Record if any were found.
+ */
+ for (unit = 0; unit < userboot_disk_maxunit; unit++) {
+ sprintf(devname, "disk%d:", unit);
+ pool_guid = 0;
+ zfs_probe_dev(devname, &pool_guid);
+ if (pool_guid != 0)
+ userboot_zfs_found = 1;
+ }
+}
+
+COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
+ command_lszfs);
+
+static int
+command_lszfs(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "a single dataset must be supplied";
+ return (CMD_ERROR);
+ }
+
+ err = zfs_list(argv[1]);
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+#endif /* USERBOOT_ZFS_SUPPORT */
+
COMMAND_SET(quit, "quit", "exit the loader", command_quit);
static int
diff --git a/sys/boot/userboot/zfs/Makefile b/sys/boot/userboot/zfs/Makefile
new file mode 100644
index 0000000..8fe315b
--- /dev/null
+++ b/sys/boot/userboot/zfs/Makefile
@@ -0,0 +1,18 @@
+# $FreeBSD$
+
+S= ${.CURDIR}/../../zfs
+
+.PATH: ${S}
+LIB= zfsboot
+INTERNALLIB=
+
+SRCS+= zfs.c
+
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+
+CFLAGS+= -ffreestanding -fPIC
+CFLAGS+= -Wformat -Wall
+
+.include <bsd.lib.mk>
OpenPOWER on IntegriCloud