1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-28 04:23:49 +03:00

Compare commits

...

89 Commits

Author SHA1 Message Date
Alasdair Kergon
33d516748f 1.01.01 2005-03-29 14:47:39 +00:00
Alasdair Kergon
de17f6f0fd Update dmsetup man page. 2005-03-29 14:46:30 +00:00
Alasdair Kergon
756731fc02 Drop-in devmap_name replacement. 2005-03-27 11:37:46 +00:00
Alasdair Kergon
e46be0415f post-release 2005-03-22 16:50:17 +00:00
Alasdair Kergon
aa02fb50bf update pofile 2005-03-22 15:13:48 +00:00
Alasdair Kergon
8b6cd9c772 2.01.08 2005-03-22 15:12:37 +00:00
Alasdair Kergon
cdd0d3351a Add clustered attribute so vgchange can identify clustered VGs w/o locking. 2005-03-21 22:55:12 +00:00
Alasdair Kergon
8b6d584529 Improve detection of external changes affecting internal cache. 2005-03-21 22:40:35 +00:00
Alasdair Kergon
f49fdd4141 Add 'already in device cache' debug message. 2005-03-21 14:51:49 +00:00
Alasdair Kergon
b26e1be81a Add -a to pvdisplay -C. 2005-03-21 14:47:36 +00:00
Alasdair Kergon
bacab38d7f Avoid rmdir opendir error messsages when dir was already removed. 2005-03-21 14:43:02 +00:00
Alasdair Kergon
701c05ce96 Tighten signal handlers. 2005-03-21 14:16:16 +00:00
Alasdair Kergon
438c452585 Fix WHATS_NEW. 2005-03-10 23:04:42 +00:00
Alasdair Kergon
0a7a1eff3f Avoid some compiler warnings. 2005-03-10 22:34:17 +00:00
Alasdair Kergon
87e743e381 Additional rename failure error message. 2005-03-10 22:31:10 +00:00
Alasdair Kergon
a03f1b3d55 read/write may be macros 2005-03-10 20:23:36 +00:00
Alasdair Kergon
2d8dc3d243 post-release 2005-03-10 20:22:40 +00:00
Patrick Caulfield
b982232cc5 Don't take out the lvm_thread_lock at startup - it only protects the jobs list.
DEBUGLOG() message now print threadid rather than PID which is more useful.
2005-03-09 14:08:11 +00:00
Alasdair Kergon
61c8d728ac update pofile 2005-03-08 13:48:13 +00:00
Alasdair Kergon
851a2bf855 Cope with new devices appearing by rescanning /dev if a uuid can't be found. 2005-03-08 13:46:17 +00:00
Alasdair Kergon
e0bdde3630 Remove DESTDIR from LVM_SHARED_PATH. 2005-03-08 13:39:39 +00:00
Patrick Caulfield
6a0dcd7f0e make clvmd FDs close-on-exec, to avoid warnings when running lvm via popen.
clvmd-gulm unlocks VG & orphan locks at startup in case they are stale.
clvmd-gulm now unlocks VG & orphan locks if client dies.
2005-03-07 17:03:44 +00:00
Alasdair Kergon
75f0b4c879 post-release 2005-03-03 22:31:01 +00:00
Alasdair Kergon
db536a9504 2.01.06 2005-03-03 22:26:34 +00:00
Alasdair Kergon
0fb114dede Option to suppress warnings of file descriptors left open. 2005-03-03 22:09:20 +00:00
Alasdair Kergon
e703342179 Suppress 'open failed' error messages during scanning. 2005-03-03 21:54:35 +00:00
Alasdair Kergon
35c8f4a611 Fix default value of metadatacopies in documentation (2->1). 2005-03-03 21:52:58 +00:00
Patrick Caulfield
7c89ae44a9 Fix clvmd-gulm node up/down code so it actually works.
clvmd-gulm now releases locks when shut down.
2005-02-22 16:26:21 +00:00
Patrick Caulfield
84fe06da22 ./configure --enable-debug now enables debugging code in clvmd 2005-02-21 15:58:06 +00:00
Patrick Caulfield
806318c8b3 Always manipulate both locks in sync_lock() otherwise they get left
hanging around and cause trouble.
2005-02-21 14:36:09 +00:00
Alasdair Kergon
3aac2e1822 post-release 2005-02-18 19:06:16 +00:00
Alasdair Kergon
168baef433 Static binary invokes dynamic binary if appropriate. 2005-02-18 18:58:31 +00:00
Patrick Caulfield
6dba6cd78d Cope with more than one message arriving at the TCP socket, also
fix some instances where the length in the message was wrong (cman
code didn't notice this because it is packet-based comms anyway)
2005-02-18 15:31:32 +00:00
Patrick Caulfield
502250d08f Fix gulm->errno error number conversion. 2005-02-17 12:56:19 +00:00
Patrick Caulfield
7395f0e680 Make config check a little more tolerant of library names. 2005-02-14 09:07:14 +00:00
Alasdair Kergon
494d3fdaca post-release 2005-02-09 18:26:38 +00:00
Alasdair Kergon
7b86a157de Add fixed offset to imported pool minor numbers. 2005-02-09 17:49:36 +00:00
Adam Manthei
0988c41785 o cluster lvm requires that /usr/sbin/$TOOL is used instead of
/sbin/lvm.static $TOOL

o made variables LVDISPLAY, VGSCAN and VGCHANGE configurable in
  /etc/sysconfig/cluster
2005-02-08 17:20:24 +00:00
Patrick Caulfield
522db1bf01 Fix thread shutdown race which could cause clvmd to hang in pthread_join. 2005-02-08 09:05:58 +00:00
Patrick Caulfield
06f066f90d Revert last clvmd patch. More testing reveals that this just doesn't
work yet.
2005-02-07 14:45:38 +00:00
Patrick Caulfield
f37b20677b Make clvmd use the command library rather than popen() to
preload the lock state.
2005-02-07 10:04:27 +00:00
Alasdair Kergon
cd2eac1032 lvm2cmd.so should skip the check for open fds. 2005-02-03 16:34:53 +00:00
Alasdair Kergon
8ac38d58d7 Remove unused -f from pvmove 2005-02-02 14:31:48 +00:00
Patrick Caulfield
4c80cc313a Make clvmd do a quick sanity check on the clustering bits of lvm.conf 2005-02-02 11:42:29 +00:00
Patrick Caulfield
1c65fee9b4 Get rid of "connection refused" message because Corey doesn't like it. 2005-02-02 09:17:56 +00:00
Alasdair Kergon
90dda7edc1 post-release 2005-02-01 16:40:16 +00:00
Alasdair Kergon
da054fae20 pofile 2005-02-01 16:33:45 +00:00
Alasdair Kergon
bdb6611e30 2.01.03 2005-02-01 16:29:22 +00:00
Alasdair Kergon
9284f973f1 More 64-bit display/report fixes. 2005-02-01 16:19:48 +00:00
Alasdair Kergon
2bfd64c3c9 Add option to compile without ioctl for testing. 2005-01-27 16:16:54 +00:00
Alasdair Kergon
939d24cce5 Fix DM_LIB_VERSION sed 2005-01-27 15:53:28 +00:00
Alasdair Kergon
27b0183c46 More informative startup mesg if can't create /etc/lvm. 2005-01-27 15:50:34 +00:00
Alasdair Kergon
d14efacac7 Fix snapshot device size bug (since 2.01.01). 2005-01-27 15:48:49 +00:00
Patrick Caulfield
150a002c40 Don't print CMAN error if initial probe fails - we could be running with GULM. 2005-01-26 09:30:52 +00:00
Patrick Caulfield
ce0def3bd8 Remove superflous &
Gulm clvmd no longer hangs trying to talk to a rebooted node.
2005-01-25 16:46:29 +00:00
Patrick Caulfield
ee20fa97c2 Make clvmd announce it's startup and cluster connection in syslog. 2005-01-24 15:31:13 +00:00
Alasdair Kergon
7403b7d700 postrelease 2005-01-21 19:03:48 +00:00
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
Alasdair Kergon
181ea9a381 Add dm_task_no_open_count() to skip getting open_count. 2005-01-12 22:10:14 +00:00
Alasdair Kergon
76b8f2854e Adjust RHEL4 clvmd init script priority. 2005-01-11 22:00:36 +00:00
Alasdair Kergon
320e5198f9 post-2.00.33 2005-01-07 20:06:49 +00:00
Alasdair Kergon
e522539e2d 2.00.33 2005-01-07 19:50:54 +00:00
Alasdair Kergon
7c996b83d2 post-1.00.21 2005-01-07 17:10:16 +00:00
Alasdair Kergon
3dd354d7aa 1.00.21 2005-01-07 15:53:37 +00:00
Alasdair Kergon
f4ad6e2157 Fix /proc/devices parsing. 2005-01-07 15:39:53 +00:00
Patrick Caulfield
8b170dc2bf Fix off-by-one error in cluster_locking that could case read hangs. 2005-01-07 14:22:49 +00:00
Alasdair Kergon
dcb9d779bf post-1.00.20 2005-01-06 18:41:38 +00:00
101 changed files with 3994 additions and 2629 deletions

View File

@@ -1 +1 @@
2.00.33-cvs (2004-12-22)
2.01.09-cvs (2005-03-22)

View File

@@ -1,10 +1,94 @@
Version 2.00.33 -
Version 2.01.09 -
=================================
Version 2.01.08 - 22nd March 2005
=================================
Add clustered attribute so vgchange can identify clustered VGs w/o locking.
Improve detection of external changes affecting internal cache.
Add 'already in device cache' debug message.
Add -a to pvdisplay -C.
Avoid rmdir opendir error messsages when dir was already removed.
Tighten signal handlers.
Avoid some compiler warnings.
Additional rename failure error message.
read/write may be macros.
clvmd: don't take out lvm thread lock at startup, it only protects jobs list.
Version 2.01.07 - 8th March 2005
================================
Cope with new devices appearing by rescanning /dev if a uuid can't be found.
Remove DESTDIR from LVM_SHARED_PATH.
clvmd fixes: make FDs close-on-exec
gulm unlocks VG & orphan locks at startup in case they are stale
gulm now unlocks VG & orphan locks if client dies.
Version 2.01.06 - 1st March 2005
================================
Suppress 'open failed' error messages during scanning.
Option to suppress warnings of file descriptors left open.
Fix default value of metadatacopies in documentation (2->1).
Fix clvmd-gulm locking.
./configure --enable-debug now enables debugging code in clvmd.
Fix clvmd-gulm node up/down code so it actually works.
clvmd-gulm now releases locks when shut down.
Version 2.01.05 - 18th February 2005
====================================
Static binary invokes dynamic binary if appropriate.
Make clvmd config check a little more tolerant.
gulm clvmd can now cope with >1 message arriving in a TCP message.
Version 2.01.04 - 9th February 2005
===================================
Add fixed offset to imported pool minor numbers.
Update binary pathnames in clvmd_init_rhel4.
lvm2cmd.so should skip the check for open fds.
Remove unused -f from pvmove.
Gulm clvmd doesn't report "connection refused" errors.
clvmd does a basic config file sanity check at startup.
Fix potential thread shutdown race in clvmd.
Version 2.01.03 - 1st February 2005
===================================
More 64-bit display/report fixes.
More informative startup mesg if can't create /etc/lvm.
Fix snapshot device size bug (since 2.01.01).
clvmd announces startup and cluster connection in syslog.
Gulm clvmd doesn't hang trying to talk to a rebooted node.
Gulm clvmd doesn't print cman error on startup.
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.
Enable building of CMAN & GULM versions of clvmd into a single binary
Version 2.00.33 - 7th January 2005
==================================
pvcreate wipes first 4 sectors unless given --zero n.
gulm clvmd now uses new ccsd key names.
gulm clvmd now doesn't ignore the first node in cluster.conf
Improve clvmd failure message if it's already running.
Allow user to kill clvmd during initialisation.
Fix off-by-one error in cluster_locking that could cause read hangs.
Version 2.00.32 - 22nd December 2004
====================================

View File

@@ -1,3 +1,18 @@
Version 1.01.01 - 29 Mar 2005
=============================
Update dmsetup man page.
Drop-in devmap_name replacement.
Add option to compile without ioctl for testing.
Fix DM_LIB_VERSION sed.
Version 1.01.00 - 17 Jan 2005
=============================
Add dm_task_no_open_count() to skip getting open_count.
Version 1.00.21 - 7 Jan 2005
============================
Fix /proc/devices parsing.
Version 1.00.20 - 6 Jan 2005
============================
Attempt to fix /dev/mapper/control transparently if it's wrong.

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
AC_MSG_CHECKING(whether to build cluster LVM daemon)
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] ],
[ CLVMD="$withval" ],
[ CLVMD="none" ])
if test x$CLVMD = xyes; then
CLVMD=cman
CLVMD=all
fi
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))
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_FUNCS(dup2 getmntent memmove select socket,,AC_MSG_ERROR(bailing out))
AC_FUNC_GETMNTENT

View File

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

View File

