1 /* $OpenBSD: softraid.c,v 1.5 2020/06/08 19:17:12 kn 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/dkio.h> 19 #include <sys/ioctl.h> 20 21 #include <dev/biovar.h> 22 23 #include <err.h> 24 #include <stdio.h> 25 #include <string.h> 26 27 #include "installboot.h" 28 29 static int sr_volume(int, char *, int *, int *); 30 31 void 32 sr_installboot(int devfd, char *dev) 33 { 34 int vol = -1, ndisks = 0, disk; 35 36 /* Use the normal process if this is not a softraid volume. */ 37 if (!sr_volume(devfd, dev, &vol, &ndisks)) { 38 md_installboot(devfd, dev); 39 return; 40 } 41 42 /* Install boot loader in softraid volume. */ 43 sr_install_bootldr(devfd, dev); 44 45 /* Install boot block on each disk that is part of this volume. */ 46 for (disk = 0; disk < ndisks; disk++) 47 sr_install_bootblk(devfd, vol, disk); 48 } 49 50 int 51 sr_volume(int devfd, char *dev, int *vol, int *disks) 52 { 53 struct bioc_inq bi; 54 struct bioc_vol bv; 55 int i; 56 57 /* 58 * Determine if the given device is a softraid volume. 59 */ 60 61 /* Get volume information. */ 62 memset(&bi, 0, sizeof(bi)); 63 if (ioctl(devfd, BIOCINQ, &bi) == -1) 64 return 0; 65 66 /* XXX - softraid volumes will always have a "softraid0" controller. */ 67 if (strncmp(bi.bi_dev, "softraid0", sizeof("softraid0"))) 68 return 0; 69 70 /* 71 * XXX - this only works with the real disk name (e.g. sd0) - this 72 * should be extracted from the device name, or better yet, fixed in 73 * the softraid ioctl. 74 */ 75 /* Locate specific softraid volume. */ 76 for (i = 0; i < bi.bi_novol; i++) { 77 memset(&bv, 0, sizeof(bv)); 78 bv.bv_volid = i; 79 if (ioctl(devfd, BIOCVOL, &bv) == -1) 80 err(1, "BIOCVOL"); 81 82 if (strncmp(dev, bv.bv_dev, sizeof(bv.bv_dev)) == 0) { 83 *vol = i; 84 *disks = bv.bv_nodisk; 85 break; 86 } 87 } 88 89 if (verbose) 90 fprintf(stderr, "%s: softraid volume with %i disk(s)\n", 91 dev, *disks); 92 93 return 1; 94 } 95 96 void 97 sr_status(struct bio_status *bs) 98 { 99 int i; 100 101 for (i = 0; i < bs->bs_msg_count; i++) 102 warnx("%s", bs->bs_msgs[i].bm_msg); 103 104 if (bs->bs_status == BIO_STATUS_ERROR) { 105 if (bs->bs_msg_count == 0) 106 errx(1, "unknown error"); 107 else 108 exit(1); 109 } 110 } 111