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>
This commit is contained in:
Guoqing Jiang 2015-06-10 13:42:06 +08:00 committed by NeilBrown
parent 529e2aa573
commit 7716570e6d
9 changed files with 122 additions and 3 deletions

View File

@ -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) {

View File

@ -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 =

View File

@ -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'},

View File

@ -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();

View File

@ -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

17
mdadm.c
View File

@ -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);

View File

@ -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))

View File

@ -2054,7 +2054,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;
@ -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;

57
util.c
View File

@ -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
@ -1976,3 +1985,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;
}