]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super1.c
imsm: fixup examine_brief to be more descriptive in the container only case
[thirdparty/mdadm.git] / super1.c
index f209775351ae480255b6533a5e15742b5bdfac62..056b93bb7dafdb9ba541903fec515e7bede42df6 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1,7 +1,7 @@
 /*
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *    Author: Neil Brown
- *    Email: <neilb@cse.unsw.edu.au>
- *    Paper: Neil Brown
- *           School of Computer Science and Engineering
- *           The University of New South Wales
- *           Sydney, 2052
- *           Australia
+ *    Email: <neilb@suse.de>
  */
 
 #include "mdadm.h"
@@ -141,13 +136,71 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
        return __cpu_to_le32(csum);
 }
 
+static char abuf[4096+4096];
+static int aread(int fd, void *buf, int len)
+{
+       /* aligned read.
+        * On devices with a 4K sector size, we need to read
+        * the full sector and copy relevant bits into
+        * the buffer
+        */
+       int bsize;
+       char *b;
+       int n;
+       if (ioctl(fd, BLKSSZGET, &bsize) != 0 ||
+           bsize <= len)
+               return read(fd, buf, len);
+       if (bsize > 4096)
+               return -1;
+       b = (char*)(((long)(abuf+4096))&~4095UL);
+
+       n = read(fd, b, bsize);
+       if (n <= 0)
+               return n;
+       lseek(fd, len - n, 1);
+       if (n > len)
+               n = len;
+       memcpy(buf, b, n);
+       return n;
+}
+
+static int awrite(int fd, void *buf, int len)
+{
+       /* aligned write.
+        * On devices with a 4K sector size, we need to write
+        * the full sector.  We pre-read if the sector is larger
+        * than the write.
+        * The address must be sector-aligned.
+        */
+       int bsize;
+       char *b;
+       int n;
+       if (ioctl(fd, BLKSSZGET, &bsize) != 0 ||
+           bsize <= len)
+               return write(fd, buf, len);
+       if (bsize > 4096)
+               return -1;
+       b = (char*)(((long)(abuf+4096))&~4095UL);
+
+       n = read(fd, b, bsize);
+       if (n <= 0)
+               return n;
+       lseek(fd, -n, 1);
+       memcpy(b, buf, len);
+       n = write(fd, b, bsize);
+       if (n <= 0)
+               return n;
+       lseek(fd, len - n, 1);
+       return len;
+}
+
 #ifndef MDASSEMBLE
 static void examine_super1(struct supertype *st, char *homehost)
 {
        struct mdp_superblock_1 *sb = st->sb;
        time_t atime;
        int d;
-       int faulty;
+       int role;
        int i;
        char *c;
        int l = homehost ? strlen(homehost) : 0;
@@ -298,6 +351,8 @@ static void examine_super1(struct supertype *st, char *homehost)
        default: break;
        }
        printf("\n");
+#if 0
+       /* This turns out to just be confusing */
        printf("    Array Slot : %d (", __le32_to_cpu(sb->dev_number));
        for (i= __le32_to_cpu(sb->max_dev); i> 0 ; i--)
                if (__le16_to_cpu(sb->dev_roles[i-1]) != 0xffff)
@@ -310,6 +365,18 @@ static void examine_super1(struct supertype *st, char *homehost)
                else printf("%d", role);
        }
        printf(")\n");
+#endif
+       printf("   Device Role : ");
+       d = __le32_to_cpu(sb->dev_number);
+       if (d < sb->raid_disks)
+               role = __le16_to_cpu(sb->dev_roles[d]);
+       else
+               role = 0xFFFF;
+       if (role >= 0xFFFE)
+               printf("spare\n");
+       else
+               printf("Active device %d\n", role);
+
        printf("   Array State : ");
        for (d=0; d<__le32_to_cpu(sb->raid_disks); d++) {
                int cnt = 0;
@@ -324,10 +391,11 @@ static void examine_super1(struct supertype *st, char *homehost)
                        }
                }
                if (cnt > 1) printf("?");
-               else if (cnt == 1 && me) printf("U");
-               else if (cnt == 1) printf("u");
-               else printf ("_");
+               else if (cnt == 1) printf("A");
+               else printf (".");
        }
+#if 0
+       /* This is confusing too */
        faulty = 0;
        for (i=0; i< __le32_to_cpu(sb->max_dev); i++) {
                int role = __le16_to_cpu(sb->dev_roles[i]);
@@ -335,11 +403,13 @@ static void examine_super1(struct supertype *st, char *homehost)
                        faulty++;
        }
        if (faulty) printf(" %d failed", faulty);
+#endif
+       printf(" ('A' == active, '.' == missing)");
        printf("\n");
 }
 
 
