summaryrefslogtreecommitdiffstats
path: root/Assemble.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-25 06:14:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-25 06:14:19 +0000
commit50f2ad8e92ef06e4dee6d7070049a96231d3a8ee (patch)
treeb7cda9c5caad5948899bf7d6551262d9d7d86d09 /Assemble.c
parentAdding upstream version 4.3+20240412. (diff)
downloadmdadm-50f2ad8e92ef06e4dee6d7070049a96231d3a8ee.tar.xz
mdadm-50f2ad8e92ef06e4dee6d7070049a96231d3a8ee.zip
Adding upstream version 4.3+20240723.upstream/4.3+20240723
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'Assemble.c')
-rw-r--r--Assemble.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/Assemble.c b/Assemble.c
index f6c5b99..77f2b50 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -567,6 +567,9 @@ static int select_devices(struct mddev_dev *devlist,
tmpdev->used = 1;
content = *contentp;
+ if (!st)
+ return -1;
+
if (!st->sb) {
/* we need sb from one of the spares */
int dfd = dev_open(tmpdev->devname, O_RDONLY);
@@ -652,7 +655,9 @@ static int load_devices(struct devs *devices, char *devmap,
/* prepare useful information in info structures */
struct stat stb2;
int err;
- fstat(mdfd, &stb2);
+
+ if (fstat(mdfd, &stb2) != 0)
+ goto error;
if (c->update == UOPT_UUID && !ident->uuid_set)
random_uuid((__u8 *)ident->uuid);
@@ -675,13 +680,10 @@ static int load_devices(struct devs *devices, char *devmap,
devname);
if (dfd >= 0)
close(dfd);
- close(mdfd);
- free(devices);
- free(devmap);
tst->ss->free_super(tst);
free(tst);
*stp = st;
- return -1;
+ goto error;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
@@ -715,12 +717,9 @@ static int load_devices(struct devs *devices, char *devmap,
map_num(update_options, c->update), tst->ss->name);
tst->ss->free_super(tst);
free(tst);
- close(mdfd);
close(dfd);
- free(devices);
- free(devmap);
*stp = st;
- return -1;
+ goto error;
}
if (c->update == UOPT_UUID &&
!ident->uuid_set) {
@@ -751,18 +750,23 @@ static int load_devices(struct devs *devices, char *devmap,
devname);
if (dfd >= 0)
close(dfd);
- close(mdfd);
- free(devices);
- free(devmap);
tst->ss->free_super(tst);
free(tst);
*stp = st;
- return -1;
+ goto error;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
}
- fstat(dfd, &stb);
+ if (fstat(dfd, &stb) != 0) {
+ close(dfd);
+ free(devices);
+ free(devmap);
+ tst->ss->free_super(tst);
+ free(tst);
+ *stp = st;
+ return -1;
+ }
close(dfd);
if (c->verbose > 0)
@@ -814,12 +818,12 @@ static int load_devices(struct devs *devices, char *devmap,
if (i >= bestcnt) {
int newbestcnt = i+10;
int *newbest = xmalloc(sizeof(int)*newbestcnt);
- int c;
- for (c=0; c < newbestcnt; c++)
- if (c < bestcnt)
- newbest[c] = best[c];
+ int cc;
+ for (cc = 0; cc < newbestcnt; cc++)
+ if (cc < bestcnt)
+ newbest[cc] = best[cc];
else
- newbest[c] = -1;
+ newbest[cc] = -1;
if (best)free(best);
best = newbest;
bestcnt = newbestcnt;
@@ -842,12 +846,9 @@ static int load_devices(struct devs *devices, char *devmap,
inargv ? "the list" :
"the\n DEVICE list in mdadm.conf"
);
- close(mdfd);
- free(devices);
- free(devmap);
free(best);
*stp = st;
- return -1;
+ goto error;
}
if (best[i] == -1 || (devices[best[i]].i.events
< devices[devcnt].i.events))
@@ -863,6 +864,13 @@ static int load_devices(struct devs *devices, char *devmap,
*bestp = best;
*stp = st;
return devcnt;
+
+error:
+ close(mdfd);
+ free(devices);
+ free(devmap);
+ return -1;
+
}
static int force_array(struct mdinfo *content,
@@ -1197,9 +1205,7 @@ static int start_array(int mdfd,
rv = sysfs_set_str(content, NULL,
"array_state", "readonly");
if (rv == 0)
- rv = Grow_continue(mdfd, st, content,
- c->backup_file, 0,
- c->freeze_reshape);
+ rv = Grow_continue(mdfd, st, content, 0, c);
} else if (c->readonly &&
sysfs_attribute_available(content, NULL,
"array_state")) {
@@ -1211,23 +1217,19 @@ static int start_array(int mdfd,
if (rv == 0) {
sysfs_rules_apply(mddev, content);
if (c->verbose >= 0) {
- pr_err("%s has been started with %d drive%s",
+ pr_info("%s has been started with %d drive%s",
mddev, okcnt, okcnt==1?"":"s");
if (okcnt < (unsigned)content->array.raid_disks)
- fprintf(stderr, " (out of %d)",
- content->array.raid_disks);
+ printf(" (out of %d)", content->array.raid_disks);
if (rebuilding_cnt)
- fprintf(stderr, "%s %d rebuilding",
- sparecnt?",":" and",
+ printf("%s %d rebuilding", sparecnt?",":" and",
rebuilding_cnt);
if (sparecnt)
- fprintf(stderr, " and %d spare%s",
- sparecnt,
+ printf(" and %d spare%s", sparecnt,
sparecnt == 1 ? "" : "s");
if (content->journal_clean)
- fprintf(stderr, " and %d journal",
- journalcnt);
- fprintf(stderr, ".\n");
+ printf(" and %d journal", journalcnt);
+ printf(".\n");
}
if (content->reshape_active &&
is_level456(content->array.level)) {
@@ -1494,8 +1496,11 @@ try_again:
mp = map_by_uuid(&map, content->uuid);
if (mp) {
struct mdinfo *dv;
- /* array already exists. */
pre_exist = sysfs_read(-1, mp->devnm, GET_LEVEL|GET_DEVS);
+ if (!pre_exist)
+ goto out;
+
+ /* array already exists. */
if (pre_exist->array.level != UnSet) {
pr_err("Found some drive for an array that is already active: %s\n",
mp->path);
@@ -1607,6 +1612,7 @@ try_again:
err = assemble_container_content(st, mdfd, content, c,
chosen_name, NULL);
close(mdfd);
+ sysfs_free(pre_exist);
return err;
}
@@ -1746,23 +1752,27 @@ try_again:
: (O_RDONLY|O_EXCL)))< 0) {
pr_err("Cannot open %s: %s\n",
devices[j].devname, strerror(errno));
+ free(avail);
goto out;
}
if (st->ss->load_super(st,fd, NULL)) {
close(fd);
pr_err("RAID superblock has disappeared from %s\n",
devices[j].devname);
+ free(avail);
goto out;
}
close(fd);
}
if (st->sb == NULL) {
pr_err("No suitable drives found for %s\n", mddev);
+ free(avail);
goto out;
}
st->ss->getinfo_super(st, content, NULL);
if (sysfs_init(content, mdfd, NULL)) {
pr_err("Unable to initialize sysfs\n");
+ free(avail);
goto out;
}
@@ -1825,12 +1835,14 @@ try_again:
if (fd < 0) {
pr_err("Could not open %s for write - cannot Assemble array.\n",
devices[chosen_drive].devname);
+ free(avail);
goto out;
}
if (st->ss->store_super(st, fd)) {
close(fd);
pr_err("Could not re-write superblock on %s\n",
devices[chosen_drive].devname);
+ free(avail);
goto out;
}
if (c->verbose >= 0)
@@ -1889,6 +1901,7 @@ try_again:
pr_err("Failed to restore critical section for reshape, sorry.\n");
if (c->backup_file == NULL)
cont_err("Possibly you needed to specify the --backup-file\n");
+ free(avail);
goto out;
}
}
@@ -1917,6 +1930,7 @@ try_again:
if (rv == 1 && !pre_exist)
ioctl(mdfd, STOP_ARRAY, NULL);
free(devices);
+ free(avail);
out:
map_unlock(&map);
if (rv == 0) {
@@ -1952,11 +1966,14 @@ out:
close(mdfd);
free(best);
+ sysfs_free(pre_exist);
+
/* '2' means 'OK, but not started yet' */
if (rv == -1) {
free(devices);
return 1;
}
+ close(mdfd);
return rv == 2 ? 0 : rv;
}
@@ -2175,13 +2192,12 @@ int assemble_container_content(struct supertype *st, int mdfd,
if (!mdmon_running(st->container_devnm))
start_mdmon(st->container_devnm);
ping_monitor(st->container_devnm);
- if (mdmon_running(st->container_devnm) &&
- st->update_tail == NULL)
+ if (wait_for_mdmon(st->container_devnm) == MDADM_STATUS_SUCCESS &&
+ !st->update_tail)
st->update_tail = &st->updates;
}
- err = Grow_continue(mdfd, st, content, c->backup_file,
- 0, c->freeze_reshape);
+ err = Grow_continue(mdfd, st, content, 0, c);
} else switch(content->array.level) {
case LEVEL_LINEAR:
case LEVEL_MULTIPATH: