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
);