]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
Disable compilation with diet-libc
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index da61a0be60048a2ea7da3aeb6d1a2dc6471f5d48..7fe835a412411c9cc88e00cad86988af85a09ef1 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>
@@ -820,7 +821,7 @@ struct supertype *super_by_fd(int fd)
                sprintf(version, "%d.%d", vers, minor);
                verstr = version;
        }
-       if (minor == -2 && verstr[0] == '/') {
+       if (minor == -2 && is_subarray(verstr)) {
                char *dev = verstr+1;
                subarray = strchr(dev, '/');
                int devnum;
@@ -1021,17 +1022,24 @@ int devname2devnum(char *name)
        return num;
 }
 
-int fd2devnum(int fd)
+int stat2devnum(struct stat *st)
 {
-       struct stat stb;
-       if (fstat(fd, &stb) == 0 &&
-           (S_IFMT&stb.st_mode)==S_IFBLK) {
-               if (major(stb.st_rdev) == MD_MAJOR)
-                       return minor(stb.st_rdev);
+       if ((S_IFMT & st->st_mode) == S_IFBLK) {
+               if (major(st->st_rdev) == MD_MAJOR)
+                       return minor(st->st_rdev);
                else
-                       return -1- (minor(stb.st_rdev)>>6);
+                       return -1- (minor(st->st_rdev)>>6);
        }
        return -1;
+
+}
+
+int fd2devnum(int fd)
+{
+       struct stat stb;
+       if (fstat(fd, &stb) == 0)
+               return stat2devnum(&stb);
+       return -1;
 }
 
 int mdmon_running(int devnum)
@@ -1077,24 +1085,52 @@ int signal_mdmon(int devnum)
 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);
-               execl("./mdmon", "mdmon",
-                     map_dev(dev2major(devnum),
-                             dev2minor(devnum),
-                             1), NULL);
+               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 */
+       default: /* parent - good */
+               pid = wait(&status);
+               if (pid < 0 || status != 0)
+                       return -1;
        }
        return 0;
 }