]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
Fix RAID metadata check
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index f1b0b952ab535c25f77236c8e9d020d0802c8091..a238a2107b968443ad530506340cfed7e21f8ef3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -24,7 +24,6 @@
 
 #include       "mdadm.h"
 #include       "md_p.h"
-#include       <sys/poll.h>
 #include       <sys/socket.h>
 #include       <sys/utsname.h>
 #include       <sys/wait.h>
@@ -32,6 +31,7 @@
 #include       <sys/resource.h>
 #include       <sys/vfs.h>
 #include       <linux/magic.h>
+#include       <poll.h>
 #include       <ctype.h>
 #include       <dirent.h>
 #include       <signal.h>
@@ -82,8 +82,15 @@ struct blkpg_partition {
    aren't permitted). */
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
 
-static struct dlm_hooks *dlm_hooks = NULL;
 static int is_dlm_hooks_ready = 0;
+
+int dlm_funs_ready(void)
+{
+       return is_dlm_hooks_ready ? 1 : 0;
+}
+
+#ifndef MDASSEMBLE
+static struct dlm_hooks *dlm_hooks = NULL;
 struct dlm_lock_resource *dlm_lock_res = NULL;
 static int ast_called = 0;
 
@@ -92,11 +99,6 @@ struct dlm_lock_resource {
        struct dlm_lksb lksb;
 };
 
-int dlm_funs_ready(void)
-{
-       return is_dlm_hooks_ready ? 1 : 0;
-}
-
 /* Using poll(2) to wait for and dispatch ASTs */
 static int poll_for_ast(dlm_lshandle_t ls)
 {
@@ -142,36 +144,24 @@ int cluster_get_dlmlock(int *lockid)
        dlm_lock_res->ls = dlm_hooks->create_lockspace(cluster_name, O_RDWR);
        if (!dlm_lock_res->ls) {
                pr_err("%s failed to create lockspace\n", cluster_name);
-                goto out;
+               return -ENOMEM;
        }
 
-       /* Conversions need the lockid in the LKSB */
-       if (flags & LKF_CONVERT)
-               dlm_lock_res->lksb.sb_lkid = *lockid;
-
        snprintf(str, 64, "bitmap%s", cluster_name);
-       /* if flags with LKF_CONVERT causes below return ENOENT which means
-        * "No such file or directory" */
        ret = dlm_hooks->ls_lock(dlm_lock_res->ls, LKM_PWMODE, &dlm_lock_res->lksb,
                          flags, str, strlen(str), 0, dlm_ast,
                          dlm_lock_res, NULL, NULL);
        if (ret) {
                pr_err("error %d when get PW mode on lock %s\n", errno, str);
-                goto out;
+               dlm_hooks->release_lockspace(cluster_name, dlm_lock_res->ls, 1);
+               return ret;
        }
 
        /* Wait for it to complete */
        poll_for_ast(dlm_lock_res->ls);
        *lockid = dlm_lock_res->lksb.sb_lkid;
 
-       errno = dlm_lock_res->lksb.sb_status;
-       if (errno) {
-               pr_err("error %d happened in ast with lock %s\n", errno, str);
-               goto out;
-       }
-
-out:
-       return ret;
+       return dlm_lock_res->lksb.sb_status;
 }
 
 int cluster_release_dlmlock(int lockid)
@@ -181,8 +171,6 @@ int cluster_release_dlmlock(int lockid)
        if (!cluster_name)
                return -1;
 
-       /* if flags with LKF_CONVERT causes below return EINVAL which means
-        * "Invalid argument" */
        ret = dlm_hooks->ls_unlock(dlm_lock_res->ls, lockid, 0,
                                     &dlm_lock_res->lksb, dlm_lock_res);
        if (ret) {
@@ -212,6 +200,16 @@ int cluster_release_dlmlock(int lockid)
 out:
        return ret;
 }
+#else
+int cluster_get_dlmlock(int *lockid)
+{
+       return -1;
+}
+int cluster_release_dlmlock(int lockid)
+{
+       return -1;
+}
+#endif
 
 /*
  * Parse a 128 bit uuid in 4 integers
@@ -712,17 +710,22 @@ int check_raid(int fd, char *name)
 
        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",
-               name);
-       st->ss->getinfo_super(st, &info, NULL);
-       st->ss->free_super(st);
-       crtime = info.array.ctime;
-       level = map_num(pers, info.array.level);
-       if (!level) level = "-unknown-";
-       cont_err("level=%s devices=%d ctime=%s",
-                level, info.array.raid_disks, ctime(&crtime));
+       if (st->ss->add_to_super != NULL) {
+               st->ss->load_super(st, fd, name);
+               /* Looks like a raid array .. */
+               pr_err("%s appears to be part of a raid array:\n", name);
+               st->ss->getinfo_super(st, &info, NULL);
+               st->ss->free_super(st);
+               crtime = info.array.ctime;
+               level = map_num(pers, info.array.level);
+               if (!level)
+                       level = "-unknown-";
+               cont_err("level=%s devices=%d ctime=%s",
+                       level, info.array.raid_disks, ctime(&crtime));
+       } else {
+               /* Looks like GPT or MBR */
+               pr_err("partition table exists on %s\n", name);
+       }
        return 1;
 }
 
