summaryrefslogtreecommitdiff
path: root/usr.sbin/installboot/softraid.c
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2013-12-27 13:52:41 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2013-12-27 13:52:41 +0000
commitd0c198ee56e8bcc7eaf65c1620e621b604fee7e8 (patch)
treed4d4d95e96b91b595f682d37a0469c7bad17ac7e /usr.sbin/installboot/softraid.c
parentd86bf5da7e7bdfb9d7a617df91e84cfe97bb5430 (diff)
Initial version of a unified installboot(8) that lives outside of
sys/arch/${MACHINE}/stand. For now this only supports i386, however additional architectures will be added and further development can happen in tree. Requested by deraadt@ quite some time ago.
Diffstat (limited to 'usr.sbin/installboot/softraid.c')
-rw-r--r--usr.sbin/installboot/softraid.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/usr.sbin/installboot/softraid.c b/usr.sbin/installboot/softraid.c
new file mode 100644
index 00000000000..e155cbd1c04
--- /dev/null
+++ b/usr.sbin/installboot/softraid.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: softraid.c,v 1.1 2013/12/27 13:52:40 jsing Exp $ */
+/*
+ * Copyright (c) 2012 Joel Sing <jsing@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
+
+#include <dev/biovar.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "installboot.h"
+
+static int sr_volume(int, char *, int *, int *);
+
+void
+sr_installboot(int devfd, char *dev)
+{
+ int vol = -1, ndisks = 0, disk;
+
+ /* Use the normal process if this is not a softraid volume. */
+ if (!sr_volume(devfd, dev, &vol, &ndisks)) {
+ md_installboot(devfd, dev);
+ return;
+ }
+
+ /* Install boot loader in softraid volume. */
+ sr_install_bootldr(devfd, dev);
+
+ /* Install boot block on each disk that is part of this volume. */
+ for (disk = 0; disk < ndisks; disk++)
+ sr_install_bootblk(devfd, vol, disk);
+}
+
+int
+sr_volume(int devfd, char *dev, int *vol, int *disks)
+{
+ struct bioc_inq bi;
+ struct bioc_vol bv;
+ int rv, i;
+
+ /*
+ * Determine if the given device is a softraid volume.
+ */
+
+ /* Get volume information. */
+ memset(&bi, 0, sizeof(bi));
+ rv = ioctl(devfd, BIOCINQ, &bi);
+ if (rv == -1)
+ return 0;
+
+ /* XXX - softraid volumes will always have a "softraid0" controller. */
+ if (strncmp(bi.bi_dev, "softraid0", sizeof("softraid0")))
+ return 0;
+
+ /*
+ * XXX - this only works with the real disk name (e.g. sd0) - this
+ * should be extracted from the device name, or better yet, fixed in
+ * the softraid ioctl.
+ */
+ /* Locate specific softraid volume. */
+ for (i = 0; i < bi.bi_novol; i++) {
+ memset(&bv, 0, sizeof(bv));
+ bv.bv_volid = i;
+ rv = ioctl(devfd, BIOCVOL, &bv);
+ if (rv == -1)
+ err(1, "BIOCVOL");
+
+ if (strncmp(dev, bv.bv_dev, sizeof(bv.bv_dev)) == 0) {
+ *vol = i;
+ *disks = bv.bv_nodisk;
+ break;
+ }
+ }
+
+ if (verbose)
+ fprintf(stderr, "%s: softraid volume with %i disk(s)\n",
+ dev, *disks);
+
+ return 1;
+}