1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-13 11:33:16 +03:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Alasdair Kergon
87ef173e0a update pofile 2005-01-21 18:51:48 +00:00
Alasdair Kergon
52a3fb6bc7 pre-release 2005-01-21 18:49:06 +00:00
Patrick Caulfield
92e2a257a6 Get rid of libclvm as it's out-of-date and not used at all. 2005-01-21 11:56:30 +00:00
Patrick Caulfield
32e175752c Fix clvmd startup bug introduced in cman/gulm amalgamation. bz#145729
Improve reporting of node-specific locking errors so you'll get
somthing a little more helpfiul than "host is down" - it will now tell
you /which/ host it thinks is down.
2005-01-21 11:35:24 +00:00
Alasdair Kergon
d43f7180dc Update clvmd_init_rhel4: use lvm.static and don't load dlm. 2005-01-20 22:16:55 +00:00
Alasdair Kergon
0129c2b0fc Fix some size_t printing. 2005-01-20 18:14:04 +00:00
Alasdair Kergon
4ed1990001 Fix 64 bit xlate consts. 2005-01-20 18:13:17 +00:00
Alasdair Kergon
5bd6ab27ae Split out pool sptype_names to avoid unused const. 2005-01-20 18:12:41 +00:00
Alasdair Kergon
f3593b89fa Always fail if random id generation fails. 2005-01-20 18:11:53 +00:00
Alasdair Kergon
23d84b2310 Recognise gnbd. 2005-01-19 18:56:01 +00:00
Alasdair Kergon
fdc49402ec fix clvmd lv_info_by_lvid open_count 2005-01-19 18:10:09 +00:00
Alasdair Kergon
5457c133e1 Add some comments. 2005-01-19 17:31:51 +00:00
Alasdair Kergon
292e588ee3 move recover_vg 2005-01-19 17:30:50 +00:00
Alasdair Kergon
243494c25e Store snapshot and origin sizes separately. 2005-01-19 17:19:39 +00:00
Alasdair Kergon
e4365f3706 Update vgcreate man page. 2005-01-19 17:01:18 +00:00
Alasdair Kergon
310f3038d3 Post-2.01.00 2005-01-17 20:45:05 +00:00
Alasdair Kergon
4e6033273d update po 2005-01-17 20:16:37 +00:00
Alasdair Kergon
73718586d3 2.01.00 2005-01-17 20:13:01 +00:00
Alasdair Kergon
011abe61e8 post-1.01.00 2005-01-17 20:12:12 +00:00
Alasdair Kergon
fe3a37f89d 1.01.00 2005-01-17 20:00:28 +00:00
Alasdair Kergon
8aea44e77b Fix vgscan metadata auto-correction. 2005-01-17 18:24:28 +00:00
Patrick Caulfield
5529aec0d6 You can now build clvmd with cman & gulm support in the same binary.
./configure --with-clvmd
wil do this by default. Or you can choose which you want with
./configure --with-clvmd=gulm    or
./configure --with-clvmd=cman

When clvmd with both included is run, it will automatically detect the cluster
manager in use.
2005-01-13 13:24:02 +00:00
Alasdair Kergon
369549d23f Only ask libdevmapper for open_count when we need it. 2005-01-12 22:58:21 +00:00
54 changed files with 2690 additions and 2012 deletions

View File

@@ -1 +1 @@
2.00.34-cvs (2005-01-07) 2.01.02-cvs (2005-01-21)

View File

@@ -1,6 +1,26 @@
Version 2.00.34 - Version 2.01.02 - 21st January 2005
================================== ===================================
Update clvmd_init_rhel4: use lvm.static and don't load dlm.
Fix some size_t printing.
Fix 64 bit xlate consts.
Split out pool sptype_names to avoid unused const.
Always fail if random id generation fails.
Recognise gnbd devices.
Fix clvmd startup bug introduced in cman/gulm amalgamation.
Improve reporting of node-specific locking errors.
Version 2.01.01 - 19th January 2005
===================================
Fix clvmd lv_info_by_lvid open_count.
Store snapshot and origin sizes separately.
Update vgcreate man page.
Version 2.01.00 - 17th January 2005
===================================
Fix vgscan metadata auto-correction.
Only ask libdevmapper for open_count when we need it.
Adjust RHEL4 clvmd init script priority. Adjust RHEL4 clvmd init script priority.
Enable building of CMAN & GULM versions of clvmd into a single binary
Version 2.00.33 - 7th January 2005 Version 2.00.33 - 7th January 2005
================================== ==================================

View File

@@ -1,5 +1,8 @@
Version 1.01.00 - Version 1.01.01 -
============================ =============================
Version 1.01.00 - 17 Jan 2005
=============================
Add dm_task_no_open_count() to skip getting open_count. Add dm_task_no_open_count() to skip getting open_count.
Version 1.00.21 - 7 Jan 2005 Version 1.00.21 - 7 Jan 2005

