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 * ----------------------------------------------------------------------------
9 * $FreeBSD: src/lib/libdisk/create_chunk.c,v 1.46.2.8 2001/05/13 21:01:37 jkh Exp $
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 0;
67 /* reset all names to "X" */
68 for (c1 = c->part; c1; c1 = c1->next) {
70 c1->name = malloc(12);
71 if(!c1->name) return -1;
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) {
128 Fixup_Extended_Names(struct disk *d, struct chunk *c)
133 for (c1 = c->part; c1; c1 = c1->next) {
134 if (c1->type == unused) continue;
136 c1->name = malloc(12);
137 if(!c1->name) return -1;
138 sprintf(c1->name, "%ss%d", d->chunks->name, j++);
139 if (c1->type == freebsd)
140 if (Fixup_FreeBSD_Names(d, c1) != 0)
147 Fixup_Names(struct disk *d)
149 struct chunk *c1, *c2;
157 for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
158 c2->flags &= ~CHUNK_BSD_COMPAT;
159 if (c2->type == unused)
161 if (strcmp(c2->name, "X"))
164 c2->oname = malloc(12);
165 if(!c2->oname) return -1;
166 for(j = 1; j <= NDOSPART; j++) {
167 sprintf(c2->oname, "%ss%d", c1->name, j);
168 for(c3 = c1->part; c3; c3 = c3->next)
169 if (c3 != c2 && !strcmp(c3->name, c2->oname))
172 c2->name = c2->oname;
182 c2->name = strdup(c1->name);
185 for(c2 = c1->part; c2; c2 = c2->next) {
186 if (c2->type == freebsd) {
187 c2->flags |= CHUNK_BSD_COMPAT;
191 for(c2 = c1->part; c2; c2 = c2->next) {
192 if (c2->type == freebsd)
193 Fixup_FreeBSD_Names(d, c2);
195 if (c2->type == extended)
196 Fixup_Extended_Names(d, c2);
204 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags, const char *sname)
206 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
212 if(!(flags & CHUNK_FORCE_ALL))
215 /* Never use the first cylinder */
217 offset += (d->bios_sect * d->bios_hd);
218 size -= (d->bios_sect * d->bios_hd);
221 /* Never use the first track */
223 offset += d->bios_sect;
224 size -= d->bios_sect;
228 /* Always end on cylinder boundary */
229 l = (offset+size) % (d->bios_sect * d->bios_hd);
234 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
236 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
243 Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
251 for (c1=parent->part; c1; c1 = c1->next) {
252 if (c1->type != unused) continue;
253 if (c1->size < size) continue;
260 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, "-");
262 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
267 for (c1=parent->part; c1; c1 = c1->next)
268 if (c1->offset == offset)
270 /* barfout(1, "Serious internal trouble"); */
275 MakeDev(struct chunk *c1, const char *path)
278 u_long cmaj, min, unit, part, slice;
279 char buf[BUFSIZ], buf2[BUFSIZ];
287 msgDebug("MakeDev: Called with %s on path %s\n", p, path);
291 if (!strncmp(p, "ad", 2))
294 else if (!strncmp(p, "wd", 2))
297 else if (!strncmp(p, "wfd", 3))
299 else if (!strncmp(p, "afd", 3))
301 else if (!strncmp(p, "fla", 3))
303 else if (!strncmp(p, "idad", 4))
305 else if (!strncmp(p, "mlxd", 4))
307 else if (!strncmp(p, "amrd", 4))
309 else if (!strncmp(p, "twed", 4))
311 else if (!strncmp(p, "aacd", 4))
313 else if (!strncmp(p, "ar", 2)) /* ATA RAID */
315 else if (!strncmp(p, "da", 2)) /* CAM support */
318 msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
322 msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
332 else if (isdigit(*p)) {
339 msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
344 msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
360 if(c1->type == freebsd)
361 sprintf(buf2, "%sc", c1->name);
364 if (*p < 'a' || *p > 'h') {
365 msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
371 msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
376 if ((pwd = getpwnam("root")) == NULL) {
378 msgDebug("MakeDev: Unable to lookup user \"root\", using 0.\n");
383 if ((grp = getgrnam("operator")) == NULL) {
385 msgDebug("MakeDev: Unable to lookup group \"operator\", using 5.\n");
390 min = unit * 8 + 65536 * slice + part;
391 sprintf(buf, "%s/r%s", path, c1->name);
393 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
394 msgDebug("mknod of %s returned failure status!\n", buf);
397 if (chown(buf, owner, group) == -1) {
398 msgDebug("chown of %s returned failure status!\n", buf);
402 sprintf(buf, "%s/r%s", path, buf2);
404 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
405 msgDebug("mknod of %s returned failure status!\n", buf);
408 if (chown(buf, owner, group) == -1) {
409 msgDebug("chown of %s returned failure status!\n", buf);
413 sprintf(buf, "%s/%s", path, c1->name);
415 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
416 msgDebug("mknod of %s returned failure status!\n", buf);
419 if (chown(buf, owner, group) == -1) {
420 msgDebug("chown of %s returned failure status!\n", buf);
427 MakeDevChunk(struct chunk *c1, const char *path)
431 i = MakeDev(c1, path);
433 MakeDevChunk(c1->next, path);
435 MakeDevChunk(c1->part, path);
440 MakeDevDisk(struct disk *d, const char *path)
442 return MakeDevChunk(d->chunks, path);