From owner-svn-src-user@FreeBSD.ORG Thu Jun 21 10:06:01 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 82D341065672; Thu, 21 Jun 2012 10:06:01 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 64AC38FC15; Thu, 21 Jun 2012 10:06:01 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5LA6115004183; Thu, 21 Jun 2012 10:06:01 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5LA61Xn004180; Thu, 21 Jun 2012 10:06:01 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201206211006.q5LA61Xn004180@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Thu, 21 Jun 2012 10:06:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237375 - in user/ae/bootcode/sys/boot: i386/loader zfs X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jun 2012 10:06:01 -0000 Author: ae Date: Thu Jun 21 10:06:00 2012 New Revision: 237375 URL: http://svn.freebsd.org/changeset/base/237375 Log: Teach ZFS code iterate partition tables on device probe using new API. Modified: user/ae/bootcode/sys/boot/i386/loader/main.c user/ae/bootcode/sys/boot/zfs/zfs.c Modified: user/ae/bootcode/sys/boot/i386/loader/main.c ============================================================================== --- user/ae/bootcode/sys/boot/i386/loader/main.c Thu Jun 21 10:03:48 2012 (r237374) +++ user/ae/bootcode/sys/boot/i386/loader/main.c Thu Jun 21 10:06:00 2012 (r237375) @@ -355,26 +355,18 @@ isa_outb(int port, int value) static void i386_zfs_probe(void) { - char devname[32]; - int unit, slice; + char devname[32]; + int unit; - /* - * Open all the disks we can find and see if we can reconstruct - * ZFS pools from them. Bogusly assumes that the disks are named - * diskN, diskNpM or diskNsM. - */ - for (unit = 0; unit < MAXBDDEV; unit++) { - sprintf(devname, "disk%d:", unit); - if (zfs_probe_dev(devname, NULL) == ENXIO) - continue; - for (slice = 1; slice <= 128; slice++) { - sprintf(devname, "disk%dp%d:", unit, slice); - zfs_probe_dev(devname, NULL); + /* + * Open all the disks we can find and see if we can reconstruct + * ZFS pools from them. + */ + for (unit = 0; unit < MAXBDDEV; unit++) { + if (bd_unit2bios(unit) == -1) + break; + sprintf(devname, "disk%d:", unit); + zfs_probe_dev(devname, NULL); } - for (slice = 1; slice <= 4; slice++) { - sprintf(devname, "disk%ds%d:", unit, slice); - zfs_probe_dev(devname, NULL); - } - } } #endif Modified: user/ae/bootcode/sys/boot/zfs/zfs.c ============================================================================== --- user/ae/bootcode/sys/boot/zfs/zfs.c Thu Jun 21 10:03:48 2012 (r237374) +++ user/ae/bootcode/sys/boot/zfs/zfs.c Thu Jun 21 10:06:00 2012 (r237375) @@ -33,10 +33,11 @@ __FBSDID("$FreeBSD$"); * Stand-alone file reading package. */ +#include #include -#include #include #include +#include #include #include #include @@ -376,21 +377,103 @@ zfs_dev_init(void) return (0); } -int -zfs_probe_dev(const char *devname, uint64_t *pool_guid) +struct zfs_probe_args { + int fd; + const char *devname; + uint64_t *pool_guid; + uint16_t secsz; +}; + +static int +zfs_diskread(void *arg, void *buf, size_t blocks, off_t offset) +{ + struct zfs_probe_args *ppa; + + ppa = (struct zfs_probe_args *)arg; + return (vdev_read(NULL, (void *)(uintptr_t)ppa->fd, + offset * ppa->secsz, buf, blocks * ppa->secsz)); +} + +static int +zfs_probe(int fd, uint64_t *pool_guid) { spa_t *spa; - int fd; int ret; - fd = open(devname, O_RDONLY); - if (fd == -1) - return (ENXIO); ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa); - if (ret != 0) - close(fd); - else if (pool_guid != NULL) + if (ret == 0 && pool_guid != NULL) *pool_guid = spa->spa_guid; + return (ret); +} + +static void +zfs_probe_partition(void *arg, const char *partname, + const struct ptable_entry *part) +{ + struct zfs_probe_args *ppa, pa; + struct ptable *table; + char devname[32]; + int ret; + + /* Probe only freebsd-zfs and freebsd partitions */ + if (part->type != PART_FREEBSD && + part->type != PART_FREEBSD_ZFS) + return; + + ppa = (struct zfs_probe_args *)arg; + strncpy(devname, ppa->devname, strlen(ppa->devname) - 1); + sprintf(devname, "%s%s:", devname, partname); + pa.fd = open(devname, O_RDONLY); + if (pa.fd == -1) + return; + ret = zfs_probe(pa.fd, ppa->pool_guid); + if (ret == 0) + return; + /* Do we have BSD label here? */ + if (part->type == PART_FREEBSD) { + pa.devname = devname; + pa.pool_guid = ppa->pool_guid; + pa.secsz = ppa->secsz; + table = ptable_open(&pa, part->end - part->start + 1, + ppa->secsz, zfs_diskread); + if (table != NULL) { + ptable_iterate(table, &pa, zfs_probe_partition); + ptable_close(table); + } + } + close(pa.fd); +} + +int +zfs_probe_dev(const char *devname, uint64_t *pool_guid) +{ + struct ptable *table; + struct zfs_probe_args pa; + off_t mediasz; + int ret; + + pa.fd = open(devname, O_RDONLY); + if (pa.fd == -1) + return (ENXIO); + /* Probe the whole disk */ + ret = zfs_probe(pa.fd, pool_guid); + if (ret == 0) + return (0); + /* Probe each partition */ + ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz); + if (ret == 0) + ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz); + if (ret == 0) { + pa.devname = devname; + pa.pool_guid = pool_guid; + table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz, + zfs_diskread); + if (table != NULL) { + ptable_iterate(table, &pa, zfs_probe_partition); + ptable_close(table); + } + } + close(pa.fd); return (0); }