2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
20 #include <sys/sysctl.h>
21 #include <sys/stdint.h>
22 #include <sys/types.h>
24 #include <sys/ioctl.h>
25 #include <sys/disklabel.h>
35 #define DPRINT(x) warn x
36 #define DPRINTX(x) warnx x
43 Int_Open_Disk(const char *name, char *conftxt)
47 char *p, *q, *r, *a, *b, *n, *t, *sn;
49 u_int l, s, ty, sc, hd, alt;
53 * Locate the disk (by name) in our sysctl output
55 for (p = conftxt; p != NULL && *p; p = strchr(p, '\n'), line++) {
59 /* Skip anything not with index 0 */
63 /* Skip anything not a disk */
65 if (strcmp(a, "DISK"))
78 d = (struct disk *)calloc(sizeof *d, 1);
82 d->name = strdup(name);
84 a = strsep(&p, " "); /* length in bytes */
85 len = strtoimax(a, &r, 0);
87 printf("libdisk: Int_Open_Disk(%s): can't parse length in line %d (r='%s')\n",
92 a = strsep(&p, " "); /* sectorsize */
93 s = strtoul(a, &r, 0);
95 printf("libdisk: Int_Open_Disk(%s): can't parse sector size in line %d (r='%s')\n",
103 len /= s; /* media size in number of sectors. */
105 if (Add_Chunk(d, 0, len, name, whole, 0, 0, "-")) {
106 DPRINT(("Failed to add 'whole' chunk"));
109 /* Try to parse any fields after the sector size in the DISK entry line */
115 o = strtoimax(b, &r, 0);
117 printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
121 if (!strcmp(a, "hd"))
123 else if (!strcmp(a, "sc"))
126 printf("libdisk: Int_Open_Disk(%s): unknown parameter '%s' with value '%s' in line %d, ignored\n",
131 * Calculate the number of cylinders this disk must have. If we have
132 * an obvious insanity, we set the number of cylinders to zero.
134 o = d->bios_hd * d->bios_sect;
135 d->bios_cyl = (o != 0) ? len / o : 0;
137 p = q; line++; /* p is now the start of the line _after_ the DISK entry */
140 for (; p != NULL && *p; p = q, line++) {
145 a = strsep(&p, " "); /* Index */
147 * If we find index 0 again, this means we've encountered another disk, so it's safe to assume this disk
148 * has been processed.
152 l = strtoimax(a, &r, 0);
154 printf("libdisk: Int_Open_Disk(%s): can't parse depth '%s' in line %d (r='%s')\n",
159 t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
160 n = strsep(&p, " "); /* name */
161 a = strsep(&p, " "); /* len */
162 len = strtoimax(a, &r, 0);
164 printf("libdisk: Int_Open_Disk(%s): can't parse length '%s' in line %d (r='%s')\n",
168 a = strsep(&p, " "); /* secsize */
169 s = strtoimax(a, &r, 0);
171 printf("libdisk: Int_Open_Disk(%s): can't parse sector size '%s' in line %d (r='%s')\n",
179 /* XXX: Slice name may include a space. */
180 if (!strcmp(a, "sn")) {
185 o = strtoimax(b, &r, 0);
186 /* APPLE have ty as a string */
187 if ((*r) && strcmp(t, "APPLE") &&
188 strcmp(t, "GPT") && strcmp(t, "PART")) {
189 printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
195 else if (!strcmp(a, "i"))
196 i = (!strcmp(t, "PART")) ? o - 1 : o;
197 else if (!strcmp(a, "ty"))
199 else if (!strcmp(a, "sc"))
201 else if (!strcmp(a, "hd"))
203 else if (!strcmp(a, "alt"))
205 else if (!strcmp(a, "xs"))
207 else if (!strcmp(a, "xt")) {
215 /* PLATFORM POLICY BEGIN ----------------------------------- */
216 if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
218 if (platform == p_sparc64 && !strcmp(t, "SUN") &&
219 d->chunks->part->part == NULL) {
222 o = d->chunks->size / (hd * sc);
225 if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
226 DPRINT(("Failed to add 'freebsd' chunk"));
229 if (platform == p_alpha && !strcmp(t, "BSD") &&
230 d->chunks->part->part == NULL) {
231 if (Add_Chunk(d, 0, d->chunks->size, name, freebsd,
233 DPRINT(("Failed to add 'freebsd' chunk"));
236 if (!strcmp(t, "BSD") && i == RAW_PART)
238 /* PLATFORM POLICY END ------------------------------------- */
244 if (!strcmp(t, "SUN"))
245 i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
246 else if (!strncmp(t, "MBR", 3)) {
249 i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0);
257 i = Add_Chunk(d, off, len, n, fat, ty, 0, 0);
260 i = Add_Chunk(d, off, len, n, efi, ty, 0, 0);
263 i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0);
266 } else if (!strcmp(t, "BSD"))
267 i = Add_Chunk(d, off, len, n, part, ty, 0, 0);
268 else if (!strcmp(t, "PC98")) {
271 i = Add_Chunk(d, off, len, n, freebsd, ty, 0,
279 i = Add_Chunk(d, off, len, n, fat, ty, 0, sn);
282 i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn);
285 } else if (!strcmp(t, "GPT"))
286 i = Add_Chunk(d, off, len, n, gpt, 0, 0, b);
287 else if (!strcmp(t, "APPLE"))
288 i = Add_Chunk(d, off, len, n, apple, 0, 0, sn);
290 ; /* Ignore unknown classes. */
292 /* PLATFORM POLICY BEGIN ------------------------------------- */
293 /* We have a chance to do things on a blank disk here */
294 if (platform == p_sparc64 && d->chunks->part->part == NULL) {
297 o = d->chunks->size / (hd * sc);
300 if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
301 DPRINT(("Failed to add 'freebsd' chunk"));
304 /* PLATFORM POLICY END --------------------------------------- */