You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
12 KiB
339 lines
12 KiB
commit 860f11ed4d6a7bac6f2d698a30a13371c0aa7924 |
|
Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com> |
|
Date: Wed Mar 29 11:54:20 2017 +0200 |
|
|
|
Grow: support consistency policy change |
|
|
|
Extend the --consistency-policy parameter to work also in Grow mode. |
|
Using it changes the currently active consistency policy in the kernel |
|
driver and updates the metadata to make this change permanent. Currently |
|
this supports only changing between "ppl" and "resync" policies, that is |
|
enabling or disabling PPL at runtime. |
|
|
|
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> |
|
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> |
|
|
|
diff --git a/Grow.c b/Grow.c |
|
index a849012..b86b53e 100755 |
|
--- a/Grow.c |
|
+++ b/Grow.c |
|
@@ -528,6 +528,178 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) |
|
return 0; |
|
} |
|
|
|
+int Grow_consistency_policy(char *devname, int fd, struct context *c, struct shape *s) |
|
+{ |
|
+ struct supertype *st; |
|
+ struct mdinfo *sra; |
|
+ struct mdinfo *sd; |
|
+ char *subarray = NULL; |
|
+ int ret = 0; |
|
+ char container_dev[PATH_MAX]; |
|
+ |
|
+ if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && |
|
+ s->consistency_policy != CONSISTENCY_POLICY_PPL) { |
|
+ pr_err("Operation not supported for consistency policy %s\n", |
|
+ map_num(consistency_policies, s->consistency_policy)); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ st = super_by_fd(fd, &subarray); |
|
+ if (!st) |
|
+ return 1; |
|
+ |
|
+ sra = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY|GET_LEVEL| |
|
+ GET_DEVS|GET_STATE); |
|
+ if (!sra) { |
|
+ ret = 1; |
|
+ goto free_st; |
|
+ } |
|
+ |
|
+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL && |
|
+ !st->ss->write_init_ppl) { |
|
+ pr_err("%s metadata does not support PPL\n", st->ss->name); |
|
+ ret = 1; |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ if (sra->array.level != 5) { |
|
+ pr_err("Operation not supported for array level %d\n", |
|
+ sra->array.level); |
|
+ ret = 1; |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ if (sra->consistency_policy == (unsigned)s->consistency_policy) { |
|
+ pr_err("Consistency policy is already %s\n", |
|
+ map_num(consistency_policies, s->consistency_policy)); |
|
+ ret = 1; |
|
+ goto free_info; |
|
+ } else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC && |
|
+ sra->consistency_policy != CONSISTENCY_POLICY_PPL) { |
|
+ pr_err("Current consistency policy is %s, cannot change to %s\n", |
|
+ map_num(consistency_policies, sra->consistency_policy), |
|
+ map_num(consistency_policies, s->consistency_policy)); |
|
+ ret = 1; |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ if (subarray) { |
|
+ char *update; |
|
+ |
|
+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) |
|
+ update = "ppl"; |
|
+ else |
|
+ update = "no-ppl"; |
|
+ |
|
+ sprintf(container_dev, "/dev/%s", st->container_devnm); |
|
+ |
|
+ ret = Update_subarray(container_dev, subarray, update, NULL, |
|
+ c->verbose); |
|
+ if (ret) |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) { |
|
+ struct mdinfo info; |
|
+ |
|
+ if (subarray) { |
|
+ struct mdinfo *mdi; |
|
+ int cfd; |
|
+ |
|
+ cfd = open(container_dev, O_RDWR|O_EXCL); |
|
+ if (cfd < 0) { |
|
+ pr_err("Failed to open %s\n", container_dev); |
|
+ ret = 1; |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ ret = st->ss->load_container(st, cfd, st->container_devnm); |
|
+ close(cfd); |
|
+ |
|
+ if (ret) { |
|
+ pr_err("Cannot read superblock for %s\n", |
|
+ container_dev); |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ mdi = st->ss->container_content(st, subarray); |
|
+ info = *mdi; |
|
+ free(mdi); |
|
+ } |
|
+ |
|
+ for (sd = sra->devs; sd; sd = sd->next) { |
|
+ int dfd; |
|
+ char *devpath; |
|
+ |
|
+ if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0) |
|
+ continue; |
|
+ |
|
+ devpath = map_dev(sd->disk.major, sd->disk.minor, 0); |
|
+ dfd = dev_open(devpath, O_RDWR); |
|
+ if (dfd < 0) { |
|
+ pr_err("Failed to open %s\n", devpath); |
|
+ ret = 1; |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ if (!subarray) { |
|
+ ret = st->ss->load_super(st, dfd, NULL); |
|
+ if (ret) { |
|
+ pr_err("Failed to load super-block.\n"); |
|
+ close(dfd); |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ ret = st->ss->update_super(st, sra, "ppl", devname, |
|
+ c->verbose, 0, NULL); |
|
+ if (ret) { |
|
+ close(dfd); |
|
+ st->ss->free_super(st); |
|
+ goto free_info; |
|
+ } |
|
+ st->ss->getinfo_super(st, &info, NULL); |
|
+ } |
|
+ |
|
+ ret |= sysfs_set_num(sra, sd, "ppl_sector", info.ppl_sector); |
|
+ ret |= sysfs_set_num(sra, sd, "ppl_size", info.ppl_size); |
|
+ |
|
+ if (ret) { |
|
+ pr_err("Failed to set PPL attributes for %s\n", |
|
+ sd->sys_name); |
|
+ close(dfd); |
|
+ st->ss->free_super(st); |
|
+ goto free_info; |
|
+ } |
|
+ |
|
+ ret = st->ss->write_init_ppl(st, &info, dfd); |
|
+ if (ret) |
|
+ pr_err("Failed to write PPL\n"); |
|
+ |
|
+ close(dfd); |
|
+ |
|
+ if (!subarray) |
|
+ st->ss->free_super(st); |
|
+ |
|
+ if (ret) |
|
+ goto free_info; |
|
+ } |
|
+ } |
|
+ |
|
+ ret = sysfs_set_str(sra, NULL, "consistency_policy", |
|
+ map_num(consistency_policies, |
|
+ s->consistency_policy)); |
|
+ if (ret) |
|
+ pr_err("Failed to change array consistency policy\n"); |
|
+ |
|
+free_info: |
|
+ sysfs_free(sra); |
|
+free_st: |
|
+ free(st); |
|
+ free(subarray); |
|
+ |
|
+ return ret; |
|
+} |
|
+ |
|
/* |
|
* When reshaping an array we might need to backup some data. |
|
* This is written to all spares with a 'super_block' describing it. |
|
diff --git a/ReadMe.c b/ReadMe.c |
|
index fc04c2c..eb8fb4b 100644 |
|
--- a/ReadMe.c |
|
+++ b/ReadMe.c |
|
@@ -559,28 +559,30 @@ char Help_grow[] = |
|
"reconfiguration.\n" |
|
"\n" |
|
"Options that are valid with the grow (-G --grow) mode are:\n" |
|
-" --level= -l : Tell mdadm what level to convert the array to.\n" |
|
-" --layout= -p : For a FAULTY array, set/change the error mode.\n" |
|
-" : for other arrays, update the layout\n" |
|
-" --size= -z : Change the active size of devices in an array.\n" |
|
-" : This is useful if all devices have been replaced\n" |
|
-" : with larger devices. Value is in Kilobytes, or\n" |
|
-" : the special word 'max' meaning 'as large as possible'.\n" |
|
-" --assume-clean : When increasing the --size, this flag will avoid\n" |
|
-" : a resync of the new space\n" |
|
-" --chunk= -c : Change the chunksize of the array\n" |
|
-" --raid-devices= -n : Change the number of active devices in an array.\n" |
|
-" --add= -a : Add listed devices as part of reshape. This is\n" |
|
-" : needed for resizing a RAID0 which cannot have\n" |
|
-" : spares already present.\n" |
|
-" --bitmap= -b : Add or remove a write-intent bitmap.\n" |
|
-" --backup-file= file : A file on a different device to store data for a\n" |
|
-" : short time while increasing raid-devices on a\n" |
|
-" : RAID4/5/6 array. Also needed throughout a reshape\n" |
|
-" : when changing parameters other than raid-devices\n" |
|
-" --array-size= -Z : Change visible size of array. This does not change\n" |
|
-" : any data on the device, and is not stable across restarts.\n" |
|
-" --data-offset= : Location on device to move start of data to.\n" |
|
+" --level= -l : Tell mdadm what level to convert the array to.\n" |
|
+" --layout= -p : For a FAULTY array, set/change the error mode.\n" |
|
+" : for other arrays, update the layout\n" |
|
+" --size= -z : Change the active size of devices in an array.\n" |
|
+" : This is useful if all devices have been replaced\n" |
|
+" : with larger devices. Value is in Kilobytes, or\n" |
|
+" : the special word 'max' meaning 'as large as possible'.\n" |
|
+" --assume-clean : When increasing the --size, this flag will avoid\n" |
|
+" : a resync of the new space\n" |
|
+" --chunk= -c : Change the chunksize of the array\n" |
|
+" --raid-devices= -n : Change the number of active devices in an array.\n" |
|
+" --add= -a : Add listed devices as part of reshape. This is\n" |
|
+" : needed for resizing a RAID0 which cannot have\n" |
|
+" : spares already present.\n" |
|
+" --bitmap= -b : Add or remove a write-intent bitmap.\n" |
|
+" --backup-file= file : A file on a different device to store data for a\n" |
|
+" : short time while increasing raid-devices on a\n" |
|
+" : RAID4/5/6 array. Also needed throughout a reshape\n" |
|
+" : when changing parameters other than raid-devices\n" |
|
+" --array-size= -Z : Change visible size of array. This does not change any\n" |
|
+" : data on the device, and is not stable across restarts.\n" |
|
+" --data-offset= : Location on device to move start of data to.\n" |
|
+" --consistency-policy= : Change the consistency policy of an active array.\n" |
|
+" -k : Currently works only for PPL with RAID5.\n" |
|
; |
|
|
|
char Help_incr[] = |
|
diff --git a/mdadm.8.in b/mdadm.8.in |
|
index 1178ed9..744c12b 100644 |
|
--- a/mdadm.8.in |
|
+++ b/mdadm.8.in |
|
@@ -126,7 +126,7 @@ of component devices and changing the number of active devices in |
|
Linear and RAID levels 0/1/4/5/6, |
|
changing the RAID level between 0, 1, 5, and 6, and between 0 and 10, |
|
changing the chunk size and layout for RAID 0,4,5,6,10 as well as adding or |
|
-removing a write-intent bitmap. |
|
+removing a write-intent bitmap and changing the array's consistency policy. |
|
|
|
.TP |
|
.B "Incremental Assembly" |
|
@@ -1050,6 +1050,10 @@ after unclean shutdown. Implicitly selected when using |
|
For RAID5 only, Partial Parity Log is used to close the write hole and |
|
eliminate resync. PPL is stored in the metadata region of RAID member drives, |
|
no additional journal drive is needed. |
|
+ |
|
+.PP |
|
+Can be used with \-\-grow to change the consistency policy of an active array |
|
+in some cases. See CONSISTENCY POLICY CHANGES below. |
|
.RE |
|
|
|
|
|
@@ -2694,6 +2698,8 @@ RAID0, RAID4, and RAID5, and between RAID0 and RAID10 (in the near-2 mode). |
|
.IP \(bu 4 |
|
add a write-intent bitmap to any array which supports these bitmaps, or |
|
remove a write-intent bitmap from such an array. |
|
+.IP \(bu 4 |
|
+change the array's consistency policy. |
|
.PP |
|
|
|
Using GROW on containers is currently supported only for Intel's IMSM |
|
@@ -2850,6 +2856,16 @@ can be added. Note that if you add a bitmap stored in a file which is |
|
in a filesystem that is on the RAID array being affected, the system |
|
will deadlock. The bitmap must be on a separate filesystem. |
|
|
|
+.SS CONSISTENCY POLICY CHANGES |
|
+ |
|
+The consistency policy of an active array can be changed by using the |
|
+.B \-\-consistency\-policy |
|
+option in Grow mode. Currently this works only for the |
|
+.B ppl |
|
+and |
|
+.B resync |
|
+policies and allows to enable or disable the RAID5 Partial Parity Log (PPL). |
|
+ |
|
.SH INCREMENTAL MODE |
|
|
|
.HP 12 |
|
diff --git a/mdadm.c b/mdadm.c |
|
index 6edf3ab..5ebf117 100644 |
|
--- a/mdadm.c |
|
+++ b/mdadm.c |
|
@@ -1221,6 +1221,7 @@ int main(int argc, char *argv[]) |
|
s.journaldisks = 1; |
|
continue; |
|
case O(CREATE, 'k'): |
|
+ case O(GROW, 'k'): |
|
s.consistency_policy = map_name(consistency_policies, |
|
optarg); |
|
if (s.consistency_policy == UnSet || |
|
@@ -1679,6 +1680,8 @@ int main(int argc, char *argv[]) |
|
rv = Grow_reshape(devlist->devname, mdfd, |
|
devlist->next, |
|
data_offset, &c, &s); |
|
+ } else if (s.consistency_policy != UnSet) { |
|
+ rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); |
|
} else if (array_size == 0) |
|
pr_err("no changes to --grow\n"); |
|
break; |
|
diff --git a/mdadm.h b/mdadm.h |
|
index 2c7066d..4891acf 100644 |
|
--- a/mdadm.h |
|
+++ b/mdadm.h |
|
@@ -1331,6 +1331,8 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info, |
|
extern int Grow_continue(int mdfd, struct supertype *st, |
|
struct mdinfo *info, char *backup_file, |
|
int forked, int freeze_reshape); |
|
+extern int Grow_consistency_policy(char *devname, int fd, |
|
+ struct context *c, struct shape *s); |
|
|
|
extern int restore_backup(struct supertype *st, |
|
struct mdinfo *content,
|
|
|