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",
130 /* Sanitize the parameters. */
131 Sanitize_Bios_Geom(d);
134 * Calculate the number of cylinders this disk must have. If we have
135 * an obvious insanity, we set the number of cylinders to zero.
137 o = d->bios_hd * d->bios_sect;
138 d->bios_cyl = (o != 0) ? len / o : 0;
140 p = q; line++; /* p is now the start of the line _after_ the DISK entry */
143 for (; p != NULL && *p; p = q, line++) {
148 a = strsep(&p, " "); /* Index */
150 * If we find index 0 again, this means we've encountered another disk, so it's safe to assume this disk
151 * has been processed.
155 l = strtoimax(a, &r, 0);
157 printf("libdisk: Int_Open_Disk(%s): can't parse depth '%s' in line %d (r='%s')\n",
162 t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
163 n = strsep(&p, " "); /* name */
164 a = strsep(&p, " "); /* len */
165 len = strtoimax(a, &r, 0);
167 printf("libdisk: Int_Open_Disk(%s): can't parse length '%s' in line %d (r='%s')\n",
171 a = strsep(&p, " "); /* secsize */
172 s = strtoimax(a, &r, 0);
174 printf("libdisk: Int_Open_Disk(%s): can't parse sector size '%s' in line %d (r='%s')\n",
182 /* XXX: Slice name may include a space. */
183 if (!strcmp(a, "sn")) {
188 o = strtoimax(b, &r, 0);
189 /* APPLE have ty as a string */
190 if ((*r) && strcmp(t, "APPLE") &&
191 strcmp(t, "GPT") && strcmp(t, "PART")) {
192 printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
198 else if (!strcmp(a, "i"))
199 i = (!strcmp(t, "PART")) ? o - 1 : o;
200 else if (!strcmp(a, "ty"))
202 else if (!strcmp(a, "sc"))
204 else if (!strcmp(a, "hd"))
206 else if (!strcmp(a, "alt"))
208 else if (!strcmp(a, "xs"))
210 else if (!strcmp(a, "xt")) {
218 /* PLATFORM POLICY BEGIN ----------------------------------- */
219 if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
221 if (platform == p_sparc64 && !strcmp(t, "SUN") &&
222 d->chunks->part->part == NULL) {
225 o = d->chunks->size / (hd * sc);
228 if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
229 DPRINT(("Failed to add 'freebsd' chunk"));
232 if (platform == p_alpha && !strcmp(t, "BSD") &&
233 d->chunks->part->part == NULL) {
234 if (Add_Chunk(d, 0, d->chunks->size, name, freebsd,
236 DPRINT(("Failed to add 'freebsd' chunk"));
239 if (!strcmp(t, "BSD") && i == RAW_PART)
241 /* PLATFORM POLICY END ------------------------------------- */
247 if (!strcmp(t, "SUN"))
248 i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
249 else if (!strncmp(t, "MBR", 3)) {
252 i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0);
260 i = Add_Chunk(d, off, len, n, fat, ty, 0, 0);
263 i = Add_Chunk(d, off, len, n, efi, ty, 0, 0);
266 i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0);
269 } else if (!strcmp(t, "BSD"))
270 i = Add_Chunk(d, off, len, n, part, ty, 0, 0);
271 else if (!strcmp(t, "PC98")) {
274 i = Add_Chunk(d, off, len, n, freebsd, ty, 0,
282 i = Add_Chunk(d, off, len, n, fat, ty, 0, sn);
285 i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn);
288 } else if (!strcmp(t, "GPT"))
289 i = Add_Chunk(d, off, len, n, gpt, 0, 0, b);
290 else if (!strcmp(t, "APPLE"))
291 i = Add_Chunk(d, off, len, n, apple, 0, 0, sn);
293 ; /* Ignore unknown classes. */
295 /* PLATFORM POLICY BEGIN ------------------------------------- */
296 /* We have a chance to do things on a blank disk here */
297 if (platform == p_sparc64 && d->chunks->part->part == NULL) {
300 o = d->chunks->size / (hd * sc);
303 if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
304 DPRINT(("Failed to add 'freebsd' chunk"));
307 /* PLATFORM POLICY END --------------------------------------- */