pr_err("container %s now has %d device%s\n",
chosen_name, info.array.working_disks,
info.array.working_disks == 1?"":"s");
+ sysfs_rules_apply(chosen_name, &info);
wait_for(chosen_name, mdfd);
if (st->ss->external)
strcpy(devnm, fd2devnm(mdfd));
struct supertype *st2 = NULL;
char *devname = NULL;
unsigned long long devsectors;
+ char *pathlist[2];
if (de->d_ino == 0 || de->d_name[0] == '.' ||
(de->d_type != DT_LNK && de->d_type != DT_UNKNOWN))
/* This is a partition - skip it */
goto next;
- pol2 = path_policy(de->d_name, type_disk);
+ pathlist[0] = de->d_name;
+ pathlist[1] = NULL;
+ pol2 = path_policy(pathlist, type_disk);
domain_merge(&domlist, pol2, st ? st->ss->name : NULL);
if (domain_test(domlist, pol, st ? st->ss->name : NULL) != 1)
sysfs_free(sra);
}
}
+ map_free(mapl);
return rv;
}
int trustworthy;
struct mddev_ident *match;
int rv = 0;
- struct domainlist *domains;
- struct map_ent *smp;
- int suuid[4];
- int sfd;
- int ra_blocked = 0;
- int ra_all = 0;
int result = 0;
st->ss->getinfo_super(st, &info, NULL);
struct map_ent *mp;
struct mddev_ident *match = NULL;
- ra_all++;
/* do not activate arrays blocked by metadata handler */
if (ra->array.state & (1 << MD_SB_BLOCK_VOLUME)) {
pr_err("Cannot activate array %s in %s.\n",
ra->text_version, devname);
- ra_blocked++;
continue;
}
mp = map_by_uuid(&map, ra->uuid);
assemble_container_content(st, mdfd, ra, c,
chosen_name, &result);
+ map_free(map);
+ map = NULL;
close(mdfd);
}
if (c->export && result) {
}
printf("\n");
}
-
- /* don't move spares to container with volume being activated
- when all volumes are blocked */
- if (ra_all == ra_blocked)
- return 0;
-
- /* Now move all suitable spares from spare container */
- domains = domain_from_array(list, st->ss->name);
- memcpy(suuid, uuid_zero, sizeof(int[4]));
- if (domains &&
- (smp = map_by_uuid(&map, suuid)) != NULL &&
- (sfd = open(smp->path, O_RDONLY)) >= 0) {
- /* spare container found */
- struct supertype *sst =
- super_imsm.match_metadata_desc("imsm");
- struct mdinfo *sinfo;
-
- if (!sst->ss->load_container(sst, sfd, NULL)) {
- struct spare_criteria sc = {0, 0};
-
- if (st->ss->get_spare_criteria)
- st->ss->get_spare_criteria(st, &sc);
-
- close(sfd);
- sinfo = container_choose_spares(sst, &sc,
- domains, NULL,
- st->ss->name, 0);
- sst->ss->free_super(sst);
- if (sinfo){
- int count = 0;
- struct mdinfo *disks = sinfo->devs;
- while (disks) {
- /* move spare from spare
- * container to currently
- * assembled one
- */
- if (move_spare(
- smp->path,
- devname,
- makedev(disks->disk.major,
- disks->disk.minor)))
- count++;
- disks = disks->next;
- }
- if (count)
- pr_err("Added %d spare%s to %s\n",
- count, count>1?"s":"", devname);
- }
- sysfs_free(sinfo);
- } else
- close(sfd);
- }
- domain_free(domains);
return 0;
}
int pid = fork();
int status;
if (pid == 0) {
+ manage_fork_fds(1);
execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL);
execl("/bin/udisks", "udisks", arg1, arg2, NULL);
exit(1);
;
}
+static int force_remove(char *devnm, int fd, struct mdinfo *mdi, int verbose)
+{
+ int rv;
+ int devid = devnm2devid(devnm);
+
+ run_udisks("--unmount", map_dev(major(devid), minor(devid), 0));
+ rv = Manage_stop(devnm, fd, verbose, 1);
+ if (rv) {
+ /* At least we can try to trigger a 'remove' */
+ sysfs_uevent(mdi, "remove");
+ if (verbose)
+ pr_err("Fail to stop %s too.\n", devnm);
+ }
+ return rv;
+}
+
+static void remove_from_member_array(struct mdstat_ent *memb,
+ struct mddev_dev *devlist, int verbose)
+{
+ int rv;
+ struct mdinfo mmdi;
+ int subfd = open_dev(memb->devnm);
+
+ if (subfd >= 0) {
+ rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose,
+ 0, NULL, 0);
+ if (rv & 2) {
+ if (sysfs_init(&mmdi, -1, memb->devnm))
+ pr_err("unable to initialize sysfs for: %s\n",
+ memb->devnm);
+ else
+ force_remove(memb->devnm, subfd, &mmdi,
+ verbose);
+ }
+ close(subfd);
+ }
+}
+
/*
* IncrementalRemove - Attempt to see if the passed in device belongs to any
* raid arrays, and if so first fail (if needed) and then remove the device.
strncmp(ent->metadata_version, "external:", 9) == 0) {
struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *memb;
- for (memb = mdstat ; memb ; memb = memb->next)
- if (is_container_member(memb, ent->devnm)) {
- int subfd = open_dev(memb->devnm);
- if (subfd >= 0) {
- rv |= Manage_subdevs(
- memb->devnm, subfd,
- &devlist, verbose, 0,
- NULL, 0);
- close(subfd);
- }
- }
+ for (memb = mdstat ; memb ; memb = memb->next) {
+ if (is_container_member(memb, ent->devnm))
+ remove_from_member_array(memb,
+ &devlist, verbose);
+ }
free_mdstat(mdstat);
- } else
+ } else {
rv |= Manage_subdevs(ent->devnm, mdfd, &devlist,
verbose, 0, NULL, 0);
- if (rv & 2) {
+ if (rv & 2) {
/* Failed due to EBUSY, try to stop the array.
* Give udisks a chance to unmount it first.
*/
- int devid = devnm2devid(ent->devnm);
- run_udisks("--unmount", map_dev(major(devid),minor(devid), 0));
- rv = Manage_stop(ent->devnm, mdfd, verbose, 1);
- if (rv)
- /* At least we can try to trigger a 'remove' */
- sysfs_uevent(&mdi, "remove");
- if (verbose) {
- if (rv)
- pr_err("Fail to stop %s too.\n", ent->devnm);
+ rv = force_remove(ent->devnm, mdfd, &mdi, verbose);
+ goto end;
}
- } else {
- devlist.disposition = 'r';
- rv = Manage_subdevs(ent->devnm, mdfd, &devlist,
- verbose, 0, NULL, 0);
}
+
+ devlist.disposition = 'r';
+ rv = Manage_subdevs(ent->devnm, mdfd, &devlist,
+ verbose, 0, NULL, 0);
+end:
close(mdfd);
free_mdstat(ent);
return rv;