]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
Remove --offroot argument and default to always setting argv[0] to @
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index 427a8cf7724c686d00743b98937a76988ac18064..e75b75493c4c0ff0d80604a5335676552a077d33 100644 (file)
--- a/util.c
+++ b/util.c
@@ -32,8 +32,6 @@
 #include       <dirent.h>
 #include       <signal.h>
 
-int __offroot;
-
 /*
  * following taken from linux/blkpg.h because they aren't
  * anywhere else and it isn't safe to #include linux/ * stuff.
@@ -43,10 +41,10 @@ int __offroot;
 
 /* The argument structure */
 struct blkpg_ioctl_arg {
-        int op;
-        int flags;
-        int datalen;
-        void *data;
+       int op;
+       int flags;
+       int datalen;
+       void *data;
 };
 
 /* The subfunctions (for the op field) */
@@ -127,21 +125,21 @@ int parse_uuid(char *str, int uuid[4])
 
 int md_get_version(int fd)
 {
-    struct stat stb;
-    mdu_version_t vers;
+       struct stat stb;
+       mdu_version_t vers;
 
-    if (fstat(fd, &stb)<0)
-       return -1;
-    if ((S_IFMT&stb.st_mode) != S_IFBLK)
-       return -1;
+       if (fstat(fd, &stb)<0)
+               return -1;
+       if ((S_IFMT&stb.st_mode) != S_IFBLK)
+               return -1;
 
-    if (ioctl(fd, RAID_VERSION, &vers) == 0)
-       return  (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
-    if (errno == EACCES)
-           return -1;
-    if (major(stb.st_rdev) == MD_MAJOR)
-       return (3600);
-    return -1;
+       if (ioctl(fd, RAID_VERSION, &vers) == 0)
+               return  (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
+       if (errno == EACCES)
+               return -1;
+       if (major(stb.st_rdev) == MD_MAJOR)
+               return (3600);
+       return -1;
 }
 
 int get_linux_version()
@@ -194,7 +192,7 @@ unsigned long long parse_size(char *size)
         * followed by 'K', 'M', or 'G'.
         * Without a suffix, K is assumed.
         * Number returned is in sectors (half-K)
-        * 0 returned on error.
+        * INVALID_SECTORS returned on error.
         */
        char *c;
        long long s = strtoll(size, &c, 10);
@@ -213,11 +211,14 @@ unsigned long long parse_size(char *size)
                        c++;
                        s *= 1024 * 1024 * 2;
                        break;
+               case 's': /* sectors */
+                       c++;
+                       break;
                }
        } else
-               s = 0;
+               s = INVALID_SECTORS;
        if (*c)
-               s = 0;
+               s = INVALID_SECTORS;
        return s;
 }
 
@@ -556,8 +557,8 @@ int check_raid(int fd, char *name)
        char *level;
        struct supertype *st = guess_super(fd);
 
