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:
parent
529e2aa573
commit
7716570e6d
1
Create.c
1
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) {
|
||||
|
|
6
Makefile
6
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 =
|
||||
|
|
1
ReadMe.c
1
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'},
|
||||
|
|
27
config.c
27
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();
|
||||
|
|
|
@ -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
17
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);
|
||||
|
|
5
mdadm.h
5
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))
|
||||
|
|
5
super1.c
5
super1.c
|
@ -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
57
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue