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.3 2003/11/10 06:14:40 dillon 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);
197 if (c2->type == extended)
198 Fixup_Extended_Names(d, c2);
206 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags, const char *sname)
208 Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
214 if(!(flags & CHUNK_FORCE_ALL))
217 /* Never use the first cylinder */
219 offset += (d->bios_sect * d->bios_hd);
220 size -= (d->bios_sect * d->bios_hd);
223 /* Never use the first track */
225 offset += d->bios_sect;
226 size -= d->bios_sect;
230 /* Always end on cylinder boundary */
231 l = (offset+size) % (d->bios_sect * d->bios_hd);
236 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
238 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
245 Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
253 for (c1=parent->part; c1; c1 = c1->next) {
254 if (c1->type != unused) continue;
255 if (c1->size < size) continue;
262 i = Add_Chunk(d, offset, size, "X", type, subtype, flags, "-");
264 i = Add_Chunk(d, offset, size, "X", type, subtype, flags);
269 for (c1=parent->part; c1; c1 = c1->next)
270 if (c1->offset == offset)
272 /* barfout(1, "Serious internal trouble"); */
277 MakeDev(struct chunk *c1, const char *path)
280 u_long cmaj, min, unit, part, slice;
281 char buf[BUFSIZ], buf2[BUFSIZ];
289 msgDebug("MakeDev: Called with %s on path %s\n", p, path);
293 if (!strncmp(p, "ad", 2))
296 else if (!strncmp(p, "wd", 2))
299 else if (!strncmp(p, "wfd", 3))
301 else if (!strncmp(p, "afd", 3))
303 else if (!strncmp(p, "fla", 3))
305 else if (!strncmp(p, "idad", 4))
307 else if (!strncmp(p, "mlxd", 4))
309 else if (!strncmp(p, "amrd", 4))
311 else if (!strncmp(p, "twed", 4))
313 else if (!strncmp(p, "aacd", 4))
315 else if (!strncmp(p, "ar", 2)) /* ATA RAID */
317 else if (!strncmp(p, "da", 2)) /* CAM support */
320 msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
324 msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
334 else if (isdigit(*p)) {
341 msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
346 msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
362 if(c1->type == freebsd)
363 sprintf(buf2, "%sc", c1->name);
366 if (*p < 'a' || *p > 'h') {
367 msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
373 msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
378 if ((pwd = getpwnam("root")) == NULL) {
380 msgDebug("MakeDev: Unable to lookup user \"root\", using 0.\n");
385 if ((grp = getgrnam("operator")) == NULL) {
387 msgDebug("MakeDev: Unable to lookup group \"operator\", using 5.\n");
392 min = unit * 8 + 65536 * slice + part;
393 sprintf(buf, "%s/r%s", path, c1->name);
395 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
396 msgDebug("mknod of %s returned failure status!\n", buf);
399 if (chown(buf, owner, group) == -1) {
400 msgDebug("chown of %s returned failure status!\n", buf);
404 sprintf(buf, "%s/r%s", path, buf2);
406 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
407 msgDebug("mknod of %s returned failure status!\n", buf);
410 if (chown(buf, owner, group) == -1) {
411 msgDebug("chown of %s returned failure status!\n", buf);
415 sprintf(buf, "%s/%s", path, c1->name);
417 if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
418 msgDebug("mknod of %s returned failure status!\n", buf);
421 if (chown(buf, owner, group) == -1) {
422 msgDebug("chown of %s returned failure status!\n", buf);
429 MakeDevChunk(struct chunk *c1, const char *path)
433 i = MakeDev(c1, path);
435 MakeDevChunk(c1->next, path);
437 MakeDevChunk(c1->part, path);
442 MakeDevDisk(struct disk *d, const char *path)
444 return MakeDevChunk(d->chunks, path);