-static void brief_examine_super1(struct supertype *st)
+static void brief_examine_super1(struct supertype *st, int verbose)
 {
        struct mdp_superblock_1 *sb = st->sb;
        int i;
@@ -355,17 +425,19 @@ static void brief_examine_super1(struct supertype *st)
        else
                nm = NULL;
 
-       printf("ARRAY%s%s level=%s ",
-              nm ? " /dev/md/":"", nm,
-              c?c:"-unknown-");
+       printf("ARRAY%s%s", nm ? " /dev/md/":"", nm);
+       if (verbose && c)
+               printf(" level=%s", c);
        sb_offset = __le64_to_cpu(sb->super_offset);
        if (sb_offset <= 4)
-               printf("metadata=1.1 ");
+               printf(" metadata=1.1 ");
        else if (sb_offset <= 8)
-               printf("metadata=1.2 ");
+               printf(" metadata=1.2 ");
        else
-               printf("metadata=1.0 ");
-       printf("num-devices=%d UUID=", __le32_to_cpu(sb->raid_disks));
+               printf(" metadata=1.0 ");
+       if (verbose)
+               printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks));
+       printf("UUID=");
        for (i=0; i<16; i++) {
                if ((i&3)==0 && i != 0) printf(":");
                printf("%02x", sb->set_uuid[i]);
@@ -610,10 +682,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 
                if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
                    read(rfd, sb->device_uuid, 16) != 16) {
-                       *(__u32*)(sb->device_uuid) = random();
-                       *(__u32*)(sb->device_uuid+4) = random();
-                       *(__u32*)(sb->device_uuid+8) = random();
-                       *(__u32*)(sb->device_uuid+12) = random();
+                       __u32 r[4] = {random(), random(), random(), random()};
+                       memcpy(sb->device_uuid, r, 16);
                }
 
                sb->dev_roles[i] =
@@ -739,10 +809,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
        else {
                if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
                    read(rfd, sb->set_uuid, 16) != 16) {
-                       *(__u32*)(sb->set_uuid) = random();
-                       *(__u32*)(sb->set_uuid+4) = random();
-                       *(__u32*)(sb->set_uuid+8) = random();
-                       *(__u32*)(sb->set_uuid+12) = random();
+                       __u32 r[4] = {random(), random(), random(), random()};
+                       memcpy(sb->set_uuid, r, 16);
                }
                if (rfd >= 0) close(rfd);
        }
@@ -810,6 +878,10 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
        else
                *rp = 0xfffe;
 
+       if (dk->number >= __le32_to_cpu(sb->max_dev) &&
+           __le32_to_cpu(sb->max_dev) < 384)
+               sb->max_dev = __cpu_to_le32(dk->number+1);
+
        sb->dev_number = __cpu_to_le32(dk->number);
        sb->sb_csum = calc_sb_1_csum(sb);
 
@@ -883,7 +955,7 @@ static int store_super1(struct supertype *st, int fd)
        sbsize = sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev);
        sbsize = (sbsize+511)&(~511UL);
 
-       if (write(fd, sb, sbsize) != sbsize)
+       if (awrite(fd, sb, sbsize) != sbsize)
                return 4;
 
        if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
@@ -891,8 +963,8 @@ static int store_super1(struct supertype *st, int fd)
                        (((char*)sb)+1024);
                if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
                        locate_bitmap1(st, fd);
-                       if (write(fd, bm, ROUND_UP(sizeof(*bm),512)) !=
-                           ROUND_UP(sizeof(*bm),512))
+                       if (awrite(fd, bm, sizeof(*bm)) !=
+                           sizeof(*bm))
                            return 5;
                }
        }
@@ -942,12 +1014,12 @@ static int write_init_super1(struct supertype *st)
 
                if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
                    read(rfd, sb->device_uuid, 16) != 16) {
-                       *(__u32*)(sb->device_uuid) = random();
-                       *(__u32*)(sb->device_uuid+4) = random();
-                       *(__u32*)(sb->device_uuid+8) = random();
-                       *(__u32*)(sb->device_uuid+12) = random();
+                       __u32 r[4] = {random(), random(), random(), random()};
+                       memcpy(sb->device_uuid, r, 16);
                }
-               if (rfd >= 0) close(rfd);
+               if (rfd >= 0)
+                       close(rfd);
+
                sb->events = 0;
 
                refst =*st;
@@ -1189,7 +1261,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
                return 1;
        }
 
-       if (read(fd, super, 1024) != 1024) {
+       if (aread(fd, super, 1024) != 1024) {
                if (devname)
                        fprintf(stderr, Name ": Cannot read superblock on %s\n",
                                devname);
@@ -1234,7 +1306,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
         * should get that written out.
         */
        locate_bitmap1(st, fd);
-       if (read(fd, ((char*)super)+1024, 512)
+       if (aread(fd, ((char*)super)+1024, 512)
            != 512)
                goto no_bitmap;
 
@@ -1472,8 +1544,7 @@ static int write_bitmap1(struct supertype *st, int fd)
        int rv = 0;
 
        int towrite, n;
-       char abuf[4096+512];
-       char *buf = (char*)(((long)(abuf+512))&~511UL);
+       char *buf = (char*)(((long)(abuf+4096))&~4095UL);
 
        locate_bitmap1(st, fd);
 
@@ -1574,5 +1645,5 @@ struct superswitch super1 = {
 #else
        .swapuuid = 1,
 #endif
-       .name = "1.0",
+       .name = "1.x",
 };