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 $
10 * $DragonFly: src/lib/libdisk/Attic/create_chunk.c,v 1.2 2003/06/17 04:26:49 dillon Exp $
21 #include <sys/types.h>
22 #include <sys/disklabel.h>
23 #include <sys/diskslice.h>
24 #include <sys/types.h>
31 /* Clone these two from sysinstall because we need our own copies
32 * due to link order problems with `crunch'. Feh!
37 static int debug = 0; /* Allow debugger to tweak it */
42 /* Write something to the debugging port */
44 msgDebug(char *fmt, ...)
48 static int DebugFD = -1;
51 DebugFD = open(_PATH_DEV"ttyv1", O_RDWR);
52 dbg = (char *)alloca(FILENAME_MAX);
53 strcpy(dbg, "DEBUG: ");
55 vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
57 write(DebugFD, dbg, strlen(dbg));
61 Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
63 struct chunk *c1, *c3;
66 if (!strcmp(c->name, "X")) return 0;
68 /* reset all names to "X" */
69 for (c1 = c->part; c1; c1 = c1->next) {
71 c1->name = malloc(12);
72 if(!c1->name) return -1;
76 /* Allocate the first swap-partition we find */
77 for (c1 = c->part; c1; c1 = c1->next) {
78 if (c1->type == unused) continue;
79 if (c1->subtype != FS_SWAP) continue;
80 sprintf(c1->name, "%s%c", c->name, SWAP_PART + 'a');
84 /* Allocate the first root-partition we find */
85 for (c1 = c->part; c1; c1 = c1->next) {
86 if (c1->type == unused) continue;
87 if (!(c1->flags & CHUNK_IS_ROOT)) continue;
88 sprintf(c1->name, "%s%c", c->name, 0 + 'a');
92 /* Try to give them the same as they had before */
93 for (c1 = c->part; c1; c1 = c1->next) {
94 if (strcmp(c1->name, "X")) continue;
95 for(c3 = c->part; c3 ; c3 = c3->next)
96 if (c1 != c3 && !strcmp(c3->name, c1->oname)) {
99 strcpy(c1->name, c1->oname);
104 /* Allocate the rest sequentially */
105 for (c1 = c->part; c1; c1 = c1->next) {
106 const char order[] = "efghabd";
107 if (c1->type == unused) continue;
108 if (strcmp("X", c1->name)) continue;
110 for(j = 0; j < strlen(order); j++) {
111 sprintf(c1->name, "%s%c", c->name, order[j]);
112 for(c3 = c->part; c3 ; c3 = c3->next)
113 if (c1 != c3 && !strcmp(c3->name, c1->name))
117 strcpy(c1->name, "X");
121 for (c1 = c->part; c1; c1 = c1->next) {
129 Fixup_Extended_Names(struct disk *d, struct chunk *c)
134 for (c1 = c->part; c1; c1 = c1->next) {
135 if (c1->type == unused) continue;
137 c1->name = malloc(12);
138 if(!c1->name) return -1;
139 sprintf(c1->name, "%ss%d", d->chunks->name, j++);
140 if (c1->type == freebsd)
141 if (Fixup_FreeBSD_Names(d, c1) != 0)
148 Fixup_Names(struct disk *d)
150 struct chunk *c1, *c2;
158 for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
159 c2->flags &= ~CHUNK_BSD_COMPAT;
160 if (c2->type == unused)
162 if (strcmp(c2->name, "X"))
165 c2->oname = malloc(12);
166 if(!c2->oname) return -1;
167 for(j = 1; j <= NDOSPART; j++) {
168 sprintf(c2->oname, "%ss%d", c1->name, j);
169 for(c3 = c1->part; c3; c3 = c3->next)
170 if (c3 != c2 && !strcmp(c3->name, c2->oname))
173 c2->name = c2->oname;
183 c2->name = strdup(c1->name);
186 for(c2 = c1->part; c2; c2 = c2->next) {
187 if (c2->type == freebsd) {
188 c2->flags |= CHUNK_BSD_COMPAT;
192 for(c2 = c1->part; c2; c2 = c2->next) {
193 if (c2->type == freebsd)
194 Fixup_FreeBSD_Names(d, c2);
196 if (c2->type == extended)
197 Fixup_Extended_Names(d, c2);
205 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags, const char *sname)
207 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
213 if(!(flags & CHUNK_FORCE_ALL))
216 /* Never use the first cylinder */
218 offset += (d->bios_sect * d->bios_hd);
219 size -= (d->bios_sect * d->bios_hd);
222 /* Never use the first track */
224 offset += d->bios_sect;
225 size -= d->bios_sect;
229 /* Always end on cylinder boundary */
230 l = (offset+size) % (d->bios_sect * d->bios_hd);
235 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
237 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
244 Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
252 for (c1=parent->part; c1; c1 = c1->next) {
253 if (c1->type != unused) continue;
254 if (c1->size < size) continue;
261 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, "-");
263 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
268 for (c1=parent->part; c1; c1 = c1->next)
269 if (c1->offset == offset)
271 /* barfout(1, "Serious internal trouble"); */
276 MakeDev(struct chunk *c1, const char *path)
279 u_long cmaj, min, unit, part, slice;
280 char buf[BUFSIZ], buf2[BUFSIZ];
288 msgDebug("MakeDev: Called with %s on path %s\n", p, path);
292 if (!strncmp(p, "ad", 2))
295 else if (!strncmp(p, "wd", 2))
298 else if (!strncmp(p, "wfd", 3))
300 else if (!strncmp(p, "afd", 3))
302 else if (!strncmp(p, "fla", 3))
304 else if (!strncmp(p, "idad", 4))
306 else if (!strncmp(p, "mlxd", 4))
308 else if (!strncmp(p, "amrd", 4))
310 else if (!strncmp(p, "twed", 4))
312 else if (!strncmp(p, "aacd", 4))
314 else if (!strncmp(p, "ar", 2)) /* ATA RAID */
316 else if (!strncmp(p, "da", 2)) /* CAM support */
319 msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
323 msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
333 else if (isdigit(*p)) {
340 msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
345 msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
361 if(c1->type == freebsd)
362 sprintf(buf2, "%sc", c1->name);
365 if (*p < 'a' || *p > 'h') {
366 msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
372 msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
377 if ((pwd = getpwnam("root")) == NULL) {
379 msgDebug("MakeDev: Unable to lookup user \"root\", using 0.\n");
384 if ((grp = getgrnam("operator")) == NULL) {
386 msgDebug("MakeDev: Unable to lookup group \"operator\", using 5.\n");
391 min = unit * 8 + 65536 * slice + part;
392 sprintf(buf, "%s/r%s", path, c1->name);
394 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
395 msgDebug("mknod of %s returned failure status!\n", buf);
398 if (chown(buf, owner, group) == -1) {
399 msgDebug("chown of %s returned failure status!\n", buf);
403 sprintf(buf, "%s/r%s", path, buf2);
405 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
406 msgDebug("mknod of %s returned failure status!\n", buf);
409 if (chown(buf, owner, group) == -1) {
410 msgDebug("chown of %s returned failure status!\n", buf);
414 sprintf(buf, "%s/%s", path, c1->name);
416 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
417 msgDebug("mknod of %s returned failure status!\n", buf);
420 if (chown(buf, owner, group) == -1) {
421 msgDebug("chown of %s returned failure status!\n", buf);
428 MakeDevChunk(struct chunk *c1, const char *path)
432 i = MakeDev(c1, path);
434 MakeDevChunk(c1->next, path);
436 MakeDevChunk(c1->part, path);
441 MakeDevDisk(struct disk *d, const char *path)
443 return MakeDevChunk(d->chunks, path);