]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - bitmap.c
Generic support for --consistency-policy and PPL
[thirdparty/mdadm.git] / bitmap.c
index bbe9baec6baf813a469095e575460eac65c042c9..ccedfd34715cf24e49544bfb7326f1c819464c67 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -32,6 +32,8 @@ static inline void sb_le_to_cpu(bitmap_super_t *sb)
        sb->daemon_sleep = __le32_to_cpu(sb->daemon_sleep);
        sb->sync_size = __le64_to_cpu(sb->sync_size);
        sb->write_behind = __le32_to_cpu(sb->write_behind);
+       sb->nodes = __le32_to_cpu(sb->nodes);
+       sb->sectors_reserved = __le32_to_cpu(sb->sectors_reserved);
 }
 
 static inline void sb_cpu_to_le(bitmap_super_t *sb)
@@ -45,13 +47,13 @@ mapping_t bitmap_states[] = {
        { NULL, -1 }
 };
 
-const char *bitmap_state(int state_num)
+static const char *bitmap_state(int state_num)
 {
        char *state = map_num(bitmap_states, state_num);
        return state ? state : "Unknown";
 }
 
-const char *human_chunksize(unsigned long bytes)
+static const char *human_chunksize(unsigned long bytes)
 {
        static char buf[16];
        char *suffixes[] = { "B", "KB", "MB", "GB", "TB", NULL };
@@ -93,7 +95,7 @@ static inline int count_dirty_bits_byte(char byte, int num_bits)
        return num;
 }
 
-int count_dirty_bits(char *buf, int num_bits)
+static int count_dirty_bits(char *buf, int num_bits)
 {
        int i, num = 0;
 
@@ -106,22 +108,7 @@ int count_dirty_bits(char *buf, int num_bits)
        return num;
 }
 
-/* calculate the size of the bitmap given the array size and bitmap chunksize */
-unsigned long long bitmap_bits(unsigned long long array_size,
-                               unsigned long chunksize)
-{
-       return (array_size * 512 + chunksize - 1) / chunksize;
-}
-
-unsigned long bitmap_sectors(struct bitmap_super_s *bsb)
-{
-       unsigned long long bits = bitmap_bits(__le64_to_cpu(bsb->sync_size),
-                                             __le32_to_cpu(bsb->chunksize));
-       int bits_per_sector = 8*512;
-       return (bits + bits_per_sector - 1) / bits_per_sector;
-}
-
-bitmap_info_t *bitmap_fd_read(int fd, int brief)
+static bitmap_info_t *bitmap_fd_read(int fd, int brief)
 {
        /* Note: fd might be open O_DIRECT, so we must be
         * careful to align reads properly
@@ -192,50 +179,54 @@ out:
        return info;
 }
 
-int bitmap_file_open(char *filename, struct supertype **stp)
+static int
+bitmap_file_open(char *filename, struct supertype **stp, int node_num)
 {
        int fd;
        struct stat stb;
        struct supertype *st = *stp;
 
-       if (stat(filename, &stb) < 0) {
-               pr_err("failed to find file %s: %s\n",
-                       filename, strerror(errno));
+       fd = open(filename, O_RDONLY|O_DIRECT);
+       if (fd < 0) {
+               pr_err("failed to open bitmap file %s: %s\n",
+                      filename, strerror(errno));
                return -1;
        }
-       if ((S_IFMT & stb.st_mode) == S_IFBLK) {
-               fd = open(filename, O_RDONLY|O_DIRECT);
-               if (fd < 0) {
-                       pr_err("failed to open bitmap file %s: %s\n",
-                               filename, strerror(errno));
-                       return -1;
-               }
+
+       if (fstat(fd, &stb) < 0) {
+               pr_err("failed to determine bitmap file/device type: %s\n",
+                       strerror(errno));
+               close(fd);
+               return -1;
+       }
+
+       if ((stb.st_mode & S_IFMT) == S_IFBLK) {
                /* block device, so we are probably after an internal bitmap */
-               if (!st) st = guess_super(fd);
+               if (!st)
+                       st = guess_super(fd);
                if (!st) {
                        /* just look at device... */
                        lseek(fd, 0, 0);
                } else if (!st->ss->locate_bitmap) {
                        pr_err("No bitmap possible with %s metadata\n",
                                st->ss->name);
+                       close(fd);
                        return -1;
-               } else
-                       st->ss->locate_bitmap(st, fd);
+               } else {
+                       if (st->ss->locate_bitmap(st, fd, node_num)) {
+                               pr_err("%s doesn't have bitmap\n", filename);
+                               close(fd);
+                               fd = -1;
+                       }
+               }
 
                *stp = st;
