1 /* $OpenBSD: installboot.c,v 1.14 2021/07/20 14:51:56 kettenis 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 extern char *__progname; 42 43 fprintf(stderr, "usage: %s [-npv] [-r root] disk [stage1%s]\n", 44 __progname, (stages >= 2) ? " [stage2]" : ""); 45 46 exit(1); 47 } 48 49 int 50 main(int argc, char **argv) 51 { 52 char *dev, *realdev; 53 int devfd, opt; 54 55 md_init(); 56 57 while ((opt = getopt(argc, argv, "npr:v")) != -1) { 58 switch (opt) { 59 case 'n': 60 nowrite = 1; 61 break; 62 case 'p': 63 prepare = 1; 64 break; 65 case 'r': 66 root = strdup(optarg); 67 if (root == NULL) 68 err(1, "strdup"); 69 break; 70 case 'v': 71 verbose = 1; 72 break; 73 default: 74 usage(); 75 } 76 } 77 78 argc -= optind; 79 argv += optind; 80 81 if (argc < 1 || argc > stages + 1) 82 usage(); 83 84 dev = argv[0]; 85 if (argc > 1) 86 stage1 = argv[1]; 87 if (argc > 2) 88 stage2 = argv[2]; 89 90 /* Prefix stages with root, unless they were user supplied. */ 91 if (verbose) 92 fprintf(stderr, "Using %s as root\n", root); 93 if (argc <= 1 && stage1 != NULL) { 94 stage1 = fileprefix(root, stage1); 95 if (stage1 == NULL) 96 exit(1); 97 } 98 if (argc <= 2 && stage2 != NULL) { 99 stage2 = fileprefix(root, stage2); 100 if (stage2 == NULL) 101 exit(1); 102 } 103 104 if ((devfd = opendev(dev, (nowrite ? O_RDONLY : O_RDWR), OPENDEV_PART, 105 &realdev)) == -1) 106 err(1, "open: %s", realdev); 107 108 if (verbose) { 109 fprintf(stderr, "%s bootstrap on %s\n", 110 (nowrite ? "would install" : "installing"), realdev); 111 if (stage1 || stage2) { 112 if (stage1) 113 fprintf(stderr, "using first-stage %s", stage1); 114 if (stage2) 115 fprintf(stderr, ", second-stage %s", stage2); 116 fprintf(stderr, "\n"); 117 } 118 } 119 120 md_loadboot(); 121 122 if (prepare) { 123 md_prepareboot(devfd, realdev); 124 return 0; 125 } 126 127 #ifdef SOFTRAID 128 sr_installboot(devfd, dev); 129 #else 130 md_installboot(devfd, realdev); 131 #endif 132 133 return 0; 134 } 135