]> git.neil.brown.name Git - mdadm.git/blob - monitor.c
Release mdadm-4.0
[mdadm.git] / monitor.c
1 /*
2  * mdmon - monitor external metadata arrays
3  *
4  * Copyright (C) 2007-2009 Neil Brown <neilb@suse.de>
5  * Copyright (C) 2007-2009 Intel Corporation
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include "mdadm.h"
22 #include "mdmon.h"
23 #include <sys/syscall.h>
24 #include <sys/select.h>
25 #include <signal.h>
26
27 static char *array_states[] = {
28         "clear", "inactive", "suspended", "readonly", "read-auto",
29         "clean", "active", "write-pending", "active-idle", NULL };
30 static char *sync_actions[] = {
31         "idle", "reshape", "resync", "recover", "check", "repair", NULL
32 };
33
34 enum bb_action {
35         RECORD_BB = 1,
36         COMPARE_BB,
37 };
38
39 static int write_attr(char *attr, int fd)
40 {
41         return write(fd, attr, strlen(attr));
42 }
43
44 static void add_fd(fd_set *fds, int *maxfd, int fd)
45 {
46         struct stat st;
47         if (fd < 0)
48                 return;
49         if (fstat(fd, &st) == -1) {
50                 dprintf("Invalid fd %d\n", fd);
51                 return;
52         }
53         if (st.st_nlink == 0) {
54                 dprintf("fd %d was deleted\n", fd);
55                 return;
56         }
57         if (fd > *maxfd)
58                 *maxfd = fd;
59         FD_SET(fd, fds);
60 }
61
62 static int read_attr(char *buf, int len, int fd)
63 {
64         int n;
65
66         if (fd < 0) {
67                 buf[0] = 0;
68                 return 0;
69         }
70         lseek(fd, 0, 0);
71         n = read(fd, buf, len - 1);
72
73         if (n <= 0) {
74                 buf[0] = 0;
75                 return 0;
76         }
77         buf[n] = 0;
78         if (buf[n-1] == '\n')
79                 buf[n-1] = 0;
80         return n;
81 }
82
83 static void read_resync_start(int fd, unsigned long long *v)
84 {
85         char buf[30];
86         int n;
87
88         n = read_attr(buf, 30, fd);
89         if (n <= 0) {
90                 dprintf("Failed to read resync_start (%d)\n", fd);
91                 return;
92         }
93         if (strncmp(buf, "none", 4) == 0)
94                 *v = MaxSector;
95         else
96                 *v = strtoull(buf, NULL, 10);
97 }
98
99 static unsigned long long read_sync_completed(int fd)
100 {
101         unsigned long long val;
102         char buf[50];
103         int n;
104         char *ep;
105
106         n = read_attr(buf, 50, fd);
107
108         if (n <= 0)
109                 return 0;
110         buf[n] = 0;
111         val = strtoull(buf, &ep, 0);
112         if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' '))
113                 return 0;
114         return val;
115 }
116
117 static enum array_state read_state(int fd)
118 {
119         char buf[20];
120         int n = read_attr(buf, 20, fd);
121
122         if (n <= 0)
123                 return bad_word;
124         return (enum array_state) sysfs_match_word(buf, array_states);
125 }
126
127 static enum sync_action read_action( int fd)
128 {
129         char buf[20];
130         int n = read_attr(buf, 20, fd);
131
132         if (n <= 0)
133                 return bad_action;
134         return (enum sync_action) sysfs_match_word(buf, sync_actions);
135 }
136
137 int read_dev_state(int fd)
138 {
139         char buf[100];
140         int n = read_attr(buf, sizeof(buf), fd);
141         char *cp;
142         int rv = 0;
143
144         if (n <= 0)
145                 return 0;
146
147         cp = buf;
148         while (cp) {
149                 if (sysfs_attr_match(cp, "faulty"))
150                         rv |= DS_FAULTY;
151                 if (sysfs_attr_match(cp, "in_sync"))
152                         rv |= DS_INSYNC;
153                 if (sysfs_attr_match(cp, "write_mostly"))
154                         rv |= DS_WRITE_MOSTLY;
155                 if (sysfs_attr_match(cp, "spare"))
156                         rv |= DS_SPARE;
157                 if (sysfs_attr_match(cp, "blocked"))
158                         rv |= DS_BLOCKED;
159                 cp = strchr(cp, ',');
160                 if (cp)
161                         cp++;
162         }
163         return rv;
164 }
165
166 int process_ubb(struct active_array *a, struct mdinfo *mdi, const unsigned long
167                 long sector, const int length, const char *buf,
168                 const int buf_len)
169 {
170         struct superswitch *ss = a->container->ss;
171
172         /*
173          * record bad block in metadata first, then acknowledge it to the driver
174          * via sysfs file
175          */
176         if ((ss->record_bad_block(a, mdi->disk.raid_disk, sector, length)) &&
177             (write(mdi->bb_fd, buf, buf_len) == buf_len))
178                 return 1;
179
180         /*
181          * failed to store or acknowledge bad block, switch of bad block support
182          * to get it out of blocked state
183          */
184         sysfs_set_str(&a->info, mdi, "state", "-external_bbl");
185         return -1;
186 }
187
188 int compare_bb(struct active_array *a, struct mdinfo *mdi, const unsigned long
189                long sector, const unsigned int length, void *arg)
190 {
191         struct superswitch *ss = a->container->ss;
192         struct md_bb *bb = (struct md_bb *) arg;
193         int record = 1;
194         int i;
195
196         for (i = 0; i < bb->count; i++) {
197                 unsigned long long start = bb->entries[i].sector;
198                 unsigned long long len = bb->entries[i].length;
199
200                 /*
201                  * bad block in metadata exactly matches bad block in kernel
202                  * list, just remove it from a list
203                  */
204                 if ((start == sector) && (len == length)) {
205                         if (i < bb->count - 1)
206                                 bb->entries[i] = bb->entries[bb->count - 1];
207                         bb->count -= 1;
208                         record = 0;
209                         break;
210                 }
211                 /*
212                  * bad block in metadata spans bad block in kernel list,
213                  * clear it and record new bad block
214                  */
215                 if ((sector >= start) && (sector + length <= start + len)) {
216                         ss->clear_bad_block(a, mdi->disk.raid_disk, start, len);
217                         break;
218                 }
219         }
220
221         /* record all bad blocks not in metadata list */
222         if (record && (ss->record_bad_block(a, mdi->disk.raid_disk, sector,
223                                              length) <= 0)) {
224                 sysfs_set_str(&a->info, mdi, "state", "-external_bbl");
225                 return -1;
226         }
227
228         return 1;
229 }
230
231 static int read_bb_file(int fd, struct active_array *a, struct mdinfo *mdi,
232                         enum bb_action action, void *arg)
233 {
234         char buf[30];
235         int n = 0;
236         int ret = 0;
237         int read_again = 0;
238         int off = 0;
239         int pos = 0;
240         int preserve_pos = (action == RECORD_BB ? 0 : 1);
241
242         if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
243                 return -1;
244
245         do {
246                 read_again = 0;
247                 n = read(fd, buf + pos, sizeof(buf) - 1 - pos);
248                 if (n < 0)
249                         return -1;
250                 n += pos;
251
252                 buf[n] = '\0';
253                 off = 0;
254
255                 while (off < n) {
256                         unsigned long long sector;
257                         int length;
258                         char newline;
259                         int consumed;
260                         int matched;
261                         int rc;
262
263                         /* kernel sysfs file format: "sector length\n" */
264                         matched = sscanf(buf + off, "%llu %d%c%n", &sector,
265                                          &length, &newline, &consumed);
266                         if ((matched != 3) && (off > 0)) {
267                                 /* truncated entry, read again */
268                                 if (preserve_pos) {
269                                         pos = sizeof(buf) - off - 1;
270                                         memmove(buf, buf + off, pos);
271                                 } else {
272                                         if (lseek(fd, 0, SEEK_SET) ==
273                                             (off_t) -1)
274                                                 return -1;
275                                 }
276                                 read_again = 1;
277                                 break;
278                         }
279                         if (matched != 3)
280                                 return -1;
281                         if (newline != '\n')
282                                 return -1;
283                         if (length <= 0)
284                                 return -1;
285
286                         if (action == RECORD_BB)
287                                 rc = process_ubb(a, mdi, sector, length,
288                                                   buf + off, consumed);
289                         else if (action == COMPARE_BB)
290                                 rc = compare_bb(a, mdi, sector, length, arg);
291                         else
292                                 rc = -1;
293
294                         if (rc < 0)
295                                 return rc;
296                         ret += rc;
297                         off += consumed;
298                 }
299         } while (read_again);
300
301         return ret;
302 }
303
304 static int process_dev_ubb(struct active_array *a, struct mdinfo *mdi)
305 {
306         return read_bb_file(mdi->ubb_fd, a, mdi, RECORD_BB, NULL);
307 }
308
309 static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi)
310 {
311         struct superswitch *ss = a->container->ss;
312         struct md_bb *bb;
313         int i;
314
315         /*
316          * Get a list of bad blocks for an array, then read list of
317          * acknowledged bad blocks from kernel and compare it against metadata
318          * list, clear all bad blocks remaining in metadata list
319          */
320         bb = ss->get_bad_blocks(a, mdi->disk.raid_disk);
321         if (!bb)
322                 return -1;
323
324         if (read_bb_file(mdi->bb_fd, a, mdi, COMPARE_BB, bb) < 0)
325                 return -1;
326
327         for (i = 0; i < bb->count; i++) {
328                 unsigned long long sector = bb->entries[i].sector;
329                 int length = bb->entries[i].length;
330
331                 ss->clear_bad_block(a, mdi->disk.raid_disk, sector, length);
332         }
333
334         return 0;
335 }
336
337 static void signal_manager(void)
338 {
339         /* tgkill(getpid(), mon_tid, SIGUSR1); */
340         int pid = getpid();
341         syscall(SYS_tgkill, pid, mgr_tid, SIGUSR1);
342 }
343
344 /* Monitor a set of active md arrays - all of which share the
345  * same metadata - and respond to events that require
346  * metadata update.
347  *
348  * New arrays are detected by another thread which allocates
349  * required memory and attaches the data structure to our list.
350  *
351  * Events:
352  *  Array stops.
353  *    This is detected by array_state going to 'clear' or 'inactive'.
354  *    while we thought it was active.
355  *    Response is to mark metadata as clean and 'clear' the array(??)
356  *  write-pending
357  *    array_state if 'write-pending'
358  *    We mark metadata as 'dirty' then set array to 'active'.
359  *  active_idle
360  *    Either ignore, or mark clean, then mark metadata as clean.
361  *
362  *  device fails
363  *    detected by rd-N/state reporting "faulty"
364  *    mark device as 'failed' in metadata, let the kernel release the
365  *    device by writing '-blocked' to rd/state, and finally write 'remove' to
366  *    rd/state.  Before a disk can be replaced it must be failed and removed
367  *    from all container members, this will be preemptive for the other
368  *    arrays... safe?
369  *
370  *  sync completes
371  *    sync_action was 'resync' and becomes 'idle' and resync_start becomes
372  *    MaxSector
373  *    Notify metadata that sync is complete.
374  *
375  *  recovery completes
376  *    sync_action changes from 'recover' to 'idle'
377  *    Check each device state and mark metadata if 'faulty' or 'in_sync'.
378  *
379  *  deal with resync
380  *    This only happens on finding a new array... mdadm will have set
381  *    'resync_start' to the correct value.  If 'resync_start' indicates that an
382  *    resync needs to occur set the array to the 'active' state rather than the
383  *    initial read-auto state.
384  *
385  *
386  *
387  * We wait for a change (poll/select) on array_state, sync_action, and
388  * each rd-X/state file.
389  * When we get any change, we check everything.  So read each state file,
390  * then decide what to do.
391  *
392  * The core action is to write new metadata to all devices in the array.
393  * This is done at most once on any wakeup.
394  * After that we might:
395  *   - update the array_state
396  *   - set the role of some devices.
397  *   - request a sync_action
398  *
399  */
400
401 #define ARRAY_DIRTY 1
402 #define ARRAY_BUSY 2
403 static int read_and_act(struct active_array *a, fd_set *fds)
404 {
405         unsigned long long sync_completed;
406         int check_degraded = 0;
407         int check_reshape = 0;
408         int deactivate = 0;
409         struct mdinfo *mdi;
410         int ret = 0;
411         int count = 0;
412         struct timeval tv;
413
414         a->next_state = bad_word;
415         a->next_action = bad_action;
416
417         a->curr_state = read_state(a->info.state_fd);
418         a->curr_action = read_action(a->action_fd);
419         if (a->curr_state != clear)
420                 /*
421                  * In "clear" state, resync_start may wrongly be set to "0"
422                  * when the kernel called md_clean but didn't remove the
423                  * sysfs attributes yet
424                  */
425                 read_resync_start(a->resync_start_fd, &a->info.resync_start);
426         sync_completed = read_sync_completed(a->sync_completed_fd);
427         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
428                 mdi->next_state = 0;
429                 mdi->curr_state = 0;
430                 if (mdi->state_fd >= 0) {
431                         read_resync_start(mdi->recovery_fd,
432                                           &mdi->recovery_start);
433                         mdi->curr_state = read_dev_state(mdi->state_fd);
434                 }
435                 /*
436                  * If array is blocked and metadata handler is able to handle
437                  * BB, check if you can acknowledge them to md driver. If
438                  * successful, clear faulty state and unblock the array.
439                  */
440                 if ((mdi->curr_state & DS_BLOCKED) &&
441                     a->container->ss->record_bad_block &&
442                     (process_dev_ubb(a, mdi) > 0)) {
443                         mdi->next_state |= DS_UNBLOCK;
444                 }
445                 if (FD_ISSET(mdi->bb_fd, fds))
446                         check_for_cleared_bb(a, mdi);
447         }
448
449         gettimeofday(&tv, NULL);
450         dprintf("(%d): %ld.%06ld state:%s prev:%s action:%s prev: %s start:%llu\n",
451                 a->info.container_member,
452                 tv.tv_sec, tv.tv_usec,
453                 array_states[a->curr_state],
454                 array_states[a->prev_state],
455                 sync_actions[a->curr_action],
456                 sync_actions[a->prev_action],
457                 a->info.resync_start
458                 );
459
460         if ((a->curr_state == bad_word || a->curr_state <= inactive) &&
461             a->prev_state > inactive) {
462                 /* array has been stopped */
463                 a->container->ss->set_array_state(a, 1);
464                 a->next_state = clear;
465                 deactivate = 1;
466         }
467         if (a->curr_state == write_pending) {
468                 a->container->ss->set_array_state(a, 0);
469                 a->next_state = active;
470                 ret |= ARRAY_DIRTY;
471         }
472         if (a->curr_state == active_idle) {
473                 /* Set array to 'clean' FIRST, then mark clean
474                  * in the metadata
475                  */
476                 a->next_state = clean;
477                 ret |= ARRAY_DIRTY;
478         }
479         if (a->curr_state == clean) {
480                 a->container->ss->set_array_state(a, 1);
481         }
482         if (a->curr_state == active ||
483             a->curr_state == suspended)
484                 ret |= ARRAY_DIRTY;
485         if (a->curr_state == readonly) {
486                 /* Well, I'm ready to handle things.  If readonly
487                  * wasn't requested, transition to read-auto.
488                  */
489                 char buf[64];
490                 read_attr(buf, sizeof(buf), a->metadata_fd);
491                 if (strncmp(buf, "external:-", 10) == 0) {
492                         /* explicit request for readonly array.  Leave it alone */
493                         ;
494                 } else {
495                         if (a->container->ss->set_array_state(a, 2))
496                                 a->next_state = read_auto; /* array is clean */
497                         else {
498                                 a->next_state = active; /* Now active for recovery etc */
499                                 ret |= ARRAY_DIRTY;
500                         }
501                 }
502         }
503
504         if (!deactivate &&
505             a->curr_action == idle &&
506             a->prev_action == resync) {
507                 /* A resync has finished.  The endpoint is recorded in
508                  * 'sync_start'.  We don't update the metadata
509                  * until the array goes inactive or readonly though.
510                  * Just check if we need to fiddle spares.
511                  */
512                 a->container->ss->set_array_state(a, a->curr_state <= clean);
513                 check_degraded = 1;
514         }
515
516         if (!deactivate &&
517             a->curr_action == idle &&
518             a->prev_action == recover) {
519                 /* A recovery has finished.  Some disks may be in sync now,
520                  * and the array may no longer be degraded
521                  */
522                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next) {
523                         a->container->ss->set_disk(a, mdi->disk.raid_disk,
524                                                    mdi->curr_state);
525                         if (! (mdi->curr_state & DS_INSYNC))
526                                 check_degraded = 1;
527                         count++;
528                 }
529                 if (count != a->info.array.raid_disks)
530                         check_degraded = 1;
531         }
532
533         if (!deactivate &&
534             a->curr_action == reshape &&
535             a->prev_action != reshape)
536                 /* reshape was requested by mdadm.  Need to see if
537                  * new devices have been added.  Manager does that
538                  * when it sees check_reshape
539                  */
540                 check_reshape = 1;
541
542         /* Check for failures and if found:
543          * 1/ Record the failure in the metadata and unblock the device.
544          *    FIXME update the kernel to stop notifying on failed drives when
545          *    the array is readonly and we have cleared 'blocked'
546          * 2/ Try to remove the device if the array is writable, or can be
547          *    made writable.
548          */
549         for (mdi = a->info.devs ; mdi ; mdi = mdi->next) {
550                 if (mdi->curr_state & DS_FAULTY) {
551                         a->container->ss->set_disk(a, mdi->disk.raid_disk,
552                                                    mdi->curr_state);
553                         check_degraded = 1;
554                         if (mdi->curr_state & DS_BLOCKED)
555                                 mdi->next_state |= DS_UNBLOCK;
556                         if (a->curr_state == read_auto) {
557                                 a->container->ss->set_array_state(a, 0);
558                                 a->next_state = active;
559                         }
560                         if (a->curr_state > readonly)
561                                 mdi->next_state |= DS_REMOVE;
562                 }
563         }
564
565         /* Check for recovery checkpoint notifications.  We need to be a
566          * minimum distance away from the last checkpoint to prevent
567          * over checkpointing.  Note reshape checkpointing is handled
568          * in the second branch.
569          */
570         if (sync_completed > a->last_checkpoint &&
571             sync_completed - a->last_checkpoint > a->info.component_size >> 4 &&
572             a->curr_action > reshape) {
573                 /* A (non-reshape) sync_action has reached a checkpoint.
574                  * Record the updated position in the metadata
575                  */
576                 a->last_checkpoint = sync_completed;
577                 a->container->ss->set_array_state(a, a->curr_state <= clean);
578         } else if ((a->curr_action == idle && a->prev_action == reshape) ||
579                    (a->curr_action == reshape
580                     && sync_completed > a->last_checkpoint) ) {
581                 /* Reshape has progressed or completed so we need to
582                  * update the array state - and possibly the array size
583                  */
584                 if (sync_completed != 0)
585                         a->last_checkpoint = sync_completed;
586                 /* We might need to update last_checkpoint depending on
587                  * the reason that reshape finished.
588                  * if array reshape is really finished:
589                  *        set check point to the end, this allows
590                  *        set_array_state() to finalize reshape in metadata
591                  * if reshape if broken: do not set checkpoint to the end
592                  *        this allows for reshape restart from checkpoint
593                  */
594                 if ((a->curr_action != reshape) &&
595                     (a->prev_action == reshape)) {
596                         char buf[40];
597                         if ((sysfs_get_str(&a->info, NULL,
598                                           "reshape_position",
599                                           buf,
600                                           sizeof(buf)) >= 0) &&
601                              strncmp(buf, "none", 4) == 0)
602                                 a->last_checkpoint = a->info.component_size;
603                 }
604                 a->container->ss->set_array_state(a, a->curr_state <= clean);
605                 a->last_checkpoint = sync_completed;
606         }
607
608         if (sync_completed > a->last_checkpoint)
609                 a->last_checkpoint = sync_completed;
610
611         if (sync_completed >= a->info.component_size)
612                 a->last_checkpoint = 0;
613
614         a->container->ss->sync_metadata(a->container);
615         dprintf("(%d): state:%s action:%s next(", a->info.container_member,
616                 array_states[a->curr_state], sync_actions[a->curr_action]);
617
618         /* Effect state changes in the array */
619         if (a->next_state != bad_word) {
620                 dprintf_cont(" state:%s", array_states[a->next_state]);
621                 write_attr(array_states[a->next_state], a->info.state_fd);
622         }
623         if (a->next_action != bad_action) {
624                 write_attr(sync_actions[a->next_action], a->action_fd);
625                 dprintf_cont(" action:%s", sync_actions[a->next_action]);
626         }
627         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
628                 if (mdi->next_state & DS_UNBLOCK) {
629                         dprintf_cont(" %d:-blocked", mdi->disk.raid_disk);
630                         write_attr("-blocked", mdi->state_fd);
631                 }
632
633                 if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
634                         int remove_result;
635
636                         /* The kernel may not be able to immediately remove the
637                          * disk.  In that case we wait a little while and
638                          * try again.
639                          */
640                         remove_result = write_attr("remove", mdi->state_fd);
641                         if (remove_result > 0) {
642                                 dprintf_cont(" %d:removed", mdi->disk.raid_disk);
643                                 close(mdi->state_fd);
644                                 close(mdi->recovery_fd);
645                                 close(mdi->bb_fd);
646                                 close(mdi->ubb_fd);
647                                 mdi->state_fd = -1;
648                         } else
649                                 ret |= ARRAY_BUSY;
650                 }
651                 if (mdi->next_state & DS_INSYNC) {
652                         write_attr("+in_sync", mdi->state_fd);
653                         dprintf_cont(" %d:+in_sync", mdi->disk.raid_disk);
654                 }
655         }
656         dprintf_cont(" )\n");
657
658         /* move curr_ to prev_ */
659         a->prev_state = a->curr_state;
660
661         a->prev_action = a->curr_action;
662
663         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
664                 mdi->prev_state = mdi->curr_state;
665                 mdi->next_state = 0;
666         }
667
668         if (check_degraded || check_reshape) {
669                 /* manager will do the actual check */
670                 if (check_degraded)
671                         a->check_degraded = 1;
672                 if (check_reshape)
673                         a->check_reshape = 1;
674                 signal_manager();
675         }
676
677         if (deactivate)
678                 a->container = NULL;
679
680         return ret;
681 }
682
683 static struct mdinfo *
684 find_device(struct active_array *a, int major, int minor)
685 {
686         struct mdinfo *mdi;
687
688         for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
689                 if (mdi->disk.major == major && mdi->disk.minor == minor)
690                         return mdi;
691
692         return NULL;
693 }
694
695 static void reconcile_failed(struct active_array *aa, struct mdinfo *failed)
696 {
697         struct active_array *a;
698         struct mdinfo *victim;
699
700         for (a = aa; a; a = a->next) {
701                 if (!a->container || a->to_remove)
702                         continue;
703                 victim = find_device(a, failed->disk.major, failed->disk.minor);
704                 if (!victim)
705                         continue;
706
707                 if (!(victim->curr_state & DS_FAULTY))
708                         write_attr("faulty", victim->state_fd);
709         }
710 }
711
712 #ifdef DEBUG
713 static void dprint_wake_reasons(fd_set *fds)
714 {
715         int i;
716         char proc_path[256];
717         char link[256];
718         char *basename;
719         int rv;
720
721         fprintf(stderr, "monitor: wake ( ");
722         for (i = 0; i < FD_SETSIZE; i++) {
723                 if (FD_ISSET(i, fds)) {
724                         sprintf(proc_path, "/proc/%d/fd/%d",
725                                 (int) getpid(), i);
726
727                         rv = readlink(proc_path, link, sizeof(link) - 1);
728                         if (rv < 0) {
729                                 fprintf(stderr, "%d:unknown ", i);
730                                 continue;
731                         }
732                         link[rv] = '\0';
733                         basename = strrchr(link, '/');
734                         fprintf(stderr, "%d:%s ",
735                                 i, basename ? ++basename : link);
736                 }
737         }
738         fprintf(stderr, ")\n");
739 }
740 #endif
741
742 int monitor_loop_cnt;
743
744 static int wait_and_act(struct supertype *container, int nowait)
745 {
746         fd_set rfds;
747         int maxfd = 0;
748         struct active_array **aap = &container->arrays;
749         struct active_array *a, **ap;
750         int rv;
751         struct mdinfo *mdi;
752         static unsigned int dirty_arrays = ~0; /* start at some non-zero value */
753
754         FD_ZERO(&rfds);
755
756         for (ap = aap ; *ap ;) {
757                 a = *ap;
758                 /* once an array has been deactivated we want to
759                  * ask the manager to discard it.
760                  */
761                 if (!a->container || a->to_remove) {
762                         if (discard_this) {
763                                 ap = &(*ap)->next;
764                                 continue;
765                         }
766                         *ap = a->next;
767                         a->next = NULL;
768                         discard_this = a;
769                         signal_manager();
770                         continue;
771                 }
772
773                 add_fd(&rfds, &maxfd, a->info.state_fd);
774                 add_fd(&rfds, &maxfd, a->action_fd);
775                 add_fd(&rfds, &maxfd, a->sync_completed_fd);
776                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next) {
777                         add_fd(&rfds, &maxfd, mdi->state_fd);
778                         add_fd(&rfds, &maxfd, mdi->bb_fd);
779                         add_fd(&rfds, &maxfd, mdi->ubb_fd);
780                 }
781
782                 ap = &(*ap)->next;
783         }
784
785         if (manager_ready && (*aap == NULL || (sigterm && !dirty_arrays))) {
786                 /* No interesting arrays, or we have been told to
787                  * terminate and everything is clean.  Lets see about
788                  * exiting.  Note that blocking at this point is not a
789                  * problem as there are no active arrays, there is
790                  * nothing that we need to be ready to do.
791                  */
792                 int fd;
793                 if (sigterm)
794                         fd = open_dev_excl(container->devnm);
795                 else
796                         fd = open_dev_flags(container->devnm, O_RDONLY|O_EXCL);
797                 if (fd >= 0 || errno != EBUSY) {
798                         /* OK, we are safe to leave */
799                         if (sigterm && !dirty_arrays)
800                                 dprintf("caught sigterm, all clean... exiting\n");
801                         else
802                                 dprintf("no arrays to monitor... exiting\n");
803                         if (!sigterm)
804                                 /* On SIGTERM, someone (the take-over mdmon) will
805                                  * clean up
806                                  */
807                                 remove_pidfile(container->devnm);
808                         exit_now = 1;
809                         signal_manager();
810                         close(fd);
811                         exit(0);
812                 }
813         }
814
815         if (!nowait) {
816                 sigset_t set;
817                 struct timespec ts;
818                 ts.tv_sec = 24*3600;
819                 ts.tv_nsec = 0;
820                 if (*aap == NULL || container->retry_soon) {
821                         /* just waiting to get O_EXCL access */
822                         ts.tv_sec = 0;
823                         ts.tv_nsec = 20000000ULL;
824                 }
825                 sigprocmask(SIG_UNBLOCK, NULL, &set);
826                 sigdelset(&set, SIGUSR1);
827                 monitor_loop_cnt |= 1;
828                 rv = pselect(maxfd+1, NULL, NULL, &rfds, &ts, &set);
829                 monitor_loop_cnt += 1;
830                 if (rv == -1) {
831                         if (errno == EINTR) {
832                                 rv = 0;
833                                 FD_ZERO(&rfds);
834                                 dprintf("monitor: caught signal\n");
835                         } else
836                                 dprintf("monitor: error %d in pselect\n",
837                                         errno);
838                 }
839                 #ifdef DEBUG
840                 else
841                         dprint_wake_reasons(&rfds);
842                 #endif
843                 container->retry_soon = 0;
844         }
845
846         if (update_queue) {
847                 struct metadata_update *this;
848
849                 for (this = update_queue; this ; this = this->next)
850                         container->ss->process_update(container, this);
851
852                 update_queue_handled = update_queue;
853                 update_queue = NULL;
854                 signal_manager();
855                 container->ss->sync_metadata(container);
856         }
857
858         rv = 0;
859         dirty_arrays = 0;
860         for (a = *aap; a ; a = a->next) {
861
862                 if (a->replaces && !discard_this) {
863                         struct active_array **ap;
864                         for (ap = &a->next; *ap && *ap != a->replaces;
865                              ap = & (*ap)->next)
866                                 ;
867                         if (*ap)
868                                 *ap = (*ap)->next;
869                         discard_this = a->replaces;
870                         a->replaces = NULL;
871                         /* FIXME check if device->state_fd need to be cleared?*/
872                         signal_manager();
873                 }
874                 if (a->container && !a->to_remove) {
875                         int ret = read_and_act(a, &rfds);
876                         rv |= 1;
877                         dirty_arrays += !!(ret & ARRAY_DIRTY);
878                         /* when terminating stop manipulating the array after it
879                          * is clean, but make sure read_and_act() is given a
880                          * chance to handle 'active_idle'
881                          */
882                         if (sigterm && !(ret & ARRAY_DIRTY))
883                                 a->container = NULL; /* stop touching this array */
884                         if (ret & ARRAY_BUSY)
885                                 container->retry_soon = 1;
886                 }
887         }
888
889         /* propagate failures across container members */
890         for (a = *aap; a ; a = a->next) {
891                 if (!a->container || a->to_remove)
892                         continue;
893                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
894                         if (mdi->curr_state & DS_FAULTY)
895                                 reconcile_failed(*aap, mdi);
896         }
897
898         return rv;
899 }
900
901 void do_monitor(struct supertype *container)
902 {
903         int rv;
904         int first = 1;
905         do {
906                 rv = wait_and_act(container, first);
907                 first = 0;
908         } while (rv >= 0);
909 }