#include <dirent.h>
#include <ctype.h>
-static int count_active(struct supertype *st, int mdfd, char **availp,
+static int count_active(struct supertype *st, struct mdinfo *sra,
+ int mdfd, char **availp,
struct mdinfo *info);
static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
int number, __u64 events, int verbose,
*/
struct stat stb;
struct mdinfo info, dinfo;
+ struct mdinfo *sra = NULL;
struct mddev_ident *match;
char chosen_name[1024];
int rv = 1;
mdfd = -1;
if (mdfd < 0) {
- struct mdinfo *sra;
/* Couldn't find an existing array, maybe make a new one */
mdfd = create_mddev(match ? match->devname : NULL,
rv = 2;
goto out;
}
- sra = sysfs_read(mdfd, fd2devnum(mdfd), GET_DEVS);
+ sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
+ GET_OFFSET | GET_SIZE));
+
if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
/* It really should be 'none' - must be old buggy
* kernel, and mdadm -I may not be able to complete.
goto out;
}
info.array.working_disks = 1;
- sysfs_free(sra);
/* 6/ Make sure /var/run/mdadm.map contains this array. */
map_update(&map, fd2devnum(mdfd),
info.text_version,
char dn[20];
int dfd2;
int err;
- struct mdinfo *sra;
struct supertype *st2;
struct mdinfo info2, *d;
+ sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
+ GET_OFFSET | GET_SIZE));
+
if (mp->path)
strcpy(chosen_name, mp->path);
else
goto out;
}
}
- sra = sysfs_read(mdfd, fd2devnum(mdfd), (GET_DEVS | GET_STATE));
if (!sra) {
rv = 2;
goto out;
chosen_name, info.array.working_disks);
wait_for(chosen_name, mdfd);
close(mdfd);
+ sysfs_free(sra);
rv = Incremental(chosen_name, verbose, runstop,
NULL, homehost, require_homehost, autof);
if (rv == 1)
return rv;
}
avail = NULL;
- active_disks = count_active(st, mdfd, &avail, &info);
+ /* We have added something to the array, so need to re-read the
+ * state. Eventually this state should be kept up-to-date as
+ * things change.
+ */
+ sysfs_free(sra);
+ sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
+ GET_OFFSET | GET_SIZE));
+ active_disks = count_active(st, sra, mdfd, &avail, &info);
if (enough(info.array.level, info.array.raid_disks,
info.array.layout, info.array.state & 1,
avail, active_disks) == 0) {
map_unlock(&map);
if (runstop > 0 || active_disks >= info.array.working_disks) {
- struct mdinfo *sra, *dsk;
+ struct mdinfo *dsk;
/* Let's try to start it */
if (match && match->bitmap_file) {
int bmfd = open(match->bitmap_file, O_RDWR);
}
close(bmfd);
}
- /* GET_* needed so add_disk works below */
- sra = sysfs_read(mdfd, fd2devnum(mdfd),
- GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
+
if ((sra == NULL || active_disks >= info.array.working_disks)
&& trustworthy != FOREIGN)
rv = ioctl(mdfd, RUN_ARRAY, NULL);
close(mdfd);
if (policy)
dev_policy_free(policy);
+ if (sra)
+ sysfs_free(sra);
return rv;
}
}
}
-static int count_active(struct supertype *st, int mdfd, char **availp,
+static int count_active(struct supertype *st, struct mdinfo *sra,
+ int mdfd, char **availp,
struct mdinfo *bestinfo)
{
/* count how many devices in sra think they are active */
struct mdinfo *d;
int cnt = 0, cnt1 = 0;
__u64 max_events = 0;
- struct mdinfo *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
char *avail = NULL;
if (!sra)