jcs's openbsd hax
openbsd
1/* $OpenBSD: installboot.c,v 1.18 2025/11/19 15:05:04 deraadt 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 <sys/types.h>
20#include <sys/disklabel.h>
21#include <err.h>
22#include <fcntl.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <stddef.h>
27#include <unistd.h>
28#include <util.h>
29
30#include "installboot.h"
31
32int config;
33int nowrite;
34int prepare;
35int stages;
36int verbose;
37
38char *root;
39char *stage1;
40char *stage2;
41
42/*
43 * XXX Only read the old smaller "skinny" label for now which
44 * has 16 partitions. offsetof() is used to carve struct disklabel.
45 * Later we'll add code to read and process the "fat" label with
46 * 52 partitions.
47 */
48size_t dl16sz = offsetof(struct disklabel, d_partitions[MAXPARTITIONS16]);
49
50static __dead void
51usage(void)
52{
53 fprintf(stderr, "usage:\t%1$s [-cnv] [-r root] disk [stage1%2$s]\n"
54 "\t%1$s [-nv] -p disk\n",
55 getprogname(), (stages >= 2) ? " [stage2]" : "");
56
57 exit(1);
58}
59
60int
61main(int argc, char **argv)
62{
63 char *dev, *realdev;
64 int devfd, opt;
65
66 md_init();
67
68 while ((opt = getopt(argc, argv, "cnpr:v")) != -1) {
69 switch (opt) {
70 case 'c':
71 config = 1;
72 break;
73 case 'n':
74 nowrite = 1;
75 break;
76 case 'p':
77 prepare = 1;
78 break;
79 case 'r':
80 root = optarg;
81 break;
82 case 'v':
83 verbose = 1;
84 break;
85 default:
86 usage();
87 }
88 }
89
90 argc -= optind;
91 argv += optind;
92
93 if (argc < 1 || argc > stages + 1)
94 usage();
95 if (prepare && (root != NULL || argc > 1))
96 usage();
97
98 dev = argv[0];
99 if (argc > 1)
100 stage1 = argv[1];
101 if (argc > 2)
102 stage2 = argv[2];
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 (prepare) {
109#if SOFTRAID
110 sr_prepareboot(devfd, dev);
111#else
112 md_prepareboot(devfd, realdev);
113#endif
114 return 0;
115 }
116
117 /* Prefix stages with root, unless they were user supplied. */
118 if (root == NULL)
119 root = "/";
120 if (verbose)
121 fprintf(stderr, "Using %s as root\n", root);
122 if (argc <= 1 && stage1 != NULL) {
123 stage1 = fileprefix(root, stage1);
124 if (stage1 == NULL)
125 exit(1);
126 }
127 if (argc <= 2 && stage2 != NULL) {
128 stage2 = fileprefix(root, stage2);
129 if (stage2 == NULL)
130 exit(1);
131 }
132
133 if (verbose) {
134 fprintf(stderr, "%s bootstrap on %s\n",
135 (nowrite ? "would install" : "installing"), realdev);
136 if (stage1 || stage2) {
137 if (stage1)
138 fprintf(stderr, "using first-stage %s", stage1);
139 if (stage2)
140 fprintf(stderr, ", second-stage %s", stage2);
141 fprintf(stderr, "\n");
142 }
143 }
144
145 md_loadboot();
146
147#ifdef SOFTRAID
148 sr_installboot(devfd, dev);
149#else
150 md_installboot(devfd, realdev);
151#endif
152
153 return 0;
154}