@@ -43,6 +43,7 @@ struct clvm_header {
/* Flags */
#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_NODEERRS 4 /* Reply has errors in node-specific portion */
/* Name of the local socket to communicate between libclvm and clvmd */
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd";

View File

@@ -66,7 +66,7 @@ struct lock_wait {
struct dlm_lksb lksb;
};
int init_cluster()
static int _init_cluster(void)
{
struct sockaddr_cl saddr;
int port = CLUSTER_PORT_CLVMD;
@@ -74,9 +74,11 @@ int init_cluster()
/* Open the cluster communication socket */
cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
if (cluster_sock == -1) {
syslog(LOG_ERR, "Can't open cluster manager socket: %m");
/* Don't print an error here because we could be just probing for CMAN */
return -1;
}
/* Set Close-on-exec */
fcntl(cluster_sock, F_SETFD, 1);
/* Bind to our port number on the cluster.
Writes to this will block if the cluster loses quorum */
@@ -101,21 +103,27 @@ int init_cluster()
return -1;
}
dlm_ls_pthread_init(lockspace);
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;
}
int get_num_nodes()
static int _get_num_nodes()
{
return num_nodes;
}
/* 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 msghdr msg;
@@ -135,7 +143,7 @@ int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
if (csid) {
msg.msg_name = &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 */
msg.msg_name = NULL;
@@ -151,26 +159,26 @@ int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
return len;
}
void get_our_csid(char *csid)
static void _get_our_csid(char *csid)
{
int i;
memset(csid, 0, MAX_CSID_LEN);
memset(csid, 0, CMAN_MAX_CSID_LEN);
for (i = 0; i < num_nodes; i++) {
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) */
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 *,
int))
{
int i;
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]);
if (!node_updown[nodes[i].node_id])
somedown = -1;
@@ -202,7 +210,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 iovec iov[2];
@@ -254,7 +262,7 @@ int cluster_fd_callback(struct local_client *client, char *buf, int len, char *c
return len;
}
void add_up_node(char *csid)
static void _add_up_node(char *csid)
{
/* It's up ! */
int nodeid = nodeid_from_csid(csid);
@@ -278,7 +286,7 @@ void add_up_node(char *csid)
DEBUGLOG("Added new node %d to updown list\n", nodeid);
}
void cluster_closedown()
static void _cluster_closedown()
{
unlock_all();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
@@ -307,7 +315,7 @@ static int is_listening(int nodeid)
/* Populate the list of CLVMDs running.
called only at startup time */
void count_clvmds_running(void)
static void count_clvmds_running(void)
{
int i;
@@ -366,13 +374,13 @@ static void get_members()
}
/* 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;
for (i = 0; i < num_nodes; i++) {
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;
}
}
@@ -380,12 +388,12 @@ int csid_from_name(char *csid, char *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;
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);
return 0;
}
@@ -396,7 +404,7 @@ int name_from_csid(char *csid, char *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;
@@ -416,12 +424,12 @@ static int nodeid_from_csid(char *csid)
{
int nodeid;
memcpy(&nodeid, csid, MAX_CSID_LEN);
memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
return nodeid;
}
int is_quorate()
static int _is_quorate()
{
return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0);
}
@@ -435,7 +443,7 @@ static void sync_ast_routine(void *arg)
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;
struct lock_wait lwait;
@@ -478,7 +486,7 @@ int sync_lock(const char *resource, int mode, int flags, int *lockid)
return 0;
}
int sync_unlock(const char *resource /* UNUSED */, int lockid)
static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
{
int status;
struct lock_wait lwait;
@@ -505,3 +513,28 @@ int sync_unlock(const char *resource /* UNUSED */, int lockid)
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

@@ -274,9 +274,10 @@ void cmd_client_cleanup(struct local_client *client)
hash_iterate(v, lock_hash) {
int lkid = (int)(long)hash_get_data(lock_hash, v);
char *lockname = hash_get_key(lock_hash, v);
DEBUGLOG("cleanup: Unlocking lkid %x\n", lkid);
sync_unlock("DUMMY", lkid);
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
sync_unlock(lockname, lkid);
}
hash_destroy(lock_hash);

View File

@@ -22,33 +22,47 @@
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);
extern int name_from_csid(char *csid, char *name);
extern int csid_from_name(char *csid, char *name);
extern int get_num_nodes(void);
extern int cluster_fd_callback(struct local_client *fd, char *buf, int len,
int (*name_from_csid) (char *csid, char *name);
int (*csid_from_name) (char *csid, char *name);
int (*get_num_nodes) (void);
int (*cluster_fd_callback) (struct local_client *fd, char *buf, int len,
char *csid, struct local_client **new_client);
extern int init_cluster(void);
extern int get_main_cluster_fd(void); /* gets accept FD or cman cluster socket */
extern int cluster_do_node_callback(struct local_client *client,
int (*get_main_cluster_fd) (void); /* gets accept FD or cman cluster socket */
int (*cluster_do_node_callback) (struct local_client *client,
void (*callback) (struct local_client *,
char *csid, int node_up));
extern int is_quorate(void);
int (*is_quorate) (void);
extern void get_our_csid(char *csid);
extern void add_up_node(char *csid);
extern void cluster_closedown(void);
void (*get_our_csid) (char *csid);
void (*add_up_node) (char *csid);
void (*cluster_closedown) (void);
extern int sync_lock(const char *resource, int mode, int flags, int *lockid);
extern int sync_unlock(const char *resource, int lockid);
int (*sync_lock) (const char *resource, int mode, int flags, int *lockid);
int (*sync_unlock) (const char *resource, int lockid);
};
#ifdef USE_GULM
#include "tcp-comms.h"
#else
/* cman */
#include "cnxman-socket.h"
#define MAX_CSID_LEN 4
# include "tcp-comms.h"
struct cluster_ops *init_gulm_cluster(void);
#define MAX_CSID_LEN GULM_MAX_CSID_LEN
#define MAX_CLUSTER_MEMBER_NAME_LEN GULM_MAX_CLUSTER_MEMBER_NAME_LEN
#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

View File

@@ -2,6 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
@@ -46,6 +47,7 @@
#include "log.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "lvm-functions.h"
#include "clvmd.h"
#include "hash.h"
#include "clvmd-gulm.h"
@@ -65,6 +67,7 @@ static uint8_t current_corestate;
static int num_nodes;
static char *cluster_name;
static int in_shutdown = 0;
static pthread_mutex_t lock_start_mutex;
static volatile int lock_start_flag;
@@ -72,7 +75,7 @@ static volatile int lock_start_flag;
struct node_info
{
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
@@ -88,6 +91,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,
struct local_client **new_client);
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 */
extern struct hash_table *sock_hash;
@@ -112,6 +117,9 @@ static int add_internal_client(int fd, fd_callback_t callback)
client->callback = callback;
add_client(client);
/* Set Close-on-exec */
fcntl(fd, F_SETFD, 1);
return 0;
}
@@ -123,7 +131,7 @@ static lg_lockspace_callbacks_t lock_callbacks;
static void badsig_handler(int sig)
{
DEBUGLOG("got sig %d\n", sig);
cluster_closedown();
_cluster_closedown();
exit(0);
}
@@ -135,7 +143,7 @@ static void sighup_handler(int sig)
get_all_cluster_nodes();
}
int init_cluster()
static int _init_cluster(void)
{
int status;
int ccs_h;
@@ -222,7 +230,7 @@ int init_cluster()
exit(status);
}
/* Request a list of nodes, we can;t really do anything until
/* Request a list of nodes, we can't really do anything until
this comes back */
status = lg_core_nodelist(gulm_if);
if (status)
@@ -241,9 +249,11 @@ int init_cluster()
return 0;
}
void cluster_closedown()
static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
in_shutdown = 1;
unlock_all();
lg_lock_logout(gulm_if);
lg_core_logout(gulm_if);
lg_release(gulm_if);
@@ -256,6 +266,7 @@ static void drop_expired_locks(char *nodename)
struct utsname nodeinfo;
uint8_t mask[GIO_KEY_SIZE];
DEBUGLOG("Dropping expired locks for %s\n", nodename?nodename:"(null)");
memset(mask, 0xff, GIO_KEY_SIZE);
if (!nodename)
@@ -339,7 +350,7 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
{
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 we can't find that node then re-read the config file in case it
@@ -348,7 +359,7 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
get_all_cluster_nodes();
/* 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)
{
DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
@@ -356,11 +367,16 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
}
}
set_node_state(ninfo, (char *)&ip, state);
set_node_state(ninfo, (char *)ip, state);
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)
{
DEBUGLOG("CORE nodelist\n");
@@ -381,14 +397,14 @@ static int core_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *
{
if (type == lglcb_stop)
{
char ourcsid[MAX_CSID_LEN];
char ourcsid[GULM_MAX_CSID_LEN];
DEBUGLOG("Got Nodelist, stop\n");
clvmd_cluster_init_completed();
/* Mark ourself as up */
get_our_csid(ourcsid);
add_up_node(ourcsid);
_get_our_csid(ourcsid);
gulm_add_up_node(ourcsid);
}
else
{
@@ -417,7 +433,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 (!nodeip)
csid_from_name((char *)nodeip, nodename);
_csid_from_name((char *)nodeip, nodename);
if (!nodeip)
return 0;
@@ -458,7 +474,7 @@ static int lock_login_reply(void *misc, uint32_t error, uint8_t which)
lock_start_flag = 0;
pthread_mutex_unlock(&lock_start_mutex);
}
return 0;
}
@@ -471,6 +487,10 @@ static int lock_lock_state(void *misc, uint8_t *key, uint16_t keylen,
DEBUGLOG("LOCK lock state: %s, error = %d\n", key, error);
/* No waiting process to wake up when we are shutting down */
if (in_shutdown)
return 0;
lwait = hash_lookup(lock_hash, key);
if (!lwait)
{
@@ -540,15 +560,15 @@ int get_next_node_csid(void **context, char *csid)
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;
}
int name_from_csid(char *csid, char *name)
int gulm_name_from_csid(char *csid, char *name)
{
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)
{
sprintf(name, "UNKNOWN %s", print_csid(csid));
@@ -560,7 +580,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 node_info *ninfo;
@@ -570,28 +590,31 @@ int csid_from_name(char *csid, char *name)
ninfo = hash_get_data(node_hash, hn);
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 -1;
}
int get_num_nodes()
static int _get_num_nodes()
{
DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes;
}
/* 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;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN);
if (!ninfo)
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
if (!ninfo) {
DEBUGLOG("gulm_add_up_node no node_hash entry for csid %s\n", print_csid(csid));
return;
}
DEBUGLOG("gulm_add_up_node %s\n", ninfo->name);
ninfo->state = NODE_CLVMD;
return;
@@ -601,7 +624,7 @@ void add_down_node(char *csid)
{
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)
return;
@@ -609,30 +632,42 @@ void add_down_node(char *csid)
running clvmd - gulm may set it DOWN quite soon */
if (ninfo->state == NODE_CLVMD)
ninfo->state = NODE_UP;
drop_expired_locks(ninfo->name);
return;
}
/* 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,
void (*callback)(struct local_client *, char *csid, int node_up))
static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *, char *csid, int node_up))
{
struct hash_node *hn;
struct node_info *ninfo;
hash_iterate(hn, node_hash)
{
char csid[MAX_CSID_LEN];
char csid[GULM_MAX_CSID_LEN];
struct local_client *client;
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);
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN);
if (client)
callback(master_client, csid, ninfo->state == NODE_CLVMD);
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (!client)
{
/* If it's up but not connected, try to make contact */
if (ninfo->state == NODE_UP)
gulm_connect_csid(csid, &client);
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
}
if (ninfo->state != NODE_DOWN)
callback(master_client, csid, ninfo->state == NODE_CLVMD);
}
return 0;
}
@@ -643,15 +678,13 @@ static int gulm_to_errno(int gulm_ret)
switch (gulm_ret)
{
case lg_err_TryFailed:
errno = EAGAIN;
break;
case lg_err_AlreadyPend:
errno = EBUSY;
errno = EAGAIN;
break;
/* More?? */
default:
errno = EINVAL;
errno = EINVAL;
}
return gulm_ret ? -1 : 0;
@@ -722,6 +755,11 @@ static int _unlock_resource(char *resource, int lockid)
return status;
}
/* When we are shutting down, don't wait for unlocks
to be acknowledged, just do it. */
if (in_shutdown)
return status;
/* Wait for it to complete */
pthread_cond_wait(&lwait.cond, &lwait.mutex);
@@ -742,7 +780,7 @@ static int _unlock_resource(char *resource, int lockid)
To aid unlocking, we store the lock mode in the lockid (as GULM
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;
char lock1[strlen(resource)+3];
@@ -758,7 +796,7 @@ int sync_lock(const char *resource, int mode, int flags, int *lockid)
if (status)
goto out;
/* If we can't get this lock then bail out */
/* If we can't get this lock too then bail out */
status = _lock_resource(lock2, lg_lock_state_Exclusive, LCK_NONBLOCK, lockid);
if (status == lg_err_TryFailed)
{
@@ -770,10 +808,16 @@ int sync_lock(const char *resource, int mode, int flags, int *lockid)
case LCK_READ:
status = _lock_resource(lock1, lg_lock_state_Shared, flags, lockid);
if (status)
goto out;
status = _unlock_resource(lock2, *lockid);
break;
case LCK_WRITE:
status = _lock_resource(lock2, lg_lock_state_Exclusive, flags, lockid);
if (status)
goto out;
status = _unlock_resource(lock1, *lockid);
break;
default:
@@ -786,7 +830,7 @@ int sync_lock(const char *resource, int mode, int flags, int *lockid)
return status;
}
int sync_unlock(const char *resource, int lockid)
static int _sync_unlock(const char *resource, int lockid)
{
int status = 0;
char lock1[strlen(resource)+3];
@@ -800,29 +844,14 @@ int sync_unlock(const char *resource, int lockid)
lockid == LCK_READ ||
lockid == LCK_WRITE);
switch (lockid)
{
case LCK_EXCL:
status = _unlock_resource(lock1, lockid);
if (status)
goto out;
status = _unlock_resource(lock2, lockid);
break;
status = _unlock_resource(lock1, lockid);
if (!status)
status = _unlock_resource(lock2, lockid);
case LCK_READ:
status = _unlock_resource(lock1, lockid);
break;
case LCK_WRITE:
status = _unlock_resource(lock2, lockid);
break;
}
out:
return status;
}
int is_quorate()
static int _is_quorate()
{
if (current_corestate == lg_core_Slave ||
current_corestate == lg_core_Master ||
@@ -854,7 +883,7 @@ static int get_all_cluster_nodes()
for (i=1;;i++)
{
char nodekey[256];
char nodeip[MAX_CSID_LEN];
char nodeip[GULM_MAX_CSID_LEN];
int clvmflag = 1;
char *clvmflagstr;
char key[256];
@@ -877,7 +906,7 @@ static int get_all_cluster_nodes()
struct node_info *ninfo;
/* 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)
{
ninfo = malloc(sizeof(struct node_info));
@@ -890,7 +919,7 @@ static int get_all_cluster_nodes()
strcpy(ninfo->name, nodename);
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
@@ -906,3 +935,42 @@ static int get_all_cluster_nodes()
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 void tcp_remove_client(char *csid);
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

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -34,6 +34,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <syslog.h>
#include <errno.h>
#include "clvmd-comms.h"
@@ -55,9 +56,9 @@
/* The maximum size of a message that will fit into a packet. Anything bigger
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
the cluster_socket details */
@@ -65,7 +66,12 @@ static struct local_client local_client_head;
static unsigned short global_xid = 0; /* Last transaction ID issued */
static struct cluster_ops *clops = NULL;
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 */
struct lvm_thread_cmd {
@@ -82,7 +88,7 @@ static pthread_t lvm_thread;
static pthread_mutex_t lvm_thread_mutex;
static pthread_cond_t lvm_thread_cond;
static struct list lvm_cmd_head;
static int quit = 0;
static volatile sig_atomic_t quit = 0;
static int child_pipe[2];
/* Reasons the daemon failed initialisation */
@@ -159,6 +165,7 @@ int main(int argc, char *argv[])
int debug = 0;
int cmd_timeout = DEFAULT_CMD_TIMEOUT;
sigset_t ss;
int using_gulm = 0;
/* Deal with command-line arguments */
opterr = 0;
@@ -230,7 +237,26 @@ int main(int argc, char *argv[])
init_lvhash();
/* 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;
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to CMAN");
}
#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;
using_gulm = 1;
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to GULM");
}
#endif
if (!clops) {
DEBUGLOG("Can't initialise cluster interface\n");
log_error("Can't initialise cluster interface\n");
child_init_signal(DFAIL_CLUSTER_IF);
@@ -239,12 +265,12 @@ int main(int argc, char *argv[])
/* Save our CSID */
uname(&nodeinfo);
get_our_csid(our_csid);
clops->get_our_csid(our_csid);
/* 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.callback = cluster_fd_callback;
local_client_head.callback = clops->cluster_fd_callback;
/* Add the local socket to the list */
newfd = malloc(sizeof(struct local_client));
@@ -260,15 +286,14 @@ int main(int argc, char *argv[])
/* This needs to be started after cluster initialisation
as it may need to take out locks */
DEBUGLOG("starting LVM thread\n");
pthread_create(&lvm_thread, NULL, lvm_thread_fn, nodeinfo.nodename);
pthread_create(&lvm_thread, NULL, lvm_thread_fn, (void *)using_gulm);
#ifndef USE_GULM
/* Tell the rest of the cluster our version number */
/* CMAN can do this immediately, gulm needs to wait until
the core initialisation has finished and the node list
has been gathered */
send_version_message();
#endif
if (clops->cluster_init_completed)
clops->cluster_init_completed();
DEBUGLOG("clvmd ready for work\n");
child_init_signal(SUCCESS);
@@ -417,9 +442,9 @@ static void timedout_callback(struct local_client *client, char *csid,
{
if (node_up) {
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);
pthread_mutex_lock(&client->bits.localsock.reply_mutex);
@@ -448,7 +473,7 @@ static void timedout_callback(struct local_client *client, char *csid,
static void request_timed_out(struct local_client *client)
{
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 !=
client->bits.localsock.expected_replies) {
@@ -473,7 +498,7 @@ static void main_loop(int local_sock, int cmd_timeout)
int select_status;
struct local_client *thisfd;
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 */
FD_ZERO(&in);
@@ -488,7 +513,7 @@ static void main_loop(int local_sock, int cmd_timeout)
if ((select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv)) > 0) {
struct local_client *lastfd = NULL;
char csid[MAX_CSID_LEN];
char buf[MAX_CLUSTER_MESSAGE];
char buf[max_cluster_message];
for (thisfd = &local_client_head; thisfd != NULL;
thisfd = thisfd->next) {
@@ -520,8 +545,9 @@ static void main_loop(int local_sock, int cmd_timeout)
lastfd->next = thisfd->next;
free_fd = thisfd;
thisfd = lastfd;
cmd_client_cleanup(free_fd);
free(free_fd);
/* Queue cleanup, this also frees the client struct */
add_to_lvmqueue(free_fd, NULL, 0, NULL);
break;
}
@@ -573,7 +599,7 @@ static void main_loop(int local_sock, int cmd_timeout)
}
closedown:
cluster_closedown();
clops->cluster_closedown();
close(local_sock);
}
@@ -696,7 +722,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (thisfd->bits.localsock.threadid) {
DEBUGLOG("Waiting for child thread\n");
pthread_mutex_lock(&thisfd->bits.localsock.mutex);
thisfd->bits.localsock.state = POST_COMMAND;
thisfd->bits.localsock.state = PRE_COMMAND;
pthread_cond_signal(&thisfd->bits.localsock.cond);
pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
@@ -765,7 +791,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (thisfd->bits.localsock.in_progress) {
struct clvm_header reply;
reply.cmd = CLVMD_CMD_REPLY;
reply.status = -EBUSY;
reply.status = EBUSY;
reply.arglen = 0;
reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid,
@@ -788,7 +814,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (!thisfd->bits.localsock.cmd) {
struct clvm_header reply;
reply.cmd = CLVMD_CMD_REPLY;
reply.status = -ENOMEM;
reply.status = ENOMEM;
reply.arglen = 0;
reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid,
@@ -829,13 +855,13 @@ static int read_from_local_sock(struct local_client *thisfd)
}
/* 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 */
struct clvm_header reply;
DEBUGLOG("Unknown node: '%s'\n", inheader->node);
reply.cmd = CLVMD_CMD_REPLY;
reply.status = -ENOENT;
reply.status = ENOENT;
reply.flags = 0;
reply.arglen = 0;
send_message(&reply, sizeof(reply), our_csid,
@@ -866,7 +892,7 @@ static int read_from_local_sock(struct local_client *thisfd)
close(comms_pipe[1]);
reply.cmd = CLVMD_CMD_REPLY;
reply.status = -ENOMEM;
reply.status = ENOMEM;
reply.arglen = 0;
reply.flags = 0;
send_message(&reply, sizeof(reply), our_csid,
@@ -961,7 +987,7 @@ static int distribute_command(struct local_client *thisfd)
/* if node is empty then do it on the whole cluster */
if (inheader->node[0] == '\0') {
thisfd->bits.localsock.expected_replies =
get_num_nodes();
clops->get_num_nodes();
thisfd->bits.localsock.num_replies = 0;
thisfd->bits.localsock.sent_time = time(NULL);
thisfd->bits.localsock.in_progress = TRUE;
@@ -982,7 +1008,7 @@ static int distribute_command(struct local_client *thisfd)
/* Do it on a single node */
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 */
return 0;
} else {
@@ -992,7 +1018,7 @@ static int distribute_command(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE;
/* 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");
add_to_lvmqueue(thisfd, inheader, len, NULL);
} else {
@@ -1024,14 +1050,14 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
char *csid)
{
char *replyargs;
char nodename[MAX_CLUSTER_MEMBER_NAME_LEN];
char nodename[max_cluster_member_name_len];
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 msg_malloced = 0;
/* 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",
msg->cmd, msg->clientid, nodename);
@@ -1056,7 +1082,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
/* Return a failure response */
head.cmd = CLVMD_CMD_REPLY;
head.status = -EFBIG;
head.status = EFBIG;
head.flags = 0;
head.clientid = msg->clientid;
head.arglen = 0;
@@ -1073,7 +1099,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
msg->arglen);
/* Return a failure response */
head.cmd = CLVMD_CMD_REPLY;
head.status = -ENOMEM;
head.status = ENOMEM;
head.flags = 0;
head.clientid = msg->clientid;
head.arglen = 0;
@@ -1097,7 +1123,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
if (msg->cmd == CLVMD_CMD_VERSION) {
int *version_nums = (int *) msg->args;
char node[256];
name_from_csid(csid, node);
clops->name_from_csid(csid, node);
DEBUGLOG("Remote node %s is version %d.%d.%d\n",
node,
ntohl(version_nums[0]),
@@ -1118,17 +1144,17 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
byebyemsg.flags = 0;
byebyemsg.arglen = 0;
byebyemsg.clientid = 0;
cluster_send_message(&byebyemsg, sizeof(byebyemsg),
clops->cluster_send_message(&byebyemsg, sizeof(byebyemsg),
our_csid,
"Error Sending GOAWAY message");
} else {
add_up_node(csid);
clops->add_up_node(csid);
}
return;
}
/* 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) {
/* Run the command */
@@ -1136,7 +1162,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
do_command(NULL, msg, msglen, &replyargs, buflen,
&replylen);
} else {
status = -ENOMEM;
status = ENOMEM;
}
/* If it wasn't a reply, then reply */
@@ -1167,11 +1193,10 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
/* If System LV operation failed then report it as EFBIG but only do it
if the data buffer has something in it. */
if (system_lv_write_data
(aggreply,
replylen + sizeof(struct clvm_header)) < 0
if (system_lv_write_data(aggreply,
replylen + sizeof(struct clvm_header)) < 0
&& replylen > 0)
agghead->status = -EFBIG;
agghead->status = EFBIG;
send_message(agghead,
sizeof(struct clvm_header), csid,
@@ -1187,7 +1212,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
agghead->node[0] = '\0';
send_message(aggreply,
sizeof(struct clvm_header) +
replylen + 2, csid, fd,
replylen, csid, fd,
"Error sending command reply");
}
} else {
@@ -1196,7 +1221,7 @@ void process_remote_command(struct clvm_header *msg, int msglen, int fd,
DEBUGLOG("Error attempting to realloc return buffer\n");
/* Return a failure response */
head.cmd = CLVMD_CMD_REPLY;
head.status = -ENOMEM;
head.status = ENOMEM;
head.flags = 0;
head.clientid = msg->clientid;
head.arglen = 0;
@@ -1228,13 +1253,13 @@ static void add_reply_to_list(struct local_client *client, int status,
reply = malloc(sizeof(struct node_reply));
if (reply) {
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);
if (len > 0) {
reply->replymsg = malloc(len);
if (!reply->replymsg) {
reply->status = -ENOMEM;
reply->status = ENOMEM;
} else {
memcpy(reply->replymsg, buf, len);
}
@@ -1313,13 +1338,12 @@ static void *pre_and_post_thread(void *arg)
DEBUGLOG("Got post command condition...\n");
/* POST function must always run, even if the client aborts */
status = 0;
do_post_command(client);
write(pipe_fd, &status, sizeof(int));
if (client->bits.localsock.finished)
break;
DEBUGLOG("Waiting for next pre command\n");
pthread_mutex_lock(&client->bits.localsock.mutex);
@@ -1341,8 +1365,8 @@ static int process_local_command(struct clvm_header *msg, int msglen,
struct local_client *client,
unsigned short xid)
{
char *replybuf = malloc(MAX_CLUSTER_MESSAGE);
int buflen = MAX_CLUSTER_MESSAGE - sizeof(struct clvm_header) - 1;
char *replybuf = malloc(max_cluster_message);
int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
int replylen = 0;
int status;
@@ -1424,9 +1448,10 @@ static void send_local_reply(struct local_client *client, int status, int fd)
replybuf = malloc(message_len);
clientreply = (struct clvm_header *) replybuf;
clientreply->status = -status;
clientreply->status = status;
clientreply->cmd = CLVMD_CMD_REPLY;
clientreply->node[0] = '\0';
clientreply->flags = 0;
ptr = clientreply->args;
@@ -1438,6 +1463,9 @@ static void send_local_reply(struct local_client *client, int status, int fd)
strcpy(ptr, thisreply->node);
ptr += strlen(thisreply->node) + 1;
if (thisreply->status)
clientreply->flags |= CLVMD_FLAG_NODEERRS;
*(int *) ptr = thisreply->status;
ptr += sizeof(int);
@@ -1506,7 +1534,8 @@ static void send_version_message()
version_nums[1] = htonl(CLVMD_MINOR_VERSION);
version_nums[2] = htonl(CLVMD_PATCH_VERSION);
cluster_send_message(message, sizeof(message), NULL,
hton_clvm(msg);
clops->cluster_send_message(message, sizeof(message), NULL,
"Error Sending version number");
}
@@ -1518,8 +1547,8 @@ static int send_message(void *buf, int msglen, char *csid, int fd,
/* Send remote messages down the cluster socket */
if (csid == NULL || !ISLOCAL_CSID(csid)) {
hton_clvm((struct clvm_header *) buf); /* Byte swap if necessary */
return cluster_send_message(buf, msglen, csid, errtext);
hton_clvm((struct clvm_header *) buf);
return clops->cluster_send_message(buf, msglen, csid, errtext);
} else {
int ptr = 0;
@@ -1539,6 +1568,14 @@ static int send_message(void *buf, int msglen, char *csid, int fd,
static int process_work_item(struct lvm_thread_cmd *cmd)
{
/* If msg is NULL then this is a cleanup request */
if (cmd->msg == NULL) {
cmd_client_cleanup(cmd->client);
free(cmd->client);
return 0;
}
if (!cmd->remote) {
DEBUGLOG("process_work_item: local\n");
process_local_command(cmd->msg, cmd->msglen, cmd->client,
@@ -1558,9 +1595,9 @@ static void *lvm_thread_fn(void *arg)
{
struct list *cmdl, *tmp;
sigset_t ss;
int using_gulm = (int)arg;
DEBUGLOG("LVM thread function started\n");
pthread_mutex_lock(&lvm_thread_mutex);
/* Ignore SIGUSR1 & 2 */
sigemptyset(&ss);
@@ -1569,8 +1606,7 @@ static void *lvm_thread_fn(void *arg)
pthread_sigmask(SIG_BLOCK, &ss, NULL);
/* Initialise the interface to liblvm */
init_lvm();
pthread_mutex_unlock(&lvm_thread_mutex);
init_lvm(using_gulm);
/* Now wait for some actual work */
for (;;) {
@@ -1606,21 +1642,26 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
cmd = malloc(sizeof(struct lvm_thread_cmd));
if (!cmd)
return -ENOMEM;
return ENOMEM;
cmd->msg = malloc(msglen);
if (!cmd->msg) {
log_error("Unable to allocate buffer space\n");
free(cmd);
return -1;
if (msglen) {
cmd->msg = malloc(msglen);
if (!cmd->msg) {
log_error("Unable to allocate buffer space\n");
free(cmd);
return -1;
}
memcpy(cmd->msg, msg, msglen);
}
else {
cmd->msg = NULL;
}
cmd->client = client;
cmd->msglen = msglen;
cmd->xid = client->xid;
memcpy(cmd->msg, msg, msglen);
if (csid) {
memcpy(cmd->csid, csid, MAX_CSID_LEN);
memcpy(cmd->csid, csid, max_csid_len);
cmd->remote = 1;
} else {
cmd->remote = 0;
@@ -1651,6 +1692,8 @@ static int open_local_sock()
log_error("Can't create local socket: %m");
return -1;
}
/* Set Close-on-exec */
fcntl(local_socket, F_SETFD, 1);
memset(&sockaddr, 0, sizeof(sockaddr));
memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));
@@ -1688,7 +1731,7 @@ static void check_all_callback(struct local_client *client, char *csid,
int 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);
}
@@ -1698,7 +1741,7 @@ static void check_all_callback(struct local_client *client, char *csid,
static int check_all_clvmds_running(struct local_client *client)
{
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.
@@ -1744,3 +1787,14 @@ static void sigterm_handler(int sig)
quit = 1;
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

@@ -95,7 +95,7 @@ struct local_client {
};
#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[%x]: %ld ", (int)pthread_self(), time(NULL) ); fprintf(stderr, fmt, ## args)
#else
#define DEBUGLOG(fmt, args...)
#endif
@@ -116,4 +116,8 @@ extern int add_client(struct local_client *new_client);
extern void clvmd_cluster_init_completed(void);
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

View File

@@ -63,8 +63,8 @@
/* Maximum size of a cluster message */
#define MAX_CLUSTER_MESSAGE 1500
#define MAX_CLUSTER_MEMBER_NAME_LEN 255
#define CMAN_MAX_CLUSTER_MESSAGE 1500
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
#define MAX_BARRIER_NAME_LEN 33
#define MAX_SA_ADDR_LEN 12
#define MAX_CLUSTER_NAME_LEN 16
@@ -147,7 +147,7 @@ struct cl_cluster_node {
unsigned int leave_reason;
unsigned int incarnation;
nodestate_t state;
char name[MAX_CLUSTER_MEMBER_NAME_LEN];
char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
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;
/* 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;
if (lvi.suspended)
@@ -244,7 +244,7 @@ static int do_suspend_lv(char *resource)
}
/* 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;
if (lvi.exists) {
@@ -363,7 +363,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
if (oldmode == LKM_PWMODE) {
struct lvinfo lvi;
if (!lv_info_by_lvid(cmd, resource, &lvi))
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
return EIO;
if (lvi.exists) {
@@ -388,6 +388,44 @@ int do_check_lvm1(char *vgname)
return status == 1 ? 0 : EBUSY;
}
/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
that might be hanging around if we died for any reason
*/
static void drop_vg_locks()
{
char vg[128];
char line[255];
FILE *vgs =
popen
("lvm pvs --nolocking --noheadings -o vg_name", "r");
sync_unlock("P_orphans", LCK_EXCL);
if (!vgs)
return;
while (fgets(line, sizeof(line), vgs)) {
char *vgend;
char *vgstart;
if (line[strlen(line)-1] == '\n')
line[strlen(line)-1] = '\0';
vgstart = line + strspn(line, " ");
vgend = vgstart + strcspn(vgstart, " ");
*vgend = '\0';
if (strncmp(vgstart, "WARNING:", 8) == 0)
continue;
sprintf(vg, "V_%s", vgstart);
sync_unlock(vg, LCK_EXCL);
}
fclose(vgs);
}
/*
* Ideally, clvmd should be started before any LVs are active
* but this may not be the case...
@@ -400,7 +438,7 @@ static void *get_initial_state()
char line[255];
FILE *lvs =
popen
("/sbin/lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr",
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr",
"r");
if (!lvs)
@@ -438,6 +476,30 @@ static void *get_initial_state()
return NULL;
}
/* This checks some basic cluster-LVM configuration stuff */
static void check_config()
{
int locking_type;
locking_type = find_config_int(cmd->cft->root, "global/locking_type", 1);
if (locking_type == 3) /* compiled-in cluster support */
return;
if (locking_type == 2) { /* External library, check name */
const char *libname;
libname = find_config_str(cmd->cft->root, "global/locking_library",
"");
if (strstr(libname, "liblvm2clusterlock.so"))
return;
log_error("Incorrect LVM locking library specified in lvm.conf, cluster operations may not work.");
return;
}
log_error("locking_type not set correctly in lvm.conf, cluster operations will not work.");
}
void init_lvhash()
{
/* Create hash table for keeping LV locks & status */
@@ -446,7 +508,7 @@ void init_lvhash()
}
/* Called to initialise the LVM context of the daemon */
int init_lvm(void)
int init_lvm(int using_gulm)
{
if (!(cmd = create_toolcontext(NULL))) {
log_error("Failed to allocate command context");
@@ -457,6 +519,13 @@ int init_lvm(void)
init_syslog(LOG_DAEMON);
init_debug(_LOG_ERR);
/* Check lvm.conf is setup for cluster-LVM */
check_config();
/* Remove any non-LV locks that may have been left around */
if (using_gulm)
drop_vg_locks();
get_initial_state();
return 1;

View File

@@ -25,7 +25,7 @@ extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(char *vgname);
extern int init_lvm(void);
extern int init_lvm(int using_gulm);
extern void init_lvhash(void);
extern int hold_unlock(char *resource);

View File

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

View File

@@ -2,6 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
@@ -84,6 +85,9 @@ int init_comms(unsigned short port)
listen(listen_fd, 5);
/* Set Close-on-exec */
fcntl(listen_fd, F_SETFD, 1);
return 0;
}
@@ -96,19 +100,19 @@ void tcp_remove_client(char *csid)
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
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)
{
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 */
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)
{
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 */
@@ -137,7 +141,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
*new_client = client;
/* 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");
/* This is a duplicate connection but we can't close it because
@@ -150,7 +154,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
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");
syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
@@ -160,26 +164,26 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
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;
}
int get_main_cluster_fd()
int get_main_gulm_cluster_fd()
{
return listen_fd;
}
/* 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)
{
int newfd;
struct sockaddr_in6 addr;
socklen_t addrlen = sizeof(addr);
int status;
char name[MAX_CLUSTER_MEMBER_NAME_LEN];
char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
DEBUGLOG("cluster_fd_callback\n");
*new_client = NULL;
@@ -196,7 +200,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
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",
print_csid((char *)&addr.sin6_addr));
@@ -227,16 +231,37 @@ static int read_from_tcpsock(struct local_client *client, char *buf, int len, ch
{
struct sockaddr_in6 addr;
socklen_t slen = sizeof(addr);
struct clvm_header *header = (struct clvm_header *)buf;
int status;
uint32_t arglen;
DEBUGLOG("read_from_tcpsock fd %d\n", client->fd);
*new_client = NULL;
/* Get "csid" */
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);
/* Read just the header first, then get the rest if there is any.
* Stream sockets, sigh.
*/
status = read(client->fd, buf, sizeof(struct clvm_header));
if (status > 0)
{
int status2;
arglen = ntohl(header->arglen);
/* Get the rest */
if (arglen && arglen < GULM_MAX_CLUSTER_MESSAGE)
{
status2 = read(client->fd, buf+status, arglen);
if (status2 > 0)
status += status2;
else
status = status2;
}
}
DEBUGLOG("read_from_tcpsock, status = %d(errno = %d)\n", status, errno);
@@ -245,27 +270,28 @@ static int read_from_tcpsock(struct local_client *client, char *buf, int len, ch
if (status == 0 ||
(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);
/* If the csid was mangled, then make sure we remove the right entry */
if (client->bits.net.flags)
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 */
add_down_node(remcsid);
}
else {
gulm_add_up_node(csid);
/* Send it back to clvmd */
process_message(client, buf, len, csid);
}
return status;
}
static int connect_csid(char *csid, struct local_client **newclient)
int gulm_connect_csid(char *csid, struct local_client **newclient)
{
int fd;
struct sockaddr_in6 addr;
@@ -281,18 +307,27 @@ static int connect_csid(char *csid, struct local_client **newclient)
}
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);
DEBUGLOG("Connecting socket %d\n", fd);
if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) < 0)
{
syslog(LOG_ERR, "Unable to connect to remote node: %m");
/* "Connection refused" is "normal" because clvmd may not yet be running
* on that node.
*/
if (errno != ECONNREFUSED)
{
syslog(LOG_ERR, "Unable to connect to remote node: %m");
}
DEBUGLOG("Unable to connect to remote node: %s\n", strerror(errno));
close(fd);
return -1;
}
/* Set Close-on-exec */
fcntl(fd, F_SETFD, 1);
status = alloc_client(fd, csid, newclient);
if (status)
close(fd);
@@ -300,7 +335,7 @@ static int connect_csid(char *csid, struct local_client **newclient)
add_client(*newclient);
/* If we can connect to it, it must be running a clvmd */
add_up_node(csid);
gulm_add_up_node(csid);
return status;
}
@@ -309,21 +344,21 @@ static int tcp_send_message(void *buf, int msglen, unsigned char *csid, const ch
{
int status;
struct local_client *client;
char ourcsid[MAX_CSID_LEN];
char ourcsid[GULM_MAX_CSID_LEN];
assert(csid);
DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen);
/* Don't connect to ourself */
get_our_csid(ourcsid);
if (memcmp(csid, ourcsid, MAX_CSID_LEN) == 0)
get_our_gulm_csid(ourcsid);
if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
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)
{
status = connect_csid(csid, &client);
status = gulm_connect_csid(csid, &client);
if (status)
return -1;
}
@@ -333,7 +368,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;
@@ -343,7 +378,7 @@ int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
if (!csid)
{
void *context = NULL;
char loop_csid[MAX_CSID_LEN];
char loop_csid[GULM_MAX_CSID_LEN];
/* Loop round all gulm-known nodes */
while (get_next_node_csid(&context, loop_csid))
@@ -377,9 +412,9 @@ static int get_our_ip_address(char *addr, int *family)
/* Public version of above for those that don't care what protocol
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;
if (!got_csid)
@@ -392,7 +427,7 @@ void get_our_csid(char *csid)
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)
@@ -408,7 +443,7 @@ int get_ip_address(char *node, char *addr)
{
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 ???
// CCSs ip_interfaces solved this but some bugger removed it.

View File

@@ -1,8 +1,13 @@
#include <netinet/in.h>
#define MAX_CLUSTER_MESSAGE 1600
#define MAX_CSID_LEN sizeof(struct in6_addr)
#define MAX_CLUSTER_MEMBER_NAME_LEN 128
#define GULM_MAX_CLUSTER_MESSAGE 1600
#define GULM_MAX_CSID_LEN sizeof(struct in6_addr)
#define GULM_MAX_CLUSTER_MEMBER_NAME_LEN 128
extern int init_comms(unsigned short);
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);
int gulm_connect_csid(char *csid, struct local_client **newclient);

View File

@@ -258,11 +258,10 @@ activation {
#
# metadata {
# Default number of copies of metadata to hold on each PV. 0, 1 or 2.
# It's best to leave this at 2.
# You might want to override it from the command line with 0 or 1
# You might want to override it from the command line with 0
# when running pvcreate on new PVs which are to be added to large VGs.
# pvmetadatacopies = 2
# pvmetadatacopies = 1
# Approximate default size of on-disk metadata areas in sectors.
# You should increase this if you have large volume groups or

View File

@@ -78,12 +78,13 @@ int target_present(const char *target_name)
{
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;
}
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;
}
@@ -333,7 +334,7 @@ int target_present(const char *target_name)
* Returns 1 if info structure populated, else 0 on failure.
*/
static int _lv_info(const struct logical_volume *lv, int mknodes,
struct lvinfo *info)
struct lvinfo *info, int with_open_count)
{
int r;
struct dev_manager *dm;
@@ -347,7 +348,7 @@ static int _lv_info(const struct logical_volume *lv, int mknodes,
return 0;
}
if (!(r = dev_manager_info(dm, lv, mknodes, &dminfo)))
if (!(r = dev_manager_info(dm, lv, mknodes, with_open_count, &dminfo)))
stack;
info->exists = dminfo.exists;
@@ -361,20 +362,21 @@ static int _lv_info(const struct logical_volume *lv, int mknodes,
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,
struct lvinfo *info)
struct lvinfo *info, int with_open_count)
{
struct logical_volume *lv;
if (!(lv = lv_from_lvid(cmd, lvid_s)))
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())
return 0;
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 0)) {
stack;
return 0;
}
@@ -437,7 +439,7 @@ static int _lv_active(struct logical_volume *lv)
{
struct lvinfo info;
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 0)) {
stack;
return -1;
}
@@ -449,7 +451,7 @@ static int _lv_open_count(struct logical_volume *lv)
{
struct lvinfo info;
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 1)) {
stack;
return -1;
}
@@ -566,7 +568,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
return 1;
}
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 0)) {
stack;
return 0;
}
@@ -612,7 +614,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
return 1;
}
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 0)) {
stack;
return 0;
}
@@ -657,7 +659,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
return 1;
}
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 1)) {
stack;
return 0;
}
@@ -726,7 +728,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
return 1;
}
if (!lv_info(lv, &info)) {
if (!lv_info(lv, &info, 0)) {
stack;
return 0;
}
@@ -765,7 +767,7 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
return r;
}
if (!_lv_info(lv, 1, &info)) {
if (!_lv_info(lv, 1, &info, 0)) {
stack;
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.
*/
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,
struct lvinfo *info);
struct lvinfo *info, int with_open_count);
/*
* 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,
int mknodes, struct pool *mem, char **uuid_out)
int mknodes, int with_open_count, struct pool *mem,
char **uuid_out)
{
int r = 0;
struct dm_task *dmt;
@@ -225,6 +226,10 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
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)) {
stack;
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,
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 &&
_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;
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;
}
@@ -279,6 +287,9 @@ static int _status_run(const char *name, const char *uuid,
return 0;
}
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_run(dmt)) {
stack;
goto out;
@@ -357,6 +368,9 @@ static int _percent_run(struct dev_manager *dm, const char *name,
return 0;
}
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_run(dmt)) {
stack;
goto out;
@@ -460,6 +474,9 @@ static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
goto out;
}
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!(r = dm_task_run(dmt))) {
log_error("Couldn't rename device '%s'.", dl->name);
goto out;
@@ -488,6 +505,9 @@ static int _suspend_or_resume(const char *name, action_t suspend)
return 0;
}
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!(r = dm_task_run(dmt)))
log_error("Couldn't %s device '%s'", sus ? "suspend" : "resume",
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);
}
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!(r = dm_task_run(dmt))) {
log_error("Couldn't load device '%s'.", dl->name);
if ((dl->lv->minor >= 0 || dl->lv->major >= 0) &&
@@ -635,6 +658,9 @@ static int _remove(struct dev_layer *dl)
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 */
log_suppress(1);
@@ -852,6 +878,7 @@ static int _populate_snapshot(struct dev_manager *dm,
struct snapshot *s;
struct dev_layer *dlo, *dlc;
char devbufo[10], devbufc[10];
uint64_t size;
if (!(s = find_cow(dl->lv))) {
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;
}
log_debug("Adding target: 0 %" PRIu64 " snapshot %s",
s->origin->size, params);
if (!dm_task_add_target
(dmt, UINT64_C(0), s->origin->size, "snapshot", params)) {
size = (uint64_t) s->le_count * s->origin->vg->extent_size;
log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
if (!dm_task_add_target(dmt, UINT64_C(0), size, "snapshot", params)) {
stack;
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 mknodes, struct dm_info *info)
int mknodes, int with_open_count, struct dm_info *info)
{
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.
*/
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;
return 0;
}
@@ -1065,7 +1093,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->name = 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;
return NULL;
}

View File

@@ -36,7 +36,7 @@ void dev_manager_exit(void);
* unsuspended until the snapshot is also created.)
*/
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,
struct logical_volume *lv, float *percent);
int dev_manager_mirror_percent(struct dev_manager *dm,

View File

@@ -65,7 +65,7 @@ static int _rm_dir(const char *dev_dir, const char *vg_name)
return 0;
}
if (is_empty_dir(vg_path)) {
if (dir_exists(vg_path) && is_empty_dir(vg_path)) {
log_very_verbose("Removing directory %s", vg_path);
rmdir(vg_path);
}

29
lib/cache/lvmcache.c vendored
View File

@@ -104,10 +104,30 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
const struct format_type *fmt_from_vgname(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
struct label *label;
struct list *ih, *devh, *tmp;
struct list devs;
struct device_list *devl;
if (!(vginfo = vginfo_from_vgname(vgname)))
return NULL;
/* This function is normally called before reading metadata so
* we check cached labels here. Unfortunately vginfo is volatile. */
list_init(&devs);
list_iterate(ih, &vginfo->infos) {
devl = malloc(sizeof(*devl));
devl->dev = list_item(ih, struct lvmcache_info)->dev;
list_add(&devs, &devl->list);
}
list_iterate_safe(devh, tmp, &devs) {
devl = list_item(devh, struct device_list);
label_read(devl->dev, &label);
list_del(&devl->list);
free(devl);
}
return vginfo->fmt;
}
@@ -188,7 +208,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
goto out;
}
if (!(iter = dev_iter_create(cmd->filter))) {
if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1: 0))) {
log_error("dev_iter creation failed");
goto out;
}
@@ -266,7 +286,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
if (memlock())
return NULL;
lvmcache_label_scan(cmd, 1);
lvmcache_label_scan(cmd, 2);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
@@ -403,6 +423,9 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
/* FIXME Check consistency of list! */
vginfo->fmt = info->fmt;
log_debug("lvmcache: %s now %s%s", dev_name(info->dev),
*vgname ? "in VG " : "orphaned", vgname);
return 1;
}
@@ -551,6 +574,8 @@ static void _lvmcache_destroy_lockname(int present)
void lvmcache_destroy(void)
{
log_verbose("Wiping internal VG cache");
_has_scanned = 0;
if (_vgid_hash) {

View File

@@ -56,7 +56,8 @@ struct lvmcache_info {
int lvmcache_init(void);
void lvmcache_destroy(void);
/* Set full_scan to 1 to reread every filtered device label */
/* Set full_scan to 1 to reread every filtered device label or
* 2 to rescan /dev for new devices */
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
/* Add/delete a device */

View File

@@ -181,6 +181,12 @@ static int _process_config(struct cmd_context *cmd)
return 0;
}
if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
log_error("Warning: proc dir %s not found - some checks will be bypassed",
cmd->proc_dir);
cmd->proc_dir[0] = '\0';
}
/* activation? */
cmd->default_settings.activation = find_config_int(cmd->cft->root,
"global/activation",
@@ -825,8 +831,13 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
goto error;
/* Create system directory if it doesn't already exist */
if (*cmd->sys_dir && !create_dir(cmd->sys_dir))
if (*cmd->sys_dir && !create_dir(cmd->sys_dir)) {
log_error("Failed to create LVM2 system dir for metadata backups, config "
"files and internal cache.");
log_error("Set environment variable LVM_SYSTEM_DIR to alternative location "
"or empty string.");
goto error;
}
if (!(cmd->libmem = pool_create("library", 4 * 1024))) {
log_error("Library memory pool creation failed");

View File

@@ -21,6 +21,7 @@
#include "lvm-types.h"
#include "btree.h"
#include "filter.h"
#include "filter-persistent.h"
#include <unistd.h>
#include <sys/param.h>
@@ -186,7 +187,7 @@ static int _add_alias(struct device *dev, const char *path)
/* Is name already there? */
list_iterate(ah, &dev->aliases) {
if (!strcmp(list_item(ah, struct str_list)->str, path)) {
stack;
log_debug("%s: Already in device cache", path);
return 1;
}
}
@@ -355,11 +356,11 @@ static int _insert(const char *path, int rec)
return r;
}
static void _full_scan(void)
static void _full_scan(int dev_scan)
{
struct list *dh;
if (_cache.has_scanned)
if (_cache.has_scanned && !dev_scan)
return;
list_iterate(dh, &_cache.dirs) {
@@ -368,6 +369,7 @@ static void _full_scan(void)
};
_cache.has_scanned = 1;
init_full_scan_done(1);
}
int dev_cache_has_scanned(void)
@@ -379,15 +381,14 @@ void dev_cache_scan(int do_scan)
{
if (!do_scan)
_cache.has_scanned = 1;
else {
_cache.has_scanned = 0;
_full_scan();
}
else
_full_scan(1);
}
int dev_cache_init(void)
{
_cache.names = NULL;
_cache.has_scanned = 0;
if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
stack;
@@ -540,7 +541,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
return (d && (!f || f->passes_filter(f, d))) ? d : NULL;
}
struct dev_iter *dev_iter_create(struct dev_filter *f)
struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
{
struct dev_iter *di = dbg_malloc(sizeof(*di));
@@ -549,7 +550,14 @@ struct dev_iter *dev_iter_create(struct dev_filter *f)
return NULL;
}
_full_scan();
if (dev_scan) {
/* Flag gets reset between each command */
if (!full_scan_done())
persistent_filter_wipe(f); /* Calls _full_scan(1) */
} else
_full_scan(0);
di->current = btree_first(_cache.devices);
di->filter = f;

View File

@@ -45,7 +45,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f);
* Object for iterating through the cache.
*/
struct dev_iter;
struct dev_iter *dev_iter_create(struct dev_filter *f);
struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan);
void dev_iter_destroy(struct dev_iter *iter);
struct device *dev_iter_get(struct dev_iter *iter);

View File

@@ -341,7 +341,10 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
#endif
if ((dev->fd = open(name, flags, 0777)) < 0) {
log_sys_error("open", name);
if (quiet)
log_sys_debug("open", name);
else
log_sys_error("open", name);
return 0;
}

View File

@@ -258,7 +258,7 @@ void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
log_print("PV Size %s" " / not usable %s", /* [LVM: %s]", */
size,
display_size(cmd, (pv->size -
pv->pe_count * pv->pe_size),
(uint64_t) pv->pe_count * pv->pe_size),
SIZE_SHORT));
} else
@@ -317,7 +317,7 @@ void lvdisplay_colons(struct logical_volume *lv)
{
int inkernel;
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",
lv->vg->cmd->dev_dir,
@@ -348,7 +348,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
inkernel = lv_info(lv, &info) && info.exists;
inkernel = lv_info(lv, &info, 1) && info.exists;
log_print("--- Logical volume ---");

View File

@@ -53,7 +53,9 @@ int persistent_filter_wipe(struct dev_filter *f)
{
struct pfilter *pf = (struct pfilter *) f->private;
log_verbose("Wiping cache of LVM-capable devices");
hash_wipe(pf->devices);
/* Trigger complete device scan */
dev_cache_scan(1);

View File

@@ -172,7 +172,7 @@ static int _read_devs(struct dev_set *ds, const char *dir)
unsigned char dtype;
struct stat info;
char path[PATH_MAX];
dev_t dev;
dev_t dev = { 0 };
int r = 1;
if (!(dr = opendir(dir))) {

View File

@@ -69,6 +69,7 @@ static const device_info_t device_info[] = {
{"power2", 16}, /* EMC Powerpath */
{"i2o_block", 16}, /* i2o Block Disk */
{"iseries/vd", 8}, /* iSeries disks */
{"gnbd", 1}, /* Network block device */
{NULL, 0}
};
@@ -87,7 +88,7 @@ static int _passes_lvm_type_device_filter(struct dev_filter *f,
}
/* Check it's accessible */
if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
if (!dev_open_flags(dev, O_RDONLY, 0, 1)) {
log_debug("%s: Skipping: open failed", name);
return 0;
}

View File

@@ -482,7 +482,7 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
/* vgcache_del(vg_name); */
}
if (!(iter = dev_iter_create(filter))) {
if (!(iter = dev_iter_create(filter, 1))) {
log_error("read_pvs_in_vg: dev_iter_create failed");
return 0;
}

View File

@@ -646,7 +646,7 @@ int import_snapshots(struct pool *mem, struct volume_group *vg,
continue;
/* 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)) {
log_err("Couldn't add snapshot.");
return 0;

View File

@@ -20,6 +20,8 @@
#include "metadata.h"
#include "pool.h"
#define MINOR_OFFSET 65536
/* From NSP.cf */
#define NSPMajorVersion 4
#define NSPMinorVersion 1
@@ -66,29 +68,6 @@ struct pool_list;
struct user_subpool;
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 {
uint64_t pl_magic; /* Pool magic number */
uint64_t pl_pool_id; /* Unique pool identifier */

View File

@@ -19,6 +19,7 @@
#include "metadata.h"
#include "lvmcache.h"
#include "disk_rep.h"
#include "sptype_names.h"
#include "lv_alloc.h"
#include "str_list.h"
#include "display.h"
@@ -107,7 +108,7 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
/* for pool a minor of 0 is dynamic */
if (pl->pd.pl_minor) {
lv->status |= FIXED_MINOR;
lv->minor = pl->pd.pl_minor;
lv->minor = pl->pd.pl_minor + MINOR_OFFSET;
} else {
lv->minor = -1;
}

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

@@ -53,7 +53,7 @@ struct archive_file {
struct list list;
char *path;
int index;
uint32_t index;
};
/*
@@ -132,7 +132,8 @@ static char *_join(struct pool *mem, const char *dir, const char *name)
static struct list *_scan_archive(struct pool *mem,
const char *vgname, const char *dir)
{
int i, count, ix;
int i, count;
uint32_t ix;
char vgname_found[64], *path;
struct dirent **dirent;
struct archive_file *af;
@@ -240,7 +241,7 @@ int archive_vg(struct volume_group *vg,
uint32_t retain_days, uint32_t min_archive)
{
int i, fd, renamed = 0;
unsigned int ix = 0;
uint32_t ix = 0;
struct archive_file *last;
FILE *fp = NULL;
char temp_file[PATH_MAX], archive_name[PATH_MAX];
@@ -285,7 +286,7 @@ int archive_vg(struct volume_group *vg,
for (i = 0; i < 10; i++) {
if (lvm_snprintf(archive_name, sizeof(archive_name),
"%s/%s_%05d.vg", dir, vg->name, ix) < 0) {
"%s/%s_%05u.vg", dir, vg->name, ix) < 0) {
log_error("Archive file name too long.");
return 0;
}

View File

@@ -513,7 +513,7 @@ static int _print_snapshot(struct formatter *f, struct snapshot *snap,
}
seg.le = 0;
seg.len = snap->origin->le_count;
seg.len = snap->le_count;
seg.origin = snap->origin;
seg.cow = snap->cow;
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)
lvid_create(&lv->lvid, &lv->vg->id);
if (!*lv->lvid.s && !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;
}
@@ -185,6 +188,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
size_t len;
char vgnamebuf[NAME_LEN + 2];
struct raw_locn *rlocn;
struct lvmcache_info *info;
rlocn = mdah->raw_locns;
@@ -193,7 +197,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
sizeof(vgnamebuf), vgnamebuf)) {
stack;
return NULL;
goto error;
}
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
@@ -202,6 +206,10 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
rlocn++;
}
error:
if ((info = info_from_pvid(dev_area->dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
return NULL;
}
@@ -261,7 +269,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
}
if (!(rlocn = _vg_posn(fid, area, vgname))) {
stack;
log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
goto out;
}
@@ -1180,9 +1188,9 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
return 1;
}
/* Perform full scan and try again */
if (!memlock()) {
lvmcache_label_scan(fmt->cmd, 1);
/* Perform full scan (just the first time) and try again */
if (!memlock() && !full_scan_done()) {
lvmcache_label_scan(fmt->cmd, 2);
if (info->vginfo && info->vginfo->vgname &&
*info->vginfo->vgname &&

View File

@@ -31,7 +31,7 @@ typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
struct hash_table * pv_hash);
#define _read_int32(root, path, result) \
get_config_uint32(root, path, result)
get_config_uint32(root, path, (uint32_t *) result)
#define _read_uint32(root, path, result) \
get_config_uint32(root, path, result)

View File

@@ -117,12 +117,17 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
struct labeller_i *li;
struct labeller *r = NULL;
struct label_header *lh;
struct lvmcache_info *info;
uint64_t sector;
int found = 0;
char readbuf[LABEL_SCAN_SIZE];
if (!dev_open(dev)) {
stack;
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
return NULL;
}
@@ -182,10 +187,13 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
}
}
if (!found)
log_very_verbose("%s: No label detected", dev_name(dev));
out:
if (!found) {
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
log_very_verbose("%s: No label detected", dev_name(dev));
}
if (!dev_close(dev))
stack;
@@ -279,7 +287,7 @@ int label_read(struct device *dev, struct label **result)
return 0;
}
if ((r = l->ops->read(l, dev, buf, result)) && result && *result)
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
(*result)->sector = sector;
return r;
@@ -309,7 +317,7 @@ int label_write(struct device *dev, struct label *label)
lh->sector_xl = xlate64(label->sector);
lh->offset_xl = xlate32(sizeof(*lh));
if (!label->labeller->ops->write(label, buf)) {
if (!(label->labeller->ops->write)(label, buf)) {
stack;
return 0;
}

View File

@@ -139,8 +139,7 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
/* Read the returned values */
off = 1; /* we've already read the first byte */
while (off < outheader->arglen && len > 0) {
while (off <= outheader->arglen && len > 0) {
len = read(_clvmd_sock, outheader->args + off,
buflen - off - offsetof(struct clvm_header, args));
if (len > 0)
@@ -148,10 +147,16 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
}
/* Was it an error ? */
if (outheader->status < 0) {
errno = -outheader->status;
log_error("cluster send request failed: %s", strerror(errno));
return 0;
if (outheader->status != 0) {
errno = outheader->status;
/* 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;
@@ -329,7 +334,7 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
* VG locks are just that: locks, and have no side effects
* so we only need to do them on the local node because all
* locks are cluster-wide.
* Also, if the lock is exclusive it makes no sense to try to
* Also, if the lock is exclusive it makes no sense to try to
* acquire it on all nodes, so just do that on the local node too.
*/
if (cmd == CLVMD_CMD_LOCK_VG ||
@@ -342,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 */
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",
response[i].node);
status = 0;
errno = response[i].status;
} else if (response[i].status) {
log_error("Error locking on node %s: %s",
response[i].node,
@@ -353,6 +359,7 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
response[i].response :
strerror(response[i].status));
status = 0;
errno = response[i].status;
}
}
@@ -439,7 +446,7 @@ int init_cluster_locking(struct locking_type *locking, struct config_tree *cft)
locking->lock_resource = _lock_resource;
locking->fin_locking = _locking_end;
locking->reset_locking = _reset_locking;
locking->flags = LCK_PRE_MEMLOCK;
locking->flags = LCK_PRE_MEMLOCK | LCK_CLUSTERED;
_clvmd_sock = _open_local_sock();
if (_clvmd_sock == -1)
@@ -456,6 +463,7 @@ int locking_init(int type, struct config_tree *cf, uint32_t *flags)
/* Ask LVM to lock memory before calling us */
*flags |= LCK_PRE_MEMLOCK;
*flags |= LCK_CLUSTERED;
return 1;
}

View File

@@ -41,7 +41,7 @@ static char _lock_dir[NAME_LEN];
static sig_t _oldhandler;
static sigset_t _fullsigset, _intsigset;
static int _handler_installed;
static volatile sig_atomic_t _handler_installed;
static int _release_lock(const char *file, int unlock)
{
@@ -95,38 +95,40 @@ static void _reset_file_locking(void)
static void _remove_ctrl_c_handler()
{
siginterrupt(SIGINT, 0);
if (!_handler_installed || _oldhandler == SIG_ERR)
if (!_handler_installed)
return;
_handler_installed = 0;
sigprocmask(SIG_SETMASK, &_fullsigset, NULL);
if (signal(SIGINT, _oldhandler) == SIG_ERR)
log_sys_error("signal", "_remove_ctrl_c_handler");
_handler_installed = 0;
}
static void _trap_ctrl_c(int sig)
{
_remove_ctrl_c_handler();
log_error("CTRL-c detected: giving up waiting for lock");
return;
}
static void _install_ctrl_c_handler()
{
if ((_oldhandler = signal(SIGINT, _trap_ctrl_c)) == SIG_ERR)
_handler_installed = 1;
if ((_oldhandler = signal(SIGINT, _trap_ctrl_c)) == SIG_ERR) {
_handler_installed = 0;
return;
}
sigprocmask(SIG_SETMASK, &_intsigset, NULL);
siginterrupt(SIGINT, 1);
_handler_installed = 1;
}
static int _lock_file(const char *file, int flags)
{
int operation;
int r = 1;
int old_errno;
struct lock_list *ll;
struct stat buf1, buf2;
@@ -176,10 +178,12 @@ static int _lock_file(const char *file, int flags)
_install_ctrl_c_handler();
r = flock(ll->lf, operation);
old_errno = errno;
if (!(flags & LCK_NONBLOCK))
_remove_ctrl_c_handler();
if (r) {
errno = old_errno;
log_sys_error("flock", ll->res);
goto err;
}

View File

@@ -124,6 +124,8 @@ static inline void _update_vg_lock_count(int flags)
*/
int init_locking(int type, struct config_tree *cft)
{
init_lockingfailed(0);
switch (type) {
case 0:
init_no_locking(&_locking, cft);
@@ -165,6 +167,7 @@ int init_locking(int type, struct config_tree *cft)
log_verbose("Locking disabled - only read operations permitted.");
init_no_locking(&_locking, cft);
init_lockingfailed(1);
return 1;
}
@@ -321,3 +324,9 @@ int vg_write_lock_held(void)
{
return _vg_write_lock_held;
}
int locking_is_clustered(void)
{
return (_locking.flags & LCK_CLUSTERED) ? 1 : 0;
}

View File

@@ -20,6 +20,7 @@ int init_locking(int type, struct config_tree *cf);
void fin_locking(void);
void reset_locking(void);
int vg_write_lock_held(void);
int locking_is_clustered(void);
/*
* LCK_VG:

View File

@@ -23,6 +23,7 @@ typedef void (*fin_lock_fn) (void);
typedef void (*reset_lock_fn) (void);
#define LCK_PRE_MEMLOCK 0x00000001 /* Is memlock() needed before calls? */
#define LCK_CLUSTERED 0x00000002
struct locking_type {
uint32_t flags;

View File

@@ -30,6 +30,7 @@ static int _test = 0;
static int _partial = 0;
static int _md_filtering = 0;
static int _pvmove = 0;
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
static int _debug_level = 0;
static int _syslog = 0;
static int _log_to_file = 0;
@@ -39,6 +40,7 @@ static int _indent = 1;
static int _log_cmd_name = 0;
static int _log_suppress = 0;
static int _ignorelockingfailure = 0;
static int _lockingfailed = 0;
static int _security_level = SECURITY_LEVEL;
static char _cmd_name[30] = "";
static char _msg_prefix[30] = " ";
@@ -149,11 +151,21 @@ void init_pvmove(int level)
_pvmove = level;
}
void init_full_scan_done(int level)
{
_full_scan_done = level;
}
void init_ignorelockingfailure(int level)
{
_ignorelockingfailure = level;
}
void init_lockingfailed(int level)
{
_lockingfailed = level;
}
void init_security_level(int level)
{
_security_level = level;
@@ -203,6 +215,16 @@ int pvmove_mode()
return _pvmove;
}
int full_scan_done()
{
return _full_scan_done;
}
int lockingfailed()
{
return _lockingfailed;
}
int ignorelockingfailure()
{
return _ignorelockingfailure;

View File

@@ -65,11 +65,13 @@ void init_test(int level);
void init_partial(int level);
void init_md_filtering(int level);
void init_pvmove(int level);
void init_full_scan_done(int level);
void init_debug(int level);
void init_cmd_name(int status);
void init_msg_prefix(const char *prefix);
void init_indent(int indent);
void init_ignorelockingfailure(int level);
void init_lockingfailed(int level);
void init_security_level(int level);
void set_cmd_name(const char *cmd_name);
@@ -78,8 +80,10 @@ int test_mode(void);
int partial_mode(void);
int md_filtering(void);
int pvmove_mode(void);
int full_scan_done(void);
int debug_level(void);
int ignorelockingfailure(void);
int lockingfailed(void);
int security_level(void);
/* Suppress messages to stdout/stderr */

View File

@@ -267,10 +267,13 @@ struct physical_volume *pv_create(const struct format_type *fmt,
return NULL;
}
if (!id)
id_create(&pv->id);
else
if (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;
@@ -651,7 +654,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
stack;
return NULL;
}
lvmcache_label_scan(cmd, 1);
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname))) {
stack;
return NULL;
@@ -684,10 +687,46 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
}
}
/* Failed to find VG */
/* Failed to find VG where we expected it - full scan and retry */
if (!correct_vg) {
stack;
return NULL;
inconsistent = 0;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname))) {
stack;
return NULL;
}
/* create format instance with appropriate metadata area */
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
log_error("Failed to create format instance");
return NULL;
}
/* Ensure contents of all metadata areas match - else recover */
list_iterate(mdah, &fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (!(vg = mda->ops->vg_read(fid, vgname, mda))) {
inconsistent = 1;
continue;
}
if (!correct_vg) {
correct_vg = vg;
continue;
}
/* FIXME Also ensure contents same - checksums same? */
if (correct_vg->seqno != vg->seqno) {
inconsistent = 1;
if (vg->seqno > correct_vg->seqno)
correct_vg = vg;
}
}
/* Give up looking */
if (!correct_vg) {
stack;
return NULL;
}
}
lvmcache_update_vg(correct_vg);
@@ -711,6 +750,11 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
log_error("Automatic metadata correction failed");
return NULL;
}
if (!vg_commit(correct_vg)) {
log_error("Automatic metadata correction commit "
"failed");
return NULL;
}
}
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
@@ -760,7 +804,7 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
* allowed to do a full scan here any more. */
// The slow way - full scan required to cope with vgrename
if (!(vgnames = get_vgs(cmd, 1))) {
if (!(vgnames = get_vgs(cmd, 2))) {
log_error("vg_read_by_vgid: get_vgs failed");
return NULL;
}

View File

@@ -255,6 +255,7 @@ struct snapshot {
int persistent; /* boolean */
uint32_t chunk_size; /* in 512 byte sectors */
uint32_t le_count;
struct logical_volume *origin;
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 list *find_snapshots(const struct logical_volume *lv);
int vg_add_snapshot(struct logical_volume *origin,
struct logical_volume *cow,
int persistent, struct id *id, uint32_t chunk_size);
int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
int persistent, struct id *id, uint32_t extent_count,
uint32_t chunk_size);
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;
}
int vg_add_snapshot(struct logical_volume *origin,
struct logical_volume *cow,
int persistent, struct id *id, uint32_t chunk_size)
int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
int persistent, struct id *id, uint32_t extent_count,
uint32_t chunk_size)
{
struct snapshot *s;
struct snapshot_list *sl;
@@ -127,13 +127,15 @@ int vg_add_snapshot(struct logical_volume *origin,
s->persistent = persistent;
s->chunk_size = chunk_size;
s->le_count = extent_count;
s->origin = origin;
s->cow = cow;
if (id)
s->id = *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;
}

View File

@@ -86,7 +86,11 @@ int lvm_rename(const char *old, const char *new)
{
struct stat buf;
link(old, new);
if (link(old, new)) {
log_error("%s: rename to %s failed: %s", old, new,
strerror(errno));
return 0;
}
if (stat(old, &buf)) {
log_sys_error("stat", old);

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);
if (s > 50000000) {
log_error("Huge memory allocation (size %" PRIuPTR
log_error("Huge memory allocation (size %" PRIsize_t
") rejected - metadata corruption?", s);
return 0;
}
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;
}
@@ -190,7 +191,7 @@ int dump_memory(void)
str[sizeof(str) - 1] = '\0';
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);
tot += mb->length;
}
@@ -220,7 +221,7 @@ void bounds_check(void)
void *malloc_aux(size_t s, const char *file, int line)
{
if (s > 50000000) {
log_error("Huge memory allocation (size %" PRIuPTR
log_error("Huge memory allocation (size %" PRIsize_t
") rejected - metadata corruption?", s);
return 0;
}

View File

@@ -27,14 +27,14 @@
((x) & 0xff000000U) >> 24 | \
((x) & 0x0000ff00U) << 8 | \
((x) & 0x00ff0000U) >> 8)
# define bswap_64(x) (((x) & 0x00000000000000ffU) << 56 | \
((x) & 0xff00000000000000U) >> 56 | \
((x) & 0x000000000000ff00U) << 40 | \
((x) & 0x00ff000000000000U) >> 40 | \
((x) & 0x0000000000ff0000U) << 24 | \
((x) & 0x0000ff0000000000U) >> 24 | \
((x) & 0x00000000ff000000U) << 8 | \
((x) & 0x000000ff00000000U) >> 8)
# define bswap_64(x) (((x) & 0x00000000000000ffULL) << 56 | \
((x) & 0xff00000000000000ULL) >> 56 | \
((x) & 0x000000000000ff00ULL) << 40 | \
((x) & 0x00ff000000000000ULL) >> 40 | \
((x) & 0x0000000000ff0000ULL) << 24 | \
((x) & 0x0000ff0000000000ULL) >> 24 | \
((x) & 0x00000000ff000000ULL) << 8 | \
((x) & 0x000000ff00000000ULL) >> 8)
#endif
#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;
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);
else
return _int_disp(rh, field, &minusone);
@@ -310,7 +310,7 @@ static int _lvkmin_disp(struct report_handle *rh, struct field *field,
struct lvinfo info;
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);
else
return _int_disp(rh, field, &minusone);
@@ -362,7 +362,7 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
else
repstr[3] = '-';
if (lv_info(lv, &info) && info.exists) {
if (lv_info(lv, &info, 1) && info.exists) {
if (info.suspended)
repstr[4] = 's'; /* Suspended */
else
@@ -573,7 +573,7 @@ static int _vgsize_disp(struct report_handle *rh, struct field *field,
const struct volume_group *vg = (const struct volume_group *) data;
uint64_t size;
size = vg->extent_count * vg->extent_size;
size = (uint64_t) vg->extent_count * vg->extent_size;
return _size64_disp(rh, field, &size);
}
@@ -584,7 +584,7 @@ static int _segstart_disp(struct report_handle *rh, struct field *field,
const struct lv_segment *seg = (const struct lv_segment *) data;
uint64_t start;
start = seg->le * seg->lv->vg->extent_size;
start = (uint64_t) seg->le * seg->lv->vg->extent_size;
return _size64_disp(rh, field, &start);
}
@@ -595,7 +595,7 @@ static int _segsize_disp(struct report_handle *rh, struct field *field,
const struct lv_segment *seg = (const struct lv_segment *) data;
uint64_t size;
size = seg->len * seg->lv->vg->extent_size;
size = (uint64_t) seg->len * seg->lv->vg->extent_size;
return _size64_disp(rh, field, &size);
}
@@ -610,7 +610,7 @@ static int _pvused_disp(struct report_handle *rh, struct field *field,
if (!pv->pe_count)
used = 0LL;
else
used = pv->pe_alloc_count * pv->pe_size;
used = (uint64_t) pv->pe_alloc_count * pv->pe_size;
return _size64_disp(rh, field, &used);
}
@@ -625,7 +625,7 @@ static int _pvfree_disp(struct report_handle *rh, struct field *field,
if (!pv->pe_count)
freespace = pv->size;
else
freespace = (pv->pe_count - pv->pe_alloc_count) * pv->pe_size;
freespace = (uint64_t) (pv->pe_count - pv->pe_alloc_count) * pv->pe_size;
return _size64_disp(rh, field, &freespace);
}
@@ -640,7 +640,7 @@ static int _pvsize_disp(struct report_handle *rh, struct field *field,
if (!pv->pe_count)
size = pv->size;
else
size = pv->pe_count * pv->pe_size;
size = (uint64_t) pv->pe_count * pv->pe_size;
return _size64_disp(rh, field, &size);
}
@@ -663,7 +663,7 @@ static int _vgfree_disp(struct report_handle *rh, struct field *field,
const struct volume_group *vg = (const struct volume_group *) data;
uint64_t freespace;
freespace = vg->free_count * vg->extent_size;
freespace = (uint64_t) vg->free_count * vg->extent_size;
return _size64_disp(rh, field, &freespace);
}
@@ -774,7 +774,7 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
}
if (!(snap = find_cow(lv)) ||
(lv_info(snap->cow, &info) && !info.exists)) {
(lv_info(snap->cow, &info, 0) && !info.exists)) {
field->report_string = "";
*sortval = UINT64_C(0);
field->sort_value = sortval;

View File

@@ -70,7 +70,8 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
return 0;
}
if (!vg_add_snapshot(org, cow, 1, &seg->lv->lvid.id[1], chunk_size)) {
if (!vg_add_snapshot(org, cow, 1, &seg->lv->lvid.id[1], seg->len,
chunk_size)) {
stack;
return 0;
}

View File

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

View File

@@ -20,6 +20,7 @@ dm_task_set_minor
dm_task_set_sector
dm_task_set_message
dm_task_add_target
dm_task_no_open_count
dm_get_next_target
dm_task_run
dm_set_dev_dir

View File

@@ -22,7 +22,12 @@ SOURCES = libdm-common.c libdm-file.c $(interface)/libdm-iface.c
INCLUDES = -I$(interface)
LIB_STATIC = $(interface)/libdevmapper.a
LIB_SHARED = $(interface)/libdevmapper.so
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = $(interface)/libdevmapper.dylib
else
LIB_SHARED = $(interface)/libdevmapper.so
endif
CFLAGS += -DDEVICE_UID=@DEVICE_UID@ -DDEVICE_GID=@DEVICE_GID@ \
-DDEVICE_MODE=@DEVICE_MODE@
@@ -41,7 +46,8 @@ endif
install: $(INSTALL_TYPE)
install_dynamic: install_@interface@
$(LN_S) -f libdevmapper.so.$(LIB_VERSION) $(libdir)/libdevmapper.so
$(LN_S) -f libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION) \
$(libdir)/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.h \
$(includedir)/libdevmapper.h
@@ -50,13 +56,13 @@ install_static: install_@interface@_static
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.h \
$(includedir)/libdevmapper.h
install_fs: fs/libdevmapper.so
install_fs: fs/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.so.$(LIB_VERSION)
$(libdir)/libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
install_ioctl: ioctl/libdevmapper.so
install_ioctl: ioctl/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.so.$(LIB_VERSION)
$(libdir)/libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
install_ioctl_static: ioctl/libdevmapper.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \

View File

@@ -30,13 +30,14 @@
#ifdef linux
# include "kdev_t.h"
# include <linux/limits.h>
# include <linux/dm-ioctl.h>
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
#include <linux/dm-ioctl.h>
/*
* Ensure build compatibility.
* The hard-coded versions here are the highest present
@@ -134,8 +135,7 @@ static int _get_proc_number(const char *file, const char *name,
fclose(fl);
return 1;
}
}
do {
} else do {
c = fgetc(fl);
} while (c != EOF && c != '\n');
}
@@ -229,6 +229,7 @@ static int _create_control(const char *control, uint32_t major, uint32_t minor)
static int _open_control(void)
{
#ifdef DM_IOCTLS
char control[PATH_MAX];
uint32_t major = 0, minor;
@@ -254,6 +255,9 @@ static int _open_control(void)
error:
log_error("Failure to communicate with kernel device-mapper driver.");
return 0;
#else
return 1;
#endif
}
void dm_task_destroy(struct dm_task *dmt)
@@ -609,7 +613,9 @@ static int _dm_task_run_v1(struct dm_task *dmt)
if (dmt->type == DM_DEVICE_LIST) {
if (!_dm_names_v1(dmi))
goto bad;
} else if (ioctl(_control_fd, command, dmi) < 0) {
}
#ifdef DM_IOCTLS
else if (ioctl(_control_fd, command, dmi) < 0) {
if (_log_suppress)
log_verbose("device-mapper ioctl cmd %d failed: %s",
_IOC_NR(command), strerror(errno));
@@ -618,6 +624,8 @@ static int _dm_task_run_v1(struct dm_task *dmt)
_IOC_NR(command), strerror(errno));
goto bad;
}
#else /* Userspace alternative for testing */
#endif
if (dmi->flags & DM_BUFFER_FULL_FLAG)
/* FIXME Increase buffer size and retry operation (if query) */
@@ -930,6 +938,13 @@ int dm_task_set_sector(struct dm_task *dmt, uint64_t sector)
return 1;
}
int dm_task_no_open_count(struct dm_task *dmt)
{
dmt->no_open_count = 1;
return 1;
}
int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr)
{
dmt->event_nr = event_nr;
@@ -1299,25 +1314,34 @@ int dm_task_run(struct dm_task *dmt)
dmi->flags |= DM_STATUS_TABLE_FLAG;
dmi->flags |= DM_EXISTS_FLAG; /* FIXME */
log_debug("dm %s %s %s %s%.0llu %s", _cmd_data_v4[dmt->type].name,
if (dmt->no_open_count)
dmi->flags |= DM_SKIP_BDGET_FLAG;
log_debug("dm %s %s %s %s%c %.0llu %s", _cmd_data_v4[dmt->type].name,
dmi->name, dmi->uuid, dmt->newname ? dmt->newname : "",
dmt->no_open_count ? 'N' : 'O',
dmt->sector, dmt->message ? dmt->message : "");
#ifdef DM_IOCTLS
if (ioctl(_control_fd, command, dmi) < 0) {
if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
(dmt->type == DM_DEVICE_MKNODES))) {
(dmt->type == DM_DEVICE_MKNODES)))
dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */
goto ignore_error;
else {
if (_log_suppress)
log_verbose("device-mapper ioctl "
"cmd %d failed: %s",
_IOC_NR(command), strerror(errno));
else
log_error("device-mapper ioctl "
"cmd %d failed: %s",
_IOC_NR(command), strerror(errno));
goto bad;
}
if (_log_suppress)
log_verbose("device-mapper ioctl cmd %d failed: %s",
_IOC_NR(command), strerror(errno));
else
log_error("device-mapper ioctl cmd %d failed: %s",
_IOC_NR(command), strerror(errno));
goto bad;
}
#else /* Userspace alternative for testing */
#endif
ignore_error:
switch (dmt->type) {
case DM_DEVICE_CREATE:
add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev),

