* [PATCH 08/11] mdadm: add the ability to change cluster name
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
To support change the cluster name, the commit do the followings:
1. extend original write_bitmap function for new scenario.
2. add the scenarion to handle the modification of cluster's name
in write_bitmap1.
3. let the cluster name also show in examine_super1 and detail_super1
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Assemble.c | 5 ++++-
Grow.c | 2 +-
mdadm.8.in | 6 ++++++
mdadm.c | 5 ++++-
mdadm.h | 7 ++++++-
super0.c | 4 ++--
super1.c | 23 +++++++++++++++++++++--
7 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 42710a8..12ac299 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -626,7 +626,10 @@ static int load_devices(struct devs *devices, char *devmap,
if (strcmp(c->update, "byteorder") == 0)
err = 0;
- else
+ else if (strcmp(c->update, "home-cluster") == 0) {
+ tst->cluster_name = c->homecluster;
+ tst->ss->write_bitmap(tst, dfd, NameUpdate);
+ } else
err = tst->ss->update_super(tst, content, c->update,
devname, c->verbose,
ident->uuid_set,
diff --git a/Grow.c b/Grow.c
index 90a7fe9..857c7e1 100644
--- a/Grow.c
+++ b/Grow.c
@@ -412,7 +412,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
bitmapsize, offset_setable,
major)
)
- st->ss->write_bitmap(st, fd2);
+ st->ss->write_bitmap(st, fd2, NoUpdate);
else {
pr_err("failed to create internal bitmap - chunksize problem.\n");
close(fd2);
diff --git a/mdadm.8.in b/mdadm.8.in
index 3dd000c..99b02a3 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1098,6 +1098,7 @@ argument given to this flag can be one of
.BR uuid ,
.BR name ,
.BR homehost ,
+.BR home-cluster ,
.BR resync ,
.BR byteorder ,
.BR devicesize ,
@@ -1160,6 +1161,11 @@ same as updating the UUID.
For version-1 superblocks, this involves updating the name.
The
+.B home\-cluster
+option will change the cluster name as recorded in the superblock and
+bitmap. This option only works for clustered environment.
+
+The
.B resync
option will cause the array to be marked
.I dirty
diff --git a/mdadm.c b/mdadm.c
index f08d8c9..5e9b302 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -598,6 +598,7 @@ int main(int argc, char *argv[])
}
continue;
case O(CREATE, ClusterName):
+ case O(ASSEMBLE, ClusterName):
c.homecluster = optarg;
if (strlen(c.homecluster) > 64) {
pr_err("Cluster name too big.\n");
@@ -741,6 +742,8 @@ int main(int argc, char *argv[])
continue;
if (strcmp(c.update, "homehost")==0)
continue;
+ if (strcmp(c.update, "home-cluster")==0)
+ continue;
if (strcmp(c.update, "devicesize")==0)
continue;
if (strcmp(c.update, "no-bitmap")==0)
@@ -780,7 +783,7 @@ int main(int argc, char *argv[])
}
fprintf(outf, "Valid --update options are:\n"
" 'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
- " 'summaries', 'homehost', 'byteorder', 'devicesize',\n"
+ " 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
" 'no-bitmap', 'metadata', 'revert-reshape'\n"
" 'bbl', 'no-bbl'\n"
);
diff --git a/mdadm.h b/mdadm.h
index 00c726e..d8b0749 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -354,6 +354,11 @@ enum prefix_standard {
IEC
};
+enum bitmap_update {
+ NoUpdate,
+ NameUpdate,
+};
+
/* structures read from config file */
/* List of mddevice names and identifiers
* Identifiers can be:
@@ -850,7 +855,7 @@ extern struct superswitch {
/* if add_internal_bitmap succeeded for existing array, this
* writes it out.
*/
- int (*write_bitmap)(struct supertype *st, int fd);
+ int (*write_bitmap)(struct supertype *st, int fd, enum bitmap_update update);
/* Free the superblock and any other allocated data */
void (*free_super)(struct supertype *st);
diff --git a/super0.c b/super0.c
index deb5999..6ad9d39 100644
--- a/super0.c
+++ b/super0.c
@@ -900,7 +900,7 @@ static int write_init_super0(struct supertype *st)
rv = store_super0(st, di->fd);
if (rv == 0 && (sb->state & (1<<MD_SB_BITMAP_PRESENT)))
- rv = st->ss->write_bitmap(st, di->fd);
+ rv = st->ss->write_bitmap(st, di->fd, NoUpdate);
if (rv)
pr_err("failed to write superblock to %s\n",
@@ -1175,7 +1175,7 @@ static void locate_bitmap0(struct supertype *st, int fd)
lseek64(fd, offset, 0);
}
-static int write_bitmap0(struct supertype *st, int fd)
+static int write_bitmap0(struct supertype *st, int fd, enum bitmap_update update)
{
unsigned long long dsize;
unsigned long long offset;
diff --git a/super1.c b/super1.c
index fd728d2..699f1ec 100644
--- a/super1.c
+++ b/super1.c
@@ -256,6 +256,7 @@ static int awrite(struct align_fd *afd, void *buf, int len)
static void examine_super1(struct supertype *st, char *homehost)
{
struct mdp_superblock_1 *sb = st->sb;
+ bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
time_t atime;
unsigned int d;
int role;
@@ -289,6 +290,8 @@ static void examine_super1(struct supertype *st, char *homehost)
strncmp(sb->set_name, homehost, l) == 0)
printf(" (local to host %s)", homehost);
printf("\n");
+ if (bms->nodes > 0)
+ printf("Cluster Name : %s", bms->cluster_name);
atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL;
printf(" Creation Time : %.24s\n", ctime(&atime));
c=map_num(pers, __le32_to_cpu(sb->level));
@@ -740,6 +743,7 @@ err:
static void detail_super1(struct supertype *st, char *homehost)
{
struct mdp_superblock_1 *sb = st->sb;
+ bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
int i;
int l = homehost ? strlen(homehost) : 0;
@@ -748,6 +752,8 @@ static void detail_super1(struct supertype *st, char *homehost)
sb->set_name[l] == ':' &&
strncmp(sb->set_name, homehost, l) == 0)
printf(" (local to host %s)", homehost);
+ if (bms->nodes > 0)
+ printf("Cluster Name : %64s", bms->cluster_name);
printf("\n UUID : ");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0) printf(":");
@@ -1691,7 +1697,7 @@ static int write_init_super1(struct supertype *st)
sb->sb_csum = calc_sb_1_csum(sb);
rv = store_super1(st, di->fd);
if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
- rv = st->ss->write_bitmap(st, di->fd);
+ rv = st->ss->write_bitmap(st, di->fd, NoUpdate);
close(di->fd);
di->fd = -1;
if (rv)
@@ -2175,7 +2181,7 @@ static void locate_bitmap1(struct supertype *st, int fd)
lseek64(fd, offset<<9, 0);
}
-static int write_bitmap1(struct supertype *st, int fd)
+static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update)
{
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
@@ -2185,6 +2191,19 @@ static int write_bitmap1(struct supertype *st, int fd)
struct align_fd afd;
unsigned int i = 0;
+ switch (update) {
+ case NameUpdate:
+ /* update cluster name */
+ if (st->cluster_name) {
+ memset((char *)bms->cluster_name, 0, sizeof(bms->cluster_name));
+ strncpy((char *)bms->cluster_name, st->cluster_name, 64);
+ }
+ break;
+ case NoUpdate:
+ default:
+ break;
+ }
+
init_afd(&afd, fd);
locate_bitmap1(st, fd);
--
1.7.12.4
^ permalink raw reply related
* [PATCH 07/11] Skip clustered devices in incremental
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
We want the clustered devices to be started exclusively by a cluster
resource-agent. So, avoid starting using the incremental option.
This also skips a clustered md from starting during boot in inactive mode.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Incremental.c | 5 +++++
super1.c | 2 ++
2 files changed, 7 insertions(+)
diff --git a/Incremental.c b/Incremental.c
index 0c9a9a4..5450a5c 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -232,6 +232,11 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
devname);
goto out;
}
+ /* Skip the clustered ones. This should be started by
+ * clustering resource agents
+ */
+ if (info.array.state & (1 << MD_SB_CLUSTERED))
+ goto out;
/* 3a/ if not, check for homehost match. If no match, continue
* but don't trust the 'name' in the array. Thus a 'random' minor
diff --git a/super1.c b/super1.c
index 60f470b..fd728d2 100644
--- a/super1.c
+++ b/super1.c
@@ -891,6 +891,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
info->array.state =
(__le64_to_cpu(sb->resync_offset) == MaxSector)
? 1 : 0;
+ if (__le32_to_cpu(bsb->nodes) > 1)
+ info->array.state |= (1 << MD_SB_CLUSTERED);
info->data_offset = __le64_to_cpu(sb->data_offset);
info->component_size = __le64_to_cpu(sb->size);
--
1.7.12.4
^ permalink raw reply related
* [PATCH 06/11] Convert a bitmap=none device to clustered
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
This adds the ability to convert a regular md without bitmap
(--bitmap=none) to a clustered device (--bitmap=clustered).
To convert a device with --bitmap=internal or --bitmap=external,
you have to convert to --bitmap=none and then re-execute the
command with --bitmap=clustered.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Grow.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/Grow.c b/Grow.c
index 3180be9..90a7fe9 100644
--- a/Grow.c
+++ b/Grow.c
@@ -330,8 +330,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
}
return 0;
}
- pr_err("Internal bitmap already present on %s\n",
- devname);
+ pr_err("%s bitmap already present on %s\n", s->bitmap_file, devname);
return 1;
}
@@ -375,7 +374,8 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
free(st);
return 1;
}
- if (strcmp(s->bitmap_file, "internal") == 0) {
+ if (strcmp(s->bitmap_file, "internal") == 0 ||
+ strcmp(s->bitmap_file, "clustered") == 0) {
int rv;
int d;
int offset_setable = 0;
@@ -384,6 +384,8 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name);
return 1;
}
+ st->nodes = c->nodes;
+ st->cluster_name = c->homecluster;
mdi = sysfs_read(fd, NULL, GET_BITMAP_LOCATION);
if (mdi)
offset_setable = 1;
@@ -426,6 +428,8 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
mdi->bitmap_offset);
} else {
+ if (strcmp(s->bitmap_file, "clustered") == 0)
+ array.state |= (1<<MD_SB_CLUSTERED);
array.state |= (1<<MD_SB_BITMAP_PRESENT);
rv = ioctl(fd, SET_ARRAY_INFO, &array);
}
--
1.7.12.4
^ permalink raw reply related
* [PATCH 05/11] Add a new clustered disk
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
A clustered disk is added by the traditional --add sequence.
However, other nodes need to acknowledge that they can "see"
the device. This is done by --cluster-confirm:
--cluster-confirm SLOTNUM:/dev/whatever (if disk is found)
or
--cluster-confirm SLOTNUM:missing (if disk is not found)
The node initiating the --add, has the disk state tagged with
MD_DISK_CLUSTER_ADD and the one confirming tag the disk with
MD_DISK_CANDIDATE.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Manage.c | 39 +++++++++++++++++++++++++++++++++++----
ReadMe.c | 1 +
md_p.h | 7 +++++++
md_u.h | 1 +
mdadm.8.in | 9 +++++++++
mdadm.c | 4 ++++
mdadm.h | 2 ++
util.c | 10 ++++++++++
8 files changed, 69 insertions(+), 4 deletions(-)
diff --git a/Manage.c b/Manage.c
index 2e602d7..f337ec2 100644
--- a/Manage.c
+++ b/Manage.c
@@ -690,7 +690,8 @@ skip_re_add:
int Manage_add(int fd, int tfd, struct mddev_dev *dv,
struct supertype *tst, mdu_array_info_t *array,
int force, int verbose, char *devname,
- char *update, unsigned long rdev, unsigned long long array_size)
+ char *update, unsigned long rdev, unsigned long long array_size,
+ int raid_slot)
{
unsigned long long ldsize;
struct supertype *dev_st = NULL;
@@ -880,7 +881,10 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
}
disc.major = major(rdev);
disc.minor = minor(rdev);
- disc.number =j;
+ if (raid_slot < 0)
+ disc.number = j;
+ else
+ disc.number = raid_slot;
disc.state = 0;
if (array->not_persistent==0) {
int dfd;
@@ -921,6 +925,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
}
free(used);
}
+
+ if (array->state & (1 << MD_SB_CLUSTERED)) {
+ if (dv->disposition == 'c')
+ disc.state |= (1 << MD_DISK_CANDIDATE);
+ else
+ disc.state |= (1 << MD_DISK_CLUSTER_ADD);
+ }
+
if (dv->writemostly == 1)
disc.state |= (1 << MD_DISK_WRITEMOSTLY);
if (tst->ss->external) {
@@ -1240,6 +1252,7 @@ int Manage_subdevs(char *devname, int fd,
* variant on 'A'
* 'F' - Another variant of 'A', where the device was faulty
* so must be removed from the array first.
+ * 'c' - confirm the device as found (for clustered environments)
*
* For 'f' and 'r', the device can also be a kernel-internal
* name such as 'sdb'.
@@ -1255,6 +1268,7 @@ int Manage_subdevs(char *devname, int fd,
struct mdinfo info;
int frozen = 0;
int busy = 0;
+ int raid_slot = -1;
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
pr_err("Cannot get array info for %s\n",
@@ -1283,6 +1297,17 @@ int Manage_subdevs(char *devname, int fd,
int rv;
int mj,mn;
+ raid_slot = -1;
+ if (dv->disposition == 'c') {
+ rv = parse_cluster_confirm_arg(dv->devname,
+ &dv->devname,
+ &raid_slot);
+ if (!rv) {
+ pr_err("Could not get the devname of cluster\n");
+ goto abort;
+ }
+ }
+
if (strcmp(dv->devname, "failed") == 0 ||
strcmp(dv->devname, "faulty") == 0) {
if (dv->disposition != 'A'
@@ -1308,6 +1333,11 @@ int Manage_subdevs(char *devname, int fd,
if (strcmp(dv->devname, "missing") == 0) {
struct mddev_dev *add_devlist = NULL;
struct mddev_dev **dp;
+ if (dv->disposition == 'c') {
+ rv = ioctl(fd, CLUSTERED_DISK_NACK, NULL);
+ break;
+ }
+
if (dv->disposition != 'A') {
pr_err("'missing' only meaningful with --re-add\n");
goto abort;
@@ -1400,7 +1430,7 @@ int Manage_subdevs(char *devname, int fd,
else {
int open_err = errno;
if (stat(dv->devname, &stb) != 0) {
- pr_err("Cannot find %s: %s\n",
+ pr_err("%s: %d Cannot find %s: %s\n", __func__, __LINE__,
dv->devname, strerror(errno));
goto abort;
}
@@ -1438,6 +1468,7 @@ int Manage_subdevs(char *devname, int fd,
case 'A':
case 'M': /* --re-add missing */
case 'F': /* --re-add faulty */
+ case 'c': /* --cluster-confirm */
/* add the device */
if (subarray) {
pr_err("Cannot add disks to a \'member\' array, perform this operation on the parent container\n");
@@ -1471,7 +1502,7 @@ int Manage_subdevs(char *devname, int fd,
}
rv = Manage_add(fd, tfd, dv, tst, &array,
force, verbose, devname, update,
- rdev, array_size);
+ rdev, array_size, raid_slot);
close(tfd);
tfd = -1;
if (rv < 0)
diff --git a/ReadMe.c b/ReadMe.c
index c6286ae..c854cd5 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -169,6 +169,7 @@ struct option long_options[] = {
{"wait", 0, 0, WaitOpt},
{"wait-clean", 0, 0, Waitclean },
{"action", 1, 0, Action },
+ {"cluster-confirm", 0, 0, ClusterConfirm},
/* For Detail/Examine */
{"brief", 0, 0, Brief},
diff --git a/md_p.h b/md_p.h
index c4846ba..e59504f 100644
--- a/md_p.h
+++ b/md_p.h
@@ -78,6 +78,12 @@
#define MD_DISK_ACTIVE 1 /* disk is running but may not be in sync */
#define MD_DISK_SYNC 2 /* disk is in sync with the raid set */
#define MD_DISK_REMOVED 3 /* disk is in sync with the raid set */
+#define MD_DISK_CLUSTER_ADD 4 /* Initiate a disk add across the cluster
+ * For clustered enviroments only.
+ */
+#define MD_DISK_CANDIDATE 5 /* disk is added as spare (local) until confirmed
+ * For clustered enviroments only.
+ */
#define MD_DISK_WRITEMOSTLY 9 /* disk is "write-mostly" is RAID1 config.
* read requests will only be sent here in
@@ -106,6 +112,7 @@ typedef struct mdp_device_descriptor_s {
#define MD_SB_BLOCK_CONTAINER_RESHAPE 3 /* block container wide reshapes */
#define MD_SB_BLOCK_VOLUME 4 /* block activation of array, other arrays
* in container can be activated */
+#define MD_SB_CLUSTERED 5 /* MD is clustered */
#define MD_SB_BITMAP_PRESENT 8 /* bitmap may be present nearby */
typedef struct mdp_superblock_s {
diff --git a/md_u.h b/md_u.h
index be9868a..76068d6 100644
--- a/md_u.h
+++ b/md_u.h
@@ -44,6 +44,7 @@
#define STOP_ARRAY _IO (MD_MAJOR, 0x32)
#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33)
#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34)
+#define CLUSTERED_DISK_NACK _IO (MD_MAJOR, 0x35)
typedef struct mdu_version_s {
int major;
diff --git a/mdadm.8.in b/mdadm.8.in
index a07ddb7..3dd000c 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1406,6 +1406,15 @@ will avoid reading from these devices if possible.
.BR \-\-readwrite
Subsequent devices that are added or re\-added will have the 'write-mostly'
flag cleared.
+.TP
+.BR \-\-cluster\-confirm
+Confirm the existence of the device. This is issued in response to an \-\-add
+request by a node in a cluster. When a node adds a device it sends a message
+to all nodes in the cluster to look for a device with a UUID. This translates
+to a udev notification with the UUID of the device to be added and the slot
+number. The receiving node must acknowledge this message
+with \-\-cluster\-confirm. Valid arguments are <slot>:<devicename> in case
+the device is found or <slot>:missing in case the device is not found.
.P
Each of these options requires that the first device listed is the array
diff --git a/mdadm.c b/mdadm.c
index c39d11e..f08d8c9 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -196,6 +196,7 @@ int main(int argc, char *argv[])
case 'f':
case Fail:
case ReAdd: /* re-add */
+ case ClusterConfirm:
if (!mode) {
newmode = MANAGE;
shortopt = short_bitmap_options;
@@ -933,6 +934,9 @@ int main(int argc, char *argv[])
* remove the device */
devmode = 'f';
continue;
+ case O(MANAGE, ClusterConfirm):
+ devmode = 'c';
+ continue;
case O(MANAGE,Replace):
/* Mark these devices for replacement */
devmode = 'R';
diff --git a/mdadm.h b/mdadm.h
index f56d9d6..00c726e 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -346,6 +346,7 @@ enum special_options {
Action,
Nodes,
ClusterName,
+ ClusterConfirm,
};
enum prefix_standard {
@@ -1281,6 +1282,7 @@ extern int parse_uuid(char *str, int uuid[4]);
extern int parse_layout_10(char *layout);
extern int parse_layout_faulty(char *layout);
extern long parse_num(char *num);
+extern int parse_cluster_confirm_arg(char *inp, char **devname, int *slot);
extern int check_ext2(int fd, char *name);
extern int check_reiser(int fd, char *name);
extern int check_raid(int fd, char *name);
diff --git a/util.c b/util.c
index ed9a745..8d27564 100644
--- a/util.c
+++ b/util.c
@@ -273,6 +273,16 @@ long parse_num(char *num)
}
#endif
+int parse_cluster_confirm_arg(char *input, char **devname, int *slot)
+{
+ char *dev;
+ *slot = strtoul(input, &dev, 10);
+ if (dev == input || dev[0] != ':')
+ return -1;
+ *devname = dev+1;
+ return 0;
+}
+
void remove_partitions(int fd)
{
/* remove partitions from this block devices.
--
1.7.12.4
^ permalink raw reply related
* [PATCH 04/11] Show all bitmaps while examining bitmap
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
This adds capability of exmining bitmaps corresponding to all
nodes/slots on the device.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
bitmap.c | 49 ++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 40 insertions(+), 9 deletions(-)
diff --git a/bitmap.c b/bitmap.c
index 920033a..d21e5cc 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -260,7 +260,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
int rv = 1;
char buf[64];
int swap;
- int fd;
+ int fd, i;
__u32 uuid32[4];
fd = bitmap_file_open(filename, &st);
@@ -317,9 +317,13 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
uuid32[2],
uuid32[3]);
- printf(" Events : %llu\n", (unsigned long long)sb->events);
- printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
- printf(" State : %s\n", bitmap_state(sb->state));
+ if (sb->nodes == 0) {
+ printf(" Events : %llu\n", (unsigned long long)sb->events);
+ printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
+ printf(" State : %s\n", bitmap_state(sb->state));
+
+ }
+
printf(" Chunksize : %s\n", human_chunksize(sb->chunksize));
printf(" Daemon : %ds flush period\n", sb->daemon_sleep);
if (sb->write_behind)
@@ -329,11 +333,38 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
printf(" Write Mode : %s\n", buf);
printf(" Sync Size : %llu%s\n", (unsigned long long)sb->sync_size/2,
human_size(sb->sync_size * 512));
- if (brief)
- goto free_info;
- printf(" Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
- info->total_bits, info->dirty_bits,
- 100.0 * info->dirty_bits / (info->total_bits?:1));
+
+ if (sb->nodes == 0) {
+ if (brief)
+ goto free_info;
+ printf(" Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
+ info->total_bits, info->dirty_bits,
+ 100.0 * info->dirty_bits / (info->total_bits?:1));
+ } else {
+ printf(" Cluster nodes : %d\n", sb->nodes);
+ printf(" Cluster name : %64s\n", sb->cluster_name);
+ for (i = 0; i < (int)sb->nodes; i++) {
+ if (i) {
+ free(info);
+ info = bitmap_fd_read(fd, brief);
+ sb = &info->sb;
+ }
+ if (sb->magic != BITMAP_MAGIC)
+ pr_err("invalid bitmap magic 0x%x, the bitmap file appears to be corrupted\n", sb->magic);
+
+ printf(" Node Slot : %d\n", i);
+ printf(" Events : %llu\n", (unsigned long long)sb->events);
+ printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
+ printf(" State : %s\n", bitmap_state(sb->state));
+ if (brief)
+ continue;
+ printf(" Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
+ info->total_bits, info->dirty_bits,
+ 100.0 * info->dirty_bits / (info->total_bits?:1));
+
+ }
+ }
+
free_info:
free(info);
return rv;
--
1.7.12.4
^ permalink raw reply related
* [PATCH 03/11] home-cluster while creating an array
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
The home-cluster is stored in the bitmap super block of the
array. The device can be assembled on a cluster with the
cluster name same as the one recorded in the bitmap.
If home-cluster is not specified, this is auto-detected using
dlopen corosync cmap library.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Create.c | 1 +
Makefile | 1 +
ReadMe.c | 1 +
config.c | 27 ++++++++++++++++++++++++++-
mdadm.8.in | 6 ++++++
mdadm.c | 17 +++++++++++++++++
mdadm.h | 5 +++++
super1.c | 3 +++
util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/Create.c b/Create.c
index e4577af..9663dc4 100644
--- a/Create.c
+++ b/Create.c
@@ -532,6 +532,7 @@ int Create(struct supertype *st, char *mddev,
warn = 1;
}
st->nodes = c->nodes;
+ st->cluster_name = c->homecluster;
if (warn) {
if (c->runstop!= 1) {
diff --git a/Makefile b/Makefile
index a7d8c5c..431f08b 100644
--- a/Makefile
+++ b/Makefile
@@ -101,6 +101,7 @@ endif
# If you want a static binary, you might uncomment these
# LDFLAGS = -static
# STRIP = -s
+LDLIBS=-ldl
INSTALL = /usr/bin/install
DESTDIR =
diff --git a/ReadMe.c b/ReadMe.c
index 30c569d..c6286ae 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -141,6 +141,7 @@ struct option long_options[] = {
{"symlinks", 1, 0, Symlinks},
{"data-offset",1, 0, DataOffset},
{"nodes",1, 0, Nodes},
+ {"home-cluster",1, 0, ClusterName},
/* For assemble */
{"uuid", 1, 0, 'u'},
diff --git a/config.c b/config.c
index 7342c42..21b6afd 100644
--- a/config.c
+++ b/config.c
@@ -77,7 +77,7 @@ char DefaultAltConfFile[] = CONFFILE2;
char DefaultAltConfDir[] = CONFFILE2 ".d";
enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev,
- Homehost, AutoMode, Policy, PartPolicy, LTEnd };
+ Homehost, HomeCluster, AutoMode, Policy, PartPolicy, LTEnd };
char *keywords[] = {
[Devices] = "devices",
[Array] = "array",
@@ -86,6 +86,7 @@ char *keywords[] = {
[Program] = "program",
[CreateDev]= "create",
[Homehost] = "homehost",
+ [HomeCluster] = "homecluster",
[AutoMode] = "auto",
[Policy] = "policy",
[PartPolicy]="part-policy",
@@ -562,6 +563,21 @@ void homehostline(char *line)
}
}
+static char *home_cluster = NULL;
+void homeclusterline(char *line)
+{
+ char *w;
+
+ for (w=dl_next(line); w != line ; w=dl_next(w)) {
+ if (home_cluster == NULL) {
+ if (strcasecmp(w, "<none>")==0)
+ home_cluster = xstrdup("");
+ else
+ home_cluster = xstrdup(w);
+ }
+ }
+}
+
char auto_yes[] = "yes";
char auto_no[] = "no";
char auto_homehost[] = "homehost";
@@ -724,6 +740,9 @@ void conf_file(FILE *f)
case Homehost:
homehostline(line);
break;
+ case HomeCluster:
+ homeclusterline(line);
+ break;
case AutoMode:
autoline(line);
break;
@@ -884,6 +903,12 @@ char *conf_get_homehost(int *require_homehostp)
return home_host;
}
+char *conf_get_homecluster(void)
+{
+ load_conffile();
+ return home_cluster;
+}
+
struct createinfo *conf_get_create_info(void)
{
load_conffile();
diff --git a/mdadm.8.in b/mdadm.8.in
index fed0007..a07ddb7 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -415,6 +415,12 @@ This functionality is currently only provided by
and
.BR \-\-monitor .
+.TP
+.B \-\-home\-cluster=
+specifies the cluster name for the md device. The md device can be assembled
+only on the cluster which matches the name specified. If this option is not
+provided, mdadm tries to detect the cluster name automatically.
+
.SH For create, build, or grow:
.TP
diff --git a/mdadm.c b/mdadm.c
index 25d15a8..c39d11e 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -596,6 +596,13 @@ int main(int argc, char *argv[])
exit(2);
}
continue;
+ case O(CREATE, ClusterName):
+ c.homecluster = optarg;
+ if (strlen(c.homecluster) > 64) {
+ pr_err("Cluster name too big.\n");
+ exit(ERANGE);
+ }
+ continue;
case O(CREATE,'x'): /* number of spare (eXtra) disks */
if (s.sparedisks) {
pr_err("spare-devices set twice: %d and %s\n",
@@ -1276,6 +1283,16 @@ int main(int argc, char *argv[])
c.require_homehost = 0;
}
+ if (c.homecluster == NULL && (c.nodes > 0)) {
+ c.homecluster = conf_get_homecluster();
+ if (c.homecluster == NULL)
+ rv = get_cluster_name(&c.homecluster);
+ if (rv != 0) {
+ pr_err("The md can't get cluster name\n");
+ exit(1);
+ }
+ }
+
if (c.backup_file && data_offset != INVALID_SECTORS) {
pr_err("--backup-file and --data-offset are incompatible\n");
exit(2);
diff --git a/mdadm.h b/mdadm.h
index 9d55801..f56d9d6 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -345,6 +345,7 @@ enum special_options {
Restore,
Action,
Nodes,
+ ClusterName,
};
enum prefix_standard {
@@ -420,6 +421,7 @@ struct context {
int invalid_backup;
char *action;
int nodes;
+ char *homecluster;
};
struct shape {
@@ -1032,6 +1034,7 @@ struct supertype {
int devcnt;
int retry_soon;
int nodes;
+ char *cluster_name;
struct mdinfo *devs;
@@ -1308,6 +1311,7 @@ extern char *conf_get_mailaddr(void);
extern char *conf_get_mailfrom(void);
extern char *conf_get_program(void);
extern char *conf_get_homehost(int *require_homehostp);
+extern char *conf_get_homecluster(void);
extern char *conf_line(FILE *file);
extern char *conf_word(FILE *file, int allow_key);
extern void print_quoted(char *str);
@@ -1416,6 +1420,7 @@ extern char *stat2devnm(struct stat *st);
extern char *fd2devnm(int fd);
extern int in_initrd(void);
+extern int get_cluster_name(char **name);
#define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1))
#define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base))
diff --git a/super1.c b/super1.c
index 78d98a7..60f470b 100644
--- a/super1.c
+++ b/super1.c
@@ -2145,6 +2145,9 @@ add_internal_bitmap1(struct supertype *st,
bms->sync_size = __cpu_to_le64(size);
bms->write_behind = __cpu_to_le32(write_behind);
bms->nodes = __cpu_to_le32(st->nodes);
+ if (st->cluster_name)
+ strncpy((char *)bms->cluster_name,
+ st->cluster_name, strlen(st->cluster_name));
*chunkp = chunk;
return 1;
diff --git a/util.c b/util.c
index cc98d3b..ed9a745 100644
--- a/util.c
+++ b/util.c
@@ -34,6 +34,8 @@
#include <ctype.h>
#include <dirent.h>
#include <signal.h>
+#include <dlfcn.h>
+#include <corosync/cmap.h>
/*
* following taken from linux/blkpg.h because they aren't
@@ -1976,3 +1978,51 @@ void reopen_mddev(int mdfd)
if (fd >= 0 && fd != mdfd)
dup2(fd, mdfd);
}
+
+int get_cluster_name(char **cluster_name)
+{
+ void *lib_handle = NULL;
+ int rv = -1;
+
+ cmap_handle_t handle;
+ static int (*initialize)(cmap_handle_t *handle);
+ static int (*get_string)(cmap_handle_t handle,
+ const char *string,
+ char **name);
+ static int (*finalize)(cmap_handle_t handle);
+
+
+ lib_handle = dlopen("libcmap.so.4", RTLD_NOW | RTLD_LOCAL);
+ if (!lib_handle)
+ return rv;
+
+ initialize = dlsym(lib_handle, "cmap_initialize");
+ if (!initialize)
+ goto out;
+
+ get_string = dlsym(lib_handle, "cmap_get_string");
+ if (!get_string)
+ goto out;
+
+ finalize = dlsym(lib_handle, "cmap_finalize");
+ if (!finalize)
+ goto out;
+
+ rv = initialize(&handle);
+ if (rv != CS_OK)
+ goto out;
+
+ rv = get_string(handle, "totem.cluster_name", cluster_name);
+ if (rv != CS_OK) {
+ free(*cluster_name);
+ rv = -1;
+ goto name_err;
+ }
+
+ rv = 0;
+name_err:
+ finalize(handle);
+out:
+ dlclose(lib_handle);
+ return rv;
+}
--
1.7.12.4
^ permalink raw reply related
* [PATCH 02/11] Add nodes option while creating md
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
Specifies the maximum number of nodes in the cluster that may use
this device simultaneously. This is equivalent to the number of
bitmaps created in the internal superblock (patches to follow).
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Create.c | 1 +
ReadMe.c | 1 +
mdadm.8.in | 6 ++++++
mdadm.c | 33 ++++++++++++++++++++++++++++++++-
mdadm.h | 3 +++
super1.c | 1 +
6 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/Create.c b/Create.c
index 69f5432..e4577af 100644
--- a/Create.c
+++ b/Create.c
@@ -531,6 +531,7 @@ int Create(struct supertype *st, char *mddev,
st->ss->name);
warn = 1;
}
+ st->nodes = c->nodes;
if (warn) {
if (c->runstop!= 1) {
diff --git a/ReadMe.c b/ReadMe.c
index 87a4916..30c569d 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -140,6 +140,7 @@ struct option long_options[] = {
{"homehost", 1, 0, HomeHost},
{"symlinks", 1, 0, Symlinks},
{"data-offset",1, 0, DataOffset},
+ {"nodes",1, 0, Nodes},
/* For assemble */
{"uuid", 1, 0, 'u'},
diff --git a/mdadm.8.in b/mdadm.8.in
index 2a89458..fed0007 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -971,6 +971,12 @@ However for RAID0, it is not possible to add spares. So to increase
the number of devices in a RAID0, it is necessary to set the new
number of devices, and to add the new devices, in the same command.
+.TP
+.BR \-\-nodes
+Only works when the array is for clustered environment. It specifies
+the maximum number of nodes in the cluster that will use this device
+simultaneously. If not specified, this defaults to 4.
+
.SH For assemble:
.TP
diff --git a/mdadm.c b/mdadm.c
index 3e8c49b..25d15a8 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -588,7 +588,14 @@ int main(int argc, char *argv[])
}
ident.raid_disks = s.raiddisks;
continue;
-
+ case O(CREATE, Nodes):
+ c.nodes = parse_num(optarg);
+ if (c.nodes <= 0) {
+ pr_err("invalid number for the number of cluster nodes: %s\n",
+ optarg);
+ exit(2);
+ }
+ continue;
case O(CREATE,'x'): /* number of spare (eXtra) disks */
if (s.sparedisks) {
pr_err("spare-devices set twice: %d and %s\n",
@@ -1097,6 +1104,15 @@ int main(int argc, char *argv[])
s.bitmap_file = optarg;
continue;
}
+ if (strcmp(optarg, "clustered")== 0) {
+ s.bitmap_file = optarg;
+ /* Set the default number of cluster nodes
+ * to 4 if not already set by user
+ */
+ if (c.nodes < 1)
+ c.nodes = 4;
+ continue;
+ }
/* probable typo */
pr_err("bitmap file must contain a '/', or be 'internal', or 'none'\n"
" not '%s'\n", optarg);
@@ -1377,6 +1393,21 @@ int main(int argc, char *argv[])
case CREATE:
if (c.delay == 0)
c.delay = DEFAULT_BITMAP_DELAY;
+
+ if (c.nodes) {
+ if (!s.bitmap_file || strcmp(s.bitmap_file, "clustered") != 0) {
+ pr_err("--nodes argument only compatible with --bitmap=clustered\n");
+ rv = 1;
+ break;
+ }
+
+ if (s.level != 1) {
+ pr_err("--bitmap=clustered is currently supported with RAID mirror only\n");
+ rv = 1;
+ break;
+ }
+ }
+
if (s.write_behind && !s.bitmap_file) {
pr_err("write-behind mode requires a bitmap.\n");
rv = 1;
diff --git a/mdadm.h b/mdadm.h
index 141f963..9d55801 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -344,6 +344,7 @@ enum special_options {
Dump,
Restore,
Action,
+ Nodes,
};
enum prefix_standard {
@@ -418,6 +419,7 @@ struct context {
char *backup_file;
int invalid_backup;
char *action;
+ int nodes;
};
struct shape {
@@ -1029,6 +1031,7 @@ struct supertype {
*/
int devcnt;
int retry_soon;
+ int nodes;
struct mdinfo *devs;
diff --git a/super1.c b/super1.c
index 7928a3d..78d98a7 100644
--- a/super1.c
+++ b/super1.c
@@ -2144,6 +2144,7 @@ add_internal_bitmap1(struct supertype *st,
bms->daemon_sleep = __cpu_to_le32(delay);
bms->sync_size = __cpu_to_le64(size);
bms->write_behind = __cpu_to_le32(write_behind);
+ bms->nodes = __cpu_to_le32(st->nodes);
*chunkp = chunk;
return 1;
--
1.7.12.4
^ permalink raw reply related
* [PATCH 01/11] Create n bitmaps for clustered mode
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
In-Reply-To: <1433914934-21195-1-git-send-email-gqjiang@suse.com>
For a clustered MD, create bitmaps equal to number of nodes so
each node has an independent bitmap.
Only the first bitmap is has the bits set so that the first node
that assembles the device also performs the sync.
The bitmaps are aligned to 4k boundaries.
On-disk format:
0 4k 8k 12k
-------------------------------------------------------------------
| idle | md super | bm super [0] + bits |
| bm bits[0, contd] | bm super[1] + bits | bm bits[1, contd] |
| bm super[2] + bits | bm bits [2, contd] | bm super[3] + bits |
| bm bits [3, contd] | | |
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
---
Create.c | 3 ++-
bitmap.c | 2 ++
bitmap.h | 7 +++++--
mdadm.8.in | 7 ++++++-
super1.c | 53 ++++++++++++++++++++++++++++++++++-------------------
5 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/Create.c b/Create.c
index ef28da0..69f5432 100644
--- a/Create.c
+++ b/Create.c
@@ -750,7 +750,8 @@ int Create(struct supertype *st, char *mddev,
#endif
}
- if (s->bitmap_file && strcmp(s->bitmap_file, "internal")==0) {
+ if (s->bitmap_file && (strcmp(s->bitmap_file, "internal")==0
+ || strcmp(s->bitmap_file, "clustered")==0)) {
if ((vers%100) < 2) {
pr_err("internal bitmaps not supported by this kernel.\n");
goto abort_locked;
diff --git a/bitmap.c b/bitmap.c
index b1d54a6..920033a 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -32,6 +32,8 @@ inline void sb_le_to_cpu(bitmap_super_t *sb)
sb->daemon_sleep = __le32_to_cpu(sb->daemon_sleep);
sb->sync_size = __le64_to_cpu(sb->sync_size);
sb->write_behind = __le32_to_cpu(sb->write_behind);
+ sb->nodes = __le32_to_cpu(sb->nodes);
+ sb->sectors_reserved = __le32_to_cpu(sb->sectors_reserved);
}
inline void sb_cpu_to_le(bitmap_super_t *sb)
diff --git a/bitmap.h b/bitmap.h
index c8725a3..adbf0b4 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -154,8 +154,11 @@ typedef struct bitmap_super_s {
__u32 chunksize; /* 52 the bitmap chunk size in bytes */
__u32 daemon_sleep; /* 56 seconds between disk flushes */
__u32 write_behind; /* 60 number of outstanding write-behind writes */
-
- __u8 pad[256 - 64]; /* set to zero */
+ __u32 sectors_reserved; /* 64 number of 512-byte sectors that are
+ * reserved for the bitmap. */
+ __u32 nodes; /* 68 the maximum number of nodes in cluster. */
+ __u8 cluster_name[64]; /* 72 cluster name to which this md belongs */
+ __u8 pad[256 - 136]; /* set to zero */
} bitmap_super_t;
/* notes:
diff --git a/mdadm.8.in b/mdadm.8.in
index b4a21d9..2a89458 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -694,7 +694,12 @@ and so is replicated on all devices. If the word
.B "none"
is given with
.B \-\-grow
-mode, then any bitmap that is present is removed.
+mode, then any bitmap that is present is removed. If the word
+.B "clustered"
+is given, the array is created for a clustered environment. One bitmap
+is created for each node as defined by the
+.B \-\-nodes
+parameter and are stored internally.
To help catch typing errors, the filename must contain at least one
slash ('/') if it is a real file (not 'internal' or 'none').
diff --git a/super1.c b/super1.c
index f0508fe..7928a3d 100644
--- a/super1.c
+++ b/super1.c
@@ -2177,6 +2177,7 @@ static int write_bitmap1(struct supertype *st, int fd)
void *buf;
int towrite, n;
struct align_fd afd;
+ unsigned int i = 0;
init_afd(&afd, fd);
@@ -2185,27 +2186,41 @@ static int write_bitmap1(struct supertype *st, int fd)
if (posix_memalign(&buf, 4096, 4096))
return -ENOMEM;
- memset(buf, 0xff, 4096);
- memcpy(buf, (char *)bms, sizeof(bitmap_super_t));
-
- towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
- towrite = (towrite+7) >> 3; /* bits to bytes */
- towrite += sizeof(bitmap_super_t);
- towrite = ROUND_UP(towrite, 512);
- while (towrite > 0) {
- n = towrite;
- if (n > 4096)
- n = 4096;
- n = awrite(&afd, buf, n);
- if (n > 0)
- towrite -= n;
+ do {
+ /* Only the bitmap[0] should resync
+ * whole device on initial assembly
+ */
+ if (i)
+ memset(buf, 0x00, 4096);
else
+ memset(buf, 0xff, 4096);
+ memcpy(buf, (char *)bms, sizeof(bitmap_super_t));
+
+ towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
+ towrite = (towrite+7) >> 3; /* bits to bytes */
+ towrite += sizeof(bitmap_super_t);
+ /* we need the bitmaps to be at 4k boundary */
+ towrite = ROUND_UP(towrite, 4096);
+ while (towrite > 0) {
+ n = towrite;
+ if (n > 4096)
+ n = 4096;
+ n = awrite(&afd, buf, n);
+ if (n > 0)
+ towrite -= n;
+ else
+ break;
+ if (i)
+ memset(buf, 0x00, 4096);
+ else
+ memset(buf, 0xff, 4096);
+ }
+ fsync(fd);
+ if (towrite) {
+ rv = -2;
break;
- memset(buf, 0xff, 4096);
- }
- fsync(fd);
- if (towrite)
- rv = -2;
+ }
+ } while (++i < __le32_to_cpu(bms->nodes));
free(buf);
return rv;
--
1.7.12.4
^ permalink raw reply related
* [PATCH 00/11] mdadm tool: add the support for cluster-md
From: Guoqing Jiang @ 2015-06-10 5:42 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, rgoldwyn
V4 changes:
1. update documation for syntax correct and add missed infos
2. code modification for remove duplicated code and coding style etc
3. make cluster name only appear in bitmap
4. add UUIDUpdate handling to write_bitmap0
V3 changes:
1. re-orgnize some codes to ensure mdadm compiles after each patch is applied
2. change the code for super1.c for first patch since it has side effect for
non-cluster condition
V2 changes:
1. re-arrange the squence of patches
2. add some memembers into sb_le_to_cpu
3. handle some logic change and comments from Neil
Basic background for Cluster MD: Cluster MD is a shared-device RAID for a
cluster, currently, the implementation is limited to RAID1 but with further
work (and some positive feedback), it could be extend to other RAID levels.
The kernel part code of cluster-md has been sent to maillist several month
ago by Goldywyn, and to make cluster-md works, the mdadm tools also need to
do some changes accordingly.
This patch set extends mdadm tool to aware cluster MD scenario, and handle
related cluster-md scenario.
1. the first part (0001-0007) comes from Goldwyn, which add initial
support for cluster-md, those changes included make mdadm awares nodes,
home-cluster and n bitmaps for clustered mode, also let mdadm can
confirm disk which is added by another node.
2. the second part is for support change cluster-name and node nums under
assemble mode. Which extend write-bitmap to handle above cases, and also
use the extended write_bitmap for update uuid. [PATCH V2 10/10] is just compiled
test only.
BTW: this series could be apply on top of commit "2a6493 Grow: fix a couple of typos".
Some reltated links:
[1] http://marc.info/?l=linux-raid&m=141891941330336&w=2
[2] http://marc.info/?l=linux-raid&m=141935561418770&w=2
Guoqing Jiang (11):
Create n bitmaps for clustered mode
Add nodes option while creating md
home-cluster while creating an array
Show all bitmaps while examining bitmap
Add a new clustered disk
Convert a bitmap=none device to clustered
Skip clustered devices in incremental
mdadm: add the ability to change cluster name
mdadm: change the num of cluster node
Reuse calc_bitmap_size to reduce code size
Reuse the write_bitmap for update uuid
Assemble.c | 12 ++++--
Create.c | 5 ++-
Grow.c | 12 ++++--
Incremental.c | 5 +++
Makefile | 1 +
Manage.c | 39 ++++++++++++++++--
ReadMe.c | 3 ++
bitmap.c | 71 +++++++++++++++++++--------------
bitmap.h | 7 +++-
config.c | 27 ++++++++++++-
md_p.h | 7 ++++
md_u.h | 1 +
mdadm.8.in | 42 +++++++++++++++++++-
mdadm.c | 64 ++++++++++++++++++++++++++++--
mdadm.h | 20 +++++++++-
super0.c | 15 ++++++-
super1.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++------------
util.c | 60 ++++++++++++++++++++++++++++
18 files changed, 438 insertions(+), 78 deletions(-)
--
1.7.12.4
^ permalink raw reply
* Re: [dm-devel] [PATCH] block: add a bi_error field to struct bio
From: Neil Brown @ 2015-06-10 2:50 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Jens Axboe, linux-raid, dm-devel, linux-btrfs
In-Reply-To: <1433338959-24808-2-git-send-email-hch@lst.de>
On Wed, 3 Jun 2015 15:42:39 +0200
Christoph Hellwig <hch@lst.de> wrote:
> Currently we have two different ways to signal an I/O error on a BIO:
>
> (1) by clearing the BIO_UPTODATE flag
> (2) by returning a Linux errno value to the bi_end_io callback
>
> The first one has the drawback of only communicating a single possible
> error (-EIO), and the second one has the drawback of not beeing persistent
> when bios are queued up, and are not passed along from child to parent
> bio in the ever more popular chaining scenario. Having both mechanisms
> available has the additional drawback of utterly confusing driver authors
> and introducing bugs where various I/O submitters only deal with one of
> them, and the others have to add boilerplate code to deal with both kinds
> of error returns.
>
> So add a new bi_error field to store an errno value directly in struct
> bio and remove the existing mechanisms to clean all this up.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
I really like this clean up.
It is unfortunate that the patch is so big, but I guess it has to be.
It mostly looks good, but review is hard and testing is harder :-(
I found:
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index f80f1af..1bad16f 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
....
> @@ -1800,7 +1799,7 @@ static void end_sync_write(struct bio *bio, int error)
> reschedule_retry(r1_bio);
> else {
> put_buf(r1_bio);
> - md_done_sync(mddev, s, uptodate);
> + md_done_sync(mddev, s, !bio->bi_error);
> }
> }
> }
This introduces a use-after-free. put_buf(r1_bio) can result in bio_put on
'bio'.
It is safe to move the put_buf call after the md_done_sync(), but it is
probably best to leave the 'update' variable as it. i.e. Just change:
- int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
+ int uptodate = !bio->bi_error;
I can't see any other problems with the md changes.
Reviewed-by: NeilBrown <neilb@suse.de> (md/raid parts)
Thanks,
NeilBrown
^ permalink raw reply
* Re: 4.1-rc6 radi5 OOPS
From: Neil Brown @ 2015-06-10 1:57 UTC (permalink / raw)
To: Jes Sorensen; +Cc: linux-raid, Xiao Ni
In-Reply-To: <20150610101942.0bc26a25@home.neil.brown.name>
On Wed, 10 Jun 2015 10:19:42 +1000 Neil Brown <neilb@suse.de> wrote:
> So it looks like some sort of race. I have other evidence of a race
> with the resync/reshape thread starting/stopping. If I track that
> down it'll probably fix this issue too.
I think I have found just such a race. If you request a reshape just
as a recovery completes, you can end up with two reshapes running.
This causes confusion :-)
Can you try this patch? If I can remember how to reproduce my race
I'll test it on that too.
Thanks,
NeilBrown
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 83532fe84205..03f460a1de60 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -4146,6 +4146,7 @@ static int raid10_start_reshape(struct mddev
*mddev)
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+ clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 0e49b2c94bdd..59e44e99eef3 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -7368,6 +7368,7 @@ static int raid5_start_reshape(struct mddev
*mddev)
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+ clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
mddev->sync_thread = md_register_thread(md_do_sync, mddev,
^ permalink raw reply related
* Re: 4.1-rc6 radi5 OOPS
From: Neil Brown @ 2015-06-10 0:19 UTC (permalink / raw)
To: Jes Sorensen; +Cc: linux-raid, Xiao Ni
In-Reply-To: <wrfjzj4glajs.fsf@jes.lga.redhat.com>
On Wed, 03 Jun 2015 17:57:43 -0400
Jes Sorensen <Jes.Sorensen@redhat.com> wrote:
> NeilBrown <neilb@suse.de> writes:
> > On Wed, 03 Jun 2015 16:20:21 -0400 Jes Sorensen
> > <Jes.Sorensen@redhat.com> wrote:
> >
> >> Neil,
> >>
> >> I was running testing on the current 4.1-rc6 tree (Linus' top of
> >> trunk 8cd9234c64c584432f6992fe944ca9e46ca8ea76) and I am seeing
> >> the following OOPS which is reproducible.
> >>
> >> It shows up when running the mdadm test suite, 07changelevelintr
> >> to be specific.
> >>
> >> Is this something you have seen?
> >>
> >> Cheers,
> >> Jes
> >>
> >> ------------[ cut here ]------------
> >> kernel BUG at drivers/md/raid5.c:5391!
> >
> > No, I haven't seen that. And I've been running the test suite
> > quite a bit lately.
> >
> > Can you get it to print out the relevant numbers? Include
> > readpos/writepos/safepos too.
>
> This enough? Let me know if you need more.
>
> I suspect this started happening with the changes that went in between
> 4.1-rc5 and 4.1-rc6. I will try to bisect it tomorrow.
>
> Cheers,
> Jes
>
> mddev->dev_sectors: 0x9800, reshape_sectors: 0x0200 stripe_addr:
> fffffffffffffdff, sector_nr 0, readpos 511, writepos -513, safepos
> 512
These numbers suggest that conf->reshape_progress divided by
"data_disks" or "new_data_disks" is -1 - or really the unsigned
equivalent, which is MaxSectors.
But unless data_disks is 1, ->reshape_progress must really be -2 or -3
or something.
So maybe if you could confirm the values of ->reshape_progress,
data_disks, and new_data_disks, that might help.
I don't think ->reshape_progress could get a negative value in any way
except by being assigned MaxSectors. And that only happens when the
reshape has really completely finished.
So it looks like some sort of race. I have other evidence of a race
with the resync/reshape thread starting/stopping. If I track that
down it'll probably fix this issue too.
Thanks,
NeilBrown
^ permalink raw reply
* Re: [PATCH v2 6/8] drivers/md/md.c: Use strreplace
From: Neil Brown @ 2015-06-09 21:17 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Andrew Morton, Joe Perches, Al Viro, linux-raid, linux-kernel
In-Reply-To: <1433806017-10823-7-git-send-email-linux@rasmusvillemoes.dk>
On Tue, 9 Jun 2015 01:26:54 +0200
Rasmus Villemoes <linux@rasmusvillemoes.dk> wrote:
> There's no point in starting over when we meet a '/'. This also
> eliminates a stack variable and a little .text.
>
> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> ---
> v2: no changes.
>
> drivers/md/md.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 27506302eb7a..2ea2f28551c5 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -2024,7 +2024,6 @@ static int bind_rdev_to_array(struct md_rdev
> *rdev, struct mddev *mddev) {
> char b[BDEVNAME_SIZE];
> struct kobject *ko;
> - char *s;
> int err;
>
> /* prevent duplicates */
> @@ -2070,8 +2069,7 @@ static int bind_rdev_to_array(struct md_rdev
> *rdev, struct mddev *mddev) return -EBUSY;
> }
> bdevname(rdev->bdev,b);
> - while ( (s=strchr(b, '/')) != NULL)
> - *s = '!';
> + strreplace(b, '/', '!');
>
> rdev->mddev = mddev;
> printk(KERN_INFO "md: bind<%s>\n", b);
Acked-by: NeilBrown <neilb@suse.de>
I'm happy for Andrew to merge this.
Thanks,
NeilBrown
^ permalink raw reply
* Re: [PATCH v2 0/8] Introduce strreplace
From: Andrew Morton @ 2015-06-09 21:02 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Greg Kroah-Hartman, Neil Brown, Theodore Ts'o, Andreas Dilger,
Steven Rostedt, Ingo Molnar, Joe Perches, Al Viro, linux-kernel,
linux-raid, linux-ext4
In-Reply-To: <1433806017-10823-1-git-send-email-linux@rasmusvillemoes.dk>
On Tue, 9 Jun 2015 01:26:48 +0200 Rasmus Villemoes <linux@rasmusvillemoes.dk> wrote:
> Doing single-character substitution on an entire string is open-coded
> in a few places, sometimes in a rather suboptimal way. This introduces
> a trivial helper, strreplace, for this task along with a few example
> conversions.
>
> Andrew, can I get you to take 1/8 through the mm tree? I'm not sure
> what the easiest path is for the remaining patches.
With this sort of thing I grab everything them feed the dependent
patches to maintainers after the base patch is upstream.
Or I merge the dependent patches myself if they were acked.
Or if the dependent patches are simple I'll just merge them anyway,
shrug. I'd say these fall into that category.
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Can Jeuleers @ 2015-06-09 19:18 UTC (permalink / raw)
To: Wols Lists, Pierre Wieser, linux-raid
In-Reply-To: <55773493.3050605@youngman.org.uk>
On 09/06/15 20:46, Wols Lists wrote:
> Please expand! Having read the article, it doesn't seem to say anything
> more than what is repeated time and time on this list - MAKE SURE YOUR
> DRIVES ARE DECENT RAID DRIVES.
Large RAID5 arrays are a bad idea because of the probability of
unrecoverable read errors occurring during a rebuild, which increases
with the size of the array.
Decent RAID drives will have better reliability than indecent-ones
(haha), but in absolute terms their URE rates are still going to
increase with array size.
> If you have ERC, then the odd "soft" read error doesn't matter. If you
> don't have ERC, then your data is at risk when you replace a drive, and
> it doesn't matter how big your drives are, it's the array size that matters.
Indeed. Pierre was proposing to further increase the size of his RAID5
array, and I was advising him against it because of the above.
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Roman Mamedov @ 2015-06-09 19:15 UTC (permalink / raw)
To: Pierre Wieser; +Cc: Can Jeuleers, linux-raid
In-Reply-To: <1222347192.1017.1433875572719.JavaMail.zimbra@wieser.fr>
[-- Attachment #1: Type: text/plain, Size: 840 bytes --]
On Tue, 9 Jun 2015 20:46:12 +0200 (CEST)
Pierre Wieser <pwieser@trychlos.org> wrote:
> Does linux-raid have any recommandation(s) when managing more than 10TB of data ?
>
> I may imagine:
> - several smaller RAID 5 devices
> - would RAID10 be a valuable solution in your opinion ?
The solution is called RAID6.
And don't go for overly large drives, e.g. 6x2TB is better than 4x3TB.
1) smaller drives might use more proven technology, require less precision, so
might be more reliable (at least according to hearsay and urban legends);
2) you need a considerable array member count anyway, to justify "losing" two
drives for parity in RAID6.
"But my enclosure only fits 4 drives". "But I don't have enough SATA ports".
Get a bigger enclosure. Get a second/third SATA controller. :)
--
With respect,
Roman
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Another Sillyname @ 2015-06-09 19:06 UTC (permalink / raw)
To: linux-raid
In-Reply-To: <55773493.3050605@youngman.org.uk>
If you can try to pick up a cheap IBM M1015 Raid controller that you
can configure as JBOD (look to pay no more then £50 or $75).
Flash it to the standard LSI firmware (google M1015 LSI
firmware...there's plenty of forum pages on this).
Add your new drives to this controller, build new raid on this new
controller......copy dataset from old array.
I personally would NEVER suggest doing a migrate of drives or data
sizes on an active live dataset...if anything goes wrong you could
easily kill your data and have no backup.
On 9 June 2015 at 19:46, Wols Lists <antlists@youngman.org.uk> wrote:
> On 09/06/15 06:23, Can Jeuleers wrote:
>> On 08/06/15 21:28, Pierre Wieser wrote:
>>> Hi all,
>>>
>>> I currently have an almost full RAID 5 built with 4 x 2 TB disks.
>>> I wonder if it would be possible to migrate it to a bigger RAID 5
>>> with 3 x 6TB new disks.
>>
>> I'd recommend against it:
>>
>> https://en.wikipedia.org/wiki/RAID#Unrecoverable_read_errors_during_rebuild
>>
>> Jan
>>
> Please expand! Having read the article, it doesn't seem to say anything
> more than what is repeated time and time on this list - MAKE SURE YOUR
> DRIVES ARE DECENT RAID DRIVES.
>
> If you have ERC, then the odd "soft" read error doesn't matter. If you
> don't have ERC, then your data is at risk when you replace a drive, and
> it doesn't matter how big your drives are, it's the array size that matters.
>
> Cheers,
> Wol
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Wols Lists @ 2015-06-09 19:06 UTC (permalink / raw)
To: Pierre Wieser, Can Jeuleers; +Cc: linux-raid
In-Reply-To: <1222347192.1017.1433875572719.JavaMail.zimbra@wieser.fr>
On 09/06/15 19:46, Pierre Wieser wrote:
> ---- Original Message -----
>> On 08/06/15 21:28, Pierre Wieser wrote:
>>> Hi all,
>>>
>>> I currently have an almost full RAID 5 built with 4 x 2 TB disks.
>>> I wonder if it would be possible to migrate it to a bigger RAID 5
>>> with 3 x 6TB new disks.
>>
>> I'd recommend against it:
>>
>> https://en.wikipedia.org/wiki/RAID#Unrecoverable_read_errors_during_rebuild
>
> Oop's! I was not conscious at all of this issue. It happens that I am currenly
> living dangerously as I have another RAID 5 11,5 TB device :( I had already
> seen various administration issues when the size increases to this level, but
> I tought this was only an issue regarding the volumes organization (not tought
> deeply enough, obviously)....
>
> Starting from your link, and searching a bit, I understand now that the 10TB
> is a maximal limit for desktop-grade disks (regarding the URE at least). And
> thus for any element of a RAID device which needs to be scanned at recovery
> time.
> Apart from my poor english, would you say I'm right with this ?
I don't think so. You may be lucky, and your drives are better than
average. You may be unlucky, and your drives are worse than average.
DON'T USE DESKTOP GRADE DISKS EXCEPT IN RAID 1. That said, I'm using
Seagate Barracudas which I was planning to upgrade to raid 5 - not a
good idea :-(
>
> Does linux-raid have any recommandation(s) when managing more than 10TB of data ?
>
> I may imagine:
> - several smaller RAID 5 devices
> - would RAID10 be a valuable solution in your opinion ?
Read the list archive. There's a bunch of stuff about how to mitigate
the problem - mostly by increasing the raid timeout (the problem is,
basically, that the raid software returns with an error before the disk
times out - increase the raid timeout and it will detect the disk error
and retry).
>
> (as a precision, all my servers have been migrated to CentOS 7.1)
>
> Nonetheless, I thank you very much for the link, which may prevent me to
> lose a big bunch of data !
>
"man smartctl" is your friend :-)
You'll have to read up, but try
"smartctl -i /dev/sdx"
That'll tell you if smart is turned on - if it isn't, turn it on.
"smartctl -s on /dev/sdx"
Then do
"smartctl -x /dev/sdx"
and look for anything about ERC or Error Recovery Control. From my
Barracudas I get
SCT Data Table command not supported
SCT Error Recovery Control command not supported
Device Statistics (GP Log 0x04) not supported
OOPS!!! These drives are NOT NOT NOT suitable for raid :-( Everything
will be fine if I increase the raid timeout, but given that the typical
drive timeout is two minutes, the raid timeout needs to be longer than
that which means if I have any soft errors, the rebuild will be horribly
slow.
Looks like my next drives will be WD Reds, they're not much more expensive.
WARNING: If you have to enable smartctl, it's supposed to survive a
cold-boot, but it doesn't look like it has on my drives, and it's
reported a lot of drives don't. You need to make sure you have a boot
script that forces it on, and forces ERC on or sets the timeout.
All that said, as you can see, desktop drives are fine for raid IF
repeat IF you take the necessary precautions. They're probably fine on a
desktop :-)
Cheers,
Wol
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Wols Lists @ 2015-06-09 18:46 UTC (permalink / raw)
To: Can Jeuleers, Pierre Wieser, linux-raid
In-Reply-To: <55767860.5000803@gmail.com>
On 09/06/15 06:23, Can Jeuleers wrote:
> On 08/06/15 21:28, Pierre Wieser wrote:
>> Hi all,
>>
>> I currently have an almost full RAID 5 built with 4 x 2 TB disks.
>> I wonder if it would be possible to migrate it to a bigger RAID 5
>> with 3 x 6TB new disks.
>
> I'd recommend against it:
>
> https://en.wikipedia.org/wiki/RAID#Unrecoverable_read_errors_during_rebuild
>
> Jan
>
Please expand! Having read the article, it doesn't seem to say anything
more than what is repeated time and time on this list - MAKE SURE YOUR
DRIVES ARE DECENT RAID DRIVES.
If you have ERC, then the odd "soft" read error doesn't matter. If you
don't have ERC, then your data is at risk when you replace a drive, and
it doesn't matter how big your drives are, it's the array size that matters.
Cheers,
Wol
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Pierre Wieser @ 2015-06-09 18:46 UTC (permalink / raw)
To: Can Jeuleers; +Cc: linux-raid
In-Reply-To: <55767860.5000803@gmail.com>
---- Original Message -----
> On 08/06/15 21:28, Pierre Wieser wrote:
> > Hi all,
> >
> > I currently have an almost full RAID 5 built with 4 x 2 TB disks.
> > I wonder if it would be possible to migrate it to a bigger RAID 5
> > with 3 x 6TB new disks.
>
> I'd recommend against it:
>
> https://en.wikipedia.org/wiki/RAID#Unrecoverable_read_errors_during_rebuild
Oop's! I was not conscious at all of this issue. It happens that I am currenly
living dangerously as I have another RAID 5 11,5 TB device :( I had already
seen various administration issues when the size increases to this level, but
I tought this was only an issue regarding the volumes organization (not tought
deeply enough, obviously)....
Starting from your link, and searching a bit, I understand now that the 10TB
is a maximal limit for desktop-grade disks (regarding the URE at least). And
thus for any element of a RAID device which needs to be scanned at recovery
time.
Apart from my poor english, would you say I'm right with this ?
Does linux-raid have any recommandation(s) when managing more than 10TB of data ?
I may imagine:
- several smaller RAID 5 devices
- would RAID10 be a valuable solution in your opinion ?
(as a precision, all my servers have been migrated to CentOS 7.1)
Nonetheless, I thank you very much for the link, which may prevent me to
lose a big bunch of data !
> Jan
>
Pierre
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Pierre Wieser @ 2015-06-09 18:33 UTC (permalink / raw)
To: Wols Lists; +Cc: linux-raid
In-Reply-To: <5575F6B2.6030802@youngman.org.uk>
----- Original Message -----
> On 08/06/15 20:28, Pierre Wieser wrote:
> > Hi all,
> >
> > I currently have an almost full RAID 5 built with 4 x 2 TB disks.
> > I wonder if it would be possible to migrate it to a bigger RAID 5
> > with 3 x 6TB new disks.
> >
> Do you have a spare (I presume SATA) disk port?
I am away from home this evening, but, no, I do not "see" any free sata port.
> > I've imagined something like that :
> > - successively fail, remove a 2TB disk, add a 4TB disk, wait for end of
> > recovery on three 2TB disks
>
> If you've got a spare port, the newer mdadm's have, I believe, a "clone
> and replace" option. Much better than failing then rebuilding.
I was not conscious of this option. I understand that it is better because
this prevents me to pass through a "clean, degraded" state ? As I expect that
the clone time will be identical the a recovery one ?
> If not, is it worth getting a SATA expansion board? If you've not got a
> specialist mobo, surely a board is only going to cost a tenner or so,
> and quality isn't *that* important seeing as it's only a temporary measure.
Yes, you're right: it might be worth to purchase another sata controller,
as I have PCI-e free ports, enough alimentation. Maybe a small issue at
disk enclosure level. To be checked...
> > - at the end of this first phase, I have the same ~6TB RAID 5 clean group
> > with 3 x 4TB + 1 x 2TB disks
> > - declare the last 2 TB disk faulty and remove it
> > - the RAID 5 group state goes to clean, degraded
> > - grow the RAID 5 group with --size=max option
> > - grow the RAID 5 group with --array-size=~12TB option
> > - last, grow the RAID 5 group with --raid-devices=3 and --backup-file=...
> > options.
> >
> > And I have tested it on a small test RAID 5 group.
> > As expected, this last command makes the RAID 5 group begins a reshaping
> > operation.
> > But this one keeps stucked at zero.
> >
> > So I have several questions :
> >
> Don't think I've answered any of them, but I might have raised new ones.
> I just hope the tip saves you a bit of time.
Surely you have opened new pistes. Thanks.
> Cheers,
> Wol
>
>
^ permalink raw reply
* Re: Migrating a RAID 5 from 4x2TB to 3x6TB ?
From: Pierre Wieser @ 2015-06-09 18:26 UTC (permalink / raw)
To: Another Sillyname, linux-raid
In-Reply-To: <CAOS+5GHzBgx2DuDe0+RLgZj9Q1BZ944i-9q4NEERq66Sk78b2g@mail.gmail.com>
----- Original Message -----
> I assume the motherboard you're using only has 4 sata ports?
Yes, the motherboard has 4 sata ports, and there is already a small external
sata controller. So my actual raid device has 5 disks (4+S). For the discussion,
I just omitted the spare device ;)
> On 8 June 2015 at 20:28, Pierre Wieser <pwieser@trychlos.org> wrote:
> > Hi all,
> >
> > I currently have an almost full RAID 5 built with 4 x 2 TB disks.
> > I wonder if it would be possible to migrate it to a bigger RAID 5
> > with 3 x 6TB new disks.
^ permalink raw reply
* Re: Thanks for responding
From: aswamina @ 2015-06-09 15:17 UTC (permalink / raw)
To: r.gsvaso@yahoo.com.ph
Hi,
I am diagnosed with laryngeal cancer, I' want to give my money to you & my body to science. Respond with this ref SvaSo so I know you got this.
Ruby
^ permalink raw reply
* Re: [PATCH v2 0/8] Introduce strreplace
From: Rasmus Villemoes @ 2015-06-09 7:25 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Andrew Morton, Greg Kroah-Hartman, Neil Brown, Andreas Dilger,
Steven Rostedt, Ingo Molnar, Joe Perches, Al Viro, linux-kernel,
linux-raid, linux-ext4
In-Reply-To: <20150609005554.GP19168@thunk.org>
On Tue, Jun 09 2015, Theodore Ts'o <tytso@mit.edu> wrote:
> On Tue, Jun 09, 2015 at 01:26:48AM +0200, Rasmus Villemoes wrote:
>> Doing single-character substitution on an entire string is open-coded
>> in a few places, sometimes in a rather suboptimal way. This introduces
>> a trivial helper, strreplace, for this task along with a few example
>> conversions.
>>
>> Andrew, can I get you to take 1/8 through the mm tree? I'm not sure
>> what the easiest path is for the remaining patches.
>
> This is not super urgent, right?
Right, not urgent at all.
> So we could let 1/8 go into mainline, and then the rest of the patches
> could go in the next release. That would be the simplest, although it
> would drag out how long it would take for strreplace to be used
> everywhere.
Sure, though it would be a little weird to have a helper with no users
until 4.3 comes out.
Rasmus
^ permalink raw reply
* Re: Reshape of RAID5 array from 3 to 4 disks frozen
From: Vilhelm von Ehrenheim @ 2015-06-09 7:07 UTC (permalink / raw)
To: David Wahler; +Cc: linux-raid
In-Reply-To: <CAGivzjHHm=faBv_+12ZMKE3=Se=tbja8uLJ1P6xvcMO2kgPYbQ@mail.gmail.com>
Hi again!
Thank you so much for this! Really cool. I patched the kernel changing
the line as you said and now the reshape is now continuing. Holding my
breath that it will finish but all looks ok so far.
I needed to change the patch a little as it was for an older kernel so
the lines changed a bit. This is what i used for linux 4.0.5:
--- a/drivers/md/raid5.c 2015-06-08 23:05:02.808214213 +0200
+++ b/drivers/md/raid5.c 2015-06-08 23:05:47.601355604 +0200
@@ -3855,7 +3855,7 @@
*/
if (s.failed > conf->max_degraded) {
sh->check_state = 0;
- sh->reconstruct_state = 0;
+ //sh->reconstruct_state = 0;
if (s.to_read+s.to_write+s.written)
handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
if (s.syncing + s.replacing)
Thank you again. :)
/ Vilhelm
On Mon, Jun 8, 2015 at 9:31 AM, David Wahler <dwahler@gmail.com> wrote:
> On Mon, Jun 8, 2015 at 1:19 AM, Vilhelm von Ehrenheim
> <vonehrenheim@gmail.com> wrote:
>> One thing that is strange and that seem to be connected to the reshape
>> is this error, present in dmesg:
>>
>> [ 360.625322] INFO: task md0_reshape:126 blocked for more than 120 seconds.
>> [ 360.625351] Not tainted 4.0.4-2-ARCH #1
>> [ 360.625367] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>> disables this message.
>> [ 360.625394] md0_reshape D ffff88040af57a58 0 126
>> 2 0x00000000
>> [ 360.625397] ffff88040af57a58 ffff88040cf58000 ffff8800da535b20
>> 00000001642a9888
>> [ 360.625399] ffff88040af57fd8 ffff8800da429000 ffff8800da429008
>> ffff8800da429208
>> [ 360.625401] 0000000096400e00 ffff88040af57a78 ffffffff81576707
>> ffff8800da429000
>> [ 360.625403] Call Trace:
>> [ 360.625410] [<ffffffff81576707>] schedule+0x37/0x90
>> [ 360.625428] [<ffffffffa0120de9>] get_active_stripe+0x5c9/0x760 [raid456]
>> [ 360.625432] [<ffffffff810b6c70>] ? wake_atomic_t_function+0x60/0x60
>> [ 360.625436] [<ffffffffa01246e0>] reshape_request+0x5b0/0x980 [raid456]
>> [ 360.625439] [<ffffffff81579053>] ? schedule_timeout+0x123/0x250
>> [ 360.625443] [<ffffffffa011743f>] sync_request+0x28f/0x400 [raid456]
>> [ 360.625449] [<ffffffffa00da486>] ? is_mddev_idle+0x136/0x170 [md_mod]
>> [ 360.625454] [<ffffffffa00de4ba>] md_do_sync+0x8ba/0xe70 [md_mod]
>> [ 360.625457] [<ffffffff81576002>] ? __schedule+0x362/0xa30
>> [ 360.625462] [<ffffffffa00d9e54>] md_thread+0x144/0x150 [md_mod]
>> [ 360.625464] [<ffffffff810b6c70>] ? wake_atomic_t_function+0x60/0x60
>> [ 360.625468] [<ffffffffa00d9d10>] ? md_start_sync+0xf0/0xf0 [md_mod]
>> [ 360.625471] [<ffffffff81093418>] kthread+0xd8/0xf0
>> [ 360.625473] [<ffffffff81093340>] ? kthread_worker_fn+0x170/0x170
>> [ 360.625476] [<ffffffff8157a398>] ret_from_fork+0x58/0x90
>> [ 360.625478] [<ffffffff81093340>] ? kthread_worker_fn+0x170/0x170
>>
>>
>> Also, looking at CPU usage md0_raid5 seems to be having problems as it
>> is stuck on 100% CPU on one core:
>>
>> PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
>> 125 root 20 0 0.0m 0.0m 100.0 0.0 35:57.44 R `- md0_raid5
>> 126 root 20 0 0.0m 0.0m 0.0 0.0 0:00.06 D `- md0_reshape
>>
>> Could this be why the reshape has stopped?
>>
>> Can I do something to get it going again or Is it possible to revert
>> to using 3 drives again without losing data? The data is not super
>> important, hence no backup solution, but it would mean a lot of lost
>> work.
>>
>> I'm thankful for any help I can get. Not sure what to do now.
>
> Hi Vilhelm,
>
> I ran into this exact situation several weeks ago. Fortunately Neil
> Brown was able to track it down; it turns out that the reshape
> operation can get stuck if it encounters bad blocks. See
> http://article.gmane.org/gmane.linux.raid/48673
>
> You can try applying the kernel patch from that message as a temporary
> hack to allow the reshape to complete. It worked fine for me, aside
> from a small amount of filesystem corruption that was fixable with
> fsck.
>
> -- David
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox