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("/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) err(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) err(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, *c3;
150 for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
151 c2->flags &= ~CHUNK_BSD_COMPAT;
152 if (c2->type == unused)
154 if (strcmp(c2->name,"X"))
157 c2->oname = malloc(12);
158 if(!c2->oname) err(1,"malloc failed");
159 for(j=1;j<=NDOSPART;j++) {
160 sprintf(c2->oname,"%ss%d",c1->name,j);
161 for(c3 = c1->part; c3 ; c3 = c3->next)
162 if (c3 != c2 && !strcmp(c3->name, c2->oname))
165 c2->name = c2->oname;
175 c2->name = strdup(c1->name);
178 for(c2 = c1->part; c2 ; c2 = c2->next) {
179 if (c2->type == freebsd) {
180 c2->flags |= CHUNK_BSD_COMPAT;
184 for(c2 = c1->part; c2 ; c2 = c2->next) {
185 if (c2->type == freebsd)
186 Fixup_FreeBSD_Names(d,c2);
188 if (c2->type == extended)
189 Fixup_Extended_Names(d,c2);
196 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags, const char *sname)
198 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
204 if(!(flags & CHUNK_FORCE_ALL))
207 /* Never use the first cylinder */
209 offset += (d->bios_sect * d->bios_hd);
210 size -= (d->bios_sect * d->bios_hd);
213 /* Never use the first track */
215 offset += d->bios_sect;
216 size -= d->bios_sect;
220 /* Always end on cylinder boundary */
221 l = (offset+size) % (d->bios_sect * d->bios_hd);
226 i = Add_Chunk(d,offset,size,"X",type,subtype,flags,sname);
228 i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
235 Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
243 for (c1=parent->part; c1 ; c1 = c1->next) {
244 if (c1->type != unused) continue;
245 if (c1->size < size) continue;
252 i = Add_Chunk(d,offset,size,"X",type,subtype,flags,"-");
254 i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
259 for (c1=parent->part; c1 ; c1 = c1->next)
260 if (c1->offset == offset)
262 err(1,"Serious internal trouble");
266 MakeDev(struct chunk *c1, const char *path)
269 u_long cmaj, min, unit, part, slice;
270 char buf[BUFSIZ], buf2[BUFSIZ];
278 msgDebug("MakeDev: Called with %s on path %s\n", p, path);
282 if (!strncmp(p, "wd", 2))
284 else if (!strncmp(p, "ad", 2))
286 else if (!strncmp(p, "wfd", 3))
288 else if (!strncmp(p, "afd", 3))
290 else if (!strncmp(p, "fla", 3))
292 else if (!strncmp(p, "idad", 4))
294 else if (!strncmp(p, "mlxd", 4))
296 else if (!strncmp(p, "amrd", 4))
298 else if (!strncmp(p, "da", 2)) /* CAM support */
301 msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
305 msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
315 else if (isdigit(*p)) {
322 msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
327 msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
343 if(c1->type == freebsd)
344 sprintf(buf2, "%sc", c1->name);
347 if (*p < 'a' || *p > 'h') {
348 msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
354 msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
359 if ((pwd = getpwnam("root")) == NULL) {
361 msgDebug("MakeDev: Unable to lookup user \"root\", using 0.\n");
366 if ((grp = getgrnam("operator")) == NULL) {
368 msgDebug("MakeDev: Unable to lookup group \"operator\", using 5.\n");
373 min = unit * 8 + 65536 * slice + part;
374 sprintf(buf, "%s/r%s", path, c1->name);
376 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
377 msgDebug("mknod of %s returned failure status!\n", buf);
380 if (chown(buf, owner, group) == -1) {
381 msgDebug("chown of %s returned failure status!\n", buf);
385 sprintf(buf, "%s/r%s", path, buf2);
387 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
388 msgDebug("mknod of %s returned failure status!\n", buf);
391 if (chown(buf, owner, group) == -1) {
392 msgDebug("chown of %s returned failure status!\n", buf);
396 sprintf(buf, "%s/%s", path, c1->name);
398 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
399 msgDebug("mknod of %s returned failure status!\n", buf);
402 if (chown(buf, owner, group) == -1) {
403 msgDebug("chown of %s returned failure status!\n", buf);
410 MakeDevChunk(struct chunk *c1, const char *path)
414 i = MakeDev(c1, path);
416 MakeDevChunk(c1->next, path);
418 MakeDevChunk(c1->part, path);
423 MakeDevDisk(struct disk *d, const char *path)
425 return MakeDevChunk(d->chunks, path);