Subject: wedges dump autoconfiguration code
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 06/20/2007 13:56:06
And merging of the disklabel compat wedge code (we had 3 copies).

christos

Index: kern/kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.158
diff -u -u -r1.158 kern_subr.c
--- kern/kern_subr.c	3 Jun 2007 07:47:50 -0000	1.158
+++ kern/kern_subr.c	20 Jun 2007 17:53:17 -0000
@@ -103,6 +103,7 @@
 #include <sys/malloc.h>
 #include <sys/mount.h>
 #include <sys/device.h>
+#include <sys/disk.h>
 #include <sys/reboot.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
@@ -111,6 +112,8 @@
 #include <sys/ktrace.h>
 #include <sys/ptrace.h>
 #include <sys/fcntl.h>
+#include <sys/kauth.h>
+#include <sys/vnode.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -807,6 +810,148 @@
 	(device_class((dv)) == DV_DISK &&				\
 	 !device_is_a((dv), "dk"))
 
+struct vnode *
+opendisk(struct device *dv)
+{
+	int bmajor, bminor;
+	struct vnode *tmpvn;
+	int error;
+	dev_t dev;
+	
+	/*
+	 * Lookup major number for disk block device.
+	 */
+	bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
+	if (bmajor == -1)
+		return NULL;
+	
+	bminor = minor(device_unit(dv));
+	/*
+	 * Fake a temporary vnode for the disk, open it, and read
+	 * and hash the sectors.
+	 */
+	dev = DEV_USES_PARTITIONS(dv) ? MAKEDISKDEV(bmajor, bminor, RAW_PART) :
+	    makedev(bmajor, bminor);
+	if (bdevvp(dev, &tmpvn))
+		panic("%s: can't alloc vnode for %s", __func__, dv->dv_xname);
+	error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
+	if (error) {
+#ifndef DEBUG
+		/*
+		 * Ignore errors caused by missing device, partition,
+		 * or medium.
+		 */
+		if (error != ENXIO && error != ENODEV)
+#endif
+			printf("%s: can't open dev %s (%d)\n",
+			    __func__, dv->dv_xname, error);
+		vput(tmpvn);
+		return NULL;
+	}
+
+	return tmpvn;
+}
+
+int
+findwedge(struct device *dv, int par, struct dkwedge_info *wip)
+{
+	struct dkwedge_list wl;
+	struct dkwedge_info *wi;
+	struct vnode *vn;
+	char diskname[16];
+	int i, error;
+
+	if ((vn = opendisk(dv)) == NULL)
+		return -1;
+
+	wl.dkwl_bufsize = sizeof(*wi) * 16;
+	wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
+
+	error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
+	VOP_CLOSE(vn, FREAD, NOCRED, 0);
+	vput(vn);
+	if (error) {
+#ifdef DEBUG_WEDGE
+		printf("%s: List wedges returned %d\n", dv->dv_xname, error);
+#endif
+		free(wi, M_TEMP);
+		return -1;
+	}
+
+#ifdef DEBUG_WEDGE
+	printf("%s: Returned %u(%u) wedges\n", dv->dv_xname,
+	    wl.dkwl_nwedges, wl.dkwl_ncopied);
+#endif
+	snprintf(diskname, sizeof(diskname), "%s%c", dv->dv_xname,
+	    par + 'a');
+
+	for (i = 0; i < wl.dkwl_ncopied; i++) {
+#ifdef DEBUG_WEDGE
+		printf("%s: Looking for %s in %s\n", 
+		    dv->dv_xname, diskname, wi[i].dkw_wname);
+#endif
+		if (strcmp(wi[i].dkw_wname, diskname) == 0)
+			break;
+	}
+
+	if (i == wl.dkwl_ncopied) {
+#ifdef DEBUG_WEDGE
+		printf("%s: Cannot find wedge with parent %s\n",
+		    dv->dv_xname, diskname);
+#endif
+		free(wi, M_TEMP);
+		return -1;
+	}
+
+	*wip = wi[i];
+	free(wi, M_TEMP);
+	return 0;
+}
+
+static int
+isswap(struct device *dv)
+{
+	struct dkwedge_info wi;
+	struct vnode *vn;
+	int error;
+
+	if (device_class(dv) != DV_DISK || !device_is_a(dv, "dk"))
+		return 0;
+
+	if ((vn = opendisk(dv)) == NULL)
+		return 0;
+
+	error = VOP_IOCTL(vn, DIOCGWEDGEINFO, &wi, FREAD, NOCRED, 0);
+	VOP_CLOSE(vn, FREAD, NOCRED, 0);
+	vput(vn);
+	if (error) {
+#ifdef DEBUG_WEDGE
+		printf("%s: Get wedge inforeturned %d\n", dv->dv_xname, error);
+#endif
+		return 0;
+	}
+	return strcmp(wi.dkw_ptype, DKW_PTYPE_SWAP) == 0;
+}
+
+void
+handle_wedges(struct device *dv, int par)
+{
+	struct dkwedge_info wi;
+
+	if (findwedge(dv, par, &wi) == -1) {
+		booted_device = dv;
+		booted_partition = par;
+		return;
+	}
+#ifdef DEBUG_WEDGE
+	printf("%s: Setting boot wedge %s (%s) at %llu %llu\n", 
+		dv->dv_xname, wi.dkw_devname, wi.dkw_wname,
+		(unsigned long long)wi.dkw_offset,
+		(unsigned long long)wi.dkw_size);
+#endif
+	dkwedge_set_bootwedge(dv, wi.dkw_offset, wi.dkw_size);
+}
+
 void
 setroot(struct device *bootdv, int bootpartition)
 {
@@ -1129,9 +1274,22 @@
 			goto nodumpdev;
 		}
 	} else {				/* (c) */
-		if (DEV_USES_PARTITIONS(rootdv) == 0)
-			goto nodumpdev;
-		else {
+		if (DEV_USES_PARTITIONS(rootdv) == 0) {
+			int majdev;
+
+			for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
+			    dv = TAILQ_NEXT(dv, dv_list))
+				if (isswap(dv))
+					break;
+			if (dv == NULL)
+				goto nodumpdev;
+
+			majdev = devsw_name2blk(dv->dv_xname, NULL, 0);
+			if (majdev < 0)
+				goto nodumpdev;
+			dumpdv = dv;
+			dumpdev = makedev(majdev, device_unit(dumpdv));
+		} else {
 			dumpdv = rootdv;
 			dumpdev = MAKEDISKDEV(major(rootdev),
 			    device_unit(dumpdv), 1);
Index: sys/conf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/conf.h,v
retrieving revision 1.126
diff -u -u -r1.126 conf.h
--- sys/conf.h	4 Mar 2007 06:03:40 -0000	1.126
+++ sys/conf.h	20 Jun 2007 17:53:17 -0000
@@ -223,8 +223,13 @@
 
 #ifdef _KERNEL
 struct	device;
+struct	dkwedge_info;
+struct	vnode;
 void	setroot(struct device *, int);
 void	swapconf(void);
+struct	vnode *opendisk(struct device *);
+int	findwedge(struct device *, int, struct dkwedge_info *);
+void	handle_wedges(struct device *, int);
 #endif /* _KERNEL */
 
 #endif /* !_SYS_CONF_H_ */
Index: arch/x86/x86/x86_autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/x86_autoconf.c,v
retrieving revision 1.25
diff -u -u -r1.25 x86_autoconf.c
--- arch/x86/x86/x86_autoconf.c	4 Mar 2007 06:01:09 -0000	1.25
+++ arch/x86/x86/x86_autoconf.c	20 Jun 2007 17:53:18 -0000
@@ -65,114 +65,6 @@
 struct disklist *x86_alldisks;
 int x86_ndisks;
 
-static struct vnode *
-opendisk(struct device *dv)
-{
-	int bmajor, bminor;
-	struct vnode *tmpvn;
-	int error;
-	dev_t dev;
-	
-	/*
-	 * Lookup major number for disk block device.
-	 */
-	bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
-	if (bmajor == -1)
-		return NULL;
-	
-	bminor = minor(device_unit(dv));
-	/*
-	 * Fake a temporary vnode for the disk, open it, and read
-	 * and hash the sectors.
-	 */
-	dev = device_is_a(dv, "dk") ? makedev(bmajor, bminor) :
-	    MAKEDISKDEV(bmajor, bminor, RAW_PART);
-	if (bdevvp(dev, &tmpvn))
-		panic("%s: can't alloc vnode for %s", __func__, dv->dv_xname);
-	error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
-	if (error) {
-#ifndef DEBUG
-		/*
-		 * Ignore errors caused by missing device, partition,
-		 * or medium.
-		 */
-		if (error != ENXIO && error != ENODEV)
-#endif
-			printf("%s: can't open dev %s (%d)\n",
-			    __func__, dv->dv_xname, error);
-		vput(tmpvn);
-		return NULL;
-	}
-
-	return tmpvn;
-}
-
-static void
-handle_wedges(struct device *dv, int par)
-{
-	struct dkwedge_list wl;
-	struct dkwedge_info *wi;
-	struct vnode *vn;
-	char diskname[16];
-	int i, error;
-
-	if ((vn = opendisk(dv)) == NULL)
-		goto out;
-
-	wl.dkwl_bufsize = sizeof(*wi) * 16;
-	wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
-
-	error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
-	VOP_CLOSE(vn, FREAD, NOCRED, 0);
-	vput(vn);
-	if (error) {
-#ifdef DEBUG_WEDGE
-		printf("%s: List wedges returned %d\n", dv->dv_xname, error);
-#endif
-		free(wi, M_TEMP);
-		goto out;
-	}
-
-#ifdef DEBUG_WEDGE
-	printf("%s: Returned %u(%u) wedges\n", dv->dv_xname,
-	    wl.dkwl_nwedges, wl.dkwl_ncopied);
-#endif
-	snprintf(diskname, sizeof(diskname), "%s%c", dv->dv_xname,
-	    par + 'a');
-
-	for (i = 0; i < wl.dkwl_ncopied; i++) {
-#ifdef DEBUG_WEDGE
-		printf("%s: Looking for %s in %s\n", 
-		    dv->dv_xname, diskname, wi[i].dkw_wname);
-#endif
-		if (strcmp(wi[i].dkw_wname, diskname) == 0)
-			break;
-	}
-
-	if (i == wl.dkwl_ncopied) {
-#ifdef DEBUG_WEDGE
-		printf("%s: Cannot find wedge with parent %s\n",
-		    dv->dv_xname, diskname);
-#endif
-		free(wi, M_TEMP);
-		goto out;
-	}
-
-#ifdef DEBUG_WEDGE
-	printf("%s: Setting boot wedge %s (%s) at %llu %llu\n", 
-		dv->dv_xname, wi[i].dkw_devname, wi[i].dkw_wname,
-		(unsigned long long)wi[i].dkw_offset,
-		(unsigned long long)wi[i].dkw_size);
-#endif
-	dkwedge_set_bootwedge(dv, wi[i].dkw_offset, wi[i].dkw_size);
-	free(wi, M_TEMP);
-	return;
-out:
-	booted_device = dv;
-	booted_partition = par;
-}
-
-
 static int
 is_valid_disk(struct device *dv)
 {
Index: arch/sparc64/sparc64/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/autoconf.c,v
retrieving revision 1.137
diff -u -u -r1.137 autoconf.c
--- arch/sparc64/sparc64/autoconf.c	4 Mar 2007 06:00:50 -0000	1.137
+++ arch/sparc64/sparc64/autoconf.c	20 Jun 2007 17:53:18 -0000
@@ -430,49 +430,6 @@
 	(void)spl0();
 }
 
-static struct vnode *
-opendisk(struct device *dv)
-{
-	int bmajor, bminor;
-	struct vnode *tmpvn;
-	int error;
-	dev_t dev;
-	
-	/*
-	 * Lookup major number for disk block device.
-	 */
-	bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
-	if (bmajor == -1)
-		return NULL;
-	
-	bminor = minor(device_unit(dv));
-	/*
-	 * Fake a temporary vnode for the disk, open it, and read
-	 * and hash the sectors.
-	 */
-	dev = device_is_a(dv, "dk") ? makedev(bmajor, bminor) :
-	    MAKEDISKDEV(bmajor, bminor, RAW_PART);
-	if (bdevvp(dev, &tmpvn))
-		panic("%s: can't alloc vnode for %s", __func__,
-		    device_xname(dv));
-	error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
-	if (error) {
-#ifndef DEBUG
-		/*
-		 * Ignore errors caused by missing device, partition,
-		 * or medium.
-		 */
-		if (error != ENXIO && error != ENODEV)
-#endif
-			printf("%s: can't open dev %s (%d)\n",
-			    __func__, device_xname(dv), error);
-		vput(tmpvn);
-		return NULL;
-	}
-
-	return tmpvn;
-}
-
 void
 cpu_rootconf(void)
 {
Index: arch/xen/i386/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/i386/autoconf.c,v
retrieving revision 1.23
diff -u -u -r1.23 autoconf.c
--- arch/xen/i386/autoconf.c	17 May 2007 14:51:35 -0000	1.23
+++ arch/xen/i386/autoconf.c	20 Jun 2007 17:53:18 -0000
@@ -94,8 +94,6 @@
 static void matchbiosdisks(void);
 static void findroot(void);
 static int is_valid_disk(struct device *);
-static struct vnode *opendisk(struct device *);
-static void handle_wedges(struct device *, int);
 
 struct disklist *x86_alldisks;
 int x86_ndisks;
@@ -568,108 +566,6 @@
 	booted_device = dev;
 }
 
-static struct vnode *
-opendisk(struct device *dv)
-{
-	int bmajor;
-	struct vnode *tmpvn;
-	int error;
-	
-	/*
-	 * Lookup major number for disk block device.
-	 */
-	bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
-	if (bmajor == -1)
-		return NULL;
-	
-	/*
-	 * Fake a temporary vnode for the disk, open it, and read
-	 * and hash the sectors.
-	 */
-	if (bdevvp(MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART), &tmpvn))
-		panic("%s: can't alloc vnode for %s", __func__, dv->dv_xname);
-	error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
-	if (error) {
-#ifndef DEBUG
-		/*
-		 * Ignore errors caused by missing device, partition,
-		 * or medium.
-		 */
-		if (error != ENXIO && error != ENODEV)
-#endif
-			printf("%s: can't open dev %s (%d)\n",
-			    __func__, dv->dv_xname, error);
-		vput(tmpvn);
-		return NULL;
-	}
-
-	return tmpvn;
-}
-
-static void
-handle_wedges(struct device *dv, int par)
-{
-	struct dkwedge_list wl;
-	struct dkwedge_info *wi;
-	struct vnode *vn;
-	char diskname[16];
-	int i, error;
-
-	if ((vn = opendisk(dv)) == NULL)
-		goto out;
-
-	wl.dkwl_bufsize = sizeof(*wi) * 16;
-	wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
-
-	error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
-	vput(vn);
-	if (error) {
-#ifdef DEBUG_WEDGE
-		printf("%s: List wedges returned %d\n", dv->dv_xname, error);
-#endif
-		free(wi, M_TEMP);
-		goto out;
-	}
-
-#ifdef DEBUG_WEDGE
-	printf("%s: Returned %u(%u) wedges\n", dv->dv_xname,
-	    wl.dkwl_nwedges, wl.dkwl_ncopied);
-#endif
-	snprintf(diskname, sizeof(diskname), "%s%c", dv->dv_xname,
-	    par + 'a');
-
-	for (i = 0; i < wl.dkwl_ncopied; i++) {
-#ifdef DEBUG_WEDGE
-		printf("%s: Looking for %s in %s\n", 
-		    dv->dv_xname, diskname, wi[i].dkw_wname);
-#endif
-		if (strcmp(wi[i].dkw_wname, diskname) == 0)
-			break;
-	}
-
-	if (i == wl.dkwl_ncopied) {
-#ifdef DEBUG_WEDGE
-		printf("%s: Cannot find wedge with parent %s\n",
-		    dv->dv_xname, diskname);
-#endif
-		free(wi, M_TEMP);
-		goto out;
-	}
-
-#ifdef DEBUG_WEDGE
-	printf("%s: Setting boot wedge %s (%s) at %llu %llu\n", 
-		dv->dv_xname, wi[i].dkw_devname, wi[i].dkw_wname,
-		(unsigned long long)wi[i].dkw_offset,
-		(unsigned long long)wi[i].dkw_size);
-#endif
-	dkwedge_set_bootwedge(dv, wi[i].dkw_offset, wi[i].dkw_size);
-	free(wi, M_TEMP);
-	return;
-out:
-	booted_device = dv;
-	booted_partition = par;
-}
-
 static int
 is_valid_disk(struct device *dv)
 {