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>
This commit is contained in:
parent
3c558363a1
commit
e9dd159873
43
Manage.c
43
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);
|
||||
|
|
|
@ -460,6 +460,7 @@ static void manage_new(struct mdstat_ent *mdstat,
|
|||
new->action_fd = sysfs_open(new->devnum, NULL, "sync_action");
|
||||
new->info.state_fd = sysfs_open(new->devnum, NULL, "array_state");
|
||||
new->resync_start_fd = sysfs_open(new->devnum, NULL, "resync_start");
|
||||
new->metadata_fd = sysfs_open(new->devnum, NULL, "metadata_version");
|
||||
get_resync_start(new);
|
||||
dprintf("%s: inst: %d action: %d state: %d\n", __func__, atoi(inst),
|
||||
new->action_fd, new->info.state_fd);
|
||||
|
|
9
mdadm.h
9
mdadm.h
|
@ -807,7 +807,14 @@ static inline int ROUND_UP(int a, int base)
|
|||
|
||||
static inline int is_subarray(char *vers)
|
||||
{
|
||||
return (*vers == '/');
|
||||
/* The version string for a 'subarray' (an array in a container)
|
||||
* is
|
||||
* /containername/componentname for normal read-write arrays
|
||||
* -containername/componentname for read-only arrays.
|
||||
* containername is e.g. md0, md_d1
|
||||
* componentname is dependant on the metadata. e.g. '1' 'S1' ...
|
||||
*/
|
||||
return (*vers == '/' || *vers == '-');
|
||||
}
|
||||
|
||||
#define LEVEL_MULTIPATH (-4)
|
||||
|
|
1
mdmon.h
1
mdmon.h
|
@ -19,6 +19,7 @@ struct active_array {
|
|||
|
||||
int action_fd;
|
||||
int resync_start_fd;
|
||||
int metadata_fd; /* for monitoring rw/ro status */
|
||||
|
||||
enum array_state prev_state, curr_state, next_state;
|
||||
enum sync_action prev_action, curr_action, next_action;
|
||||
|
|
22
monitor.c
22
monitor.c
|
@ -238,15 +238,21 @@ static int read_and_act(struct active_array *a)
|
|||
}
|
||||
|
||||
if (a->curr_state == readonly) {
|
||||
/* Well, I'm ready to handle things, so
|
||||
* read-auto is OK. FIXME what if we really want
|
||||
* readonly ???
|
||||
/* Well, I'm ready to handle things. If readonly
|
||||
* wasn't requested, transition to read-auto.
|
||||
*/
|
||||
get_resync_start(a);
|
||||
if (a->container->ss->set_array_state(a, 2))
|
||||
a->next_state = read_auto; /* array is clean */
|
||||
else
|
||||
a->next_state = active; /* Now active for recovery etc */
|
||||
char buf[64];
|
||||
read_attr(buf, sizeof(buf), a->metadata_fd);
|
||||
if (strncmp(buf, "external:-", 10) == 0) {
|
||||
/* explicit request for readonly array. Leave it alone */
|
||||
;
|
||||
} else {
|
||||
get_resync_start(a);
|
||||
if (a->container->ss->set_array_state(a, 2))
|
||||
a->next_state = read_auto; /* array is clean */
|
||||
else
|
||||
a->next_state = active; /* Now active for recovery etc */
|
||||
}
|
||||
}
|
||||
|
||||
if (!deactivate &&
|
||||
|
|
Loading…
Reference in New Issue