1 /* $OpenBSD: installboot.c,v 1.16 2022/11/08 12:08:53 kn Exp $ */ 2 3 /* 4 * Copyright (c) 2012, 2013 Joel Sing <jsing@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <err.h> 20 #include <fcntl.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <unistd.h> 25 #include <util.h> 26 27 #include "installboot.h" 28 29 int nowrite; 30 int prepare; 31 int stages; 32 int verbose; 33 34 char *root; 35 char *stage1; 36 char *stage2; 37 38 static __dead void 39 usage(void) 40 { 41 fprintf(stderr, "usage:\t%1$s [-nv] [-r root] disk [stage1%2$s]\n" 42 "\t%1$s [-nv] -p disk\n", 43 getprogname(), (stages >= 2) ? " [stage2]" : ""); 44 45 exit(1); 46 } 47 48 int 49 main(int argc, char **argv) 50 { 51 char *dev, *realdev; 52 int devfd, opt; 53 54 md_init(); 55 56 while ((opt = getopt(argc, argv, "npr:v")) != -1) { 57 switch (opt) { 58 case 'n': 59 nowrite = 1; 60 break; 61 case 'p': 62 prepare = 1; 63 break; 64 case 'r': 65 root = optarg; 66 break; 67 case 'v': 68 verbose = 1; 69 break; 70 default: 71 usage(); 72 } 73 } 74 75 argc -= optind; 76 argv += optind; 77 78 if (argc < 1 || argc > stages + 1) 79 usage(); 80 if (prepare && (root != NULL || argc > 1)) 81 usage(); 82 83 dev = argv[0]; 84 if (argc > 1) 85 stage1 = argv[1]; 86 if (argc > 2) 87 stage2 = argv[2]; 88 89 if ((devfd = opendev(dev, (nowrite ? O_RDONLY : O_RDWR), OPENDEV_PART, 90 &realdev)) == -1) 91 err(1, "open: %s", realdev); 92 93 if (prepare) { 94 #if SOFTRAID 95 sr_prepareboot(devfd, dev); 96 #else 97 md_prepareboot(devfd, realdev); 98 #endif 99 return 0; 100 } 101 102 /* Prefix stages with root, unless they were user supplied. */ 103 if (root == NULL) 104 root = "/"; 105 if (verbose) 106 fprintf(stderr, "Using %s as root\n", root); 107 if (argc <= 1 && stage1 != NULL) { 108 stage1 = fileprefix(root, stage1); 109 if (stage1 == NULL) 110 exit(1); 111 } 112 if (argc <= 2 && stage2 != NULL) { 113 stage2 = fileprefix(root, stage2); 114 if (stage2 == NULL) 115 exit(1); 116 } 117 118 if (verbose) { 119 fprintf(stderr, "%s bootstrap on %s\n", 120 (nowrite ? "would install" : "installing"), realdev); 121 if (stage1 || stage2) { 122 if (stage1) 123 fprintf(stderr, "using first-stage %s", stage1); 124 if (stage2) 125 fprintf(stderr, ", second-stage %s", stage2); 126 fprintf(stderr, "\n"); 127 } 128 } 129 130 md_loadboot(); 131 132 #ifdef SOFTRAID 133 sr_installboot(devfd, dev); 134 #else 135 md_installboot(devfd, realdev); 136 #endif 137 138 return 0; 139 } 140