2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@login.dknet.dk> 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 * ----------------------------------------------------------------------------
20 #include <sys/types.h>
21 #include <sys/disklabel.h>
22 #include <sys/diskslice.h>
23 #include <sys/types.h>
30 /* Clone these two from sysinstall because we need our own copies
31 * due to link order problems with `crunch'. Feh!
36 static int debug = 0; /* Allow debugger to tweak it */
41 /* Write something to the debugging port */
43 msgDebug(char *fmt, ...)
47 static int DebugFD = -1;
50 DebugFD = open(_PATH_DEV"ttyv1", O_RDWR);
51 dbg = (char *)alloca(FILENAME_MAX);
52 strcpy(dbg, "DEBUG: ");
54 vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
56 write(DebugFD, dbg, strlen(dbg));
60 Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
62 struct chunk *c1, *c3;
65 if (!strcmp(c->name, "X")) return;
67 /* reset all names to "X" */
68 for (c1 = c->part; c1; c1 = c1->next) {
70 c1->name = malloc(12);
71 if(!c1->name) barfout(1, "Malloc failed");
75 /* Allocate the first swap-partition we find */
76 for (c1 = c->part; c1; c1 = c1->next) {
77 if (c1->type == unused) continue;
78 if (c1->subtype != FS_SWAP) continue;
79 sprintf(c1->name, "%s%c", c->name, SWAP_PART + 'a');
83 /* Allocate the first root-partition we find */
84 for (c1 = c->part; c1; c1 = c1->next) {
85 if (c1->type == unused) continue;
86 if (!(c1->flags & CHUNK_IS_ROOT)) continue;
87 sprintf(c1->name, "%s%c", c->name, 0 + 'a');
91 /* Try to give them the same as they had before */
92 for (c1 = c->part; c1; c1 = c1->next) {
93 if (strcmp(c1->name, "X")) continue;
94 for(c3 = c->part; c3 ; c3 = c3->next)
95 if (c1 != c3 && !strcmp(c3->name, c1->oname)) {
98 strcpy(c1->name, c1->oname);
103 /* Allocate the rest sequentially */
104 for (c1 = c->part; c1; c1 = c1->next) {
105 const char order[] = "efghabd";
106 if (c1->type == unused) continue;
107 if (strcmp("X", c1->name)) continue;
109 for(j = 0; j < strlen(order); j++) {
110 sprintf(c1->name, "%s%c", c->name, order[j]);
111 for(c3 = c->part; c3 ; c3 = c3->next)
112 if (c1 != c3 && !strcmp(c3->name, c1->name))
116 strcpy(c1->name, "X");
120 for (c1 = c->part; c1; c1 = c1->next) {
127 Fixup_Extended_Names(struct disk *d, struct chunk *c)
132 for (c1 = c->part; c1; c1 = c1->next) {
133 if (c1->type == unused) continue;
135 c1->name = malloc(12);
136 if(!c1->name) barfout(1, "malloc failed");
137 sprintf(c1->name, "%ss%d", d->chunks->name, j++);
138 if (c1->type == freebsd)
139 Fixup_FreeBSD_Names(d, c1);
144 Fixup_Names(struct disk *d)
146 struct chunk *c1, *c2;
154 for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
155 c2->flags &= ~CHUNK_BSD_COMPAT;
156 if (c2->type == unused)
158 if (strcmp(c2->name, "X"))
161 c2->oname = malloc(12);
162 if(!c2->oname) barfout(1, "malloc failed");
163 for(j = 1; j <= NDOSPART; j++) {
164 sprintf(c2->oname, "%ss%d", c1->name, j);
165 for(c3 = c1->part; c3; c3 = c3->next)
166 if (c3 != c2 && !strcmp(c3->name, c2->oname))
169 c2->name = c2->oname;
179 c2->name = strdup(c1->name);
182 for(c2 = c1->part; c2; c2 = c2->next) {
183 if (c2->type == freebsd) {
184 c2->flags |= CHUNK_BSD_COMPAT;
188 for(c2 = c1->part; c2; c2 = c2->next) {
189 if (c2->type == freebsd)
190 Fixup_FreeBSD_Names(d, c2);
192 if (c2->type == extended)
193 Fixup_Extended_Names(d, c2);
200 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags, const char *sname)
202 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
208 if(!(flags & CHUNK_FORCE_ALL))
211 /* Never use the first cylinder */
213 offset += (d->bios_sect * d->bios_hd);
214 size -= (d->bios_sect * d->bios_hd);
217 /* Never use the first track */
219 offset += d->bios_sect;
220 size -= d->bios_sect;
224 /* Always end on cylinder boundary */
225 l = (offset+size) % (d->bios_sect * d->bios_hd);
230 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
232 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
239 Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
247 for (c1=parent->part; c1; c1 = c1->next) {
248 if (c1->type != unused) continue;
249 if (c1->size < size) continue;
256 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, "-");
258 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
263 for (c1=parent->part; c1; c1 = c1->next)
264 if (c1->offset == offset)
266 barfout(1, "Serious internal trouble");
271 MakeDev(struct chunk *c1, const char *path)
274 u_long cmaj, min, unit, part, slice;
275 char buf[BUFSIZ], buf2[BUFSIZ];
283 msgDebug("MakeDev: Called with %s on path %s\n", p, path);
287 if (!strncmp(p, "ad", 2))
290 else if (!strncmp(p, "wd", 2))
293 else if (!strncmp(p, "wfd", 3))
295 else if (!strncmp(p, "afd", 3))
297 else if (!strncmp(p, "fla", 3))
299 else if (!strncmp(p, "idad", 4))
301 else if (!strncmp(p, "mlxd", 4))
303 else if (!strncmp(p, "amrd", 4))
305 else if (!strncmp(p, "twed", 4))
307 else if (!strncmp(p, "aacd", 4))
309 else if (!strncmp(p, "ar", 2)) /* ATA RAID */
311 else if (!strncmp(p, "da", 2)) /* CAM support */
314 msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
318 msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
328 else if (isdigit(*p)) {
335 msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
340 msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
356 if(c1->type == freebsd)
357 sprintf(buf2, "%sc", c1->name);
360 if (*p < 'a' || *p > 'h') {
361 msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
367 msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
372 if ((pwd = getpwnam("root")) == NULL) {
374 msgDebug("MakeDev: Unable to lookup user \"root\", using 0.\n");
379 if ((grp = getgrnam("operator")) == NULL) {
381 msgDebug("MakeDev: Unable to lookup group \"operator\", using 5.\n");
386 min = unit * 8 + 65536 * slice + part;
387 sprintf(buf, "%s/r%s", path, c1->name);
389 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
390 msgDebug("mknod of %s returned failure status!\n", buf);
393 if (chown(buf, owner, group) == -1) {
394 msgDebug("chown of %s returned failure status!\n", buf);
398 sprintf(buf, "%s/r%s", path, buf2);
400 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
401 msgDebug("mknod of %s returned failure status!\n", buf);
404 if (chown(buf, owner, group) == -1) {
405 msgDebug("chown of %s returned failure status!\n", buf);
409 sprintf(buf, "%s/%s", path, c1->name);
411 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
412 msgDebug("mknod of %s returned failure status!\n", buf);
415 if (chown(buf, owner, group) == -1) {
416 msgDebug("chown of %s returned failure status!\n", buf);
423 MakeDevChunk(struct chunk *c1, const char *path)
427 i = MakeDev(c1, path);
429 MakeDevChunk(c1->next, path);
431 MakeDevChunk(c1->part, path);
436 MakeDevDisk(struct disk *d, const char *path)
438 return MakeDevChunk(d->chunks, path);