| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: storage.c,v 1.12 2009/01/25 14:25:27 lukem Exp $ */ | | 1 | /* $NetBSD: storage.c,v 1.13 2009/06/23 05:08:22 agc Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright © 2006 Alistair Crooks. All rights reserved. | | 4 | * Copyright © 2006 Alistair Crooks. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * 3. The name of the author may not be used to endorse or promote | | 14 | * 3. The name of the author may not be used to endorse or promote |
| @@ -169,72 +169,111 @@ getsize(conffile_t *cf, devv_t *devvp, e | | | @@ -169,72 +169,111 @@ getsize(conffile_t *cf, devv_t *devvp, e |
169 | case DE_DEVICE: | | 169 | case DE_DEVICE: |
170 | return dp->xv[0].u.dp->len; | | 170 | return dp->xv[0].u.dp->len; |
171 | } | | 171 | } |
172 | } | | 172 | } |
173 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 173 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); |
174 | (void) fprintf(stderr, "Warning: sub-device/extent `%s' not found\n", s); | | 174 | (void) fprintf(stderr, "Warning: sub-device/extent `%s' not found\n", s); |
175 | return 0; | | 175 | return 0; |
176 | } | | 176 | } |
177 | | | 177 | |
178 | /* allocate space for a device */ | | 178 | /* allocate space for a device */ |
179 | static int | | 179 | static int |
180 | do_device(conffile_t *cf, devv_t *devvp, extv_t *evp, ent_t *ep) | | 180 | do_device(conffile_t *cf, devv_t *devvp, extv_t *evp, ent_t *ep) |
181 | { | | 181 | { |
182 | if (find_device(devvp, ep->sv.v[DEVICE_NAME_COL]) != NULL) { | | 182 | disc_device_t *disk; |
183 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 183 | char *device; |
184 | (void) fprintf(stderr, "Error: attempt to re-define device `%s'\n", ep->sv.v[DEVICE_NAME_COL]); | | 184 | |
| | | 185 | device = ep->sv.v[DEVICE_NAME_COL]; |
| | | 186 | if ((disk = find_device(devvp, device)) != NULL) { |
| | | 187 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), |
| | | 188 | conffile_get_lineno(cf)); |
| | | 189 | (void) fprintf(stderr, |
| | | 190 | "Error: attempt to re-define device `%s'\n", |
| | | 191 | device); |
185 | return 0; | | 192 | return 0; |
186 | } | | 193 | } |
187 | ALLOC(disc_device_t, devvp->v, devvp->size, devvp->c, 14, 14, "do_device", exit(EXIT_FAILURE)); | | 194 | ALLOC(disc_device_t, devvp->v, devvp->size, devvp->c, 14, 14, |
188 | devvp->v[devvp->c].dev = strdup(ep->sv.v[DEVICE_NAME_COL]); | | 195 | "do_device", exit(EXIT_FAILURE)); |
189 | devvp->v[devvp->c].raid = (strncasecmp(ep->sv.v[DEVICE_RAIDLEVEL_COL], "raid", 4) == 0) ? atoi(&ep->sv.v[DEVICE_RAIDLEVEL_COL][4]) : 0; | | 196 | disk = &devvp->v[devvp->c]; |
190 | devvp->v[devvp->c].size = ep->sv.c - 2; | | 197 | disk->dev = strdup(device); |
191 | devvp->v[devvp->c].len = getsize(cf, devvp, evp, ep->sv.v[DEVICE_LENGTH_COL]); | | 198 | disk->raid = |
192 | NEWARRAY(disc_de_t, devvp->v[devvp->c].xv, ep->sv.c - 2, "do_device", exit(EXIT_FAILURE)); | | 199 | (strncasecmp(ep->sv.v[DEVICE_RAIDLEVEL_COL], "raid", 4) == 0) ? |
193 | for (devvp->v[devvp->c].c = 0 ; devvp->v[devvp->c].c < devvp->v[devvp->c].size ; devvp->v[devvp->c].c++) { | | 200 | atoi(&ep->sv.v[DEVICE_RAIDLEVEL_COL][4]) : 0; |
194 | if ((devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp = find_extent(evp, ep->sv.v[devvp->v[devvp->c].c + 2])) != NULL) { | | 201 | disk->size = ep->sv.c - 2; |
195 | if (devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->used) { | | 202 | disk->len = getsize(cf, devvp, evp, ep->sv.v[DEVICE_LENGTH_COL]); |
196 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 203 | NEWARRAY(disc_de_t, disk->xv, ep->sv.c - 2, "do_device", |
197 | (void) fprintf(stderr, "Error: extent `%s' has already been used\n", ep->sv.v[devvp->v[devvp->c].c + 2]); | | 204 | exit(EXIT_FAILURE)); |
| | | 205 | for (disk->c = 0 ; disk->c < disk->size ; disk->c++) { |
| | | 206 | disk->xv[disk->c].u.xp = |
| | | 207 | find_extent(evp, ep->sv.v[disk->c + 2]); |
| | | 208 | if (disk->xv[disk->c].u.xp != NULL) { |
| | | 209 | if (disk->xv[disk->c].u.xp->used) { |
| | | 210 | (void) fprintf(stderr, "%s:%d: ", |
| | | 211 | conffile_get_name(cf), |
| | | 212 | conffile_get_lineno(cf)); |
| | | 213 | (void) fprintf(stderr, |
| | | 214 | "Error: extent `%s' has already been used\n", |
| | | 215 | ep->sv.v[disk->c + 2]); |
198 | return 0; | | 216 | return 0; |
199 | } | | 217 | } |
200 | if (devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->len != devvp->v[devvp->c].len && devvp->v[devvp->c].raid != 0) { | | 218 | if (disk->xv[disk->c].u.xp->len != disk->len && |
201 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 219 | disk->raid != 0) { |
202 | (void) fprintf(stderr, "Error: extent `%s' has size %" PRIu64 ", not %" PRIu64"\n", ep->sv.v[devvp->v[devvp->c].c + 2], devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->len, devvp->v[devvp->c].len); | | 220 | (void) fprintf(stderr, "%s:%d: ", |
| | | 221 | conffile_get_name(cf), |
| | | 222 | conffile_get_lineno(cf)); |
| | | 223 | (void) fprintf(stderr, |
| | | 224 | "Error: extent `%s' has size %" PRIu64 |
| | | 225 | ", not %" PRIu64"\n", |
| | | 226 | ep->sv.v[disk->c + 2], |
| | | 227 | disk->xv[disk->c].u.xp->len, |
| | | 228 | disk->len); |
203 | return 0; | | 229 | return 0; |
204 | } | | 230 | } |
205 | devvp->v[devvp->c].xv[devvp->v[devvp->c].c].type = DE_EXTENT; | | 231 | disk->xv[disk->c].type = DE_EXTENT; |
206 | devvp->v[devvp->c].xv[devvp->v[devvp->c].c].size = devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->len; | | 232 | disk->xv[disk->c].size = disk->xv[disk->c].u.xp->len; |
207 | devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->used = 1; | | 233 | disk->xv[disk->c].u.xp->used = 1; |
208 | } else if ((devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp = find_device(devvp, ep->sv.v[devvp->v[devvp->c].c + 2])) != NULL) { | | 234 | } else if ((disk->xv[disk->c].u.dp = |
209 | if (devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp->used) { | | 235 | find_device(devvp, ep->sv.v[disk->c + 2])) != NULL) { |
210 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 236 | if (disk->xv[disk->c].u.dp->used) { |
211 | (void) fprintf(stderr, "Error: device `%s' has already been used\n", ep->sv.v[devvp->v[devvp->c].c + 2]); | | 237 | (void) fprintf(stderr, "%s:%d: ", |
| | | 238 | conffile_get_name(cf), |
| | | 239 | conffile_get_lineno(cf)); |
| | | 240 | (void) fprintf(stderr, |
| | | 241 | "Error: device `%s' has already been used\n", |
| | | 242 | ep->sv.v[disk->c + 2]); |
212 | return 0; | | 243 | return 0; |
213 | } | | 244 | } |
214 | devvp->v[devvp->c].xv[devvp->v[devvp->c].c].type = DE_DEVICE; | | 245 | disk->xv[disk->c].type = DE_DEVICE; |
215 | devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp->used = 1; | | 246 | disk->xv[disk->c].u.dp->used = 1; |
216 | devvp->v[devvp->c].xv[devvp->v[devvp->c].c].size = devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp->len; | | 247 | disk->xv[disk->c].size = disk->xv[disk->c].u.dp->len; |
217 | } else { | | 248 | } else { |
218 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 249 | (void) fprintf(stderr, "%s:%d: ", |
219 | (void) fprintf(stderr, "Error: no extent or device found for `%s'\n", ep->sv.v[devvp->v[devvp->c].c + 2]); | | 250 | conffile_get_name(cf), |
| | | 251 | conffile_get_lineno(cf)); |
| | | 252 | (void) fprintf(stderr, |
| | | 253 | "Error: no extent or device found for `%s'\n", |
| | | 254 | ep->sv.v[disk->c + 2]); |
220 | return 0; | | 255 | return 0; |
221 | } | | 256 | } |
222 | } | | 257 | } |
223 | if (devvp->v[devvp->c].raid == 1) { | | 258 | if (disk->raid == 1) { |
224 | /* check we have more than 1 device/extent */ | | 259 | /* check we have more than 1 device/extent */ |
225 | if (devvp->v[devvp->c].c < 2) { | | 260 | if (disk->c < 2) { |
226 | (void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf)); | | 261 | (void) fprintf(stderr, "%s:%d: ", |
227 | (void) fprintf(stderr, "Error: device `%s' is specified as RAID1, but has only %d sub-devices/extents\n", devvp->v[devvp->c].dev, devvp->v[devvp->c].c); | | 262 | conffile_get_name(cf), |
| | | 263 | conffile_get_lineno(cf)); |
| | | 264 | (void) fprintf(stderr, |
| | | 265 | "Error: device `%s' is RAID1, but has only %d sub-devices/extents\n", |
| | | 266 | disk->dev, disk->c); |
228 | return 0; | | 267 | return 0; |
229 | } | | 268 | } |
230 | } | | 269 | } |
231 | devvp->c += 1; | | 270 | devvp->c += 1; |
232 | return 1; | | 271 | return 1; |
233 | } | | 272 | } |
234 | | | 273 | |
235 | /* find a target by name */ | | 274 | /* find a target by name */ |
236 | static disc_target_t * | | 275 | static disc_target_t * |
237 | find_target(targv_t *tvp, char *s) | | 276 | find_target(targv_t *tvp, char *s) |
238 | { | | 277 | { |
239 | size_t i; | | 278 | size_t i; |
240 | | | 279 | |