Changeset View
Changeset View
Standalone View
Standalone View
stand/efi/boot1/zfs_module.c
Show First 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | |||||
static EFI_STATUS | static EFI_STATUS | ||||
load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize) | load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize) | ||||
{ | { | ||||
spa_t *spa; | spa_t *spa; | ||||
struct zfsmount zmount; | struct zfsmount zmount; | ||||
dnode_phys_t dn; | dnode_phys_t dn; | ||||
struct stat st; | struct stat st; | ||||
uint64_t rootobj; | |||||
int err; | int err; | ||||
void *buf; | void *buf; | ||||
spa = devinfo->devdata; | spa = devinfo->devdata; | ||||
#ifdef EFI_DEBUG | #ifdef EFI_DEBUG | ||||
{ | { | ||||
CHAR16 *text = efi_devpath_name(devinfo->devpath); | CHAR16 *text = efi_devpath_name(devinfo->devpath); | ||||
DPRINTF("load: '%s' spa: '%s', devpath: %S\n", filepath, | DPRINTF("load: '%s' spa: '%s', devpath: %S\n", filepath, | ||||
spa->spa_name, text); | spa->spa_name, text); | ||||
efi_free_devpath_name(text); | efi_free_devpath_name(text); | ||||
} | } | ||||
#endif | #endif | ||||
if ((err = zfs_spa_init(spa)) != 0) { | if ((err = zfs_spa_init(spa)) != 0) { | ||||
DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err); | DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err); | ||||
return (EFI_NOT_FOUND); | return (EFI_NOT_FOUND); | ||||
} | } | ||||
if ((err = zfs_mount_impl(spa, 0, &zmount)) != 0) { | if (zfs_get_bootonce_spa(spa, OS_BOOTONCE, zfs_bootonce, | ||||
DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err); | sizeof(zfs_bootonce)) == 0) { | ||||
return (EFI_NOT_FOUND); | |||||
} | |||||
/* | /* | ||||
* OK. We've found a filesystem. Any attempt to use it should clear the | * If bootonce attribute is present, use it as root dataset. | ||||
* 'once' flag. Prior to now, we'd not be able to clear it anyway. We | * Any attempt to use it should clear the 'once' flag. Prior | ||||
* don't care if we can't find the files to boot, or if there's a | * to now, we'd not be able to clear it anyway. We don't care | ||||
* problem with it: we've tried to use it once we're able to mount the | * if we can't find the files to boot, or if there's a problem | ||||
* with it: we've tried to use it once we're able to mount the | |||||
* ZFS dataset. | * ZFS dataset. | ||||
* | |||||
* Note: the attribute is prefixed with "zfs:" and suffixed | |||||
* with ":". | |||||
*/ | */ | ||||
char *dname, *end; | |||||
if (zfs_bootonce[0] != 'z' || zfs_bootonce[1] != 'f' || | |||||
zfs_bootonce[2] != 's' || zfs_bootonce[3] != ':' || | |||||
(dname = strchr(&zfs_bootonce[4], '/')) == NULL || | |||||
(end = strrchr(&zfs_bootonce[4], ':')) == NULL) { | |||||
printf("INVALID zfs bootonce: %s\n", zfs_bootonce); | |||||
*zfs_bootonce = '\0'; | *zfs_bootonce = '\0'; | ||||
zfs_get_bootonce_spa(spa, OS_BOOTONCE, zfs_bootonce, sizeof(zfs_bootonce)); | rootobj = 0; | ||||
} else { | |||||
dname += 1; | |||||
*end = '\0'; | |||||
if (zfs_lookup_dataset(spa, dname, &rootobj) != 0) { | |||||
printf("zfs bootonce dataset %s NOT FOUND\n", | |||||
dname); | |||||
*zfs_bootonce = '\0'; | |||||
rootobj = 0; | |||||
} else | |||||
printf("zfs bootonce: %s\n", zfs_bootonce); | |||||
*end = ':'; | |||||
} | |||||
} else { | |||||
*zfs_bootonce = '\0'; | |||||
rootobj = 0; | |||||
} | |||||
if ((err = zfs_mount_impl(spa, rootobj, &zmount)) != 0) { | |||||
printf("Failed to mount pool '%s' (%d)\n", spa->spa_name, err); | |||||
return (EFI_NOT_FOUND); | |||||
} | |||||
imp: this has the same issue... If we try the boot once property and it can't be mounted, we should… | |||||
if ((err = zfs_lookup(&zmount, filepath, &dn)) != 0) { | if ((err = zfs_lookup(&zmount, filepath, &dn)) != 0) { | ||||
if (err == ENOENT) { | if (err == ENOENT) { | ||||
DPRINTF("Failed to find '%s' on pool '%s' (%d)\n", | DPRINTF("Failed to find '%s' on pool '%s' (%d)\n", | ||||
filepath, spa->spa_name, err); | filepath, spa->spa_name, err); | ||||
return (EFI_NOT_FOUND); | return (EFI_NOT_FOUND); | ||||
} | } | ||||
printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath, | printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath, | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |
this has the same issue... If we try the boot once property and it can't be mounted, we should try again with what we would have done had that boot once not been there.
In this case I think it's just having
but I can't recall if zfs_lookup_dataset updates the spa to point to the looked up image or not...