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/rules.c,v 1.16.2.4 2001/05/13 20:16:32 jkh Exp $
10 * $DragonFly: src/lib/libdisk/Attic/rules.c,v 1.4 2005/03/13 15:10:03 swildner Exp $
18 #include <sys/types.h>
19 #include <sys/diskslice.h>
20 #include <sys/disklabel.h>
21 #include <sys/diskmbr.h>
25 Track_Aligned(struct disk
*d
, u_long offset
)
29 if (offset
% d
->bios_sect
)
35 Prev_Track_Aligned(struct disk
*d
, u_long offset
)
39 return (offset
/ d
->bios_sect
) * d
->bios_sect
;
43 Next_Track_Aligned(struct disk
*d
, u_long offset
)
47 return Prev_Track_Aligned(d
, offset
+ d
->bios_sect
-1);
51 Cyl_Aligned(struct disk
*d
, u_long offset
)
53 if (!d
->bios_sect
|| !d
->bios_hd
)
55 if (offset
% (d
->bios_sect
* d
->bios_hd
))
61 Prev_Cyl_Aligned(struct disk
*d
, u_long offset
)
63 if (!d
->bios_sect
|| !d
->bios_hd
)
65 return (offset
/ (d
->bios_sect
*d
->bios_hd
)) * d
->bios_sect
* d
->bios_hd
;
69 Next_Cyl_Aligned(struct disk
*d
, u_long offset
)
71 if (!d
->bios_sect
|| !d
->bios_hd
)
73 return Prev_Cyl_Aligned(d
,offset
+ (d
->bios_sect
* d
->bios_hd
)-1);
78 * Chunks of type 'whole' can have max NDOSPART children.
79 * Only one of them can have the "active" flag
82 Rule_000(struct disk
*d
, struct chunk
*c
, char *msg
)
89 for (c1
= c
->part
; c1
; c1
= c1
->next
) {
90 if (c1
->type
!= unused
) continue;
91 if (c1
->flags
& CHUNK_ACTIVE
)
96 sprintf(msg
+ strlen(msg
),
97 "%d is too many children of the 'whole' chunk. Max is %d\n",
100 sprintf(msg
+ strlen(msg
),
101 "Too many active children of 'whole'");
106 * All children of 'whole' and 'extended' must be track-aligned.
107 * Exception: the end can be unaligned if it matches the end of 'whole'
110 Rule_001(struct disk
*d
, struct chunk
*c
, char *msg
)
115 if (c
->type
!= whole
&& c
->type
!= extended
)
117 for (i
= 0, c1
= c
->part
; c1
; c1
= c1
->next
) {
118 if (c1
->type
== unused
) continue;
119 c1
->flags
|= CHUNK_ALIGN
;
120 if (!Track_Aligned(d
, c1
->offset
))
121 sprintf(msg
+ strlen(msg
),
122 "chunk '%s' [%ld..%ld] does not start on a track boundary\n",
123 c1
->name
, c1
->offset
, c1
->end
);
124 if ((c
->type
== whole
|| c
->end
== c1
->end
)
125 || Cyl_Aligned(d
, c1
->end
+ 1))
128 sprintf(msg
+ strlen(msg
),
129 "chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
130 c1
->name
, c1
->offset
, c1
->end
);
136 * Max one 'fat' as child of 'whole'
139 Rule_002(struct disk
*d
, struct chunk
*c
, char *msg
)
144 if (c
->type
!= whole
)
146 for (i
= 0, c1
= c
->part
; c1
; c1
= c1
->next
) {
152 sprintf(msg
+ strlen(msg
),
153 "Max one 'fat' allowed as child of 'whole'\n");
159 * Max one extended as child of 'whole'
162 Rule_003(struct disk
*d
, struct chunk
*c
, char *msg
)
167 if (c
->type
!= whole
)
169 for (i
= 0, c1
= c
->part
; c1
; c1
= c1
->next
) {
170 if (c1
->type
!= extended
)
175 sprintf(msg
+ strlen(msg
),
176 "Max one 'extended' allowed as child of 'whole'\n");
182 * Max seven 'part' as children of 'freebsd'
183 * Max one CHUNK_IS_ROOT child per 'freebsd'
186 Rule_004(struct disk
*d
, struct chunk
*c
, char *msg
)
191 if (c
->type
!= freebsd
)
194 for (c1
= c
->part
; c1
; c1
= c1
->next
) {
195 if (c1
->type
!= part
)
197 if (c1
->flags
& CHUNK_IS_ROOT
)
202 sprintf(msg
+ strlen(msg
),
203 "Max seven partitions per freebsd slice\n");
206 sprintf(msg
+ strlen(msg
),
207 "Max one root partition child per freebsd slice\n");
212 Check_Chunk(struct disk
*d
, struct chunk
*c
, char *msg
)
220 Check_Chunk(d
, c
->part
, msg
);
222 Check_Chunk(d
, c
->next
, msg
);
226 CheckRules(struct disk
*d
)
231 Check_Chunk(d
, d
->chunks
, msg
);
238 ChunkCanBeRoot(struct chunk
*c
)
241 struct disk
*d
= c
->disk
;
245 for (c1
= d
->chunks
->part
; ; ) {
246 for (; c1
; c1
= c1
->next
)
247 if (c1
->offset
<= c
->offset
&& c1
->end
>= c
->end
)
251 "Internal trouble, cannot find this chunk in the chunk-tree\n");
254 if (c1
->type
== freebsd
)
259 if (c1
->type
!= freebsd
) {
261 "The root partition must be in a FreeBSD slice, otherwise\n");
263 "the kernel cannot be booted from it\n");