rules.c revision 8233
1/* 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 * ---------------------------------------------------------------------------- 8 * 9 * $Id: rules.c,v 1.4 1995/04/30 06:09:27 phk Exp $ 10 * 11 */ 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <unistd.h> 16#include <string.h> 17#include <sys/types.h> 18#include <sys/diskslice.h> 19#include <sys/disklabel.h> 20#include <err.h> 21#include "libdisk.h" 22 23int 24Track_Aligned(struct disk *d, u_long offset) 25{ 26 if (!d->bios_sect) 27 return 1; 28 if (offset % d->bios_sect) 29 return 0; 30 return 1; 31} 32 33u_long 34Prev_Track_Aligned(struct disk *d, u_long offset) 35{ 36 if (!d->bios_sect) 37 return offset; 38 return (offset / d->bios_sect) * d->bios_sect; 39} 40 41u_long 42Next_Track_Aligned(struct disk *d, u_long offset) 43{ 44 if (!d->bios_sect) 45 return offset; 46 return Prev_Track_Aligned(d,offset + d->bios_sect); 47} 48 49int 50Cyl_Aligned(struct disk *d, u_long offset) 51{ 52 if (!d->bios_sect || !d->bios_hd) 53 return 1; 54 if (offset % (d->bios_sect * d->bios_hd)) 55 return 0; 56 return 1; 57} 58 59u_long 60Prev_Cyl_Aligned(struct disk *d, u_long offset) 61{ 62 if (!d->bios_sect || !d->bios_hd) 63 return offset; 64 return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd; 65} 66 67u_long 68Next_Cyl_Aligned(struct disk *d, u_long offset) 69{ 70 if (!d->bios_sect || !d->bios_hd) 71 return offset; 72 return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd)); 73} 74 75/* 76 * Rule#0: 77 * Chunks of type 'whole' can have max NDOSPART children. 78 */ 79void 80Rule_000(struct disk *d, struct chunk *c, char *msg) 81{ 82 int i; 83 struct chunk *c1; 84 85 if (c->type != whole) 86 return; 87 for (i=0, c1=c->part; c1; c1=c1->next) { 88 if (c1->type != reserved) 89 continue; 90 if (c1->type != reserved) 91 continue; 92 i++; 93 } 94 if (i <= NDOSPART) 95 return; 96 sprintf(msg+strlen(msg), 97 "%d is too many children of the 'whole' chunk. Max is %d\n", 98 i, NDOSPART); 99} 100 101/* 102 * Rule#1: 103 * All children of 'whole' must be track-aligned. 104 * Exception: the end can be unaligned if it matches the end of 'whole' 105 */ 106void 107Rule_001(struct disk *d, struct chunk *c, char *msg) 108{ 109 int i; 110 struct chunk *c1; 111 112 if (c->type != whole) 113 return; 114 for (i=0, c1=c->part; c1; c1=c1->next) { 115 if (c1->type == reserved) 116 continue; 117 if (c1->type == unused) 118 continue; 119 if (!Track_Aligned(d,c1->offset)) 120 sprintf(msg+strlen(msg), 121 "chunk '%s' [%ld..%ld] does not start on a track boundary\n", 122 c1->name,c1->offset,c1->end); 123 if (c->end != c1->end && !Cyl_Aligned(d,c1->end+1)) 124 sprintf(msg+strlen(msg), 125 "chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n", 126 c1->name,c1->offset,c1->end); 127 } 128} 129 130/* 131 * Rule#2: 132 * Max one 'fat' as child of 'whole' 133 */ 134void 135Rule_002(struct disk *d, struct chunk *c, char *msg) 136{ 137 int i; 138 struct chunk *c1; 139 140 if (c->type != whole) 141 return; 142 for (i=0, c1=c->part; c1; c1=c1->next) { 143 if (c1->type != fat) 144 continue; 145 i++; 146 } 147 if (i > 1) { 148 sprintf(msg+strlen(msg), 149 "Max one 'fat' allowed as child of 'whole'\n"); 150 } 151} 152 153/* 154 * Rule#3: 155 * Max one extended as child of 'whole' 156 */ 157void 158Rule_003(struct disk *d, struct chunk *c, char *msg) 159{ 160 int i; 161 struct chunk *c1; 162 163 if (c->type != whole) 164 return; 165 for (i=0, c1=c->part; c1; c1=c1->next) { 166 if (c1->type != extended) 167 continue; 168 i++; 169 } 170 if (i > 1) { 171 sprintf(msg+strlen(msg), 172 "Max one 'extended' allowed as child of 'whole'\n"); 173 } 174} 175 176/* 177 * Rule#4: 178 * Max seven 'part' as children of 'freebsd' 179 */ 180void 181Rule_004(struct disk *d, struct chunk *c, char *msg) 182{ 183 int i=0,j=0,k=0; 184 struct chunk *c1; 185 186 if (c->type != freebsd) 187 return; 188 for (c1=c->part; c1; c1=c1->next) { 189 if (c1->type != part) 190 continue; 191 if (c1->subtype == FS_SWAP) 192 j++; 193 if (c1->flags & CHUNK_IS_ROOT) 194 k++; 195 i++; 196 } 197 if (i > 7) { 198 sprintf(msg+strlen(msg), 199 "Max seven 'part' per 'freebsd' chunk\n"); 200 } 201 if (j > 1) { 202 sprintf(msg+strlen(msg), 203 "Max one subtype=FS_SWAP child per 'freebsd' chunk\n"); 204 } 205 if (k > 1) { 206 sprintf(msg+strlen(msg), 207 "Max one CHUNK_IS_ROOT child per 'freebsd' chunk\n"); 208 } 209} 210 211void 212Check_Chunk(struct disk *d, struct chunk *c, char *msg) 213{ 214 Rule_000(d,c,msg); 215 Rule_001(d,c,msg); 216 Rule_002(d,c,msg); 217 Rule_003(d,c,msg); 218 Rule_004(d,c,msg); 219 if (c->part) 220 Check_Chunk(d,c->part,msg); 221 if (c->next) 222 Check_Chunk(d,c->next,msg); 223 return; 224} 225 226char * 227CheckRules(struct disk *d) 228{ 229 char msg[BUFSIZ]; 230 231 *msg = '\0'; 232 Check_Chunk(d,d->chunks,msg); 233 if (*msg) 234 return strdup(msg); 235 return 0; 236} 237