]> git.neil.brown.name Git - mdadm.git/blob - mdmon.c
Release mdadm-4.0
[mdadm.git] / mdmon.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 /*
22  * md array manager.
23  * When md arrays have user-space managed metadata, this is the program
24  * that does the managing.
25  *
26  * Given one argument: the name of the array (e.g. /dev/md0) that is
27  * the container.
28  * We fork off a helper that runs high priority and mlocked.  It responds to
29  * device failures and other events that might stop writeout, or that are
30  * trivial to deal with.
31  * The main thread then watches for new arrays being created in the container
32  * and starts monitoring them too ... along with a few other tasks.
33  *
34  * The main thread communicates with the priority thread by writing over
35  * a pipe.
36  * Separate programs can communicate with the main thread via Unix-domain
37  * socket.
38  * The two threads share address space and open file table.
39  *
40  */
41
42 #ifndef _GNU_SOURCE
43 #define _GNU_SOURCE
44 #endif
45
46 #include        <unistd.h>
47 #include        <stdlib.h>
48 #include        <sys/types.h>
49 #include        <sys/stat.h>
50 #include        <sys/socket.h>
51 #include        <sys/un.h>
52 #include        <sys/mman.h>
53 #include        <sys/syscall.h>
54 #include        <sys/wait.h>
55 #include        <stdio.h>
56 #include        <errno.h>
57 #include        <string.h>
58 #include        <fcntl.h>
59 #include        <signal.h>
60 #include        <dirent.h>
61 #ifdef USE_PTHREADS
62 #include        <pthread.h>
63 #else
64 #include        <sched.h>
65 #endif
66
67 #include        "mdadm.h"
68 #include        "mdmon.h"
69
70 char const Name[] = "mdmon";
71
72 struct active_array *discard_this;
73 struct active_array *pending_discard;
74
75 int mon_tid, mgr_tid;
76
77 int sigterm;
78
79 #ifdef USE_PTHREADS
80 static void *run_child(void *v)
81 {
82         struct supertype *c = v;
83
84         mon_tid = syscall(SYS_gettid);
85         do_monitor(c);
86         return 0;
87 }
88
89 static int clone_monitor(struct supertype *container)
90 {
91         pthread_attr_t attr;
92         pthread_t thread;
93         int rc;
94
95         mon_tid = -1;
96         pthread_attr_init(&attr);
97         pthread_attr_setstacksize(&attr, 4096);
98         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
99         rc = pthread_create(&thread, &attr, run_child, container);
100         if (rc)
101                 return rc;
102         while (mon_tid == -1)
103                 usleep(10);
104         pthread_attr_destroy(&attr);
105
106         mgr_tid = syscall(SYS_gettid);
107
108         return mon_tid;
109 }
110 #else /* USE_PTHREADS */
111 static int run_child(void *v)
112 {
113         struct supertype *c = v;
114
115         do_monitor(c);
116         return 0;
117 }
118
119 #ifdef __ia64__
120 int __clone2(int (*fn)(void *),
121             void *child_stack_base, size_t stack_size,
122             int flags, void *arg, ...
123          /* pid_t *pid, struct user_desc *tls, pid_t *ctid */ );
124 #endif
125 static int clone_monitor(struct supertype *container)
126 {
127         static char stack[4096];
128
129 #ifdef __ia64__
130         mon_tid = __clone2(run_child, stack, sizeof(stack),
131                    CLONE_FS|CLONE_FILES|CLONE_VM|CLONE_SIGHAND|CLONE_THREAD,
132                    container);
133 #else
134         mon_tid = clone(run_child, stack+4096-64,
135                    CLONE_FS|CLONE_FILES|CLONE_VM|CLONE_SIGHAND|CLONE_THREAD,
136                    container);
137 #endif
138
139         mgr_tid = syscall(SYS_gettid);
140
141         return mon_tid;
142 }
143 #endif /* USE_PTHREADS */
144
145 static int make_pidfile(char *devname)
146 {
147         char path[100];
148         char pid[10];
149         int fd;
150         int n;
151
152         if (mkdir(MDMON_DIR, 0755) < 0 &&
153             errno != EEXIST)
154                 return -errno;
155         sprintf(path, "%s/%s.pid", MDMON_DIR, devname);
156
157         fd = open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
158         if (fd < 0)
159                 return -errno;
160         sprintf(pid, "%d\n", getpid());
161         n = write(fd, pid, strlen(pid));
162         close(fd);
163         if (n < 0)
164                 return -errno;
165         return 0;
166 }
167
168 static void try_kill_monitor(pid_t pid, char *devname, int sock)
169 {
170         char buf[100];
171         int fd;
172         int n;
173         long fl;
174
175         /* first rule of survival... don't off yourself */
176         if (pid == getpid())
177                 return;
178
179         /* kill this process if it is mdmon */
180         sprintf(buf, "/proc/%lu/cmdline", (unsigned long) pid);
181         fd = open(buf, O_RDONLY);
182         if (fd < 0)
183                 return;
184
185         n = read(fd, buf, sizeof(buf)-1);
186         buf[sizeof(buf)-1] = 0;
187         close(fd);
188
189         if (n < 0 || !(strstr(buf, "mdmon") ||
190                        strstr(buf, "@dmon")))
191                 return;
192
193         kill(pid, SIGTERM);
194
195         if (sock < 0)
196                 return;
197
198         /* Wait for monitor to exit by reading from the socket, after
199          * clearing the non-blocking flag */
200         fl = fcntl(sock, F_GETFL, 0);
201         fl &= ~O_NONBLOCK;
202         fcntl(sock, F_SETFL, fl);
203         n = read(sock, buf, 100);
204         /* Ignore result, it is just the wait that
205          * matters
206          */
207 }
208
209 void remove_pidfile(char *devname)
210 {
211         char buf[100];
212
213         sprintf(buf, "%s/%s.pid", MDMON_DIR, devname);
214         unlink(buf);
215         sprintf(buf, "%s/%s.sock", MDMON_DIR, devname);
216         unlink(buf);
217 }
218
219 static int make_control_sock(char *devname)
220 {
221         char path[100];
222         int sfd;
223         long fl;
224         struct sockaddr_un addr;
225
226         if (sigterm)
227                 return -1;
228
229         sprintf(path, "%s/%s.sock", MDMON_DIR, devname);
230         unlink(path);
231         sfd = socket(PF_LOCAL, SOCK_STREAM, 0);
232         if (sfd < 0)
233                 return -1;
234
235         addr.sun_family = PF_LOCAL;
236         strcpy(addr.sun_path, path);
237         umask(077); /* ensure no world write access */
238         if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
239                 close(sfd);
240                 return -1;
241         }
242         listen(sfd, 10);
243         fl = fcntl(sfd, F_GETFL, 0);
244         fl |= O_NONBLOCK;
245         fcntl(sfd, F_SETFL, fl);
246         return sfd;
247 }
248
249 static void term(int sig)
250 {
251         sigterm = 1;
252 }
253
254 static void wake_me(int sig)
255 {
256
257 }
258
259 /* if we are debugging and starting mdmon by hand then don't fork */
260 static int do_fork(void)
261 {
262         #ifdef DEBUG
263         if (check_env("MDADM_NO_MDMON"))
264                 return 0;
265         #endif
266
267         return 1;
268 }
269
270 void usage(void)
271 {
272         fprintf(stderr,
273 "Usage: mdmon [options] CONTAINER\n"
274 "\n"
275 "Options are:\n"
276 "  --help        -h   : This message\n"
277 "  --all         -a   : All devices\n"
278 "  --foreground  -F   : Run in foreground (do not fork)\n"
279 "  --takeover    -t   : Takeover container\n"
280 );
281         exit(2);
282 }
283
284 static int mdmon(char *devnm, int must_fork, int takeover);
285
286 int main(int argc, char *argv[])
287 {
288         char *container_name = NULL;
289         char *devnm = NULL;
290         int status = 0;
291         int opt;
292         int all = 0;
293         int takeover = 0;
294         int dofork = 1;
295         static struct option options[] = {
296                 {"all", 0, NULL, 'a'},
297                 {"takeover", 0, NULL, 't'},
298                 {"help", 0, NULL, 'h'},
299                 {"offroot", 0, NULL, OffRootOpt},
300                 {"foreground", 0, NULL, 'F'},
301                 {NULL, 0, NULL, 0}
302         };
303
304         if (in_initrd()) {
305                 /*
306                  * set first char of argv[0] to @. This is used by
307                  * systemd to signal that the task was launched from
308                  * initrd/initramfs and should be preserved during shutdown
309                  */
310                 argv[0][0] = '@';
311         }
312
313         while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) {
314                 switch (opt) {
315                 case 'a':
316                         container_name = argv[optind-1];
317                         all = 1;
318                         break;
319                 case 't':
320                         takeover = 1;
321                         break;
322                 case 'F':
323                         dofork = 0;
324                         break;
325                 case OffRootOpt:
326                         argv[0][0] = '@';
327                         break;
328                 case 'h':
329                 default:
330                         usage();
331                         break;
332                 }
333         }
334
335         if (all == 0 && container_name == NULL) {
336                 if (argv[optind])
337                         container_name = argv[optind];
338         }
339
340         if (container_name == NULL)
341                 usage();
342
343         if (argc - optind > 1)
344                 usage();
345
346         if (strcmp(container_name, "/proc/mdstat") == 0)
347                 all = 1;
348
349         if (all) {
350                 struct mdstat_ent *mdstat, *e;
351                 int container_len = strlen(container_name);
352
353                 /* launch an mdmon instance for each container found */
354                 mdstat = mdstat_read(0, 0);
355                 for (e = mdstat; e; e = e->next) {
356                         if (e->metadata_version &&
357                             strncmp(e->metadata_version, "external:", 9) == 0 &&
358                             !is_subarray(&e->metadata_version[9])) {
359                                 /* update cmdline so this mdmon instance can be
360                                  * distinguished from others in a call to ps(1)
361                                  */
362                                 if (strlen(e->devnm) <= (unsigned)container_len) {
363                                         memset(container_name, 0, container_len);
364                                         sprintf(container_name, "%s", e->devnm);
365                                 }
366                                 status |= mdmon(e->devnm, 1, takeover);
367                         }
368                 }
369                 free_mdstat(mdstat);
370
371                 return status;
372         } else if (strncmp(container_name, "md", 2) == 0) {
373                 int id = devnm2devid(container_name);
374                 if (id)
375                         devnm = container_name;
376         } else {
377                 struct stat st;
378
379                 if (stat(container_name, &st) == 0)
380                         devnm = xstrdup(stat2devnm(&st));
381         }
382
383         if (!devnm) {
384                 pr_err("%s is not a valid md device name\n",
385                         container_name);
386                 exit(1);
387         }
388         return mdmon(devnm, dofork && do_fork(), takeover);
389 }
390
391 static int mdmon(char *devnm, int must_fork, int takeover)
392 {
393         int mdfd;
394         struct mdinfo *mdi, *di;
395         struct supertype *container;
396         sigset_t set;
397         struct sigaction act;
398         int pfd[2];
399         int status;
400         int ignore;
401         pid_t victim = -1;
402         int victim_sock = -1;
403
404         dprintf("starting mdmon for %s\n", devnm);
405
406         mdfd = open_dev(devnm);
407         if (mdfd < 0) {
408                 pr_err("%s: %s\n", devnm, strerror(errno));
409                 return 1;
410         }
411         if (md_get_version(mdfd) < 0) {
412                 pr_err("%s: Not an md device\n", devnm);
413                 return 1;
414         }
415
416         /* Fork, and have the child tell us when they are ready */
417         if (must_fork) {
418                 if (pipe(pfd) != 0) {
419                         pr_err("failed to create pipe\n");
420                         return 1;
421                 }
422                 switch(fork()) {
423                 case -1:
424                         pr_err("failed to fork: %s\n", strerror(errno));
425                         return 1;
426                 case 0: /* child */
427                         close(pfd[0]);
428                         break;
429                 default: /* parent */
430                         close(pfd[1]);
431                         if (read(pfd[0], &status, sizeof(status)) != sizeof(status)) {
432                                 wait(&status);
433                                 status = WEXITSTATUS(status);
434                         }
435                         close(pfd[0]);
436                         return status;
437                 }
438         } else
439                 pfd[0] = pfd[1] = -1;
440
441         container = xcalloc(1, sizeof(*container));
442         strcpy(container->devnm, devnm);
443         container->arrays = NULL;
444         container->sock = -1;
445
446         mdi = sysfs_read(mdfd, container->devnm, GET_VERSION|GET_LEVEL|GET_DEVS);
447
448         if (!mdi) {
449                 pr_err("failed to load sysfs info for %s\n", container->devnm);
450                 exit(3);
451         }
452         if (mdi->array.level != UnSet) {
453                 pr_err("%s is not a container - cannot monitor\n", devnm);
454                 exit(3);
455         }
456         if (mdi->array.major_version != -1 ||
457             mdi->array.minor_version != -2) {
458                 pr_err("%s does not use external metadata - cannot monitor\n",
459                         devnm);
460                 exit(3);
461         }
462
463         container->ss = version_to_superswitch(mdi->text_version);
464         if (container->ss == NULL) {
465                 pr_err("%s uses unsupported metadata: %s\n",
466                         devnm, mdi->text_version);
467                 exit(3);
468         }
469
470         container->devs = NULL;
471         for (di = mdi->devs; di; di = di->next) {
472                 struct mdinfo *cd = xmalloc(sizeof(*cd));
473                 *cd = *di;
474                 cd->next = container->devs;
475                 container->devs = cd;
476         }
477         sysfs_free(mdi);
478
479         /* SIGUSR is sent between parent and child.  So both block it
480          * and enable it only with pselect.
481          */
482         sigemptyset(&set);
483         sigaddset(&set, SIGUSR1);
484         sigaddset(&set, SIGTERM);
485         sigprocmask(SIG_BLOCK, &set, NULL);
486         act.sa_handler = wake_me;
487         act.sa_flags = 0;
488         sigaction(SIGUSR1, &act, NULL);
489         act.sa_handler = term;
490         sigaction(SIGTERM, &act, NULL);
491         act.sa_handler = SIG_IGN;
492         sigaction(SIGPIPE, &act, NULL);
493
494         victim = mdmon_pid(container->devnm);
495         if (victim >= 0)
496                 victim_sock = connect_monitor(container->devnm);
497
498         ignore = chdir("/");
499         if (!takeover && victim > 0 && victim_sock >= 0) {
500                 if (fping_monitor(victim_sock) == 0) {
501                         pr_err("%s already managed\n", container->devnm);
502                         exit(3);
503                 }
504                 close(victim_sock);
505                 victim_sock = -1;
506         }
507         if (container->ss->load_container(container, mdfd, devnm)) {
508                 pr_err("Cannot load metadata for %s\n", devnm);
509                 exit(3);
510         }
511         close(mdfd);
512
513         /* Ok, this is close enough.  We can say goodbye to our parent now.
514          */
515         if (victim > 0)
516                 remove_pidfile(devnm);
517         if (make_pidfile(devnm) < 0) {
518                 exit(3);
519         }
520         container->sock = make_control_sock(devnm);
521
522         status = 0;
523         if (pfd[1] >= 0) {
524                 if (write(pfd[1], &status, sizeof(status)) < 0)
525                         pr_err("failed to notify our parent: %d\n",
526                                getppid());
527                 close(pfd[1]);
528         }
529
530         mlockall(MCL_CURRENT | MCL_FUTURE);
531
532         if (clone_monitor(container) < 0) {
533                 pr_err("failed to start monitor process: %s\n",
534                         strerror(errno));
535                 exit(2);
536         }
537
538         if (victim > 0) {
539                 try_kill_monitor(victim, container->devnm, victim_sock);
540                 if (victim_sock >= 0)
541                         close(victim_sock);
542         }
543
544         setsid();
545         close(0);
546         open("/dev/null", O_RDWR);
547         close(1);
548         ignore = dup(0);
549 #ifndef DEBUG
550         close(2);
551         ignore = dup(0);
552 #endif
553
554         /* This silliness is to stop the compiler complaining
555          * that we ignore 'ignore'
556          */
557         if (ignore)
558                 ignore++;
559
560         do_manager(container);
561
562         exit(0);
563 }
564
565 /* Some stub functions so super-* can link with us */
566 int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
567                   struct supertype *st, unsigned long blocks,
568                   int *fds, unsigned long long *offsets,
569                   int dests, int *destfd, unsigned long long *destoffsets)
570 {
571         return 0;
572 }
573
574 int restore_stripes(int *dest, unsigned long long *offsets,
575                     int raid_disks, int chunk_size, int level, int layout,
576                     int source, unsigned long long read_offset,
577                     unsigned long long start, unsigned long long length,
578                     char *src_buf)
579 {
580         return 1;
581 }
582
583 void abort_reshape(struct mdinfo *sra)
584 {
585         return;
586 }
587
588 int save_stripes(int *source, unsigned long long *offsets,
589                  int raid_disks, int chunk_size, int level, int layout,
590                  int nwrites, int *dest,
591                  unsigned long long start, unsigned long long length,
592                  char *buf)
593 {
594         return 0;
595 }
596
597 struct superswitch super0 = {
598         .name = "0.90",
599 };
600 struct superswitch super1 = {
601         .name = "1.x",
602 };