-       } else {
-               fd = open(filename, O_RDONLY|O_DIRECT);
-               if (fd < 0) {
-                       pr_err("failed to open bitmap file %s: %s\n",
-                               filename, strerror(errno));
-                       return -1;
-               }
        }
 
        return fd;
 }
 
-__u32 swapl(__u32 l)
+static __u32 swapl(__u32 l)
 {
        char *c = (char*)&l;
        char t= c[0];
@@ -258,10 +249,10 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        int rv = 1;
        char buf[64];
        int swap;
-       int fd;
+       int fd, i;
        __u32 uuid32[4];
 
-       fd = bitmap_file_open(filename, &st);
+       fd = bitmap_file_open(filename, &st, 0);
        if (fd < 0)
                return rv;
 
@@ -285,7 +276,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        }
        printf("         Version : %d\n", sb->version);
        if (sb->version < BITMAP_MAJOR_LO ||
-           sb->version > BITMAP_MAJOR_HI) {
+           sb->version > BITMAP_MAJOR_CLUSTERED) {
                pr_err("unknown bitmap version %d, either the bitmap file\n",
                       sb->version);
                pr_err("is corrupted or you need to upgrade your tools\n");
@@ -315,9 +306,13 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
                       uuid32[2],
                       uuid32[3]);
 
-       printf("          Events : %llu\n", (unsigned long long)sb->events);
-       printf("  Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
-       printf("           State : %s\n", bitmap_state(sb->state));
+       if (sb->nodes == 0) {
+               printf("          Events : %llu\n", (unsigned long long)sb->events);
+               printf("  Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
+               printf("           State : %s\n", bitmap_state(sb->state));
+
+       }
+
        printf("       Chunksize : %s\n", human_chunksize(sb->chunksize));
        printf("          Daemon : %ds flush period\n", sb->daemon_sleep);
        if (sb->write_behind)
@@ -327,11 +322,50 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        printf("      Write Mode : %s\n", buf);
        printf("       Sync Size : %llu%s\n", (unsigned long long)sb->sync_size/2,
                                        human_size(sb->sync_size * 512));
-       if (brief)
-               goto free_info;
-       printf("          Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
-                       info->total_bits, info->dirty_bits,
-                       100.0 * info->dirty_bits / (info->total_bits?:1));
+
+       if (sb->nodes == 0) {
+               if (brief)
+                       goto free_info;
+               printf("          Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
+                      info->total_bits, info->dirty_bits,
+                      100.0 * info->dirty_bits / (info->total_bits?:1));
+       } else {
+               printf("   Cluster nodes : %d\n", sb->nodes);
+               printf("    Cluster name : %-64s\n", sb->cluster_name);
+               for (i = 0; i < (int)sb->nodes; i++) {
+                       st = NULL;
+                       free(info);
+                       fd = bitmap_file_open(filename, &st, i);
+                       if (fd < 0) {
+                               printf("   Unable to open bitmap file on node: %i\n", i);
+
+                               continue;
+                       }
+                       info = bitmap_fd_read(fd, brief);
+                       if (!info) {
+                               close(fd);
+                               printf("   Unable to read bitmap on node: %i\n", i);
+                               continue;
+                       }
+                       sb = &info->sb;
+                       if (sb->magic != BITMAP_MAGIC)
+                               pr_err("invalid bitmap magic 0x%x, the bitmap file appears to be corrupted\n", sb->magic);
+
+                       printf("       Node Slot : %d\n", i);
+                       printf("          Events : %llu\n",
+                              (unsigned long long)sb->events);
+                       printf("  Events Cleared : %llu\n",
+                              (unsigned long long)sb->events_cleared);
+                       printf("           State : %s\n", bitmap_state(sb->state));
+                       if (brief)
+                               continue;
+                       printf("          Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
+                              info->total_bits, info->dirty_bits,
+                              100.0 * info->dirty_bits / (info->total_bits?:1));
+                        close(fd);
+               }
+       }
+
 free_info:
        free(info);
        return rv;