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.4 2005/03/13 15:10:03 swildner Exp $
21 #include <sys/types.h>
22 #include <sys/disklabel.h>
23 #include <sys/diskslice.h>
24 #include <sys/diskmbr.h>
25 #include <sys/types.h>
32 /* Clone these two from sysinstall because we need our own copies
33 * due to link order problems with `crunch'. Feh!
38 static int debug = 0; /* Allow debugger to tweak it */
43 /* Write something to the debugging port */
45 msgDebug(char *fmt, ...)
49 static int DebugFD = -1;
52 DebugFD = open(_PATH_DEV"ttyv1", O_RDWR);
53 dbg = (char *)alloca(FILENAME_MAX);
54 strcpy(dbg, "DEBUG: ");
56 vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
58 write(DebugFD, dbg, strlen(dbg));
62 Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
64 struct chunk *c1, *c3;
67 if (!strcmp(c->name, "X")) return 0;
69 /* reset all names to "X" */
70 for (c1 = c->part; c1; c1 = c1->next) {
72 c1->name = malloc(12);
73 if(!c1->name) return -1;
77 /* Allocate the first swap-partition we find */
78 for (c1 = c->part; c1; c1 = c1->next) {
79 if (c1->type == unused) continue;
80 if (c1->subtype != FS_SWAP) continue;
81 sprintf(c1->name, "%s%c", c->name, SWAP_PART + 'a');
85 /* Allocate the first root-partition we find */
86 for (c1 = c->part; c1; c1 = c1->next) {
87 if (c1->type == unused) continue;
88 if (!(c1->flags & CHUNK_IS_ROOT)) continue;
89 sprintf(c1->name, "%s%c", c->name, 0 + 'a');
93 /* Try to give them the same as they had before */
94 for (c1 = c->part; c1; c1 = c1->next) {
95 if (strcmp(c1->name, "X")) continue;
96 for(c3 = c->part; c3 ; c3 = c3->next)
97 if (c1 != c3 && !strcmp(c3->name, c1->oname)) {
100 strcpy(c1->name, c1->oname);
105 /* Allocate the rest sequentially */
106 for (c1 = c->part; c1; c1 = c1->next) {
107 const char order[] = "efghabd";
108 if (c1->type == unused) continue;
109 if (strcmp("X", c1->name)) continue;
111 for(j = 0; j < strlen(order); j++) {
112 sprintf(c1->name, "%s%c", c->name, order[j]);
113 for(c3 = c->part; c3 ; c3 = c3->next)
114 if (c1 != c3 && !strcmp(c3->name, c1->name))
118 strcpy(c1->name, "X");
122 for (c1 = c->part; c1; c1 = c1->next) {
130 Fixup_Extended_Names(struct disk *d, struct chunk *c)
135 for (c1 = c->part; c1; c1 = c1->next) {
136 if (c1->type == unused) continue;
138 c1->name = malloc(12);
139 if(!c1->name) return -1;
140 sprintf(c1->name, "%ss%d", d->chunks->name, j++);
141 if (c1->type == freebsd)
142 if (Fixup_FreeBSD_Names(d, c1) != 0)
149 Fixup_Names(struct disk *d)
151 struct chunk *c1, *c2;
159 for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
160 c2->flags &= ~CHUNK_BSD_COMPAT;
161 if (c2->type == unused)
163 if (strcmp(c2->name, "X"))
166 c2->oname = malloc(12);
167 if(!c2->oname) return -1;
168 for(j = 1; j <= NDOSPART; j++) {
169 sprintf(c2->oname, "%ss%d", c1->name, j);
170 for(c3 = c1->part; c3; c3 = c3->next)
171 if (c3 != c2 && !strcmp(c3->name, c2->oname))
174 c2->name = c2->oname;
184 c2->name = strdup(c1->name);
187 for(c2 = c1->part; c2; c2 = c2->next) {
188 if (c2->type == freebsd) {
189 c2->flags |= CHUNK_BSD_COMPAT;
193 for(c2 = c1->part; c2; c2 = c2->next) {
194 if (c2->type == freebsd)
195 Fixup_FreeBSD_Names(d, c2);
196 if (c2->type == extended)
197 Fixup_Extended_Names(d, c2);
203 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))
210 /* Never use the first track */
212 offset += d->bios_sect;
213 size -= d->bios_sect;
216 /* Always end on cylinder boundary */
217 l = (offset+size) % (d->bios_sect * d->bios_hd);
221 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
227 Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
235 for (c1=parent->part; c1; c1 = c1->next) {
236 if (c1->type != unused) continue;
237 if (c1->size < size) continue;
243 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
247 for (c1=parent->part; c1; c1 = c1->next)
248 if (c1->offset == offset)
250 /* barfout(1, "Serious internal trouble"); */
255 MakeDev(struct chunk *c1, const char *path)
258 u_long cmaj, min, unit, part, slice;
259 char buf[BUFSIZ], buf2[BUFSIZ];
267 msgDebug("MakeDev: Called with %s on path %s\n", p, path);
271 if (!strncmp(p, "ad", 2))
273 else if (!strncmp(p, "wfd", 3))
275 else if (!strncmp(p, "afd", 3))
277 else if (!strncmp(p, "fla", 3))
279 else if (!strncmp(p, "idad", 4))
281 else if (!strncmp(p, "mlxd", 4))
283 else if (!strncmp(p, "amrd", 4))
285 else if (!strncmp(p, "twed", 4))
287 else if (!strncmp(p, "aacd", 4))
289 else if (!strncmp(p, "ar", 2)) /* ATA RAID */
291 else if (!strncmp(p, "da", 2)) /* CAM support */
294 msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
298 msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
308 else if (isdigit(*p)) {
314 msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
319 msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
332 if(c1->type == freebsd)
333 sprintf(buf2, "%sc", c1->name);
336 if (*p < 'a' || *p > 'h') {
337 msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
343 msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
348 if ((pwd = getpwnam("root")) == NULL) {
350 msgDebug("MakeDev: Unable to lookup user \"root\", using 0.\n");
355 if ((grp = getgrnam("operator")) == NULL) {
357 msgDebug("MakeDev: Unable to lookup group \"operator\", using 5.\n");
362 min = unit * 8 + 65536 * slice + part;
363 sprintf(buf, "%s/r%s", path, c1->name);
365 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
366 msgDebug("mknod of %s returned failure status!\n", buf);
369 if (chown(buf, owner, group) == -1) {
370 msgDebug("chown of %s returned failure status!\n", buf);
374 sprintf(buf, "%s/r%s", path, buf2);
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/%s", path, c1->name);
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);
399 MakeDevChunk(struct chunk *c1, const char *path)
403 i = MakeDev(c1, path);
405 MakeDevChunk(c1->next, path);
407 MakeDevChunk(c1->part, path);
412 MakeDevDisk(struct disk *d, const char *path)
414 return MakeDevChunk(d->chunks, path);