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)
{