2457
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -281,12 +281,12 @@ AC_MSG_RESULT($SELINUX)
dnl -- Build cluster LVM daemon dnl -- Build cluster LVM daemon
AC_MSG_CHECKING(whether to build cluster LVM daemon) AC_MSG_CHECKING(whether to build cluster LVM daemon)
AC_ARG_WITH(clvmd, AC_ARG_WITH(clvmd,
[ --with-clvmd=TYPE Build cluster LVM Daemon: cman/gulm/none [ --with-clvmd=TYPE Build cluster LVM Daemon: cman/gulm/none/all
[TYPE=none] ], [TYPE=none] ],
[ CLVMD="$withval" ], [ CLVMD="$withval" ],
[ CLVMD="none" ]) [ CLVMD="none" ])
if test x$CLVMD = xyes; then if test x$CLVMD = xyes; then
CLVMD=cman CLVMD=all
fi fi
AC_MSG_RESULT($CLVMD) AC_MSG_RESULT($CLVMD)
@@ -481,7 +481,7 @@ if test x$READLINE = xyes; then
AC_CHECK_HEADERS(readline/readline.h readline/history.h,,AC_MSG_ERROR(bailing out)) AC_CHECK_HEADERS(readline/readline.h readline/history.h,,AC_MSG_ERROR(bailing out))
fi fi
if test x$CLVMD = xyes; then if test x$CLVMD != xnone; then
AC_CHECK_HEADERS(mntent.h netdb.h netinet/in.h pthread.h search.h sys/mount.h sys/socket.h sys/uio.h sys/un.h utmpx.h,,AC_MSG_ERROR(bailing out)) AC_CHECK_HEADERS(mntent.h netdb.h netinet/in.h pthread.h search.h sys/mount.h sys/socket.h sys/uio.h sys/un.h utmpx.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(dup2 getmntent memmove select socket,,AC_MSG_ERROR(bailing out)) AC_CHECK_FUNCS(dup2 getmntent memmove select socket,,AC_MSG_ERROR(bailing out))
AC_FUNC_GETMNTENT AC_FUNC_GETMNTENT

View File

@@ -18,19 +18,32 @@ VPATH = @srcdir@
SOURCES = \ SOURCES = \
clvmd-command.c \ clvmd-command.c \
clvmd.c \ clvmd.c \
libclvm.c \
lvm-functions.c \ lvm-functions.c \
system-lv.c system-lv.c
ifeq ("@CLVMD@", "gulm") ifeq ("@CLVMD@", "gulm")
GULM = yes
endif
ifeq ("@CLVMD@", "cman")
CMAN = yes
endif
ifeq ("@CLVMD@", "all")
GULM = yes
CMAN = yes
endif
ifeq ("$(GULM)", "yes")
SOURCES += clvmd-gulm.c tcp-comms.c SOURCES += clvmd-gulm.c tcp-comms.c
LMLIBS += -lccs -lgulm LMLIBS += -lccs -lgulm
CFLAGS += -DUSE_GULM CFLAGS += -DUSE_GULM
endif endif
ifeq ("@CLVMD@", "cman") ifeq ("$(CMAN)", "yes")
SOURCES += clvmd-cman.c SOURCES += clvmd-cman.c
LMLIBS += -ldlm LMLIBS += -ldlm
CFLAGS += -DUSE_CMAN
endif endif
TARGETS = \ TARGETS = \

View File

@@ -43,6 +43,7 @@ struct clvm_header {
/* Flags */ /* Flags */
#define CLVMD_FLAG_LOCAL 1 /* Only do this on the local node */ #define CLVMD_FLAG_LOCAL 1 /* Only do this on the local node */
#define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */ #define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */
#define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */
/* Name of the local socket to communicate between libclvm and clvmd */ /* Name of the local socket to communicate between libclvm and clvmd */
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd"; //static const char CLVMD_SOCKNAME[]="/var/run/clvmd";

View File

@@ -66,7 +66,7 @@ struct lock_wait {
struct dlm_lksb lksb; struct dlm_lksb lksb;
}; };
int init_cluster() static int _init_cluster(void)
{ {
struct sockaddr_cl saddr; struct sockaddr_cl saddr;
int port = CLUSTER_PORT_CLVMD; int port = CLUSTER_PORT_CLVMD;
@@ -74,7 +74,7 @@ int init_cluster()
/* Open the cluster communication socket */ /* Open the cluster communication socket */
cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
if (cluster_sock == -1) { if (cluster_sock == -1) {
syslog(LOG_ERR, "Can't open cluster manager socket: %m"); syslog(LOG_ERR, "Can't open cman cluster manager socket: %m");
return -1; return -1;
} }
@@ -104,18 +104,23 @@ int init_cluster()
return 0; return 0;
} }
int get_main_cluster_fd() static void _cluster_init_completed(void)
{
clvmd_cluster_init_completed();
}
static int _get_main_cluster_fd()
{ {
return cluster_sock; return cluster_sock;
} }
int get_num_nodes() static int _get_num_nodes()
{ {
return num_nodes; return num_nodes;
} }
/* send_message with the fd check removed */ /* send_message with the fd check removed */
int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext) static int _cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
{ {
struct iovec iov[2]; struct iovec iov[2];
struct msghdr msg; struct msghdr msg;
@@ -135,7 +140,7 @@ int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
if (csid) { if (csid) {
msg.msg_name = &saddr; msg.msg_name = &saddr;
msg.msg_namelen = sizeof(saddr); msg.msg_namelen = sizeof(saddr);
memcpy(&saddr.scl_nodeid, csid, MAX_CSID_LEN); memcpy(&saddr.scl_nodeid, csid, CMAN_MAX_CSID_LEN);
} else { /* Cluster broadcast */ } else { /* Cluster broadcast */
msg.msg_name = NULL; msg.msg_name = NULL;
@@ -151,26 +156,26 @@ int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
return len; return len;
} }
void get_our_csid(char *csid) static void _get_our_csid(char *csid)
{ {
int i; int i;
memset(csid, 0, MAX_CSID_LEN); memset(csid, 0, CMAN_MAX_CSID_LEN);
for (i = 0; i < num_nodes; i++) { for (i = 0; i < num_nodes; i++) {
if (nodes[i].us) if (nodes[i].us)
memcpy(csid, &nodes[i].node_id, MAX_CSID_LEN); memcpy(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN);
} }
} }
/* Call a callback routine for each node that known (down mean not running a clvmd) */ /* Call a callback routine for each node that known (down mean not running a clvmd) */
int cluster_do_node_callback(struct local_client *client, static int _cluster_do_node_callback(struct local_client *client,
void (*callback) (struct local_client *, char *, void (*callback) (struct local_client *, char *,
int)) int))
{ {
int i; int i;
int somedown = 0; int somedown = 0;
for (i = 0; i < get_num_nodes(); i++) { for (i = 0; i < _get_num_nodes(); i++) {
callback(client, (char *)&nodes[i].node_id, node_updown[nodes[i].node_id]); callback(client, (char *)&nodes[i].node_id, node_updown[nodes[i].node_id]);
if (!node_updown[nodes[i].node_id]) if (!node_updown[nodes[i].node_id])
somedown = -1; somedown = -1;
@@ -202,7 +207,7 @@ static void process_oob_msg(char *buf, int len, int nodeid)
} }
} }
int cluster_fd_callback(struct local_client *client, char *buf, int len, char *csid, static int _cluster_fd_callback(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client) struct local_client **new_client)
{ {
struct iovec iov[2]; struct iovec iov[2];
@@ -254,7 +259,7 @@ int cluster_fd_callback(struct local_client *client, char *buf, int len, char *c
return len; return len;
} }
void add_up_node(char *csid) static void _add_up_node(char *csid)
{ {
/* It's up ! */ /* It's up ! */
int nodeid = nodeid_from_csid(csid); int nodeid = nodeid_from_csid(csid);
@@ -278,7 +283,7 @@ void add_up_node(char *csid)
DEBUGLOG("Added new node %d to updown list\n", nodeid); DEBUGLOG("Added new node %d to updown list\n", nodeid);
} }
void cluster_closedown() static void _cluster_closedown()
{ {
unlock_all(); unlock_all();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
@@ -307,7 +312,7 @@ static int is_listening(int nodeid)
/* Populate the list of CLVMDs running. /* Populate the list of CLVMDs running.
called only at startup time */ called only at startup time */
void count_clvmds_running(void) static void count_clvmds_running(void)
{ {
int i; int i;
@@ -366,13 +371,13 @@ static void get_members()
} }
/* Convert a node name to a CSID */ /* Convert a node name to a CSID */
int csid_from_name(char *csid, char *name) static int _csid_from_name(char *csid, char *name)
{ {
int i; int i;
for (i = 0; i < num_nodes; i++) { for (i = 0; i < num_nodes; i++) {
if (strcmp(name, nodes[i].name) == 0) { if (strcmp(name, nodes[i].name) == 0) {
memcpy(csid, &nodes[i].node_id, MAX_CSID_LEN); memcpy(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN);
return 0; return 0;
} }
} }
@@ -380,12 +385,12 @@ int csid_from_name(char *csid, char *name)
} }
/* Convert a CSID to a node name */ /* Convert a CSID to a node name */
int name_from_csid(char *csid, char *name) static int _name_from_csid(char *csid, char *name)
{ {
int i; int i;
for (i = 0; i < num_nodes; i++) { for (i = 0; i < num_nodes; i++) {
if (memcmp(csid, &nodes[i].node_id, MAX_CSID_LEN) == 0) { if (memcmp(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN) == 0) {
strcpy(name, nodes[i].name); strcpy(name, nodes[i].name);
return 0; return 0;
} }
@@ -396,7 +401,7 @@ int name_from_csid(char *csid, char *name)
} }
/* Convert a node ID to a node name */ /* Convert a node ID to a node name */
int name_from_nodeid(int nodeid, char *name) static int name_from_nodeid(int nodeid, char *name)
{ {
int i; int i;
@@ -416,12 +421,12 @@ static int nodeid_from_csid(char *csid)
{ {
int nodeid; int nodeid;
memcpy(&nodeid, csid, MAX_CSID_LEN); memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
return nodeid; return nodeid;
} }
int is_quorate() static int _is_quorate()
{ {
return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0); return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0);
} }
@@ -435,7 +440,7 @@ static void sync_ast_routine(void *arg)
pthread_mutex_unlock(&lwait->mutex); pthread_mutex_unlock(&lwait->mutex);
} }
int sync_lock(const char *resource, int mode, int flags, int *lockid) static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
{ {
int status; int status;
struct lock_wait lwait; struct lock_wait lwait;
@@ -478,7 +483,7 @@ int sync_lock(const char *resource, int mode, int flags, int *lockid)
return 0; return 0;
} }
int sync_unlock(const char *resource /* UNUSED */, int lockid) static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
{ {
int status; int status;
struct lock_wait lwait; struct lock_wait lwait;
@@ -505,3 +510,28 @@ int sync_unlock(const char *resource /* UNUSED */, int lockid)
return 0; return 0;
} }
static struct cluster_ops _cluster_cman_ops = {
.cluster_init_completed = _cluster_init_completed,
.cluster_send_message = _cluster_send_message,
.name_from_csid = _name_from_csid,
.csid_from_name = _csid_from_name,
.get_num_nodes = _get_num_nodes,
.cluster_fd_callback = _cluster_fd_callback,
.get_main_cluster_fd = _get_main_cluster_fd,
.cluster_do_node_callback = _cluster_do_node_callback,
.is_quorate = _is_quorate,
.get_our_csid = _get_our_csid,
.add_up_node = _add_up_node,
.cluster_closedown = _cluster_closedown,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
};
struct cluster_ops *init_cman_cluster(void)
{
if (!_init_cluster())
return &_cluster_cman_ops;
else
return NULL;
}

View File

@@ -22,33 +22,47 @@
struct local_client; struct local_client;
extern int cluster_send_message(void *buf, int msglen, char *csid, struct cluster_ops {
void (*cluster_init_completed) (void);
int (*cluster_send_message) (void *buf, int msglen, char *csid,
const char *errtext); const char *errtext);
extern int name_from_csid(char *csid, char *name); int (*name_from_csid) (char *csid, char *name);
extern int csid_from_name(char *csid, char *name); int (*csid_from_name) (char *csid, char *name);
extern int get_num_nodes(void); int (*get_num_nodes) (void);
extern int cluster_fd_callback(struct local_client *fd, char *buf, int len, int (*cluster_fd_callback) (struct local_client *fd, char *buf, int len,
char *csid, struct local_client **new_client); char *csid, struct local_client **new_client);
extern int init_cluster(void); int (*get_main_cluster_fd) (void); /* gets accept FD or cman cluster socket */
extern int get_main_cluster_fd(void); /* gets accept FD or cman cluster socket */ int (*cluster_do_node_callback) (struct local_client *client,
extern int cluster_do_node_callback(struct local_client *client,
void (*callback) (struct local_client *, void (*callback) (struct local_client *,
char *csid, int node_up)); char *csid, int node_up));
extern int is_quorate(void); int (*is_quorate) (void);
extern void get_our_csid(char *csid); void (*get_our_csid) (char *csid);
extern void add_up_node(char *csid); void (*add_up_node) (char *csid);
extern void cluster_closedown(void); void (*cluster_closedown) (void);
extern int sync_lock(const char *resource, int mode, int flags, int *lockid); int (*sync_lock) (const char *resource, int mode, int flags, int *lockid);
extern int sync_unlock(const char *resource, int lockid); int (*sync_unlock) (const char *resource, int lockid);
};
#ifdef USE_GULM #ifdef USE_GULM
#include "tcp-comms.h" # include "tcp-comms.h"
#else struct cluster_ops *init_gulm_cluster(void);
/* cman */ #define MAX_CSID_LEN GULM_MAX_CSID_LEN
#include "cnxman-socket.h" #define MAX_CLUSTER_MEMBER_NAME_LEN GULM_MAX_CLUSTER_MEMBER_NAME_LEN
#define MAX_CSID_LEN 4 #endif
#ifdef USE_CMAN
# include "cnxman-socket.h"
# define CMAN_MAX_CSID_LEN 4
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN CMAN_MAX_CSID_LEN
# endif
# undef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN CMAN_MAX_CLUSTER_MEMBER_NAME_LEN
struct cluster_ops *init_cman_cluster(void);
#endif #endif

View File

@@ -72,7 +72,7 @@ static volatile int lock_start_flag;
struct node_info struct node_info
{ {
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state; enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
char name[MAX_CLUSTER_MEMBER_NAME_LEN]; char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
}; };
struct lock_wait struct lock_wait
@@ -88,6 +88,8 @@ static int read_from_core_sock(struct local_client *client, char *buf, int len,
static int read_from_lock_sock(struct local_client *client, char *buf, int len, char *csid, static int read_from_lock_sock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client); struct local_client **new_client);
static int get_all_cluster_nodes(void); static int get_all_cluster_nodes(void);
static int _csid_from_name(char *csid, char *name);
static void _cluster_closedown(void);
/* In tcp-comms.c */ /* In tcp-comms.c */
extern struct hash_table *sock_hash; extern struct hash_table *sock_hash;
@@ -123,7 +125,7 @@ static lg_lockspace_callbacks_t lock_callbacks;
static void badsig_handler(int sig) static void badsig_handler(int sig)
{ {
DEBUGLOG("got sig %d\n", sig); DEBUGLOG("got sig %d\n", sig);
cluster_closedown(); _cluster_closedown();
exit(0); exit(0);
} }
@@ -135,7 +137,7 @@ static void sighup_handler(int sig)
get_all_cluster_nodes(); get_all_cluster_nodes();
} }
int init_cluster() static int _init_cluster(void)
{ {
int status; int status;
int ccs_h; int ccs_h;
@@ -241,7 +243,7 @@ int init_cluster()
return 0; return 0;
} }
void cluster_closedown() static void _cluster_closedown(void)
{ {
DEBUGLOG("cluster_closedown\n"); DEBUGLOG("cluster_closedown\n");
lg_lock_logout(gulm_if); lg_lock_logout(gulm_if);
@@ -339,7 +341,7 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
{ {
struct node_info *ninfo; struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, (char *)ip, MAX_CSID_LEN); ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
if (!ninfo) if (!ninfo)
{ {
/* If we can't find that node then re-read the config file in case it /* If we can't find that node then re-read the config file in case it
@@ -348,7 +350,7 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
get_all_cluster_nodes(); get_all_cluster_nodes();
/* Now try again */ /* Now try again */
ninfo = hash_lookup_binary(node_hash, (char *)ip, MAX_CSID_LEN); ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
if (!ninfo) if (!ninfo)
{ {
DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name); DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
@@ -361,6 +363,11 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
return ninfo; return ninfo;
} }
static void _get_our_csid(char *csid)
{
get_our_gulm_csid(csid);
}
static int core_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *ip, uint8_t state) static int core_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *ip, uint8_t state)
{ {
DEBUGLOG("CORE nodelist\n"); DEBUGLOG("CORE nodelist\n");
@@ -381,14 +388,14 @@ static int core_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *
{ {
if (type == lglcb_stop) if (type == lglcb_stop)
{ {
char ourcsid[MAX_CSID_LEN]; char ourcsid[GULM_MAX_CSID_LEN];
DEBUGLOG("Got Nodelist, stop\n"); DEBUGLOG("Got Nodelist, stop\n");
clvmd_cluster_init_completed(); clvmd_cluster_init_completed();
/* Mark ourself as up */ /* Mark ourself as up */
get_our_csid(ourcsid); _get_our_csid(ourcsid);
add_up_node(ourcsid); gulm_add_up_node(ourcsid);
} }
else else
{ {
@@ -417,7 +424,7 @@ static int core_nodechange(void *misc, char *nodename, struct in6_addr *nodeip,
/* If we don't get nodeip here, try a lookup by name */ /* If we don't get nodeip here, try a lookup by name */
if (!nodeip) if (!nodeip)
csid_from_name((char *)nodeip, nodename); _csid_from_name((char *)nodeip, nodename);
if (!nodeip) if (!nodeip)
return 0; return 0;
@@ -540,15 +547,15 @@ int get_next_node_csid(void **context, char *csid)
return 0; return 0;
} }
memcpy(csid, hash_get_key(node_hash, *context), MAX_CSID_LEN); memcpy(csid, hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
return 1; return 1;
} }
int name_from_csid(char *csid, char *name) int gulm_name_from_csid(char *csid, char *name)
{ {
struct node_info *ninfo; struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN); ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
if (!ninfo) if (!ninfo)
{ {
sprintf(name, "UNKNOWN %s", print_csid(csid)); sprintf(name, "UNKNOWN %s", print_csid(csid));
@@ -560,7 +567,7 @@ int name_from_csid(char *csid, char *name)
} }
int csid_from_name(char *csid, char *name) static int _csid_from_name(char *csid, char *name)
{ {
struct hash_node *hn; struct hash_node *hn;
struct node_info *ninfo; struct node_info *ninfo;
@@ -570,25 +577,25 @@ int csid_from_name(char *csid, char *name)
ninfo = hash_get_data(node_hash, hn); ninfo = hash_get_data(node_hash, hn);
if (strcmp(ninfo->name, name) == 0) if (strcmp(ninfo->name, name) == 0)
{ {
memcpy(csid, hash_get_key(node_hash, hn), MAX_CSID_LEN); memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
return 0; return 0;
} }
} }
return -1; return -1;
} }
int get_num_nodes() static int _get_num_nodes()
{ {
DEBUGLOG("num_nodes = %d\n", num_nodes); DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes; return num_nodes;
} }
/* Node is now known to be running a clvmd */ /* Node is now known to be running a clvmd */
void add_up_node(char *csid) void gulm_add_up_node(char *csid)
{ {
struct node_info *ninfo; struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN); ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
if (!ninfo) if (!ninfo)
return; return;
@@ -601,7 +608,7 @@ void add_down_node(char *csid)
{ {
struct node_info *ninfo; struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN); ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
if (!ninfo) if (!ninfo)
return; return;
@@ -614,7 +621,7 @@ void add_down_node(char *csid)
} }
/* Call a callback for each node, so the caller knows whether it's up or down */ /* Call a callback for each node, so the caller knows whether it's up or down */
int cluster_do_node_callback(struct local_client *master_client, static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *, char *csid, int node_up)) void (*callback)(struct local_client *, char *csid, int node_up))
{ {
struct hash_node *hn; struct hash_node *hn;
@@ -622,15 +629,15 @@ int cluster_do_node_callback(struct local_client *master_client,
hash_iterate(hn, node_hash) hash_iterate(hn, node_hash)
{ {
char csid[MAX_CSID_LEN]; char csid[GULM_MAX_CSID_LEN];
struct local_client *client; struct local_client *client;
ninfo = hash_get_data(node_hash, hn); ninfo = hash_get_data(node_hash, hn);
memcpy(csid, hash_get_key(node_hash, hn), MAX_CSID_LEN); memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state); DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN); client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (client) if (client)
callback(master_client, csid, ninfo->state == NODE_CLVMD); callback(master_client, csid, ninfo->state == NODE_CLVMD);
} }
@@ -742,7 +749,7 @@ static int _unlock_resource(char *resource, int lockid)
To aid unlocking, we store the lock mode in the lockid (as GULM To aid unlocking, we store the lock mode in the lockid (as GULM
doesn't use this). doesn't use this).
*/ */
int sync_lock(const char *resource, int mode, int flags, int *lockid) static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
{ {
int status; int status;
char lock1[strlen(resource)+3]; char lock1[strlen(resource)+3];
@@ -786,7 +793,7 @@ int sync_lock(const char *resource, int mode, int flags, int *lockid)
return status; return status;
} }
int sync_unlock(const char *resource, int lockid) static int _sync_unlock(const char *resource, int lockid)
{ {
int status = 0; int status = 0;
char lock1[strlen(resource)+3]; char lock1[strlen(resource)+3];
@@ -822,7 +829,7 @@ int sync_unlock(const char *resource, int lockid)
return status; return status;
} }
int is_quorate() static int _is_quorate()
{ {
if (current_corestate == lg_core_Slave || if (current_corestate == lg_core_Slave ||
current_corestate == lg_core_Master || current_corestate == lg_core_Master ||
@@ -854,7 +861,7 @@ static int get_all_cluster_nodes()
for (i=1;;i++) for (i=1;;i++)
{ {
char nodekey[256]; char nodekey[256];
char nodeip[MAX_CSID_LEN]; char nodeip[GULM_MAX_CSID_LEN];
int clvmflag = 1; int clvmflag = 1;
char *clvmflagstr; char *clvmflagstr;
char key[256]; char key[256];
@@ -877,7 +884,7 @@ static int get_all_cluster_nodes()
struct node_info *ninfo; struct node_info *ninfo;
/* If it's not in the list, then add it */ /* If it's not in the list, then add it */
ninfo = hash_lookup_binary(node_hash, nodeip, MAX_CSID_LEN); ninfo = hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
if (!ninfo) if (!ninfo)
{ {
ninfo = malloc(sizeof(struct node_info)); ninfo = malloc(sizeof(struct node_info));
@@ -890,7 +897,7 @@ static int get_all_cluster_nodes()
strcpy(ninfo->name, nodename); strcpy(ninfo->name, nodename);
ninfo->state = NODE_DOWN; ninfo->state = NODE_DOWN;
hash_insert_binary(node_hash, nodeip, MAX_CSID_LEN, ninfo); hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
} }
} }
else else
@@ -906,3 +913,42 @@ static int get_all_cluster_nodes()
return 0; return 0;
} }
static int _get_main_cluster_fd(void)
{
return get_main_gulm_cluster_fd();
}
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid, struct local_client **new_client)
{
return cluster_fd_gulm_callback(fd, buf, len, csid, new_client);
}
static int _cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
{
return gulm_cluster_send_message(buf, msglen, csid, errtext);
}
static struct cluster_ops _cluster_gulm_ops = {
.cluster_init_completed = NULL,
.cluster_send_message = _cluster_send_message,
.name_from_csid = gulm_name_from_csid,
.csid_from_name = _csid_from_name,
.get_num_nodes = _get_num_nodes,
.cluster_fd_callback = _cluster_fd_callback,
.get_main_cluster_fd = _get_main_cluster_fd,
.cluster_do_node_callback = _cluster_do_node_callback,
.is_quorate = _is_quorate,
.get_our_csid = _get_our_csid,
.add_up_node = gulm_add_up_node,
.cluster_closedown = _cluster_closedown,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
};
struct cluster_ops *init_gulm_cluster(void)
{
if (!_init_cluster())
return &_cluster_gulm_ops;
else
return NULL;
}

View File

@@ -7,3 +7,6 @@ extern int gulm_fd(void);
extern int get_ip_address(char *node, char *addr); extern int get_ip_address(char *node, char *addr);
extern void tcp_remove_client(char *csid); extern void tcp_remove_client(char *csid);
extern int alloc_client(int fd, char *csid, struct local_client **new_client); extern int alloc_client(int fd, char *csid, struct local_client **new_client);
void gulm_add_up_node(char *csid);
int gulm_name_from_csid(char *csid, char *name);

View File

@@ -55,9 +55,9 @@
/* The maximum size of a message that will fit into a packet. Anything bigger /* The maximum size of a message that will fit into a packet. Anything bigger
than this is sent via the system LV */ than this is sent via the system LV */
#define MAX_INLINE_MESSAGE (MAX_CLUSTER_MESSAGE-sizeof(struct clvm_header)) #define MAX_INLINE_MESSAGE (max_cluster_message-sizeof(struct clvm_header))
#define ISLOCAL_CSID(c) (memcmp(c, our_csid, MAX_CSID_LEN) == 0) #define ISLOCAL_CSID(c) (memcmp(c, our_csid, max_csid_len) == 0)
/* Head of the fd list. Also contains /* Head of the fd list. Also contains
the cluster_socket details */ the cluster_socket details */
@@ -65,7 +65,12 @@ static struct local_client local_client_head;
static unsigned short global_xid = 0; /* Last transaction ID issued */ static unsigned short global_xid = 0; /* Last transaction ID issued */
static struct cluster_ops *clops = NULL;
static char our_csid[MAX_CSID_LEN]; static char our_csid[MAX_CSID_LEN];
static unsigned max_csid_len;
static unsigned max_cluster_message;
static unsigned max_cluster_member_name_len;
/* Structure of items on the LVM thread list */ /* Structure of items on the LVM thread list */
struct lvm_thread_cmd { struct lvm_thread_cmd {
@@ -230,7 +235,23 @@ int main(int argc, char *argv[])
init_lvhash(); init_lvhash();
/* Start the cluster interface */ /* Start the cluster interface */
if (init_cluster()) { #ifdef USE_CMAN
if ((clops = init_cman_cluster())) {
max_csid_len = CMAN_MAX_CSID_LEN;
max_cluster_message = CMAN_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = CMAN_MAX_CLUSTER_MEMBER_NAME_LEN;
}
#endif
#ifdef USE_GULM
if (!clops)
if ((clops = init_gulm_cluster())) {
max_csid_len = GULM_MAX_CSID_LEN;
max_cluster_message = GULM_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = GULM_MAX_CLUSTER_MEMBER_NAME_LEN;
}
#endif
if (!clops) {
DEBUGLOG("Can't initialise cluster interface\n"); DEBUGLOG("Can't initialise cluster interface\n");
log_error("Can't initialise cluster interface\n"); log_error("Can't initialise cluster interface\n");
child_init_signal(DFAIL_CLUSTER_IF); child_init_signal(DFAIL_CLUSTER_IF);
@@ -239,12 +260,12 @@ int main(int argc, char *argv[])
/* Save our CSID */ /* Save our CSID */
uname(&nodeinfo); uname(&nodeinfo);
get_our_csid(our_csid); clops->get_our_csid(our_csid);
/* Initialise the FD list head */ /* Initialise the FD list head */
local_client_head.fd = get_main_cluster_fd(); local_client_head.fd = clops->get_main_cluster_fd();
local_client_head.type = CLUSTER_MAIN_SOCK; local_client_head.type = CLUSTER_MAIN_SOCK;
local_client_head.callback = cluster_fd_callback; local_client_head.callback = clops->cluster_fd_callback;
/* Add the local socket to the list */ /* Add the local socket to the list */
newfd = malloc(sizeof(struct local_client)); newfd = malloc(sizeof(struct local_client));
@@ -262,13 +283,12 @@ int main(int argc, char *argv[])
DEBUGLOG("starting LVM thread\n"); DEBUGLOG("starting LVM thread\n");
pthread_create(&lvm_thread, NULL, lvm_thread_fn, nodeinfo.nodename); pthread_create(&lvm_thread, NULL, lvm_thread_fn, nodeinfo.nodename);
#ifndef USE_GULM
/* Tell the rest of the cluster our version number */ /* Tell the rest of the cluster our version number */
/* CMAN can do this immediately, gulm needs to wait until /* CMAN can do this immediately, gulm needs to wait until
the core initialisation has finished and the node list the core initialisation has finished and the node list
has been gathered */ has been gathered */
send_version_message(); if (clops->cluster_init_completed)
#endif clops->cluster_init_completed();
DEBUGLOG("clvmd ready for work\n"); DEBUGLOG("clvmd ready for work\n");
child_init_signal(SUCCESS); child_init_signal(SUCCESS);
@@ -417,9 +437,9 @@ static void timedout_callback(struct local_client *client, char *csid,
{ {
if (node_up) { if (node_up) {
struct node_reply *reply; struct node_reply *reply;
char nodename[MAX_CLUSTER_MEMBER_NAME_LEN]; char nodename[max_cluster_member_name_len];
name_from_csid(csid, nodename); clops->name_from_csid(csid, nodename);
DEBUGLOG("PJC: checking for a reply from %s\n", nodename); DEBUGLOG("PJC: checking for a reply from %s\n", nodename);
pthread_mutex_lock(&client->bits.localsock.reply_mutex); pthread_mutex_lock(&client->bits.localsock.reply_mutex);
@@ -448,7 +468,7 @@ static void timedout_callback(struct local_client *client, char *csid,
static void request_timed_out(struct local_client *client) static void request_timed_out(struct local_client *client)
{ {
DEBUGLOG("Request timed-out. padding\n"); DEBUGLOG("Request timed-out. padding\n");
cluster_do_node_callback(client, timedout_callback); clops->cluster_do_node_callback(client, timedout_callback);
if (client->bits.localsock.num_replies != if (client->bits.localsock.num_replies !=
client->bits.localsock.expected_replies) { client->bits.localsock.expected_replies) {
@@ -473,7 +493,7 @@ static void main_loop(int local_sock, int cmd_timeout)
int select_status; int select_status;
struct local_client *thisfd; struct local_client *thisfd;
struct timeval tv = { cmd_timeout, 0 }; struct timeval tv = { cmd_timeout, 0 };
int quorate = is_quorate(); int quorate = clops->is_quorate();
/* Wait on the cluster FD and all local sockets/pipes */ /* Wait on the cluster FD and all local sockets/pipes */
FD_ZERO(&in); FD_ZERO(&in);
@@ -488,7 +508,7 @@ static void main_loop(int local_sock, int cmd_timeout)
if ((select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv)) > 0) { if ((select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv)) > 0) {
struct local_client *lastfd = NULL; struct local_client *lastfd = NULL;
char csid[MAX_CSID_LEN]; char csid[MAX_CSID_LEN];
char buf[MAX_CLUSTER_MESSAGE]; char buf[max_cluster_message];
for (thisfd = &local_client_head; thisfd != NULL; for (thisfd = &local_client_head; thisfd != NULL;
thisfd = thisfd->next) { thisfd = thisfd->next) {
@@ -573,7 +593,7 @@ static void main_loop(int local_sock, int cmd_timeout)
} }
closedown: closedown:
cluster_closedown(); clops->cluster_closedown();
close(local_sock); close(local_sock);
} }
@@ -765,7 +785,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (thisfd->bits.localsock.in_progress) { if (thisfd->bits.localsock.in_progress) {
struct clvm_header reply; struct clvm_header reply;
reply.cmd = CLVMD_CMD_REPLY; reply.cmd = CLVMD_CMD_REPLY;
reply.status = -EBUSY; reply.status = EBUSY;
reply.arglen = 0; reply.arglen = 0;
reply.flags = 0; reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid, send_message(&reply, sizeof(reply), our_csid,
@@ -788,7 +808,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (!thisfd->bits.localsock.cmd) { if (!thisfd->bits.localsock.cmd) {
struct clvm_header reply; struct clvm_header reply;
reply.cmd = CLVMD_CMD_REPLY; reply.cmd = CLVMD_CMD_REPLY;
reply.status = -ENOMEM; reply.status = ENOMEM;
reply.arglen = 0; reply.arglen = 0;
reply.flags = 0; reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid, send_message(&reply, sizeof(reply), our_csid,
@@ -829,13 +849,13 @@ static int read_from_local_sock(struct local_client *thisfd)
} }
/* Check the node name for validity */ /* Check the node name for validity */
if (inheader->node[0] && csid_from_name(csid, inheader->node)) { if (inheader->node[0] && clops->csid_from_name(csid, inheader->node)) {
/* Error, node is not in the cluster */ /* Error, node is not in the cluster */
struct clvm_header reply; struct clvm_header reply;
DEBUGLOG("Unknown node: '%s'\n", inheader->node); DEBUGLOG("Unknown node: '%s'\n", inheader->node);
reply.cmd = CLVMD_CMD_REPLY; reply.cmd = CLVMD_CMD_REPLY;
reply.status = -ENOENT; reply.status = ENOENT;
reply.flags = 0; reply.flags = 0;
reply.arglen = 0; reply.arglen = 0;
send_message(&reply, sizeof(reply), our_csid, send_message(&reply, sizeof(reply), our_csid,
@@ -866,7 +886,7 @@ static int read_from_local_sock(struct local_client *thisfd)
close(comms_pipe[1]); close(comms_pipe[1]);
reply.cmd = CLVMD_CMD_REPLY; reply.cmd = CLVMD_CMD_REPLY;
reply.status = -ENOMEM; reply.status = ENOMEM;
reply.arglen = 0; reply.arglen = 0;
reply.flags = 0; reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid, send_message(&reply, sizeof(reply), our_csid,
@@ -961,7 +981,7 @@ static int distribute_command(struct local_client *thisfd)
/* if node is empty then do it on the whole cluster */ /* if node is empty then do it on the whole cluster */
if (inheader->node[0] == '\0') { if (inheader->node[0] == '\0') {
thisfd->bits.localsock.expected_replies = thisfd->bits.localsock.expected_replies =
get_num_nodes(); clops->get_num_nodes();
thisfd->bits.localsock.num_replies = 0; thisfd->bits.localsock.num_replies = 0;
thisfd->bits.localsock.sent_time = time(NULL); thisfd->bits.localsock.sent_time = time(NULL);
thisfd->bits.localsock.in_progress = TRUE; thisfd->bits.localsock.in_progress = TRUE;
@@ -982,7 +1002,7 @@ static int distribute_command(struct local_client *thisfd)
/* Do it on a single node */ /* Do it on a single node */
char csid[MAX_CSID_LEN]; char csid[MAX_CSID_LEN];
if (csid_from_name(csid, inheader->node)) { if (clops->csid_from_name(csid, inheader->node)) {
/* This has already been checked so should not happen */ /* This has already been checked so should not happen */
return 0; return 0;
} else { } else {
@@ -992,7 +1012,7 @@ static int distribute_command(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE; thisfd->bits.localsock.in_progress = TRUE;
/* Are we the requested node ?? */ /* Are we the requested node ?? */
if (memcmp(csid, our_csid, MAX_CSID_LEN) == 0) { if (memcmp(csid, our_csid, max_csid_len) == 0) {
DEBUGLOG("Doing command on local node only\n"); DEBUGLOG("Doing command on local node only\n");
add_to_lvmqueue(thisfd, inheader, len, NULL); add_to_lvmqueue(thisfd, inheader, len, NULL);
} else { } else {
@@ -1024,14 +1044,14 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
char *csid) char *csid)
{ {
char *replyargs; char *replyargs;
char nodename[MAX_CLUSTER_MEMBER_NAME_LEN]; char nodename[max_cluster_member_name_len];
int replylen = 0; int replylen = 0;
int buflen = MAX_CLUSTER_MESSAGE - sizeof(struct clvm_header) - 1; int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
int status; int status;
int msg_malloced = 0; int msg_malloced = 0;
/* Get the node name as we /may/ need it later */ /* Get the node name as we /may/ need it later */
name_from_csid(csid, nodename); clops->name_from_csid(csid, nodename);
DEBUGLOG("process_remote_command %d for clientid 0x%x on node %s\n", DEBUGLOG("process_remote_command %d for clientid 0x%x on node %s\n",
msg->cmd, msg->clientid, nodename); msg->cmd, msg->clientid, nodename);
@@ -1056,7 +1076,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
/* Return a failure response */ /* Return a failure response */
head.cmd = CLVMD_CMD_REPLY; head.cmd = CLVMD_CMD_REPLY;
head.status = -EFBIG; head.status = EFBIG;
head.flags = 0; head.flags = 0;
head.clientid = msg->clientid; head.clientid = msg->clientid;
head.arglen = 0; head.arglen = 0;
@@ -1073,7 +1093,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
msg->arglen); msg->arglen);
/* Return a failure response */ /* Return a failure response */
head.cmd = CLVMD_CMD_REPLY; head.cmd = CLVMD_CMD_REPLY;
head.status = -ENOMEM; head.status = ENOMEM;
head.flags = 0; head.flags = 0;
head.clientid = msg->clientid; head.clientid = msg->clientid;
head.arglen = 0; head.arglen = 0;
@@ -1097,7 +1117,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
if (msg->cmd == CLVMD_CMD_VERSION) { if (msg->cmd == CLVMD_CMD_VERSION) {
int *version_nums = (int *) msg->args; int *version_nums = (int *) msg->args;
char node[256]; char node[256];
name_from_csid(csid, node); clops->name_from_csid(csid, node);
DEBUGLOG("Remote node %s is version %d.%d.%d\n", DEBUGLOG("Remote node %s is version %d.%d.%d\n",
node, node,
ntohl(version_nums[0]), ntohl(version_nums[0]),
@@ -1118,17 +1138,17 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
byebyemsg.flags = 0; byebyemsg.flags = 0;
byebyemsg.arglen = 0; byebyemsg.arglen = 0;
byebyemsg.clientid = 0; byebyemsg.clientid = 0;
cluster_send_message(&byebyemsg, sizeof(byebyemsg), clops->cluster_send_message(&byebyemsg, sizeof(byebyemsg),
our_csid, our_csid,
"Error Sending GOAWAY message"); "Error Sending GOAWAY message");
} else { } else {
add_up_node(csid); clops->add_up_node(csid);
} }
return; return;
} }
/* Allocate a default reply buffer */ /* Allocate a default reply buffer */
replyargs = malloc(MAX_CLUSTER_MESSAGE - sizeof(struct clvm_header)); replyargs = malloc(max_cluster_message - sizeof(struct clvm_header));
if (replyargs != NULL) { if (replyargs != NULL) {
/* Run the command */ /* Run the command */
@@ -1136,7 +1156,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
do_command(NULL, msg, msglen, &replyargs, buflen, do_command(NULL, msg, msglen, &replyargs, buflen,
&replylen); &replylen);
} else { } else {
status = -ENOMEM; status = ENOMEM;
} }
/* If it wasn't a reply, then reply */ /* If it wasn't a reply, then reply */
@@ -1171,7 +1191,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
(aggreply, (aggreply,
replylen + sizeof(struct clvm_header)) < 0 replylen + sizeof(struct clvm_header)) < 0
&& replylen > 0) && replylen > 0)
agghead->status = -EFBIG; agghead->status = EFBIG;
send_message(agghead, send_message(agghead,
sizeof(struct clvm_header), csid, sizeof(struct clvm_header), csid,
@@ -1196,7 +1216,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
DEBUGLOG("Error attempting to realloc return buffer\n"); DEBUGLOG("Error attempting to realloc return buffer\n");
/* Return a failure response */ /* Return a failure response */
head.cmd = CLVMD_CMD_REPLY; head.cmd = CLVMD_CMD_REPLY;
head.status = -ENOMEM; head.status = ENOMEM;
head.flags = 0; head.flags = 0;
head.clientid = msg->clientid; head.clientid = msg->clientid;
head.arglen = 0; head.arglen = 0;
@@ -1228,13 +1248,13 @@ static void add_reply_to_list(struct local_client *client, int status,
reply = malloc(sizeof(struct node_reply)); reply = malloc(sizeof(struct node_reply));
if (reply) { if (reply) {
reply->status = status; reply->status = status;
name_from_csid(csid, reply->node); clops->name_from_csid(csid, reply->node);
DEBUGLOG("Reply from node %s: %d bytes\n", reply->node, len); DEBUGLOG("Reply from node %s: %d bytes\n", reply->node, len);
if (len > 0) { if (len > 0) {
reply->replymsg = malloc(len); reply->replymsg = malloc(len);
if (!reply->replymsg) { if (!reply->replymsg) {
reply->status = -ENOMEM; reply->status = ENOMEM;
} else { } else {
memcpy(reply->replymsg, buf, len); memcpy(reply->replymsg, buf, len);
} }
@@ -1342,8 +1362,8 @@ static int process_local_command(struct clvm_header *msg, int msglen,
struct local_client *client, struct local_client *client,
unsigned short xid) unsigned short xid)
{ {
char *replybuf = malloc(MAX_CLUSTER_MESSAGE); char *replybuf = malloc(max_cluster_message);
int buflen = MAX_CLUSTER_MESSAGE - sizeof(struct clvm_header) - 1; int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
int replylen = 0; int replylen = 0;
int status; int status;
@@ -1425,9 +1445,10 @@ static void send_local_reply(struct local_client *client, int status, int fd)
replybuf = malloc(message_len); replybuf = malloc(message_len);
clientreply = (struct clvm_header *) replybuf; clientreply = (struct clvm_header *) replybuf;
clientreply->status = -status; clientreply->status = status;
clientreply->cmd = CLVMD_CMD_REPLY; clientreply->cmd = CLVMD_CMD_REPLY;
clientreply->node[0] = '\0'; clientreply->node[0] = '\0';
clientreply->flags = 0;
ptr = clientreply->args; ptr = clientreply->args;
@@ -1439,6 +1460,9 @@ static void send_local_reply(struct local_client *client, int status, int fd)
strcpy(ptr, thisreply->node); strcpy(ptr, thisreply->node);
ptr += strlen(thisreply->node) + 1; ptr += strlen(thisreply->node) + 1;
if (thisreply->status)
clientreply->flags |= CLVMD_FLAG_NODEERRS;
*(int *) ptr = thisreply->status; *(int *) ptr = thisreply->status;
ptr += sizeof(int); ptr += sizeof(int);
@@ -1507,7 +1531,7 @@ static void send_version_message()
version_nums[1] = htonl(CLVMD_MINOR_VERSION); version_nums[1] = htonl(CLVMD_MINOR_VERSION);
version_nums[2] = htonl(CLVMD_PATCH_VERSION); version_nums[2] = htonl(CLVMD_PATCH_VERSION);
cluster_send_message(message, sizeof(message), NULL, clops->cluster_send_message(message, sizeof(message), NULL,
"Error Sending version number"); "Error Sending version number");
} }
@@ -1520,7 +1544,7 @@ static int send_message(void *buf, int msglen, char *csid, int fd,
/* Send remote messages down the cluster socket */ /* Send remote messages down the cluster socket */
if (csid == NULL || !ISLOCAL_CSID(csid)) { if (csid == NULL || !ISLOCAL_CSID(csid)) {
hton_clvm((struct clvm_header *) buf); /* Byte swap if necessary */ hton_clvm((struct clvm_header *) buf); /* Byte swap if necessary */
return cluster_send_message(buf, msglen, csid, errtext); return clops->cluster_send_message(buf, msglen, csid, errtext);
} else { } else {
int ptr = 0; int ptr = 0;
@@ -1607,7 +1631,7 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
cmd = malloc(sizeof(struct lvm_thread_cmd)); cmd = malloc(sizeof(struct lvm_thread_cmd));
if (!cmd) if (!cmd)
return -ENOMEM; return ENOMEM;
cmd->msg = malloc(msglen); cmd->msg = malloc(msglen);
if (!cmd->msg) { if (!cmd->msg) {
@@ -1621,7 +1645,7 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
cmd->xid = client->xid; cmd->xid = client->xid;
memcpy(cmd->msg, msg, msglen); memcpy(cmd->msg, msg, msglen);
if (csid) { if (csid) {
memcpy(cmd->csid, csid, MAX_CSID_LEN); memcpy(cmd->csid, csid, max_csid_len);
cmd->remote = 1; cmd->remote = 1;
} else { } else {
cmd->remote = 0; cmd->remote = 0;
@@ -1689,7 +1713,7 @@ static void check_all_callback(struct local_client *client, char *csid,
int node_up) int node_up)
{ {
if (!node_up) if (!node_up)
add_reply_to_list(client, -EHOSTDOWN, csid, "CLVMD not running", add_reply_to_list(client, EHOSTDOWN, csid, "CLVMD not running",
18); 18);
} }
@@ -1699,7 +1723,7 @@ static void check_all_callback(struct local_client *client, char *csid,
static int check_all_clvmds_running(struct local_client *client) static int check_all_clvmds_running(struct local_client *client)
{ {
DEBUGLOG("check_all_clvmds_running\n"); DEBUGLOG("check_all_clvmds_running\n");
return cluster_do_node_callback(client, check_all_callback); return clops->cluster_do_node_callback(client, check_all_callback);
} }
/* Return a local_client struct given a client ID. /* Return a local_client struct given a client ID.
@@ -1745,3 +1769,14 @@ static void sigterm_handler(int sig)
quit = 1; quit = 1;
return; return;
} }
int sync_lock(const char *resource, int mode, int flags, int *lockid)
{
return clops->sync_lock(resource, mode, flags, lockid);
}
int sync_unlock(const char *resource, int lockid)
{
return clops->sync_unlock(resource, lockid);
}

View File

@@ -93,7 +93,7 @@ struct local_client {
struct netsock_bits net; struct netsock_bits net;
} bits; } bits;
}; };
#define DEBUG
#ifdef DEBUG #ifdef DEBUG
#define DEBUGLOG(fmt, args...) fprintf(stderr, "CLVMD[%d]: %ld ", getpid(), time(NULL) ); fprintf(stderr, fmt, ## args) #define DEBUGLOG(fmt, args...) fprintf(stderr, "CLVMD[%d]: %ld ", getpid(), time(NULL) ); fprintf(stderr, fmt, ## args)
#else #else
@@ -116,4 +116,8 @@ extern int add_client(struct local_client *new_client);
extern void clvmd_cluster_init_completed(void); extern void clvmd_cluster_init_completed(void);
extern void process_message(struct local_client *client, char *buf, int len, char *csid); extern void process_message(struct local_client *client, char *buf, int len, char *csid);
int sync_lock(const char *resource, int mode, int flags, int *lockid);
int sync_unlock(const char *resource, int lockid);
#endif #endif

View File

@@ -63,8 +63,8 @@
/* Maximum size of a cluster message */ /* Maximum size of a cluster message */
#define MAX_CLUSTER_MESSAGE 1500 #define CMAN_MAX_CLUSTER_MESSAGE 1500
#define MAX_CLUSTER_MEMBER_NAME_LEN 255 #define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
#define MAX_BARRIER_NAME_LEN 33 #define MAX_BARRIER_NAME_LEN 33
#define MAX_SA_ADDR_LEN 12 #define MAX_SA_ADDR_LEN 12
#define MAX_CLUSTER_NAME_LEN 16 #define MAX_CLUSTER_NAME_LEN 16
@@ -147,7 +147,7 @@ struct cl_cluster_node {
unsigned int leave_reason; unsigned int leave_reason;
unsigned int incarnation; unsigned int incarnation;
nodestate_t state; nodestate_t state;
char name[MAX_CLUSTER_MEMBER_NAME_LEN]; char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
unsigned char votes; unsigned char votes;
}; };

View File

@@ -1,446 +0,0 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* library functions for Cluster LVM Daemon */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <syslog.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <search.h>
#include <errno.h>
#include "clvm.h"
#include "libclvm.h"
/* CLVM in hex! */
#define LVM_SIGNATURE 0x434C564D
#define MAX_CLUSTER_MEMBER_NAME_LEN 255
/* NOTE: the LVMD uses the socket FD as the client ID, this means
that any client that calls fork() will inherit the context of
it's parent. */
static int clvmd_sock = -1;
static int open_local_sock(void)
{
int local_socket;
struct sockaddr_un sockaddr;
/* Open local socket */
local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
if (local_socket < 0) {
perror("Can't create local socket");
return -1;
}
fcntl(local_socket, F_SETFD, !FD_CLOEXEC);
strcpy(sockaddr.sun_path, CLVMD_SOCKNAME);
sockaddr.sun_family = AF_UNIX;
if (connect
(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
int saved_errno = errno;
close(local_socket);
errno = saved_errno;
return -1;
}
return local_socket;
}
/* Send a request and return the status */
static int send_request(char *inbuf, int inlen, char **retbuf)
{
char outbuf[PIPE_BUF];
struct clvm_header *outheader = (struct clvm_header *) outbuf;
int len;
int off;
fd_set fds;
FD_ZERO(&fds);
FD_SET(clvmd_sock, &fds);
/* Send it to CLVMD */
if (write(clvmd_sock, inbuf, inlen) != inlen) {
perror("Error writing to CLVMD");
return -1;
}
/* Get the response */
if ((len = read(clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
perror("Error reading CLVMD");
return -1;
}
if (len == 0) {
fprintf(stderr, "EOF reading CLVMD");
errno = ENOTCONN;
return -1;
}
/* Allocate buffer */
*retbuf = malloc(len + outheader->arglen);
if (!*retbuf) {
errno = ENOMEM;
return -1;
}
/* Copy the header */
memcpy(*retbuf, outbuf, len);
outheader = (struct clvm_header *) *retbuf;
/* Read the returned values */
off = 1; /* we've already read the first byte */
while (off < outheader->arglen && len > 0) {
len = read(clvmd_sock, outheader->args + off, PIPE_BUF);
if (len > 0)
off += len;
}
/* Was it an error ? */
if (outheader->status < 0) {
errno = -outheader->status;
return -2;
}
return 0;
}
/* Build the structure header and parse-out wildcard node names */
static void build_header(struct clvm_header *head, int cmd, const char *node,
void *data, int len)
{
head->cmd = cmd;
head->status = 0;
head->flags = 0;
head->clientid = 0;
head->arglen = len;
if (node) {
/* Allow a couple of special node names:
"*" for all nodes,
"." for the local node only
*/
if (strcmp(node, "*") == 0) {
head->node[0] = '\0';
} else if (strcmp(node, ".") == 0) {
head->node[0] = '\0';
head->flags = CLVMD_FLAG_LOCAL;
} else {
strcpy(head->node, node);
}
} else {
head->node[0] = '\0';
}
}
/* Send a message to a(or all) node(s) in the cluster */
int lvm_cluster_write(char cmd, char *node, void *data, int len)
{
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
char *retbuf = NULL;
int status;
struct clvm_header *head = (struct clvm_header *) outbuf;
if (clvmd_sock == -1)
clvmd_sock = open_local_sock();
if (clvmd_sock == -1)
return -1;
build_header(head, cmd, node, data, len);
memcpy(head->node + strlen(head->node) + 1, data, len);
status =
send_request(outbuf,
sizeof(struct clvm_header) + strlen(head->node) + len,
&retbuf);
if (retbuf)
free(retbuf);
return status;
}
/* API: Send a message to a(or all) node(s) in the cluster
and wait for replies */
int lvm_cluster_request(char cmd, const char *node, void *data, int len,
lvm_response_t ** response, int *num)
{
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
int *outptr;
char *inptr;
char *retbuf = NULL;
int status;
int i;
int num_responses = 0;
struct clvm_header *head = (struct clvm_header *) outbuf;
lvm_response_t *rarray;
*num = 0;
if (clvmd_sock == -1)
clvmd_sock = open_local_sock();
if (clvmd_sock == -1)
return -1;
build_header(head, cmd, node, data, len);
memcpy(head->node + strlen(head->node) + 1, data, len);
status =
send_request(outbuf,
sizeof(struct clvm_header) + strlen(head->node) + len,
&retbuf);
if (status == 0 || status == -2) {
/* Count the number of responses we got */
head = (struct clvm_header *) retbuf;
inptr = head->args;
while (inptr[0]) {
num_responses++;
inptr += strlen(inptr) + 1;
inptr += sizeof(int);
inptr += strlen(inptr) + 1;
}
/* Allocate response array. With an extra pair of INTs on the front to sanity
check the pointer when we are given it back to free */
outptr =
malloc(sizeof(lvm_response_t) * num_responses +
sizeof(int) * 2);
if (!outptr) {
if (retbuf)
free(retbuf);
errno = ENOMEM;
return -1;
}
*response = (lvm_response_t *) (outptr + 2);
outptr[0] = LVM_SIGNATURE;
outptr[1] = num_responses;
rarray = *response;
/* Unpack the response into an lvm_response_t array */
inptr = head->args;
i = 0;
while (inptr[0]) {
strcpy(rarray[i].node, inptr);
inptr += strlen(inptr) + 1;
rarray[i].status = *(int *) inptr;
inptr += sizeof(int);
rarray[i].response = malloc(strlen(inptr) + 1);
if (rarray[i].response == NULL) {
/* Free up everything else and return error */
int j;
for (j = 0; j < i; j++)
free(rarray[i].response);
free(outptr);
errno = ENOMEM;
return -1;
}
strcpy(rarray[i].response, inptr);
rarray[i].len = strlen(inptr);
inptr += strlen(inptr) + 1;
i++;
}
*num = num_responses;
*response = rarray;
}
if (retbuf)
free(retbuf);
return status;
}
/* API: Free reply array */
int lvm_cluster_free_request(lvm_response_t * response)
{
int *ptr = (int *) response - 2;
int i;
int num;
/* Check it's ours to free */
if (response == NULL || *ptr != LVM_SIGNATURE) {
errno = EINVAL;
return -1;
}
num = ptr[1];
for (i = 0; i < num; i++) {
free(response[i].response);
}
free(ptr);
return 0;
}
/* These are a "higher-level" API providing black-box lock/unlock
functions for cluster LVM...maybe */
/* Set by lock(), used by unlock() */
static int num_responses;
static lvm_response_t *response;
int lvm_lock_for_cluster(char scope, char *name, int verbosity)
{
int status;
int i;
char *args;
int len;
if (name) {
len = strlen(name) + 2;
args = alloca(len);
strcpy(args + 1, name);
} else {
len = 2;
args = alloca(len);
args[1] = '\0';
}
args[0] = scope;
status = lvm_cluster_request(CLVMD_CMD_LOCK,
"", args, len, &response, &num_responses);
/* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) {
if (response[i].status == -EHOSTDOWN) {
if (verbosity)
fprintf(stderr,
"clvmd not running on node %s\n",
response[i].node);
status = -1;
}
}
/* If there was an error then free the memory now as the caller won't
want to do the unlock */
if (status) {
int saved_errno = errno;
lvm_cluster_free_request(response);
num_responses = 0;
errno = saved_errno;
}
return status;
}
int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
{
int status;
int i;
int len;
int failed;
int num_unlock_responses;
char *args;
lvm_response_t *unlock_response;
/* We failed - this should not have been called */
if (num_responses == 0)
return 0;
if (name) {
len = strlen(name) + 2;
args = alloca(len);
strcpy(args + 1, name);
} else {
len = 2;
args = alloca(len);
args[1] = '\0';
}
args[0] = scope;
/* See if it failed anywhere */
failed = 0;
for (i = 0; i < num_responses; i++) {
if (response[i].status != 0)
failed++;
}
/* If it failed on any nodes then we only unlock on
the nodes that succeeded */
if (failed) {
for (i = 0; i < num_responses; i++) {
/* Unlock the ones that succeeded */
if (response[i].status == 0) {
status = lvm_cluster_request(CLVMD_CMD_UNLOCK,
response[i].node,
args, len,
&unlock_response,
&num_unlock_responses);
if (status) {
if (verbosity)
fprintf(stderr,
"cluster command to node %s failed: %s\n",
response[i].node,
strerror(errno));
} else if (unlock_response[0].status != 0) {
if (verbosity > 1)
fprintf(stderr,
"unlock on node %s failed: %s\n",
response[i].node,
strerror(unlock_response
[0].status));
}
lvm_cluster_free_request(unlock_response);
} else {
if (verbosity)
fprintf(stderr,
"command on node %s failed: '%s' - will be left locked\n",
response[i].node,
strerror(response[i].status));
}
}
} else {
/* All OK, we can do a full cluster unlock */
status = lvm_cluster_request(CLVMD_CMD_UNLOCK,
"",
args, len,
&unlock_response,
&num_unlock_responses);
if (status) {
if (verbosity > 1)
fprintf(stderr, "cluster command failed: %s\n",
strerror(errno));
} else {
for (i = 0; i < num_unlock_responses; i++) {
if (unlock_response[i].status != 0) {
if (verbosity > 1)
fprintf(stderr,
"unlock on node %s failed: %s\n",
response[i].node,
strerror(unlock_response
[0].status));
}
}
}
lvm_cluster_free_request(unlock_response);
}
lvm_cluster_free_request(response);
return 0;
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LIBCLVM_H
#define _LIBCLVM_H
typedef struct lvm_response {
char node[255];
char *response;
int status;
int len;
} lvm_response_t;
extern int lvm_cluster_request(char cmd, const char *node, void *data, int len,
lvm_response_t ** response, int *num);
extern int lvm_cluster_write(char cmd, char *node, void *data, int len);
extern int lvm_cluster_free_request(lvm_response_t * response);
/* The "high-level" API */
extern int lvm_lock_for_cluster(char scope, char *name, int verbosity);
extern int lvm_unlock_for_cluster(char scope, char *name, int verbosity);
#endif

View File

@@ -198,7 +198,7 @@ static int do_activate_lv(char *resource, int mode)
return errno; return errno;
/* If it's suspended then resume it */ /* If it's suspended then resume it */
if (!lv_info_by_lvid(cmd, resource, &lvi)) if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
return EIO; return EIO;
if (lvi.suspended) if (lvi.suspended)
@@ -244,7 +244,7 @@ static int do_suspend_lv(char *resource)
} }
/* Only suspend it if it exists */ /* Only suspend it if it exists */
if (!lv_info_by_lvid(cmd, resource, &lvi)) if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
return EIO; return EIO;
if (lvi.exists) { if (lvi.exists) {
@@ -363,7 +363,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
if (oldmode == LKM_PWMODE) { if (oldmode == LKM_PWMODE) {
struct lvinfo lvi; struct lvinfo lvi;
if (!lv_info_by_lvid(cmd, resource, &lvi)) if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
return EIO; return EIO;
if (lvi.exists) { if (lvi.exists) {

View File

@@ -42,7 +42,9 @@
#include "list.h" #include "list.h"
#include "locking.h" #include "locking.h"
#include "system-lv.h" #include "system-lv.h"
#include "clvm.h"
#include "clvmd-comms.h" #include "clvmd-comms.h"
#include "clvmd.h"
#ifdef HAVE_CCS #ifdef HAVE_CCS
#include "ccs.h" #include "ccs.h"
#endif #endif

View File

@@ -96,19 +96,19 @@ void tcp_remove_client(char *csid)
job of clvmd.c whch will do the job when it notices the job of clvmd.c whch will do the job when it notices the
other end has gone. We just need to remove the client(s) from other end has gone. We just need to remove the client(s) from
the hash table so we don't try to use it for sending any more */ the hash table so we don't try to use it for sending any more */
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN); client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (client) if (client)
{ {
hash_remove_binary(sock_hash, csid, MAX_CSID_LEN); hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
} }
/* Look for a mangled one too */ /* Look for a mangled one too */
csid[0] ^= 0x80; csid[0] ^= 0x80;
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN); client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (client) if (client)
{ {
hash_remove_binary(sock_hash, csid, MAX_CSID_LEN); hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
} }
/* Put it back as we found it */ /* Put it back as we found it */
@@ -137,7 +137,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
*new_client = client; *new_client = client;
/* Add to our list of node sockets */ /* Add to our list of node sockets */
if (hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN)) if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
{ {
DEBUGLOG("alloc_client mangling CSID for second connection\n"); DEBUGLOG("alloc_client mangling CSID for second connection\n");
/* This is a duplicate connection but we can't close it because /* This is a duplicate connection but we can't close it because
@@ -150,7 +150,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
/* If it still exists then kill the connection as we should only /* If it still exists then kill the connection as we should only
ever have one incoming connection from each node */ ever have one incoming connection from each node */
if (hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN)) if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
{ {
DEBUGLOG("Multiple incoming connections from node\n"); DEBUGLOG("Multiple incoming connections from node\n");
syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]); syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
@@ -160,26 +160,26 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
return -1; return -1;
} }
} }
hash_insert_binary(sock_hash, csid, MAX_CSID_LEN, client); hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
return 0; return 0;
} }
int get_main_cluster_fd() int get_main_gulm_cluster_fd()
{ {
return listen_fd; return listen_fd;
} }
/* Read on main comms (listen) socket, accept it */ /* Read on main comms (listen) socket, accept it */
int cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid, int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, char *csid,
struct local_client **new_client) struct local_client **new_client)
{ {
int newfd; int newfd;
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
socklen_t addrlen = sizeof(addr); socklen_t addrlen = sizeof(addr);
int status; int status;
char name[MAX_CLUSTER_MEMBER_NAME_LEN]; char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
DEBUGLOG("cluster_fd_callback\n"); DEBUGLOG("cluster_fd_callback\n");
*new_client = NULL; *new_client = NULL;
@@ -196,7 +196,7 @@ int cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid,
/* Check that the client is a member of the cluster /* Check that the client is a member of the cluster
and reject if not. and reject if not.
*/ */
if (name_from_csid((char *)&addr.sin6_addr, name) < 0) if (gulm_name_from_csid((char *)&addr.sin6_addr, name) < 0)
{ {
syslog(LOG_ERR, "Got connect from non-cluster node %s\n", syslog(LOG_ERR, "Got connect from non-cluster node %s\n",
print_csid((char *)&addr.sin6_addr)); print_csid((char *)&addr.sin6_addr));
@@ -234,7 +234,7 @@ static int read_from_tcpsock(struct local_client *client, char *buf, int len, ch
/* Get "csid" */ /* Get "csid" */
getpeername(client->fd, (struct sockaddr *)&addr, &slen); getpeername(client->fd, (struct sockaddr *)&addr, &slen);
memcpy(csid, &addr.sin6_addr, MAX_CSID_LEN); memcpy(csid, &addr.sin6_addr, GULM_MAX_CSID_LEN);
status = read(client->fd, buf, len); status = read(client->fd, buf, len);
@@ -245,15 +245,15 @@ static int read_from_tcpsock(struct local_client *client, char *buf, int len, ch
if (status == 0 || if (status == 0 ||
(status < 0 && errno != EAGAIN && errno != EINTR)) (status < 0 && errno != EAGAIN && errno != EINTR))
{ {
char remcsid[MAX_CSID_LEN]; char remcsid[GULM_MAX_CSID_LEN];
memcpy(remcsid, csid, MAX_CSID_LEN); memcpy(remcsid, csid, GULM_MAX_CSID_LEN);
close(client->fd); close(client->fd);
/* If the csid was mangled, then make sure we remove the right entry */ /* If the csid was mangled, then make sure we remove the right entry */
if (client->bits.net.flags) if (client->bits.net.flags)
remcsid[0] ^= 0x80; remcsid[0] ^= 0x80;
hash_remove_binary(sock_hash, remcsid, MAX_CSID_LEN); hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
/* Tell cluster manager layer */ /* Tell cluster manager layer */
add_down_node(remcsid); add_down_node(remcsid);
@@ -281,7 +281,7 @@ static int connect_csid(char *csid, struct local_client **newclient)
} }
addr.sin6_family = AF_INET6; addr.sin6_family = AF_INET6;
memcpy(&addr.sin6_addr, csid, MAX_CSID_LEN); memcpy(&addr.sin6_addr, csid, GULM_MAX_CSID_LEN);
addr.sin6_port = htons(tcp_port); addr.sin6_port = htons(tcp_port);
DEBUGLOG("Connecting socket %d\n", fd); DEBUGLOG("Connecting socket %d\n", fd);
@@ -300,7 +300,7 @@ static int connect_csid(char *csid, struct local_client **newclient)
add_client(*newclient); add_client(*newclient);
/* If we can connect to it, it must be running a clvmd */ /* If we can connect to it, it must be running a clvmd */
add_up_node(csid); gulm_add_up_node(csid);
return status; return status;
} }
@@ -309,18 +309,18 @@ static int tcp_send_message(void *buf, int msglen, unsigned char *csid, const ch
{ {
int status; int status;
struct local_client *client; struct local_client *client;
char ourcsid[MAX_CSID_LEN]; char ourcsid[GULM_MAX_CSID_LEN];
assert(csid); assert(csid);
DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen); DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen);
/* Don't connect to ourself */ /* Don't connect to ourself */
get_our_csid(ourcsid); get_our_gulm_csid(ourcsid);
if (memcmp(csid, ourcsid, MAX_CSID_LEN) == 0) if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
return msglen; return msglen;
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN); client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (!client) if (!client)
{ {
status = connect_csid(csid, &client); status = connect_csid(csid, &client);
@@ -333,7 +333,7 @@ static int tcp_send_message(void *buf, int msglen, unsigned char *csid, const ch
} }
int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext) int gulm_cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
{ {
int status=0; int status=0;
@@ -343,7 +343,7 @@ int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
if (!csid) if (!csid)
{ {
void *context = NULL; void *context = NULL;
char loop_csid[MAX_CSID_LEN]; char loop_csid[GULM_MAX_CSID_LEN];
/* Loop round all gulm-known nodes */ /* Loop round all gulm-known nodes */
while (get_next_node_csid(&context, loop_csid)) while (get_next_node_csid(&context, loop_csid))
@@ -377,9 +377,9 @@ static int get_our_ip_address(char *addr, int *family)
/* Public version of above for those that don't care what protocol /* Public version of above for those that don't care what protocol
we're using */ we're using */
void get_our_csid(char *csid) void get_our_gulm_csid(char *csid)
{ {
static char our_csid[MAX_CSID_LEN]; static char our_csid[GULM_MAX_CSID_LEN];
static int got_csid = 0; static int got_csid = 0;
if (!got_csid) if (!got_csid)
@@ -392,7 +392,7 @@ void get_our_csid(char *csid)
got_csid = 1; got_csid = 1;
} }
} }
memcpy(csid, our_csid, MAX_CSID_LEN); memcpy(csid, our_csid, GULM_MAX_CSID_LEN);
} }
static void map_v4_to_v6(struct in_addr *ip4, struct in6_addr *ip6) static void map_v4_to_v6(struct in_addr *ip4, struct in6_addr *ip6)
@@ -408,7 +408,7 @@ int get_ip_address(char *node, char *addr)
{ {
struct hostent *he; struct hostent *he;
memset(addr, 0, MAX_CSID_LEN); memset(addr, 0, GULM_MAX_CSID_LEN);
// TODO: what do we do about multi-homed hosts ??? // TODO: what do we do about multi-homed hosts ???
// CCSs ip_interfaces solved this but some bugger removed it. // CCSs ip_interfaces solved this but some bugger removed it.

View File

@@ -1,8 +1,12 @@
#include <netinet/in.h> #include <netinet/in.h>
#define MAX_CLUSTER_MESSAGE 1600 #define GULM_MAX_CLUSTER_MESSAGE 1600
#define MAX_CSID_LEN sizeof(struct in6_addr) #define GULM_MAX_CSID_LEN sizeof(struct in6_addr)
#define MAX_CLUSTER_MEMBER_NAME_LEN 128 #define GULM_MAX_CLUSTER_MEMBER_NAME_LEN 128
extern int init_comms(unsigned short); extern int init_comms(unsigned short);
extern char *print_csid(char *); extern char *print_csid(char *);
int get_main_gulm_cluster_fd(void);
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, char *csid, struct local_client **new_client);
int gulm_cluster_send_message(void *buf, int msglen, char *csid, const char *errtext);
void get_our_gulm_csid(char *csid);

View File

@@ -78,12 +78,13 @@ int target_present(const char *target_name)
{ {
return 0; return 0;
} }
int lv_info(const struct logical_volume *lv, struct lvinfo *info) int lv_info(const struct logical_volume *lv, struct lvinfo *info,
int with_open_count)
{ {
return 0; return 0;
} }
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
struct lvinfo *info) struct lvinfo *info, int with_open_count)
{ {
return 0; return 0;
} }
@@ -333,7 +334,7 @@ int target_present(const char *target_name)
* Returns 1 if info structure populated, else 0 on failure. * Returns 1 if info structure populated, else 0 on failure.
*/ */
static int _lv_info(const struct logical_volume *lv, int mknodes, static int _lv_info(const struct logical_volume *lv, int mknodes,
struct lvinfo *info) struct lvinfo *info, int with_open_count)
{ {
int r; int r;
struct dev_manager *dm; struct dev_manager *dm;
@@ -347,7 +348,7 @@ static int _lv_info(const struct logical_volume *lv, int mknodes,
return 0; return 0;
} }
if (!(r = dev_manager_info(dm, lv, mknodes, &dminfo))) if (!(r = dev_manager_info(dm, lv, mknodes, with_open_count, &dminfo)))
stack; stack;
info->exists = dminfo.exists; info->exists = dminfo.exists;
@@ -361,20 +362,21 @@ static int _lv_info(const struct logical_volume *lv, int mknodes,
return r; return r;
} }
int lv_info(const struct logical_volume *lv, struct lvinfo *info) int lv_info(const struct logical_volume *lv, struct lvinfo *info,
int with_open_count)
{ {
return _lv_info(lv, 0, info); return _lv_info(lv, 0, info, with_open_count);
} }
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
struct lvinfo *info) struct lvinfo *info, int with_open_count)
{ {
struct logical_volume *lv; struct logical_volume *lv;
if (!(lv = lv_from_lvid(cmd, lvid_s))) if (!(lv = lv_from_lvid(cmd, lvid_s)))
return 0; return 0;
return _lv_info(lv, 0, info); return _lv_info(lv, 0, info, with_open_count);
} }
/* /*
@@ -412,7 +414,7 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
if (!activation()) if (!activation())
return 0; return 0;
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 0)) {
stack; stack;
return 0; return 0;
} }
@@ -437,7 +439,7 @@ static int _lv_active(struct logical_volume *lv)
{ {
struct lvinfo info; struct lvinfo info;
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 0)) {
stack; stack;
return -1; return -1;
} }
@@ -449,7 +451,7 @@ static int _lv_open_count(struct logical_volume *lv)
{ {
struct lvinfo info; struct lvinfo info;
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 1)) {
stack; stack;
return -1; return -1;
} }
@@ -566,7 +568,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
return 1; return 1;
} }
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 0)) {
stack; stack;
return 0; return 0;
} }
@@ -612,7 +614,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
return 1; return 1;
} }
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 0)) {
stack; stack;
return 0; return 0;
} }
@@ -657,7 +659,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
return 1; return 1;
} }
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 1)) {
stack; stack;
return 0; return 0;
} }
@@ -726,7 +728,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
return 1; return 1;
} }
if (!lv_info(lv, &info)) { if (!lv_info(lv, &info, 0)) {
stack; stack;
return 0; return 0;
} }
@@ -765,7 +767,7 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
return r; return r;
} }
if (!_lv_info(lv, 1, &info)) { if (!_lv_info(lv, 1, &info, 0)) {
stack; stack;
return 0; return 0;
} }

View File

@@ -55,9 +55,10 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
/* /*
* Returns 1 if info structure has been populated, else 0. * Returns 1 if info structure has been populated, else 0.
*/ */
int lv_info(const struct logical_volume *lv, struct lvinfo *info); int lv_info(const struct logical_volume *lv, struct lvinfo *info,
int with_open_count);
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
struct lvinfo *info); struct lvinfo *info, int with_open_count);
/* /*
* Returns 1 if activate_lv has been set: 1 = activate; 0 = don't. * Returns 1 if activate_lv has been set: 1 = activate; 0 = don't.

View File

@@ -211,7 +211,8 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
} }
static int _info_run(const char *name, const char *uuid, struct dm_info *info, static int _info_run(const char *name, const char *uuid, struct dm_info *info,
int mknodes, struct pool *mem, char **uuid_out) int mknodes, int with_open_count, struct pool *mem,
char **uuid_out)
{ {
int r = 0; int r = 0;
struct dm_task *dmt; struct dm_task *dmt;
@@ -225,6 +226,10 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
return 0; return 0;
} }
if (!with_open_count)
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_run(dmt)) { if (!dm_task_run(dmt)) {
stack; stack;
goto out; goto out;
@@ -250,14 +255,17 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
} }
static int _info(const char *name, const char *uuid, int mknodes, static int _info(const char *name, const char *uuid, int mknodes,
struct dm_info *info, struct pool *mem, char **uuid_out) int with_open_count, struct dm_info *info,
struct pool *mem, char **uuid_out)
{ {
if (!mknodes && uuid && *uuid && if (!mknodes && uuid && *uuid &&
_info_run(NULL, uuid, info, 0, mem, uuid_out) && info->exists) _info_run(NULL, uuid, info, 0, with_open_count, mem, uuid_out) &&
info->exists)
return 1; return 1;
if (name) if (name)
return _info_run(name, NULL, info, mknodes, mem, uuid_out); return _info_run(name, NULL, info, mknodes, with_open_count,
mem, uuid_out);
return 0; return 0;
} }
@@ -279,6 +287,9 @@ static int _status_run(const char *name, const char *uuid,
return 0; return 0;
} }
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_run(dmt)) { if (!dm_task_run(dmt)) {
stack; stack;
goto out; goto out;
@@ -357,6 +368,9 @@ static int _percent_run(struct dev_manager *dm, const char *name,
return 0; return 0;
} }
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_run(dmt)) { if (!dm_task_run(dmt)) {
stack; stack;
goto out; goto out;
@@ -460,6 +474,9 @@ static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
goto out; goto out;
} }
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!(r = dm_task_run(dmt))) { if (!(r = dm_task_run(dmt))) {
log_error("Couldn't rename device '%s'.", dl->name); log_error("Couldn't rename device '%s'.", dl->name);
goto out; goto out;
@@ -488,6 +505,9 @@ static int _suspend_or_resume(const char *name, action_t suspend)
return 0; return 0;
} }
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!(r = dm_task_run(dmt))) if (!(r = dm_task_run(dmt)))
log_error("Couldn't %s device '%s'", sus ? "suspend" : "resume", log_error("Couldn't %s device '%s'", sus ? "suspend" : "resume",
name); name);
@@ -579,6 +599,9 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
log_very_verbose("Activating %s read-only", dl->name); log_very_verbose("Activating %s read-only", dl->name);
} }
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!(r = dm_task_run(dmt))) { if (!(r = dm_task_run(dmt))) {
log_error("Couldn't load device '%s'.", dl->name); log_error("Couldn't load device '%s'.", dl->name);
if ((dl->lv->minor >= 0 || dl->lv->major >= 0) && if ((dl->lv->minor >= 0 || dl->lv->major >= 0) &&
@@ -635,6 +658,9 @@ static int _remove(struct dev_layer *dl)
return 0; return 0;
} }
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
/* Suppress error message if it's still in use - we'll log it later */ /* Suppress error message if it's still in use - we'll log it later */
log_suppress(1); log_suppress(1);
@@ -852,6 +878,7 @@ static int _populate_snapshot(struct dev_manager *dm,
struct snapshot *s; struct snapshot *s;
struct dev_layer *dlo, *dlc; struct dev_layer *dlo, *dlc;
char devbufo[10], devbufc[10]; char devbufo[10], devbufc[10];
uint64_t size;
if (!(s = find_cow(dl->lv))) { if (!(s = find_cow(dl->lv))) {
log_error("Couldn't find snapshot for '%s'.", dl->lv->name); log_error("Couldn't find snapshot for '%s'.", dl->lv->name);
@@ -899,10 +926,10 @@ static int _populate_snapshot(struct dev_manager *dm,
return 0; return 0;
} }
log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size = (uint64_t) s->le_count * s->origin->vg->extent_size;
s->origin->size, params);
if (!dm_task_add_target log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
(dmt, UINT64_C(0), s->origin->size, "snapshot", params)) { if (!dm_task_add_target(dmt, UINT64_C(0), size, "snapshot", params)) {
stack; stack;
return 0; return 0;
} }
@@ -970,7 +997,7 @@ void dev_manager_destroy(struct dev_manager *dm)
} }
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv, int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
int mknodes, struct dm_info *info) int mknodes, int with_open_count, struct dm_info *info)
{ {
char *name; char *name;
@@ -986,7 +1013,8 @@ int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
* Try and get some info on this device. * Try and get some info on this device.
*/ */
log_debug("Getting device info for %s", name); log_debug("Getting device info for %s", name);
if (!_info(name, lv->lvid.s, mknodes, info, NULL, NULL)) { if (!_info(name, lv->lvid.s, mknodes, with_open_count, info, NULL,
NULL)) {
stack; stack;
return 0; return 0;
} }
@@ -1065,7 +1093,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->name = name; dl->name = name;
log_debug("Getting device info for %s", dl->name); log_debug("Getting device info for %s", dl->name);
if (!_info(dl->name, dlid, 0, &dl->info, dm->mem, &uuid)) { if (!_info(dl->name, dlid, 0, 0, &dl->info, dm->mem, &uuid)) {
stack; stack;
return NULL; return NULL;
} }

View File

@@ -36,7 +36,7 @@ void dev_manager_exit(void);
* unsuspended until the snapshot is also created.) * unsuspended until the snapshot is also created.)
*/ */
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv, int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
int mknodes, struct dm_info *info); int mknodes, int with_open_count, struct dm_info *info);
int dev_manager_snapshot_percent(struct dev_manager *dm, int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent); struct logical_volume *lv, float *percent);
int dev_manager_mirror_percent(struct dev_manager *dm, int dev_manager_mirror_percent(struct dev_manager *dm,

View File

@@ -317,7 +317,7 @@ void lvdisplay_colons(struct logical_volume *lv)
{ {
int inkernel; int inkernel;
struct lvinfo info; struct lvinfo info;
inkernel = lv_info(lv, &info) && info.exists; inkernel = lv_info(lv, &info, 1) && info.exists;
log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d", log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
lv->vg->cmd->dev_dir, lv->vg->cmd->dev_dir,
@@ -348,7 +348,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
return 0; return 0;
} }
inkernel = lv_info(lv, &info) && info.exists; inkernel = lv_info(lv, &info, 1) && info.exists;
log_print("--- Logical volume ---"); log_print("--- Logical volume ---");

View File

@@ -69,6 +69,7 @@ static const device_info_t device_info[] = {
{"power2", 16}, /* EMC Powerpath */ {"power2", 16}, /* EMC Powerpath */
{"i2o_block", 16}, /* i2o Block Disk */ {"i2o_block", 16}, /* i2o Block Disk */
{"iseries/vd", 8}, /* iSeries disks */ {"iseries/vd", 8}, /* iSeries disks */
{"gnbd", 1}, /* Network block device */
{NULL, 0} {NULL, 0}
}; };

View File

@@ -646,7 +646,7 @@ int import_snapshots(struct pool *mem, struct volume_group *vg,
continue; continue;
/* insert the snapshot */ /* insert the snapshot */
if (!vg_add_snapshot(org, cow, 1, NULL, if (!vg_add_snapshot(org, cow, 1, NULL, org->le_count,
lvd->lv_chunk_size)) { lvd->lv_chunk_size)) {
log_err("Couldn't add snapshot."); log_err("Couldn't add snapshot.");
return 0; return 0;

View File

@@ -66,29 +66,6 @@ struct pool_list;
struct user_subpool; struct user_subpool;
struct user_device; struct user_device;
/* This must be kept up to date with sistina/pool/module/pool_sptypes.h */
/* Generic Labels */
#define SPTYPE_DATA (0x00000000)
/* GFS specific labels */
#define SPTYPE_GFS_DATA (0x68011670)
#define SPTYPE_GFS_JOURNAL (0x69011670)
struct sptype_name {
const char *name;
uint32_t label;
};
static const struct sptype_name sptype_names[] = {
{"data", SPTYPE_DATA},
{"gfs_data", SPTYPE_GFS_DATA},
{"gfs_journal", SPTYPE_GFS_JOURNAL},
{"", 0x0} /* This must be the last flag. */
};
struct pool_disk { struct pool_disk {
uint64_t pl_magic; /* Pool magic number */ uint64_t pl_magic; /* Pool magic number */
uint64_t pl_pool_id; /* Unique pool identifier */ uint64_t pl_pool_id; /* Unique pool identifier */

View File

@@ -19,6 +19,7 @@
#include "metadata.h" #include "metadata.h"
#include "lvmcache.h" #include "lvmcache.h"
#include "disk_rep.h" #include "disk_rep.h"
#include "sptype_names.h"
#include "lv_alloc.h" #include "lv_alloc.h"
#include "str_list.h" #include "str_list.h"
#include "display.h" #include "display.h"

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SPTYPE_NAMES_H
#define SPTYPE_NAMES_H
/* This must be kept up to date with sistina/pool/module/pool_sptypes.h */
/* Generic Labels */
#define SPTYPE_DATA (0x00000000)
/* GFS specific labels */
#define SPTYPE_GFS_DATA (0x68011670)
#define SPTYPE_GFS_JOURNAL (0x69011670)
struct sptype_name {
const char *name;
uint32_t label;
};
static const struct sptype_name sptype_names[] = {
{"data", SPTYPE_DATA},
{"gfs_data", SPTYPE_GFS_DATA},
{"gfs_journal", SPTYPE_GFS_JOURNAL},
{"", 0x0} /* This must be the last flag. */
};
#endif

View File

@@ -513,7 +513,7 @@ static int _print_snapshot(struct formatter *f, struct snapshot *snap,
} }
seg.le = 0; seg.le = 0;
seg.len = snap->origin->le_count; seg.len = snap->le_count;
seg.origin = snap->origin; seg.origin = snap->origin;
seg.cow = snap->cow; seg.cow = snap->cow;
seg.chunk_size = snap->chunk_size; seg.chunk_size = snap->chunk_size;

View File

@@ -88,8 +88,11 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
} }
*/ */
if (!*lv->lvid.s) if (!*lv->lvid.s && !lvid_create(&lv->lvid, &lv->vg->id)) {
lvid_create(&lv->lvid, &lv->vg->id); log_error("Random lvid creation failed for %s/%s.",
lv->vg->name, lv->name);
return 0;
}
return 1; return 1;
} }

View File

@@ -147,10 +147,16 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
} }
/* Was it an error ? */ /* Was it an error ? */
if (outheader->status < 0) { if (outheader->status != 0) {
errno = -outheader->status; errno = outheader->status;
log_error("cluster request failed: %s", strerror(errno));
return 0; /* Only return an error here if there are no node-specific
errors present in the message that might have more detail */
if (!(outheader->flags & CLVMD_FLAG_NODEERRS)) {
log_error("cluster request failed: %s", strerror(errno));
return 0;
}
} }
return 1; return 1;
@@ -341,10 +347,11 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
/* If any nodes were down then display them and return an error */ /* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) { for (i = 0; i < num_responses; i++) {
if (response[i].status == -EHOSTDOWN) { if (response[i].status == EHOSTDOWN) {
log_error("clvmd not running on node %s", log_error("clvmd not running on node %s",
response[i].node); response[i].node);
status = 0; status = 0;
errno = response[i].status;
} else if (response[i].status) { } else if (response[i].status) {
log_error("Error locking on node %s: %s", log_error("Error locking on node %s: %s",
response[i].node, response[i].node,
@@ -352,6 +359,7 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
response[i].response : response[i].response :
strerror(response[i].status)); strerror(response[i].status));
status = 0; status = 0;
errno = response[i].status;
} }
} }

View File

@@ -267,10 +267,13 @@ struct physical_volume *pv_create(const struct format_type *fmt,
return NULL; return NULL;
} }
if (!id) if (id)
id_create(&pv->id);
else
memcpy(&pv->id, id, sizeof(*id)); memcpy(&pv->id, id, sizeof(*id));
else if (!id_create(&pv->id)) {
log_error("Failed to create random uuid for %s.",
dev_name(dev));
return NULL;
}
pv->dev = dev; pv->dev = dev;
@@ -711,6 +714,11 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
log_error("Automatic metadata correction failed"); log_error("Automatic metadata correction failed");
return NULL; return NULL;
} }
if (!vg_commit(correct_vg)) {
log_error("Automatic metadata correction commit "
"failed");
return NULL;
}
} }
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) { if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {

View File

@@ -255,6 +255,7 @@ struct snapshot {
int persistent; /* boolean */ int persistent; /* boolean */
uint32_t chunk_size; /* in 512 byte sectors */ uint32_t chunk_size; /* in 512 byte sectors */
uint32_t le_count;
struct logical_volume *origin; struct logical_volume *origin;
struct logical_volume *cow; struct logical_volume *cow;
@@ -496,9 +497,9 @@ struct snapshot *find_cow(const struct logical_volume *lv);
struct snapshot *find_origin(const struct logical_volume *lv); struct snapshot *find_origin(const struct logical_volume *lv);
struct list *find_snapshots(const struct logical_volume *lv); struct list *find_snapshots(const struct logical_volume *lv);
int vg_add_snapshot(struct logical_volume *origin, int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
struct logical_volume *cow, int persistent, struct id *id, uint32_t extent_count,
int persistent, struct id *id, uint32_t chunk_size); uint32_t chunk_size);
int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow); int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow);

View File

@@ -104,9 +104,9 @@ struct list *find_snapshots(const struct logical_volume *lv)
return snaplist; return snaplist;
} }
int vg_add_snapshot(struct logical_volume *origin, int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
struct logical_volume *cow, int persistent, struct id *id, uint32_t extent_count,
int persistent, struct id *id, uint32_t chunk_size) uint32_t chunk_size)
{ {
struct snapshot *s; struct snapshot *s;
struct snapshot_list *sl; struct snapshot_list *sl;
@@ -127,13 +127,15 @@ int vg_add_snapshot(struct logical_volume *origin,
s->persistent = persistent; s->persistent = persistent;
s->chunk_size = chunk_size; s->chunk_size = chunk_size;
s->le_count = extent_count;
s->origin = origin; s->origin = origin;
s->cow = cow; s->cow = cow;
if (id) if (id)
s->id = *id; s->id = *id;
else if (!id_create(&s->id)) { else if (!id_create(&s->id)) {
log_error("Snapshot UUID creation failed"); log_error("Random UUID creation failed for snapshot %s.",
cow->name);
return 0; return 0;
} }

View File

@@ -48,13 +48,14 @@ void *malloc_aux(size_t s, const char *file, int line)
size_t tsize = s + sizeof(*nb) + sizeof(unsigned long); size_t tsize = s + sizeof(*nb) + sizeof(unsigned long);
if (s > 50000000) { if (s > 50000000) {
log_error("Huge memory allocation (size %" PRIuPTR log_error("Huge memory allocation (size %" PRIsize_t
") rejected - metadata corruption?", s); ") rejected - metadata corruption?", s);
return 0; return 0;
} }
if (!(nb = malloc(tsize))) { if (!(nb = malloc(tsize))) {
log_error("couldn't allocate any memory, size = %" PRIuPTR, s); log_error("couldn't allocate any memory, size = %" PRIsize_t,
s);
return 0; return 0;
} }
@@ -190,7 +191,7 @@ int dump_memory(void)
str[sizeof(str) - 1] = '\0'; str[sizeof(str) - 1] = '\0';
print_log(_LOG_INFO, mb->file, mb->line, print_log(_LOG_INFO, mb->file, mb->line,
"block %d at %p, size %" PRIdPTR "\t [%s]", "block %d at %p, size %" PRIsize_t "\t [%s]",
mb->id, mb->magic, mb->length, str); mb->id, mb->magic, mb->length, str);
tot += mb->length; tot += mb->length;
} }
@@ -220,7 +221,7 @@ void bounds_check(void)
void *malloc_aux(size_t s, const char *file, int line) void *malloc_aux(size_t s, const char *file, int line)
{ {
if (s > 50000000) { if (s > 50000000) {
log_error("Huge memory allocation (size %" PRIuPTR log_error("Huge memory allocation (size %" PRIsize_t
") rejected - metadata corruption?", s); ") rejected - metadata corruption?", s);
return 0; return 0;
} }

View File

@@ -27,14 +27,14 @@
((x) & 0xff000000U) >> 24 | \ ((x) & 0xff000000U) >> 24 | \
((x) & 0x0000ff00U) << 8 | \ ((x) & 0x0000ff00U) << 8 | \
((x) & 0x00ff0000U) >> 8) ((x) & 0x00ff0000U) >> 8)
# define bswap_64(x) (((x) & 0x00000000000000ffU) << 56 | \ # define bswap_64(x) (((x) & 0x00000000000000ffULL) << 56 | \
((x) & 0xff00000000000000U) >> 56 | \ ((x) & 0xff00000000000000ULL) >> 56 | \
((x) & 0x000000000000ff00U) << 40 | \ ((x) & 0x000000000000ff00ULL) << 40 | \
((x) & 0x00ff000000000000U) >> 40 | \ ((x) & 0x00ff000000000000ULL) >> 40 | \
((x) & 0x0000000000ff0000U) << 24 | \ ((x) & 0x0000000000ff0000ULL) << 24 | \
((x) & 0x0000ff0000000000U) >> 24 | \ ((x) & 0x0000ff0000000000ULL) >> 24 | \
((x) & 0x00000000ff000000U) << 8 | \ ((x) & 0x00000000ff000000ULL) << 8 | \
((x) & 0x000000ff00000000U) >> 8) ((x) & 0x000000ff00000000ULL) >> 8)
#endif #endif
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN

View File

@@ -295,7 +295,7 @@ static int _lvkmaj_disp(struct report_handle *rh, struct field *field,
struct lvinfo info; struct lvinfo info;
uint64_t minusone = UINT64_C(-1); uint64_t minusone = UINT64_C(-1);
if (lv_info(lv, &info) && info.exists) if (lv_info(lv, &info, 0) && info.exists)
return _int_disp(rh, field, &info.major); return _int_disp(rh, field, &info.major);
else else
return _int_disp(rh, field, &minusone); return _int_disp(rh, field, &minusone);
@@ -310,7 +310,7 @@ static int _lvkmin_disp(struct report_handle *rh, struct field *field,
struct lvinfo info; struct lvinfo info;
uint64_t minusone = UINT64_C(-1); uint64_t minusone = UINT64_C(-1);
if (lv_info(lv, &info) && info.exists) if (lv_info(lv, &info, 0) && info.exists)
return _int_disp(rh, field, &info.minor); return _int_disp(rh, field, &info.minor);
else else
return _int_disp(rh, field, &minusone); return _int_disp(rh, field, &minusone);
@@ -362,7 +362,7 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
else else
repstr[3] = '-'; repstr[3] = '-';
if (lv_info(lv, &info) && info.exists) { if (lv_info(lv, &info, 1) && info.exists) {
if (info.suspended) if (info.suspended)
repstr[4] = 's'; /* Suspended */ repstr[4] = 's'; /* Suspended */
else else
@@ -774,7 +774,7 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
} }
if (!(snap = find_cow(lv)) || if (!(snap = find_cow(lv)) ||
(lv_info(snap->cow, &info) && !info.exists)) { (lv_info(snap->cow, &info, 0) && !info.exists)) {
field->report_string = ""; field->report_string = "";
*sortval = UINT64_C(0); *sortval = UINT64_C(0);
field->sort_value = sortval; field->sort_value = sortval;

View File

@@ -31,7 +31,7 @@ static const char *_name(const struct lv_segment *seg)
static int _text_import(struct lv_segment *seg, const struct config_node *sn, static int _text_import(struct lv_segment *seg, const struct config_node *sn,
struct hash_table *pv_hash) struct hash_table *pv_hash)
{ {
uint32_t chunk_size; uint32_t chunk_size, extent_count;
const char *org_name, *cow_name; const char *org_name, *cow_name;
struct logical_volume *org, *cow; struct logical_volume *org, *cow;
@@ -70,7 +70,11 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
return 0; return 0;
} }
if (!vg_add_snapshot(org, cow, 1, &seg->lv->lvid.id[1], chunk_size)) { if (!get_config_uint32(sn, "extent_count", &extent_count))
extent_count = org->le_count;
if (!vg_add_snapshot(org, cow, 1, &seg->lv->lvid.id[1], extent_count,
chunk_size)) {
stack; stack;
return 0; return 0;
} }
@@ -81,6 +85,8 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
static int _text_export(const struct lv_segment *seg, struct formatter *f) static int _text_export(const struct lv_segment *seg, struct formatter *f)
{ {
outf(f, "chunk_size = %u", seg->chunk_size); outf(f, "chunk_size = %u", seg->chunk_size);
if (seg->len != seg->origin->le_count)
outf(f, "extent_count = %u", seg->len);
outf(f, "origin = \"%s\"", seg->origin->name); outf(f, "origin = \"%s\"", seg->origin->name);
outf(f, "cow_store = \"%s\"", seg->cow->name); outf(f, "cow_store = \"%s\"", seg->cow->name);

View File

@@ -29,9 +29,7 @@ static unsigned char _inverse_c[256];
int lvid_create(union lvid *lvid, struct id *vgid) int lvid_create(union lvid *lvid, struct id *vgid)
{ {
memcpy(lvid->id, vgid, sizeof(*lvid->id)); memcpy(lvid->id, vgid, sizeof(*lvid->id));
id_create(&lvid->id[1]); return id_create(&lvid->id[1]);
return 1;
} }
void uuid_from_num(char *uuid, uint32_t num) void uuid_from_num(char *uuid, uint32_t num)
@@ -83,16 +81,18 @@ int id_create(struct id *id)
memset(id->uuid, 0, len); memset(id->uuid, 0, len);
if ((randomfile = open("/dev/urandom", O_RDONLY)) < 0) { if ((randomfile = open("/dev/urandom", O_RDONLY)) < 0) {
log_sys_error("open", "id_create"); log_sys_error("open", "id_create: /dev/urandom");
return 0; return 0;
} }
if (read(randomfile, id->uuid, len) != len) { if (read(randomfile, id->uuid, len) != len) {
log_sys_error("read", "id_create"); log_sys_error("read", "id_create: /dev/urandom");
close(randomfile); if (close(randomfile))
stack;
return 0; return 0;
} }
close(randomfile); if (close(randomfile))
stack;
/* /*
* Skip out the last 2 chars in randomized creation for LVM1 * Skip out the last 2 chars in randomized creation for LVM1

View File

@@ -33,29 +33,44 @@ previously configured for LVM with
.SH OPTIONS .SH OPTIONS
See \fBlvm\fP for common options. See \fBlvm\fP for common options.
.TP .TP
.BR \-A ", " \-\-autobackup " {" y | n }
Controls automatic backup of VG metadata after the change (see
.BR vgcfgbackup (8)).
Default is yes.
.TP
.BR \-l ", " \-\-maxlogicalvolumes " " \fIMaxLogicalVolumes\fR .BR \-l ", " \-\-maxlogicalvolumes " " \fIMaxLogicalVolumes\fR
Sets the maximum possible logical volume count. Sets the maximum number of logical volumes allowed in this
More logical volumes can't be created in this volume group. volume group.
Absolute maximum is 256. The setting can be changed with \fBvgchange\fP.
For volume groups with metadata in lvm1 format, the limit
and default value is 255.
If the metadata uses lvm2 format, the default value is 0
which removes this restriction: there is then no limit.
.TP .TP
.BR \-p ", " \-\-maxphysicalvolumes " " \fIMaxPhysicalVolumes\fR .BR \-p ", " \-\-maxphysicalvolumes " " \fIMaxPhysicalVolumes\fR
Sets the maximum possible physical volume count. Sets the maximum number of physical volumes that can belong
More physical volumes can't be included in this volume group. to this volume group.
Absolute maximum is 256. The setting can be changed with \fBvgchange\fP.
For volume groups with metadata in lvm1 format, the limit
and default value is 255.
If the metadata uses lvm2 format, the default value is 0
which removes this restriction: there is then no limit.
If you have a large number of physical volumes in
a volume group with metadata in lvm2 format,
for tool performance reasons, you should consider
some use of \fB--metadatacopies 0\fP
as described in \fBpvcreate(8)\fP.
.TP .TP
.BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBkKmMgGtT\fR] .BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBkKmMgGtT\fR]
Sets the physical extent size on physical volumes of this volume group. Sets the physical extent size on physical volumes of this volume group.
A size suffix (k for kilobytes up to t for terabytes) is optional, megabytes A size suffix (k for kilobytes up to t for terabytes) is optional, megabytes
is the default if no suffix is present. Values can be from 8 KB to 16 GB in is the default if no suffix is present. Values can be from 8 KB to 16 GB in
powers of 2. The default of 4 MB causes maximum LV sizes of ~256GB because as powers of 2. The default is 4 MB.
many as ~64k extents are supported per LV. In case larger maximum LV sizes are Once this value has been set, it is difficult to change it without recreating
needed (later), you need to set the PE size to a larger value as well. Later the volume group which would involve backing up and restoring data on any
changes of the PE size in an existing VG are not supported. logical volumes.
If the volume group metadata uses lvm1 format, there is a limit of 65534
extents in each logical volume, so the default of 4 MB leads to a maximum
logical volume size of around 256GB.
If the volume group metadata uses lvm2 format there is no such restriction,
although having a large number of extents will slow down
the tools but have no impact on I/O performance to the logical volume.
The 2.4 kernel has a limitation of 2TB per block device.
.SH EXAMPLES .SH EXAMPLES
To create a volume group named To create a volume group named
.B test_vg .B test_vg
@@ -67,11 +82,6 @@ with default physical extent size of 4MB:
\ vgcreate test_vg /dev/sdk1 /dev/sdl1 \ vgcreate test_vg /dev/sdk1 /dev/sdl1
.fi .fi
To limit kernel memory usage, there is a limit of 65536 physical extents
(PE) per logical volume, so the PE size determines the maximum logical volume
size. The default PE size of 4MB limits a single logical volume to 256GB (see
the -s option to raise that limit).
There is also (as of Linux 2.4) a kernel limitation of 2TB per block device.
.SH SEE ALSO .SH SEE ALSO
.BR lvm (8), .BR lvm (8),
.BR pvdisplay (8), .BR pvdisplay (8),

File diff suppressed because it is too large Load Diff

View File

@@ -13,15 +13,12 @@
LOCK_FILE="/var/lock/subsys/clvmd" LOCK_FILE="/var/lock/subsys/clvmd"
# lvdisplay="/sbin/lvm.static lvdisplay"
# FIXME -- the lvm2-cluster rpms put the lvm tools in a different location vgchange="/sbin/lvm.static vgchange"
# vgscan="/sbin/lvm.static vgscan"
lvdisplay=/usr/sbin/cluster/lvdisplay
vgchange=/usr/sbin/cluster/vgchange
start() start()
{ {
modprobe dlm
for rtrn in 0 for rtrn in 0
do do
if ! pidof clvmd > /dev/null if ! pidof clvmd > /dev/null
@@ -40,6 +37,9 @@ start()
fi fi
fi fi
# refresh cache
$vgscan > /dev/null 2>&1
if [ -n "$LVM_VGS" ] if [ -n "$LVM_VGS" ]
then then
for vg in $LVM_VGS for vg in $LVM_VGS
@@ -124,7 +124,6 @@ stop()
echo echo
fi fi
done done
modprobe -r dlm > /dev/null 2>&1
return $rtrn return $rtrn
} }

View File

@@ -256,7 +256,7 @@ static int lvchange_persistent(struct cmd_context *cmd,
log_error("Major number must be specified with -My"); log_error("Major number must be specified with -My");
return 0; return 0;
} }
if (lv_info(lv, &info) && info.exists && if (lv_info(lv, &info, 0) && info.exists &&
!arg_count(cmd, force_ARG)) { !arg_count(cmd, force_ARG)) {
if (yes_no_prompt("Logical volume %s will be " if (yes_no_prompt("Logical volume %s will be "
"deactivated temporarily. " "deactivated temporarily. "

View File

@@ -609,7 +609,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
return 0; return 0;
} }
if (!vg_add_snapshot(org, lv, 1, NULL, lp->chunk_size)) { if (!vg_add_snapshot(org, lv, 1, NULL, lv->le_count,
lp->chunk_size)) {
log_err("Couldn't create snapshot."); log_err("Couldn't create snapshot.");
return 0; return 0;
} }

View File

@@ -41,7 +41,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
/* FIXME Ensure not referred to by another existing LVs */ /* FIXME Ensure not referred to by another existing LVs */
if (lv_info(lv, &info)) { if (lv_info(lv, &info, 1)) {
if (info.open_count) { if (info.open_count) {
log_error("Can't remove open logical volume \"%s\"", log_error("Can't remove open logical volume \"%s\"",
lv->name); lv->name);

View File

@@ -364,7 +364,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
if (lp->resize == LV_REDUCE || lp->resizefs) { if (lp->resize == LV_REDUCE || lp->resizefs) {
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
if (!lv_info(lv, &info) && driver_version(NULL, 0)) { if (!lv_info(lv, &info, 1) && driver_version(NULL, 0)) {
log_error("lv_info failed: aborting"); log_error("lv_info failed: aborting");
return ECMD_FAILED; return ECMD_FAILED;
} }

View File

@@ -25,7 +25,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
const char *active_str, *snapshot_str; const char *active_str, *snapshot_str;
/* FIXME Add -D arg to skip this! */ /* FIXME Add -D arg to skip this! */
if (lv_info(lv, &info) && info.exists) if (lv_info(lv, &info, 0) && info.exists)
active_str = "ACTIVE "; active_str = "ACTIVE ";
else else
active_str = "inactive "; active_str = "inactive ";

View File

@@ -173,7 +173,11 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
} }
} else { } else {
/* --uuid: Change PV ID randomly */ /* --uuid: Change PV ID randomly */
id_create(&pv->id); if (!id_create(&pv->id)) {
log_error("Failed to generate new random UUID for %s.",
pv_name);
return 0;
}
} }
log_verbose("Updating physical volume \"%s\"", pv_name); log_verbose("Updating physical volume \"%s\"", pv_name);

View File

@@ -18,6 +18,9 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
/*
* Metadata iteration functions
*/
int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg, int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct list *arg_lvnames, struct list *tags, struct list *arg_lvnames, struct list *tags,
void *handle, void *handle,
@@ -93,23 +96,6 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
return ret_max; return ret_max;
} }
struct volume_group *recover_vg(struct cmd_context *cmd, const char *vgname,
int lock_type)
{
int consistent = 1;
lock_type &= ~LCK_TYPE_MASK;
lock_type |= LCK_WRITE;
if (!lock_vol(cmd, vgname, lock_type)) {
log_error("Can't lock %s for metadata recovery: skipping",
vgname);
return NULL;
}
return vg_read(cmd, vgname, &consistent);
}
int process_each_lv(struct cmd_context *cmd, int argc, char **argv, int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
int lock_type, void *handle, int lock_type, void *handle,
int (*process_single) (struct cmd_context * cmd, int (*process_single) (struct cmd_context * cmd,
@@ -608,6 +594,9 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
return ret_max; return ret_max;
} }
/*
* Determine volume group name from a logical volume name
*/
const char *extract_vgname(struct cmd_context *cmd, const char *lv_name) const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
{ {
const char *vg_name = lv_name; const char *vg_name = lv_name;
@@ -666,6 +655,9 @@ const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
return vg_name; return vg_name;
} }
/*
* Extract default volume group name from environment
*/
char *default_vgname(struct cmd_context *cmd) char *default_vgname(struct cmd_context *cmd)
{ {
char *vg_path; char *vg_path;
@@ -694,6 +686,9 @@ char *default_vgname(struct cmd_context *cmd)
return pool_strdup(cmd->mem, vg_path); return pool_strdup(cmd->mem, vg_path);
} }
/*
* Process physical extent range specifiers
*/
static int _add_pe_range(struct pool *mem, struct list *pe_ranges, static int _add_pe_range(struct pool *mem, struct list *pe_ranges,
uint32_t start, uint32_t count) uint32_t start, uint32_t count)
{ {
@@ -928,6 +923,29 @@ struct list *clone_pv_list(struct pool *mem, struct list *pvsl)
return r; return r;
} }
/*
* Attempt metadata recovery
*/
struct volume_group *recover_vg(struct cmd_context *cmd, const char *vgname,
int lock_type)
{
int consistent = 1;
lock_type &= ~LCK_TYPE_MASK;
lock_type |= LCK_WRITE;
if (!lock_vol(cmd, vgname, lock_type)) {
log_error("Can't lock %s for metadata recovery: skipping",
vgname);
return NULL;
}
return vg_read(cmd, vgname, &consistent);
}
/*
* Execute and wait for external command
*/
int exec_cmd(const char *command, const char *fscmd, const char *lv_path, int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
const char *size) const char *size)
{ {

View File

@@ -264,7 +264,11 @@ static int _vgchange_uuid(struct cmd_context *cmd, struct volume_group *vg)
if (!archive(vg)) if (!archive(vg))
return ECMD_FAILED; return ECMD_FAILED;
id_create(&vg->id); if (!id_create(&vg->id)) {
log_error("Failed to generate new random UUID for VG %s.",
vg->name);
return ECMD_FAILED;
}
list_iterate_items(lvl, &vg->lvs) { list_iterate_items(lvl, &vg->lvs) {
memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id)); memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));

View File

@@ -94,7 +94,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
lv = lvl->lv; lv = lvl->lv;
if (lvnum_from_lvid(&lv->lvid) < MAX_RESTRICTED_LVS) if (lvnum_from_lvid(&lv->lvid) < MAX_RESTRICTED_LVS)
continue; continue;
if (lv_info(lv, &info) && info.exists) { if (lv_info(lv, &info, 0) && info.exists) {
log_error("Logical volume %s must be " log_error("Logical volume %s must be "
"deactivated before conversion.", "deactivated before conversion.",
lv->name); lv->name);

View File

@@ -56,7 +56,7 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
log_print("Reading all physical volumes. This may take a while..."); log_print("Reading all physical volumes. This may take a while...");
maxret = process_each_vg(cmd, argc, argv, LCK_VG_READ, 1, NULL, maxret = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, NULL,
&vgscan_single); &vgscan_single);
if (arg_count(cmd, mknodes_ARG)) { if (arg_count(cmd, mknodes_ARG)) {