]> git.neil.brown.name Git - mdadm.git/blob - monitor.c
Fix some issues found by clang
[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         if (sync_completed >= a->info.component_size)
424                 a->last_checkpoint = 0;
425
426         a->container->ss->sync_metadata(a->container);
427         dprintf("(%d): state:%s action:%s next(", a->info.container_member,
428                 array_states[a->curr_state], sync_actions[a->curr_action]);
429
430         /* Effect state changes in the array */
431         if (a->next_state != bad_word) {
432                 dprintf_cont(" state:%s", array_states[a->next_state]);
433                 write_attr(array_states[a->next_state], a->info.state_fd);
434         }
435         if (a->next_action != bad_action) {
436                 write_attr(sync_actions[a->next_action], a->action_fd);
437                 dprintf_cont(" action:%s", sync_actions[a->next_action]);
438         }
439         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
440                 if (mdi->next_state & DS_UNBLOCK) {
441                         dprintf_cont(" %d:-blocked", mdi->disk.raid_disk);
442                         write_attr("-blocked", mdi->state_fd);
443                 }
444
445                 if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
446                         int remove_result;
447
448                         /* The kernel may not be able to immediately remove the
449                          * disk.  In that case we wait a little while and
450                          * try again.
451                          */
452                         remove_result = write_attr("remove", mdi->state_fd);
453                         if (remove_result > 0) {
454                                 dprintf_cont(" %d:removed", mdi->disk.raid_disk);
455                                 close(mdi->state_fd);
456                                 close(mdi->recovery_fd);
457                                 mdi->state_fd = -1;
458                         } else
459                                 ret |= ARRAY_BUSY;
460                 }
461                 if (mdi->next_state & DS_INSYNC) {
462                         write_attr("+in_sync", mdi->state_fd);
463                         dprintf_cont(" %d:+in_sync", mdi->disk.raid_disk);
464                 }
465         }
466         dprintf_cont(" )\n");
467
468         /* move curr_ to prev_ */
469         a->prev_state = a->curr_state;
470
471         a->prev_action = a->curr_action;
472
473         for (mdi = a->info.devs; mdi ; mdi = mdi->next) {
474                 mdi->prev_state = mdi->curr_state;
475                 mdi->next_state = 0;
476         }
477
478         if (check_degraded || check_reshape) {
479                 /* manager will do the actual check */
480                 if (check_degraded)
481                         a->check_degraded = 1;
482                 if (check_reshape)
483                         a->check_reshape = 1;
484                 signal_manager();
485         }
486
487         if (deactivate)
488                 a->container = NULL;
489
490         return ret;
491 }
492
493 static struct mdinfo *
494 find_device(struct active_array *a, int major, int minor)
495 {
496         struct mdinfo *mdi;
497
498         for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
499                 if (mdi->disk.major == major && mdi->disk.minor == minor)
500                         return mdi;
501
502         return NULL;
503 }
504
505 static void reconcile_failed(struct active_array *aa, struct mdinfo *failed)
506 {
507         struct active_array *a;
508         struct mdinfo *victim;
509
510         for (a = aa; a; a = a->next) {
511                 if (!a->container || a->to_remove)
512                         continue;
513                 victim = find_device(a, failed->disk.major, failed->disk.minor);
514                 if (!victim)
515                         continue;
516
517                 if (!(victim->curr_state & DS_FAULTY))
518                         write_attr("faulty", victim->state_fd);
519         }
520 }
521
522 #ifdef DEBUG
523 static void dprint_wake_reasons(fd_set *fds)
524 {
525         int i;
526         char proc_path[256];
527         char link[256];
528         char *basename;
529         int rv;
530
531         fprintf(stderr, "monitor: wake ( ");
532         for (i = 0; i < FD_SETSIZE; i++) {
533                 if (FD_ISSET(i, fds)) {
534                         sprintf(proc_path, "/proc/%d/fd/%d",
535                                 (int) getpid(), i);
536
537                         rv = readlink(proc_path, link, sizeof(link) - 1);
538                         if (rv < 0) {
539                                 fprintf(stderr, "%d:unknown ", i);
540                                 continue;
541                         }
542                         link[rv] = '\0';
543                         basename = strrchr(link, '/');
544                         fprintf(stderr, "%d:%s ",
545                                 i, basename ? ++basename : link);
546                 }
547         }
548         fprintf(stderr, ")\n");
549 }
550 #endif
551
552 int monitor_loop_cnt;
553
554 static int wait_and_act(struct supertype *container, int nowait)
555 {
556         fd_set rfds;
557         int maxfd = 0;
558         struct active_array **aap = &container->arrays;
559         struct active_array *a, **ap;
560         int rv;
561         struct mdinfo *mdi;
562         static unsigned int dirty_arrays = ~0; /* start at some non-zero value */
563
564         FD_ZERO(&rfds);
565
566         for (ap = aap ; *ap ;) {
567                 a = *ap;
568                 /* once an array has been deactivated we want to
569                  * ask the manager to discard it.
570                  */
571                 if (!a->container || a->to_remove) {
572                         if (discard_this) {
573                                 ap = &(*ap)->next;
574                                 continue;
575                         }
576                         *ap = a->next;
577                         a->next = NULL;
578                         discard_this = a;
579                         signal_manager();
580                         continue;
581                 }
582
583                 add_fd(&rfds, &maxfd, a->info.state_fd);
584                 add_fd(&rfds, &maxfd, a->action_fd);
585                 add_fd(&rfds, &maxfd, a->sync_completed_fd);
586                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
587                         add_fd(&rfds, &maxfd, mdi->state_fd);
588
589                 ap = &(*ap)->next;
590         }
591
592         if (manager_ready && (*aap == NULL || (sigterm && !dirty_arrays))) {
593                 /* No interesting arrays, or we have been told to
594                  * terminate and everything is clean.  Lets see about
595                  * exiting.  Note that blocking at this point is not a
596                  * problem as there are no active arrays, there is
597                  * nothing that we need to be ready to do.
598                  */
599                 int fd;
600                 if (sigterm)
601                         fd = open_dev_excl(container->devnm);
602                 else
603                         fd = open_dev_flags(container->devnm, O_RDONLY|O_EXCL);
604                 if (fd >= 0 || errno != EBUSY) {
605                         /* OK, we are safe to leave */
606                         if (sigterm && !dirty_arrays)
607                                 dprintf("caught sigterm, all clean... exiting\n");
608                         else
609                                 dprintf("no arrays to monitor... exiting\n");
610                         if (!sigterm)
611                                 /* On SIGTERM, someone (the take-over mdmon) will
612                                  * clean up
613                                  */
614                                 remove_pidfile(container->devnm);
615                         exit_now = 1;
616                         signal_manager();
617                         close(fd);
618                         exit(0);
619                 }
620         }
621
622         if (!nowait) {
623                 sigset_t set;
624                 struct timespec ts;
625                 ts.tv_sec = 24*3600;
626                 ts.tv_nsec = 0;
627                 if (*aap == NULL || container->retry_soon) {
628                         /* just waiting to get O_EXCL access */
629                         ts.tv_sec = 0;
630                         ts.tv_nsec = 20000000ULL;
631                 }
632                 sigprocmask(SIG_UNBLOCK, NULL, &set);
633                 sigdelset(&set, SIGUSR1);
634                 monitor_loop_cnt |= 1;
635                 rv = pselect(maxfd+1, NULL, NULL, &rfds, &ts, &set);
636                 monitor_loop_cnt += 1;
637                 if (rv == -1) {
638                         if (errno == EINTR) {
639                                 rv = 0;
640                                 dprintf("monitor: caught signal\n");
641                         } else
642                                 dprintf("monitor: error %d in pselect\n",
643                                         errno);
644                 }
645                 #ifdef DEBUG
646                 else
647                         dprint_wake_reasons(&rfds);
648                 #endif
649                 container->retry_soon = 0;
650         }
651
652         if (update_queue) {
653                 struct metadata_update *this;
654
655                 for (this = update_queue; this ; this = this->next)
656                         container->ss->process_update(container, this);
657
658                 update_queue_handled = update_queue;
659                 update_queue = NULL;
660                 signal_manager();
661                 container->ss->sync_metadata(container);
662         }
663
664         rv = 0;
665         dirty_arrays = 0;
666         for (a = *aap; a ; a = a->next) {
667
668                 if (a->replaces && !discard_this) {
669                         struct active_array **ap;
670                         for (ap = &a->next; *ap && *ap != a->replaces;
671                              ap = & (*ap)->next)
672                                 ;
673                         if (*ap)
674                                 *ap = (*ap)->next;
675                         discard_this = a->replaces;
676                         a->replaces = NULL;
677                         /* FIXME check if device->state_fd need to be cleared?*/
678                         signal_manager();
679                 }
680                 if (a->container && !a->to_remove) {
681                         int ret = read_and_act(a);
682                         rv |= 1;
683                         dirty_arrays += !!(ret & ARRAY_DIRTY);
684                         /* when terminating stop manipulating the array after it
685                          * is clean, but make sure read_and_act() is given a
686                          * chance to handle 'active_idle'
687                          */
688                         if (sigterm && !(ret & ARRAY_DIRTY))
689                                 a->container = NULL; /* stop touching this array */
690                         if (ret & ARRAY_BUSY)
691                                 container->retry_soon = 1;
692                 }
693         }
694
695         /* propagate failures across container members */
696         for (a = *aap; a ; a = a->next) {
697                 if (!a->container || a->to_remove)
698                         continue;
699                 for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
700                         if (mdi->curr_state & DS_FAULTY)
701                                 reconcile_failed(*aap, mdi);
702         }
703
704         return rv;
705 }
706
707 void do_monitor(struct supertype *container)
708 {
709         int rv;
710         int first = 1;
711         do {
712                 rv = wait_and_act(container, first);
713                 first = 0;
714         } while (rv >= 0);
715 }