Codebase list mdadm / 1ffd284
mdmon: support scanning for containers When the given container is '/proc/mdstat' then launch an mdmon instance per container found in /proc/mdstat. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Dan Williams authored 15 years ago root committed 15 years ago
1 changed file(s) with 83 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
274274 exit(2);
275275 }
276276
277 int mdmon(char *devname, int devnum, int scan, char *switchroot);
278
277279 int main(int argc, char *argv[])
280 {
281 char *container_name = NULL;
282 char *switchroot = NULL;
283 int devnum;
284 char *devname;
285 int scan = 0;
286 int status = 0;
287
288 switch (argc) {
289 case 2:
290 container_name = argv[1];
291 break;
292 case 4:
293 if (strcmp(argv[1], "--switch-root") != 0) {
294 fprintf(stderr, "mdmon: unknown argument %s\n", argv[1]);
295 usage();
296 }
297 switchroot = argv[2];
298 container_name = argv[3];
299 break;
300 default:
301 usage();
302 }
303
304 if (strcmp(container_name, "/proc/mdstat") == 0) {
305 struct mdstat_ent *mdstat, *e;
306
307 /* launch an mdmon instance for each container found */
308 scan = 1;
309 mdstat = mdstat_read(0, 0);
310 for (e = mdstat; e; e = e->next) {
311 if (strncmp(e->metadata_version, "external:", 9) == 0 &&
312 !is_subarray(&e->metadata_version[9])) {
313 devname = devnum2devname(e->devnum);
314 status |= mdmon(devname, e->devnum, scan,
315 switchroot);
316 }
317 }
318 free_mdstat(mdstat);
319
320 return status;
321 } else if (strncmp(container_name, "md", 2) == 0) {
322 devnum = devname2devnum(container_name);
323 devname = devnum2devname(devnum);
324 if (strcmp(container_name, devname) != 0)
325 devname = NULL;
326 } else {
327 struct stat st;
328
329 devnum = NoMdDev;
330 if (stat(container_name, &st) == 0)
331 devnum = stat2devnum(&st);
332 if (devnum == NoMdDev)
333 devname = NULL;
334 else
335 devname = devnum2devname(devnum);
336 }
337
338 if (!devname) {
339 fprintf(stderr, "mdmon: %s is not a valid md device name\n",
340 container_name);
341 exit(1);
342 }
343 return mdmon(devname, devnum, scan, switchroot);
344 }
345
346 int mdmon(char *devname, int devnum, int scan, char *switchroot)
278347 {
279348 int mdfd;
280349 struct mdinfo *mdi, *di;
284353 int pfd[2];
285354 int status;
286355 int ignore;
287 char *container_name = NULL;
288 char *switchroot = NULL;
289 int devnum;
290 char *devname;
291
292 switch (argc) {
293 case 2:
294 container_name = argv[1];
295 break;
296 case 4:
297 if (strcmp(argv[1], "--switch-root") != 0) {
298 fprintf(stderr, "mdmon: unknown argument %s\n", argv[1]);
299 usage();
300 }
301 switchroot = argv[2];
302 container_name = argv[3];
303 break;
304 default:
305 usage();
306 }
307
308 if (strncmp(container_name, "md", 2) == 0) {
309 devnum = devname2devnum(container_name);
310 devname = devnum2devname(devnum);
311 if (strcmp(container_name, devname) != 0)
312 devname = NULL;
313 } else {
314 struct stat st;
315
316 devnum = NoMdDev;
317 if (stat(container_name, &st) == 0)
318 devnum = stat2devnum(&st);
319 if (devnum == NoMdDev)
320 devname = NULL;
321 else
322 devname = devnum2devname(devnum);
323 }
324
325 if (!devname) {
326 fprintf(stderr, "mdmon: %s is not a valid md device name\n",
327 container_name);
328 exit(1);
329 }
356
330357 mdfd = open_dev(devnum);
331358 if (mdfd < 0) {
332 fprintf(stderr, "mdmon: %s: %s\n", container_name,
359 fprintf(stderr, "mdmon: %s: %s\n", devname,
333360 strerror(errno));
334 exit(1);
361 return 1;
335362 }
336363 if (md_get_version(mdfd) < 0) {
337364 fprintf(stderr, "mdmon: %s: Not an md device\n",
338 container_name);
339 exit(1);
365 devname);
366 return 1;
340367 }
341368
342369 /* Fork, and have the child tell us when they are ready */
343 if (do_fork()) {
370 if (do_fork() || scan) {
344371 if (pipe(pfd) != 0) {
345372 fprintf(stderr, "mdmon: failed to create pipe\n");
346 exit(1);
373 return 1;
347374 }
348375 switch(fork()) {
349376 case -1:
350377 fprintf(stderr, "mdmon: failed to fork: %s\n",
351378 strerror(errno));
352 exit(1);
379 return 1;
353380 case 0: /* child */
354381 close(pfd[0]);
355382 break;
359386 wait(&status);
360387 status = WEXITSTATUS(status);
361388 }
362 exit(status);
389 return status;
363390 }
364391 } else
365392 pfd[0] = pfd[1] = -1;
385412 }
386413 if (mdi->array.level != UnSet) {
387414 fprintf(stderr, "mdmon: %s is not a container - cannot monitor\n",
388 container_name);
415 devname);
389416 exit(3);
390417 }
391418 if (mdi->array.major_version != -1 ||
392419 mdi->array.minor_version != -2) {
393420 fprintf(stderr, "mdmon: %s does not use external metadata - cannot monitor\n",
394 container_name);
421 devname);
395422 exit(3);
396423 }
397424
398425 container->ss = find_metadata_methods(mdi->text_version);
399426 if (container->ss == NULL) {
400427 fprintf(stderr, "mdmon: %s uses unknown metadata: %s\n",
401 container_name, mdi->text_version);
428 devname, mdi->text_version);
402429 exit(3);
403430 }
404431
480507 }
481508 container->sock = make_control_sock(container->devname);
482509
483 if (container->ss->load_super(container, mdfd, container_name)) {
510 if (container->ss->load_super(container, mdfd, devname)) {
484511 fprintf(stderr, "mdmon: Cannot load metadata for %s\n",
485 container_name);
512 devname);
486513 exit(3);
487514 }
488515 close(mdfd);