View File

@@ -51,6 +51,7 @@ struct dm_task {
char *newname;
char *message;
uint64_t sector;
int no_open_count;
char *uuid;
};

View File

@@ -134,6 +134,7 @@ int dm_task_set_major(struct dm_task *dmt, int major);
int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
int dm_task_set_message(struct dm_task *dmt, const char *message);
int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
int dm_task_no_open_count(struct dm_task *dmt);
/*
* Use these to prepare for a create or reload.

View File

@@ -21,6 +21,7 @@
#include <stdarg.h>
#include <sys/param.h>
#include <linux/dm-ioctl.h>
#ifdef HAVE_SELINUX

View File

@@ -19,7 +19,10 @@
#include <sys/file.h>
#include <fcntl.h>
#include <dirent.h>
#include <malloc.h>
#ifdef linux
# include <malloc.h>
#endif
static int _create_dir_recursive(const char *dir)
{

View File

@@ -31,7 +31,10 @@ dmsetup \- low level logical volume management
.br
.B dmsetup ls
.br
.B dmsetup info
.B dmsetup info
.I [device_name]
.br
.B dmsetup info -c|-C|--columns [--noheadings] [-o name]
.I [device_name]
.br
.B dmsetup deps
@@ -53,6 +56,13 @@ dmsetup \- low level logical volume management
.B dmsetup targets
.br
.B dmsetup version
.br
.B devmap_name
.I major minor
.br
.B devmap_name
.I major:minor
.ad b
.SH DESCRIPTION
dmsetup manages logical devices that use the device-mapper driver.
@@ -61,16 +71,38 @@ each sector (512 bytes) in the logical device.
The first argument to dmsetup is a command.
The second argument is the logical device name or uuid.
Invoking the command as \fBdevmap_name\fP is equivalent to
.br
\fBdmsetup info -c --noheadings -j \fImajor\fB -m \fIminor\fP.
.SH OPTIONS
.IP \fB-c|-C|--columns
.br
Display output in columns rather than as Field: Value lines.
.IP \fB-j|--major\ \fImajor
.br
Specify the major number to use on creation.
.IP \fB-j|--minor\ \fIminor
Specify the major number.
.IP \fB-m|--minor\ \fIminor
.br
Specify the minor number to use on creation.
Specify the minor number.
.IP \fB-n|--noheadings
.br
Suppress the headings line when using columnar output.
.IP \fB--noopencount
.br
Tell the kernel not to supply the open reference count for the device.
.IP \fB--notable
.br
When creating a device, don't load any table.
.IP \fB-o|--options
.br
Specify which fields to display. Only \fB-o\ name\fP is supported.
.IP \fB-r|--readonly
.br
Set the table being loaded read-only.
.IP \fB-u|--uuid
.br
Specify the uuid.
.IP \fB-v|--verbose [-v|--verbose]
.br
Produce additional output.

View File

@@ -91,10 +91,10 @@ The approximate amount of space to be set aside for each metadata area.
.BR \-\-metadatacopies " copies"
The number of metadata areas to set aside on each PV. Currently
this can be 0, 1 or 2.
If set to 2 (the default), two copies of the volume group metadata
If set to 2, two copies of the volume group metadata
are held on the PV, one at the front of the PV and one at the end.
If set to 1, one copy is kept at the front of the PV (starting in the
5th sector).
If set to 1 (the default), one copy is kept at the front of the PV
(starting in the 5th sector).
If set to 0, no copies are kept on this PV - you might wish to use this
with VGs containing large numbers of PVs. But if you do this and
then later use \fBvgsplit\fP you must ensure that each VG is still going

View File

@@ -33,29 +33,44 @@ previously configured for LVM with
.SH OPTIONS
See \fBlvm\fP for common options.
.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
Sets the maximum possible logical volume count.
More logical volumes can't be created in this volume group.
Absolute maximum is 256.
Sets the maximum number of logical volumes allowed in this
volume group.
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
.BR \-p ", " \-\-maxphysicalvolumes " " \fIMaxPhysicalVolumes\fR
Sets the maximum possible physical volume count.
More physical volumes can't be included in this volume group.
Absolute maximum is 256.
Sets the maximum number of physical volumes that can belong
to this volume group.
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
.BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBkKmMgGtT\fR]
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
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
many as ~64k extents are supported per LV. In case larger maximum LV sizes are
needed (later), you need to set the PE size to a larger value as well. Later
changes of the PE size in an existing VG are not supported.
powers of 2. The default is 4 MB.
Once this value has been set, it is difficult to change it without recreating
the volume group which would involve backing up and restoring data on any
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
To create a volume group named
.B test_vg
@@ -67,11 +82,6 @@ with default physical extent size of 4MB:
\ vgcreate test_vg /dev/sdk1 /dev/sdl1
.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
.BR lvm (8),
.BR pvdisplay (8),

1651
po/lvm2.po

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# chkconfig: 345 23 77
# chkconfig: 345 24 76
# description: Starts and stops clvmd
#
#
@@ -9,19 +9,17 @@
### END INIT INFO
. /etc/init.d/functions
LVDISPLAY="/usr/sbin/lvdisplay"
VGCHANGE="/usr/sbin/vgchange"
VGSCAN="/usr/sbin/vgscan"
[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
LOCK_FILE="/var/lock/subsys/clvmd"
#
# FIXME -- the lvm2-cluster rpms put the lvm tools in a different location
#
lvdisplay=/usr/sbin/cluster/lvdisplay
vgchange=/usr/sbin/cluster/vgchange
start()
{
modprobe dlm
for rtrn in 0
do
if ! pidof clvmd > /dev/null
@@ -40,12 +38,15 @@ start()
fi
fi
# refresh cache
$VGSCAN > /dev/null 2>&1
if [ -n "$LVM_VGS" ]
then
for vg in $LVM_VGS
do
echo -n "Activating lvm $vg:"
if $vgchange -ayl $vg > /dev/null 2>&1
if $VGCHANGE -ayl $vg > /dev/null 2>&1
then
success
echo
@@ -57,7 +58,7 @@ start()
done
else
echo -n "Activating lvms:"
if $vgchange -ayl > /dev/null 2>&1
if $VGCHANGE -ayl > /dev/null 2>&1
then
success
echo
@@ -81,7 +82,7 @@ stop()
for vg in $LVM_VGS
do
echo -n "Deactivating lvm $vg:"
if $vgchange -anl $vg > /dev/null 2>&1
if $VGCHANGE -anl $vg > /dev/null 2>&1
then
success
echo
@@ -93,7 +94,7 @@ stop()
done
else
echo -n "Deactivating lvms:"
if $vgchange -anl > /dev/null 2>&1
if $VGCHANGE -anl > /dev/null 2>&1
then
success
echo
@@ -124,7 +125,6 @@ stop()
echo
fi
done
modprobe -r dlm > /dev/null 2>&1
return $rtrn
}
@@ -153,7 +153,7 @@ case "$1" in
status)
status clvmd
vols=$( $lvdisplay -C --nohead 2> /dev/null | awk '($3 ~ /....a./) {print $1}' )
vols=$( $LVDISPLAY -C --nohead 2> /dev/null | awk '($3 ~ /....a./) {print $1}' )
echo active volumes: ${vols:-"(none)"}
rtrn=0
;;

View File

@@ -90,14 +90,16 @@ ifeq ("@DEVMAPPER@", "yes")
LVMLIBS += -ldevmapper
endif
CFLAGS += -DLVM_SHARED_PATH=\"$(exec_prefix)/sbin/lvm\"
include $(top_srcdir)/make.tmpl
lvm: $(OBJECTS) lvm.o $(top_srcdir)/lib/liblvm.a
$(CC) -o $@ $(OBJECTS) lvm.o $(LDFLAGS) $(LVMLIBS) $(LIBS) -rdynamic
lvm.static: $(OBJECTS) lvm.o $(top_srcdir)/lib/liblvm.a
$(CC) -o $@ $(OBJECTS) lvm.o -static $(LDFLAGS) $(LVMLIBS) $(LIBS) \
-rdynamic
lvm.static: $(OBJECTS) lvm-static.o $(top_srcdir)/lib/liblvm.a
$(CC) -o $@ $(OBJECTS) lvm-static.o -static $(LDFLAGS) $(LVMLIBS) \
$(LIBS) -rdynamic
liblvm2cmd.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS)
cat $(top_srcdir)/lib/liblvm.a > $@

View File

@@ -59,6 +59,7 @@ arg(activevolumegroups_ARG, 'A', "activevolumegroups", NULL)
arg(background_ARG, 'b', "background", NULL)
arg(blockdevice_ARG, 'b', "blockdevice", NULL)
arg(chunksize_ARG, 'c', "chunksize", size_kb_arg)
arg(clustered_ARG, 'c', "clustered", yes_no_arg)
arg(colon_ARG, 'c', "colon", NULL)
arg(columns_ARG, 'C', "columns", NULL)
arg(contiguous_ARG, 'C', "contiguous", yes_no_arg)

View File

@@ -410,6 +410,7 @@ xx(pvdisplay,
"\n"
"pvdisplay --columns|-C\n"
"\t[--aligned]\n"
"\t[-a|--all]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -424,9 +425,9 @@ xx(pvdisplay,
"\t[--version]" "\n"
"\t[PhysicalVolumePath [PhysicalVolumePath...]]\n",
aligned_ARG, colon_ARG, columns_ARG, ignorelockingfailure_ARG, maps_ARG,
noheadings_ARG, nosuffix_ARG, options_ARG, separator_ARG, short_ARG,
sort_ARG, unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, colon_ARG, columns_ARG, ignorelockingfailure_ARG,
maps_ARG, noheadings_ARG, nosuffix_ARG, options_ARG, separator_ARG,
short_ARG, sort_ARG, unbuffered_ARG, units_ARG)
xx(pvmove,
"Move extents from one physical volume to another",
@@ -436,7 +437,6 @@ xx(pvmove,
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
"\t[-d|--debug]\n "
"\t[-f|--force]\n"
"\t[-h|-?|--help]\n"
"\t[-i|--interval seconds]\n"
"\t[-t|--test]\n "
@@ -447,7 +447,7 @@ xx(pvmove,
"\tSourcePhysicalVolume[:PhysicalExtent[-PhysicalExtent]...]}\n"
"\t[DestinationPhysicalVolume[:PhysicalExtent[-PhysicalExtent]...]...]\n",
abort_ARG, alloc_ARG, autobackup_ARG, background_ARG, force_ARG,
abort_ARG, alloc_ARG, autobackup_ARG, background_ARG,
interval_ARG, name_ARG, test_ARG)
xx(pvremove,
@@ -566,6 +566,7 @@ xx(vgchange,
"\t[-v|--verbose] " "\n"
"\t[--version]" "\n"
"\t{-a|--available [e|l]{y|n} |" "\n"
"\t -c|--clustered {y|n} |" "\n"
"\t -x|--resizeable {y|n} |" "\n"
"\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
"\t --addtag Tag |\n"
@@ -573,8 +574,8 @@ xx(vgchange,
"\t[VolumeGroupName...]\n",
addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
deltag_ARG, ignorelockingfailure_ARG, logicalvolume_ARG, partial_ARG,
resizeable_ARG, resizable_ARG, test_ARG, uuid_ARG)
clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, logicalvolume_ARG,
partial_ARG, resizeable_ARG, resizable_ARG, test_ARG, uuid_ARG)
xx(vgck,
"Check the consistency of volume group(s)",
@@ -608,6 +609,7 @@ xx(vgcreate,
"\t[-A|--autobackup {y|n}] " "\n"
"\t[--addtag Tag] " "\n"
"\t[--alloc AllocationPolicy] " "\n"
"\t[-c|--clustered] " "\n"
"\t[-d|--debug]" "\n"
"\t[-h|--help]" "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
@@ -619,7 +621,7 @@ xx(vgcreate,
"\t[--version] " "\n"
"\tVolumeGroupName PhysicalVolume [PhysicalVolume...]\n",
addtag_ARG, alloc_ARG, autobackup_ARG, maxlogicalvolumes_ARG,
addtag_ARG, alloc_ARG, autobackup_ARG, clustered_ARG, maxlogicalvolumes_ARG,
maxphysicalvolumes_ARG, metadatatype_ARG, physicalextentsize_ARG, test_ARG)
xx(vgdisplay,

View File

@@ -23,6 +23,7 @@
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <libgen.h>
#ifdef HAVE_GETOPTLONG
# include <getopt.h>
@@ -58,7 +59,9 @@ enum {
MAJOR_ARG,
MINOR_ARG,
NOHEADINGS_ARG,
NOOPENCOUNT_ARG,
NOTABLE_ARG,
OPTIONS_ARG,
UUID_ARG,
VERBOSE_ARG,
VERSION_ARG,
@@ -68,6 +71,7 @@ enum {
static int _switches[NUM_SWITCHES];
static int _values[NUM_SWITCHES];
static char *_uuid;
static char *_fields;
/*
* Commands
@@ -136,15 +140,18 @@ static void _display_info_cols_noheadings(struct dm_task *dmt,
uuid = dm_task_get_uuid(dmt);
printf("%s:%d:%d:%s%s%s%s:%d:%d:%" PRIu32 ":%s\n",
dm_task_get_name(dmt),
info->major, info->minor,
info->live_table ? "L" : "-",
info->inactive_table ? "I" : "-",
info->suspended ? "s" : "-",
info->read_only ? "r" : "w",
info->open_count, info->target_count, info->event_nr,
uuid && *uuid ? uuid : "");
if (_switches[OPTIONS_ARG])
printf("%s\n", dm_task_get_name(dmt));
else
printf("%s:%d:%d:%s%s%s%s:%d:%d:%" PRIu32 ":%s\n",
dm_task_get_name(dmt),
info->major, info->minor,
info->live_table ? "L" : "-",
info->inactive_table ? "I" : "-",
info->suspended ? "s" : "-",
info->read_only ? "r" : "w",
info->open_count, info->target_count, info->event_nr,
uuid && *uuid ? uuid : "");
}
static void _display_info_cols(struct dm_task *dmt, struct dm_info *info)
@@ -158,24 +165,31 @@ static void _display_info_cols(struct dm_task *dmt, struct dm_info *info)
}
if (!_headings) {
printf("Name Maj Min Stat Open Targ Event UUID\n");
if (_switches[OPTIONS_ARG])
printf("Name\n");
else
printf("Name Maj Min Stat Open Targ "
"Event UUID\n");
_headings = 1;
}
printf("%-16s ", dm_task_get_name(dmt));
if (_switches[OPTIONS_ARG])
printf("%s\n", dm_task_get_name(dmt));
else {
printf("%-16s %3d %3d %s%s%s%s %4d %4d %6" PRIu32 " ",
dm_task_get_name(dmt),
info->major, info->minor,
info->live_table ? "L" : "-",
info->inactive_table ? "I" : "-",
info->suspended ? "s" : "-",
info->read_only ? "r" : "w",
info->open_count, info->target_count, info->event_nr);
printf("%3d %3d %s%s%s%s %4d %4d %6" PRIu32 " ",
info->major, info->minor,
info->live_table ? "L" : "-",
info->inactive_table ? "I" : "-",
info->suspended ? "s" : "-",
info->read_only ? "r" : "w",
info->open_count, info->target_count, info->event_nr);
if ((uuid = dm_task_get_uuid(dmt)) && *uuid)
printf("%s", uuid);
if ((uuid = dm_task_get_uuid(dmt)) && *uuid)
printf("%s", uuid);
printf("\n");
printf("\n");
}
}
static void _display_info_long(struct dm_task *dmt, struct dm_info *info)
@@ -216,12 +230,12 @@ static void _display_info_long(struct dm_task *dmt, struct dm_info *info)
printf("\n");
}
static void _display_info(struct dm_task *dmt)
static int _display_info(struct dm_task *dmt)
{
struct dm_info info;
if (!dm_task_get_info(dmt, &info))
return;
return 0;
if (!_switches[COLS_ARG])
_display_info_long(dmt, &info);
@@ -229,6 +243,8 @@ static void _display_info(struct dm_task *dmt)
_display_info_cols_noheadings(dmt, &info);
else
_display_info_cols(dmt, &info);
return info.exists ? 1 : 0;
}
static int _set_task_device(struct dm_task *dmt, const char *name, int optional)
@@ -291,13 +307,16 @@ static int _load(int argc, char **argv, void *data)
if (_switches[READ_ONLY] && !dm_task_set_ro(dmt))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
r = 1;
if (_switches[VERBOSE_ARG])
_display_info(dmt);
r = _display_info(dmt);
out:
dm_task_destroy(dmt);
@@ -335,13 +354,16 @@ static int _create(int argc, char **argv, void *data)
if (_switches[MINOR_ARG] && !dm_task_set_minor(dmt, _values[MINOR_ARG]))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
r = 1;
if (_switches[VERBOSE_ARG])
_display_info(dmt);
r = _display_info(dmt);
out:
dm_task_destroy(dmt);
@@ -364,6 +386,9 @@ static int _rename(int argc, char **argv, void *data)
if (!dm_task_set_newname(dmt, argv[argc - 1]))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
@@ -420,6 +445,9 @@ static int _message(int argc, char **argv, void *data)
free(str);
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
@@ -476,10 +504,13 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
if (event_nr && !dm_task_set_event_nr(dmt, event_nr))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
r = dm_task_run(dmt);
if (r && display && _switches[VERBOSE_ARG])
_display_info(dmt);
r = _display_info(dmt);
out:
dm_task_destroy(dmt);
@@ -599,6 +630,9 @@ static int _status(int argc, char **argv, void *data)
if (!_set_task_device(dmt, name, 0))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
@@ -674,6 +708,9 @@ static int _mknodes(int argc, char **argv, void *data)
if (!_set_task_device(dmt, argc > 1 ? argv[1] : NULL, 1))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
@@ -707,12 +744,13 @@ static int _info(int argc, char **argv, void *data)
if (!_set_task_device(dmt, name, 0))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
_display_info(dmt);
r = 1;
r = _display_info(dmt);
out:
dm_task_destroy(dmt);
@@ -744,6 +782,9 @@ static int _deps(int argc, char **argv, void *data)
if (!_set_task_device(dmt, name, 0))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
@@ -841,7 +882,7 @@ static void _usage(FILE *out)
fprintf(out, "Usage:\n\n");
fprintf(out, "dmsetup [--version] [-v|--verbose [-v|--verbose ...]]\n"
" [-r|--readonly]\n\n");
" [-r|--readonly] [--noopencount]\n\n");
for (i = 0; _commands[i].name; i++)
fprintf(out, "\t%s %s\n", _commands[i].name, _commands[i].help);
fprintf(out, "\n<device> may be device name or -u <uuid> or "
@@ -863,6 +904,7 @@ static struct command *_find_command(const char *name)
static int _process_switches(int *argc, char ***argv)
{
char *base, *namebase;
int ind;
int c;
@@ -873,7 +915,9 @@ static int _process_switches(int *argc, char ***argv)
{"major", 1, NULL, MAJOR_ARG},
{"minor", 1, NULL, MINOR_ARG},
{"noheadings", 0, NULL, NOHEADINGS_ARG},
{"noopencount", 0, NULL, NOOPENCOUNT_ARG},
{"notable", 0, NULL, NOTABLE_ARG},
{"options", 1, NULL, OPTIONS_ARG},
{"uuid", 1, NULL, UUID_ARG},
{"verbose", 1, NULL, VERBOSE_ARG},
{"version", 0, NULL, VERSION_ARG},
@@ -889,9 +933,43 @@ static int _process_switches(int *argc, char ***argv)
memset(&_switches, 0, sizeof(_switches));
memset(&_values, 0, sizeof(_values));
namebase = strdup((*argv)[0]);
base = basename(namebase);
if (!strcmp(base, "devmap_name")) {
free(namebase);
_switches[COLS_ARG]++;
_switches[NOHEADINGS_ARG]++;
_switches[OPTIONS_ARG]++;
_switches[MAJOR_ARG]++;
_switches[MINOR_ARG]++;
_fields = (char *) "name";
if (*argc == 3) {
_values[MAJOR_ARG] = atoi((*argv)[1]);
_values[MINOR_ARG] = atoi((*argv)[2]);
*argc -= 2;
*argv += 2;
} else if ((*argc == 2) &&
(2 == sscanf((*argv)[1], "%i:%i",
&_values[MAJOR_ARG],
&_values[MINOR_ARG]))) {
*argc -= 1;
*argv += 1;
} else {
fprintf(stderr, "Usage: devmap_name <major> <minor>\n");
return 0;
}
(*argv)[0] = (char *) "info";
return 1;
}
free(namebase);
optarg = 0;
optind = OPTIND_INIT;
while ((c = GETOPTLONG_FN(*argc, *argv, "cCj:m:nru:v",
while ((c = GETOPTLONG_FN(*argc, *argv, "cCj:m:no:ru:v",
long_options, &ind)) != -1) {
if (c == 'c' || c == 'C' || ind == COLS_ARG)
_switches[COLS_ARG]++;
@@ -907,6 +985,10 @@ static int _process_switches(int *argc, char ***argv)
}
if (c == 'n' || ind == NOTABLE_ARG)
_switches[NOTABLE_ARG]++;
if (c == 'o' || ind == OPTIONS_ARG) {
_switches[OPTIONS_ARG]++;
_fields = optarg;
}
if (c == 'v' || ind == VERBOSE_ARG)
_switches[VERBOSE_ARG]++;
if (c == 'u' || ind == UUID_ARG) {
@@ -915,6 +997,8 @@ static int _process_switches(int *argc, char ***argv)
}
if ((ind == NOHEADINGS_ARG))
_switches[NOHEADINGS_ARG]++;
if ((ind == NOOPENCOUNT_ARG))
_switches[NOOPENCOUNT_ARG]++;
if ((ind == VERSION_ARG))
_switches[VERSION_ARG]++;
}
@@ -929,6 +1013,11 @@ static int _process_switches(int *argc, char ***argv)
return 0;
}
if (_switches[OPTIONS_ARG] && strcmp(_fields, "name")) {
fprintf(stderr, "Only -o name is supported so far.\n");
return 0;
}
*argv += optind;
*argc -= optind;
return 1;
@@ -939,7 +1028,7 @@ int main(int argc, char **argv)
struct command *c;
if (!_process_switches(&argc, &argv)) {
fprintf(stderr, "Couldn't process command line switches.\n");
fprintf(stderr, "Couldn't process command line.\n");
exit(1);
}

View File

@@ -94,6 +94,12 @@ static int lvchange_availability(struct cmd_context *cmd,
return 0;
}
} else {
if (lockingfailed() && (lv->vg->status & CLUSTERED)) {
log_verbose("Locking failed: ignoring clustered "
"logical volume %s", lv->name);
return 0;
}
if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
log_verbose("Activating logical volume \"%s\" "
"exclusively", lv->name);
@@ -256,7 +262,7 @@ static int lvchange_persistent(struct cmd_context *cmd,
log_error("Major number must be specified with -My");
return 0;
}
if (lv_info(lv, &info) && info.exists &&
if (lv_info(lv, &info, 0) && info.exists &&
!arg_count(cmd, force_ARG)) {
if (yes_no_prompt("Logical volume %s will be "
"deactivated temporarily. "
@@ -361,6 +367,7 @@ static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
return 1;
}
static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{

View File

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

21
tools/lvm-static.c Normal file
View File

@@ -0,0 +1,21 @@
/*
* Copyright (C) 2001-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
*/
#include "lvm2cmdline.h"
int main(int argc, char **argv)
{
return lvm2_main(argc, argv, 1);
}

