]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
mdmon: fork and run as a daemon.
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index 553426647aede5ad69063e694640d6a052fb8328..3bf4cbe31d832eb124f5bf37315ec67f70ce912c 100644 (file)
--- a/util.c
+++ b/util.c
@@ -31,6 +31,7 @@
 #include       "md_p.h"
 #include       <sys/socket.h>
 #include       <sys/utsname.h>
+#include       <sys/wait.h>
 #include       <sys/un.h>
 #include       <ctype.h>
 #include       <dirent.h>
@@ -826,10 +827,7 @@ struct supertype *super_by_fd(int fd)
                int devnum;
                if (subarray)
                        *subarray++ = '\0';
-               if (strncmp(dev, "md_d", 4) == 0)
-                       devnum = -1-atoi(dev+4);
-               else
-                       devnum = atoi(dev+2);
+               devnum = devname2devnum(dev);
                subarray = strdup(subarray);
                if (sra)
                        sysfs_free(sra);
@@ -1013,6 +1011,17 @@ char *devnum2devname(int num)
        return strdup(name);
 }
 
+int devname2devnum(char *name)
+{
+       char *ep;
+       int num;
+       if (strncmp(name, "md_d", 4)==0)
+               num = -1-strtoul(name+4, &ep, 10);
+       else
+               num = strtoul(name+2, &ep, 10);
+       return num;
+}
+
 int fd2devnum(int fd)
 {
        struct stat stb;
@@ -1066,6 +1075,69 @@ int signal_mdmon(int devnum)
        return 0;
 }
 
+int start_mdmon(int devnum)
+{
+       int i;
+       int len;
+       pid_t pid;      
+       int status;
+       char pathbuf[1024];
+       char *paths[4] = {
+               pathbuf,
+               "/sbin/mdmon",
+               "mdmon",
+               NULL
+       };
+
+       if (env_no_mdmon())
+               return 0;
+
+       len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf));
+       if (len > 0) {
+               char *sl;
+               pathbuf[len] = 0;
+               sl = strrchr(pathbuf, '/');
+               if (sl)
+                       sl++;
+               else
+                       sl = pathbuf;
+               strcpy(sl, "mdmon");
+       } else
+               pathbuf[0] = '\0';
+
+       switch(fork()) {
+       case 0:
+               /* FIXME yuk. CLOSE_EXEC?? */
+               for (i=3; i < 100; i++)
+                       close(i);
+               for (i=0; paths[i]; i++)
+                       if (paths[i][0])
+                               execl(paths[i], "mdmon",
+                                     map_dev(dev2major(devnum),
+                                             dev2minor(devnum),
+                                             1), NULL);
+               exit(1);
+       case -1: fprintf(stderr, Name ": cannot run mdmon. "
+                        "Array remains readonly\n");
+               return -1;
+       default: /* parent - good */
+               pid = wait(&status);
+               if (pid < 0 || status != 0)
+                       return -1;
+       }
+       return 0;
+}
+
+int env_no_mdmon(void)
+{
+       char *val = getenv("MDADM_NO_MDMON");
+
+       if (val && atoi(val) == 1)
+               return 1;
+
+       return 0;
+}
+
 
 int flush_metadata_updates(struct supertype *st)
 {