]> git.neil.brown.name Git - mdadm.git/blob - monitor.c
870cc1a7cd4249266b9a61550d04bdfb1e6062db
[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 static int write_attr(char *attr, int fd)
35 {
36         return write(fd, attr, strlen(attr));
37 }
38
39 static void add_fd(fd_set *fds, int *maxfd, int fd)
40 {
41         struct stat st;
42         if (fd < 0)
43                 return;
44         if (fstat(fd, &st) == -1) {
45                 dprintf("Invalid fd %d\n", fd);
46                 return;
47         }
48         if (st.st_nlink == 0) {
49                 dprintf("fd %d was deleted\n", fd);
50                 return;
51         }
52         if (fd > *maxfd)
53                 *maxfd = fd;
54         FD_SET(fd, fds);
55 }
56
57 static int read_attr(char *buf, int len, int fd)
58 {
59         int n;
60
61         if (fd < 0) {
62                 buf[0] = 0;
63                 return 0;
64         }
65         lseek(fd, 0, 0);
66         n = read(fd, buf, len - 1);
67
68         if (n <= 0) {
69                 buf[0] = 0;
70                 return 0;
71         }
72         buf[n] = 0;
73         if (buf[n-1] == '\n')
74                 buf[n-1] = 0;
75         return n;
76 }
77
78 static void read_resync_start(int fd, unsigned long long *v)
79 {
80         char buf[30];
81         int n;
82
83         n = read_attr(buf, 30, fd);
84         if (n <= 0) {
85                 dprintf("Failed to read resync_start (%d)\n", fd);
86                 return;
87         }
88         if (strncmp(buf, "none", 4) == 0)
89                 *v = MaxSector;
90         else
91                 *v = strtoull(buf, NULL, 10);
92 }
93
94 static unsigned long long read_sync_completed(int fd)
95 {
96         unsigned long long val;
97         char buf[50];
98         int n;
99         char *ep;
100
101         n = read_attr(buf, 50, fd);
102
103         if (n <= 0)
104                 return 0;
105         buf[n] = 0;
106         val = strtoull(buf, &ep, 0);
107         if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' '))
108                 return 0;
109         return val;
110 }
111
112 static enum array_state read_state(int fd)
113 {
114         char buf[20];
115         int n = read_attr(buf, 20, fd);
116
117         if (n <= 0)
118                 return bad_word;
119         return (enum array_state) sysfs_match_word(buf, array_states);
120 }
121
122 static enum sync_action read_action( int fd)
123 {
124         char buf[20];
125         int n = read_attr(buf, 20, fd);
126
127         if (n <= 0)
128                 return bad_action;
129         return (enum sync_action) sysfs_match_word(buf, sync_actions);
130 }
131
132 int read_dev_state(int fd)
133 {
134         char buf[60];
135         int n = read_attr(buf, 60, fd);
136         char *cp;
137         int rv = 0;
138
139         if (n <= 0)
140                 return 0;
141
142         cp = buf;
143         while (cp) {
144                 if (sysfs_attr_match(cp, "faulty"))
145                         rv |= DS_FAULTY;
146                 if (sysfs_attr_match(cp, "in_sync"))
147                         rv |= DS_INSYNC;
148                 if (sysfs_attr_match(cp, "write_mostly"))
149                         rv |= DS_WRITE_MOSTLY;
150                 if (sysfs_attr_match(cp, "spare"))
151                         rv |= DS_SPARE;
152                 if (sysfs_attr_match(cp, "blocked"))
153                         rv |= DS_BLOCKED;
154                 cp = strchr(cp, ',');
155                 if (cp)
156                         cp++;
157         }
158         return rv;
159 }
160
161 static void signal_manager(void)
162 {
163         /* tgkill(getpid(), mon_tid, SIGUSR1); */
164         int pid = getpid();
165         syscall(SYS_tgkill, pid, mgr_tid, SIGUSR1);
166 }
167
168 /* Monitor a set of active md arrays - all of which share the
169  * same metadata - and respond to events that require
170  * metadata update.
171  *
172  * New arrays are detected by another thread which allocates
173  * required memory and attaches the data structure to our list.
174  *
175  * Events:
176  *  Array stops.
177  *    This is detected by array_state going to 'clear' or 'inactive'.
178  *    while we thought it was active.
179  *    Response is to mark metadata as clean and 'clear' the array(??)
180  *  write-pending
181  *    array_state if 'write-pending'
182  *    We mark metadata as 'dirty' then set array to 'active'.
183  *  active_idle
184  *    Either ignore, or mark clean, then mark metadata as clean.
185  *
186  *  device fails
187  *    detected by rd-N/state reporting "faulty"
188  *    mark device as 'failed' in metadata, let the kernel release the
189  *    device by writing '-blocked' to rd/state, and finally write 'remove' to
190  *    rd/state.  Before a disk can be replaced it must be failed and removed
191  *    from all container members, this will be preemptive for the other
192  *    arrays... safe?
193  *
194  *  sync completes
195  *    sync_action was 'resync' and becomes 'idle' and resync_start becomes
196  *    MaxSector
197  *    Notify metadata that sync is complete.
198  *
199  *  recovery completes
200  *    sync_action changes from 'recover' to 'idle'
201  *    Check each device state and mark metadata if 'faulty' or 'in_sync'.
202  *
203  *  deal with resync
204  *    This only happens on finding a new array... mdadm will have set
205  *    'resync_start' to the correct value.  If 'resync_start' indicates that an
206  *    resync needs to occur set the array to the 'active' state rather than the
207  *    initial read-auto state.
208  *
209  *
210  *
211  * We wait for a change (poll/select) on array_state, sync_action, and
212  * each rd-X/state file.
213  * When we get any change, we check everything.  So read each state file,
214  * then decide what to do.
215  *
216  * The core action is to write new metadata to all devices in the array.
217  * This is done at most once on any wakeup.
218  * After that we might:
219  *   - update the array_state
220  *   - set the role of some devices.
221  *   - request a sync_action
222  *
223  */
224
225 #define ARRAY_DIRTY 1
226 #define ARRAY_BUSY 2
227 static int read_and_act(struct active_array *a)
228 {
229         unsigned long long sync_completed;
230         int check_degraded = 0;
231         int check_reshape = 0;
232         int deactivate = 0;
233         struct mdinfo *mdi;
234         int ret = 0;
235         int count = 0;
236         struct timeval tv;
237
238         a->next_state = bad_word;
239         a->next_action = bad_action;
240
241         a->curr_state = read_state(a->info.state_fd);
242         a->curr_action = read_action(a->action_fd);
243         if (a->curr_state != clear)
244                 /*
245                  * In "clear" state, resync_start may wrongly be set to "0"
246                  * when the kernel called md_clean but didn't remove the
247                  * sysfs attributes yet
248                  */
249                 read_resync_start(a->resync_start_fd, &a->info.resync_start);
250         sync_completed = read_sync_completed(a->sync_completed_fd);
251         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
252                 mdi->next_state = 0;
253                 mdi->curr_state = 0;
254                 if (mdi->state_fd >= 0) {
255                         read_resync_start(mdi->recovery_fd,
256                                           &mdi->recovery_start);
257                         mdi->curr_state = read_dev_state(mdi->state_fd);
258                 }
259         }
260
261         gettimeofday(&tv, NULL);
262         dprintf("(%d): %ld.%06ld state:%s prev:%s action:%s prev: %s start:%llu\n",
263                 a->info.container_member,
264                 tv.tv_sec, tv.tv_usec,
265                 array_states[a->curr_state],
266                 array_states[a->prev_state],
267                 sync_actions[a->curr_action],
268                 sync_actions[a->prev_action],
269                 a->info.resync_start
270                 );
271
272         if ((a->curr_state == bad_word || a->curr_state <= inactive) &&
273             a->prev_state > inactive) {
274                 /* array has been stopped */
275                 a->container->ss->set_array_state(a, 1);
276                 a->next_state = clear;
277                 deactivate = 1;
278         }
279         if (a->curr_state == write_pending) {
280                 a->container->ss->set_array_state(a, 0);
281                 a->next_state = active;
282                 ret |= ARRAY_DIRTY;
283         }
284         if (a->curr_state == active_idle) {
285                 /* Set array to 'clean' FIRST, then mark clean
286                  * in the metadata
287                  */
288                 a->next_state = clean;
289                 ret |= ARRAY_DIRTY;
290         }
291         if (a->curr_state == clean) {
292                 a->container->ss->set_array_state(a, 1);
293         }
294         if (a->curr_state == active ||
295             a->curr_state == suspended)
296                 ret |= ARRAY_DIRTY;
297         if (a->curr_state == readonly) {
298                 /* Well, I'm ready to handle things.  If readonly
299                  * wasn't requested, transition to read-auto.
300                  */
301                 char buf[64];
302                 read_attr(buf, sizeof(buf), a->metadata_fd);
303                 if (strncmp(buf, "external:-", 10) == 0) {
304                         /* explicit request for readonly array.  Leave it alone */
305                         ;
306                 } else {
307                         if (a->container->ss->set_array_state(a, 2))
308                                 a->next_state = read_auto; /* array is clean */
309                         else {
310                                 a->next_state = active; /* Now active for recovery etc */
311                                 ret |= ARRAY_DIRTY;
312                         }
313                 }
314         }
315
316         if (!deactivate &&
317             a->curr_action == idle &&
318             a->prev_action == resync) {
319                 /* A resync has finished.  The endpoint is recorded in
320                  * 'sync_start'.  We don't update the metadata
321                  * until the array goes inactive or readonly though.
322                  * Just check if we need to fiddle spares.
323                  */
324                 a->container->ss->set_array_state(a, a->curr_state <= clean);
325                 check_degraded = 1;
326         }
327
328         if (!deactivate &&
329             a->curr_action == idle &&
330             a->prev_action == recover) {
331                 /* A recovery has finished.  Some disks may be in sync now,
332                  * and the array may no longer be degraded
333                  */
334                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next) {
335                         a->container->ss->set_disk(a, mdi->disk.raid_disk,
336                                                    mdi->curr_state);
337                         if (! (mdi->curr_state & DS_INSYNC))
338                                 check_degraded = 1;
339                         count++;
340                 }
341                 if (count != a->info.array.raid_disks)
342                         check_degraded = 1;
343         }
344
345         if (!deactivate &&
346             a->curr_action == reshape &&
347             a->prev_action != reshape)
348                 /* reshape was requested by mdadm.  Need to see if
349                  * new devices have been added.  Manager does that
350                  * when it sees check_reshape
351                  */
352                 check_reshape = 1;
353
354         /* Check for failures and if found:
355          * 1/ Record the failure in the metadata and unblock the device.
356          *    FIXME update the kernel to stop notifying on failed drives when
357          *    the array is readonly and we have cleared 'blocked'
358          * 2/ Try to remove the device if the array is writable, or can be
359          *    made writable.
360          */
361         for (mdi = a->info.devs ; mdi ; mdi = mdi->next) {
362                 if (mdi->curr_state & DS_FAULTY) {
363                         a->container->ss->set_disk(a, mdi->disk.raid_disk,
364                                                    mdi->curr_state);
365                         check_degraded = 1;
366                         if (mdi->curr_state & DS_BLOCKED)
367                                 mdi->next_state |= DS_UNBLOCK;
368                         if (a->curr_state == read_auto) {
369                                 a->container->ss->set_array_state(a, 0);
370                                 a->next_state = active;
371                         }
372                         if (a->curr_state > readonly)
373                                 mdi->next_state |= DS_REMOVE;
374                 }
375         }
376
377         /* Check for recovery checkpoint notifications.  We need to be a
378          * minimum distance away from the last checkpoint to prevent
379          * over checkpointing.  Note reshape checkpointing is handled
380          * in the second branch.
381          */
382         if (sync_completed > a->last_checkpoint &&
383             sync_completed - a->last_checkpoint > a->info.component_size >> 4 &&
384             a->curr_action > reshape) {
385                 /* A (non-reshape) sync_action has reached a checkpoint.
386                  * Record the updated position in the metadata
387                  */
388                 a->last_checkpoint = sync_completed;
389                 a->container->ss->set_array_state(a, a->curr_state <= clean);
390         } else if ((a->curr_action == idle && a->prev_action == reshape) ||
391                    (a->curr_action == reshape
392                     && sync_completed > a->last_checkpoint) ) {
393                 /* Reshape has progressed or completed so we need to
394                  * update the array state - and possibly the array size
395                  */
396                 if (sync_completed != 0)
397                         a->last_checkpoint = sync_completed;
398                 /* We might need to update last_checkpoint depending on
399                  * the reason that reshape finished.
400                  * if array reshape is really finished:
401                  *        set check point to the end, this allows
402                  *        set_array_state() to finalize reshape in metadata
403                  * if reshape if broken: do not set checkpoint to the end
404                  *        this allows for reshape restart from checkpoint
405                  */
406                 if ((a->curr_action != reshape) &&
407                     (a->prev_action == reshape)) {
408                         char buf[40];
409                         if ((sysfs_get_str(&a->info, NULL,
410                                           "reshape_position",
411                                           buf,
412                                           sizeof(buf)) >= 0) &&
413                              strncmp(buf, "none", 4) == 0)
414                                 a->last_checkpoint = a->info.component_size;
415                 }
416                 a->container->ss->set_array_state(a, a->curr_state <= clean);
417                 a->last_checkpoint = sync_completed;
418         }
419
420         if (sync_completed > a->last_checkpoint)
421                 a->last_checkpoint = sync_completed;
422
423         a->container->ss->sync_metadata(a->container);
424         dprintf("(%d): state:%s action:%s next(", a->info.container_member,
425                 array_states[a->curr_state], sync_actions[a->curr_action]);
426
427         /* Effect state changes in the array */
428         if (a->next_state != bad_word) {
429                 dprintf_cont(" state:%s", array_states[a->next_state]);
430                 write_attr(array_states[a->next_state], a->info.state_fd);
431         }
432         if (a->next_action != bad_action) {
433                 write_attr(sync_actions[a->next_action], a->action_fd);
434                 dprintf_cont(" action:%s", sync_actions[a->next_action]);
435         }
436         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
437                 if (mdi->next_state & DS_UNBLOCK) {
438                         dprintf_cont(" %d:-blocked", mdi->disk.raid_disk);
439                         write_attr("-blocked", mdi->state_fd);
440                 }
441
442                 if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
443                         int remove_result;
444
445                         /* The kernel may not be able to immediately remove the
446                          * disk.  In that case we wait a little while and
447                          * try again.
448                          */
449                         remove_result = write_attr("remove", mdi->state_fd);
450                         if (remove_result > 0) {
451                                 dprintf_cont(" %d:removed", mdi->disk.raid_disk);
452                                 close(mdi->state_fd);
453                                 close(mdi->recovery_fd);
454                                 mdi->state_fd = -1;
455                         } else
456                                 ret |= ARRAY_BUSY;
457                 }
458                 if (mdi->next_state & DS_INSYNC) {
459                         write_attr("+in_sync", mdi->state_fd);
460                         dprintf_cont(" %d:+in_sync", mdi->disk.raid_disk);
461                 }
462         }
463         dprintf_cont(" )\n");
464
465         /* move curr_ to prev_ */
466         a->prev_state = a->curr_state;
467
468         a->prev_action = a->curr_action;
469
470         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
471                 mdi->prev_state = mdi->curr_state;
472                 mdi->next_state = 0;
473         }
474
475         if (check_degraded || check_reshape) {
476                 /* manager will do the actual check */
477                 if (check_degraded)
478                         a->check_degraded = 1;
479                 if (check_reshape)
480                         a->check_reshape = 1;
481                 signal_manager();
482         }
483
484         if (deactivate)
485                 a->container = NULL;
486
487         return ret;
488 }
489
490 static struct mdinfo *
491 find_device(struct active_array *a, int major, int minor)
492 {
493         struct mdinfo *mdi;
494
495         for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
496                 if (mdi->disk.major == major && mdi->disk.minor == minor)
497                         return mdi;
498
499         return NULL;
500 }
501
502 static void reconcile_failed(struct active_array *aa, struct mdinfo *failed)
503 {
504         struct active_array *a;
505         struct mdinfo *victim;
506
507         for (a = aa; a; a = a->next) {
508                 if (!a->container || a->to_remove)
509                         continue;
510                 victim = find_device(a, failed->disk.major, failed->disk.minor);
511                 if (!victim)
512                         continue;
513
514                 if (!(victim->curr_state & DS_FAULTY))
515                         write_attr("faulty", victim->state_fd);
516         }
517 }
518
519 #ifdef DEBUG
520 static void dprint_wake_reasons(fd_set *fds)
521 {
522         int i;
523         char proc_path[256];
524         char link[256];
525         char *basename;
526         int rv;
527
528         fprintf(stderr, "monitor: wake ( ");
529         for (i = 0; i < FD_SETSIZE; i++) {
530                 if (FD_ISSET(i, fds)) {
531                         sprintf(proc_path, "/proc/%d/fd/%d",
532                                 (int) getpid(), i);
533
534                         rv = readlink(proc_path, link, sizeof(link) - 1);
535                         if (rv < 0) {
536                                 fprintf(stderr, "%d:unknown ", i);
537                                 continue;
538                         }
539                         link[rv] = '\0';
540                         basename = strrchr(link, '/');
541                         fprintf(stderr, "%d:%s ",
542                                 i, basename ? ++basename : link);
543                 }
544         }
545         fprintf(stderr, ")\n");
546 }
547 #endif
548
549 int monitor_loop_cnt;
550
551 static int wait_and_act(struct supertype *container, int nowait)
552 {
553         fd_set rfds;
554         int maxfd = 0;
555         struct active_array **aap = &container->arrays;
556         struct active_array *a, **ap;
557         int rv;
558         struct mdinfo *mdi;
559         static unsigned int dirty_arrays = ~0; /* start at some non-zero value */
560
561         FD_ZERO(&rfds);
562
563         for (ap = aap ; *ap ;) {
564                 a = *ap;
565                 /* once an array has been deactivated we want to
566                  * ask the manager to discard it.
567                  */
568                 if (!a->container || a->to_remove) {
569                         if (discard_this) {
570                                 ap = &(*ap)->next;
571                                 continue;
572                         }
573                         *ap = a->next;
574                         a->next = NULL;
575                         discard_this = a;
576                         signal_manager();
577                         continue;
578                 }
579
580                 add_fd(&rfds, &maxfd, a->info.state_fd);
581                 add_fd(&rfds, &maxfd, a->action_fd);
582                 add_fd(&rfds, &maxfd, a->sync_completed_fd);
583                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
584                         add_fd(&rfds, &maxfd, mdi->state_fd);
585
586                 ap = &(*ap)->next;
587         }
588
589         if (manager_ready && (*aap == NULL || (sigterm && !dirty_arrays))) {
590                 /* No interesting arrays, or we have been told to
591                  * terminate and everything is clean.  Lets see about
592                  * exiting.  Note that blocking at this point is not a
593                  * problem as there are no active arrays, there is
594                  * nothing that we need to be ready to do.
595                  */
596                 int fd;
597                 if (sigterm)
598                         fd = open_dev_excl(container->devnm);
599                 else
600                         fd = open_dev_flags(container->devnm, O_RDONLY|O_EXCL);
601                 if (fd >= 0 || errno != EBUSY) {
602                         /* OK, we are safe to leave */
603                         if (sigterm && !dirty_arrays)
604                                 dprintf("caught sigterm, all clean... exiting\n");
605                         else
606                                 dprintf("no arrays to monitor... exiting\n");
607                         if (!sigterm)
608                                 /* On SIGTERM, someone (the take-over mdmon) will
609                                  * clean up
610                                  */
611                                 remove_pidfile(container->devnm);
612                         exit_now = 1;
613                         signal_manager();
614                         close(fd);
615                         exit(0);
616                 }
617         }
618
619         if (!nowait) {
620                 sigset_t set;
621                 struct timespec ts;
622                 ts.tv_sec = 24*3600;
623                 ts.tv_nsec = 0;
624                 if (*aap == NULL || container->retry_soon) {
625                         /* just waiting to get O_EXCL access */
626                         ts.tv_sec = 0;
627                         ts.tv_nsec = 20000000ULL;
628                 }
629                 sigprocmask(SIG_UNBLOCK, NULL, &set);
630                 sigdelset(&set, SIGUSR1);
631                 monitor_loop_cnt |= 1;
632                 rv = pselect(maxfd+1, NULL, NULL, &rfds, &ts, &set);
633                 monitor_loop_cnt += 1;
634                 if (rv == -1) {
635                         if (errno == EINTR) {
636                                 rv = 0;
637                                 dprintf("monitor: caught signal\n");
638                         } else
639                                 dprintf("monitor: error %d in pselect\n",
640                                         errno);
641                 }
642                 #ifdef DEBUG
643                 else
644                         dprint_wake_reasons(&rfds);
645                 #endif
646                 container->retry_soon = 0;
647         }
648
649         if (update_queue) {
650                 struct metadata_update *this;
651
652                 for (this = update_queue; this ; this = this->next)
653                         container->ss->process_update(container, this);
654
655                 update_queue_handled = update_queue;
656                 update_queue = NULL;
657                 signal_manager();
658                 container->ss->sync_metadata(container);
659         }
660
661         rv = 0;
662         dirty_arrays = 0;
663         for (a = *aap; a ; a = a->next) {
664
665                 if (a->replaces && !discard_this) {
666                         struct active_array **ap;
667                         for (ap = &a->next; *ap && *ap != a->replaces;
668                              ap = & (*ap)->next)
669                                 ;
670                         if (*ap)
671                                 *ap = (*ap)->next;
672                         discard_this = a->replaces;
673                         a->replaces = NULL;
674                         /* FIXME check if device->state_fd need to be cleared?*/
675                         signal_manager();
676                 }
677                 if (a->container && !a->to_remove) {
678                         int ret = read_and_act(a);
679                         rv |= 1;
680                         dirty_arrays += !!(ret & ARRAY_DIRTY);
681                         /* when terminating stop manipulating the array after it
682                          * is clean, but make sure read_and_act() is given a
683                          * chance to handle 'active_idle'
684                          */
685                         if (sigterm && !(ret & ARRAY_DIRTY))
686                                 a->container = NULL; /* stop touching this array */
687                         if (ret & ARRAY_BUSY)
688                                 container->retry_soon = 1;
689                 }
690         }
691
692         /* propagate failures across container members */
693         for (a = *aap; a ; a = a->next) {
694                 if (!a->container || a->to_remove)
695                         continue;
696                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
697                         if (mdi->curr_state & DS_FAULTY)
698                                 reconcile_failed(*aap, mdi);
699         }
700
701         return rv;
702 }
703
704 void do_monitor(struct supertype *container)
705 {
706         int rv;
707         int first = 1;
708         do {
709                 rv = wait_and_act(container, first);
710                 first = 0;
711         } while (rv >= 0);
712 }