File 0003-Set-home-cluster-while-creating-an-array.patch of Package mdadm
From 2d4c0988133480cd015a031292e42d3ff04a3c61 Mon Sep 17 00:00:00 2001
From: Guoqing Jiang <gqjiang@suse.com>
Date: Wed, 10 Jun 2015 13:42:06 +0800
Subject: [PATCH 03/11] Set home-cluster while creating an array
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.
neilb: allow code to compile when corosync-devel is not installed.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
Create.c | 1 +
Makefile | 6 +++++-
ReadMe.c | 1 +
config.c | 27 ++++++++++++++++++++++++++-
mdadm.8.in | 6 ++++++
mdadm.c | 17 +++++++++++++++++
mdadm.h | 5 +++++
super1.c | 5 ++++-
util.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 122 insertions(+), 3 deletions(-)
diff --git a/Create.c b/Create.c
index c967120..01afb97 100644
--- a/Create.c
+++ b/Create.c
@@ -539,6 +539,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 1a4a5dc..e3b6529 100644
--- a/Makefile
+++ b/Makefile
@@ -79,10 +79,13 @@ MDMON_DIR = $(RUN_DIR)
# place for autoreplace cookies
FAILED_SLOTS_DIR = $(RUN_DIR)/failed-slots
SYSTEMD_DIR=/lib/systemd/system
+
+COROSYNC:=$(shell [ -d /usr/include/corosync ] || echo -DNO_COROSYNC)
+
DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\"
DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\"
DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
-CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS)
+CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS) $(COROSYNC)
VERSION = $(shell [ -d .git ] && git describe HEAD | sed 's/mdadm-//')
VERS_DATE = $(shell [ -d .git ] && date --date="`git log -n1 --format=format:%cd --date=short`" '+%0dth %B %Y' | sed -e 's/1th/1st/' -e 's/2th/2nd/' -e 's/11st/11th/' -e 's/12nd/12th/')
@@ -101,6 +104,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 dd7a1ad..80f2be8 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -143,6 +143,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 a35807c..b6b17bc 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",
@@ -559,6 +560,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";
@@ -721,6 +737,9 @@ void conf_file(FILE *f)
case Homehost:
homehostline(line);
break;
+ case HomeCluster:
+ homeclusterline(line);
+ break;
case AutoMode:
autoline(line);
break;
@@ -881,6 +900,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 d8bcf05..db0d06f 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 40d56cb..3235ff4 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -615,6 +615,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",
@@ -1309,6 +1316,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 434ce4d..80a1073 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -346,6 +346,7 @@ enum special_options {
Restore,
Action,
Nodes,
+ ClusterName,
};
enum prefix_standard {
@@ -421,6 +422,7 @@ struct context {
int invalid_backup;
char *action;
int nodes;
+ char *homecluster;
};
struct shape {
@@ -1033,6 +1035,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 43ee1a0..fa1b356 100644
--- a/super1.c
+++ b/super1.c
@@ -2071,7 +2071,7 @@ add_internal_bitmap1(struct supertype *st,
bbl_size = -bbl_offset;
if (!may_change || (room < 3*2 &&
- __le32_to_cpu(sb->max_dev) <= 384)) {
+ __le32_to_cpu(sb->max_dev) <= 384)) {
room = 3*2;
offset = 1*2;
bbl_size = 0;
@@ -2158,6 +2158,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 7937eb6..f7d902f 100644
--- a/util.c
+++ b/util.c
@@ -34,6 +34,15 @@
#include <ctype.h>
#include <dirent.h>
#include <signal.h>
+#include <dlfcn.h>
+#include <stdint.h>
+#ifdef NO_COROSYNC
+ typedef uint64_t cmap_handle_t;
+ #define CS_OK 1
+#else
+ #include <corosync/cmap.h>
+#endif
+
/*
* following taken from linux/blkpg.h because they aren't
@@ -1968,3 +1977,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