zfs boot: export boot/primary pool and vdev guid all the way to kenv
This is work in progress to for znextboot and it also provides some convenient infrastructure. MFC after: 20 days
This commit is contained in:
parent
9e17baa574
commit
ba598b122e
@ -209,6 +209,7 @@ extract_currdev(void)
|
||||
{
|
||||
struct i386_devdesc new_currdev;
|
||||
#ifdef LOADER_ZFS_SUPPORT
|
||||
char buf[20];
|
||||
struct zfs_boot_args *zargs;
|
||||
#endif
|
||||
int biosdev = -1;
|
||||
@ -239,10 +240,17 @@ extract_currdev(void)
|
||||
if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0)
|
||||
zargs = (struct zfs_boot_args *)(kargs + 1);
|
||||
|
||||
if (zargs != NULL && zargs->size >= sizeof(*zargs)) {
|
||||
if (zargs != NULL &&
|
||||
zargs->size >= offsetof(struct zfs_boot_args, primary_pool)) {
|
||||
/* sufficient data is provided */
|
||||
new_currdev.d_kind.zfs.pool_guid = zargs->pool;
|
||||
new_currdev.d_kind.zfs.root_guid = zargs->root;
|
||||
if (zargs->size >= sizeof(*zargs) && zargs->primary_vdev != 0) {
|
||||
sprintf(buf, "%llu", zargs->primary_pool);
|
||||
setenv("vfs.zfs.boot.primary_pool", buf, 1);
|
||||
sprintf(buf, "%llu", zargs->primary_vdev);
|
||||
setenv("vfs.zfs.boot.primary_vdev", buf, 1);
|
||||
}
|
||||
} else {
|
||||
/* old style zfsboot block */
|
||||
new_currdev.d_kind.zfs.pool_guid = kargs->zfspool;
|
||||
|
@ -176,6 +176,8 @@ zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t
|
||||
* Current ZFS pool
|
||||
*/
|
||||
static spa_t *spa;
|
||||
static spa_t *primary_spa;
|
||||
static vdev_t *primary_vdev;
|
||||
|
||||
/*
|
||||
* A wrapper for dskread that doesn't have to worry about whether the
|
||||
@ -526,7 +528,7 @@ main(void)
|
||||
* first pool we found, if any.
|
||||
*/
|
||||
if (!spa) {
|
||||
spa = STAILQ_FIRST(&zfs_pools);
|
||||
spa = spa_get_primary();
|
||||
if (!spa) {
|
||||
printf("%s: No ZFS pools located, can't boot\n", BOOTPROG);
|
||||
for (;;)
|
||||
@ -534,6 +536,9 @@ main(void)
|
||||
}
|
||||
}
|
||||
|
||||
primary_spa = spa;
|
||||
primary_vdev = spa_get_primary_vdev(spa);
|
||||
|
||||
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);
|
||||
@ -702,6 +707,11 @@ load(void)
|
||||
zfsargs.size = sizeof(zfsargs);
|
||||
zfsargs.pool = zfsmount.spa->spa_guid;
|
||||
zfsargs.root = zfsmount.rootobj;
|
||||
zfsargs.primary_pool = primary_spa->spa_guid;
|
||||
if (primary_vdev != NULL)
|
||||
zfsargs.primary_vdev = primary_vdev->v_guid;
|
||||
else
|
||||
printf("failed to detect primary vdev\n");
|
||||
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
|
||||
bootdev,
|
||||
KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG,
|
||||
|
@ -53,6 +53,8 @@ struct zfs_boot_args
|
||||
uint32_t reserved;
|
||||
uint64_t pool;
|
||||
uint64_t root;
|
||||
uint64_t primary_pool;
|
||||
uint64_t primary_vdev;
|
||||
};
|
||||
|
||||
int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
|
||||
|
@ -706,6 +706,34 @@ spa_find_by_name(const char *name)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef BOOT2
|
||||
static spa_t *
|
||||
spa_get_primary(void)
|
||||
{
|
||||
|
||||
return (STAILQ_FIRST(&zfs_pools));
|
||||
}
|
||||
|
||||
static vdev_t *
|
||||
spa_get_primary_vdev(const spa_t *spa)
|
||||
{
|
||||
vdev_t *vdev;
|
||||
vdev_t *kid;
|
||||
|
||||
if (spa == NULL)
|
||||
spa = spa_get_primary();
|
||||
if (spa == NULL)
|
||||
return (NULL);
|
||||
vdev = STAILQ_FIRST(&spa->spa_vdevs);
|
||||
if (vdev == NULL)
|
||||
return (NULL);
|
||||
for (kid = STAILQ_FIRST(&vdev->v_children); kid != NULL;
|
||||
kid = STAILQ_FIRST(&vdev->v_children))
|
||||
vdev = kid;
|
||||
return (vdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static spa_t *
|
||||
spa_create(uint64_t guid)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user