Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 Aug 2012 14:48:28 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r239068 - in head/sys/boot: i386/loader zfs
Message-ID:  <201208051448.q75EmSaU094322@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Sun Aug  5 14:48:28 2012
New Revision: 239068
URL: http://svn.freebsd.org/changeset/base/239068

Log:
  Teach the ZFS use new partitions API when probing.
  Note: now ZFS does probe only for partitions with type "freebsd-zfs"
  and "freebsd".

Modified:
  head/sys/boot/i386/loader/main.c
  head/sys/boot/zfs/zfs.c

Modified: head/sys/boot/i386/loader/main.c
==============================================================================
--- head/sys/boot/i386/loader/main.c	Sun Aug  5 14:38:53 2012	(r239067)
+++ head/sys/boot/i386/loader/main.c	Sun Aug  5 14:48:28 2012	(r239068)
@@ -356,25 +356,17 @@ static void
 i386_zfs_probe(void)
 {
     char devname[32];
-    int unit, slice;
+    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.
+     * ZFS pools from them.
      */
     for (unit = 0; unit < MAXBDDEV; unit++) {
+	if (bd_unit2bios(unit) == -1)
+	    break;
 	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);
-	}
-	for (slice = 1; slice <= 4; slice++) {
-	    sprintf(devname, "disk%ds%d:", unit, slice);
-	    zfs_probe_dev(devname, NULL);
-	}
+	zfs_probe_dev(devname, NULL);
     }
 }
 #endif

Modified: head/sys/boot/zfs/zfs.c
==============================================================================
--- head/sys/boot/zfs/zfs.c	Sun Aug  5 14:38:53 2012	(r239067)
+++ head/sys/boot/zfs/zfs.c	Sun Aug  5 14:48:28 2012	(r239068)
@@ -33,10 +33,11 @@ __FBSDID("$FreeBSD$");
  *	Stand-alone file reading package.
  */
 
+#include <sys/disk.h>
 #include <sys/param.h>
-#include <sys/disklabel.h>
 #include <sys/time.h>
 #include <sys/queue.h>
+#include <part.h>
 #include <stddef.h>
 #include <stdarg.h>
 #include <string.h>
@@ -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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208051448.q75EmSaU094322>