-       if (!st) return 0;
-       st->ignore_hw_compat = 1;
+       if (!st)
+               return 0;
        st->ss->load_super(st, fd, name);
        /* Looks like a raid array .. */
        pr_err("%s appears to be part of a raid array:\n",
@@ -836,7 +837,6 @@ int find_free_devnum(int use_partitions)
        int devnum;
        for (devnum = 127; devnum != 128;
             devnum = devnum ? devnum-1 : (1<<20)-1) {
-               char *dn;
                int _devnum;
                char nbuf[50];
 
@@ -846,11 +846,14 @@ int find_free_devnum(int use_partitions)
                sprintf(nbuf, "%s%d", use_partitions?"mdp":"md", devnum);
                if (!conf_name_is_free(nbuf))
                        continue;
-               /* make sure it is new to /dev too, at least as a
-                * non-standard */
-               dn = map_dev(dev2major(_devnum), dev2minor(_devnum), 0);
-               if (dn && ! is_standard(dn, NULL))
-                       continue;
+               if (!use_udev()) {
+                       /* make sure it is new to /dev too, at least as a
+                        * non-standard */
+                       char *dn = map_dev(dev2major(_devnum),
+                                          dev2minor(_devnum), 0);
+                       if (dn && ! is_standard(dn, NULL))
+                               continue;
+               }
                break;
        }
        if (devnum == 128)
@@ -877,18 +880,14 @@ int dev_open(char *dev, int flags)
        if (e > dev && *e == ':' && e[1] &&
            (minor = strtoul(e+1, &e, 0)) >= 0 &&
            *e == 0) {
-               char *path = map_dev(major, minor, 0);
-               if (path)
-                       fd = open(path, flags);
-               if (fd < 0) {
-                       snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
-                                (int)getpid(), major, minor);
-                       if (mknod(devname, S_IFBLK|0600, makedev(major, minor)) == 0) {
-                               fd = open(devname, flags);
-                               unlink(devname);
-                       }
+               snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
+                        (int)getpid(), major, minor);
+               if (mknod(devname, S_IFBLK|0600, makedev(major, minor)) == 0) {
+                       fd = open(devname, flags);
+                       unlink(devname);
                }
                if (fd < 0) {
+                       /* Try /tmp as /dev appear to be read-only */
                        snprintf(devname, sizeof(devname), "/tmp/.tmp.md.%d:%d:%d",
                                 (int)getpid(), major, minor);
                        if (mknod(devname, S_IFBLK|0600, makedev(major, minor)) == 0) {
@@ -1074,6 +1073,7 @@ struct supertype *dup_super(struct supertype *orig)
        st->ss = orig->ss;
        st->max_devs = orig->max_devs;
        st->minor_version = orig->minor_version;
+       st->ignore_hw_compat = orig->ignore_hw_compat;
        st->sb = NULL;
        st->info = NULL;
        return st;
@@ -1121,7 +1121,6 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
                rv = superlist[bestsuper]->load_super(st, fd, NULL);
                if (rv == 0) {
                        superlist[bestsuper]->free_super(st);
-                       st->ignore_hw_compat = 0;
                        return st;
                }
        }
@@ -1309,18 +1308,6 @@ int check_partitions(int fd, char *dname, unsigned long long freesize,
        return 0;
 }
 
-void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk)
-{
-       int d;
-
-       ioctl(mdfd, GET_ARRAY_INFO, ainf);
-       for (d = 0 ; d < MAX_DISKS ; d++) {
-               if (ioctl(mdfd, GET_DISK_INFO, disk) == 0 &&
-                   (disk->major || disk->minor))
-                       return;
-       }
-}
-
 int open_container(int fd)
 {
        /* 'fd' is a block device.  Find out if it is in use
@@ -1349,6 +1336,20 @@ int open_container(int fd)
                        continue;
                if (de->d_name[0] == '.')
                        continue;
+               /* Need to make sure it is a container and not a volume */
+               sprintf(e, "/%s/md/metadata_version", de->d_name);
+               dfd = open(path, O_RDONLY);
+               if (dfd < 0)
+                       continue;
+               n = read(dfd, buf, sizeof(buf));
+               close(dfd);
+               if (n <= 0 || (unsigned)n >= sizeof(buf))
+                       continue;
+               buf[n] = 0;
+               if (strncmp(buf, "external", 8) != 0 ||
+                   n < 10 ||
+                   buf[9] == '/')
+                       continue;
                sprintf(e, "/%s/dev", de->d_name);
                dfd = open(path, O_RDONLY);
                if (dfd < 0)
@@ -1671,15 +1672,8 @@ int start_mdmon(int devnum)
 
                for (i = 0; paths[i]; i++)
                        if (paths[i][0]) {
-                               if (__offroot) {
-                                       execl(paths[i], "mdmon", "--offroot",
-                                             devnum2devname(devnum),
-                                             NULL);
-                               } else {
-                                       execl(paths[i], "mdmon",
-                                             devnum2devname(devnum),
-                                             NULL);
-                               }
+                               execl(paths[i], "mdmon",
+                                     devnum2devname(devnum), NULL);
                        }
                exit(1);
        case -1: pr_err("cannot run mdmon. "
@@ -1834,3 +1828,24 @@ struct mdinfo *container_choose_spares(struct supertype *st,
        }
        return disks;
 }
+
+/* Checks if paths point to the same device
+ * Returns 0 if they do.
+ * Returns 1 if they don't.
+ * Returns -1 if something went wrong,
+ * e.g. paths are empty or the files
+ * they point to don't exist */
+int compare_paths (char* path1, char* path2)
+{
+       struct stat st1,st2;
+
+       if (path1 == NULL || path2 == NULL)
+               return -1;
+       if (stat(path1,&st1) != 0)
+               return -1;
+       if (stat(path2,&st2) != 0)
+               return -1;
+       if ((st1.st_ino == st2.st_ino) && (st1.st_dev == st2.st_dev))
+               return 0;
+       return 1;
+}