* These need to be remove from, or added to, the array
*/
mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS);
- if (!mdi)
+ if (!mdi) {
+ /* invalidate the current count so we can try again */
+ container->devcnt = -1;
return;
+ }
/* check for removals */
for (cdp = &container->devs; *cdp; ) {
struct mdinfo *newd;
if (sysfs_add_disk(&newa->info, d) < 0)
continue;
- newd = newa->info.devs;
+ newd = malloc(sizeof(*newd));
+ *newd = *d;
+ newd->next = newa->info.devs;
+ newa->info.devs = newd;
+
newd->state_fd = sysfs_open(a->devnum,
newd->sys_name,
"state");
mdstat->metadata_version);
new->container = NULL;
free_aa(new);
- } else
+ } else {
replace_array(container, victim, new);
+ if (failed) {
+ new->check_degraded = 1;
+ manage_member(mdstat, new);
+ }
+ }
}
void manage(struct mdstat_ent *mdstat, struct supertype *container)
struct metadata_update *mu;
- if (msg->len == 0) {
- int cnt;
-
+ if (msg->len <= 0)
while (update_queue_pending || update_queue) {
check_update_queue(container);
usleep(15*1000);
}
+ if (msg->len == 0) { /* ping_monitor */
+ int cnt;
+
cnt = monitor_loop_cnt;
if (cnt & 1)
cnt += 2; /* wait until next pselect */
while (monitor_loop_cnt - cnt < 0)
usleep(10 * 1000);
+ } else if (msg->len == -1) { /* ping_manager */
+ struct mdstat_ent *mdstat = mdstat_read(1, 0);
+
+ manage(mdstat, container);
+ free_mdstat(mdstat);
} else {
mu = malloc(sizeof(*mu));
mu->len = msg->len;
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
+ sigdelset(&set, SIGHUP);
do {
read_sock(container);
+ if (socket_hup_requested) {
+ close(container->sock);
+ container->sock = make_control_sock(container->devname);
+ make_pidfile(container->devname, 0);
+ socket_hup_requested = 0;
+ }
+
free_mdstat(mdstat);
}
remove_old();