From ce05cad71c235a8dd4ee787648080ee5d11792b0 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Sun, 14 Jun 2020 20:57:24 +0000 Subject: [PATCH] zfsboot: cstyle cleanup No functional changes intended. (cherry picked from commit dfdeb45425cf025ce32c517ec3f85a8dd9fdff54) --- stand/i386/zfsboot/zfsboot.c | 1317 +++++++++++++++++----------------- 1 file changed, 673 insertions(+), 644 deletions(-) diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/zfsboot/zfsboot.c index 03edb08409c..a51c69267fb 100644 --- a/stand/i386/zfsboot/zfsboot.c +++ b/stand/i386/zfsboot/zfsboot.c @@ -48,20 +48,20 @@ __FBSDID("$FreeBSD$"); #include "libzfs.h" -#define ARGS 0x900 -#define NOPT 14 -#define NDEV 3 +#define ARGS 0x900 +#define NOPT 14 +#define NDEV 3 -#define BIOS_NUMDRIVES 0x475 -#define DRV_HARD 0x80 -#define DRV_MASK 0x7f +#define BIOS_NUMDRIVES 0x475 +#define DRV_HARD 0x80 +#define DRV_MASK 0x7f -#define TYPE_AD 0 -#define TYPE_DA 1 -#define TYPE_MAXHARD TYPE_DA -#define TYPE_FD 2 +#define TYPE_AD 0 +#define TYPE_DA 1 +#define TYPE_MAXHARD TYPE_DA +#define TYPE_FD 2 -#define DEV_GELIBOOT_BSIZE 4096 +#define DEV_GELIBOOT_BSIZE 4096 extern uint32_t _end; @@ -97,12 +97,12 @@ uint32_t opts; * If no loader is found, try to load a kernel directly instead. */ static const struct string { - const char *p; - size_t len; + const char *p; + size_t len; } loadpath[] = { - { PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS) }, - { PATH_LOADER, sizeof(PATH_LOADER) }, - { PATH_KERNEL, sizeof(PATH_KERNEL) }, + { PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS) }, + { PATH_LOADER, sizeof(PATH_LOADER) }, + { PATH_KERNEL, sizeof(PATH_KERNEL) }, }; static const unsigned char dev_maj[NDEV] = {30, 4, 2}; @@ -130,7 +130,7 @@ static char *heap_next; static char *heap_end; /* Buffers that must not span a 64k boundary. */ -#define READ_BUF_SIZE 8192 +#define READ_BUF_SIZE 8192 struct dmadat { char rdbuf[READ_BUF_SIZE]; /* for reading large things */ char secbuf[READ_BUF_SIZE]; /* for MBR/disklabel */ @@ -150,9 +150,9 @@ static char gelipw[GELI_PW_MAXLEN]; #endif struct zfsdsk { - struct dsk dsk; + struct dsk dsk; #ifdef LOADER_GELI_SUPPORT - struct geli_dev *gdev; + struct geli_dev *gdev; #endif }; @@ -162,7 +162,8 @@ struct zfsdsk { * Read from a dnode (which must be from a ZPL filesystem). */ static int -zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t size) +zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, + size_t size) { const znode_phys_t *zp = (const znode_phys_t *) dnode->dn_bonus; size_t n; @@ -198,10 +199,10 @@ vdev_read(void *xvdev, void *priv, off_t off, void *buf, size_t bytes) daddr_t lba, alignlba; off_t diff; unsigned int nb, alignnb; - struct zfsdsk *zdsk = (struct zfsdsk *) priv; + struct zfsdsk *zdsk = priv; if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1))) - return -1; + return (-1); p = buf; lba = off / DEV_BSIZE; @@ -242,12 +243,13 @@ vdev_read(void *xvdev, void *priv, off_t off, void *buf, size_t bytes) } if (drvread(&zdsk->dsk, dmadat->rdbuf, alignlba, alignnb)) - return -1; + return (-1); #ifdef LOADER_GELI_SUPPORT /* decrypt */ if (zdsk->gdev != NULL) { - if (geli_read(zdsk->gdev, ((alignlba - zdsk->dsk.start) * - DEV_BSIZE), dmadat->rdbuf, alignnb * DEV_BSIZE)) + if (geli_read(zdsk->gdev, + ((alignlba - zdsk->dsk.start) * DEV_BSIZE), + dmadat->rdbuf, alignnb * DEV_BSIZE)) return (-1); } #endif @@ -260,13 +262,13 @@ vdev_read(void *xvdev, void *priv, off_t off, void *buf, size_t bytes) diff = 0; } - return 0; + return (0); } /* Match the signature exactly due to signature madness */ static int vdev_read2(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) { - return vdev_read(vdev, priv, off, buf, bytes); + return (vdev_read(vdev, priv, off, buf, bytes)); } @@ -276,10 +278,10 @@ vdev_write(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) char *p; daddr_t lba; unsigned int nb; - struct zfsdsk *zdsk = (struct zfsdsk *) priv; + struct zfsdsk *zdsk = priv; if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1))) - return -1; + return (-1); p = buf; lba = off / DEV_BSIZE; @@ -290,23 +292,23 @@ vdev_write(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) nb = READ_BUF_SIZE / DEV_BSIZE; memcpy(dmadat->rdbuf, p, nb * DEV_BSIZE); if (drvwrite(&zdsk->dsk, dmadat->rdbuf, lba, nb)) - return -1; + return (-1); p += nb * DEV_BSIZE; lba += nb; bytes -= nb * DEV_BSIZE; } - return 0; + return (0); } 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 format\n"); - return -1; - } - return 0; + if ((size_t)zfs_read(spa, dnode, offp, buf, nbyte) != nbyte) { + printf("Invalid format\n"); + return (-1); + } + return (0); } /* @@ -369,87 +371,93 @@ vdev_clear_pad2(vdev_t *vdev) static void bios_getmem(void) { - uint64_t size; + uint64_t size; + + /* Parse system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe820 */ + v86.eax = 0xe820; + v86.ecx = sizeof(struct bios_smap); + v86.edx = SMAP_SIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if (V86_CY(v86.efl) || (v86.eax != SMAP_SIG)) + break; + /* look for a low-memory segment that's large enough */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && + (smap.length >= (512 * 1024))) + bios_basemem = smap.length; + /* look for the first segment in 'extended' memory */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base == 0x100000)) { + bios_extmem = smap.length; + } - /* Parse system memory map */ - v86.ebx = 0; - do { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe820*/ - v86.eax = 0xe820; - v86.ecx = sizeof(struct bios_smap); - v86.edx = SMAP_SIG; - v86.es = VTOPSEG(&smap); - v86.edi = VTOPOFF(&smap); - v86int(); - if (V86_CY(v86.efl) || (v86.eax != SMAP_SIG)) - break; - /* look for a low-memory segment that's large enough */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && - (smap.length >= (512 * 1024))) - bios_basemem = smap.length; - /* look for the first segment in 'extended' memory */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { - bios_extmem = smap.length; + /* + * Look for the largest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && + (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, + * truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + if (size > high_heap_size) { + high_heap_size = size; + high_heap_base = smap.base; + } + } + } while (v86.ebx != 0); + + /* Fall back to the old compatibility function for base memory */ + if (bios_basemem == 0) { + v86.ctl = 0; + v86.addr = 0x12; /* int 0x12 */ + v86int(); + + bios_basemem = (v86.eax & 0xffff) * 1024; } /* - * Look for the largest segment in 'extended' memory beyond - * 1MB but below 4GB. + * Fall back through several compatibility functions for extended + * memory. */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && - (smap.base < 0x100000000ull)) { - size = smap.length; - - /* - * If this segment crosses the 4GB boundary, truncate it. - */ - if (smap.base + size > 0x100000000ull) - size = 0x100000000ull - smap.base; - - if (size > high_heap_size) { - high_heap_size = size; - high_heap_base = smap.base; - } + if (bios_extmem == 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe801 */ + v86.eax = 0xe801; + v86int(); + if (!V86_CY(v86.efl)) { + bios_extmem = ((v86.ecx & 0xffff) + + ((v86.edx & 0xffff) * 64)) * 1024; + } + } + if (bios_extmem == 0) { + v86.ctl = 0; + v86.addr = 0x15; /* int 0x15 function 0x88 */ + v86.eax = 0x8800; + v86int(); + bios_extmem = (v86.eax & 0xffff) * 1024; } - } while (v86.ebx != 0); - - /* Fall back to the old compatibility function for base memory */ - if (bios_basemem == 0) { - v86.ctl = 0; - v86.addr = 0x12; /* int 0x12 */ - v86int(); - - bios_basemem = (v86.eax & 0xffff) * 1024; - } - /* Fall back through several compatibility functions for extended memory */ - if (bios_extmem == 0) { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe801*/ - v86.eax = 0xe801; - v86int(); - if (!V86_CY(v86.efl)) { - bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024; + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last 3MB of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; } - } - if (bios_extmem == 0) { - v86.ctl = 0; - v86.addr = 0x15; /* int 0x15 function 0x88*/ - v86.eax = 0x8800; - v86int(); - bios_extmem = (v86.eax & 0xffff) * 1024; - } - - /* - * If we have extended memory and did not find a suitable heap - * region in the SMAP, use the last 3MB of 'extended' memory as a - * high heap candidate. - */ - if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { - high_heap_size = HEAP_MIN; - high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; - } } /* @@ -458,20 +466,20 @@ bios_getmem(void) static int int13probe(int drive) { - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - v86.eax = 0x800; - v86.edx = drive; - v86int(); - - if (!V86_CY(v86.efl) && /* carry clear */ - ((v86.edx & 0xff) != (drive & DRV_MASK))) { /* unit # OK */ - if ((v86.ecx & 0x3f) == 0) { /* absurd sector size */ - return(0); /* skip device */ + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x800; + v86.edx = drive; + v86int(); + + if (!V86_CY(v86.efl) && /* carry clear */ + ((v86.edx & 0xff) != (drive & DRV_MASK))) { /* unit # OK */ + if ((v86.ecx & 0x3f) == 0) { /* absurd sector size */ + return (0); /* skip device */ + } + return (1); } - return (1); - } - return(0); + return (0); } /* @@ -481,11 +489,11 @@ int13probe(int drive) static struct zfsdsk * copy_dsk(struct zfsdsk *zdsk) { - struct zfsdsk *newdsk; + struct zfsdsk *newdsk; - newdsk = malloc(sizeof(struct zfsdsk)); - *newdsk = *zdsk; - return (newdsk); + newdsk = malloc(sizeof(struct zfsdsk)); + *newdsk = *zdsk; + return (newdsk); } /* @@ -560,8 +568,8 @@ drvsize_ext(struct zfsdsk *zdsk) v86.edx = dskp->drive; v86.ebx = 0x55aa; v86int(); - if (V86_CY(v86.efl) || /* carry set */ - (v86.ebx & 0xffff) != 0xaa55 || /* signature */ + if (V86_CY(v86.efl) || /* carry set */ + (v86.ebx & 0xffff) != 0xaa55 || /* signature */ (v86.ecx & EDD_INTERFACE_FIXED_DISK) == 0) return (size); @@ -593,598 +601,619 @@ static void probe_drive(struct zfsdsk *zdsk) { #ifdef GPT - struct gpt_hdr hdr; - struct gpt_ent *ent; - unsigned part, entries_per_sec; - daddr_t slba; + struct gpt_hdr hdr; + struct gpt_ent *ent; + unsigned part, entries_per_sec; + daddr_t slba; #endif #if defined(GPT) || defined(LOADER_GELI_SUPPORT) - daddr_t elba; + daddr_t elba; #endif - struct dos_partition *dp; - char *sec; - unsigned i; + struct dos_partition *dp; + char *sec; + unsigned i; #ifdef LOADER_GELI_SUPPORT - /* - * Taste the disk, if it is GELI encrypted, decrypt it then dig out the - * partition table and probe each slice/partition in turn for a vdev or - * GELI encrypted vdev. - */ - elba = drvsize_ext(zdsk); - if (elba > 0) { - elba--; - } - zdsk->gdev = geli_taste(vdev_read, zdsk, elba, "disk%u:0:"); - if ((zdsk->gdev != NULL) && (geli_havekey(zdsk->gdev) == 0)) - geli_passphrase(zdsk->gdev, gelipw); + /* + * Taste the disk, if it is GELI encrypted, decrypt it then dig out the + * partition table and probe each slice/partition in turn for a vdev or + * GELI encrypted vdev. + */ + elba = drvsize_ext(zdsk); + if (elba > 0) { + elba--; + } + zdsk->gdev = geli_taste(vdev_read, zdsk, elba, "disk%u:0:"); + if ((zdsk->gdev != NULL) && (geli_havekey(zdsk->gdev) == 0)) + geli_passphrase(zdsk->gdev, gelipw); #endif /* LOADER_GELI_SUPPORT */ - sec = dmadat->secbuf; - zdsk->dsk.start = 0; + sec = dmadat->secbuf; + zdsk->dsk.start = 0; #ifdef GPT - /* - * First check for GPT. - */ - if (drvread(&zdsk->dsk, sec, 1, 1)) { - return; - } - memcpy(&hdr, sec, sizeof(hdr)); - if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 || - hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 || - hdr.hdr_entsz < sizeof(*ent) || DEV_BSIZE % hdr.hdr_entsz != 0) { - goto trymbr; - } - - /* - * Probe all GPT partitions for the presence of ZFS pools. We - * return the spa_t for the first we find (if requested). This - * will have the effect of booting from the first pool on the - * disk. - * - * If no vdev is found, GELI decrypting the device and try again - */ - entries_per_sec = DEV_BSIZE / hdr.hdr_entsz; - slba = hdr.hdr_lba_table; - elba = slba + hdr.hdr_entries / entries_per_sec; - while (slba < elba) { - zdsk->dsk.start = 0; - if (drvread(&zdsk->dsk, sec, slba, 1)) - return; - for (part = 0; part < entries_per_sec; part++) { - ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz); - if (memcmp(&ent->ent_type, &freebsd_zfs_uuid, - sizeof(uuid_t)) == 0) { - zdsk->dsk.start = ent->ent_lba_start; - zdsk->dsk.size = ent->ent_lba_end - ent->ent_lba_start + 1; - zdsk->dsk.slice = part + 1; - zdsk->dsk.part = 255; - if (vdev_probe(vdev_read2, zdsk, NULL) == 0) { - /* - * This slice had a vdev. We need a new dsk - * structure now since the vdev now owns this one. - */ - zdsk = copy_dsk(zdsk); - } + /* + * First check for GPT. + */ + if (drvread(&zdsk->dsk, sec, 1, 1)) { + return; + } + memcpy(&hdr, sec, sizeof(hdr)); + if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 || + hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 || + hdr.hdr_entsz < sizeof(*ent) || DEV_BSIZE % hdr.hdr_entsz != 0) { + goto trymbr; + } + + /* + * Probe all GPT partitions for the presence of ZFS pools. We + * return the spa_t for the first we find (if requested). This + * will have the effect of booting from the first pool on the + * disk. + * + * If no vdev is found, GELI decrypting the device and try again + */ + entries_per_sec = DEV_BSIZE / hdr.hdr_entsz; + slba = hdr.hdr_lba_table; + elba = slba + hdr.hdr_entries / entries_per_sec; + while (slba < elba) { + zdsk->dsk.start = 0; + if (drvread(&zdsk->dsk, sec, slba, 1)) + return; + for (part = 0; part < entries_per_sec; part++) { + ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz); + if (memcmp(&ent->ent_type, &freebsd_zfs_uuid, + sizeof(uuid_t)) == 0) { + zdsk->dsk.start = ent->ent_lba_start; + zdsk->dsk.size = + ent->ent_lba_end - ent->ent_lba_start + 1; + zdsk->dsk.slice = part + 1; + zdsk->dsk.part = 255; + if (vdev_probe(vdev_read2, zdsk, NULL) == 0) { + /* + * This slice had a vdev. We need a new + * dsk structure now since the vdev now + * owns this one. + */ + zdsk = copy_dsk(zdsk); + } #ifdef LOADER_GELI_SUPPORT - else if ((zdsk->gdev = geli_taste(vdev_read, zdsk, - ent->ent_lba_end - ent->ent_lba_start, "disk%up%u:", - zdsk->dsk.unit, zdsk->dsk.slice)) != NULL) { - if (geli_havekey(zdsk->gdev) == 0 || - geli_passphrase(zdsk->gdev, gelipw) == 0) { - /* - * This slice has GELI, check it for ZFS. - */ - if (vdev_probe(vdev_read2, zdsk, NULL) == 0) { - /* - * This slice had a vdev. We need a new dsk - * structure now since the vdev now owns this one. - */ - zdsk = copy_dsk(zdsk); + else if ((zdsk->gdev = geli_taste(vdev_read, + zdsk, ent->ent_lba_end - ent->ent_lba_start, + "disk%up%u:", zdsk->dsk.unit, + zdsk->dsk.slice)) != NULL) { + if (geli_havekey(zdsk->gdev) == 0 || + geli_passphrase(zdsk->gdev, gelipw) + == 0) { + /* + * This slice has GELI, + * check it for ZFS. + */ + if (vdev_probe(vdev_read2, + zdsk, NULL) == 0) { + /* + * This slice had a + * vdev. We need a new + * dsk structure now + * since the vdev now + * owns this one. + */ + zdsk = copy_dsk(zdsk); + } + break; + } + } +#endif /* LOADER_GELI_SUPPORT */ } - break; - } } -#endif /* LOADER_GELI_SUPPORT */ - } + slba++; } - slba++; - } - return; + return; trymbr: #endif /* GPT */ - if (drvread(&zdsk->dsk, sec, DOSBBSECTOR, 1)) - return; - dp = (void *)(sec + DOSPARTOFF); - - for (i = 0; i < NDOSPART; i++) { - if (!dp[i].dp_typ) - continue; - zdsk->dsk.start = dp[i].dp_start; - zdsk->dsk.size = dp[i].dp_size; - zdsk->dsk.slice = i + 1; - if (vdev_probe(vdev_read2, zdsk, NULL) == 0) { - zdsk = copy_dsk(zdsk); - } -#ifdef LOADER_GELI_SUPPORT - else if ((zdsk->gdev = geli_taste(vdev_read, zdsk, dp[i].dp_size - - dp[i].dp_start, "disk%us%u:")) != NULL) { - if (geli_havekey(zdsk->gdev) == 0 || - geli_passphrase(zdsk->gdev, gelipw) == 0) { - /* - * This slice has GELI, check it for ZFS. - */ + if (drvread(&zdsk->dsk, sec, DOSBBSECTOR, 1)) + return; + dp = (void *)(sec + DOSPARTOFF); + + for (i = 0; i < NDOSPART; i++) { + if (!dp[i].dp_typ) + continue; + zdsk->dsk.start = dp[i].dp_start; + zdsk->dsk.size = dp[i].dp_size; + zdsk->dsk.slice = i + 1; if (vdev_probe(vdev_read2, zdsk, NULL) == 0) { - /* - * This slice had a vdev. We need a new dsk - * structure now since the vdev now owns this one. - */ - zdsk = copy_dsk(zdsk); + zdsk = copy_dsk(zdsk); + } +#ifdef LOADER_GELI_SUPPORT + else if ((zdsk->gdev = geli_taste(vdev_read, zdsk, + dp[i].dp_size - dp[i].dp_start, "disk%us%u:")) != NULL) { + if (geli_havekey(zdsk->gdev) == 0 || + geli_passphrase(zdsk->gdev, gelipw) == 0) { + /* + * This slice has GELI, check it for ZFS. + */ + if (vdev_probe(vdev_read2, zdsk, NULL) == 0) { + /* + * This slice had a vdev. We need a new + * dsk structure now since the vdev now + * owns this one. + */ + zdsk = copy_dsk(zdsk); + } + break; + } } - break; - } - } #endif /* LOADER_GELI_SUPPORT */ - } + } } int main(void) { - dnode_phys_t dn; - off_t off; - struct zfsdsk *zdsk; - int autoboot, i; - int nextboot; - int rc; - - dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); - - bios_getmem(); - - if (high_heap_size > 0) { - heap_end = PTOV(high_heap_base + high_heap_size); - heap_next = PTOV(high_heap_base); - } else { - heap_next = (char *)dmadat + sizeof(*dmadat); - heap_end = (char *)PTOV(bios_basemem); - } - setheap(heap_next, heap_end); - - zdsk = calloc(1, sizeof(struct zfsdsk)); - zdsk->dsk.drive = *(uint8_t *)PTOV(ARGS); - zdsk->dsk.type = zdsk->dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD; - zdsk->dsk.unit = zdsk->dsk.drive & DRV_MASK; - zdsk->dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1; - zdsk->dsk.part = 0; - zdsk->dsk.start = 0; - zdsk->dsk.size = drvsize_ext(zdsk); - - bootinfo.bi_version = BOOTINFO_VERSION; - bootinfo.bi_size = sizeof(bootinfo); - bootinfo.bi_basemem = bios_basemem / 1024; - bootinfo.bi_extmem = bios_extmem / 1024; - bootinfo.bi_memsizes_valid++; - bootinfo.bi_bios_dev = zdsk->dsk.drive; - - bootdev = MAKEBOOTDEV(dev_maj[zdsk->dsk.type], - zdsk->dsk.slice, zdsk->dsk.unit, zdsk->dsk.part); - - /* Process configuration file */ - - autoboot = 1; - - zfs_init(); - - /* - * Probe the boot drive first - we will try to boot from whatever - * pool we find on that drive. - */ - probe_drive(zdsk); - - /* - * Probe the rest of the drives that the bios knows about. This - * will find any other available pools and it may fill in missing - * vdevs for the boot pool. - */ -#ifndef VIRTUALBOX - for (i = 0; i < *(unsigned char *)PTOV(BIOS_NUMDRIVES); i++) -#else - for (i = 0; i < MAXBDDEV; i++) -#endif - { - if ((i | DRV_HARD) == *(uint8_t *)PTOV(ARGS)) - continue; + dnode_phys_t dn; + off_t off; + struct zfsdsk *zdsk; + int autoboot, i; + int nextboot; + int rc; + + dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); - if (!int13probe(i | DRV_HARD)) - break; + bios_getmem(); + + if (high_heap_size > 0) { + heap_end = PTOV(high_heap_base + high_heap_size); + heap_next = PTOV(high_heap_base); + } else { + heap_next = (char *)dmadat + sizeof(*dmadat); + heap_end = (char *)PTOV(bios_basemem); + } + setheap(heap_next, heap_end); zdsk = calloc(1, sizeof(struct zfsdsk)); - zdsk->dsk.drive = i | DRV_HARD; - zdsk->dsk.type = zdsk->dsk.drive & TYPE_AD; - zdsk->dsk.unit = i; - zdsk->dsk.slice = 0; + zdsk->dsk.drive = *(uint8_t *)PTOV(ARGS); + zdsk->dsk.type = zdsk->dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD; + zdsk->dsk.unit = zdsk->dsk.drive & DRV_MASK; + zdsk->dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1; zdsk->dsk.part = 0; zdsk->dsk.start = 0; zdsk->dsk.size = drvsize_ext(zdsk); + + bootinfo.bi_version = BOOTINFO_VERSION; + bootinfo.bi_size = sizeof(bootinfo); + bootinfo.bi_basemem = bios_basemem / 1024; + bootinfo.bi_extmem = bios_extmem / 1024; + bootinfo.bi_memsizes_valid++; + bootinfo.bi_bios_dev = zdsk->dsk.drive; + + bootdev = MAKEBOOTDEV(dev_maj[zdsk->dsk.type], + zdsk->dsk.slice, zdsk->dsk.unit, zdsk->dsk.part); + + /* Process configuration file */ + + autoboot = 1; + + zfs_init(); + + /* + * Probe the boot drive first - we will try to boot from whatever + * pool we find on that drive. + */ probe_drive(zdsk); - } - - /* - * The first discovered pool, if any, is the pool. - */ - spa = spa_get_primary(); - if (!spa) { - printf("%s: No ZFS pools located, can't boot\n", BOOTPROG); - for (;;) - ; - } - - primary_spa = spa; - primary_vdev = spa_get_primary_vdev(spa); - - nextboot = 0; - rc = vdev_read_pad2(primary_vdev, cmd, sizeof(cmd)); - if (vdev_clear_pad2(primary_vdev)) - printf("failed to clear pad2 area of primary vdev\n"); - if (rc == 0) { + + /* + * Probe the rest of the drives that the bios knows about. This + * will find any other available pools and it may fill in missing + * vdevs for the boot pool. + */ +#ifndef VIRTUALBOX + for (i = 0; i < *(unsigned char *)PTOV(BIOS_NUMDRIVES); i++) +#else + for (i = 0; i < MAXBDDEV; i++) +#endif + { + if ((i | DRV_HARD) == *(uint8_t *)PTOV(ARGS)) + continue; + + if (!int13probe(i | DRV_HARD)) + break; + + zdsk = calloc(1, sizeof(struct zfsdsk)); + zdsk->dsk.drive = i | DRV_HARD; + zdsk->dsk.type = zdsk->dsk.drive & TYPE_AD; + zdsk->dsk.unit = i; + zdsk->dsk.slice = 0; + zdsk->dsk.part = 0; + zdsk->dsk.start = 0; + zdsk->dsk.size = drvsize_ext(zdsk); + probe_drive(zdsk); + } + + /* + * The first discovered pool, if any, is the pool. + */ + spa = spa_get_primary(); + if (!spa) { + printf("%s: No ZFS pools located, can't boot\n", BOOTPROG); + for (;;) + ; + } + + primary_spa = spa; + primary_vdev = spa_get_primary_vdev(spa); + + nextboot = 0; + rc = vdev_read_pad2(primary_vdev, cmd, sizeof(cmd)); + if (vdev_clear_pad2(primary_vdev)) + printf("failed to clear pad2 area of primary vdev\n"); + if (rc == 0) { + if (*cmd) { + /* + * We could find an old-style ZFS Boot Block header + * here. Simply ignore it. + */ + if (*(uint64_t *)cmd != 0x2f5b007b10c) { + /* + * Note that parse() is destructive to cmd[] + * and we also want to honor RBX_QUIET option + * that could be present in cmd[]. + */ + nextboot = 1; + memcpy(cmddup, cmd, sizeof(cmd)); + if (parse_cmd()) { + printf("failed to parse pad2 area of " + "primary vdev\n"); + reboot(); + } + if (!OPT_CHECK(RBX_QUIET)) + printf("zfs nextboot: %s\n", cmddup); + } + /* Do not process this command twice */ + *cmd = 0; + } + } else + printf("failed to read pad2 area of primary vdev\n"); + + /* Mount ZFS only if it's not already mounted via nextboot parsing. */ + if (zfsmount.spa == NULL && + (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)); + } + if (*cmd) { - /* - * We could find an old-style ZFS Boot Block header here. - * Simply ignore it. - */ - if (*(uint64_t *)cmd != 0x2f5b007b10c) { /* - * Note that parse() is destructive to cmd[] and we also want - * to honor RBX_QUIET option that could be present in cmd[]. + * Note that parse_cmd() is destructive to cmd[] and we also + * want to honor RBX_QUIET option that could be present in + * cmd[]. */ - nextboot = 1; memcpy(cmddup, cmd, sizeof(cmd)); - if (parse_cmd()) { - printf("failed to parse pad2 area of primary vdev\n"); - reboot(); - } + if (parse_cmd()) + autoboot = 0; if (!OPT_CHECK(RBX_QUIET)) - printf("zfs nextboot: %s\n", cmddup); - } - /* Do not process this command twice */ - *cmd = 0; + printf("%s: %s\n", PATH_CONFIG, cmddup); + /* Do not process this command twice */ + *cmd = 0; } - } else - printf("failed to read pad2 area of primary vdev\n"); - - /* Mount ZFS only if it's not already mounted via nextboot parsing. */ - if (zfsmount.spa == NULL && - (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)); - } - if (*cmd) { - /* - * Note that parse_cmd() is destructive to cmd[] and we also want - * to honor RBX_QUIET option that could be present in cmd[]. - */ - memcpy(cmddup, cmd, sizeof(cmd)); - if (parse_cmd()) - autoboot = 0; - if (!OPT_CHECK(RBX_QUIET)) - printf("%s: %s\n", PATH_CONFIG, cmddup); - /* Do not process this command twice */ - *cmd = 0; - } - - /* Do not risk waiting at the prompt forever. */ - if (nextboot && !autoboot) - reboot(); - - if (autoboot && !*kname) { - /* - * Iterate through the list of loader and kernel paths, trying to load. - * If interrupted by a keypress, or in case of failure, drop the user - * to the boot2 prompt. - */ - for (i = 0; i < nitems(loadpath); i++) { - memcpy(kname, loadpath[i].p, loadpath[i].len); - if (keyhit(3)) - break; - load(); + /* Do not risk waiting at the prompt forever. */ + if (nextboot && !autoboot) + reboot(); + + if (autoboot && !*kname) { + /* + * Iterate through the list of loader and kernel paths, + * trying to load. If interrupted by a keypress, or in case of + * failure, drop the user to the boot2 prompt. + */ + for (i = 0; i < nitems(loadpath); i++) { + memcpy(kname, loadpath[i].p, loadpath[i].len); + if (keyhit(3)) + break; + load(); + } } - } - - /* Present the user with the boot2 prompt. */ - - for (;;) { - 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 if (rootname[0] != '\0') - printf("Default: %s/%s:%s\n" - "boot: ", - spa->spa_name, rootname, kname); - else - printf("Default: %s:%s\n" - "boot: ", - spa->spa_name, kname); + + /* Present the user with the boot2 prompt. */ + + for (;;) { + 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 if (rootname[0] != '\0') + printf("Default: %s/%s:%s\n" + "boot: ", + spa->spa_name, rootname, kname); + else + printf("Default: %s:%s\n" + "boot: ", + spa->spa_name, kname); + } + if (ioctrl & IO_SERIAL) + sio_flush(); + if (!autoboot || keyhit(5)) + getstr(cmd, sizeof(cmd)); + else if (!autoboot || !OPT_CHECK(RBX_QUIET)) + putchar('\n'); + autoboot = 0; + if (parse_cmd()) + putchar('\a'); + else + load(); } - if (ioctrl & IO_SERIAL) - sio_flush(); - if (!autoboot || keyhit(5)) - getstr(cmd, sizeof(cmd)); - else if (!autoboot || !OPT_CHECK(RBX_QUIET)) - putchar('\n'); - autoboot = 0; - if (parse_cmd()) - putchar('\a'); - else - load(); - } } /* XXX - Needed for btxld to link the boot2 binary; do not remove. */ void exit(int x) { - __exit(x); + __exit(x); } void reboot(void) { - __exit(0); + __exit(0); } static void load(void) { - union { - struct exec ex; - Elf32_Ehdr eh; - } hdr; - static Elf32_Phdr ep[2]; - static Elf32_Shdr es[2]; - caddr_t p; - dnode_phys_t dn; - off_t off; - uint32_t addr, x; - int fmt, i, j; - - if (zfs_lookup(&zfsmount, kname, &dn)) { - printf("\nCan't find %s\n", kname); - return; - } - off = 0; - if (xfsread(&dn, &off, &hdr, sizeof(hdr))) - return; - if (N_GETMAGIC(hdr.ex) == ZMAGIC) - fmt = 0; - else if (IS_ELF(hdr.eh)) - fmt = 1; - else { - printf("Invalid %s\n", "format"); - return; - } - if (fmt == 0) { - addr = hdr.ex.a_entry & 0xffffff; - p = PTOV(addr); - off = PAGE_SIZE; - if (xfsread(&dn, &off, p, hdr.ex.a_text)) - return; - p += roundup2(hdr.ex.a_text, PAGE_SIZE); - if (xfsread(&dn, &off, p, hdr.ex.a_data)) - return; - p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); - p += sizeof(hdr.ex.a_syms); - if (hdr.ex.a_syms) { - if (xfsread(&dn, &off, p, hdr.ex.a_syms)) - return; - p += hdr.ex.a_syms; - if (xfsread(&dn, &off, p, sizeof(int))) + union { + struct exec ex; + Elf32_Ehdr eh; + } hdr; + static Elf32_Phdr ep[2]; + static Elf32_Shdr es[2]; + caddr_t p; + dnode_phys_t dn; + off_t off; + uint32_t addr, x; + int fmt, i, j; + + if (zfs_lookup(&zfsmount, kname, &dn)) { + printf("\nCan't find %s\n", kname); return; - x = *(uint32_t *)p; - p += sizeof(int); - x -= sizeof(int); - if (xfsread(&dn, &off, p, x)) - return; - p += x; } - } else { - off = hdr.eh.e_phoff; - for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { - if (xfsread(&dn, &off, ep + j, sizeof(ep[0]))) + off = 0; + if (xfsread(&dn, &off, &hdr, sizeof(hdr))) return; - if (ep[j].p_type == PT_LOAD) - j++; - } - for (i = 0; i < 2; i++) { - p = PTOV(ep[i].p_paddr & 0xffffff); - off = ep[i].p_offset; - if (xfsread(&dn, &off, p, ep[i].p_filesz)) + if (N_GETMAGIC(hdr.ex) == ZMAGIC) + fmt = 0; + else if (IS_ELF(hdr.eh)) + fmt = 1; + else { + printf("Invalid %s\n", "format"); return; } - p += roundup2(ep[1].p_memsz, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { - off = hdr.eh.e_shoff + sizeof(es[0]) * - (hdr.eh.e_shstrndx + 1); - if (xfsread(&dn, &off, &es, sizeof(es))) - return; - for (i = 0; i < 2; i++) { - memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size)); - p += sizeof(es[i].sh_size); - off = es[i].sh_offset; - if (xfsread(&dn, &off, p, es[i].sh_size)) - return; - p += es[i].sh_size; - } + if (fmt == 0) { + addr = hdr.ex.a_entry & 0xffffff; + p = PTOV(addr); + off = PAGE_SIZE; + if (xfsread(&dn, &off, p, hdr.ex.a_text)) + return; + p += roundup2(hdr.ex.a_text, PAGE_SIZE); + if (xfsread(&dn, &off, p, hdr.ex.a_data)) + return; + p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); + p += sizeof(hdr.ex.a_syms); + if (hdr.ex.a_syms) { + if (xfsread(&dn, &off, p, hdr.ex.a_syms)) + return; + p += hdr.ex.a_syms; + if (xfsread(&dn, &off, p, sizeof(int))) + return; + x = *(uint32_t *)p; + p += sizeof(int); + x -= sizeof(int); + if (xfsread(&dn, &off, p, x)) + return; + p += x; + } + } else { + off = hdr.eh.e_phoff; + for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { + if (xfsread(&dn, &off, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = PTOV(ep[i].p_paddr & 0xffffff); + off = ep[i].p_offset; + if (xfsread(&dn, &off, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(&dn, &off, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + memcpy(p, &es[i].sh_size, + sizeof(es[i].sh_size)); + p += sizeof(es[i].sh_size); + off = es[i].sh_offset; + if (xfsread(&dn, &off, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } + addr = hdr.eh.e_entry & 0xffffff; } - addr = hdr.eh.e_entry & 0xffffff; - } - bootinfo.bi_esymtab = VTOP(p); - bootinfo.bi_kernelname = VTOP(kname); - zfsargs.size = sizeof(zfsargs); - zfsargs.pool = zfsmount.spa->spa_guid; - zfsargs.root = zfsmount.rootobj; - zfsargs.primary_pool = primary_spa->spa_guid; + bootinfo.bi_esymtab = VTOP(p); + bootinfo.bi_kernelname = VTOP(kname); + zfsargs.size = sizeof(zfsargs); + zfsargs.pool = zfsmount.spa->spa_guid; + zfsargs.root = zfsmount.rootobj; + zfsargs.primary_pool = primary_spa->spa_guid; #ifdef LOADER_GELI_SUPPORT - explicit_bzero(gelipw, sizeof(gelipw)); - export_geli_boot_data(&zfsargs.gelidata); + explicit_bzero(gelipw, sizeof(gelipw)); + export_geli_boot_data(&zfsargs.gelidata); #endif - if (primary_vdev != NULL) - zfsargs.primary_vdev = primary_vdev->v_guid; - else - printf("failed to detect primary vdev\n"); - /* - * Note that the zfsargs struct is passed by value, not by pointer. Code in - * btxldr.S copies the values from the entry stack to a fixed location - * within loader(8) at startup due to the presence of KARGS_FLAGS_EXTARG. - */ - __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), - bootdev, - KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, - (uint32_t) spa->spa_guid, - (uint32_t) (spa->spa_guid >> 32), - VTOP(&bootinfo), - zfsargs); + if (primary_vdev != NULL) + zfsargs.primary_vdev = primary_vdev->v_guid; + else + printf("failed to detect primary vdev\n"); + /* + * Note that the zfsargs struct is passed by value, not by pointer. + * Code in btxldr.S copies the values from the entry stack to a fixed + * location within loader(8) at startup due to the presence of + * KARGS_FLAGS_EXTARG. + */ + __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), + bootdev, + KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, + (uint32_t)spa->spa_guid, + (uint32_t)(spa->spa_guid >> 32), + VTOP(&bootinfo), + zfsargs); } static int zfs_mount_ds(char *dsname) { - uint64_t newroot; - spa_t *newspa; - char *q; - - q = strchr(dsname, '/'); - if (q) - *q++ = '\0'; - newspa = spa_find_by_name(dsname); - if (newspa == NULL) { - printf("\nCan't find ZFS pool %s\n", dsname); - return -1; - } - - if (zfs_spa_init(newspa)) - return -1; - - newroot = 0; - if (q) { - if (zfs_lookup_dataset(newspa, q, &newroot)) { - printf("\nCan't find dataset %s in ZFS pool %s\n", - q, newspa->spa_name); - return -1; + uint64_t newroot; + spa_t *newspa; + char *q; + + q = strchr(dsname, '/'); + if (q) + *q++ = '\0'; + newspa = spa_find_by_name(dsname); + if (newspa == NULL) { + printf("\nCan't find ZFS pool %s\n", dsname); + return (-1); + } + + if (zfs_spa_init(newspa)) + return (-1); + + newroot = 0; + if (q) { + if (zfs_lookup_dataset(newspa, q, &newroot)) { + printf("\nCan't find dataset %s in ZFS pool %s\n", + q, newspa->spa_name); + return (-1); + } + } + if (zfs_mount(newspa, newroot, &zfsmount)) { + printf("\nCan't mount ZFS dataset\n"); + return (-1); } - } - if (zfs_mount(newspa, newroot, &zfsmount)) { - printf("\nCan't mount ZFS dataset\n"); - return -1; - } - spa = newspa; - return (0); + spa = newspa; + return (0); } static int parse_cmd(void) { - char *arg = cmd; - char *ep, *p, *q; - const char *cp; - int c, i, j; - - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - if (c == 'P') { - if (*(uint8_t *)PTOV(0x496) & 0x10) { - cp = "yes"; - } else { - opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); - cp = "no"; - } - printf("Keyboard: %s\n", cp); - continue; - } else if (c == 'S') { - j = 0; - while ((unsigned int)(i = *arg++ - '0') <= 9) - j = j * 10 + i; - if (j > 0 && i == -'0') { - comspeed = j; - break; - } - /* Fall through to error below ('S' not in optstr[]). */ + char *arg = cmd; + char *ep, *p, *q; + const char *cp; + int c, i, j; + + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++) + ; + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= OPT_SET(RBX_DUAL); + opts |= OPT_SET(RBX_SERIAL); + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int) + (i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* + * Fall through to error below + * ('S' not in optstr[]). + */ + } + for (i = 0; c != optstr[i]; i++) + if (i == NOPT - 1) + return (-1); + opts ^= OPT_SET(flags[i]); + } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; + if (ioctrl & IO_SERIAL) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } + } if (c == '?') { + dnode_phys_t dn; + + if (zfs_lookup(&zfsmount, arg, &dn) == 0) { + zap_list(spa, &dn); + } + return (-1); + } else { + arg--; + + /* + * Report pool status if the comment is 'status'. Lets + * hope no-one wants to load /status as a kernel. + */ + if (strcmp(arg, "status") == 0) { + spa_all_status(); + return (-1); + } + + /* + * If there is "zfs:" prefix simply ignore it. + */ + if (strncmp(arg, "zfs:", 4) == 0) + arg += 4; + + /* + * If there is a colon, switch pools. + */ + q = strchr(arg, ':'); + if (q) { + *q++ = '\0'; + if (zfs_mount_ds(arg) != 0) + return (-1); + arg = q; + } + if ((i = ep - arg)) { + if ((size_t)i >= sizeof(kname)) + return (-1); + memcpy(kname, arg, i + 1); + } } - for (i = 0; c != optstr[i]; i++) - if (i == NOPT - 1) - return -1; - opts ^= OPT_SET(flags[i]); - } - ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : - OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; - if (ioctrl & IO_SERIAL) { - if (sio_init(115200 / comspeed) != 0) - ioctrl &= ~IO_SERIAL; - } - } if (c == '?') { - dnode_phys_t dn; - - if (zfs_lookup(&zfsmount, arg, &dn) == 0) { - zap_list(spa, &dn); - } - return -1; - } else { - arg--; - - /* - * Report pool status if the comment is 'status'. Lets - * hope no-one wants to load /status as a kernel. - */ - if (!strcmp(arg, "status")) { - spa_all_status(); - return -1; - } - - /* - * If there is "zfs:" prefix simply ignore it. - */ - if (strncmp(arg, "zfs:", 4) == 0) - arg += 4; - - /* - * If there is a colon, switch pools. - */ - q = strchr(arg, ':'); - if (q) { - *q++ = '\0'; - if (zfs_mount_ds(arg) != 0) - return -1; - arg = q; - } - if ((i = ep - arg)) { - if ((size_t)i >= sizeof(kname)) - return -1; - memcpy(kname, arg, i + 1); - } + arg = p; } - arg = p; - } - return 0; + return (0); } -- 2.45.0