Codebase list mdadm / 1ed3f38
Remove stopped arrays. When an array becomes inactive, clean up and forget it. This involves signalling the manager. Neil Brown 15 years ago
5 changed file(s) with 77 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
7474 #include "mdadm.h"
7575 #include "mdmon.h"
7676 #include <sys/socket.h>
77 #include <signal.h>
7778
7879 static void close_aa(struct active_array *aa)
7980 {
115116 read(c->mon_pipe[0], &err, 1);
116117 }
117118
119 static void remove_old(void)
120 {
121 if (discard_this) {
122 discard_this->next = NULL;
123 free_aa(discard_this);
124 if (pending_discard == discard_this)
125 pending_discard = NULL;
126 discard_this = NULL;
127 }
128 }
129
118130 static void replace_array(struct supertype *container,
119131 struct active_array *old,
120132 struct active_array *new)
125137 * and put it on 'discard_this'. We take it from there
126138 * and discard it.
127139 */
128
140 remove_old();
129141 while (pending_discard) {
142 write_wakeup(container);
130143 while (discard_this == NULL)
131144 sleep(1);
132 if (discard_this != pending_discard)
133 abort();
134 discard_this->next = NULL;
135 free_aa(discard_this);
136 discard_this = NULL;
137 pending_discard = NULL;
145 remove_old();
138146 }
139147 pending_discard = old;
140148 new->replaces = old;
142150 container->arrays = new;
143151 write_wakeup(container);
144152 }
145
146153
147154 static void manage_container(struct mdstat_ent *mdstat,
148155 struct supertype *container)
367374
368375 close(fd);
369376 }
377
378 static int woke = 0;
379 void wake_me(int sig)
380 {
381 woke = 1;
382 }
383
370384 void do_manager(struct supertype *container)
371385 {
372386 struct mdstat_ent *mdstat;
387 sigset_t block, orig;
388
389 sigemptyset(&block);
390 sigaddset(&block, SIGUSR1);
391
392 signal(SIGUSR1, wake_me);
373393
374394 do {
395 woke = 0;
396
375397 mdstat = mdstat_read(1, 0);
376398
377399 manage(mdstat, container);
380402
381403 free_mdstat(mdstat);
382404
383 mdstat_wait_fd(container->sock);
405 remove_old();
406
407 sigprocmask(SIG_SETMASK, &block, &orig);
408 if (woke == 0)
409 mdstat_wait_fd(container->sock, &orig);
410 sigprocmask(SIG_SETMASK, &orig, NULL);
384411 } while(1);
385412 }
291291 extern struct mdstat_ent *mdstat_read(int hold, int start);
292292 extern void free_mdstat(struct mdstat_ent *ms);
293293 extern void mdstat_wait(int seconds);
294 extern void mdstat_wait_fd(int fd);
294 extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
295295 extern int mddev_busy(int devnum);
296296
297297 struct map_ent {
4747 int run_child(void *v)
4848 {
4949 struct supertype *c = v;
50 sigset_t set;
51 /* SIGUSR is sent from child to parent, So child must block it */
52 sigemptyset(&set);
53 sigaddset(&set, SIGUSR1);
54 sigprocmask(SIG_BLOCK, &set, NULL);
55
5056 do_monitor(c);
5157 return 0;
5258 }
271271 select(mdstat_fd >2 ? mdstat_fd+1:3, NULL, NULL, &fds, &tm);
272272 }
273273
274 void mdstat_wait_fd(int fd)
274 void mdstat_wait_fd(int fd, const sigset_t *sigmask)
275275 {
276276 fd_set fds, rfds;
277277
281281 FD_SET(mdstat_fd, &fds);
282282 FD_SET(fd, &rfds);
283283
284 select(mdstat_fd >2 ? mdstat_fd+1:3, &rfds, NULL, &fds, NULL);
284 pselect(mdstat_fd >2 ? mdstat_fd+1:3, &rfds, NULL, &fds,
285 NULL, sigmask);
285286 }
286287
287288 int mddev_busy(int devnum)
22 #include "mdmon.h"
33
44 #include <sys/select.h>
5
5 #include <signal.h>
66
77 static char *array_states[] = {
88 "clear", "inactive", "suspended", "readonly", "read-auto",
151151 return rv;
152152 }
153153
154 static void signal_manager(void)
155 {
156 kill(getpid(), SIGUSR1);
157 }
154158
155159 /* Monitor a set of active md arrays - all of which share the
156160 * same metadata - and respond to events that require
431435 return -1;
432436 }
433437
434 static int wait_and_act(struct active_array *aa, int pfd, int monfd, int nowait)
438 static int wait_and_act(struct active_array **aap, int pfd,
439 int monfd, int nowait)
435440 {
436441 fd_set rfds;
437442 int maxfd = 0;
438 struct active_array *a;
443 struct active_array *a, **ap;
439444 int rv;
440445 struct mdinfo *mdi;
441446
442447 FD_ZERO(&rfds);
443448
444449 add_fd(&rfds, &maxfd, pfd);
445 for (a = aa ; a ; a = a->next) {
446 /* once an array has been deactivated only the manager
447 * thread can make us care about it again
450 for (ap = aap ; *ap ;) {
451 a = *ap;
452 /* once an array has been deactivated we want to
453 * ask the manager to discard it.
448454 */
449 if (!a->container)
450 continue;
455 if (!a->container) {
456 if (discard_this) {
457 ap = &(*ap)->next;
458 continue;
459 }
460 *ap = a->next;
461 a->next = NULL;
462 discard_this = a;
463 signal_manager();
464 continue;
465 }
451466
452467 add_fd(&rfds, &maxfd, a->info.state_fd);
453468 add_fd(&rfds, &maxfd, a->action_fd);
454469 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
455470 add_fd(&rfds, &maxfd, mdi->state_fd);
471
472 ap = &(*ap)->next;
456473 }
457474
458475 if (!nowait) {
465482 int err = -1;
466483
467484 if (read(pfd, &err, 1) > 0)
468 err = handle_pipe(active_cmd, aa);
485 err = handle_pipe(active_cmd, *aap);
469486 write(monfd, &err, 1);
470487 }
471488 }
472489
473 for (a = aa; a ; a = a->next) {
490 for (a = *aap; a ; a = a->next) {
474491 if (a->replaces && !discard_this) {
475492 struct active_array **ap;
476493 for (ap = &a->next; *ap && *ap != a->replaces;
480497 *ap = (*ap)->next;
481498 discard_this = a->replaces;
482499 a->replaces = NULL;
500 signal_manager();
483501 }
484502 if (a->container)
485503 rv += read_and_act(a);
486504 }
487505
488506 /* propagate failures across container members */
489 for (a = aa; a ; a = a->next) {
507 for (a = *aap; a ; a = a->next) {
490508 if (!a->container)
491509 continue;
492510 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
493511 if (mdi->curr_state & DS_FAULTY)
494 reconcile_failed(aa, mdi);
512 reconcile_failed(*aap, mdi);
495513 }
496514
497515 return rv;
502520 int rv;
503521 int first = 1;
504522 do {
505 rv = wait_and_act(container->arrays, container->mgr_pipe[0],
523 rv = wait_and_act(&container->arrays, container->mgr_pipe[0],
506524 container->mon_pipe[1], first);
507525 first = 0;
508526 } while (rv >= 0);