From 8a200b8ecf6471a2f6b31a0056a9302651259a95 Mon Sep 17 00:00:00 2001 From: rnoland Date: Fri, 23 Oct 2009 18:44:53 +0000 Subject: Correct some issues with zfs boot. - Teach it to read gang blocks. (essentially untested) If you see "ZFS: gang block detected!", please let me know, so we can either remove the printf if it works, or fix it if it doesn't. - If multiple partitions exist on a disk, probe them all. We also need to reset dsk->start to 0 to read the right sector here. - With GPT, we can have 128 partitions. - If the bootfs property has ever been set on a pool it seems that it never goes away. zpool won't allow you to add to the pool with the bootfs property set. However, if you clear the property back to default we end up getting 0 for the object number and read a bogus block pointer and fail to boot. - Fix some error printfs. The printf in the loader is only capable of c,s and u formats. - Teach printf how to display %llu Reviewed by: dfr, jhb MFC after: 2 weeks --- sys/boot/i386/zfsboot/zfsboot.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'sys/boot/i386') diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index a654393..c0dedd7 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -474,6 +474,7 @@ probe_drive(struct dsk *dsk, spa_t **spap) slba = hdr.hdr_lba_table; elba = slba + hdr.hdr_entries / entries_per_sec; while (slba < elba) { + dsk->start = 0; if (drvread(dsk, sec, slba, 1)) return; for (part = 0; part < entries_per_sec; part++) { @@ -494,7 +495,6 @@ probe_drive(struct dsk *dsk, spa_t **spap) */ dsk = copy_dsk(dsk); } - break; } } slba++; @@ -857,12 +857,13 @@ static void printf(const char *fmt,...) { va_list ap; - char buf[10]; + char buf[20]; char *s; - unsigned u; + unsigned long long u; int c; int minus; int prec; + int l; int len; int pad; @@ -871,6 +872,7 @@ printf(const char *fmt,...) if (c == '%') { minus = 0; prec = 0; + l = 0; nextfmt: c = *fmt++; switch (c) { @@ -892,6 +894,9 @@ printf(const char *fmt,...) case 'c': putchar(va_arg(ap, int)); continue; + case 'l': + l++; + goto nextfmt; case 's': s = va_arg(ap, char *); if (prec) { @@ -914,7 +919,17 @@ printf(const char *fmt,...) } continue; case 'u': - u = va_arg(ap, unsigned); + switch (l) { + case 2: + u = va_arg(ap, unsigned long long); + break; + case 1: + u = va_arg(ap, unsigned long); + break; + default: + u = va_arg(ap, unsigned); + break; + } s = buf; do *s++ = '0' + u % 10U; -- cgit v1.1