]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Assemble: allow arrays to be assembled read-only.
authorNeilBrown <neilb@suse.de>
Mon, 9 Jul 2012 07:14:16 +0000 (17:14 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 9 Jul 2012 07:14:16 +0000 (17:14 +1000)
The option was there, but never used.

Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
Incremental.c
ReadMe.c
mdadm.8.in
mdadm.c
mdadm.h

index c0ed917dd00234d71f3857f418e2eeaf0b698943..d765001085bca50c01c5e72f5c00df875336464a 100644 (file)
@@ -719,6 +719,7 @@ int Assemble(struct supertype *st, char *mddev,
                /* This is a member of a container.  Try starting the array. */
                int err;
                err = assemble_container_content(st, mdfd, content, runstop,
+                                                readonly,
                                                 chosen_name, verbose,
                                                 backup_file, freeze_reshape);
                close(mdfd);
@@ -1378,6 +1379,11 @@ int Assemble(struct supertype *st, char *mddev,
                                        rv = Grow_continue(mdfd, st, content,
                                                           backup_file,
                                                           freeze_reshape);
+                       } else if (readonly &&
+                                  sysfs_attribute_available(
+                                          content, NULL, "array_state")) {
+                               rv = sysfs_set_str(content, NULL,
+                                                  "array_state", "readonly");
                        } else
 #endif
                                rv = ioctl(mdfd, RUN_ARRAY, NULL);
@@ -1543,6 +1549,7 @@ int Assemble(struct supertype *st, char *mddev,
 #ifndef MDASSEMBLE
 int assemble_container_content(struct supertype *st, int mdfd,
                               struct mdinfo *content, int runstop,
+                              int readonly,
                               char *chosen_name, int verbose,
                               char *backup_file, int freeze_reshape)
 {
@@ -1556,12 +1563,18 @@ int assemble_container_content(struct supertype *st, int mdfd,
        sysfs_init(content, mdfd, 0);
 
        sra = sysfs_read(mdfd, 0, GET_VERSION);
-       if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
+       if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) {
+               if (content->array.major_version == -1 &&
+                   content->array.minor_version == -2 &&
+                   readonly &&
+                   content->text_version[0] == '/')
+                       content->text_version[0] = '-';
                if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
                        if (sra)
                                sysfs_free(sra);
                        return 1;
                }
+       }
 
        /* There are two types of reshape: container wide or sub-array specific
         * Check if metadata requests blocking container wide reshapes
@@ -1628,7 +1641,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
                case LEVEL_MULTIPATH:
                case 0:
                        err = sysfs_set_str(content, NULL, "array_state",
-                                           "active");
+                                           readonly ? "readonly" : "active");
                        break;
                default:
                        err = sysfs_set_str(content, NULL, "array_state",
index 44d5c7c22c3c82811d5814fef3f2ec7a3c08ce95..009d88c1f7921d0deeaddaf6a3f062e08fdb9f92 100644 (file)
@@ -44,7 +44,8 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
 
 static int Incremental_container(struct supertype *st, char *devname,
                                 char *homehost,
-                                int verbose, int runstop, int autof,
+                                int verbose, int runstop,
+                                int readonly, int autof,
                                 int freeze_reshape);
 
 int Incremental(char *devname, int verbose, int runstop,
@@ -139,7 +140,8 @@ int Incremental(char *devname, int verbose, int runstop,
                                pr_err("failed to get "
                                       "exclusive lock on mapfile\n");
                        rv = Incremental_container(st, devname, homehost,
-                                                  verbose, runstop, autof,
+                                                  verbose, runstop,
+                                                  0, autof,
                                                   freeze_reshape);
                        map_unlock(&map);
                        return rv;
@@ -451,7 +453,7 @@ int Incremental(char *devname, int verbose, int runstop,
                sysfs_free(sra);
                if (!rv)
                        rv = Incremental_container(st, chosen_name, homehost,
-                                                  verbose, runstop, autof,
+                                                  verbose, runstop, 0, autof,
                                                   freeze_reshape);
                map_unlock(&map);
                if (rv == 1)
@@ -1335,7 +1337,8 @@ static char *container2devname(char *devname)
 
 static int Incremental_container(struct supertype *st, char *devname,
                                 char *homehost, int verbose,
-                                int runstop, int autof, int freeze_reshape)
+                                int runstop, int readonly,
+                                int autof, int freeze_reshape)
 {
        /* Collect the contents of this container and for each
         * array, choose a device name and assemble the array.
@@ -1470,7 +1473,7 @@ static int Incremental_container(struct supertype *st, char *devname,
                        return 2;
                }
 
-               assemble_container_content(st, mdfd, ra, runstop,
+               assemble_container_content(st, mdfd, ra, runstop, readonly,
                                           chosen_name, verbose, NULL,
                                           freeze_reshape);
                close(mdfd);
index b6aac0b3d8210c0ef2ba77d13cec2c84e76a3794..35ffeaac6a1348880f2d0843834f9809ec2eef08 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -440,6 +440,7 @@ char Help_assemble[] =
 "                     : out-of-date.  This involves modifying the superblocks.\n"
 "  --update=     -U   : Update superblock: try '-A --update=?' for option list.\n"
 "  --no-degraded      : Assemble but do not start degraded arrays.\n"
+"  --readonly    -o   : Mark the array as read-only. No resync will start.\n"
 ;
 
 char Help_manage[] =
index 1a7cba7e62c681541deb20aa4acc099356c96ed4..33919bd21f3efedcd91cf10c7a478046d7289982 100644 (file)
@@ -831,6 +831,13 @@ initial resync work faster).  With
 .I mdadm
 will not try to be so clever.
 
+.TP
+.BR \-o ", " \-\-readonly
+Start the array
+.B read only
+rather than read-write as normal.  No writes will be allowed to the
+array, and no resync, recovery, or reshape will be started.
+
 .TP
 .BR \-a ", " "\-\-auto{=yes,md,mdp,part,p}{NN}"
 Instruct mdadm how to create the device file if needed, possibly allocating
diff --git a/mdadm.c b/mdadm.c
index d346240ef89a6e5ffecadf2cf02c53f3c6b0631b..e10fc38d72fff03c13e698908f351c46e82af269 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -707,6 +707,12 @@ int main(int argc, char *argv[])
                        }
                        continue;
 
+               case O(ASSEMBLE,'o'):
+               case O(MANAGE,'o'):
+               case O(CREATE,'o'):
+                       readonly = 1;
+                       continue;
+
                case O(ASSEMBLE,'U'): /* update the superblock */
                case O(MISC,'U'):
                        if (update) {
diff --git a/mdadm.h b/mdadm.h
index 3071c45be9af49bfa04e6636bde197ee50430de7..f96ac7b1855dce5ee3d5c01477f5a8c61db49d2c 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1193,6 +1193,7 @@ extern int flush_metadata_updates(struct supertype *st);
 extern void append_metadata_update(struct supertype *st, void *buf, int len);
 extern int assemble_container_content(struct supertype *st, int mdfd,
                                      struct mdinfo *content, int runstop,
+                                     int readonly,
                                      char *chosen_name, int verbose,
                                      char *backup_file, int freeze_reshape);
 extern struct mdinfo *container_choose_spares(struct supertype *st,