@@ -930,7 +933,7 @@ int get_data_disks(int level, int layout, int raid_disks)
        return data_disks;
 }
 
-int devnm2devid(char *devnm)
+dev_t devnm2devid(char *devnm)
 {
        /* First look in /sys/block/$DEVNM/dev for %d:%d
         * If that fails, try parsing out a number
@@ -1041,7 +1044,8 @@ int dev_open(char *dev, int flags)
        int major;
        int minor;
 
-       if (!dev) return -1;
+       if (!dev)
+               return -1;
        flags |= O_DIRECT;
 
        if (get_maj_min(dev, &major, &minor)) {
@@ -1067,7 +1071,7 @@ int dev_open(char *dev, int flags)
 
 int open_dev_flags(char *devnm, int flags)
 {
-       int devid;
+       dev_t devid;
        char buf[20];
 
        devid = devnm2devid(devnm);
@@ -1085,7 +1089,7 @@ int open_dev_excl(char *devnm)
        char buf[20];
        int i;
        int flags = O_RDWR;
-       int devid = devnm2devid(devnm);
+       dev_t devid = devnm2devid(devnm);
        long delay = 1000;
 
        sprintf(buf, "%d:%d", major(devid), minor(devid));
@@ -1193,8 +1197,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
                        subarray = xstrdup(subarray);
                }
                strcpy(container, dev);
-               if (sra)
-                       sysfs_free(sra);
+               sysfs_free(sra);
                sra = sysfs_read(-1, container, GET_VERSION);
                if (sra && sra->text_version[0])
                        verstr = sra->text_version;
@@ -1205,8 +1208,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
        for (i = 0; st == NULL && superlist[i] ; i++)
                st = superlist[i]->match_metadata_desc(verstr);
 
-       if (sra)
-               sysfs_free(sra);
+       sysfs_free(sra);
        if (st) {
                st->sb = NULL;
                if (subarrayp)
@@ -1261,7 +1263,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
         */
        struct superswitch  *ss;
        struct supertype *st;
-       time_t besttime = 0;
+       unsigned int besttime = 0;
        int bestsuper = -1;
        int i;
 
@@ -1939,6 +1941,27 @@ __u32 random32(void)
        return rv;
 }
 
+void random_uuid(__u8 *buf)
+{
+       int fd, i, len;
+       __u32 r[4];
+
+       fd = open("/dev/urandom", O_RDONLY);
+       if (fd < 0)
+               goto use_random;
+       len = read(fd, buf, 16);
+       close(fd);
+       if (len != 16)
+               goto use_random;
+
+       return;
+
+use_random:
+       for (i = 0; i < 4; i++)
+               r[i] = random();
+       memcpy(buf, r, 16);
+}
+
 #ifndef MDASSEMBLE
 int flush_metadata_updates(struct supertype *st)
 {
@@ -2121,10 +2144,10 @@ void reopen_mddev(int mdfd)
                dup2(fd, mdfd);
 }
 
+#ifndef MDASSEMBLE
 static struct cmap_hooks *cmap_hooks = NULL;
 static int is_cmap_hooks_ready = 0;
 
-#ifndef MDASSEMBLE
 void set_cmap_hooks(void)
 {
        cmap_hooks = xmalloc(sizeof(struct cmap_hooks));