View File

@@ -17,5 +17,5 @@
int main(int argc, char **argv)
{
return lvm2_main(argc, argv);
return lvm2_main(argc, argv, 0);
}

View File

@@ -16,6 +16,6 @@
#ifndef _LVM_CMDLINE_H
#define _LVM_CMDLINE_H
int lvm2_main(int argc, char **argv);
int lvm2_main(int argc, char **argv, int is_static);
#endif

View File

@@ -753,6 +753,7 @@ static void _apply_settings(struct cmd_context *cmd)
init_debug(cmd->current_settings.debug);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
init_test(cmd->current_settings.test);
init_full_scan_done(0);
init_msg_prefix(cmd->default_settings.msg_prefix);
init_cmd_name(cmd->default_settings.cmd_name);
@@ -978,6 +979,7 @@ static void _close_stray_fds(void)
{
struct rlimit rlim;
int fd;
int suppress_warnings = 0;
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
fprintf(stderr, "getrlimit(RLIMIT_NOFILE) failed: %s\n",
@@ -985,8 +987,13 @@ static void _close_stray_fds(void)
return;
}
if (getenv("LVM_SUPPRESS_FD_WARNINGS"))
suppress_warnings = 1;
for (fd = 3; fd < rlim.rlim_cur; fd++) {
if (!close(fd))
if (suppress_warnings)
close(fd);
else if (!close(fd))
fprintf(stderr, "File descriptor %d left open\n", fd);
else if (errno != EBADF)
fprintf(stderr, "Close failed on stray file "
@@ -998,8 +1005,6 @@ static struct cmd_context *_init_lvm(void)
{
struct cmd_context *cmd;
_close_stray_fds();
if (!(cmd = create_toolcontext(&the_args[0]))) {
stack;
return NULL;
@@ -1411,16 +1416,14 @@ static void _exec_lvm1_command(struct cmd_context *cmd, int argc, char **argv)
log_sys_error("execvp", path);
}
int lvm2_main(int argc, char **argv)
int lvm2_main(int argc, char **argv, int is_static)
{
char *namebase, *base;
int ret, alias = 0;
struct cmd_context *cmd;
if (!(cmd = _init_lvm()))
return -1;
_close_stray_fds();
cmd->argv = argv;
namebase = strdup(argv[0]);
base = basename(namebase);
while (*base == '/')
@@ -1428,8 +1431,21 @@ int lvm2_main(int argc, char **argv)
if (strcmp(base, "lvm") && strcmp(base, "lvm.static") &&
strcmp(base, "initrd-lvm"))
alias = 1;
if (is_static && strcmp(base, "lvm.static") &&
path_exists(LVM_SHARED_PATH) &&
!getenv("LVM_DID_EXEC")) {
setenv("LVM_DID_EXEC", base, 1);
execvp(LVM_SHARED_PATH, argv);
unsetenv("LVM_DID_EXEC");
}
free(namebase);
if (!(cmd = _init_lvm()))
return -1;
cmd->argv = argv;
_register_commands();
if (_lvm1_fallback(cmd)) {

View File

@@ -34,7 +34,7 @@ static int _get_max_dev_name_len(struct dev_filter *filter)
struct dev_iter *iter;
struct device *dev;
if (!(iter = dev_iter_create(filter))) {
if (!(iter = dev_iter_create(filter, 1))) {
log_error("dev_iter_create failed");
return 0;
}
@@ -103,7 +103,7 @@ int lvmdiskscan(struct cmd_context *cmd, int argc, char **argv)
max_len = _get_max_dev_name_len(cmd->filter);
if (!(iter = dev_iter_create(cmd->filter))) {
if (!(iter = dev_iter_create(cmd->filter, 0))) {
log_error("dev_iter_create failed");
return ECMD_FAILED;
}

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 */
if (lv_info(lv, &info)) {
if (lv_info(lv, &info, 1)) {
if (info.open_count) {
log_error("Can't remove open logical volume \"%s\"",
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) {
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");
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;
/* 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 ";
else
active_str = "inactive ";

View File

@@ -138,8 +138,11 @@ static int _wait_for_single_mirror(struct cmd_context *cmd, const char *name,
while (!finished) {
/* FIXME Also needed in vg/lvchange -ay? */
/* FIXME Use alarm for regular intervals instead */
if (parms->interval && !parms->aborting)
if (parms->interval && !parms->aborting) {
sleep(parms->interval);
/* Devices might have changed while we slept */
init_full_scan_done(0);
}
/* Locks the (possibly renamed) VG again */
if (!(vg = parms->poll_fns->get_copy_vg(cmd, name))) {

View File

@@ -173,7 +173,11 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
}
} else {
/* --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);

View File

@@ -63,10 +63,10 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
/* Is there an md superblock here? */
if (!dev && md_filtering()) {
unlock_vg(cmd, "");
log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter);
log_verbose("Wiping internal cache");
lvmcache_destroy();
init_md_filtering(0);
if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");

View File

@@ -64,6 +64,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
}
return pvs(cmd, argc, argv);
} else if (arg_count(cmd, aligned_ARG) ||
arg_count(cmd, all_ARG) ||
arg_count(cmd, noheadings_ARG) ||
arg_count(cmd, options_ARG) ||
arg_count(cmd, separator_ARG) ||

View File

@@ -123,10 +123,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, exported_ARG) ?
"of exported volume group(s)" : "in no volume group");
log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter);
log_verbose("Wiping internal cache");
lvmcache_destroy();
log_verbose("Walking through all physical volumes");

View File

@@ -18,6 +18,9 @@
#include <sys/stat.h>
#include <sys/wait.h>
/*
* Metadata iteration functions
*/
int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct list *arg_lvnames, struct list *tags,
void *handle,
@@ -93,23 +96,6 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
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 lock_type, void *handle,
int (*process_single) (struct cmd_context * cmd,
@@ -477,7 +463,7 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle,
int ret_max = 0;
int ret = 0;
if (!(iter = dev_iter_create(cmd->filter))) {
if (!(iter = dev_iter_create(cmd->filter, 1))) {
log_error("dev_iter creation failed");
return ECMD_FAILED;
}
@@ -608,6 +594,9 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
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 *vg_name = lv_name;
@@ -666,6 +655,9 @@ const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
return vg_name;
}
/*
* Extract default volume group name from environment
*/
char *default_vgname(struct cmd_context *cmd)
{
char *vg_path;
@@ -694,6 +686,9 @@ char *default_vgname(struct cmd_context *cmd)
return pool_strdup(cmd->mem, vg_path);
}
/*
* Process physical extent range specifiers
*/
static int _add_pe_range(struct pool *mem, struct list *pe_ranges,
uint32_t start, uint32_t count)
{
@@ -928,6 +923,29 @@ struct list *clone_pv_list(struct pool *mem, struct list *pvsl)
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,
const char *size)
{

View File

@@ -135,7 +135,7 @@ int alloc_arg(struct cmd_context *cmd, struct arg *a);
char yes_no_prompt(const char *prompt, ...);
/* we use the enums to access the switches */
static inline const unsigned int arg_count(struct cmd_context *cmd, int a)
static inline unsigned int arg_count(struct cmd_context *cmd, int a)
{
return cmd->args[a].count;
}
@@ -151,25 +151,25 @@ static inline const char *arg_str_value(struct cmd_context *cmd, int a,
return arg_count(cmd, a) ? cmd->args[a].value : def;
}
static inline const int32_t arg_int_value(struct cmd_context *cmd, int a,
static inline int32_t arg_int_value(struct cmd_context *cmd, int a,
const int32_t def)
{
return arg_count(cmd, a) ? cmd->args[a].i_value : def;
}
static inline const uint32_t arg_uint_value(struct cmd_context *cmd, int a,
static inline uint32_t arg_uint_value(struct cmd_context *cmd, int a,
const uint32_t def)
{
return arg_count(cmd, a) ? cmd->args[a].ui_value : def;
}
static inline const int64_t arg_int64_value(struct cmd_context *cmd, int a,
static inline int64_t arg_int64_value(struct cmd_context *cmd, int a,
const uint64_t def)
{
return arg_count(cmd, a) ? cmd->args[a].i64_value : def;
}
static inline const uint64_t arg_uint64_value(struct cmd_context *cmd, int a,
static inline uint64_t arg_uint64_value(struct cmd_context *cmd, int a,
const uint64_t def)
{
return arg_count(cmd, a) ? cmd->args[a].ui64_value : def;
@@ -181,13 +181,13 @@ static inline const void *arg_ptr_value(struct cmd_context *cmd, int a,
return arg_count(cmd, a) ? cmd->args[a].ptr : def;
}
static inline const sign_t arg_sign_value(struct cmd_context *cmd, int a,
static inline sign_t arg_sign_value(struct cmd_context *cmd, int a,
const sign_t def)
{
return arg_count(cmd, a) ? cmd->args[a].sign : def;
}
static inline const int arg_count_increment(struct cmd_context *cmd, int a)
static inline int arg_count_increment(struct cmd_context *cmd, int a)
{
return cmd->args[a].count++;
}

View File

@@ -83,6 +83,12 @@ static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
return ECMD_FAILED;
}
if (activate && lockingfailed() && (vg->status & CLUSTERED)) {
log_error("Locking inactive: ignoring clustered "
"volume group %s", vg->name);
return ECMD_FAILED;
}
if (activate && (active = lvs_in_vg_activated(vg)))
log_verbose("%d logical volume(s) in volume group \"%s\" "
"already active", active, vg->name);
@@ -168,6 +174,41 @@ static int _vgchange_resizeable(struct cmd_context *cmd,
return ECMD_PROCESSED;
}
static int _vgchange_clustered(struct cmd_context *cmd,
struct volume_group *vg)
{
int clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
if (clustered && (vg->status & CLUSTERED)) {
log_error("Volume group \"%s\" is already clustered",
vg->name);
return ECMD_FAILED;
}
if (!clustered && !(vg->status & CLUSTERED)) {
log_error("Volume group \"%s\" is already not clustered",
vg->name);
return ECMD_FAILED;
}
if (!archive(vg))
return ECMD_FAILED;
if (clustered)
vg->status |= CLUSTERED;
else
vg->status &= ~CLUSTERED;
if (!vg_write(vg) || !vg_commit(vg))
return ECMD_FAILED;
backup(vg);
log_print("Volume group \"%s\" successfully changed", vg->name);
return ECMD_PROCESSED;
}
static int _vgchange_logicalvolume(struct cmd_context *cmd,
struct volume_group *vg)
{
@@ -264,7 +305,11 @@ static int _vgchange_uuid(struct cmd_context *cmd, struct volume_group *vg)
if (!archive(vg))
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) {
memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));
@@ -330,6 +375,9 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
else if (arg_count(cmd, alloc_ARG))
r = _vgchange_alloc(cmd, vg);
else if (arg_count(cmd, clustered_ARG))
r = _vgchange_clustered(cmd, vg);
return r;
}
@@ -339,8 +387,8 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
(arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) +
arg_count(cmd, alloc_ARG))) {
log_error("One of -a, -l, -x, --alloc, --addtag, --deltag "
arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG))) {
log_error("One of -a, -c, -l, -x, --alloc, --addtag, --deltag "
"or --uuid required");
return EINVALID_CMD_LINE;
}
@@ -349,9 +397,9 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
if (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, alloc_ARG) +
arg_count(cmd, uuid_ARG) > 1) {
log_error("Only one of -a, -l, -x, --alloc, --addtag, --deltag "
"or --uuid allowed");
arg_count(cmd, uuid_ARG) + arg_count(cmd, clustered_ARG) > 1) {
log_error("Only one of -a, -c, -l, -x, --uuid, --alloc, "
"--addtag or --deltag allowed");
return EINVALID_CMD_LINE;
}

View File

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

View File

@@ -26,6 +26,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
struct volume_group *vg;
const char *tag;
alloc_policy_t alloc;
int clustered;
if (!argc) {
log_error("Please provide volume group name and "
@@ -130,6 +131,17 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
}
if (arg_count(cmd, clustered_ARG))
clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
else
/* Default depends on current locking type */
clustered = locking_is_clustered();
if (clustered)
vg->status |= CLUSTERED;
else
vg->status &= ~CLUSTERED;
if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
return ECMD_FAILED;

Some files were not shown because too many files have changed in this diff Show More