1 /* $OpenBSD: softraid.c,v 1.2 2013/12/28 11:26:57 jsing Exp $ */ 2 /* 3 * Copyright (c) 2012 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/dkio.h> 20 #include <sys/ioctl.h> 21 22 #include <dev/biovar.h> 23 24 #include <err.h> 25 #include <stdio.h> 26 #include <string.h> 27 28 #include "installboot.h" 29 30 static int sr_volume(int, char *, int *, int *); 31 32 void 33 sr_installboot(int devfd, char *dev) 34 { 35 int vol = -1, ndisks = 0, disk; 36 37 /* Use the normal process if this is not a softraid volume. */ 38 if (!sr_volume(devfd, dev, &vol, &ndisks)) { 39 md_installboot(devfd, dev); 40 return; 41 } 42 43 /* Install boot loader in softraid volume. */ 44 sr_install_bootldr(devfd, dev); 45 46 /* Install boot block on each disk that is part of this volume. */ 47 for (disk = 0; disk < ndisks; disk++) 48 sr_install_bootblk(devfd, vol, disk); 49 } 50 51 int 52 sr_volume(int devfd, char *dev, int *vol, int *disks) 53 { 54 struct bioc_inq bi; 55 struct bioc_vol bv; 56 int i; 57 58 /* 59 * Determine if the given device is a softraid volume. 60 */ 61 62 /* Get volume information. */ 63 memset(&bi, 0, sizeof(bi)); 64 if (ioctl(devfd, BIOCINQ, &bi) == -1) 65 return 0; 66 67 /* XXX - softraid volumes will always have a "softraid0" controller. */ 68 if (strncmp(bi.bi_dev, "softraid0", sizeof("softraid0"))) 69 return 0; 70 71 /* 72 * XXX - this only works with the real disk name (e.g. sd0) - this 73 * should be extracted from the device name, or better yet, fixed in 74 * the softraid ioctl. 75 */ 76 /* Locate specific softraid volume. */ 77 for (i = 0; i < bi.bi_novol; i++) { 78 memset(&bv, 0, sizeof(bv)); 79 bv.bv_volid = i; 80 if (ioctl(devfd, BIOCVOL, &bv) == -1) 81 err(1, "BIOCVOL"); 82 83 if (strncmp(dev, bv.bv_dev, sizeof(bv.bv_dev)) == 0) { 84 *vol = i; 85 *disks = bv.bv_nodisk; 86 break; 87 } 88 } 89 90 if (verbose) 91 fprintf(stderr, "%s: softraid volume with %i disk(s)\n", 92 dev, *disks); 93 94 return 1; 95 } 96