summaryrefslogtreecommitdiffstats
path: root/Manage.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-08-19 17:55:15 +1000
committerNeilBrown <neilb@suse.de>2008-08-19 17:55:15 +1000
commite9dd159873cfa0da1ec3e4f173c24f330ea526f8 (patch)
treef95abf6b0736b9f7a0bd3743d037bc8f3f7b793d /Manage.c
parent3c558363a1991430e8a9e10c93ee9ee3f8996940 (diff)
downloadmdadm-e9dd159873cfa0da1ec3e4f173c24f330ea526f8.tar.gz
mdadm-e9dd159873cfa0da1ec3e4f173c24f330ea526f8.tar.xz
mdadm-e9dd159873cfa0da1ec3e4f173c24f330ea526f8.zip
Allow an externally managed array to be marked readonly
If the metadata_version is -mdXXX/whatever rather than /mdXXX/whatever then the array is readonly and should be left alone by mdmon. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Manage.c')
-rw-r--r--Manage.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/Manage.c b/Manage.c
index 084e270..56bc2c3 100644
--- a/Manage.c
+++ b/Manage.c
@@ -45,11 +45,54 @@ int Manage_ro(char *devname, int fd, int readonly)
*
*/
mdu_array_info_t array;
+ struct mdinfo *mdi;
if (md_get_version(fd) < 9000) {
fprintf(stderr, Name ": need md driver version 0.90.0 or later\n");
return 1;
}
+ /* If this is an externally-manage array, we need to modify the
+ * metadata_version so that mdmon doesn't undo our change.
+ */
+ mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
+ if (mdi &&
+ mdi->array.major_version == -1 &&
+ mdi->array.level > 0 &&
+ is_subarray(mdi->text_version)) {
+ char vers[64];
+ strcpy(vers, "external:");
+ strcat(vers, mdi->text_version);
+ if (readonly > 0) {
+ int rv;
+ /* We set readonly ourselves. */
+ vers[9] = '-';
+ sysfs_set_str(mdi, NULL, "metadata_version", vers);
+
+ close(fd);
+ rv = sysfs_set_str(mdi, NULL, "array_state", "readonly");
+
+ if (rv < 0) {
+ fprintf(stderr, Name ": failed to set readonly for %s: %s\n",
+ devname, strerror(errno));
+
+ vers[9] = mdi->text_version[0];
+ sysfs_set_str(mdi, NULL, "metadata_version", vers);
+ return 1;
+ }
+ } else {
+ char *cp;
+ /* We cannot set read/write - must signal mdmon */
+ vers[9] = '/';
+ sysfs_set_str(mdi, NULL, "metadata_version", vers);
+
+ cp = strchr(vers+10, '/');
+ if (*cp)
+ *cp = 0;
+ ping_monitor(vers+10);
+ }
+ return 0;
+ }
+
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
fprintf(stderr, Name ": %s does not appear to be active.\n",
devname);