Factor out test for subarray version string.
[thirdparty/mdadm.git] / managemon.c
1
2 /*
3  * The management thread for monitoring active md arrays.
4  * This thread does things which might block such as memory
5  * allocation.
6  * In particular:
7  *
8  * - Find out about new arrays in this container.
9  *   Allocate the data structures and open the files.
10  *
11  *   For this we watch /proc/mdstat and find new arrays with
12  *   metadata type that confirms sharing. e.g. "md4"
13  *   When we find a new array we slip it into the list of
14  *   arrays and signal 'monitor' by writing to a pipe.
15  *
16  * - Respond to reshape requests by allocating new data structures
17  *   and opening new files.
18  *
19  *   These come as a change to raid_disks.  We allocate a new
20  *   version of the data structures and slip it into the list.
21  *   'monitor' will notice and release the old version.
22  *   Changes to level, chunksize, layout.. do not need re-allocation.
23  *   Reductions in raid_disks don't really either, but we handle
24  *   them the same way for consistency.
25  *
26  * - When a device is added to the container, we add it to the metadata
27  *   as a spare.
28  *
29  * - Deal with degraded array
30  *    We only do this when first noticing the array is degraded.
31  *    This can be when we first see the array, when sync completes or
32  *    when recovery completes.
33  *
34  *    Check if number of failed devices suggests recovery is needed, and
35  *    skip if not.
36  *    Ask metadata to allocate a spare device
37  *    Add device as not in_sync and give a role
38  *    Update metadata.
39  *    Open sysfs files and pass to monitor.
40  *    Make sure that monitor Starts recovery....
41  *
42  * - Pass on metadata updates from external programs such as
43  *   mdadm creating a new array.
44  *
45  *   This is most-messy.
46  *   It might involve adding a new array or changing the status of
47  *   a spare, or any reconfig that the kernel doesn't get involved in.
48  *
49  *   The required updates are received via a named pipe.  There will
50  *   be one named pipe for each container. Each message contains a
51  *   sync marker: 0x5a5aa5a5, A byte count, and the message.  This is
52  *   passed to the metadata handler which will interpret and process it.
53  *   For 'DDF' messages are internal data blocks with the leading
54  *   'magic number' signifying what sort of data it is.
55  *
56  */
57
58 /*
59  * We select on /proc/mdstat and the named pipe.
60  * We create new arrays or updated version of arrays and slip
61  * them into the head of the list, then signal 'monitor' via a pipe write.
62  * 'monitor' will notice and place the old array on a return list.
63  * Metadata updates are placed on a queue just like they arrive
64  * from the named pipe.
65  *
66  * When new arrays are found based on correct metadata string, we
67  * need to identify them with an entry in the metadata.  Maybe we require
68  * the metadata to be mdX/NN  when NN is the index into an appropriate table.
69  *
70  */
71
72 /*
73  * List of tasks:
74  * - Watch for spares to be added to the container, and write updated
75  *   metadata to them.
76  * - Watch for new arrays using this container, confirm they match metadata
77  *   and if so, start monitoring them
78  * - Watch for spares being added to monitored arrays.  This shouldn't
79  *   happen, as we should do all the adding.  Just remove them.
80  * - Watch for change in raid-disks, chunk-size, etc.  Update metadata and
81  *   start a reshape.
82  */
83 #ifndef _GNU_SOURCE
84 #define _GNU_SOURCE
85 #endif
86 #include        "mdadm.h"
87 #include        "mdmon.h"
88 #include        <sys/syscall.h>
89 #include        <sys/socket.h>
90 #include        <signal.h>
91
92 static void close_aa(struct active_array *aa)
93 {
94         struct mdinfo *d;
95
96         for (d = aa->info.devs; d; d = d->next)
97                 close(d->state_fd);
98
99         close(aa->action_fd);
100         close(aa->info.state_fd);
101         close(aa->resync_start_fd);
102 }
103
104 static void free_aa(struct active_array *aa)
105 {
106         /* Note that this doesn't close fds if they are being used
107          * by a clone.  ->container will be set for a clone
108          */
109         dprintf("%s: devnum: %d\n", __func__, aa->devnum);
110         if (!aa->container)
111                 close_aa(aa);
112         while (aa->info.devs) {
113                 struct mdinfo *d = aa->info.devs;
114                 aa->info.devs = d->next;
115                 free(d);
116         }
117         free(aa);
118 }
119
120 static struct active_array *duplicate_aa(struct active_array *aa)
121 {
122         struct active_array *newa = malloc(sizeof(*newa));
123         struct mdinfo **dp1, **dp2;
124
125         *newa = *aa;
126         newa->next = NULL;
127         newa->replaces = NULL;
128         newa->info.next = NULL;
129
130         dp2 = &newa->info.devs;
131
132         for (dp1 = &aa->info.devs; *dp1; dp1 = &(*dp1)->next) {
133                 struct mdinfo *d;
134                 if ((*dp1)->state_fd < 0)
135                         continue;
136
137                 d = malloc(sizeof(*d));
138                 *d = **dp1;
139                 *dp2 = d;
140                 dp2 = & d->next;
141         }
142         *dp2 = NULL;
143
144         return newa;
145 }
146
147 static void wakeup_monitor(void)
148 {
149         /* tgkill(getpid(), mon_tid, SIGUSR1); */
150         int pid = getpid();
151         syscall(SYS_tgkill, pid, mon_tid, SIGUSR1);
152 }
153
154 static void remove_old(void)
155 {
156         if (discard_this) {
157                 discard_this->next = NULL;
158                 free_aa(discard_this);
159                 if (pending_discard == discard_this)
160                         pending_discard = NULL;
161                 discard_this = NULL;
162                 wakeup_monitor();
163         }
164 }
165
166 static void replace_array(struct supertype *container,
167                           struct active_array *old,
168                           struct active_array *new)
169 {
170         /* To replace an array, we add it to the top of the list
171          * marked with ->replaces to point to the original.
172          * 'monitor' will take the original out of the list
173          * and put it on 'discard_this'.  We take it from there
174          * and discard it.
175          */
176         remove_old();
177         while (pending_discard) {
178                 while (discard_this == NULL)
179                         sleep(1);
180                 remove_old();
181         }
182         pending_discard = old;
183         new->replaces = old;
184         new->next = container->arrays;
185         container->arrays = new;
186         wakeup_monitor();
187 }
188
189 struct metadata_update *update_queue = NULL;
190 struct metadata_update *update_queue_handled = NULL;
191 struct metadata_update *update_queue_pending = NULL;
192
193 void check_update_queue(struct supertype *container)
194 {
195         while (update_queue_handled) {
196                 struct metadata_update *this = update_queue_handled;
197                 update_queue_handled = this->next;
198                 free(this->buf);
199                 if (this->space)
200                         free(this->space);
201                 free(this);
202         }
203         if (update_queue == NULL &&
204             update_queue_pending) {
205                 update_queue = update_queue_pending;
206                 update_queue_pending = NULL;
207                 wakeup_monitor();
208         }
209 }
210
211 static void queue_metadata_update(struct metadata_update *mu)
212 {
213         struct metadata_update **qp;
214
215         qp = &update_queue_pending;
216         while (*qp)
217                 qp = & ((*qp)->next);
218         *qp = mu;
219 }
220
221 static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
222 {
223         int dfd;
224         char nm[20];
225         struct metadata_update *update = NULL;
226         mdu_disk_info_t dk = {
227                 .number = -1,
228                 .major = sd->disk.major,
229                 .minor = sd->disk.minor,
230                 .raid_disk = -1,
231                 .state = 0,
232         };
233
234         dprintf("%s: add %d:%d to container\n",
235                 __func__, sd->disk.major, sd->disk.minor);
236
237         sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
238         dfd = dev_open(nm, O_RDWR);
239         if (dfd < 0)
240                 return;
241
242         st->update_tail = &update;
243         st->ss->add_to_super(st, &dk, dfd, NULL);
244         st->ss->write_init_super(st);
245         queue_metadata_update(update);
246         st->update_tail = NULL;
247 }
248
249 static void manage_container(struct mdstat_ent *mdstat,
250                              struct supertype *container)
251 {
252         /* The only thing of interest here is if a new device
253          * has been added to the container.  We add it to the
254          * array ignoring any metadata on it.
255          * FIXME should we look for compatible metadata and take hints
256          * about spare assignment.... probably not.
257          */
258         if (mdstat->devcnt != container->devcnt) {
259                 struct mdinfo **cdp, *cd, *di, *mdi;
260                 int found;
261
262                 /* read /sys/block/NAME/md/dev-??/block/dev to find out
263                  * what is there, and compare with container->info.devs
264                  * To see what is removed and what is added.
265                  * These need to be remove from, or added to, the array
266                  */
267                 mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS);
268                 if (!mdi)
269                         return;
270
271                 /* check for removals */
272                 for (cdp = &container->devs; *cdp; ) {
273                         found = 0;
274                         for (di = mdi->devs; di; di = di->next)
275                                 if (di->disk.major == (*cdp)->disk.major &&
276                                     di->disk.minor == (*cdp)->disk.minor) {
277                                         found = 1;
278                                         break;
279                                 }
280                         if (!found) {
281                                 cd = *cdp;
282                                 *cdp = (*cdp)->next;
283                                 free(cd);
284                         } else
285                                 cdp = &(*cdp)->next;
286                 }
287
288                 /* check for additions */
289                 for (di = mdi->devs; di; di = di->next) {
290                         for (cd = container->devs; cd; cd = cd->next)
291                                 if (di->disk.major == cd->disk.major &&
292                                     di->disk.minor == cd->disk.minor)
293                                         break;
294                         if (!cd)
295                                 add_disk_to_container(container, di);
296                 }
297                 sysfs_free(mdi);
298                 container->devcnt = mdstat->devcnt;
299         }
300 }
301
302 static void manage_member(struct mdstat_ent *mdstat,
303                           struct active_array *a)
304 {
305         /* Compare mdstat info with known state of member array.
306          * We do not need to look for device state changes here, that
307          * is dealt with by the monitor.
308          *
309          * We just look for changes which suggest that a reshape is
310          * being requested.
311          * Unfortunately decreases in raid_disks don't show up in
312          * mdstat until the reshape completes FIXME.
313          *
314          * Actually, we also want to handle degraded arrays here by
315          * trying to find and assign a spare.
316          * We do that whenever the monitor tells us too.
317          */
318         // FIXME
319         a->info.array.raid_disks = mdstat->raid_disks;
320         a->info.array.chunk_size = mdstat->chunk_size;
321         // MORE
322
323         if (a->check_degraded) {
324                 struct metadata_update *updates = NULL;
325                 struct mdinfo *newdev;
326                 struct active_array *newa;
327
328                 a->check_degraded = 0;
329
330                 /* The array may not be degraded, this is just a good time
331                  * to check.
332                  */
333                 newdev = a->container->ss->activate_spare(a, &updates);
334                 if (newdev) {
335                         struct mdinfo *d;
336                         /* Cool, we can add a device or several. */
337                         newa = duplicate_aa(a);
338                         /* suspend recovery - maybe not needed */
339
340                         /* Add device to array and set offset/size/slot.
341                          * and open files for each newdev */
342                         for (d = newdev; d ; d = d->next) {
343                                 struct mdinfo *newd;
344                                 if (sysfs_add_disk(&newa->info, d) < 0)
345                                         continue;
346                                 newd = newa->info.devs;
347                                 newd->state_fd = sysfs_open(a->devnum,
348                                                             newd->sys_name,
349                                                             "state");
350                                 newd->prev_state
351                                         = read_dev_state(newd->state_fd);
352                                 newd->curr_state = newd->prev_state;
353                         }
354                         queue_metadata_update(updates);
355                         replace_array(a->container, a, newa);
356                         sysfs_set_str(&a->info, NULL, "sync_action", "recover");
357                 }
358         }
359 }
360
361 static int aa_ready(struct active_array *aa)
362 {
363         struct mdinfo *d;
364         int level = aa->info.array.level;
365
366         for (d = aa->info.devs; d; d = d->next)
367                 if (d->state_fd < 0)
368                         return 0;
369
370         if (aa->info.state_fd < 0)
371                 return 0;
372
373         if (level > 0 && (aa->action_fd < 0 || aa->resync_start_fd < 0))
374                 return 0;
375
376         if (!aa->container)
377                 return 0;
378
379         return 1;
380 }
381
382 static void manage_new(struct mdstat_ent *mdstat,
383                        struct supertype *container,
384                        struct active_array *victim)
385 {
386         /* A new array has appeared in this container.
387          * Hopefully it is already recorded in the metadata.
388          * Check, then create the new array to report it to
389          * the monitor.
390          */
391
392         struct active_array *new;
393         struct mdinfo *mdi, *di;
394         char *inst;
395         int i;
396         int failed = 0;
397
398         /* check if array is ready to be monitored */
399         if (!mdstat->active)
400                 return;
401
402         mdi = sysfs_read(-1, mdstat->devnum,
403                          GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT|
404                          GET_DEGRADED|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
405
406         new = malloc(sizeof(*new));
407
408         if (!new || !mdi) {
409                 if (mdi)
410                         sysfs_free(mdi);
411                 if (new)
412                         free(new);
413                 return;
414         }
415         memset(new, 0, sizeof(*new));
416
417         new->devnum = mdstat->devnum;
418         strcpy(new->info.sys_name, devnum2devname(new->devnum));
419
420         new->prev_state = new->curr_state = new->next_state = inactive;
421         new->prev_action= new->curr_action= new->next_action= idle;
422
423         new->container = container;
424
425         inst = &mdstat->metadata_version[10+strlen(container->devname)+1];
426
427         new->info.array = mdi->array;
428         new->info.component_size = mdi->component_size;
429
430         for (i = 0; i < new->info.array.raid_disks; i++) {
431                 struct mdinfo *newd = malloc(sizeof(*newd));
432
433                 for (di = mdi->devs; di; di = di->next)
434                         if (i == di->disk.raid_disk)
435                                 break;
436
437                 if (di) {
438                         memcpy(newd, di, sizeof(*newd));
439
440                         newd->state_fd = sysfs_open(new->devnum,
441                                                     newd->sys_name,
442                                                     "state");
443
444                         newd->prev_state = read_dev_state(newd->state_fd);
445                         newd->curr_state = newd->prev_state;
446                 } else if (failed + 1 > new->info.array.failed_disks) {
447                         /* we cannot properly monitor without all working disks */
448                         new->container = NULL;
449                         break;
450                 } else {
451                         failed++;
452                         free(newd);
453                         continue;
454                 }
455                 sprintf(newd->sys_name, "rd%d", i);
456                 newd->next = new->info.devs;
457                 new->info.devs = newd;
458         }
459
460         new->action_fd = sysfs_open(new->devnum, NULL, "sync_action");
461         new->info.state_fd = sysfs_open(new->devnum, NULL, "array_state");
462         new->resync_start_fd = sysfs_open(new->devnum, NULL, "resync_start");
463         get_resync_start(new);
464         dprintf("%s: inst: %d action: %d state: %d\n", __func__, atoi(inst),
465                 new->action_fd, new->info.state_fd);
466
467         sysfs_free(mdi);
468
469         /* if everything checks out tell the metadata handler we want to
470          * manage this instance
471          */
472         if (!aa_ready(new) || container->ss->open_new(container, new, inst) < 0) {
473                 fprintf(stderr, "mdmon: failed to monitor %s\n",
474                         mdstat->metadata_version);
475                 new->container = NULL;
476                 free_aa(new);
477         } else
478                 replace_array(container, victim, new);
479 }
480
481 void manage(struct mdstat_ent *mdstat, struct supertype *container)
482 {
483         /* We have just read mdstat and need to compare it with
484          * the known active arrays.
485          * Arrays with the wrong metadata are ignored.
486          */
487
488         for ( ; mdstat ; mdstat = mdstat->next) {
489                 struct active_array *a;
490                 if (mdstat->devnum == container->devnum) {
491                         manage_container(mdstat, container);
492                         continue;
493                 }
494                 if (mdstat->metadata_version == NULL ||
495                     strncmp(mdstat->metadata_version, "external:", 9) != 0 ||
496                     !is_subarray(mdstat->metadata_version+9) ||
497                     strncmp(mdstat->metadata_version+10, container->devname,
498                             strlen(container->devname)) != 0 ||
499                     mdstat->metadata_version[10+strlen(container->devname)]
500                       != '/')
501                         /* Not for this array */
502                         continue;
503                 /* Looks like a member of this container */
504                 for (a = container->arrays; a; a = a->next) {
505                         if (mdstat->devnum == a->devnum) {
506                                 if (a->container)
507                                         manage_member(mdstat, a);
508                                 break;
509                         }
510                 }
511                 if (a == NULL || !a->container)
512                         manage_new(mdstat, container, a);
513         }
514 }
515
516 static void handle_message(struct supertype *container, struct metadata_update *msg)
517 {
518         /* queue this metadata update through to the monitor */
519
520         struct metadata_update *mu;
521
522         if (msg->len == 0) {
523                 int cnt;
524                 
525                 while (update_queue_pending || update_queue) {
526                         check_update_queue(container);
527                         usleep(15*1000);
528                 }
529
530                 cnt = monitor_loop_cnt;
531                 if (cnt & 1)
532                         cnt += 2; /* wait until next pselect */
533                 else
534                         cnt += 3; /* wait for 2 pselects */
535                 wakeup_monitor();
536
537                 while (monitor_loop_cnt - cnt < 0)
538                         usleep(10 * 1000);
539         } else {
540                 mu = malloc(sizeof(*mu));
541                 mu->len = msg->len;
542                 mu->buf = msg->buf;
543                 msg->buf = NULL;
544                 mu->space = NULL;
545                 mu->next = NULL;
546                 if (container->ss->prepare_update)
547                         container->ss->prepare_update(container, mu);
548                 queue_metadata_update(mu);
549         }
550 }
551
552 void read_sock(struct supertype *container)
553 {
554         int fd;
555         struct metadata_update msg;
556         int terminate = 0;
557         long fl;
558         int tmo = 3; /* 3 second timeout before hanging up the socket */
559
560         fd = accept(container->sock, NULL, NULL);
561         if (fd < 0)
562                 return;
563
564         fl = fcntl(fd, F_GETFL, 0);
565         fl |= O_NONBLOCK;
566         fcntl(fd, F_SETFL, fl);
567
568         do {
569                 msg.buf = NULL;
570
571                 /* read and validate the message */
572                 if (receive_message(fd, &msg, tmo) == 0) {
573                         handle_message(container, &msg);
574                         if (ack(fd, tmo) < 0)
575                                 terminate = 1;
576                 } else
577                         terminate = 1;
578
579         } while (!terminate);
580
581         close(fd);
582 }
583
584 int exit_now = 0;
585 int manager_ready = 0;
586 void do_manager(struct supertype *container)
587 {
588         struct mdstat_ent *mdstat;
589         sigset_t set;
590
591         sigprocmask(SIG_UNBLOCK, NULL, &set);
592         sigdelset(&set, SIGUSR1);
593
594         do {
595
596                 if (exit_now)
597                         exit(0);
598
599                 /* Can only 'manage' things if 'monitor' is not making
600                  * structural changes to metadata, so need to check
601                  * update_queue
602                  */
603                 if (update_queue == NULL) {
604                         mdstat = mdstat_read(1, 0);
605
606                         manage(mdstat, container);
607
608                         read_sock(container);
609
610                         free_mdstat(mdstat);
611                 }
612                 remove_old();
613
614                 check_update_queue(container);
615
616                 manager_ready = 1;
617
618                 if (update_queue == NULL)
619                         mdstat_wait_fd(container->sock, &set);
620                 else
621                         /* If an update is happening, just wait for signal */
622                         pselect(0, NULL, NULL, NULL, NULL, &set);
623         } while(1);
624 }