X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Incremental.c;h=2e23677dc88820c4229b0ee561ce9f385a18c051;hp=0fb9afd3c8aa55717b86e8fa7ea445fb937f82f2;hb=598f0d58ac3544e25f90f2d34337e15764f4d877;hpb=a19c88b83db3cc25affb75fe2d5531c964379d96;ds=sidebyside diff --git a/Incremental.c b/Incremental.c index 0fb9afd3..2e23677d 100644 --- a/Incremental.c +++ b/Incremental.c @@ -40,7 +40,7 @@ int Incremental(char *devname, int verbose, int runstop, struct supertype *st, char *homehost, int autof) { /* Add this device to an array, creating the array if necessary - * and starting the array if sensibe or - if runstop>0 - if possible. + * and starting the array if sensible or - if runstop>0 - if possible. * * This has several steps: * @@ -140,9 +140,17 @@ int Incremental(char *devname, int verbose, int runstop, close(dfd); return 1; } - st->ss->getinfo_super(st, &info); close (dfd); + if (st->ss->container_content) { + /* This is a pre-built container array, so we do something + * rather different. + */ + return Incremental_container(st, devname, verbose, runstop, + autof); + } + + st->ss->getinfo_super(st, &info); /* 3/ Check if there is a match in mdadm.conf */ array_list = conf_get_ident(NULL); @@ -708,3 +716,90 @@ int IncrementalScan(int verbose) } return rv; } + +int Incremental_container(struct supertype *st, char *devname, int verbose, + int runstop, int autof) +{ + /* Collect the contents of this container and for each + * array, choose a device name and assemble the array. + */ + + struct mdinfo *list = st->ss->container_content(st); + struct mdinfo *ra; + + for (ra = list ; ra ; ra = ra->next) { + struct mdinfo *sra; + struct mdinfo *dev; + int devnum = -1; + int mdfd; + char chosen_name[1024]; + int usepart = 1; + char *n; + int working = 0; + + if ((autof&7) == 3 || (autof&7) == 5) + usepart = 0; + + n = ra->name; + if (*n == 'd') + n++; + if (*n) { + devnum = strtoul(n, &n, 10); + if (devnum >= 0 && (*n == 0 || *n == ' ')) { + /* Use this devnum */ + usepart = (ra->name[0] == 'd'); + if (mddev_busy(usepart ? (-1-devnum) : devnum)) + devnum = -1; + } else + devnum = -1; + } + + if (devnum >= 0) + devnum = usepart ? (-1-devnum) : devnum; + else + devnum = find_free_devnum(usepart); + mdfd = open_mddev_devnum(NULL, devnum, ra->name, + chosen_name, autof>>3); + + if (mdfd < 0) { + fprintf(stderr, Name ": failed to open %s: %s.\n", + chosen_name, strerror(errno)); + return 2; + } + + sra = sysfs_read(mdfd, 0, 0); + + sysfs_set_array(sra, ra); + for (dev = ra->devs; dev; dev = dev->next) { + char buf[20]; + int dfd; + sprintf(buf, "%d:%d", dev->disk.major, dev->disk.minor); + dfd = dev_open(buf, O_RDONLY); + if (sysfs_add_disk(sra, dfd, dev) == 0) + working++; + } + if (runstop > 0 || working >= ra->array.working_disks) { + switch(ra->array.level) { + case LEVEL_LINEAR: + case LEVEL_MULTIPATH: + case 0: + sysfs_set_str(sra, NULL, "array_state", + "active"); + break; + default: + sysfs_set_str(sra, NULL, "array_state", + "readonly"); + break; + } + if (verbose >= 0) + printf("Started %s with %d devices\n", + chosen_name, working); + } else + if (verbose >= 0) + printf("%s assembled with %d devices but " + "not started\n", + chosen_name, working); + close(mdfd); + } + return 0; +}