summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac289
-rw-r--r--daemons/Makefile.in8
-rw-r--r--daemons/clvmd/.gitignore1
-rw-r--r--daemons/clvmd/Makefile.in94
-rw-r--r--daemons/clvmd/clvm.h85
-rw-r--r--daemons/clvmd/clvmd-cman.c505
-rw-r--r--daemons/clvmd/clvmd-command.c415
-rw-r--r--daemons/clvmd/clvmd-common.h27
-rw-r--r--daemons/clvmd/clvmd-comms.h119
-rw-r--r--daemons/clvmd/clvmd-corosync.c662
-rw-r--r--daemons/clvmd/clvmd-openais.c687
-rw-r--r--daemons/clvmd/clvmd-singlenode.c382
-rw-r--r--daemons/clvmd/clvmd.c2422
-rw-r--r--daemons/clvmd/clvmd.h126
-rw-r--r--daemons/clvmd/lvm-functions.c927
-rw-r--r--daemons/clvmd/lvm-functions.h40
-rw-r--r--daemons/clvmd/refresh_clvmd.c382
-rw-r--r--daemons/clvmd/refresh_clvmd.h19
-rw-r--r--daemons/cmirrord/Makefile.in6
-rw-r--r--daemons/cmirrord/cluster.c3
-rw-r--r--include/configure.h.in18
-rw-r--r--lib/Makefile.in13
-rw-r--r--lib/activate/activate.c214
-rw-r--r--lib/cache/lvmcache.c395
-rw-r--r--lib/locking/Makefile.in26
-rw-r--r--lib/locking/cluster_locking.c636
-rw-r--r--lib/locking/external_locking.c106
-rw-r--r--lib/locking/locking.c152
-rw-r--r--lib/locking/locking_types.h6
-rw-r--r--lib/locking/no_locking.c126
-rw-r--r--lib/metadata/lv.c10
-rw-r--r--lib/metadata/lv_manip.c20
-rw-r--r--lib/metadata/metadata.c126
-rw-r--r--lib/metadata/metadata.h9
-rw-r--r--lib/metadata/vg.c50
-rw-r--r--lib/metadata/vg.h1
-rw-r--r--lib/mirror/mirrored.c15
-rw-r--r--tools/args.h13
-rw-r--r--tools/command-lines.in4
-rw-r--r--tools/lvchange.c29
-rw-r--r--tools/lvconvert.c13
-rw-r--r--tools/lvmcmdline.c5
-rw-r--r--tools/pvmove.c4
-rw-r--r--tools/toollib.c59
-rw-r--r--tools/vgchange.c139
-rw-r--r--tools/vgcreate.c11
-rw-r--r--tools/vgsplit.c1
47 files changed, 36 insertions, 9364 deletions
diff --git a/configure.ac b/configure.ac
index 751a78445..67f24624e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,6 @@ case "$host_os" in
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
- CLUSTER=internal
FSADM=yes
BLKDEACTIVATE=yes
;;
@@ -61,7 +60,6 @@ case "$host_os" in
ODIRECT=no
DM_IOCTLS=no
SELINUX=no
- CLUSTER=none
FSADM=no
BLKDEACTIVATE=no
;;
@@ -283,22 +281,6 @@ AC_MSG_RESULT($MANGLING)
AC_DEFINE_UNQUOTED([DEFAULT_DM_NAME_MANGLING], $mangling, [Define default name mangling behaviour])
################################################################################
-dnl -- cluster_locking inclusion type
-AC_MSG_CHECKING(whether to include support for cluster locking)
-AC_ARG_WITH(cluster,
- AC_HELP_STRING([--with-cluster=TYPE],
- [cluster LVM locking support: internal/shared/none [internal]]),
- CLUSTER=$withval)
-AC_MSG_RESULT($CLUSTER)
-
-case "$CLUSTER" in
- none|shared) ;;
- internal) AC_DEFINE([CLUSTER_LOCKING_INTERNAL], 1,
- [Define to 1 to include built-in support for clustered LVM locking.]) ;;
- *) AC_MSG_ERROR([--with-cluster parameter invalid]) ;;
-esac
-
-################################################################################
dnl -- snapshots inclusion type
AC_MSG_CHECKING(whether to include snapshots)
AC_ARG_WITH(snapshots,
@@ -672,241 +654,6 @@ AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR, ["$DEFAULT_RUN_DIR"],
[Default LVM run directory.])
################################################################################
-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
- The following cluster manager combinations are valid:
- * cman (RHEL5 or equivalent)
- * cman,corosync,openais (or selection of them)
- * singlenode (localhost only)
- * all (autodetect)
- * none (disable build)
- [[none]]],
- CLVMD=$withval, CLVMD=none)
-test "$CLVMD" = yes && CLVMD=all
-AC_MSG_RESULT($CLVMD)
-
-dnl -- If clvmd enabled without cluster locking, automagically include it
-test "$CLVMD" != none -a "$CLUSTER" = none && CLUSTER=internal
-
-dnl -- init pkgconfig if required
-test "$CLVMD" != none && pkg_config_init
-
-dnl -- Express clvmd init script Required-Start / Required-Stop
-CLVMD_CMANAGERS=""
-dnl -- On RHEL4/RHEL5, qdiskd is started from a separate init script.
-dnl -- Enable if we are build for cman.
-CLVMD_NEEDS_QDISKD=no
-
-dnl -- define build types
-if [[ `expr x"$CLVMD" : '.*gulm.*'` != 0 ]]; then
- AC_MSG_ERROR([Since version 2.02.87 GULM locking is no longer supported.]);
-fi
-if [[ `expr x"$CLVMD" : '.*cman.*'` != 0 ]]; then
- BUILDCMAN=yes
- CLVMD_CMANAGERS="$CLVMD_CMANAGERS cman"
- CLVMD_NEEDS_QDISKD=yes
-fi
-if [[ `expr x"$CLVMD" : '.*corosync.*'` != 0 ]]; then
- BUILDCOROSYNC=yes
- CLVMD_CMANAGERS="$CLVMD_CMANAGERS corosync"
-fi
-if [[ `expr x"$CLVMD" : '.*openais.*'` != 0 ]]; then
- BUILDOPENAIS=yes
- CLVMD_CMANAGERS="$CLVMD_CMANAGERS openais"
-fi
-test "$CLVMD_NEEDS_QDISKD" != no && CLVMD_CMANAGERS="$CLVMD_CMANAGERS qdiskd"
-
-dnl -- define a soft bailout if we are autodetecting
-soft_bailout() {
- NOTFOUND=1
-}
-
-hard_bailout() {
- AC_MSG_ERROR([bailing out])
-}
-
-dnl -- if clvmd=all then set soft_bailout (we do not want to error)
-dnl -- and set all builds to yes. We need to do this here
-dnl -- to skip the openais|corosync sanity check above.
-if test "$CLVMD" = all; then
- bailout=soft_bailout
- BUILDCMAN=yes
- BUILDCOROSYNC=yes
- BUILDOPENAIS=yes
-else
- bailout=hard_bailout
-fi
-
-dnl -- helper macro to check libs without adding them to LIBS
-check_lib_no_libs() {
- lib_no_libs_arg1=$1
- shift
- lib_no_libs_arg2=$1
- shift
- lib_no_libs_args=$@
- AC_CHECK_LIB([$lib_no_libs_arg1],
- [$lib_no_libs_arg2],,
- [$bailout],
- [$lib_no_libs_args])
- LIBS=$ac_check_lib_save_LIBS
-}
-
-dnl -- Look for cman libraries if required.
-if test "$BUILDCMAN" = yes; then
- PKG_CHECK_MODULES(CMAN, libcman, [HAVE_CMAN=yes],
- [NOTFOUND=0
- AC_CHECK_HEADERS(libcman.h,,$bailout)
- check_lib_no_libs cman cman_init
- if test $NOTFOUND = 0; then
- AC_MSG_RESULT([no pkg for libcman, using -lcman])
- CMAN_LIBS="-lcman"
- HAVE_CMAN=yes
- fi])
- CHECKCONFDB=yes
- CHECKDLM=yes
-fi
-
-dnl -- Look for corosync that is required also for openais build
-dnl -- only enough recent version of corosync ship pkg-config files.
-dnl -- We can safely rely on that to detect the correct bits.
-if test "$BUILDCOROSYNC" = yes -o "$BUILDOPENAIS" = yes; then
- PKG_CHECK_MODULES(COROSYNC, corosync, [HAVE_COROSYNC=yes], $bailout)
- CHECKCONFDB=yes
- CHECKCMAP=yes
-fi
-
-dnl -- Look for corosync libraries if required.
-if test "$BUILDCOROSYNC" = yes; then
- PKG_CHECK_MODULES(QUORUM, libquorum, [HAVE_QUORUM=yes], $bailout)
- CHECKCPG=yes
- CHECKDLM=yes
-fi
-
-dnl -- Look for openais libraries if required.
-if test "$BUILDOPENAIS" = yes; then
- PKG_CHECK_MODULES(SALCK, libSaLck, [HAVE_SALCK=yes], $bailout)
- CHECKCPG=yes
-fi
-
-dnl -- Below are checks for libraries common to more than one build.
-
-dnl -- Check confdb library.
-dnl -- mandatory for corosync < 2.0 build.
-dnl -- optional for openais/cman build.
-
-if test "$CHECKCONFDB" = yes; then
- PKG_CHECK_MODULES(CONFDB, libconfdb,
- [HAVE_CONFDB=yes], [HAVE_CONFDB=no])
-
- AC_CHECK_HEADERS([corosync/confdb.h],
- [HAVE_CONFDB_H=yes], [HAVE_CONFDB_H=no])
-
- if test "$HAVE_CONFDB" != yes -a "$HAVE_CONFDB_H" = yes; then
- check_lib_no_libs confdb confdb_initialize
- AC_MSG_RESULT([no pkg for confdb, using -lconfdb])
- CONFDB_LIBS="-lconfdb"
- HAVE_CONFDB=yes
- fi
-fi
-
-dnl -- Check cmap library
-dnl -- mandatory for corosync >= 2.0 build.
-
-if test "$CHECKCMAP" = yes; then
- PKG_CHECK_MODULES(CMAP, libcmap,
- [HAVE_CMAP=yes], [HAVE_CMAP=no])
-
- AC_CHECK_HEADERS([corosync/cmap.h],
- [HAVE_CMAP_H=yes], [HAVE_CMAP_H=no])
-
- if test "$HAVE_CMAP" != yes -a "$HAVE_CMAP_H" = yes; then
- check_lib_no_libs cmap cmap_initialize
- AC_MSG_RESULT([no pkg for cmap, using -lcmap])
- CMAP_LIBS="-lcmap"
- HAVE_CMAP=yes
- fi
-fi
-
-if test "$BUILDCOROSYNC" = yes -a \
- "$HAVE_CMAP" != yes -a "$HAVE_CONFDB" != yes -a "$CLVMD" != all; then
- AC_MSG_ERROR([bailing out... cmap (corosync >= 2.0) or confdb (corosync < 2.0) library is required])
-fi
-
-dnl -- Check cpg library.
-if test "$CHECKCPG" = yes; then
- PKG_CHECK_MODULES(CPG, libcpg, [HAVE_CPG=yes], [$bailout])
-fi
-
-dnl -- Check dlm library.
-if test "$CHECKDLM" = yes; then
- PKG_CHECK_MODULES(DLM, libdlm, [HAVE_DLM=yes],
- [NOTFOUND=0
- AC_CHECK_HEADERS(libdlm.h,,[$bailout])
- check_lib_no_libs dlm dlm_lock -lpthread
- if test $NOTFOUND = 0; then
- AC_MSG_RESULT([no pkg for libdlm, using -ldlm])
- DLM_LIBS="-ldlm -lpthread"
- HAVE_DLM=yes
- fi])
-fi
-
-dnl -- If we are autodetecting, we need to re-create
-dnl -- the depedencies checks and set a proper CLVMD,
-dnl -- together with init script Required-Start/Stop entries.
-if test "$CLVMD" = all; then
- CLVMD=none
- CLVMD_CMANAGERS=""
- CLVMD_NEEDS_QDISKD=no
- if test "$HAVE_CMAN" = yes -a \
- "$HAVE_DLM" = yes; then
- AC_MSG_RESULT([Enabling clvmd cman cluster manager])
- CLVMD="$CLVMD,cman"
- CLVMD_CMANAGERS="$CLVMD_CMANAGERS cman"
- CLVMD_NEEDS_QDISKD=yes
- fi
- if test "$HAVE_COROSYNC" = yes -a \
- "$HAVE_QUORUM" = yes -a \
- "$HAVE_CPG" = yes -a \
- "$HAVE_DLM" = yes; then
- if test "$HAVE_CONFDB" = yes -o "$HAVE_CMAP" = yes; then
- AC_MSG_RESULT([Enabling clvmd corosync cluster manager])
- CLVMD="$CLVMD,corosync"
- CLVMD_CMANAGERS="$CLVMD_CMANAGERS corosync"
- fi
- fi
- if test "$HAVE_COROSYNC" = yes -a \
- "$HAVE_CPG" = yes -a \
- "$HAVE_SALCK" = yes; then
- AC_MSG_RESULT([Enabling clvmd openais cluster manager])
- CLVMD="$CLVMD,openais"
- CLVMD_CMANAGERS="$CLVMD_CMANAGERS openais"
- fi
- test "$CLVMD_NEEDS_QDISKD" != no && CLVMD_CMANAGERS="$CLVMD_CMANAGERS qdiskd"
- test "$CLVMD" = none && AC_MSG_RESULT([Disabling clvmd build. No cluster manager detected.])
-fi
-
-dnl -- Fixup CLVMD_CMANAGERS with new corosync
-dnl -- clvmd built with corosync >= 2.0 needs dlm (either init or systemd service)
-dnl -- to be started.
-if [[ `expr x"$CLVMD" : '.*corosync.*'` != 0 ]]; then
- test "$HAVE_CMAP" = yes && CLVMD_CMANAGERS="$CLVMD_CMANAGERS dlm"
-fi
-
-################################################################################
-dnl -- clvmd pidfile
-if test "$CLVMD" != none; then
- AC_ARG_WITH(clvmd-pidfile,
- AC_HELP_STRING([--with-clvmd-pidfile=PATH],
- [clvmd pidfile [PID_DIR/clvmd.pid]]),
- CLVMD_PIDFILE=$withval,
- CLVMD_PIDFILE="$DEFAULT_PID_DIR/clvmd.pid")
- AC_DEFINE_UNQUOTED(CLVMD_PIDFILE, ["$CLVMD_PIDFILE"],
- [Path to clvmd pidfile.])
-fi
-
-################################################################################
dnl -- Build cluster mirror log daemon
AC_MSG_CHECKING(whether to build cluster mirror log daemon)
AC_ARG_ENABLE(cmirrord,
@@ -934,11 +681,6 @@ dnl -- Look for corosync libraries if required.
if [[ "$BUILD_CMIRRORD" = yes ]]; then
pkg_config_init
- AC_DEFINE([CMIRROR_HAS_CHECKPOINT], 1, [Define to 1 to include libSaCkpt.])
- PKG_CHECK_MODULES(SACKPT, libSaCkpt, [HAVE_SACKPT=yes],
- [AC_MSG_RESULT([no libSaCkpt, compiling without it])
- AC_DEFINE([CMIRROR_HAS_CHECKPOINT], 0, [Define to 0 to exclude libSaCkpt.])])
-
if test "$HAVE_CPG" != yes; then
PKG_CHECK_MODULES(CPG, libcpg)
fi
@@ -1538,7 +1280,7 @@ AC_CHECK_LIB(dl, dlopen,
################################################################################
dnl -- Check for shared/static conflicts
-if [[ \( "$LVM1" = shared -o "$POOL" = shared -o "$CLUSTER" = shared \
+if [[ \( "$LVM1" = shared -o "$POOL" = shared \
\) -a "$STATIC_LINK" = yes ]]; then
AC_MSG_ERROR([Features cannot be 'shared' when building statically])
fi
@@ -1758,18 +1500,6 @@ if test "$BUILD_LVMPOLLD" = yes; then
AC_FUNC_STRERROR_R
fi
-if test "$CLVMD" != none; 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,,hard_bailout)
- AC_FUNC_GETMNTENT
- AC_FUNC_SELECT_ARGTYPES
-fi
-
-if test "$CLUSTER" != none; then
- AC_CHECK_HEADERS(sys/socket.h sys/un.h,,hard_bailout)
- AC_CHECK_FUNCS(socket,,hard_bailout)
-fi
-
if test "$BUILD_DMEVENTD" = yes; then
AC_CHECK_HEADERS(arpa/inet.h,,hard_bailout)
fi
@@ -1804,8 +1534,6 @@ LVM_PATH="$SBINDIR/lvm"
AC_DEFINE_UNQUOTED(LVM_PATH, ["$LVM_PATH"], [Path to lvm binary.])
USRSBINDIR="$(eval echo $(eval echo $usrsbindir))"
-CLVMD_PATH="$USRSBINDIR/clvmd"
-AC_DEFINE_UNQUOTED(CLVMD_PATH, ["$CLVMD_PATH"], [Path to clvmd binary.])
FSADM_PATH="$SBINDIR/fsadm"
AC_DEFINE_UNQUOTED(FSADM_PATH, ["$FSADM_PATH"], [Path to fsadm binary.])
@@ -1944,14 +1672,6 @@ AC_SUBST(CHMOD)
AC_SUBST(CLDFLAGS)
AC_SUBST(CLDNOWHOLEARCHIVE)
AC_SUBST(CLDWHOLEARCHIVE)
-AC_SUBST(CLUSTER)
-AC_SUBST(CLVMD)
-AC_SUBST(CLVMD_CMANAGERS)
-AC_SUBST(CLVMD_PATH)
-AC_SUBST(CMAN_CFLAGS)
-AC_SUBST(CMAN_LIBS)
-AC_SUBST(CMAP_CFLAGS)
-AC_SUBST(CMAP_LIBS)
AC_SUBST(CMDLIB)
AC_SUBST(CONFDB_CFLAGS)
AC_SUBST(CONFDB_LIBS)
@@ -2067,7 +1787,6 @@ AC_SUBST(DMEVENTD_PIDFILE)
AC_SUBST(LVMETAD_PIDFILE)
AC_SUBST(LVMPOLLD_PIDFILE)
AC_SUBST(LVMLOCKD_PIDFILE)
-AC_SUBST(CLVMD_PIDFILE)
AC_SUBST(CMIRRORD_PIDFILE)
AC_SUBST(interface)
AC_SUBST(kerneldir)
@@ -2090,7 +1809,6 @@ Makefile
make.tmpl
libdm/make.tmpl
daemons/Makefile
-daemons/clvmd/Makefile
daemons/cmirrord/Makefile
daemons/dmeventd/Makefile
daemons/dmeventd/libdevmapper-event.pc
@@ -2116,7 +1834,6 @@ conf/command_profile_template.profile
conf/metadata_profile_template.profile
include/Makefile
lib/Makefile
-lib/locking/Makefile
include/lvm-version.h
libdaemon/Makefile
libdaemon/client/Makefile
@@ -2132,14 +1849,10 @@ python/setup.py
scripts/blkdeactivate.sh
scripts/blk_availability_init_red_hat
scripts/blk_availability_systemd_red_hat.service
-scripts/clvmd_init_red_hat
scripts/cmirrord_init_red_hat
scripts/com.redhat.lvmdbus1.service
scripts/dm_event_systemd_red_hat.service
scripts/dm_event_systemd_red_hat.socket
-scripts/lvm2_cluster_activation_red_hat.sh
-scripts/lvm2_cluster_activation_systemd_red_hat.service
-scripts/lvm2_clvmd_systemd_red_hat.service
scripts/lvm2_cmirrord_systemd_red_hat.service
scripts/lvm2_lvmdbusd_systemd_red_hat.service
scripts/lvm2_lvmetad_init_red_hat
diff --git a/daemons/Makefile.in b/daemons/Makefile.in
index ebbd740ef..8edaefaa5 100644
--- a/daemons/Makefile.in
+++ b/daemons/Makefile.in
@@ -15,11 +15,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
-.PHONY: dmeventd clvmd cmirrord lvmetad lvmpolld lvmlockd
-
-ifneq ("@CLVMD@", "none")
- SUBDIRS += clvmd
-endif
+.PHONY: dmeventd cmirrord lvmetad lvmpolld lvmlockd
ifeq ("@BUILD_CMIRRORD@", "yes")
SUBDIRS += cmirrord
@@ -53,7 +49,7 @@ ifeq ("@BUILD_DMFILEMAPD@", "yes")
endif
ifeq ($(MAKECMDGOALS),distclean)
- SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd lvmdbusd dmfilemapd
+ SUBDIRS = cmirrord dmeventd lvmetad lvmpolld lvmlockd lvmdbusd dmfilemapd
endif
include $(top_builddir)/make.tmpl
diff --git a/daemons/clvmd/.gitignore b/daemons/clvmd/.gitignore
deleted file mode 100644
index 816032f97..000000000
--- a/daemons/clvmd/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-clvmd
diff --git a/daemons/clvmd/Makefile.in b/daemons/clvmd/Makefile.in
deleted file mode 100644
index 622a60366..000000000
--- a/daemons/clvmd/Makefile.in
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-top_builddir = @top_builddir@
-
-CMAN_LIBS = @CMAN_LIBS@
-CMAN_CFLAGS = @CMAN_CFLAGS@
-CMAP_LIBS = @CMAP_LIBS@
-CMAP_CFLAGS = @CMAP_CFLAGS@
-CONFDB_LIBS = @CONFDB_LIBS@
-CONFDB_CFLAGS = @CONFDB_CFLAGS@
-CPG_LIBS = @CPG_LIBS@
-CPG_CFLAGS = @CPG_CFLAGS@
-DLM_LIBS = @DLM_LIBS@
-DLM_CFLAGS = @DLM_CFLAGS@
-QUORUM_LIBS = @QUORUM_LIBS@
-QUORUM_CFLAGS = @QUORUM_CFLAGS@
-SALCK_LIBS = @SALCK_LIBS@
-SALCK_CFLAGS = @SALCK_CFLAGS@
-
-SOURCES = \
- clvmd-command.c\
- clvmd.c\
- lvm-functions.c\
- refresh_clvmd.c
-
-ifneq (,$(findstring cman,, "@CLVMD@,"))
- SOURCES += clvmd-cman.c
- LMLIBS += $(CMAN_LIBS) $(CONFDB_LIBS) $(DLM_LIBS)
- CFLAGS += $(CMAN_CFLAGS) $(CONFDB_CFLAGS) $(DLM_CFLAGS)
- DEFS += -DUSE_CMAN
-endif
-
-ifneq (,$(findstring openais,, "@CLVMD@,"))
- SOURCES += clvmd-openais.c
- LMLIBS += $(CONFDB_LIBS) $(CPG_LIBS) $(SALCK_LIBS)
- CFLAGS += $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(SALCK_CFLAGS)
- DEFS += -DUSE_OPENAIS
-endif
-
-ifneq (,$(findstring corosync,, "@CLVMD@,"))
- SOURCES += clvmd-corosync.c
- LMLIBS += $(CMAP_LIBS) $(CONFDB_LIBS) $(CPG_LIBS) $(DLM_LIBS) $(QUORUM_LIBS)
- CFLAGS += $(CMAP_CFLAGS) $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(DLM_CFLAGS) $(QUORUM_CFLAGS)
- DEFS += -DUSE_COROSYNC
-endif
-
-ifneq (,$(findstring singlenode,, &quot;@CLVMD@,&quot;))
- SOURCES += clvmd-singlenode.c
- DEFS += -DUSE_SINGLENODE
-endif
-
-ifeq ($(MAKECMDGOALS),distclean)
- SOURCES += clvmd-cman.c
- SOURCES += clvmd-openais.c
- SOURCES += clvmd-corosync.c
- SOURCES += clvmd-singlenode.c
-endif
-
-TARGETS = \
- clvmd
-
-include $(top_builddir)/make.tmpl
-
-LIBS += $(LVMINTERNAL_LIBS) $(PTHREAD_LIBS) -laio
-CFLAGS += -fno-strict-aliasing $(EXTRA_EXEC_CFLAGS)
-
-INSTALL_TARGETS = \
- install_clvmd
-
-clvmd: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a $(INTERNAL_LIBS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) \
- -o clvmd $+ $(LMLIBS) $(LIBS)
-
-.PHONY: install_clvmd
-
-install_clvmd: $(TARGETS)
- $(INSTALL_PROGRAM) -D clvmd $(usrsbindir)/clvmd
-
-install: $(INSTALL_TARGETS)
-
-install_cluster: $(INSTALL_TARGETS)
diff --git a/daemons/clvmd/clvm.h b/daemons/clvmd/clvm.h
deleted file mode 100644
index ae0a13aa4..000000000
--- a/daemons/clvmd/clvm.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* Definitions for CLVMD server and clients */
-
-/*
- * The protocol spoken over the cluster and across the local socket.
- */
-
-#ifndef _CLVM_H
-#define _CLVM_H
-
-#include "configure.h"
-#include <inttypes.h>
-
-struct clvm_header {
- uint8_t cmd; /* See below */
- uint8_t flags; /* See below */
- uint16_t xid; /* Transaction ID */
- uint32_t clientid; /* Only used in Daemon->Daemon comms */
- int32_t status; /* For replies, whether request succeeded */
- uint32_t arglen; /* Length of argument below.
- If >1500 then it will be passed
- around the cluster in the system LV */
- char node[1]; /* Actually a NUL-terminated string, node name.
- If this is empty then the command is
- forwarded to all cluster nodes unless
- FLAG_LOCAL or FLAG_REMOTE is also set. */
- char args[1]; /* Arguments for the command follow the
- node name, This member is only
- valid if the node name is empty */
-} __attribute__ ((packed));
-
-/* 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 */
-#define CLVMD_FLAG_REMOTE 8 /* Do this on all nodes except for the local node */
-
-/* Name of the local socket to communicate between lvm and clvmd */
-#define CLVMD_SOCKNAME DEFAULT_RUN_DIR "/clvmd.sock"
-
-/* Internal commands & replies */
-#define CLVMD_CMD_REPLY 1
-#define CLVMD_CMD_VERSION 2 /* Send version around cluster when we start */
-#define CLVMD_CMD_GOAWAY 3 /* Die if received this - we are running
- an incompatible version */
-#define CLVMD_CMD_TEST 4 /* Just for mucking about */
-
-#define CLVMD_CMD_LOCK 30
-#define CLVMD_CMD_UNLOCK 31
-
-/* Lock/Unlock commands */
-#define CLVMD_CMD_LOCK_LV 50
-#define CLVMD_CMD_LOCK_VG 51
-#define CLVMD_CMD_LOCK_QUERY 52
-
-/* Misc functions */
-#define CLVMD_CMD_REFRESH 40
-#define CLVMD_CMD_GET_CLUSTERNAME 41
-#define CLVMD_CMD_SET_DEBUG 42
-#define CLVMD_CMD_VG_BACKUP 43
-#define CLVMD_CMD_RESTART 44
-#define CLVMD_CMD_SYNC_NAMES 45
-
-/* Used internally by some callers, but not part of the protocol.*/
-#ifndef NODE_ALL
-# define NODE_ALL "*"
-# define NODE_LOCAL "."
-# define NODE_REMOTE "^"
-#endif
-
-#endif
diff --git a/daemons/clvmd/clvmd-cman.c b/daemons/clvmd/clvmd-cman.c
deleted file mode 100644
index 8cf7f176c..000000000
--- a/daemons/clvmd/clvmd-cman.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2002-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * CMAN communication layer for clvmd.
- */
-
-#include "clvmd-common.h"
-
-#include <pthread.h>
-
-#include "clvmd-comms.h"
-#include "daemons/clvmd/clvm.h"
-#include "clvmd.h"
-#include "lvm-functions.h"
-
-#include <libdlm.h>
-
-#include <syslog.h>
-
-#define LOCKSPACE_NAME "clvmd"
-
-struct clvmd_node
-{
- struct cman_node *node;
- int clvmd_up;
-};
-
-static int num_nodes;
-static struct cman_node *nodes = NULL;
-static struct cman_node this_node;
-static int count_nodes; /* size of allocated nodes array */
-static struct dm_hash_table *node_updown_hash;
-static dlm_lshandle_t *lockspace;
-static cman_handle_t c_handle;
-
-static void count_clvmds_running(void);
-static void get_members(void);
-static int nodeid_from_csid(const char *csid);
-static int name_from_nodeid(int nodeid, char *name);
-static void event_callback(cman_handle_t handle, void *private, int reason, int arg);
-static void data_callback(cman_handle_t handle, void *private,
- char *buf, int len, uint8_t port, int nodeid);
-
-struct lock_wait {
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- struct dlm_lksb lksb;
-};
-
-static int _init_cluster(void)
-{
- node_updown_hash = dm_hash_create(100);
-
- /* Open the cluster communication socket */
- c_handle = cman_init(NULL);
- if (!c_handle) {
- syslog(LOG_ERR, "Can't open cluster manager socket: %m");
- return -1;
- }
- DEBUGLOG("Connected to CMAN\n");
-
- if (cman_start_recv_data(c_handle, data_callback, CLUSTER_PORT_CLVMD)) {
- syslog(LOG_ERR, "Can't bind cluster socket: %m");
- return -1;
- }
-
- if (cman_start_notification(c_handle, event_callback)) {
- syslog(LOG_ERR, "Can't start cluster event listening");
- return -1;
- }
-
- /* Get the cluster members list */
- get_members();
- count_clvmds_running();
-
- DEBUGLOG("CMAN initialisation complete\n");
-
- /* Create a lockspace for LV & VG locks to live in */
- lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
- if (!lockspace) {
- lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
- if (!lockspace) {
- syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
- return -1;
- }
- DEBUGLOG("Created DLM lockspace for CLVMD.\n");
- } else
- DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
-
- dlm_ls_pthread_init(lockspace);
- DEBUGLOG("DLM initialisation complete\n");
- return 0;
-}
-
-static void _cluster_init_completed(void)
-{
- clvmd_cluster_init_completed();
-}
-
-static int _get_main_cluster_fd(void)
-{
- return cman_get_fd(c_handle);
-}
-
-static int _get_num_nodes(void)
-{
- int i;
- int nnodes = 0;
-
- /* return number of ACTIVE nodes */
- for (i=0; i<num_nodes; i++) {
- if (nodes[i].cn_member && nodes[i].cn_nodeid)
- nnodes++;
- }
- return nnodes;
-}
-
-/* send_message with the fd check removed */
-static int _cluster_send_message(const void *buf, int msglen, const char *csid,
- const char *errtext)
-{
- int nodeid = 0;
-
- if (csid)
- memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
-
- if (cman_send_data(c_handle, buf, msglen, 0, CLUSTER_PORT_CLVMD, nodeid) <= 0)
- {
- log_error("%s", errtext);
- }
- return msglen;
-}
-
-static void _get_our_csid(char *csid)
-{
- if (this_node.cn_nodeid == 0) {
- cman_get_node(c_handle, 0, &this_node);
- }
- memcpy(csid, &this_node.cn_nodeid, CMAN_MAX_CSID_LEN);
-}
-
-/* Call a callback routine for each node is that known (down means not running a clvmd) */
-static int _cluster_do_node_callback(struct local_client *client,
- void (*callback) (struct local_client *,
- const char *,
- int))
-{
- int i;
- int somedown = 0;
-
- for (i = 0; i < _get_num_nodes(); i++) {
- if (nodes[i].cn_member && nodes[i].cn_nodeid) {
- int up = (int)(long)dm_hash_lookup_binary(node_updown_hash, (char *)&nodes[i].cn_nodeid, sizeof(int));
-
- callback(client, (char *)&nodes[i].cn_nodeid, up);
- if (!up)
- somedown = -1;
- }
- }
- return somedown;
-}
-
-/* Process OOB messages from the cluster socket */
-static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- char namebuf[MAX_CLUSTER_MEMBER_NAME_LEN];
-
- switch (reason) {
- case CMAN_REASON_PORTCLOSED:
- name_from_nodeid(arg, namebuf);
- log_notice("clvmd on node %s has died\n", namebuf);
- DEBUGLOG("Got port closed message, removing node %s\n", namebuf);
-
- dm_hash_insert_binary(node_updown_hash, (char *)&arg, sizeof(int), (void *)0);
- break;
-
- case CMAN_REASON_STATECHANGE:
- DEBUGLOG("Got state change message, re-reading members list\n");
- get_members();
- break;
-
-#if defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2
- case CMAN_REASON_PORTOPENED:
- /* Ignore this, wait for startup message from clvmd itself */
- break;
-
- case CMAN_REASON_TRY_SHUTDOWN:
- DEBUGLOG("Got try shutdown, sending OK\n");
- cman_replyto_shutdown(c_handle, 1);
- break;
-#endif
- default:
- /* ERROR */
- DEBUGLOG("Got unknown event callback message: %d\n", reason);
- break;
- }
-}
-
-static struct local_client *cman_client;
-static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
- const char *csid,
- struct local_client **new_client)
-{
-
- /* Save this for data_callback */
- cman_client = fd;
-
- /* We never return a new client */
- *new_client = NULL;
-
- return cman_dispatch(c_handle, 0);
-}
-
-
-static void data_callback(cman_handle_t handle, void *private,
- char *buf, int len, uint8_t port, int nodeid)
-{
- /* Ignore looped back messages */
- if (nodeid == this_node.cn_nodeid)
- return;
- process_message(cman_client, buf, len, (char *)&nodeid);
-}
-
-static void _add_up_node(const char *csid)
-{
- /* It's up ! */
- int nodeid = nodeid_from_csid(csid);
-
- dm_hash_insert_binary(node_updown_hash, (char *)&nodeid, sizeof(int), (void *)1);
- DEBUGLOG("Added new node %d to updown list\n", nodeid);
-}
-
-static void _cluster_closedown(void)
-{
- dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
- cman_finish(c_handle);
-}
-
-static int is_listening(int nodeid)
-{
- int status;
-
- do {
- status = cman_is_listening(c_handle, nodeid, CLUSTER_PORT_CLVMD);
- if (status < 0 && errno == EBUSY) { /* Don't busywait */
- sleep(1);
- errno = EBUSY; /* In case sleep trashes it */
- }
- }
- while (status < 0 && errno == EBUSY);
-
- return status;
-}
-
-/* Populate the list of CLVMDs running.
- called only at startup time */
-static void count_clvmds_running(void)
-{
- int i;
-
- for (i = 0; i < num_nodes; i++) {
- int nodeid = nodes[i].cn_nodeid;
-
- if (is_listening(nodeid) == 1)
- dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)1);
- else
- dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)0);
- }
-}
-
-/* Get a list of active cluster members */
-static void get_members(void)
-{
- int retnodes;
- int status;
- int i;
- int high_nodeid = 0;
-
- num_nodes = cman_get_node_count(c_handle);
- if (num_nodes == -1) {
- log_error("Unable to get node count");
- return;
- }
-
- /* Not enough room for new nodes list ? */
- if (num_nodes > count_nodes && nodes) {
- free(nodes);
- nodes = NULL;
- }
-
- if (nodes == NULL) {
- count_nodes = num_nodes + 10; /* Overallocate a little */
- nodes = malloc(count_nodes * sizeof(struct cman_node));
- if (!nodes) {
- log_error("Unable to allocate nodes array\n");
- exit(5);
- }
- }
-
- status = cman_get_nodes(c_handle, count_nodes, &retnodes, nodes);
- if (status < 0) {
- log_error("Unable to get node details");
- exit(6);
- }
-
- /* Get the highest nodeid */
- for (i=0; i<retnodes; i++) {
- if (nodes[i].cn_nodeid > high_nodeid)
- high_nodeid = nodes[i].cn_nodeid;
- }
-}
-
-
-/* Convert a node name to a CSID */
-static int _csid_from_name(char *csid, const char *name)
-{
- int i;
-
- for (i = 0; i < num_nodes; i++) {
- if (strcmp(name, nodes[i].cn_name) == 0) {
- memcpy(csid, &nodes[i].cn_nodeid, CMAN_MAX_CSID_LEN);
- return 0;
- }
- }
- return -1;
-}
-
-/* Convert a CSID to a node name */
-static int _name_from_csid(const char *csid, char *name)
-{
- int i;
-
- for (i = 0; i < num_nodes; i++) {
- if (memcmp(csid, &nodes[i].cn_nodeid, CMAN_MAX_CSID_LEN) == 0) {
- strcpy(name, nodes[i].cn_name);
- return 0;
- }
- }
- /* Who?? */
- strcpy(name, "Unknown");
- return -1;
-}
-
-/* Convert a node ID to a node name */
-static int name_from_nodeid(int nodeid, char *name)
-{
- int i;
-
- for (i = 0; i < num_nodes; i++) {
- if (nodeid == nodes[i].cn_nodeid) {
- strcpy(name, nodes[i].cn_name);
- return 0;
- }
- }
- /* Who?? */
- strcpy(name, "Unknown");
- return -1;
-}
-
-/* Convert a CSID to a node ID */
-static int nodeid_from_csid(const char *csid)
-{
- int nodeid;
-
- memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
-
- return nodeid;
-}
-
-static int _is_quorate(void)
-{
- return cman_is_quorate(c_handle);
-}
-
-static void sync_ast_routine(void *arg)
-{
- struct lock_wait *lwait = arg;
-
- pthread_mutex_lock(&lwait->mutex);
- pthread_cond_signal(&lwait->cond);
- pthread_mutex_unlock(&lwait->mutex);
-}
-
-static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (!lockid) {
- errno = EINVAL;
- return -1;
- }
-
- DEBUGLOG("sync_lock: '%s' mode:%d flags=%d\n", resource,mode,flags);
- /* Conversions need the lockid in the LKSB */
- if (flags & LKF_CONVERT)
- lwait.lksb.sb_lkid = *lockid;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_ls_lock(lockspace,
- mode,
- &lwait.lksb,
- flags,
- resource,
- strlen(resource),
- 0, sync_ast_routine, &lwait, NULL, NULL);
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- *lockid = lwait.lksb.sb_lkid;
-
- errno = lwait.lksb.sb_status;
- DEBUGLOG("sync_lock: returning lkid %x\n", *lockid);
- if (lwait.lksb.sb_status)
- return -1;
- else
- return 0;
-}
-
-static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
-{
- int status;
- struct lock_wait lwait;
-
- DEBUGLOG("sync_unlock: '%s' lkid:%x\n", resource, lockid);
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_ls_unlock(lockspace, lockid, 0, &lwait.lksb, &lwait);
-
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status != EUNLOCK)
- return -1;
- else
- return 0;
-
-}
-
-static int _get_cluster_name(char *buf, int buflen)
-{
- cman_cluster_t cluster_info;
- int status;
-
- status = cman_get_cluster(c_handle, &cluster_info);
- if (!status) {
- strncpy(buf, cluster_info.ci_name, buflen);
- }
- return status;
-}
-
-static struct cluster_ops _cluster_cman_ops = {
- .name = "cman",
- .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,
- .get_cluster_name = _get_cluster_name,
- .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;
-}
diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c
deleted file mode 100644
index 342addaee..000000000
--- a/daemons/clvmd/clvmd-command.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
-
- CLVMD Cluster LVM daemon command processor.
-
- To add commands to the daemon simply add a processor in do_command and return
- and messages back in buf and the length in *retlen. The initial value of
- buflen is the maximum size of the buffer. if buf is not large enough then it
- may be reallocated by the functions in here to a suitable size bearing in
- mind that anything larger than the passed-in size will have to be returned
- using the system LV and so performance will suffer.
-
- The status return will be negated and passed back to the originating node.
-
- pre- and post- command routines are called only on the local node. The
- purpose is primarily to get and release locks, though the pre- routine should
- also do any other local setups required by the command (if any) and can
- return a failure code that prevents the command from being distributed around
- the cluster
-
- The pre- and post- routines are run in their own thread so can block as long
- they like, do_command is run in the main clvmd thread so should not block for
- too long. If the pre-command returns an error code (!=0) then the command
- will not be propogated around the cluster but the post-command WILL be called
-
- Also note that the pre and post routine are *always* called on the local
- node, even if the command to be executed was only requested to run on a
- remote node. It may peek inside the client structure to check the status of
- the command.
-
- The clients of the daemon must, naturally, understand the return messages and
- codes.
-
- Routines in here may only READ the values in the client structure passed in
- apart from client->private which they are free to do what they like with.
-
-*/
-
-#include "clvmd-common.h"
-#include "clvmd-comms.h"
-#include "daemons/clvmd/clvm.h"
-#include "clvmd.h"
-#include "lib/misc/lvm-globals.h"
-#include "lvm-functions.h"
-
-#include "lib/locking/locking.h"
-
-#include <sys/utsname.h>
-
-extern struct cluster_ops *clops;
-static int restart_clvmd(void);
-
-/* This is where all the real work happens:
- NOTE: client will be NULL when this is executed on a remote node */
-int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
- char **buf, int buflen, int *retlen)
-{
- char *args = msg->node + strlen(msg->node) + 1;
- int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
- int status = 0;
- char *lockname;
- const char *locktype;
- struct utsname nodeinfo;
- unsigned char lock_cmd;
- unsigned char lock_flags;
-
- /* Do the command */
- switch (msg->cmd) {
- /* Just a test message */
- case CLVMD_CMD_TEST:
- if (arglen > buflen) {
- char *new_buf;
- buflen = arglen + 200;
- new_buf = realloc(*buf, buflen);
- if (new_buf == NULL) {
- status = errno;
- free (*buf);
- }
- *buf = new_buf;
- }
- if (*buf) {
- if (uname(&nodeinfo))
- memset(&nodeinfo, 0, sizeof(nodeinfo));
-
- *retlen = 1 + dm_snprintf(*buf, buflen,
- "TEST from %s: %s v%s",
- nodeinfo.nodename, args,
- nodeinfo.release);
- }
- break;
-
- case CLVMD_CMD_LOCK_VG:
- lock_cmd = args[0];
- lock_flags = args[1];
- lockname = &args[2];
- /* Check to see if the VG is in use by LVM1 */
- do_lock_vg(lock_cmd, lock_flags, lockname);
- break;
-
- case CLVMD_CMD_LOCK_LV:
- /* This is the biggie */
- lock_cmd = args[0];
- lock_flags = args[1];
- lockname = &args[2];
- status = do_lock_lv(lock_cmd, lock_flags, lockname);
- /* Replace EIO with something less scary */
- if (status == EIO) {
- *retlen = 1 + dm_snprintf(*buf, buflen, "%s",
- get_last_lvm_error());
- return EIO;
- }
- break;
-
- case CLVMD_CMD_LOCK_QUERY:
- lockname = &args[2];
- if (buflen < 3)
- return EIO;
- if ((locktype = do_lock_query(lockname)))
- *retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype);
- break;
-
- case CLVMD_CMD_REFRESH:
- do_refresh_cache();
- break;
-
- case CLVMD_CMD_SYNC_NAMES:
- lvm_do_fs_unlock();
- break;
-
- case CLVMD_CMD_SET_DEBUG:
- clvmd_set_debug((debug_t) args[0]);
- break;
-
- case CLVMD_CMD_RESTART:
- status = restart_clvmd();
- break;
-
- case CLVMD_CMD_GET_CLUSTERNAME:
- status = clops->get_cluster_name(*buf, buflen);
- if (!status)
- *retlen = strlen(*buf)+1;
- break;
-
- case CLVMD_CMD_VG_BACKUP:
- /*
- * Do not run backup on local node, caller should do that.
- */
- if (!client)
- lvm_do_backup(&args[2]);
- break;
-
- default:
- /* Won't get here because command is validated in pre_command */
- break;
- }
-
- /* Check the status of the command and return the error text */
- if (status) {
- if (*buf)
- *retlen = dm_snprintf(*buf, buflen, "%s", strerror(status)) + 1;
- else
- *retlen = 0;
- }
-
- return status;
-}
-
-static int lock_vg(struct local_client *client)
-{
- struct dm_hash_table *lock_hash;
- struct clvm_header *header =
- (struct clvm_header *) client->bits.localsock.cmd;
- unsigned char lock_cmd;
- int lock_mode;
- char *args = header->node + strlen(header->node) + 1;
- int lkid;
- int status;
- char *lockname;
-
- /*
- * Keep a track of VG locks in our own hash table. In current
- * practice there should only ever be more than two VGs locked
- * if a user tries to merge lots of them at once
- */
- if (!client->bits.localsock.private) {
- if (!(lock_hash = dm_hash_create(3)))
- return ENOMEM;
- client->bits.localsock.private = (void *) lock_hash;
- } else
- lock_hash = (struct dm_hash_table *) client->bits.localsock.private;
-
- lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
- lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
- /* lock_flags = args[1]; */
- lockname = &args[2];
- DEBUGLOG("(%p) doing PRE command LOCK_VG '%s' at %x\n", client, lockname, lock_cmd);
-
- if (lock_mode == LCK_UNLOCK) {
- if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
- return EINVAL;
-
- if ((status = sync_unlock(lockname, lkid)))
- status = errno;
- else
- dm_hash_remove(lock_hash, lockname);
- } else {
- /* Read locks need to be PR; other modes get passed through */
- if (lock_mode == LCK_READ)
- lock_mode = LCK_PREAD;
-
- if ((status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid)))
- status = errno;
- else if (!dm_hash_insert(lock_hash, lockname, (void *) (long) lkid))
- return ENOMEM;
- }
-
- return status;
-}
-
-
-/* Pre-command is a good place to get locks that are needed only for the duration
- of the commands around the cluster (don't forget to free them in post-command),
- and to sanity check the command arguments */
-int do_pre_command(struct local_client *client)
-{
- struct clvm_header *header =
- (struct clvm_header *) client->bits.localsock.cmd;
- unsigned char lock_cmd;
- unsigned char lock_flags;
- char *args = header->node + strlen(header->node) + 1;
- int lockid = 0;
- int status = 0;
- char *lockname;
-
- switch (header->cmd) {
- case CLVMD_CMD_TEST:
- status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
- client->bits.localsock.private = (void *)(long)lockid;
- break;
-
- case CLVMD_CMD_LOCK_VG:
- lockname = &args[2];
- /* We take out a real lock unless LCK_CACHE was set */
- if (!strncmp(lockname, "V_", 2) ||
- !strncmp(lockname, "P_#", 3))
- status = lock_vg(client);
- break;
-
- case CLVMD_CMD_LOCK_LV:
- lock_cmd = args[0];
- lock_flags = args[1];
- lockname = &args[2];
- status = pre_lock_lv(lock_cmd, lock_flags, lockname);
- break;
-
- case CLVMD_CMD_REFRESH:
- case CLVMD_CMD_GET_CLUSTERNAME:
- case CLVMD_CMD_SET_DEBUG:
- case CLVMD_CMD_VG_BACKUP:
- case CLVMD_CMD_SYNC_NAMES:
- case CLVMD_CMD_LOCK_QUERY:
- case CLVMD_CMD_RESTART:
- break;
-
- default:
- log_error("Unknown command %d received\n", header->cmd);
- status = EINVAL;
- }
- return status;
-}
-
-/* Note that the post-command routine is called even if the pre-command or the real command
- failed */
-int do_post_command(struct local_client *client)
-{
- struct clvm_header *header =
- (struct clvm_header *) client->bits.localsock.cmd;
- int status = 0;
- unsigned char lock_cmd;
- unsigned char lock_flags;
- char *args = header->node + strlen(header->node) + 1;
- char *lockname;
-
- switch (header->cmd) {
- case CLVMD_CMD_TEST:
- status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
- client->bits.localsock.private = NULL;
- break;
-
- case CLVMD_CMD_LOCK_LV:
- lock_cmd = args[0];
- lock_flags = args[1];
- lockname = &args[2];
- status = post_lock_lv(lock_cmd, lock_flags, lockname);
- break;
-
- default:
- /* Nothing to do here */
- break;
- }
- return status;
-}
-
-
-/* Called when the client is about to be deleted */
-void cmd_client_cleanup(struct local_client *client)
-{
- struct dm_hash_node *v;
- struct dm_hash_table *lock_hash;
- int lkid;
- char *lockname;
-
- DEBUGLOG("(%p) Client thread cleanup\n", client);
- if (!client->bits.localsock.private)
- return;
-
- lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
-
- dm_hash_iterate(v, lock_hash) {
- lkid = (int)(long)dm_hash_get_data(lock_hash, v);
- lockname = dm_hash_get_key(lock_hash, v);
- DEBUGLOG("(%p) Cleanup: Unlocking lock %s %x\n", client, lockname, lkid);
- (void) sync_unlock(lockname, lkid);
- }
-
- dm_hash_destroy(lock_hash);
- client->bits.localsock.private = NULL;
-}
-
-static int restart_clvmd(void)
-{
- const char **argv;
- char *lv_name;
- int argc = 0, max_locks = 0;
- struct dm_hash_node *hn = NULL;
- char debug_arg[16];
- const char *clvmd = getenv("LVM_CLVMD_BINARY") ? : CLVMD_PATH;
-
- DEBUGLOG("clvmd restart requested\n");
-
- /* Count exclusively-open LVs */
- do {
- hn = get_next_excl_lock(hn, &lv_name);
- if (lv_name) {
- max_locks++;
- if (!*lv_name)
- break; /* FIXME: Is this error ? */
- }
- } while (hn);
-
- /* clvmd + locks (-E uuid) + debug (-d X) + NULL */
- if (!(argv = malloc((max_locks * 2 + 6) * sizeof(*argv))))
- goto_out;
-
- /*
- * Build the command-line
- */
- argv[argc++] = "clvmd";
-
- /* Propagate debug options */
- if (clvmd_get_debug()) {
- if (dm_snprintf(debug_arg, sizeof(debug_arg), "-d%u", clvmd_get_debug()) < 0)
- goto_out;
- argv[argc++] = debug_arg;
- }
-
- /* Propagate foreground options */
- if (clvmd_get_foreground())
- argv[argc++] = "-f";
-
- argv[argc++] = "-I";
- argv[argc++] = clops->name;
-
- /* Now add the exclusively-open LVs */
- hn = NULL;
- do {
- hn = get_next_excl_lock(hn, &lv_name);
- if (lv_name) {
- if (!*lv_name)
- break; /* FIXME: Is this error ? */
- argv[argc++] = "-E";
- argv[argc++] = lv_name;
- DEBUGLOG("excl lock: %s\n", lv_name);
- }
- } while (hn);
- argv[argc] = NULL;
-
- /* Exec new clvmd */
- DEBUGLOG("--- Restarting %s ---\n", clvmd);
- for (argc = 1; argv[argc]; argc++) DEBUGLOG("--- %d: %s\n", argc, argv[argc]);
-
- /* NOTE: This will fail when downgrading! */
- execvp(clvmd, (char **)argv);
-out:
- /* We failed */
- DEBUGLOG("Restart of clvmd failed.\n");
-
- free(argv);
-
- return EIO;
-}
diff --git a/daemons/clvmd/clvmd-common.h b/daemons/clvmd/clvmd-common.h
deleted file mode 100644
index fb1c4879b..000000000
--- a/daemons/clvmd/clvmd-common.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * This file must be included first by every clvmd source file.
- */
-#ifndef _LVM_CLVMD_COMMON_H
-#define _LVM_CLVMD_COMMON_H
-
-#define _REENTRANT
-
-#include "tools/tool.h"
-
-#include "lib/log/lvm-logging.h"
-
-#endif
diff --git a/daemons/clvmd/clvmd-comms.h b/daemons/clvmd/clvmd-comms.h
deleted file mode 100644
index f94077ceb..000000000
--- a/daemons/clvmd/clvmd-comms.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Abstraction layer for clvmd cluster communications
- */
-
-#ifndef _CLVMD_COMMS_H
-#define _CLVMD_COMMS_H
-
-struct local_client;
-
-struct cluster_ops {
- const char *name;
- void (*cluster_init_completed) (void);
-
- int (*cluster_send_message) (const void *buf, int msglen,
- const char *csid,
- const char *errtext);
- int (*name_from_csid) (const char *csid, char *name);
- int (*csid_from_name) (char *csid, const char *name);
- int (*get_num_nodes) (void);
- int (*cluster_fd_callback) (struct local_client *fd, char *buf, int len,
- const char *csid,
- struct local_client **new_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 *,
- const char *csid,
- int node_up));
- int (*is_quorate) (void);
-
- void (*get_our_csid) (char *csid);
- void (*add_up_node) (const char *csid);
- void (*reread_config) (void);
- void (*cluster_closedown) (void);
-
- int (*get_cluster_name)(char *buf, int buflen);
-
- int (*sync_lock) (const char *resource, int mode,
- int flags, int *lockid);
- int (*sync_unlock) (const char *resource, int lockid);
-
-};
-
-#ifdef USE_CMAN
-# include <netinet/in.h>
-# include "libcman.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_NODENAME_LEN
-# define CMAN_MAX_CLUSTER_MESSAGE 1500
-# define CLUSTER_PORT_CLVMD 11
-struct cluster_ops *init_cman_cluster(void);
-#endif
-
-#ifdef USE_OPENAIS
-# include <openais/saAis.h>
-# include <corosync/totem/totem.h>
-# define OPENAIS_CSID_LEN (sizeof(int))
-# define OPENAIS_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
-# define OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
-# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
-# define MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
-# endif
-# ifndef CMAN_MAX_CLUSTER_MESSAGE
-# define CMAN_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
-# endif
-# ifndef MAX_CSID_LEN
-# define MAX_CSID_LEN sizeof(int)
-# endif
-struct cluster_ops *init_openais_cluster(void);
-#endif
-
-#ifdef USE_COROSYNC
-# include <corosync/corotypes.h>
-# define COROSYNC_CSID_LEN (sizeof(int))
-# define COROSYNC_MAX_CLUSTER_MESSAGE 65535
-# define COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
-# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
-# define MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
-# endif
-# ifndef CMAN_MAX_CLUSTER_MESSAGE
-# define CMAN_MAX_CLUSTER_MESSAGE 65535
-# endif
-# ifndef MAX_CSID_LEN
-# define MAX_CSID_LEN sizeof(int)
-# endif
-struct cluster_ops *init_corosync_cluster(void);
-#endif
-
-#ifdef USE_SINGLENODE
-# define SINGLENODE_CSID_LEN (sizeof(int))
-# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
-# define MAX_CLUSTER_MEMBER_NAME_LEN 64
-# endif
-# define SINGLENODE_MAX_CLUSTER_MESSAGE 65535
-# ifndef MAX_CSID_LEN
-# define MAX_CSID_LEN sizeof(int)
-# endif
-struct cluster_ops *init_singlenode_cluster(void);
-#endif
-
-#endif
diff --git a/daemons/clvmd/clvmd-corosync.c b/daemons/clvmd/clvmd-corosync.c
deleted file mode 100644
index 6a9705d36..000000000
--- a/daemons/clvmd/clvmd-corosync.c
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (C) 2009-2012 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * This provides the interface between clvmd and corosync/DLM as the cluster
- * and lock manager.
- */
-
-#include "clvmd-common.h"
-
-#include <pthread.h>
-
-#include "daemons/clvmd/clvm.h"
-#include "clvmd-comms.h"
-#include "clvmd.h"
-#include "lvm-functions.h"
-
-#include "lib/locking/locking.h"
-
-#include <corosync/cpg.h>
-#include <corosync/quorum.h>
-
-#ifdef HAVE_COROSYNC_CONFDB_H
-# include <corosync/confdb.h>
-#elif defined HAVE_COROSYNC_CMAP_H
-# include <corosync/cmap.h>
-#else
-# error "Either HAVE_COROSYNC_CONFDB_H or HAVE_COROSYNC_CMAP_H must be defined."
-#endif
-
-#include <libdlm.h>
-
-#include <syslog.h>
-
-/* Timeout value for several corosync calls */
-#define LOCKSPACE_NAME "clvmd"
-
-static void corosync_cpg_deliver_callback (cpg_handle_t handle,
- const struct cpg_name *groupName,
- uint32_t nodeid,
- uint32_t pid,
- void *msg,
- size_t msg_len);
-static void corosync_cpg_confchg_callback(cpg_handle_t handle,
- const struct cpg_name *groupName,
- const struct cpg_address *member_list, size_t member_list_entries,
- const struct cpg_address *left_list, size_t left_list_entries,
- const struct cpg_address *joined_list, size_t joined_list_entries);
-static void _cluster_closedown(void);
-
-/* Hash list of nodes in the cluster */
-static struct dm_hash_table *node_hash;
-
-/* Number of active nodes */
-static int num_nodes;
-static unsigned int our_nodeid;
-
-static struct local_client *cluster_client;
-
-/* Corosync handles */
-static cpg_handle_t cpg_handle;
-static quorum_handle_t quorum_handle;
-
-/* DLM Handle */
-static dlm_lshandle_t *lockspace;
-
-static struct cpg_name cpg_group_name;
-
-/* Corosync callback structs */
-cpg_callbacks_t corosync_cpg_callbacks = {
- .cpg_deliver_fn = corosync_cpg_deliver_callback,
- .cpg_confchg_fn = corosync_cpg_confchg_callback,
-};
-
-quorum_callbacks_t quorum_callbacks = {
- .quorum_notify_fn = NULL,
-};
-
-struct node_info
-{
- enum {NODE_DOWN, NODE_CLVMD} state;
- int nodeid;
-};
-
-
-/* Set errno to something approximating the right value and return 0 or -1 */
-static int cs_to_errno(cs_error_t err)
-{
- switch(err)
- {
- case CS_OK:
- return 0;
- case CS_ERR_LIBRARY:
- errno = EINVAL;
- break;
- case CS_ERR_VERSION:
- errno = EINVAL;
- break;
- case CS_ERR_INIT:
- errno = EINVAL;
- break;
- case CS_ERR_TIMEOUT:
- errno = ETIME;
- break;
- case CS_ERR_TRY_AGAIN:
- errno = EAGAIN;
- break;
- case CS_ERR_INVALID_PARAM:
- errno = EINVAL;
- break;
- case CS_ERR_NO_MEMORY:
- errno = ENOMEM;
- break;
- case CS_ERR_BAD_HANDLE:
- errno = EINVAL;
- break;
- case CS_ERR_BUSY:
- errno = EBUSY;
- break;
- case CS_ERR_ACCESS:
- errno = EPERM;
- break;
- case CS_ERR_NOT_EXIST:
- errno = ENOENT;
- break;
- case CS_ERR_NAME_TOO_LONG:
- errno = ENAMETOOLONG;
- break;
- case CS_ERR_EXIST:
- errno = EEXIST;
- break;
- case CS_ERR_NO_SPACE:
- errno = ENOSPC;
- break;
- case CS_ERR_INTERRUPT:
- errno = EINTR;
- break;
- case CS_ERR_NAME_NOT_FOUND:
- errno = ENOENT;
- break;
- case CS_ERR_NO_RESOURCES:
- errno = ENOMEM;
- break;
- case CS_ERR_NOT_SUPPORTED:
- errno = EOPNOTSUPP;
- break;
- case CS_ERR_BAD_OPERATION:
- errno = EINVAL;
- break;
- case CS_ERR_FAILED_OPERATION:
- errno = EIO;
- break;
- case CS_ERR_MESSAGE_ERROR:
- errno = EIO;
- break;
- case CS_ERR_QUEUE_FULL:
- errno = EXFULL;
- break;
- case CS_ERR_QUEUE_NOT_AVAILABLE:
- errno = EINVAL;
- break;
- case CS_ERR_BAD_FLAGS:
- errno = EINVAL;
- break;
- case CS_ERR_TOO_BIG:
- errno = E2BIG;
- break;
- case CS_ERR_NO_SECTIONS:
- errno = ENOMEM;
- break;
- default:
- errno = EINVAL;
- break;
- }
- return -1;
-}
-
-static char *print_corosync_csid(const char *csid)
-{
- static char buf[128];
- int id;
-
- memcpy(&id, csid, sizeof(int));
- sprintf(buf, "%d", id);
- return buf;
-}
-
-static void corosync_cpg_deliver_callback (cpg_handle_t handle,
- const struct cpg_name *groupName,
- uint32_t nodeid,
- uint32_t pid,
- void *msg,
- size_t msg_len)
-{
- int target_nodeid;
-
- memcpy(&target_nodeid, msg, COROSYNC_CSID_LEN);
-
- DEBUGLOG("%u got message from nodeid %d for %d. len %zd\n",
- our_nodeid, nodeid, target_nodeid, msg_len-4);
-
- if (nodeid != our_nodeid)
- if (target_nodeid == our_nodeid || target_nodeid == 0)
- process_message(cluster_client, (char *)msg+COROSYNC_CSID_LEN,
- msg_len-COROSYNC_CSID_LEN, (char*)&nodeid);
-}
-
-static void corosync_cpg_confchg_callback(cpg_handle_t handle,
- const struct cpg_name *groupName,
- const struct cpg_address *member_list, size_t member_list_entries,
- const struct cpg_address *left_list, size_t left_list_entries,
- const struct cpg_address *joined_list, size_t joined_list_entries)
-{
- int i;
- struct node_info *ninfo;
-
- DEBUGLOG("confchg callback. %zd joined, %zd left, %zd members\n",
- joined_list_entries, left_list_entries, member_list_entries);
-
- for (i=0; i<joined_list_entries; i++) {
- ninfo = dm_hash_lookup_binary(node_hash,
- (char *)&joined_list[i].nodeid,
- COROSYNC_CSID_LEN);
- if (!ninfo) {
- ninfo = malloc(sizeof(struct node_info));
- if (!ninfo) {
- break;
- }
- else {
- ninfo->nodeid = joined_list[i].nodeid;
- dm_hash_insert_binary(node_hash,
- (char *)&ninfo->nodeid,
- COROSYNC_CSID_LEN, ninfo);
- }
- }
- ninfo->state = NODE_CLVMD;
- }
-
- for (i=0; i<left_list_entries; i++) {
- ninfo = dm_hash_lookup_binary(node_hash,
- (char *)&left_list[i].nodeid,
- COROSYNC_CSID_LEN);
- if (ninfo)
- ninfo->state = NODE_DOWN;
- }
-
- num_nodes = member_list_entries;
-}
-
-static int _init_cluster(void)
-{
- cs_error_t err;
-
-#ifdef QUORUM_SET /* corosync/quorum.h */
- uint32_t quorum_type;
-#endif
-
- node_hash = dm_hash_create(100);
-
- err = cpg_initialize(&cpg_handle,
- &corosync_cpg_callbacks);
- if (err != CS_OK) {
- syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d",
- err);
- DEBUGLOG("Cannot initialise Corosync CPG service: %d", err);
- return cs_to_errno(err);
- }
-
-#ifdef QUORUM_SET
- err = quorum_initialize(&quorum_handle,
- &quorum_callbacks,
- &quorum_type);
-
- if (quorum_type != QUORUM_SET) {
- syslog(LOG_ERR, "Corosync quorum service is not configured");
- DEBUGLOG("Corosync quorum service is not configured");
- return EINVAL;
- }
-#else
- err = quorum_initialize(&quorum_handle,
- &quorum_callbacks);
-#endif
-
- if (err != CS_OK) {
- syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d",
- err);
- DEBUGLOG("Cannot initialise Corosync quorum service: %d", err);
- return cs_to_errno(err);
- }
-
- /* Create a lockspace for LV & VG locks to live in */
- lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
- if (!lockspace) {
- lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
- if (!lockspace) {
- syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
- return -1;
- }
- DEBUGLOG("Created DLM lockspace for CLVMD.\n");
- } else
- DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
-
- dlm_ls_pthread_init(lockspace);
- DEBUGLOG("DLM initialisation complete\n");
-
- /* Connect to the clvmd group */
- strcpy((char *)cpg_group_name.value, "clvmd");
- cpg_group_name.length = strlen((char *)cpg_group_name.value);
- err = cpg_join(cpg_handle, &cpg_group_name);
- if (err != CS_OK) {
- cpg_finalize(cpg_handle);
- quorum_finalize(quorum_handle);
- dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
- syslog(LOG_ERR, "Cannot join clvmd process group");
- DEBUGLOG("Cannot join clvmd process group: %d\n", err);
- return cs_to_errno(err);
- }
-
- err = cpg_local_get(cpg_handle,
- &our_nodeid);
- if (err != CS_OK) {
- cpg_finalize(cpg_handle);
- quorum_finalize(quorum_handle);
- dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
- syslog(LOG_ERR, "Cannot get local node id\n");
- return cs_to_errno(err);
- }
- DEBUGLOG("Our local node id is %d\n", our_nodeid);
-
- DEBUGLOG("Connected to Corosync\n");
-
- return 0;
-}
-
-static void _cluster_closedown(void)
-{
- dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
- cpg_finalize(cpg_handle);
- quorum_finalize(quorum_handle);
-}
-
-static void _get_our_csid(char *csid)
-{
- memcpy(csid, &our_nodeid, sizeof(int));
-}
-
-/* Corosync doesn't really have nmode names so we
- just use the node ID in hex instead */
-static int _csid_from_name(char *csid, const char *name)
-{
- int nodeid;
- struct node_info *ninfo;
-
- if (sscanf(name, "%x", &nodeid) == 1) {
- ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
- if (ninfo)
- return nodeid;
- }
- return -1;
-}
-
-static int _name_from_csid(const char *csid, char *name)
-{
- struct node_info *ninfo;
-
- ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
- if (!ninfo)
- {
- sprintf(name, "UNKNOWN %s", print_corosync_csid(csid));
- return -1;
- }
-
- sprintf(name, "%x", ninfo->nodeid);
- return 0;
-}
-
-static int _get_num_nodes(void)
-{
- DEBUGLOG("num_nodes = %d\n", num_nodes);
- return num_nodes;
-}
-
-/* Node is now known to be running a clvmd */
-static void _add_up_node(const char *csid)
-{
- struct node_info *ninfo;
-
- ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
- if (!ninfo) {
- DEBUGLOG("corosync_add_up_node no node_hash entry for csid %s\n",
- print_corosync_csid(csid));
- return;
- }
-
- DEBUGLOG("corosync_add_up_node %d\n", ninfo->nodeid);
-
- ninfo->state = NODE_CLVMD;
-
- return;
-}
-
-/* Call a callback for each node, so the caller knows whether it's up or down */
-static int _cluster_do_node_callback(struct local_client *master_client,
- void (*callback)(struct local_client *,
- const char *csid, int node_up))
-{
- struct dm_hash_node *hn;
- struct node_info *ninfo;
-
- dm_hash_iterate(hn, node_hash)
- {
- char csid[COROSYNC_CSID_LEN];
-
- ninfo = dm_hash_get_data(node_hash, hn);
- memcpy(csid, dm_hash_get_key(node_hash, hn), COROSYNC_CSID_LEN);
-
- DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
- ninfo->state);
-
- if (ninfo->state == NODE_CLVMD)
- callback(master_client, csid, 1);
- }
- return 0;
-}
-
-/* Real locking */
-static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
-{
- struct dlm_lksb lksb;
- int err;
-
- DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
-
- if (flags & LKF_CONVERT)
- lksb.sb_lkid = *lockid;
-
- err = dlm_ls_lock_wait(lockspace,
- mode,
- &lksb,
- flags,
- resource,
- strlen(resource),
- 0,
- NULL, NULL, NULL);
-
- if (err != 0)
- {
- DEBUGLOG("dlm_ls_lock returned %d\n", errno);
- return err;
- }
- if (lksb.sb_status != 0)
- {
- DEBUGLOG("dlm_ls_lock returns lksb.sb_status %d\n", lksb.sb_status);
- errno = lksb.sb_status;
- return -1;
- }
-
- DEBUGLOG("lock_resource returning %d, lock_id=%x\n", err, lksb.sb_lkid);
-
- *lockid = lksb.sb_lkid;
-
- return 0;
-}
-
-
-static int _unlock_resource(const char *resource, int lockid)
-{
- struct dlm_lksb lksb;
- int err;
-
- DEBUGLOG("unlock_resource: %s lockid: %x\n", resource, lockid);
- lksb.sb_lkid = lockid;
-
- err = dlm_ls_unlock_wait(lockspace,
- lockid,
- 0,
- &lksb);
- if (err != 0)
- {
- DEBUGLOG("Unlock returned %d\n", err);
- return err;
- }
- if (lksb.sb_status != EUNLOCK)
- {
- DEBUGLOG("dlm_ls_unlock_wait returns lksb.sb_status: %d\n", lksb.sb_status);
- errno = lksb.sb_status;
- return -1;
- }
-
-
- return 0;
-}
-
-static int _is_quorate(void)
-{
- int quorate;
- if (quorum_getquorate(quorum_handle, &quorate) == CS_OK)
- return quorate;
- else
- return 0;
-}
-
-static int _get_main_cluster_fd(void)
-{
- int select_fd;
-
- cpg_fd_get(cpg_handle, &select_fd);
- return select_fd;
-}
-
-static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
- const char *csid,
- struct local_client **new_client)
-{
- cluster_client = fd;
- *new_client = NULL;
- cpg_dispatch(cpg_handle, CS_DISPATCH_ONE);
- return 1;
-}
-
-static int _cluster_send_message(const void *buf, int msglen, const char *csid,
- const char *errtext)
-{
- static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
- struct iovec iov[2];
- cs_error_t err;
- int target_node;
-
- if (csid)
- memcpy(&target_node, csid, COROSYNC_CSID_LEN);
- else
- target_node = 0;
-
- iov[0].iov_base = &target_node;
- iov[0].iov_len = sizeof(int);
- iov[1].iov_base = (char *)buf;
- iov[1].iov_len = msglen;
-
- pthread_mutex_lock(&_mutex);
- err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
- pthread_mutex_unlock(&_mutex);
-
- return cs_to_errno(err);
-}
-
-#ifdef HAVE_COROSYNC_CONFDB_H
-/*
- * We are not necessarily connected to a Red Hat Cluster system,
- * but if we are, this returns the cluster name from cluster.conf.
- * I've used confdb rather than ccs to reduce the inter-package
- * dependancies as well as to allow people to set a cluster name
- * for themselves even if they are not running on RH cluster.
- */
-static int _get_cluster_name(char *buf, int buflen)
-{
- confdb_handle_t handle;
- int result;
- size_t namelen = buflen;
- hdb_handle_t cluster_handle;
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
- /* This is a default in case everything else fails */
- strncpy(buf, "Corosync", buflen);
-
- /* Look for a cluster name in confdb */
- result = confdb_initialize (&handle, &callbacks);
- if (result != CS_OK)
- return 0;
-
- result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
- if (result != CS_OK)
- goto out;
-
- result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
- if (result != CS_OK)
- goto out;
-
- result = confdb_key_get(handle, cluster_handle, (void *)"name", strlen("name"), buf, &namelen);
- if (result != CS_OK)
- goto out;
-
- buf[namelen] = '\0';
-
-out:
- confdb_finalize(handle);
- return 0;
-}
-
-#elif defined HAVE_COROSYNC_CMAP_H
-
-static int _get_cluster_name(char *buf, int buflen)
-{
- cmap_handle_t cmap_handle = 0;
- int result;
- char *name = NULL;
-
- /* This is a default in case everything else fails */
- strncpy(buf, "Corosync", buflen);
-
- /* Look for a cluster name in cmap */
- result = cmap_initialize(&cmap_handle);
- if (result != CS_OK)
- return 0;
-
- result = cmap_get_string(cmap_handle, "totem.cluster_name", &name);
- if (result != CS_OK)
- goto out;
-
- memset(buf, 0, buflen);
- strncpy(buf, name, buflen - 1);
-
-out:
- if (name)
- free(name);
- cmap_finalize(cmap_handle);
- return 0;
-}
-
-#endif
-
-static struct cluster_ops _cluster_corosync_ops = {
- .name = "corosync",
- .cluster_init_completed = NULL,
- .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,
- .reread_config = NULL,
- .cluster_closedown = _cluster_closedown,
- .get_cluster_name = _get_cluster_name,
- .sync_lock = _lock_resource,
- .sync_unlock = _unlock_resource,
-};
-
-struct cluster_ops *init_corosync_cluster(void)
-{
- if (!_init_cluster())
- return &_cluster_corosync_ops;
- else
- return NULL;
-}
diff --git a/daemons/clvmd/clvmd-openais.c b/daemons/clvmd/clvmd-openais.c
deleted file mode 100644
index 6b4fb10f6..000000000
--- a/daemons/clvmd/clvmd-openais.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Copyright (C) 2007-2009 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * This provides the interface between clvmd and OpenAIS as the cluster
- * and lock manager.
- */
-
-#include "clvmd-common.h"
-
-#include <pthread.h>
-#include <fcntl.h>
-#include <syslog.h>
-
-#include <openais/saAis.h>
-#include <openais/saLck.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/cpg.h>
-
-#include "lib/locking/locking.h"
-#include "daemons/clvmd/clvm.h"
-#include "clvmd-comms.h"
-#include "lvm-functions.h"
-#include "clvmd.h"
-
-/* Timeout value for several openais calls */
-#define TIMEOUT 10
-
-static void openais_cpg_deliver_callback (cpg_handle_t handle,
- const struct cpg_name *groupName,
- uint32_t nodeid,
- uint32_t pid,
- void *msg,
- size_t msg_len);
-static void openais_cpg_confchg_callback(cpg_handle_t handle,
- const struct cpg_name *groupName,
- const struct cpg_address *member_list, size_t member_list_entries,
- const struct cpg_address *left_list, size_t left_list_entries,
- const struct cpg_address *joined_list, size_t joined_list_entries);
-
-static void _cluster_closedown(void);
-
-/* Hash list of nodes in the cluster */
-static struct dm_hash_table *node_hash;
-
-/* For associating lock IDs & resource handles */
-static struct dm_hash_table *lock_hash;
-
-/* Number of active nodes */
-static int num_nodes;
-static unsigned int our_nodeid;
-
-static struct local_client *cluster_client;
-
-/* OpenAIS handles */
-static cpg_handle_t cpg_handle;
-static SaLckHandleT lck_handle;
-
-static struct cpg_name cpg_group_name;
-
-/* Openais callback structs */
-cpg_callbacks_t openais_cpg_callbacks = {
- .cpg_deliver_fn = openais_cpg_deliver_callback,
- .cpg_confchg_fn = openais_cpg_confchg_callback,
-};
-
-struct node_info
-{
- enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
- int nodeid;
-};
-
-struct lock_info
-{
- SaLckResourceHandleT res_handle;
- SaLckLockIdT lock_id;
- SaNameT lock_name;
-};
-
-/* Set errno to something approximating the right value and return 0 or -1 */
-static int ais_to_errno(SaAisErrorT err)
-{
- switch(err)
- {
- case SA_AIS_OK:
- return 0;
- case SA_AIS_ERR_LIBRARY:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_VERSION:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_INIT:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_TIMEOUT:
- errno = ETIME;
- break;
- case SA_AIS_ERR_TRY_AGAIN:
- errno = EAGAIN;
- break;
- case SA_AIS_ERR_INVALID_PARAM:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_NO_MEMORY:
- errno = ENOMEM;
- break;
- case SA_AIS_ERR_BAD_HANDLE:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_BUSY:
- errno = EBUSY;
- break;
- case SA_AIS_ERR_ACCESS:
- errno = EPERM;
- break;
- case SA_AIS_ERR_NOT_EXIST:
- errno = ENOENT;
- break;
- case SA_AIS_ERR_NAME_TOO_LONG:
- errno = ENAMETOOLONG;
- break;
- case SA_AIS_ERR_EXIST:
- errno = EEXIST;
- break;
- case SA_AIS_ERR_NO_SPACE:
- errno = ENOSPC;
- break;
- case SA_AIS_ERR_INTERRUPT:
- errno = EINTR;
- break;
- case SA_AIS_ERR_NAME_NOT_FOUND:
- errno = ENOENT;
- break;
- case SA_AIS_ERR_NO_RESOURCES:
- errno = ENOMEM;
- break;
- case SA_AIS_ERR_NOT_SUPPORTED:
- errno = EOPNOTSUPP;
- break;
- case SA_AIS_ERR_BAD_OPERATION:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_FAILED_OPERATION:
- errno = EIO;
- break;
- case SA_AIS_ERR_MESSAGE_ERROR:
- errno = EIO;
- break;
- case SA_AIS_ERR_QUEUE_FULL:
- errno = EXFULL;
- break;
- case SA_AIS_ERR_QUEUE_NOT_AVAILABLE:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_BAD_FLAGS:
- errno = EINVAL;
- break;
- case SA_AIS_ERR_TOO_BIG:
- errno = E2BIG;
- break;
- case SA_AIS_ERR_NO_SECTIONS:
- errno = ENOMEM;
- break;
- default:
- errno = EINVAL;
- break;
- }
- return -1;
-}
-
-static char *print_openais_csid(const char *csid)
-{
- static char buf[128];
- int id;
-
- memcpy(&id, csid, sizeof(int));
- sprintf(buf, "%d", id);
- return buf;
-}
-
-static int add_internal_client(int fd, fd_callback_t callback)
-{
- struct local_client *client;
-
- DEBUGLOG("Add_internal_client, fd = %d\n", fd);
-
- if (!(client = dm_zalloc(sizeof(*client)))) {
- DEBUGLOG("malloc failed\n");
- return -1;
- }
-
- client->fd = fd;
- client->type = CLUSTER_INTERNAL;
- client->callback = callback;
- add_client(client);
-
- /* Set Close-on-exec */
- fcntl(fd, F_SETFD, 1);
-
- return 0;
-}
-
-static void openais_cpg_deliver_callback (cpg_handle_t handle,
- const struct cpg_name *groupName,
- uint32_t nodeid,
- uint32_t pid,
- void *msg,
- size_t msg_len)
-{
- int target_nodeid;
-
- memcpy(&target_nodeid, msg, OPENAIS_CSID_LEN);
-
- DEBUGLOG("%u got message from nodeid %d for %d. len %" PRIsize_t "\n",
- our_nodeid, nodeid, target_nodeid, msg_len-4);
-
- if (nodeid != our_nodeid)
- if (target_nodeid == our_nodeid || target_nodeid == 0)
- process_message(cluster_client, (char *)msg+OPENAIS_CSID_LEN,
- msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
-}
-
-static void openais_cpg_confchg_callback(cpg_handle_t handle,
- const struct cpg_name *groupName,
- const struct cpg_address *member_list, size_t member_list_entries,
- const struct cpg_address *left_list, size_t left_list_entries,
- const struct cpg_address *joined_list, size_t joined_list_entries)
-{
- int i;
- struct node_info *ninfo;
-
- DEBUGLOG("confchg callback. %" PRIsize_t " joined, "
- FMTsize_t " left, %" PRIsize_t " members\n",
- joined_list_entries, left_list_entries, member_list_entries);
-
- for (i=0; i<joined_list_entries; i++) {
- ninfo = dm_hash_lookup_binary(node_hash,
- (char *)&joined_list[i].nodeid,
- OPENAIS_CSID_LEN);
- if (!ninfo) {
- ninfo = malloc(sizeof(struct node_info));
- if (!ninfo) {
- break;
- }
- else {
- ninfo->nodeid = joined_list[i].nodeid;
- dm_hash_insert_binary(node_hash,
- (char *)&ninfo->nodeid,
- OPENAIS_CSID_LEN, ninfo);
- }
- }
- ninfo->state = NODE_CLVMD;
- }
-
- for (i=0; i<left_list_entries; i++) {
- ninfo = dm_hash_lookup_binary(node_hash,
- (char *)&left_list[i].nodeid,
- OPENAIS_CSID_LEN);
- if (ninfo)
- ninfo->state = NODE_DOWN;
- }
-
- for (i=0; i<member_list_entries; i++) {
- if (member_list[i].nodeid == 0) continue;
- ninfo = dm_hash_lookup_binary(node_hash,
- (char *)&member_list[i].nodeid,
- OPENAIS_CSID_LEN);
- if (!ninfo) {
- ninfo = malloc(sizeof(struct node_info));
- if (!ninfo) {
- break;
- }
- else {
- ninfo->nodeid = member_list[i].nodeid;
- dm_hash_insert_binary(node_hash,
- (char *)&ninfo->nodeid,
- OPENAIS_CSID_LEN, ninfo);
- }
- }
- ninfo->state = NODE_CLVMD;
- }
-
- num_nodes = member_list_entries;
-}
-
-static int lck_dispatch(struct local_client *client, char *buf, int len,
- const char *csid, struct local_client **new_client)
-{
- *new_client = NULL;
- saLckDispatch(lck_handle, SA_DISPATCH_ONE);
- return 1;
-}
-
-static int _init_cluster(void)
-{
- SaAisErrorT err;
- SaVersionT ver = { 'B', 1, 1 };
- int select_fd;
-
- node_hash = dm_hash_create(100);
- lock_hash = dm_hash_create(10);
-
- err = cpg_initialize(&cpg_handle,
- &openais_cpg_callbacks);
- if (err != SA_AIS_OK) {
- syslog(LOG_ERR, "Cannot initialise OpenAIS CPG service: %d",
- err);
- DEBUGLOG("Cannot initialise OpenAIS CPG service: %d", err);
- return ais_to_errno(err);
- }
-
- err = saLckInitialize(&lck_handle,
- NULL,
- &ver);
- if (err != SA_AIS_OK) {
- cpg_initialize(&cpg_handle, &openais_cpg_callbacks);
- syslog(LOG_ERR, "Cannot initialise OpenAIS lock service: %d",
- err);
- DEBUGLOG("Cannot initialise OpenAIS lock service: %d\n\n", err);
- return ais_to_errno(err);
- }
-
- /* Connect to the clvmd group */
- strcpy((char *)cpg_group_name.value, "clvmd");
- cpg_group_name.length = strlen((char *)cpg_group_name.value);
- err = cpg_join(cpg_handle, &cpg_group_name);
- if (err != SA_AIS_OK) {
- cpg_finalize(cpg_handle);
- saLckFinalize(lck_handle);
- syslog(LOG_ERR, "Cannot join clvmd process group");
- DEBUGLOG("Cannot join clvmd process group: %d\n", err);
- return ais_to_errno(err);
- }
-
- err = cpg_local_get(cpg_handle,
- &our_nodeid);
- if (err != SA_AIS_OK) {
- cpg_finalize(cpg_handle);
- saLckFinalize(lck_handle);
- syslog(LOG_ERR, "Cannot get local node id\n");
- return ais_to_errno(err);
- }
- DEBUGLOG("Our local node id is %d\n", our_nodeid);
-
- saLckSelectionObjectGet(lck_handle, (SaSelectionObjectT *)&select_fd);
- add_internal_client(select_fd, lck_dispatch);
-
- DEBUGLOG("Connected to OpenAIS\n");
-
- return 0;
-}
-
-static void _cluster_closedown(void)
-{
- saLckFinalize(lck_handle);
- cpg_finalize(cpg_handle);
-}
-
-static void _get_our_csid(char *csid)
-{
- memcpy(csid, &our_nodeid, sizeof(int));
-}
-
-/* OpenAIS doesn't really have nmode names so we
- just use the node ID in hex instead */
-static int _csid_from_name(char *csid, const char *name)
-{
- int nodeid;
- struct node_info *ninfo;
-
- if (sscanf(name, "%x", &nodeid) == 1) {
- ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
- if (ninfo)
- return nodeid;
- }
- return -1;
-}
-
-static int _name_from_csid(const char *csid, char *name)
-{
- struct node_info *ninfo;
-
- ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
- if (!ninfo)
- {
- sprintf(name, "UNKNOWN %s", print_openais_csid(csid));
- return -1;
- }
-
- sprintf(name, "%x", ninfo->nodeid);
- return 0;
-}
-
-static int _get_num_nodes()
-{
- DEBUGLOG("num_nodes = %d\n", num_nodes);
- return num_nodes;
-}
-
-/* Node is now known to be running a clvmd */
-static void _add_up_node(const char *csid)
-{
- struct node_info *ninfo;
-
- ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
- if (!ninfo) {
- DEBUGLOG("openais_add_up_node no node_hash entry for csid %s\n",
- print_openais_csid(csid));
- return;
- }
-
- DEBUGLOG("openais_add_up_node %d\n", ninfo->nodeid);
-
- ninfo->state = NODE_CLVMD;
-}
-
-/* Call a callback for each node, so the caller knows whether it's up or down */
-static int _cluster_do_node_callback(struct local_client *master_client,
- void (*callback)(struct local_client *,
- const char *csid, int node_up))
-{
- struct dm_hash_node *hn;
- struct node_info *ninfo;
- int somedown = 0;
-
- dm_hash_iterate(hn, node_hash)
- {
- char csid[OPENAIS_CSID_LEN];
-
- ninfo = dm_hash_get_data(node_hash, hn);
- memcpy(csid, dm_hash_get_key(node_hash, hn), OPENAIS_CSID_LEN);
-
- DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
- ninfo->state);
-
- if (ninfo->state != NODE_DOWN)
- callback(master_client, csid, ninfo->state == NODE_CLVMD);
- if (ninfo->state != NODE_CLVMD)
- somedown = -1;
- }
- return somedown;
-}
-
-/* Real locking */
-static int _lock_resource(char *resource, int mode, int flags, int *lockid)
-{
- struct lock_info *linfo;
- SaLckResourceHandleT res_handle;
- SaAisErrorT err;
- SaLckLockIdT lock_id;
- SaLckLockStatusT lockStatus;
-
- /* This needs to be converted from DLM/LVM2 value for OpenAIS LCK */
- if (flags & LCK_NONBLOCK) flags = SA_LCK_LOCK_NO_QUEUE;
-
- linfo = malloc(sizeof(struct lock_info));
- if (!linfo)
- return -1;
-
- DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
-
- linfo->lock_name.length = strlen(resource)+1;
- strcpy((char *)linfo->lock_name.value, resource);
-
- err = saLckResourceOpen(lck_handle, &linfo->lock_name,
- SA_LCK_RESOURCE_CREATE, TIMEOUT, &res_handle);
- if (err != SA_AIS_OK)
- {
- DEBUGLOG("ResourceOpen returned %d\n", err);
- free(linfo);
- return ais_to_errno(err);
- }
-
- err = saLckResourceLock(
- res_handle,
- &lock_id,
- mode,
- flags,
- 0,
- SA_TIME_END,
- &lockStatus);
- if (err != SA_AIS_OK && lockStatus != SA_LCK_LOCK_GRANTED)
- {
- free(linfo);
- saLckResourceClose(res_handle);
- return ais_to_errno(err);
- }
-
- /* Wait for it to complete */
-
- DEBUGLOG("lock_resource returning %d, lock_id=%" PRIx64 "\n",
- err, lock_id);
-
- linfo->lock_id = lock_id;
- linfo->res_handle = res_handle;
-
- dm_hash_insert(lock_hash, resource, linfo);
-
- return ais_to_errno(err);
-}
-
-
-static int _unlock_resource(char *resource, int lockid)
-{
- SaAisErrorT err;
- struct lock_info *linfo;
-
- DEBUGLOG("unlock_resource %s\n", resource);
- linfo = dm_hash_lookup(lock_hash, resource);
- if (!linfo)
- return 0;
-
- DEBUGLOG("unlock_resource: lockid: %" PRIx64 "\n", linfo->lock_id);
- err = saLckResourceUnlock(linfo->lock_id, SA_TIME_END);
- if (err != SA_AIS_OK)
- {
- DEBUGLOG("Unlock returned %d\n", err);
- return ais_to_errno(err);
- }
-
- /* Release the resource */
- dm_hash_remove(lock_hash, resource);
- saLckResourceClose(linfo->res_handle);
- free(linfo);
-
- return ais_to_errno(err);
-}
-
-static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
-{
- int status;
- char lock1[strlen(resource)+3];
- char lock2[strlen(resource)+3];
-
- snprintf(lock1, sizeof(lock1), "%s-1", resource);
- snprintf(lock2, sizeof(lock2), "%s-2", resource);
-
- switch (mode)
- {
- case LCK_EXCL:
- status = _lock_resource(lock1, SA_LCK_EX_LOCK_MODE, flags, lockid);
- if (status)
- goto out;
-
- /* If we can't get this lock too then bail out */
- status = _lock_resource(lock2, SA_LCK_EX_LOCK_MODE, LCK_NONBLOCK,
- lockid);
- if (status == SA_LCK_LOCK_NOT_QUEUED)
- {
- _unlock_resource(lock1, *lockid);
- status = -1;
- errno = EAGAIN;
- }
- break;
-
- case LCK_PREAD:
- case LCK_READ:
- status = _lock_resource(lock1, SA_LCK_PR_LOCK_MODE, flags, lockid);
- if (status)
- goto out;
- _unlock_resource(lock2, *lockid);
- break;
-
- case LCK_WRITE:
- status = _lock_resource(lock2, SA_LCK_EX_LOCK_MODE, flags, lockid);
- if (status)
- goto out;
- _unlock_resource(lock1, *lockid);
- break;
-
- default:
- status = -1;
- errno = EINVAL;
- break;
- }
-out:
- *lockid = mode;
- return status;
-}
-
-static int _sync_unlock(const char *resource, int lockid)
-{
- int status = 0;
- char lock1[strlen(resource)+3];
- char lock2[strlen(resource)+3];
-
- snprintf(lock1, sizeof(lock1), "%s-1", resource);
- snprintf(lock2, sizeof(lock2), "%s-2", resource);
-
- _unlock_resource(lock1, lockid);
- _unlock_resource(lock2, lockid);
-
- return status;
-}
-
-/* We are always quorate ! */
-static int _is_quorate()
-{
- return 1;
-}
-
-static int _get_main_cluster_fd(void)
-{
- int select_fd;
-
- cpg_fd_get(cpg_handle, &select_fd);
- return select_fd;
-}
-
-static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
- const char *csid,
- struct local_client **new_client)
-{
- cluster_client = fd;
- *new_client = NULL;
- cpg_dispatch(cpg_handle, SA_DISPATCH_ONE);
- return 1;
-}
-
-static int _cluster_send_message(const void *buf, int msglen, const char *csid,
- const char *errtext)
-{
- struct iovec iov[2];
- SaAisErrorT err;
- int target_node;
-
- if (csid)
- memcpy(&target_node, csid, OPENAIS_CSID_LEN);
- else
- target_node = 0;
-
- iov[0].iov_base = &target_node;
- iov[0].iov_len = sizeof(int);
- iov[1].iov_base = (char *)buf;
- iov[1].iov_len = msglen;
-
- err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
- return ais_to_errno(err);
-}
-
-/* We don't have a cluster name to report here */
-static int _get_cluster_name(char *buf, int buflen)
-{
- strncpy(buf, "OpenAIS", buflen);
- return 0;
-}
-
-static struct cluster_ops _cluster_openais_ops = {
- .name = "openais",
- .cluster_init_completed = NULL,
- .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,
- .reread_config = NULL,
- .cluster_closedown = _cluster_closedown,
- .get_cluster_name = _get_cluster_name,
- .sync_lock = _sync_lock,
- .sync_unlock = _sync_unlock,
-};
-
-struct cluster_ops *init_openais_cluster(void)
-{
- if (!_init_cluster())
- return &_cluster_openais_ops;
-
- return NULL;
-}
diff --git a/daemons/clvmd/clvmd-singlenode.c b/daemons/clvmd/clvmd-singlenode.c
deleted file mode 100644
index 2d53f1325..000000000
--- a/daemons/clvmd/clvmd-singlenode.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2009-2013 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "clvmd-common.h"
-
-#include <pthread.h>
-
-#include "lib/locking/locking.h"
-#include "daemons/clvmd/clvm.h"
-#include "clvmd-comms.h"
-#include "clvmd.h"
-
-#include <sys/un.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-
-static const char SINGLENODE_CLVMD_SOCKNAME[] = DEFAULT_RUN_DIR "/clvmd_singlenode.sock";
-static int listen_fd = -1;
-
-static struct dm_hash_table *_locks;
-static int _lockid;
-
-static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
-/* Using one common condition for all locks for simplicity */
-static pthread_cond_t _lock_cond = PTHREAD_COND_INITIALIZER;
-
-struct lock {
- struct dm_list list;
- int lockid;
- int mode;
-};
-
-static void close_comms(void)
-{
- if (listen_fd != -1 && close(listen_fd))
- stack;
- (void)unlink(SINGLENODE_CLVMD_SOCKNAME);
- listen_fd = -1;
-}
-
-static int init_comms(void)
-{
- mode_t old_mask;
- struct sockaddr_un addr = { .sun_family = AF_UNIX };
-
- if (!dm_strncpy(addr.sun_path, SINGLENODE_CLVMD_SOCKNAME,
- sizeof(addr.sun_path))) {
- DEBUGLOG("%s: singlenode socket name too long.",
- SINGLENODE_CLVMD_SOCKNAME);
- return -1;
- }
-
- close_comms();
-
- (void) dm_prepare_selinux_context(SINGLENODE_CLVMD_SOCKNAME, S_IFSOCK);
- old_mask = umask(0077);
-
- listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (listen_fd < 0) {
- DEBUGLOG("Can't create local socket: %s\n", strerror(errno));
- goto error;
- }
- /* Set Close-on-exec */
- if (fcntl(listen_fd, F_SETFD, 1)) {
- DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));
- goto error;
- }
-
- if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- DEBUGLOG("Can't bind local socket: %s\n", strerror(errno));
- goto error;
- }
- if (listen(listen_fd, 10) < 0) {
- DEBUGLOG("Can't listen local socket: %s\n", strerror(errno));
- goto error;
- }
-
- umask(old_mask);
- (void) dm_prepare_selinux_context(NULL, 0);
- return 0;
-error:
- umask(old_mask);
- (void) dm_prepare_selinux_context(NULL, 0);
- close_comms();
- return -1;
-}
-
-static int _init_cluster(void)
-{
- int r;
-
- if (!(_locks = dm_hash_create(128))) {
- DEBUGLOG("Failed to allocate single-node hash table.\n");
- return 1;
- }
-
- r = init_comms();
- if (r) {
- dm_hash_destroy(_locks);
- _locks = NULL;
- return r;
- }
-
- DEBUGLOG("Single-node cluster initialised.\n");
- return 0;
-}
-
-static void _cluster_closedown(void)
-{
- close_comms();
-
- /* If there is any awaited resource, kill it softly */
- pthread_mutex_lock(&_lock_mutex);
- dm_hash_destroy(_locks);
- _locks = NULL;
- _lockid = 0;
- pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
- pthread_mutex_unlock(&_lock_mutex);
-}
-
-static void _get_our_csid(char *csid)
-{
- int nodeid = 1;
- memcpy(csid, &nodeid, sizeof(int));
-}
-
-static int _csid_from_name(char *csid, const char *name)
-{
- return 1;
-}
-
-static int _name_from_csid(const char *csid, char *name)
-{
- strcpy(name, "SINGLENODE");
- return 0;
-}
-
-static int _get_num_nodes(void)
-{
- return 1;
-}
-
-/* Node is now known to be running a clvmd */
-static void _add_up_node(const char *csid)
-{
-}
-
-/* Call a callback for each node, so the caller knows whether it's up or down */
-static int _cluster_do_node_callback(struct local_client *master_client,
- void (*callback)(struct local_client *,
- const char *csid, int node_up))
-{
- return 0;
-}
-
-int _lock_file(const char *file, uint32_t flags);
-
-static const char *_get_mode(int mode)
-{
- switch (mode) {
- case LCK_NULL: return "NULL";
- case LCK_READ: return "READ";
- case LCK_PREAD: return "PREAD";
- case LCK_WRITE: return "WRITE";
- case LCK_EXCL: return "EXCLUSIVE";
- case LCK_UNLOCK: return "UNLOCK";
- default: return "????";
- }
-}
-
-/* Real locking */
-static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
-{
- /* DLM table of allowed transition states */
- static const int _dlm_table[6][6] = {
- /* Mode NL CR CW PR PW EX */
- /* NL */ { 1, 1, 1, 1, 1, 1},
- /* CR */ { 1, 1, 1, 1, 1, 0},
- /* CW */ { 1, 1, 1, 0, 0, 0},
- /* PR */ { 1, 1, 0, 1, 0, 0},
- /* PW */ { 1, 1, 0, 0, 0, 0},
- /* EX */ { 1, 0, 0, 0, 0, 0}
- };
-
- struct lock *lck = NULL, *lckt;
- struct dm_list *head;
-
- DEBUGLOG("Locking resource %s, flags=0x%02x (%s%s%s), mode=%s (%d)\n",
- resource, flags,
- (flags & LCKF_NOQUEUE) ? "NOQUEUE" : "",
- ((flags & (LCKF_NOQUEUE | LCKF_CONVERT)) ==
- (LCKF_NOQUEUE | LCKF_CONVERT)) ? "|" : "",
- (flags & LCKF_CONVERT) ? "CONVERT" : "",
- _get_mode(mode), mode);
-
- mode &= LCK_TYPE_MASK;
- pthread_mutex_lock(&_lock_mutex);
-
-retry:
- if (!(head = dm_hash_lookup(_locks, resource))) {
- if (flags & LCKF_CONVERT) {
- /* In real DLM, lock is identified only by lockid, resource is not used */
- DEBUGLOG("Unlocked resource %s cannot be converted\n", resource);
- goto_bad;
- }
- /* Add new locked resource */
- if (!(head = dm_malloc(sizeof(struct dm_list))) ||
- !dm_hash_insert(_locks, resource, head)) {
- dm_free(head);
- goto_bad;
- }
-
- dm_list_init(head);
- } else /* Update/convert locked resource */
- dm_list_iterate_items(lck, head) {
- /* Check is all locks are compatible with requested lock */
- if (flags & LCKF_CONVERT) {
- if (lck->lockid != *lockid)
- continue;
-
- DEBUGLOG("Converting resource %s lockid=%d mode:%s -> %s...\n",
- resource, lck->lockid, _get_mode(lck->mode), _get_mode(mode));
- dm_list_iterate_items(lckt, head) {
- if ((lckt->lockid != *lockid) &&
- !_dlm_table[mode][lckt->mode]) {
- if (!(flags & LCKF_NOQUEUE) &&
- /* TODO: Real dlm uses here conversion queues */
- !pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
- _locks) /* End of the game? */
- goto retry;
- goto bad;
- }
- }
- lck->mode = mode; /* Lock is now converted */
- goto out;
- } else if (!_dlm_table[mode][lck->mode]) {
- DEBUGLOG("Resource %s already locked lockid=%d, mode:%s\n",
- resource, lck->lockid, _get_mode(lck->mode));
- if (!(flags & LCKF_NOQUEUE) &&
- !pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
- _locks) { /* End of the game? */
- DEBUGLOG("Resource %s retrying lock in mode:%s...\n",
- resource, _get_mode(mode));
- goto retry;
- }
- goto bad;
- }
- }
-
- if (!(flags & LCKF_CONVERT)) {
- if (!(lck = dm_malloc(sizeof(struct lock))))
- goto_bad;
-
- *lockid = lck->lockid = ++_lockid;
- lck->mode = mode;
- dm_list_add(head, &lck->list);
- }
-out:
- pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
- pthread_mutex_unlock(&_lock_mutex);
- DEBUGLOG("Locked resource %s, lockid=%d, mode=%s\n",
- resource, lck->lockid, _get_mode(lck->mode));
-
- return 0;
-bad:
- pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
- pthread_mutex_unlock(&_lock_mutex);
- DEBUGLOG("Failed to lock resource %s\n", resource);
-
- return 1; /* fail */
-}
-
-static int _unlock_resource(const char *resource, int lockid)
-{
- struct lock *lck;
- struct dm_list *head;
- int r = 1;
-
- if (lockid < 0) {
- DEBUGLOG("Not tracking unlock of lockid -1: %s, lockid=%d\n",
- resource, lockid);
- return 1;
- }
-
- DEBUGLOG("Unlocking resource %s, lockid=%d\n", resource, lockid);
- pthread_mutex_lock(&_lock_mutex);
- pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
-
- if (!(head = dm_hash_lookup(_locks, resource))) {
- pthread_mutex_unlock(&_lock_mutex);
- DEBUGLOG("Resource %s is not locked.\n", resource);
- return 1;
- }
-
- dm_list_iterate_items(lck, head)
- if (lck->lockid == lockid) {
- dm_list_del(&lck->list);
- dm_free(lck);
- r = 0;
- goto out;
- }
-
- DEBUGLOG("Resource %s has wrong lockid %d.\n", resource, lockid);
-out:
- if (dm_list_empty(head)) {
- //DEBUGLOG("Resource %s is no longer hashed (lockid=%d).\n", resource, lockid);
- dm_hash_remove(_locks, resource);
- dm_free(head);
- }
-
- pthread_mutex_unlock(&_lock_mutex);
-
- return r;
-}
-
-static int _is_quorate(void)
-{
- return 1;
-}
-
-static int _get_main_cluster_fd(void)
-{
- return listen_fd;
-}
-
-static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
- const char *csid,
- struct local_client **new_client)
-{
- return 1;
-}
-
-static int _cluster_send_message(const void *buf, int msglen,
- const char *csid,
- const char *errtext)
-{
- return 0;
-}
-
-static int _get_cluster_name(char *buf, int buflen)
-{
- return dm_strncpy(buf, "localcluster", buflen) ? 0 : 1;
-}
-
-static struct cluster_ops _cluster_singlenode_ops = {
- .name = "singlenode",
- .cluster_init_completed = NULL,
- .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,
- .reread_config = NULL,
- .cluster_closedown = _cluster_closedown,
- .get_cluster_name = _get_cluster_name,
- .sync_lock = _lock_resource,
- .sync_unlock = _unlock_resource,
-};
-
-struct cluster_ops *init_singlenode_cluster(void)
-{
- if (!_init_cluster())
- return &_cluster_singlenode_ops;
-
- return NULL;
-}
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
deleted file mode 100644
index 73f471145..000000000
--- a/daemons/clvmd/clvmd.c
+++ /dev/null
@@ -1,2422 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * CLVMD: Cluster LVM daemon
- */
-
-#include "clvmd-common.h"
-
-#include "clvmd-comms.h"
-#include "daemons/clvmd/clvm.h"
-#include "clvmd.h"
-#include "lvm-functions.h"
-#include "lvm-version.h"
-#include "refresh_clvmd.h"
-
-#ifdef HAVE_COROSYNC_CONFDB_H
-#include <corosync/confdb.h>
-#endif
-
-#include <pthread.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <signal.h>
-#include <stddef.h>
-#include <syslog.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define MAX_RETRIES 4
-#define MAX_MISSING_LEN 8000 /* Max supported clvmd message size ? */
-
-#define ISLOCAL_CSID(c) (memcmp(c, our_csid, max_csid_len) == 0)
-
-/* Head of the fd list. Also contains
- the cluster_socket details */
-static struct local_client local_client_head;
-static int _local_client_count = 0;
-
-static unsigned short global_xid = 0; /* Last transaction ID issued */
-
-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;
-
-static void _add_client(struct local_client *new_client, struct local_client *existing_client)
-{
- _local_client_count++;
- DEBUGLOG("(%p) Adding listener for fd %d. (Now %d monitored fds.)\n", new_client, new_client->fd, _local_client_count);
- new_client->next = existing_client->next;
- existing_client->next = new_client;
-}
-
-int add_client(struct local_client *new_client)
-{
- _add_client(new_client, &local_client_head);
-
- return 0;
-}
-
-/* Returns 0 if delfd is found and removed from list */
-static int _del_client(struct local_client *delfd)
-{
- struct local_client *lastfd, *thisfd;
-
- for (lastfd = &local_client_head; (thisfd = lastfd->next); lastfd = thisfd)
- if (thisfd == delfd) {
- DEBUGLOG("(%p) Removing listener for fd %d\n", thisfd, thisfd->fd);
- lastfd->next = delfd->next;
- _local_client_count--;
- return 0;
- }
-
- return 1;
-}
-
-/* Structure of items on the LVM thread list */
-struct lvm_thread_cmd {
- struct dm_list list;
-
- struct local_client *client;
- struct clvm_header *msg;
- char csid[MAX_CSID_LEN];
- int remote; /* Flag */
- int msglen;
- unsigned short xid;
-};
-
-struct lvm_startup_params {
- struct dm_hash_table *excl_uuid;
-};
-
-static debug_t debug = DEBUG_OFF;
-static int foreground_mode = 0;
-static pthread_t lvm_thread;
-/* Stack size 128KiB for thread, must be bigger then DEFAULT_RESERVED_STACK */
-static const size_t STACK_SIZE = 128 * 1024;
-static pthread_attr_t stack_attr;
-static int lvm_thread_exit = 0;
-static pthread_mutex_t lvm_thread_mutex;
-static pthread_mutex_t _debuglog_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t lvm_thread_cond;
-static pthread_barrier_t lvm_start_barrier;
-static struct dm_list lvm_cmd_head;
-static volatile sig_atomic_t quit = 0;
-static volatile sig_atomic_t reread_config = 0;
-static int child_pipe[2];
-
-/* Reasons the daemon failed initialisation */
-#define DFAIL_INIT 1
-#define DFAIL_LOCAL_SOCK 2
-#define DFAIL_CLUSTER_IF 3
-#define DFAIL_MALLOC 4
-#define DFAIL_TIMEOUT 5
-#define SUCCESS 0
-
-typedef enum {IF_AUTO, IF_CMAN, IF_OPENAIS, IF_COROSYNC, IF_SINGLENODE} if_type_t;
-
-/* Prototypes for code further down */
-static void sigusr2_handler(int sig);
-static void sighup_handler(int sig);
-static void sigterm_handler(int sig);
-static void send_local_reply(struct local_client *client, int status,
- int clientid);
-static void free_reply(struct local_client *client);
-static void send_version_message(void);
-static void *pre_and_post_thread(void *arg);
-static int send_message(void *buf, int msglen, const char *csid, int fd,
- const char *errtext);
-static int read_from_local_sock(struct local_client *thisfd);
-static int cleanup_zombie(struct local_client *thisfd);
-static int process_local_command(struct clvm_header *msg, int msglen,
- struct local_client *client,
- unsigned short xid);
-static void process_remote_command(struct clvm_header *msg, int msglen, int fd,
- const char *csid);
-static int process_reply(const struct clvm_header *msg, int msglen,
- const char *csid);
-static int open_local_sock(void);
-static void close_local_sock(int local_socket);
-static int check_local_clvmd(void);
-static struct local_client *find_client(int clientid);
-static void main_loop(int cmd_timeout);
-static void be_daemon(int start_timeout);
-static int check_all_clvmds_running(struct local_client *client);
-static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
- int len, const char *csid,
- struct local_client **new_client);
-static void *lvm_thread_fn(void *) __attribute__((noreturn));
-static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
- int msglen, const char *csid);
-static int distribute_command(struct local_client *thisfd);
-static void hton_clvm(struct clvm_header *hdr);
-static void ntoh_clvm(struct clvm_header *hdr);
-static void add_reply_to_list(struct local_client *client, int status,
- const char *csid, const char *buf, int len);
-static if_type_t parse_cluster_interface(char *ifname);
-static if_type_t get_cluster_type(void);
-
-static void usage(const char *prog, FILE *file)
-{
- fprintf(file, "Usage: %s [options]\n"
- " -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
- " -d[<n>] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
- " -E<uuid> Take this lock uuid as exclusively locked resource (for restart)\n"
- " -f Don't fork, run in the foreground\n"
- " -h Show this help information\n"
- " -I<cmgr> Cluster manager (default: auto)\n"
- " Available cluster managers: "
-#ifdef USE_COROSYNC
- "corosync "
-#endif
-#ifdef USE_CMAN
- "cman "
-#endif
-#ifdef USE_OPENAIS
- "openais "
-#endif
-#ifdef USE_SINGLENODE
- "singlenode "
-#endif
- "\n"
- " -R Tell all running clvmds in the cluster to reload their device cache\n"
- " -S Restart clvmd, preserving exclusive locks\n"
- " -t<secs> Command timeout (default: 60 seconds)\n"
- " -T<secs> Startup timeout (default: 0 seconds)\n"
- " -V Show version of clvmd\n"
- "\n", prog);
-}
-
-/* Called to signal the parent how well we got on during initialisation */
-static void child_init_signal(int status)
-{
- if (child_pipe[1]) {
- /* FIXME Use a proper wrapper around write */
- if (write(child_pipe[1], &status, sizeof(status)) < 0)
- log_sys_error("write", "child_pipe");
- if (close(child_pipe[1]))
- log_sys_error("close", "child_pipe");
- }
-}
-
-static __attribute__((noreturn)) void child_init_signal_and_exit(int status)
-{
- child_init_signal(status);
- exit(status);
-}
-
-static void safe_close(int *fd)
-{
- if (*fd >= 0) {
- int to_close = *fd;
- *fd = -1;
- if (close(to_close))
- log_sys_error("close", ""); /* path */
- }
-}
-
-void debuglog(const char *fmt, ...)
-{
- time_t P;
- va_list ap;
- static int syslog_init = 0;
- char buf_ctime[64];
-
- switch (clvmd_get_debug()) {
- case DEBUG_STDERR:
- pthread_mutex_lock(&_debuglog_mutex);
- va_start(ap,fmt);
- time(&P);
- fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime_r(&P, buf_ctime) + 4);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fflush(stderr);
- pthread_mutex_unlock(&_debuglog_mutex);
- break;
- case DEBUG_SYSLOG:
- pthread_mutex_lock(&_debuglog_mutex);
- if (!syslog_init) {
- openlog("clvmd", LOG_PID, LOG_DAEMON);
- syslog_init = 1;
- }
-
- va_start(ap,fmt);
- vsyslog(LOG_DEBUG, fmt, ap);
- va_end(ap);
- pthread_mutex_unlock(&_debuglog_mutex);
- break;
- case DEBUG_OFF:
- break;
- }
-}
-
-void clvmd_set_debug(debug_t new_debug)
-{
- if (!foreground_mode && new_debug == DEBUG_STDERR)
- new_debug = DEBUG_SYSLOG;
-
- if (new_debug > DEBUG_SYSLOG)
- new_debug = DEBUG_SYSLOG;
-
- debug = new_debug;
-}
-
-debug_t clvmd_get_debug(void)
-{
- return debug;
-}
-
-int clvmd_get_foreground(void)
-{
- return foreground_mode;
-}
-
-static const char *decode_cmd(unsigned char cmdl)
-{
- static char buf[128];
- const char *command;
-
- switch (cmdl) {
- case CLVMD_CMD_TEST:
- command = "TEST";
- break;
- case CLVMD_CMD_LOCK_VG:
- command = "LOCK_VG";
- break;
- case CLVMD_CMD_LOCK_LV:
- command = "LOCK_LV";
- break;
- case CLVMD_CMD_REFRESH:
- command = "REFRESH";
- break;
- case CLVMD_CMD_SET_DEBUG:
- command = "SET_DEBUG";
- break;
- case CLVMD_CMD_GET_CLUSTERNAME:
- command = "GET_CLUSTERNAME";
- break;
- case CLVMD_CMD_VG_BACKUP:
- command = "VG_BACKUP";
- break;
- case CLVMD_CMD_REPLY:
- command = "REPLY";
- break;
- case CLVMD_CMD_VERSION:
- command = "VERSION";
- break;
- case CLVMD_CMD_GOAWAY:
- command = "GOAWAY";
- break;
- case CLVMD_CMD_LOCK:
- command = "LOCK";
- break;
- case CLVMD_CMD_UNLOCK:
- command = "UNLOCK";
- break;
- case CLVMD_CMD_LOCK_QUERY:
- command = "LOCK_QUERY";
- break;
- case CLVMD_CMD_RESTART:
- command = "RESTART";
- break;
- case CLVMD_CMD_SYNC_NAMES:
- command = "SYNC_NAMES";
- break;
- default:
- command = "unknown";
- break;
- }
-
- snprintf(buf, sizeof(buf), "%s (0x%x)", command, cmdl);
-
- return buf;
-}
-
-static void remove_lockfile(void)
-{
- if (unlink(CLVMD_PIDFILE))
- log_sys_error("unlink", CLVMD_PIDFILE);
-}
-
-/*
- * clvmd require dm-ioctl capability for operation
- */
-static void check_permissions(void)
-{
- if (getuid() || geteuid()) {
- log_error("Cannot run as a non-root user.");
-
- /*
- * Fail cleanly here if not run as root, instead of failing
- * later when attempting a root-only operation
- * Preferred exit code from an initscript for this.
- */
- exit(4);
- }
-}
-
-int main(int argc, char *argv[])
-{
- int local_sock;
- struct local_client *newfd, *delfd;
- struct lvm_startup_params lvm_params;
- int opt;
- int cmd_timeout = DEFAULT_CMD_TIMEOUT;
- int start_timeout = 0;
- if_type_t cluster_iface = IF_AUTO;
- sigset_t ss;
- debug_t debug_opt = DEBUG_OFF;
- debug_t debug_arg = DEBUG_OFF;
- int clusterwide_opt = 0;
- mode_t old_mask;
- int ret = 1;
-
- struct option longopts[] = {
- { "help", 0, 0, 'h' },
- { NULL, 0, 0, 0 }
- };
-
- if (!(lvm_params.excl_uuid = dm_hash_create(128))) {
- fprintf(stderr, "Failed to allocate hash table\n");
- return 1;
- }
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt = getopt_long(argc, argv, "Vhfd:t:RST:CI:E:",
- longopts, NULL)) != -1) {
- switch (opt) {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case 'R':
- check_permissions();
- ret = (refresh_clvmd(1) == 1) ? 0 : 1;
- goto out;
-
- case 'S':
- check_permissions();
- ret = (restart_clvmd(clusterwide_opt) == 1) ? 0 : 1;
- goto out;
-
- case 'C':
- clusterwide_opt = 1;
- break;
-
- case 'd':
- debug_opt = DEBUG_STDERR;
- debug_arg = (debug_t) atoi(optarg);
- if (debug_arg == DEBUG_STDERR)
- foreground_mode = 1;
- break;
-
- case 'f':
- foreground_mode = 1;
- break;
- case 't':
- cmd_timeout = atoi(optarg);
- if (!cmd_timeout) {
- fprintf(stderr, "command timeout is invalid\n");
- usage(argv[0], stderr);
- exit(1);
- }
- break;
- case 'I':
- cluster_iface = parse_cluster_interface(optarg);
- break;
- case 'E':
- if (!dm_hash_insert(lvm_params.excl_uuid, optarg, optarg)) {
- fprintf(stderr, "Failed to allocate hash entry\n");
- goto out;
- }
- break;
- case 'T':
- start_timeout = atoi(optarg);
- if (start_timeout <= 0) {
- fprintf(stderr, "startup timeout is invalid\n");
- usage(argv[0], stderr);
- exit(1);
- }
- break;
-
- case 'V':
- printf("Cluster LVM daemon version: %s\n", LVM_VERSION);
- printf("Protocol version: %d.%d.%d\n",
- CLVMD_MAJOR_VERSION, CLVMD_MINOR_VERSION,
- CLVMD_PATCH_VERSION);
- exit(0);
- break;
-
- default:
- usage(argv[0], stderr);
- exit(2);
- }
- }
-
- check_permissions();
-
- /*
- * Switch to C locale to avoid reading large locale-archive file
- * used by some glibc (on some distributions it takes over 100MB).
- * Daemon currently needs to use mlockall().
- */
- if (setenv("LC_ALL", "C", 1))
- perror("Cannot set LC_ALL to C");
-
- /* Setting debug options on an existing clvmd */
- if (debug_opt && !check_local_clvmd()) {
- dm_hash_destroy(lvm_params.excl_uuid);
- return debug_clvmd(debug_arg, clusterwide_opt)==1?0:1;
- }
-
- clvmd_set_debug(debug_arg);
-
- /* Fork into the background (unless requested not to) */
- if (!foreground_mode)
- be_daemon(start_timeout);
-
- (void) dm_prepare_selinux_context(DEFAULT_RUN_DIR, S_IFDIR);
- old_mask = umask(0077);
- if (dm_create_dir(DEFAULT_RUN_DIR) == 0) {
- DEBUGLOG("clvmd: unable to create %s directory\n",
- DEFAULT_RUN_DIR);
- umask(old_mask);
- exit(1);
- }
- umask(old_mask);
-
- /* Create pidfile */
- (void) dm_prepare_selinux_context(CLVMD_PIDFILE, S_IFREG);
- if (dm_create_lockfile(CLVMD_PIDFILE) == 0) {
- DEBUGLOG("clvmd: unable to create lockfile\n");
- exit(1);
- }
- (void) dm_prepare_selinux_context(NULL, 0);
-
- atexit(remove_lockfile);
-
- DEBUGLOG("CLVMD started\n");
-
- /* Open the Unix socket we listen for commands on.
- We do this before opening the cluster socket so that
- potential clients will block rather than error if we are running
- but the cluster is not ready yet */
- local_sock = open_local_sock();
- if (local_sock < 0) {
- child_init_signal_and_exit(DFAIL_LOCAL_SOCK);
- /* NOTREACHED */
- }
-
- /* Set up signal handlers, USR1 is for cluster change notifications (in cman)
- USR2 causes child threads to exit.
- (HUP used to cause gulm to re-read the nodes list from CCS.)
- PIPE should be ignored */
- signal(SIGUSR2, sigusr2_handler);
- signal(SIGHUP, sighup_handler);
- signal(SIGPIPE, SIG_IGN);
-
- /* Block SIGUSR2/SIGINT/SIGTERM in process */
- sigemptyset(&ss);
- sigaddset(&ss, SIGUSR2);
- sigaddset(&ss, SIGINT);
- sigaddset(&ss, SIGTERM);
- sigprocmask(SIG_BLOCK, &ss, NULL);
-
- /* Initialise the LVM thread variables */
- dm_list_init(&lvm_cmd_head);
- if (pthread_attr_init(&stack_attr) ||
- pthread_attr_setstacksize(&stack_attr, STACK_SIZE + getpagesize())) {
- log_sys_error("pthread_attr_init", "");
- exit(1);
- }
- pthread_mutex_init(&lvm_thread_mutex, NULL);
- pthread_cond_init(&lvm_thread_cond, NULL);
- pthread_barrier_init(&lvm_start_barrier, NULL, 2);
- init_lvhash();
-
- /* Start the cluster interface */
- if (cluster_iface == IF_AUTO)
- cluster_iface = get_cluster_type();
-
-#ifdef USE_CMAN
- if ((cluster_iface == IF_AUTO || cluster_iface == IF_CMAN) &&
- (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_NODENAME_LEN;
- syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to CMAN");
- }
-#endif
-#ifdef USE_COROSYNC
- if (!clops)
- if (((cluster_iface == IF_AUTO || cluster_iface == IF_COROSYNC) &&
- (clops = init_corosync_cluster()))) {
- max_csid_len = COROSYNC_CSID_LEN;
- max_cluster_message = COROSYNC_MAX_CLUSTER_MESSAGE;
- max_cluster_member_name_len = COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN;
- syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to Corosync");
- }
-#endif
-#ifdef USE_OPENAIS
- if (!clops)
- if ((cluster_iface == IF_AUTO || cluster_iface == IF_OPENAIS) &&
- (clops = init_openais_cluster())) {
- max_csid_len = OPENAIS_CSID_LEN;
- max_cluster_message = OPENAIS_MAX_CLUSTER_MESSAGE;
- max_cluster_member_name_len = OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN;
- syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to OpenAIS");
- }
-#endif
-#ifdef USE_SINGLENODE
- if (!clops)
- if (cluster_iface == IF_SINGLENODE && (clops = init_singlenode_cluster())) {
- max_csid_len = SINGLENODE_CSID_LEN;
- max_cluster_message = SINGLENODE_MAX_CLUSTER_MESSAGE;
- max_cluster_member_name_len = MAX_CLUSTER_MEMBER_NAME_LEN;
- syslog(LOG_NOTICE, "Cluster LVM daemon started - running in single-node mode");
- }
-#endif
-
- if (!clops) {
- DEBUGLOG("Can't initialise cluster interface\n");
- log_error("Can't initialise cluster interface.");
- child_init_signal_and_exit(DFAIL_CLUSTER_IF);
- /* NOTREACHED */
- }
- DEBUGLOG("Cluster ready, doing some more initialisation\n");
-
- /* Save our CSID */
- clops->get_our_csid(our_csid);
-
- /* Initialise the FD list head */
- local_client_head.fd = clops->get_main_cluster_fd();
- local_client_head.type = CLUSTER_MAIN_SOCK;
- local_client_head.callback = clops->cluster_fd_callback;
- _local_client_count++;
-
- /* Add the local socket to the list */
- if (!(newfd = dm_zalloc(sizeof(struct local_client)))) {
- child_init_signal_and_exit(DFAIL_MALLOC);
- /* NOTREACHED */
- }
-
- newfd->fd = local_sock;
- newfd->type = LOCAL_RENDEZVOUS;
- newfd->callback = local_rendezvous_callback;
-
- (void) add_client(newfd);
-
- /* This needs to be started after cluster initialisation
- as it may need to take out locks */
- DEBUGLOG("Starting LVM thread\n");
- DEBUGLOG("(%p) Main cluster socket fd %d with local socket %d (%p)\n",
- &local_client_head, local_client_head.fd, newfd->fd, newfd);
-
- /* Don't let anyone else to do work until we are started */
- if (pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params)) {
- log_sys_error("pthread_create", "");
- goto out;
- }
-
- /* Don't start until the LVM thread is ready */
- pthread_barrier_wait(&lvm_start_barrier);
-
- /* Tell the rest of the cluster our version number */
- if (clops->cluster_init_completed)
- clops->cluster_init_completed();
-
- DEBUGLOG("clvmd ready for work\n");
- child_init_signal(SUCCESS);
-
- /* Try to shutdown neatly */
- signal(SIGTERM, sigterm_handler);
- signal(SIGINT, sigterm_handler);
-
- /* Do some work */
- main_loop(cmd_timeout);
-
- pthread_mutex_lock(&lvm_thread_mutex);
- lvm_thread_exit = 1;
- pthread_cond_signal(&lvm_thread_cond);
- pthread_mutex_unlock(&lvm_thread_mutex);
- if ((errno = pthread_join(lvm_thread, NULL)))
- log_sys_error("pthread_join", "");
-
- close_local_sock(local_sock);
-
- while ((delfd = local_client_head.next)) {
- local_client_head.next = delfd->next;
- _local_client_count--;
- /* Failing cleanup_zombie leaks... */
- if (delfd->type == LOCAL_SOCK && !cleanup_zombie(delfd))
- cmd_client_cleanup(delfd); /* calls sync_unlock */
- if (delfd->fd != local_sock)
- safe_close(&(delfd->fd));
- dm_free(delfd);
- }
-
- DEBUGLOG("cluster_closedown\n");
- destroy_lvhash();
- clops->cluster_closedown();
-
- ret = 0;
-out:
- dm_hash_destroy(lvm_params.excl_uuid);
-
- return ret;
-}
-
-/* Called when the cluster layer has completed initialisation.
- We send the version message */
-void clvmd_cluster_init_completed(void)
-{
- send_version_message();
-}
-
-/* Data on a connected socket */
-static int local_sock_callback(struct local_client *thisfd, char *buf, int len,
- const char *csid,
- struct local_client **new_client)
-{
- *new_client = NULL;
- return read_from_local_sock(thisfd);
-}
-
-/* Data on a connected socket */
-static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
- int len, const char *csid,
- struct local_client **new_client)
-{
- /* Someone connected to our local socket, accept it. */
-
- struct sockaddr_un socka;
- struct local_client *newfd;
- socklen_t sl = sizeof(socka);
- int client_fd = accept(thisfd->fd, (struct sockaddr *) &socka, &sl);
-
- if (client_fd == -1 && errno == EINTR)
- return 1;
-
- if (client_fd >= 0) {
- if (!(newfd = dm_zalloc(sizeof(*newfd)))) {
- if (close(client_fd))
- log_sys_error("close", "socket");
- return 1;
- }
-
- pthread_cond_init(&newfd->bits.localsock.cond, NULL);
- pthread_mutex_init(&newfd->bits.localsock.mutex, NULL);
-
- if (fcntl(client_fd, F_SETFD, 1))
- DEBUGLOG("(%p) Setting CLOEXEC on client fd %d failed: %s\n", thisfd, client_fd, strerror(errno));
-
- newfd->fd = client_fd;
- newfd->type = LOCAL_SOCK;
- newfd->callback = local_sock_callback;
- newfd->bits.localsock.all_success = 1;
- DEBUGLOG("(%p) Got new connection on fd %d\n", newfd, newfd->fd);
- *new_client = newfd;
- }
- return 1;
-}
-
-static int local_pipe_callback(struct local_client *thisfd, char *buf,
- int maxlen, const char *csid,
- struct local_client **new_client)
-{
- int len;
- char buffer[PIPE_BUF];
- struct local_client *sock_client = thisfd->bits.pipe.client;
- int status = -1; /* in error by default */
-
- len = read(thisfd->fd, buffer, sizeof(int));
- if (len == -1 && errno == EINTR)
- return 1;
-
- if (len == sizeof(int))
- memcpy(&status, buffer, sizeof(int));
-
- DEBUGLOG("(%p) Read on pipe %d, %d bytes, status %d\n",
- thisfd, thisfd->fd, len, status);
-
- /* EOF on pipe or an error, close it */
- if (len <= 0) {
- void *ret = &status;
- if (close(thisfd->fd))
- log_sys_error("close", "local_pipe");
-
- /* Clear out the cross-link */
- if (thisfd->bits.pipe.client)
- thisfd->bits.pipe.client->bits.localsock.pipe_client = NULL;
-
- /* Reap child thread */
- if (thisfd->bits.pipe.threadid) {
- if ((errno = pthread_join(thisfd->bits.pipe.threadid, &ret)))
- log_sys_error("pthread_join", "");
-
- thisfd->bits.pipe.threadid = 0;
- if (thisfd->bits.pipe.client)
- thisfd->bits.pipe.client->bits.localsock.threadid = 0;
- }
- return -1;
- } else {
- DEBUGLOG("(%p) Background routine status was %d, sock_client %p\n",
- thisfd, status, sock_client);
- /* But has the client gone away ?? */
- if (!sock_client) {
- DEBUGLOG("(%p) Got pipe response for dead client, ignoring it\n", thisfd);
- } else {
- /* If error then just return that code */
- if (status)
- send_local_reply(sock_client, status,
- sock_client->fd);
- else {
- /* FIXME: closer inspect this code since state is write thread protected */
- pthread_mutex_lock(&sock_client->bits.localsock.mutex);
- if (sock_client->bits.localsock.state == POST_COMMAND) {
- pthread_mutex_unlock(&sock_client->bits.localsock.mutex);
- send_local_reply(sock_client, 0,
- sock_client->fd);
- } else {
- /* PRE_COMMAND finished. */
- pthread_mutex_unlock(&sock_client->bits.localsock.mutex);
- if ((status = distribute_command(sock_client)))
- send_local_reply(sock_client, EFBIG,
- sock_client->fd);
- }
- }
- }
- }
- return len;
-}
-
-/* If a noed is up, look for it in the reply array, if it's not there then
- add one with "ETIMEDOUT".
- NOTE: This won't race with real replies because they happen in the same thread.
-*/
-static void timedout_callback(struct local_client *client, const char *csid,
- int node_up)
-{
- struct node_reply *reply;
- char nodename[max_cluster_member_name_len];
-
- if (!node_up)
- return;
-
- clops->name_from_csid(csid, nodename);
- DEBUGLOG("(%p) Checking for a reply from %s\n", client, nodename);
- pthread_mutex_lock(&client->bits.localsock.mutex);
-
- reply = client->bits.localsock.replies;
- while (reply && strcmp(reply->node, nodename) != 0)
- reply = reply->next;
-
- pthread_mutex_unlock(&client->bits.localsock.mutex);
-
- if (!reply) {
- DEBUGLOG("(%p) Node %s timed-out\n", client, nodename);
- add_reply_to_list(client, ETIMEDOUT, csid,
- "Command timed out", 18);
- }
-}
-
-/* Called when the request has timed out on at least one node. We fill in
- the remaining node entries with ETIMEDOUT and return.
-
- By the time we get here the node that caused
- the timeout could have gone down, in which case we will never get the expected
- number of replies that triggers the post command so we need to do it here
-*/
-static void request_timed_out(struct local_client *client)
-{
- DEBUGLOG("(%p) Request timed-out. padding\n", client);
- clops->cluster_do_node_callback(client, timedout_callback);
-
- if (!client->bits.localsock.threadid)
- return;
-
- pthread_mutex_lock(&client->bits.localsock.mutex);
-
- if (!client->bits.localsock.finished &&
- (client->bits.localsock.num_replies !=
- client->bits.localsock.expected_replies)) {
- /* Post-process the command */
- client->bits.localsock.state = POST_COMMAND;
- pthread_cond_signal(&client->bits.localsock.cond);
- }
-
- pthread_mutex_unlock(&client->bits.localsock.mutex);
-}
-
-/* This is where the real work happens */
-static void main_loop(int cmd_timeout)
-{
- sigset_t ss;
-
- DEBUGLOG("Using timeout of %d seconds\n", cmd_timeout);
-
- sigemptyset(&ss);
- sigaddset(&ss, SIGINT);
- sigaddset(&ss, SIGTERM);
- pthread_sigmask(SIG_UNBLOCK, &ss, NULL);
- /* Main loop */
- while (!quit) {
- fd_set in;
- int select_status;
- struct local_client *thisfd, *nextfd;
- struct timeval tv = { cmd_timeout, 0 };
- int quorate = clops->is_quorate();
- int client_count = 0;
- int max_fd = 0;
-
- /* Wait on the cluster FD and all local sockets/pipes */
- local_client_head.fd = clops->get_main_cluster_fd();
- FD_ZERO(&in);
-
- for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
- client_count++;
- max_fd = max(max_fd, thisfd->fd);
- }
-
- if (max_fd > FD_SETSIZE - 32) {
- fprintf(stderr, "WARNING: There are too many connections to clvmd. Investigate and take action now!\n");
- fprintf(stderr, "WARNING: Your cluster may freeze up if the number of clvmd file descriptors (%d) exceeds %d.\n", max_fd + 1, FD_SETSIZE);
- }
-
- for (thisfd = &local_client_head; thisfd; thisfd = nextfd) {
- nextfd = thisfd->next;
-
- if (thisfd->removeme && !cleanup_zombie(thisfd)) {
- /* cleanup_zombie might have removed the next list element */
- nextfd = thisfd->next;
-
- (void) _del_client(thisfd);
-
- DEBUGLOG("(%p) removeme set with %d monitored fds remaining\n", thisfd, _local_client_count);
-
- /* Queue cleanup, this also frees the client struct */
- add_to_lvmqueue(thisfd, NULL, 0, NULL);
- continue;
- }
-
- if (thisfd->removeme)
- continue;
-
- /* if the cluster is not quorate then don't listen for new requests */
- if ((thisfd->type != LOCAL_RENDEZVOUS &&
- thisfd->type != LOCAL_SOCK) || quorate)
- if (thisfd->fd < FD_SETSIZE)
- FD_SET(thisfd->fd, &in);
- }
-
- select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv);
-
- if (reread_config) {
- int saved_errno = errno;
-
- reread_config = 0;
- DEBUGLOG("got SIGHUP\n");
- if (clops->reread_config)
- clops->reread_config();
- errno = saved_errno;
- }
-
- if (select_status > 0) {
- char csid[MAX_CSID_LEN];
- char buf[max_cluster_message];
-
- for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
- if (thisfd->fd < FD_SETSIZE && FD_ISSET(thisfd->fd, &in)) {
- struct local_client *newfd = NULL;
- int ret;
-
- /* FIXME Remove from main thread in case it blocks! */
- /* Do callback */
- ret = thisfd->callback(thisfd, buf, sizeof(buf),
- csid, &newfd);
- /* Ignore EAGAIN */
- if (ret < 0 && (errno == EAGAIN || errno == EINTR)) {
- continue;
- }
-
- /* Got error or EOF: Remove it from the list safely */
- if (ret <= 0) {
- int type = thisfd->type;
-
- /* If the cluster socket shuts down, so do we */
- if (type == CLUSTER_MAIN_SOCK ||
- type == CLUSTER_INTERNAL)
- goto closedown;
-
- DEBUGLOG("(%p) ret == %d, errno = %d. removing client\n",
- thisfd, ret, errno);
- thisfd->removeme = 1;
- continue;
- }
-
- /* New client...simply add it to the list */
- if (newfd) {
- _add_client(newfd, thisfd);
- thisfd = newfd;
- }
- }
- }
- }
-
- /* Select timed out. Check for clients that have been waiting too long for a response */
- if (select_status == 0) {
- time_t the_time = time(NULL);
-
- for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
- if (thisfd->type == LOCAL_SOCK &&
- thisfd->bits.localsock.sent_out &&
- (thisfd->bits.localsock.sent_time + cmd_timeout) < the_time &&
- thisfd->bits.localsock.expected_replies !=
- thisfd->bits.localsock.num_replies) {
- /* Send timed out message + replies we already have */
- DEBUGLOG("Request to client %p timed-out (send: %ld, now: %ld)\n",
- thisfd, thisfd->bits.localsock.sent_time, the_time);
-
- thisfd->bits.localsock.all_success = 0;
-
- request_timed_out(thisfd);
- }
- }
- }
- if (select_status < 0) {
- if (errno == EINTR)
- continue;
-
-#ifdef DEBUG
- perror("select error");
- exit(-1);
-#endif
- }
- }
-
- closedown:
- if (quit)
- DEBUGLOG("SIGTERM received\n");
-}
-
-static __attribute__ ((noreturn)) void wait_for_child(int c_pipe, int timeout)
-{
- int child_status;
- fd_set fds;
- struct timeval tv = {timeout, 0};
-
- FD_ZERO(&fds);
- FD_SET(c_pipe, &fds);
-
- switch (select(c_pipe+1, &fds, NULL, NULL, timeout? &tv: NULL)) {
- case 0:
- fprintf(stderr, "clvmd startup timed out\n");
- exit(DFAIL_TIMEOUT);
- case 1:
- if (read(c_pipe, &child_status, sizeof(child_status)) !=
- sizeof(child_status)) {
- fprintf(stderr, "clvmd failed in initialisation\n");
- exit(DFAIL_INIT);
- }
-
- switch (child_status) {
- case SUCCESS:
- break;
- case DFAIL_INIT:
- fprintf(stderr, "clvmd failed in initialisation\n");
- break;
- case DFAIL_LOCAL_SOCK:
- fprintf(stderr, "clvmd could not create local socket\n");
- fprintf(stderr, "Another clvmd is probably already running\n");
- break;
- case DFAIL_CLUSTER_IF:
- fprintf(stderr, "clvmd could not connect to cluster manager\n");
- fprintf(stderr, "Consult syslog for more information\n");
- break;
- case DFAIL_MALLOC:
- fprintf(stderr, "clvmd failed, not enough memory\n");
- break;
- default:
- fprintf(stderr, "clvmd failed, error was %d\n", child_status);
- break;
- }
- exit(child_status);
- default:
- fprintf(stderr, "clvmd startup, select failed: %s\n", strerror(errno));
- exit(DFAIL_INIT);
- }
-}
-
-/*
- * Fork into the background and detach from our parent process.
- * In the interests of user-friendliness we wait for the daemon
- * to complete initialisation before returning its status
- * the the user.
- */
-static void be_daemon(int timeout)
-{
- int devnull = open("/dev/null", O_RDWR);
- if (devnull == -1) {
- perror("Can't open /dev/null");
- exit(3);
- }
-
- if (pipe(child_pipe)) {
- perror("Error creating pipe");
- exit(3);
- }
-
- switch (fork()) {
- case -1:
- perror("clvmd: can't fork");
- exit(2);
-
- case 0: /* Child */
- (void) close(child_pipe[0]);
- break;
-
- default: /* Parent */
- (void) close(devnull);
- (void) close(child_pipe[1]);
- wait_for_child(child_pipe[0], timeout); /* noreturn */
- }
-
- /* Detach ourself from the calling environment */
- if ((dup2(devnull, STDIN_FILENO) == -1) ||
- (dup2(devnull, STDOUT_FILENO) == -1) ||
- (dup2(devnull, STDERR_FILENO) == -1)) {
- perror("Error setting terminal FDs to /dev/null");
- log_error("Error setting terminal FDs to /dev/null: %m");
- exit(5);
- }
-
- if ((devnull > STDERR_FILENO) && close(devnull)) {
- log_sys_error("close", "/dev/null");
- exit(7);
- }
-
- if (chdir("/")) {
- log_error("Error setting current directory to /: %m");
- exit(6);
- }
-
- setsid();
-}
-
-static int verify_message(char *buf, int len)
-{
- struct clvm_header *h = (struct clvm_header *)buf;
-
- if (len < (int)sizeof(struct clvm_header)) {
- log_error("verify_message short len %d.", len);
- return -1;
- }
-
- switch (h->cmd) {
- case CLVMD_CMD_REPLY:
- case CLVMD_CMD_VERSION:
- case CLVMD_CMD_GOAWAY:
- case CLVMD_CMD_TEST:
- case CLVMD_CMD_LOCK:
- case CLVMD_CMD_UNLOCK:
- case CLVMD_CMD_LOCK_LV:
- case CLVMD_CMD_LOCK_VG:
- case CLVMD_CMD_LOCK_QUERY:
- case CLVMD_CMD_REFRESH:
- case CLVMD_CMD_GET_CLUSTERNAME:
- case CLVMD_CMD_SET_DEBUG:
- case CLVMD_CMD_VG_BACKUP:
- case CLVMD_CMD_RESTART:
- case CLVMD_CMD_SYNC_NAMES:
- break;
- default:
- log_error("verify_message bad cmd %x.", h->cmd);
- return -1;
- }
-
- /* TODO: we may be able to narrow len/flags/clientid/arglen checks based on cmd */
-
- if (h->flags & ~(CLVMD_FLAG_LOCAL | CLVMD_FLAG_SYSTEMLV | CLVMD_FLAG_NODEERRS | CLVMD_FLAG_REMOTE)) {
- log_error("verify_message bad flags %x.", h->flags);
- return -1;
- }
-
- if (h->arglen > max_cluster_message) {
- log_error("verify_message bad arglen %x max %d.", h->arglen, max_cluster_message);
- return -1;
- }
-
- return 0;
-}
-
-static void dump_message(char *buf, int len)
-{
- unsigned char row[8];
- char str[9];
- int i, j = 0;
-
- str[8] = '\0';
- if (len > 128)
- len = 128;
-
- for (i = 0; i < len; ++i) {
- row[j] = buf[i];
- str[j] = (isprint(buf[i])) ? buf[i] : ' ';
-
- if (i + 1 == len) {
- for (;j < 8; ++j) {
- row[j] = 0;
- str[j] = ' ';
- }
-
- log_error("%02x %02x %02x %02x %02x %02x %02x %02x [%s]",
- row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], str);
- j = 0;
- }
- }
-}
-
-static int cleanup_zombie(struct local_client *thisfd)
-{
- int *status;
- struct local_client *pipe_client;
-
- if (thisfd->type != LOCAL_SOCK)
- return 0;
-
- if (!thisfd->bits.localsock.cleanup_needed)
- return 0;
-
- DEBUGLOG("(%p) EOF on local socket %d: inprogress=%d\n",
- thisfd, thisfd->fd, thisfd->bits.localsock.in_progress);
-
- if ((pipe_client = thisfd->bits.localsock.pipe_client))
- pipe_client = pipe_client->bits.pipe.client;
-
- /* If the client went away in mid command then tidy up */
- if (thisfd->bits.localsock.in_progress) {
- DEBUGLOG("Sending SIGUSR2 to pre&post thread (%p in-progress)\n", pipe_client);
- pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
- if (pthread_mutex_trylock(&thisfd->bits.localsock.mutex))
- return 1;
- thisfd->bits.localsock.state = POST_COMMAND;
- thisfd->bits.localsock.finished = 1;
- pthread_cond_signal(&thisfd->bits.localsock.cond);
- pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
-
- /* Free any unsent buffers */
- free_reply(thisfd);
- }
-
- /* Kill the subthread & free resources */
- if (thisfd->bits.localsock.threadid) {
- DEBUGLOG("(%p) Waiting for pre&post thread\n", pipe_client);
- pthread_mutex_lock(&thisfd->bits.localsock.mutex);
- thisfd->bits.localsock.state = PRE_COMMAND;
- thisfd->bits.localsock.finished = 1;
- pthread_cond_signal(&thisfd->bits.localsock.cond);
- pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
-
- if ((errno = pthread_join(thisfd->bits.localsock.threadid,
- (void **) &status)))
- log_sys_error("pthread_join", "");
-
- DEBUGLOG("(%p) Joined pre&post thread\n", pipe_client);
-
- thisfd->bits.localsock.threadid = 0;
-
- /* Remove the pipe client */
- if (thisfd->bits.localsock.pipe_client) {
- struct local_client *delfd = thisfd->bits.localsock.pipe_client;
-
- (void) close(delfd->fd); /* Close pipe */
- (void) close(thisfd->bits.localsock.pipe);
-
- /* Remove pipe client */
- if (!_del_client(delfd)) {
- dm_free(delfd);
- thisfd->bits.localsock.pipe_client = NULL;
- }
- }
- }
-
- /* Free the command buffer */
- dm_free(thisfd->bits.localsock.cmd);
-
- safe_close(&(thisfd->fd));
- thisfd->bits.localsock.cleanup_needed = 0;
-
- return 0;
-}
-
-/* Called when we have a read from the local socket.
- was in the main loop but it's grown up and is a big girl now */
-static int read_from_local_sock(struct local_client *thisfd)
-{
- int len;
- int argslen;
- int missing_len;
- char buffer[PIPE_BUF + 1];
- char csid[MAX_CSID_LEN];
- int comms_pipe[2];
- struct local_client *newfd;
- struct clvm_header *inheader = (struct clvm_header *) buffer;
- int status;
-
- len = read(thisfd->fd, buffer, sizeof(buffer) - 1);
- if (len == -1 && errno == EINTR)
- return 1;
-
- DEBUGLOG("(%p) Read on local socket %d, len = %d\n", thisfd, thisfd->fd, len);
-
- if (len && verify_message(buffer, len) < 0) {
- log_error("read_from_local_sock from %d len %d bad verify.",
- thisfd->fd, len);
- dump_message(buffer, len);
- /* force error handling below */
- len = 0;
- }
-
- /* EOF or error on socket */
- if (len <= 0) {
- thisfd->bits.localsock.cleanup_needed = 1;
- (void) cleanup_zombie(thisfd); /* ignore errors here */
- return 0;
- }
-
- buffer[len] = 0; /* Ensure \0 terminated */
-
- /* Fill in the client ID */
- inheader->clientid = htonl(thisfd->fd);
-
- /* If we are already busy then return an error */
- if (thisfd->bits.localsock.in_progress) {
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = EBUSY
- };
- send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
- "Error sending EBUSY reply to local user");
- return len;
- }
-
- /* See if we have the whole message */
- argslen = len - strlen(inheader->node) - sizeof(struct clvm_header);
- missing_len = inheader->arglen - argslen;
-
- if (missing_len < 0)
- missing_len = 0;
-
- /* We need at least sizeof(struct clvm_header) bytes in buffer */
- if (len < (int)sizeof(struct clvm_header) || /* Already handled in verify_message() */
- argslen < 0 || missing_len > MAX_MISSING_LEN) {
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = EINVAL
- };
- send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
- "Error sending EINVAL reply to local user");
- return 0;
- }
-
- /* Free any old buffer space */
- dm_free(thisfd->bits.localsock.cmd);
-
- /* Save the message */
- if (!(thisfd->bits.localsock.cmd = dm_malloc(len + missing_len))) {
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = ENOMEM
- };
- send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
- "Error sending ENOMEM reply to local user");
- return 0;
- }
- memcpy(thisfd->bits.localsock.cmd, buffer, len);
- thisfd->bits.localsock.cmd_len = len + missing_len;
- inheader = (struct clvm_header *) thisfd->bits.localsock.cmd;
-
- /* If we don't have the full message then read the rest now */
- if (missing_len) {
- char *argptr = inheader->node + strlen(inheader->node) + 1;
-
- while (missing_len > 0) {
- DEBUGLOG("(%p) got %d bytes, need another %d (total %d)\n",
- thisfd, argslen, missing_len, inheader->arglen);
- len = read(thisfd->fd, argptr + argslen, missing_len);
- if (len == -1 && errno == EINTR)
- continue;
-
- if (len <= 0) {
- /* EOF or error on socket */
- DEBUGLOG("(%p) EOF on local socket\n", thisfd);
- dm_free(thisfd->bits.localsock.cmd);
- thisfd->bits.localsock.cmd = NULL;
- return 0;
- }
-
- missing_len -= len;
- argslen += len;
- }
- }
-
- /* Only run the command if all the cluster nodes are running CLVMD */
- if (((inheader->flags & CLVMD_FLAG_LOCAL) == 0) &&
- (check_all_clvmds_running(thisfd) == -1)) {
- thisfd->bits.localsock.expected_replies = 0;
- thisfd->bits.localsock.num_replies = 0;
- send_local_reply(thisfd, EHOSTDOWN, thisfd->fd);
- return len;
- }
-
- /* Check the node name for validity */
- if (inheader->node[0] && clops->csid_from_name(csid, inheader->node)) {
- /* Error, node is not in the cluster */
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = ENOENT
- };
-
- DEBUGLOG("(%p) Unknown node: '%s'\n", thisfd, inheader->node);
- send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
- "Error sending ENOENT reply to local user");
- thisfd->bits.localsock.expected_replies = 0;
- thisfd->bits.localsock.num_replies = 0;
- thisfd->bits.localsock.in_progress = FALSE;
- thisfd->bits.localsock.sent_out = FALSE;
- return len;
- }
-
- /* If we already have a subthread then just signal it to start */
- if (thisfd->bits.localsock.threadid) {
- pthread_mutex_lock(&thisfd->bits.localsock.mutex);
- thisfd->bits.localsock.state = PRE_COMMAND;
- pthread_cond_signal(&thisfd->bits.localsock.cond);
- pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
- return len;
- }
-
- /* Create a pipe and add the reading end to our FD list */
- if (pipe(comms_pipe)) {
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = EBUSY
- };
-
- DEBUGLOG("(%p) Creating pipe failed: %s\n", thisfd, strerror(errno));
- send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
- "Error sending EBUSY reply to local user");
- return len;
- }
-
- if (!(newfd = dm_zalloc(sizeof(*newfd)))) {
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = ENOMEM
- };
-
- (void) close(comms_pipe[0]);
- (void) close(comms_pipe[1]);
-
- send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
- "Error sending ENOMEM reply to local user");
- return len;
- }
-
- DEBUGLOG("(%p) Creating pipe, [%d, %d]\n", thisfd, comms_pipe[0], comms_pipe[1]);
-
- if (fcntl(comms_pipe[0], F_SETFD, 1))
- DEBUGLOG("setting CLOEXEC on pipe[0] failed: %s\n", strerror(errno));
- if (fcntl(comms_pipe[1], F_SETFD, 1))
- DEBUGLOG("setting CLOEXEC on pipe[1] failed: %s\n", strerror(errno));
-
- newfd->fd = comms_pipe[0];
- newfd->type = THREAD_PIPE;
- newfd->callback = local_pipe_callback;
- newfd->bits.pipe.client = thisfd;
-
- _add_client(newfd, thisfd);
-
- /* Store a cross link to the pipe */
- thisfd->bits.localsock.pipe_client = newfd;
- thisfd->bits.localsock.pipe = comms_pipe[1];
-
- /* Make sure the thread has a copy of it's own ID */
- newfd->bits.pipe.threadid = thisfd->bits.localsock.threadid;
-
- /* Run the pre routine */
- thisfd->bits.localsock.in_progress = TRUE;
- thisfd->bits.localsock.state = PRE_COMMAND;
- thisfd->bits.localsock.cleanup_needed = 1;
- DEBUGLOG("(%p) Creating pre&post thread for pipe fd %d\n", newfd, newfd->fd);
- status = pthread_create(&thisfd->bits.localsock.threadid,
- &stack_attr, pre_and_post_thread, thisfd);
- DEBUGLOG("(%p) Created pre&post thread, state = %d\n", newfd, status);
-
- return len;
-}
-
-/* Add a file descriptor from the cluster or comms interface to
- our list of FDs for select
-*/
-
-/* Called when the pre-command has completed successfully - we
- now execute the real command on all the requested nodes */
-static int distribute_command(struct local_client *thisfd)
-{
- struct clvm_header *inheader =
- (struct clvm_header *) thisfd->bits.localsock.cmd;
- int len = thisfd->bits.localsock.cmd_len;
-
- thisfd->xid = global_xid++;
- DEBUGLOG("(%p) distribute command: XID = %d, flags=0x%x (%s%s)\n",
- thisfd, thisfd->xid, inheader->flags,
- (inheader->flags & CLVMD_FLAG_LOCAL) ? "LOCAL" : "",
- (inheader->flags & CLVMD_FLAG_REMOTE) ? "REMOTE" : "");
-
- /* Forward it to other nodes in the cluster if needed */
- if (!(inheader->flags & CLVMD_FLAG_LOCAL)) {
- /* if node is empty then do it on the whole cluster */
- if (inheader->node[0] == '\0') {
- thisfd->bits.localsock.expected_replies =
- clops->get_num_nodes();
- thisfd->bits.localsock.num_replies = 0;
- thisfd->bits.localsock.sent_time = time(NULL);
- thisfd->bits.localsock.in_progress = TRUE;
- thisfd->bits.localsock.sent_out = TRUE;
-
- /*
- * Send to local node first, even if CLVMD_FLAG_REMOTE
- * is set so we still get a reply if this is the
- * only node.
- */
- add_to_lvmqueue(thisfd, inheader, len, NULL);
-
- DEBUGLOG("(%p) Sending message to all cluster nodes\n", thisfd);
- inheader->xid = thisfd->xid;
- send_message(inheader, len, NULL, -1,
- "Error forwarding message to cluster");
- } else {
- /* Do it on a single node */
- char csid[MAX_CSID_LEN];
-
- if (clops->csid_from_name(csid, inheader->node))
- /* This has already been checked so should not happen */
- return 0;
-
- /* OK, found a node... */
- thisfd->bits.localsock.in_progress = TRUE;
- thisfd->bits.localsock.expected_replies = 1;
- thisfd->bits.localsock.num_replies = 0;
-
- /* Are we the requested node ?? */
- if (memcmp(csid, our_csid, max_csid_len) == 0) {
- DEBUGLOG("(%p) Doing command on local node only\n", thisfd);
- add_to_lvmqueue(thisfd, inheader, len, NULL);
- } else {
- DEBUGLOG("(%p) Sending message to single node: %s\n",
- thisfd, inheader->node);
- inheader->xid = thisfd->xid;
- send_message(inheader, len, csid, -1,
- "Error forwarding message to cluster node");
- }
- }
- } else {
- /* Local explicitly requested, ignore nodes */
- thisfd->bits.localsock.in_progress = TRUE;
- thisfd->bits.localsock.expected_replies = 1;
- thisfd->bits.localsock.num_replies = 0;
- DEBUGLOG("(%p) Doing command explicitly on local node only\n", thisfd);
- add_to_lvmqueue(thisfd, inheader, len, NULL);
- }
-
- return 0;
-}
-
-/* Process a command from a remote node and return the result */
-static void process_remote_command(struct clvm_header *msg, int msglen, int fd,
- const char *csid)
-{
- char *replyargs;
- char nodename[max_cluster_member_name_len];
- int replylen = 0;
- int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
- int status;
-
- /* Get the node name as we /may/ need it later */
- clops->name_from_csid(csid, nodename);
-
- DEBUGLOG("process_remote_command %s for clientid 0x%x XID %d on node %s\n",
- decode_cmd(msg->cmd), msg->clientid, msg->xid, nodename);
-
- /* Check for GOAWAY and sulk */
- if (msg->cmd == CLVMD_CMD_GOAWAY) {
- DEBUGLOG("Told to go away by %s\n", nodename);
- log_error("Told to go away by %s.", nodename);
- exit(99);
- }
-
- /* Version check is internal - don't bother exposing it in clvmd-command.c */
- if (msg->cmd == CLVMD_CMD_VERSION) {
- int version_nums[3];
- char node[256];
-
- memcpy(version_nums, msg->args, sizeof(version_nums));
-
- clops->name_from_csid(csid, node);
- DEBUGLOG("Remote node %s is version %d.%d.%d\n",
- node, ntohl(version_nums[0]),
- ntohl(version_nums[1]), ntohl(version_nums[2]));
-
- if (ntohl(version_nums[0]) != CLVMD_MAJOR_VERSION) {
- struct clvm_header byebyemsg = {
- .cmd = CLVMD_CMD_GOAWAY
- };
-
- DEBUGLOG("Telling node %s to go away because of incompatible version number\n",
- node);
- log_notice("Telling node %s to go away because of incompatible version number %d.%d.%d\n",
- node, ntohl(version_nums[0]),
- ntohl(version_nums[1]), ntohl(version_nums[2]));
-
- clops->cluster_send_message(&byebyemsg, sizeof(byebyemsg), our_csid,
- "Error Sending GOAWAY message");
- } else
- clops->add_up_node(csid);
-
- return;
- }
-
- /* Allocate a default reply buffer */
- if ((replyargs = dm_malloc(max_cluster_message - sizeof(struct clvm_header))))
- /* Run the command */
- /* FIXME: usage of init_test() is unprotected */
- status = do_command(NULL, msg, msglen, &replyargs,
- buflen, &replylen);
- else
- status = ENOMEM;
-
- /* If it wasn't a reply, then reply */
- if (msg->cmd != CLVMD_CMD_REPLY) {
- char *aggreply;
-
- aggreply = dm_realloc(replyargs, replylen + sizeof(struct clvm_header));
- if (aggreply) {
- struct clvm_header *agghead =
- (struct clvm_header *) aggreply;
-
- replyargs = aggreply;
- /* Move it up so there's room for a header in front of the data */
- memmove(aggreply + offsetof(struct clvm_header, args),
- replyargs, replylen);
-
- agghead->xid = msg->xid;
- agghead->cmd = CLVMD_CMD_REPLY;
- agghead->status = status;
- agghead->flags = 0;
- agghead->clientid = msg->clientid;
- agghead->arglen = replylen;
- agghead->node[0] = '\0';
- send_message(aggreply, sizeof(struct clvm_header) + replylen,
- csid, fd, "Error sending command reply");
- } else {
- /* Return a failure response */
- struct clvm_header reply = {
- .cmd = CLVMD_CMD_REPLY,
- .status = ENOMEM,
- .clientid = msg->clientid
- };
- DEBUGLOG("Error attempting to realloc return buffer\n");
- send_message(&reply, sizeof(reply), csid, fd,
- "Error sending ENOMEM command reply");
- }
- }
-
- dm_free(replyargs);
-}
-
-/* Add a reply to a command to the list of replies for this client.
- If we have got a full set then send them to the waiting client down the local
- socket */
-static void add_reply_to_list(struct local_client *client, int status,
- const char *csid, const char *buf, int len)
-{
- struct node_reply *reply;
-
- /* Add it to the list of replies */
- if (!(reply = dm_zalloc(sizeof(*reply)))) {
- /* It's all gone horribly wrong... */
- send_local_reply(client, ENOMEM, client->fd);
- return;
- }
-
- reply->status = status;
- clops->name_from_csid(csid, reply->node);
- DEBUGLOG("(%p) Reply from node %s: %d bytes\n", client, reply->node, len);
-
- if (len > 0) {
- if (!(reply->replymsg = dm_malloc(len)))
- reply->status = ENOMEM;
- else
- memcpy(reply->replymsg, buf, len);
- } else
- reply->replymsg = NULL;
-
- pthread_mutex_lock(&client->bits.localsock.mutex);
-
- if (client->bits.localsock.finished) {
- dm_free(reply->replymsg);
- dm_free(reply);
- } else {
- /* Hook it onto the reply chain */
- reply->next = client->bits.localsock.replies;
- client->bits.localsock.replies = reply;
-
- /* If we have the whole lot then do the post-process */
- /* Post-process the command */
- if (++client->bits.localsock.num_replies ==
- client->bits.localsock.expected_replies) {
- client->bits.localsock.state = POST_COMMAND;
- pthread_cond_signal(&client->bits.localsock.cond);
- }
- DEBUGLOG("(%p) Got %d replies, expecting: %d\n",
- client, client->bits.localsock.num_replies,
- client->bits.localsock.expected_replies);
- }
- pthread_mutex_unlock(&client->bits.localsock.mutex);
-}
-
-/* This is the thread that runs the PRE and post commands for a particular connection */
-static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
-{
- struct local_client *client = (struct local_client *) arg;
- int status;
- int write_status;
- sigset_t ss;
- int pipe_fd = client->bits.localsock.pipe;
-
- DEBUGLOG("(%p) Pre&post thread pipe fd %d\n", client, pipe_fd);
- pthread_mutex_lock(&client->bits.localsock.mutex);
-
- /* Ignore SIGUSR1 (handled by master process) but enable
- SIGUSR2 (kills subthreads) */
- sigemptyset(&ss);
- sigaddset(&ss, SIGUSR1);
- pthread_sigmask(SIG_BLOCK, &ss, NULL);
-
- sigdelset(&ss, SIGUSR1);
- sigaddset(&ss, SIGUSR2);
- pthread_sigmask(SIG_UNBLOCK, &ss, NULL);
-
- /* Loop around doing PRE and POST functions until the client goes away */
- while (!client->bits.localsock.finished) {
- /* Execute the code */
- /* FIXME: usage of init_test() is unprotected as in do_command() */
- if ((status = do_pre_command(client)))
- client->bits.localsock.all_success = 0;
-
- DEBUGLOG("(%p) Pre&post thread writes status %d down to pipe fd %d\n",
- client, status, pipe_fd);
-
- /* Tell the parent process we have finished this bit */
- while ((write_status = write(pipe_fd, &status, sizeof(int))) != sizeof(int))
- if (write_status >=0 || (errno != EINTR && errno != EAGAIN)) {
- log_error("Error sending to pipe: %m");
- break;
- }
-
- if (status) {
- client->bits.localsock.state = POST_COMMAND;
- goto next_pre;
- }
-
- /* We may need to wait for the condition variable before running the post command */
- if (client->bits.localsock.state != POST_COMMAND &&
- !client->bits.localsock.finished) {
- DEBUGLOG("(%p) Pre&post thread waiting to do post command, state = %d\n",
- client, client->bits.localsock.state);
- pthread_cond_wait(&client->bits.localsock.cond,
- &client->bits.localsock.mutex);
- }
-
- DEBUGLOG("(%p) Pre&post thread got post command condition...\n", client);
-
- /* POST function must always run, even if the client aborts */
- status = 0;
- do_post_command(client);
-
- while ((write_status = write(pipe_fd, &status, sizeof(int))) != sizeof(int))
- if (write_status >=0 || (errno != EINTR && errno != EAGAIN)) {
- log_error("Error sending to pipe: %m");
- break;
- }
-next_pre:
- if (client->bits.localsock.state != PRE_COMMAND &&
- !client->bits.localsock.finished) {
- DEBUGLOG("(%p) Pre&post thread waiting for next pre command\n", client);
- pthread_cond_wait(&client->bits.localsock.cond,
- &client->bits.localsock.mutex);
- }
-
- DEBUGLOG("(%p) Pre&post thread got pre command condition...\n", client);
- }
- pthread_mutex_unlock(&client->bits.localsock.mutex);
- DEBUGLOG("(%p) Pre&post thread finished\n", client);
-
- pthread_exit(NULL);
-}
-
-/* Process a command on the local node and store the result */
-static int process_local_command(struct clvm_header *msg, int msglen,
- struct local_client *client,
- unsigned short xid)
-{
- char *replybuf;
- int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
- int replylen = 0;
- int status;
-
- if (!(replybuf = dm_malloc(max_cluster_message)))
- return -1;
-
- DEBUGLOG("(%p) process_local_command: %s msg=%p, msglen =%d\n",
- client, decode_cmd(msg->cmd), msg, msglen);
-
- /* If remote flag is set, just set a successful status code. */
- if (msg->flags & CLVMD_FLAG_REMOTE)
- status = 0;
- else
- status = do_command(client, msg, msglen, &replybuf, buflen, &replylen);
-
- if (status)
- client->bits.localsock.all_success = 0;
-
- /* If we took too long then discard the reply */
- if (xid == client->xid)
- add_reply_to_list(client, status, our_csid, replybuf, replylen);
- else
- DEBUGLOG("(%p) Local command took too long, discarding xid %d, current is %d\n",
- client, xid, client->xid);
-
- dm_free(replybuf);
-
- return status;
-}
-
-static int process_reply(const struct clvm_header *msg, int msglen, const char *csid)
-{
- struct local_client *client;
-
- if (!(client = find_client(msg->clientid))) {
- DEBUGLOG("Got message for unknown client 0x%x\n",
- msg->clientid);
- log_error("Got message for unknown client 0x%x.",
- msg->clientid);
- return -1;
- }
-
- if (msg->status)
- client->bits.localsock.all_success = 0;
-
- /* Gather replies together for this client id */
- if (msg->xid == client->xid)
- add_reply_to_list(client, msg->status, csid, msg->args,
- msg->arglen);
- else
- DEBUGLOG("Discarding reply with old XID %d, current = %d\n",
- msg->xid, client->xid);
-
- return 0;
-}
-
-/* Send an aggregated reply back to the client */
-static void send_local_reply(struct local_client *client, int status, int fd)
-{
- struct clvm_header *clientreply;
- struct node_reply *thisreply = client->bits.localsock.replies;
- char *replybuf;
- char *ptr;
- int message_len = 0;
-
- DEBUGLOG("(%p) Send local reply\n", client);
-
- /* Work out the total size of the reply */
- while (thisreply) {
- if (thisreply->replymsg)
- message_len += strlen(thisreply->replymsg) + 1;
- else
- message_len++;
-
- message_len += strlen(thisreply->node) + 1 + sizeof(int);
-
- thisreply = thisreply->next;
- }
-
- /* Add in the size of our header */
- message_len = message_len + sizeof(struct clvm_header);
- if (!(replybuf = dm_malloc(message_len))) {
- DEBUGLOG("(%p) Memory allocation fails\n", client);
- return;
- }
-
- clientreply = (struct clvm_header *) replybuf;
- clientreply->status = status;
- clientreply->cmd = CLVMD_CMD_REPLY;
- clientreply->node[0] = '\0';
- clientreply->xid = 0;
- clientreply->clientid = 0;
- clientreply->flags = 0;
-
- ptr = clientreply->args;
-
- /* Add in all the replies, and free them as we go */
- thisreply = client->bits.localsock.replies;
- while (thisreply) {
- struct node_reply *tempreply = thisreply;
-
- strcpy(ptr, thisreply->node);
- ptr += strlen(thisreply->node) + 1;
-
- if (thisreply->status)
- clientreply->flags |= CLVMD_FLAG_NODEERRS;
-
- memcpy(ptr, &thisreply->status, sizeof(int));
- ptr += sizeof(int);
-
- if (thisreply->replymsg) {
- strcpy(ptr, thisreply->replymsg);
- ptr += strlen(thisreply->replymsg) + 1;
- } else {
- ptr[0] = '\0';
- ptr++;
- }
- thisreply = thisreply->next;
-
- dm_free(tempreply->replymsg);
- dm_free(tempreply);
- }
-
- /* Terminate with an empty node name */
- *ptr = '\0';
-
- clientreply->arglen = ptr - clientreply->args;
-
- /* And send it */
- send_message(replybuf, message_len, our_csid, fd,
- "Error sending REPLY to client");
- dm_free(replybuf);
-
- /* Reset comms variables */
- client->bits.localsock.replies = NULL;
- client->bits.localsock.expected_replies = 0;
- client->bits.localsock.in_progress = FALSE;
- client->bits.localsock.sent_out = FALSE;
-}
-
-/* Just free a reply chain baceuse it wasn't used. */
-static void free_reply(struct local_client *client)
-{
- /* Add in all the replies, and free them as we go */
- struct node_reply *thisreply = client->bits.localsock.replies;
- while (thisreply) {
- struct node_reply *tempreply = thisreply;
-
- thisreply = thisreply->next;
-
- dm_free(tempreply->replymsg);
- dm_free(tempreply);
- }
- client->bits.localsock.replies = NULL;
-}
-
-/* Send our version number to the cluster */
-static void send_version_message(void)
-{
- char message[sizeof(struct clvm_header) + sizeof(int) * 3];
- struct clvm_header *msg = (struct clvm_header *) message;
- int version_nums[3] = {
- htonl(CLVMD_MAJOR_VERSION),
- htonl(CLVMD_MINOR_VERSION),
- htonl(CLVMD_PATCH_VERSION)
- };
-
- msg->cmd = CLVMD_CMD_VERSION;
- msg->status = 0;
- msg->flags = 0;
- msg->clientid = 0;
- msg->arglen = sizeof(version_nums);
-
- memcpy(&msg->args, version_nums, sizeof(version_nums));
-
- hton_clvm(msg);
-
- clops->cluster_send_message(message, sizeof(message), NULL,
- "Error Sending version number");
-}
-
-/* Send a message to either a local client or another server */
-static int send_message(void *buf, int msglen, const char *csid, int fd,
- const char *errtext)
-{
- int len = 0;
- int ptr;
- struct timespec delay;
- struct timespec remtime;
- int retry_cnt = 0;
-
- /* Send remote messages down the cluster socket */
- if (!csid || !ISLOCAL_CSID(csid)) {
- hton_clvm((struct clvm_header *) buf);
- return clops->cluster_send_message(buf, msglen, csid, errtext);
- }
-
- if (fd < 0)
- return 0;
-
- /* Make sure it all goes */
- for (ptr = 0; ptr < msglen;) {
- if ((len = write(fd, (char*)buf + ptr, msglen - ptr)) <= 0) {
- if (errno == EINTR)
- continue;
- if ((errno == EAGAIN || errno == EIO || errno == ENOSPC) &&
- ++retry_cnt < MAX_RETRIES) {
- delay.tv_sec = 0;
- delay.tv_nsec = 100000;
- remtime.tv_sec = 0;
- remtime.tv_nsec = 0;
- (void) nanosleep (&delay, &remtime);
- continue;
- }
- DEBUGLOG("%s", errtext);
- log_error("%s", errtext);
- break;
- }
- ptr += len;
- }
-
- return len;
-}
-
-static int process_work_item(struct lvm_thread_cmd *cmd)
-{
- /* If msg is NULL then this is a cleanup request */
- if (cmd->msg == NULL) {
- DEBUGLOG("(%p) process_work_item: free\n", cmd->client);
- cmd_client_cleanup(cmd->client);
- pthread_mutex_destroy(&cmd->client->bits.localsock.mutex);
- pthread_cond_destroy(&cmd->client->bits.localsock.cond);
- dm_free(cmd->client);
- return 0;
- }
-
- if (!cmd->remote) {
- DEBUGLOG("(%p) process_work_item: local\n", cmd->client);
- process_local_command(cmd->msg, cmd->msglen, cmd->client,
- cmd->xid);
- } else {
- DEBUGLOG("(%p) process_work_item: remote\n", cmd->client);
- process_remote_command(cmd->msg, cmd->msglen, cmd->client->fd,
- cmd->csid);
- }
-
- return 0;
-}
-
-/*
- * Routine that runs in the "LVM thread".
- */
-static void *lvm_thread_fn(void *arg)
-{
- sigset_t ss;
- struct lvm_startup_params *lvm_params = arg;
- struct lvm_thread_cmd *cmd;
-
- DEBUGLOG("LVM thread function started\n");
-
- /* Ignore SIGUSR1 & 2 */
- sigemptyset(&ss);
- sigaddset(&ss, SIGUSR1);
- sigaddset(&ss, SIGUSR2);
- pthread_sigmask(SIG_BLOCK, &ss, NULL);
-
- /* Initialise the interface to liblvm */
- init_clvm(lvm_params->excl_uuid);
-
- /* Allow others to get moving */
- pthread_barrier_wait(&lvm_start_barrier);
- DEBUGLOG("LVM thread ready for work.\n");
-
- /* Now wait for some actual work */
- pthread_mutex_lock(&lvm_thread_mutex);
-
- for (;;) {
- while (!dm_list_empty(&lvm_cmd_head)) {
- cmd = dm_list_item(dm_list_first(&lvm_cmd_head),
- struct lvm_thread_cmd);
- dm_list_del(&cmd->list);
- pthread_mutex_unlock(&lvm_thread_mutex);
-
- process_work_item(cmd);
- dm_free(cmd->msg);
- dm_free(cmd);
-
- pthread_mutex_lock(&lvm_thread_mutex);
- }
-
- if (lvm_thread_exit)
- break;
-
- DEBUGLOG("LVM thread waiting for work\n");
- pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
- }
-
- pthread_mutex_unlock(&lvm_thread_mutex);
- DEBUGLOG("LVM thread exits\n");
-
- destroy_lvm();
-
- pthread_exit(NULL);
-}
-
-/* Pass down some work to the LVM thread */
-static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
- int msglen, const char *csid)
-{
- struct lvm_thread_cmd *cmd;
-
- if (!(cmd = dm_malloc(sizeof(*cmd))))
- return ENOMEM;
-
- if (msglen) {
- if (!(cmd->msg = dm_malloc(msglen))) {
- log_error("Unable to allocate buffer space.");
- dm_free(cmd);
- return -1;
- }
- memcpy(cmd->msg, msg, msglen);
- }
- else
- cmd->msg = NULL;
-
- cmd->client = client;
- cmd->msglen = msglen;
- cmd->xid = client->xid;
-
- if (csid) {
- memcpy(cmd->csid, csid, max_csid_len);
- cmd->remote = 1;
- } else
- cmd->remote = 0;
-
- DEBUGLOG("(%p) add_to_lvmqueue: cmd=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
- client, cmd, msg, msglen, csid, cmd->xid);
- pthread_mutex_lock(&lvm_thread_mutex);
- if (lvm_thread_exit) {
- pthread_mutex_unlock(&lvm_thread_mutex);
- dm_free(cmd->msg);
- dm_free(cmd);
- return -1; /* We are about to exit */
- }
- dm_list_add(&lvm_cmd_head, &cmd->list);
- pthread_cond_signal(&lvm_thread_cond);
- pthread_mutex_unlock(&lvm_thread_mutex);
-
- return 0;
-}
-
-/* Return 0 if we can talk to an existing clvmd */
-/*
- * FIXME:
- *
- * This function returns only -1 or 0, but there are
- * different levels of errors, some of them should stop
- * further execution of clvmd thus another state is needed
- * and some error message need to be only informational.
- */
-static int check_local_clvmd(void)
-{
- int local_socket;
- int ret = 0;
- struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
-
- if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
- log_error("%s: clvmd socket name too long.", CLVMD_SOCKNAME);
- return -1;
- }
-
- /* Open local socket */
- if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
- log_sys_error("socket", "local socket");
- return -1;
- }
-
- if (connect(local_socket,(struct sockaddr *) &sockaddr,
- sizeof(sockaddr))) {
- /* connection failure is expected state */
- if (errno == ENOENT)
- log_sys_debug("connect", "local socket");
- else
- log_sys_error("connect", "local socket");
- ret = -1;
- }
-
- if (close(local_socket))
- log_sys_error("close", "local socket");
-
- return ret;
-}
-
-static void close_local_sock(int local_socket)
-{
- if (local_socket != -1 && close(local_socket))
- log_sys_error("close", CLVMD_SOCKNAME);
-
- if (CLVMD_SOCKNAME[0] != '\0' && unlink(CLVMD_SOCKNAME))
- stack;
-}
-
-/* Open the local socket, that's the one we talk to libclvm down */
-static int open_local_sock(void)
-{
- mode_t old_mask;
- int local_socket = -1;
- struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
-
- if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
- log_error("%s: clvmd socket name too long.", CLVMD_SOCKNAME);
- return -1;
- }
-
- close_local_sock(local_socket);
-
- (void) dm_prepare_selinux_context(CLVMD_SOCKNAME, S_IFSOCK);
- old_mask = umask(0077);
-
- /* Open local socket */
- if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
- log_error("Can't create local socket: %m");
- goto error;
- }
-
- /* Set Close-on-exec & non-blocking */
- if (fcntl(local_socket, F_SETFD, 1))
- DEBUGLOG("setting CLOEXEC on local_socket failed: %s\n", strerror(errno));
- if (fcntl(local_socket, F_SETFL, fcntl(local_socket, F_GETFL, 0) | O_NONBLOCK))
- DEBUGLOG("setting O_NONBLOCK on local_socket failed: %s\n", strerror(errno));
-
-
- if (bind(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
- log_error("can't bind local socket: %m");
- goto error;
- }
- if (listen(local_socket, 1) != 0) {
- log_error("listen local: %m");
- goto error;
- }
-
- umask(old_mask);
- (void) dm_prepare_selinux_context(NULL, 0);
- return local_socket;
-error:
- close_local_sock(local_socket);
- umask(old_mask);
- (void) dm_prepare_selinux_context(NULL, 0);
- return -1;
-}
-
-void process_message(struct local_client *client, char *buf, int len,
- const char *csid)
-{
- char nodename[max_cluster_member_name_len];
- struct clvm_header *inheader = (struct clvm_header *) buf;
- ntoh_clvm(inheader); /* Byteswap fields */
-
- if (verify_message(buf, len) < 0) {
- clops->name_from_csid(csid, nodename);
- log_error("process_message from %s len %d bad verify.", nodename, len);
- dump_message(buf, len);
- return;
- }
-
- if (inheader->cmd == CLVMD_CMD_REPLY)
- process_reply(inheader, len, csid);
- else
- add_to_lvmqueue(client, inheader, len, csid);
-}
-
-
-static void check_all_callback(struct local_client *client, const char *csid,
- int node_up)
-{
- if (!node_up)
- add_reply_to_list(client, EHOSTDOWN, csid, "CLVMD not running", 18);
-}
-
-/* Check to see if all CLVMDs are running (ie one on
- every node in the cluster).
- If not, returns -1 and prints out a list of errant nodes */
-static int check_all_clvmds_running(struct local_client *client)
-{
- DEBUGLOG("(%p) check_all_clvmds_running\n", client);
-
- return clops->cluster_do_node_callback(client, check_all_callback);
-}
-
-/* Return a local_client struct given a client ID.
- client IDs are in network byte order */
-static struct local_client *find_client(int clientid)
-{
- struct local_client *thisfd;
-
- for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next)
- if (thisfd->fd == (int)ntohl(clientid))
- return thisfd;
-
- return NULL;
-}
-
-/* Byte-swapping routines for the header so we
- work in a heterogeneous environment */
-static void hton_clvm(struct clvm_header *hdr)
-{
- hdr->status = htonl(hdr->status);
- hdr->arglen = htonl(hdr->arglen);
- hdr->xid = htons(hdr->xid);
- /* Don't swap clientid as it's only a token as far as
- remote nodes are concerned */
-}
-
-static void ntoh_clvm(struct clvm_header *hdr)
-{
- hdr->status = ntohl(hdr->status);
- hdr->arglen = ntohl(hdr->arglen);
- hdr->xid = ntohs(hdr->xid);
-}
-
-/* Handler for SIGUSR2 - sent to kill subthreads */
-static void sigusr2_handler(int sig)
-{
- DEBUGLOG("SIGUSR2 received\n");
-}
-
-static void sigterm_handler(int sig)
-{
- quit = 1;
-}
-
-static void sighup_handler(int sig)
-{
- reread_config = 1;
-}
-
-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);
-}
-
-static if_type_t parse_cluster_interface(char *ifname)
-{
- if_type_t iface = IF_AUTO;
-
- if (!strcmp(ifname, "auto"))
- iface = IF_AUTO;
- else if (!strcmp(ifname, "cman"))
- iface = IF_CMAN;
- else if (!strcmp(ifname, "openais"))
- iface = IF_OPENAIS;
- else if (!strcmp(ifname, "corosync"))
- iface = IF_COROSYNC;
- else if (!strcmp(ifname, "singlenode"))
- iface = IF_SINGLENODE;
-
- return iface;
-}
-
-/*
- * Try and find a cluster system in corosync's objdb, if it is running. This is
- * only called if the command-line option is not present, and if it fails
- * we still try the interfaces in order.
- */
-static if_type_t get_cluster_type(void)
-{
-#ifdef HAVE_COROSYNC_CONFDB_H
- confdb_handle_t handle;
- if_type_t type = IF_AUTO;
- int result;
- char buf[255];
- size_t namelen = sizeof(buf);
- hdb_handle_t cluster_handle;
- hdb_handle_t clvmd_handle;
- confdb_callbacks_t callbacks = { 0 };
-
- result = confdb_initialize (&handle, &callbacks);
- if (result != CS_OK)
- return type;
-
- result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
- if (result != CS_OK)
- goto out;
-
- result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
- if (result != CS_OK)
- goto out;
-
- result = confdb_object_find_start(handle, cluster_handle);
- if (result != CS_OK)
- goto out;
-
- result = confdb_object_find(handle, cluster_handle, (void *)"clvmd", strlen("clvmd"), &clvmd_handle);
- if (result != CS_OK)
- goto out;
-
- result = confdb_key_get(handle, clvmd_handle, (void *)"interface", strlen("interface"), buf, &namelen);
- if (result != CS_OK)
- goto out;
-
- if (namelen >= sizeof(buf))
- namelen = sizeof(buf) - 1;
-
- buf[namelen] = '\0';
- type = parse_cluster_interface(buf);
- DEBUGLOG("got interface type '%s' from confdb\n", buf);
-out:
- confdb_finalize(handle);
- return type;
-#else
- return IF_AUTO;
-#endif
-}
diff --git a/daemons/clvmd/clvmd.h b/daemons/clvmd/clvmd.h
deleted file mode 100644
index edaee8872..000000000
--- a/daemons/clvmd/clvmd.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2002-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CLVMD_H
-#define _CLVMD_H
-
-#define CLVMD_MAJOR_VERSION 0
-#define CLVMD_MINOR_VERSION 2
-#define CLVMD_PATCH_VERSION 1
-
-/* Default time (in seconds) we will wait for all remote commands to execute
- before declaring them dead */
-#define DEFAULT_CMD_TIMEOUT 60
-
-/* One of these for each reply we get from command execution on a node */
-struct node_reply {
- char node[MAX_CLUSTER_MEMBER_NAME_LEN];
- char *replymsg;
- int status;
- struct node_reply *next;
-};
-
-typedef enum {DEBUG_OFF, DEBUG_STDERR, DEBUG_SYSLOG} debug_t;
-
-/*
- * These exist for the use of local sockets only when we are
- * collecting responses from all cluster nodes
- */
-struct localsock_bits {
- struct node_reply *replies;
- int num_replies;
- int expected_replies;
- time_t sent_time; /* So we can check for timeouts */
- int in_progress; /* Only execute one cmd at a time per client */
- int sent_out; /* Flag to indicate that a command was sent
- to remote nodes */
- void *private; /* Private area for command processor use */
- void *cmd; /* Whole command as passed down local socket */
- int cmd_len; /* Length of above */
- int pipe; /* Pipe to send PRE completion status down */
- int finished; /* Flag to tell subthread to exit */
- int all_success; /* Set to 0 if any node (or the pre_command)
- failed */
- int cleanup_needed; /* helper for cleanup_zombie */
- struct local_client *pipe_client;
- pthread_t threadid;
- enum { PRE_COMMAND, POST_COMMAND } state;
- pthread_mutex_t mutex; /* Main thread and worker synchronisation */
- pthread_cond_t cond;
-};
-
-/* Entries for PIPE clients */
-struct pipe_bits {
- struct local_client *client; /* Actual (localsock) client */
- pthread_t threadid; /* Our own copy of the thread id */
-};
-
-/* Entries for Network socket clients */
-struct netsock_bits {
- void *private;
- int flags;
-};
-
-typedef int (*fd_callback_t) (struct local_client * fd, char *buf, int len,
- const char *csid,
- struct local_client ** new_client);
-
-/* One of these for each fd we are listening on */
-struct local_client {
- int fd;
- enum { CLUSTER_MAIN_SOCK, CLUSTER_DATA_SOCK, LOCAL_RENDEZVOUS,
- LOCAL_SOCK, THREAD_PIPE, CLUSTER_INTERNAL } type;
- struct local_client *next;
- unsigned short xid;
- fd_callback_t callback;
- uint8_t removeme;
-
- union {
- struct localsock_bits localsock;
- struct pipe_bits pipe;
- struct netsock_bits net;
- } bits;
-};
-
-#define DEBUGLOG(fmt, args...) debuglog(fmt, ## args)
-
-#ifndef max
-#define max(a,b) ((a)>(b)?(a):(b))
-#endif
-
-/* The real command processor is in clvmd-command.c */
-extern int do_command(struct local_client *client, struct clvm_header *msg,
- int msglen, char **buf, int buflen, int *retlen);
-
-/* Pre and post command routines are called only on the local node */
-extern int do_pre_command(struct local_client *client);
-extern int do_post_command(struct local_client *client);
-extern void cmd_client_cleanup(struct local_client *client);
-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, const char *csid);
-extern void debuglog(const char *fmt, ... )
- __attribute__ ((format(printf, 1, 2)));
-
-void clvmd_set_debug(debug_t new_de);
-debug_t clvmd_get_debug(void);
-int clvmd_get_foreground(void);
-
-int sync_lock(const char *resource, int mode, int flags, int *lockid);
-int sync_unlock(const char *resource, int lockid);
-
-#endif
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
deleted file mode 100644
index ed829594a..000000000
--- a/daemons/clvmd/lvm-functions.c
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "clvmd-common.h"
-
-#include <pthread.h>
-
-#include "daemons/clvmd/clvm.h"
-#include "clvmd-comms.h"
-#include "clvmd.h"
-#include "lvm-functions.h"
-
-/* LVM2 headers */
-#include "lib/commands/toolcontext.h"
-#include "lib/cache/lvmcache.h"
-#include "lib/misc/lvm-globals.h"
-#include "lib/activate/activate.h"
-#include "lib/format_text/archiver.h"
-#include "lib/mm/memlock.h"
-
-#include <syslog.h>
-
-static struct cmd_context *cmd = NULL;
-static struct dm_hash_table *lv_hash = NULL;
-static pthread_mutex_t lv_hash_lock;
-static pthread_mutex_t lvm_lock;
-static char last_error[1024];
-
-struct lv_info {
- int lock_id;
- int lock_mode;
-};
-
-static const char *decode_full_locking_cmd(uint32_t cmdl)
-{
- static char buf[128];
- const char *type;
- const char *scope;
- const char *command;
-
- switch (cmdl & LCK_TYPE_MASK) {
- case LCK_NULL:
- type = "NULL";
- break;
- case LCK_READ:
- type = "READ";
- break;
- case LCK_PREAD:
- type = "PREAD";
- break;
- case LCK_WRITE:
- type = "WRITE";
- break;
- case LCK_EXCL:
- type = "EXCL";
- break;
- case LCK_UNLOCK:
- type = "UNLOCK";
- break;
- default:
- type = "unknown";
- break;
- }
-
- switch (cmdl & LCK_SCOPE_MASK) {
- case LCK_VG:
- scope = "VG";
- command = "LCK_VG";
- break;
- case LCK_LV:
- scope = "LV";
- switch (cmdl & LCK_MASK) {
- case LCK_LV_EXCLUSIVE & LCK_MASK:
- command = "LCK_LV_EXCLUSIVE";
- break;
- case LCK_LV_SUSPEND & LCK_MASK:
- command = "LCK_LV_SUSPEND";
- break;
- case LCK_LV_RESUME & LCK_MASK:
- command = "LCK_LV_RESUME";
- break;
- case LCK_LV_ACTIVATE & LCK_MASK:
- command = "LCK_LV_ACTIVATE";
- break;
- case LCK_LV_DEACTIVATE & LCK_MASK:
- command = "LCK_LV_DEACTIVATE";
- break;
- default:
- command = "unknown";
- break;
- }
- break;
- default:
- scope = "unknown";
- command = "unknown";
- break;
- }
-
- sprintf(buf, "0x%x %s (%s|%s%s%s%s%s)", cmdl, command, type, scope,
- cmdl & LCK_NONBLOCK ? "|NONBLOCK" : "",
- cmdl & LCK_HOLD ? "|HOLD" : "",
- cmdl & LCK_CLUSTER_VG ? "|CLUSTER_VG" : "",
- cmdl & LCK_CACHE ? "|CACHE" : "");
-
- return buf;
-}
-
-/*
- * Only processes 8 bits: excludes LCK_CACHE.
- */
-static const char *decode_locking_cmd(unsigned char cmdl)
-{
- return decode_full_locking_cmd((uint32_t) cmdl);
-}
-
-static const char *decode_flags(unsigned char flags)
-{
- static char buf[128];
- int len;
-
- len = sprintf(buf, "0x%x ( %s%s%s%s%s%s%s%s)", flags,
- flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE|" : "",
- flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC|" : "",
- flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR|" : "",
- flags & LCK_ORIGIN_ONLY_MODE ? "ORIGIN_ONLY|" : "",
- flags & LCK_TEST_MODE ? "TEST|" : "",
- flags & LCK_CONVERT_MODE ? "CONVERT|" : "",
- flags & LCK_DMEVENTD_MONITOR_IGNORE ? "DMEVENTD_MONITOR_IGNORE|" : "",
- flags & LCK_REVERT_MODE ? "REVERT|" : "");
-
- if (len > 1)
- buf[len - 2] = ' ';
- else
- buf[0] = '\0';
-
- return buf;
-}
-
-char *get_last_lvm_error(void)
-{
- return last_error;
-}
-
-/*
- * Hash lock info helpers
- */
-static struct lv_info *lookup_info(const char *resource)
-{
- struct lv_info *lvi;
-
- pthread_mutex_lock(&lv_hash_lock);
- lvi = dm_hash_lookup(lv_hash, resource);
- pthread_mutex_unlock(&lv_hash_lock);
-
- return lvi;
-}
-
-static int insert_info(const char *resource, struct lv_info *lvi)
-{
- int ret;
-
- pthread_mutex_lock(&lv_hash_lock);
- ret = dm_hash_insert(lv_hash, resource, lvi);
- pthread_mutex_unlock(&lv_hash_lock);
-
- return ret;
-}
-
-static void remove_info(const char *resource)
-{
- int num_open;
-
- pthread_mutex_lock(&lv_hash_lock);
- dm_hash_remove(lv_hash, resource);
-
- /* When last lock is remove, validate there are not left opened devices */
- if (!dm_hash_get_first(lv_hash)) {
- if (critical_section())
- log_error(INTERNAL_ERROR "No volumes are locked however clvmd is in activation mode critical section.");
- if ((num_open = dev_cache_check_for_open_devices()))
- log_error(INTERNAL_ERROR "No volumes are locked however %d devices are still open.", num_open);
- }
-
- pthread_mutex_unlock(&lv_hash_lock);
-}
-
-/*
- * Return the mode a lock is currently held at (or -1 if not held)
- */
-static int get_current_lock(char *resource)
-{
- struct lv_info *lvi;
-
- if ((lvi = lookup_info(resource)))
- return lvi->lock_mode;
-
- return -1;
-}
-
-
-void init_lvhash(void)
-{
- /* Create hash table for keeping LV locks & status */
- lv_hash = dm_hash_create(1024);
- pthread_mutex_init(&lv_hash_lock, NULL);
- pthread_mutex_init(&lvm_lock, NULL);
-}
-
-/* Called at shutdown to tidy the lockspace */
-void destroy_lvhash(void)
-{
- struct dm_hash_node *v;
- struct lv_info *lvi;
- char *resource;
- int status;
-
- pthread_mutex_lock(&lv_hash_lock);
-
- dm_hash_iterate(v, lv_hash) {
- lvi = dm_hash_get_data(lv_hash, v);
- resource = dm_hash_get_key(lv_hash, v);
-
- if ((status = sync_unlock(resource, lvi->lock_id)))
- DEBUGLOG("unlock_all. unlock failed(%d): %s\n",
- status, strerror(errno));
- dm_free(lvi);
- }
-
- dm_hash_destroy(lv_hash);
- lv_hash = NULL;
-
- pthread_mutex_unlock(&lv_hash_lock);
-}
-
-/* Gets a real lock and keeps the info in the hash table */
-static int hold_lock(char *resource, int mode, int flags)
-{
- int status;
- int saved_errno;
- struct lv_info *lvi;
-
- /* Mask off invalid options */
- flags &= LCKF_NOQUEUE | LCKF_CONVERT;
-
- lvi = lookup_info(resource);
-
- if (lvi) {
- if (lvi->lock_mode == mode) {
- DEBUGLOG("hold_lock, lock mode %d already held\n",
- mode);
- return 0;
- }
- if ((lvi->lock_mode == LCK_EXCL) && (mode == LCK_WRITE)) {
- DEBUGLOG("hold_lock, lock already held LCK_EXCL, "
- "ignoring LCK_WRITE request\n");
- return 0;
- }
- }
-
- /* Only allow explicit conversions */
- if (lvi && !(flags & LCKF_CONVERT)) {
- errno = EBUSY;
- return -1;
- }
- if (lvi) {
- /* Already exists - convert it */
- status = sync_lock(resource, mode, flags, &lvi->lock_id);
- saved_errno = errno;
- if (!status)
- lvi->lock_mode = mode;
- else
- DEBUGLOG("hold_lock. convert to %d failed: %s\n", mode,
- strerror(errno));
- errno = saved_errno;
- } else {
- if (!(lvi = dm_malloc(sizeof(struct lv_info)))) {
- errno = ENOMEM;
- return -1;
- }
-
- lvi->lock_mode = mode;
- lvi->lock_id = 0;
- status = sync_lock(resource, mode, flags & ~LCKF_CONVERT, &lvi->lock_id);
- saved_errno = errno;
- if (status) {
- dm_free(lvi);
- DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode,
- strerror(errno));
- } else
- if (!insert_info(resource, lvi)) {
- errno = ENOMEM;
- return -1;
- }
-
- errno = saved_errno;
- }
- return status;
-}
-
-/* Unlock and remove it from the hash table */
-static int hold_unlock(char *resource)
-{
- struct lv_info *lvi;
- int status;
- int saved_errno;
-
- if (!(lvi = lookup_info(resource))) {
- DEBUGLOG("hold_unlock, lock not already held\n");
- return 0;
- }
-
- status = sync_unlock(resource, lvi->lock_id);
- saved_errno = errno;
- if (!status) {
- remove_info(resource);
- dm_free(lvi);
- } else {
- DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status,
- strerror(errno));
- }
-
- errno = saved_errno;
- return status;
-}
-
-/* Watch the return codes here.
- liblvm API functions return 1(true) for success, 0(false) for failure and don't set errno.
- libdlm API functions return 0 for success, -1 for failure and do set errno.
- These functions here return 0 for success or >0 for failure (where the retcode is errno)
-*/
-
-/* Activate LV exclusive or non-exclusive */
-static int do_activate_lv(char *resource, unsigned char command, unsigned char lock_flags, int mode)
-{
- int oldmode;
- int status;
- int activate_lv;
- int exclusive = 0;
- struct lvinfo lvi;
-
- /* Is it already open ? */
- oldmode = get_current_lock(resource);
- if (oldmode == mode && (command & LCK_CLUSTER_VG)) {
- DEBUGLOG("do_activate_lv, lock already held at %d\n", oldmode);
- return 0; /* Nothing to do */
- }
-
- /* Does the config file want us to activate this LV ? */
- if (!lv_activation_filter(cmd, resource, &activate_lv, NULL))
- return EIO;
-
- if (!activate_lv)
- return 0; /* Success, we did nothing! */
-
- /* Do we need to activate exclusively? */
- if ((activate_lv == 2) || (mode == LCK_EXCL)) {
- exclusive = 1;
- mode = LCK_EXCL;
- }
-
- /*
- * Try to get the lock if it's a clustered volume group.
- * Use lock conversion only if requested, to prevent implicit conversion
- * of exclusive lock to shared one during activation.
- */
- if (!test_mode() && command & LCK_CLUSTER_VG) {
- status = hold_lock(resource, mode, LCKF_NOQUEUE | ((lock_flags & LCK_CONVERT_MODE) ? LCKF_CONVERT:0));
- if (status) {
- /* Return an LVM-sensible error for this.
- * Forcing EIO makes the upper level return this text
- * rather than the strerror text for EAGAIN.
- */
- if (errno == EAGAIN) {
- sprintf(last_error, "Volume is busy on another node");
- errno = EIO;
- }
- return errno;
- }
- }
-
- /* If it's suspended then resume it */
- if (!lv_info_by_lvid(cmd, resource, 0, &lvi, 0, 0))
- goto error;
-
- if (lvi.suspended) {
- critical_section_inc(cmd, "resuming");
- if (!lv_resume(cmd, resource, 0, NULL)) {
- critical_section_dec(cmd, "resumed");
- goto error;
- }
- }
-
- /* Now activate it */
- if (!lv_activate(cmd, resource, exclusive, 0, 0, NULL))
- goto error;
-
- return 0;
-
-error:
- if (!test_mode() && (oldmode == -1 || oldmode != mode))
- (void)hold_unlock(resource);
- return EIO;
-}
-
-/* Resume the LV if it was active */
-static int do_resume_lv(char *resource, unsigned char command, unsigned char lock_flags)
-{
- int oldmode, origin_only, exclusive, revert;
-
- /* Is it open ? */
- oldmode = get_current_lock(resource);
- if (oldmode == -1 && (command & LCK_CLUSTER_VG)) {
- DEBUGLOG("do_resume_lv, lock not already held\n");
- return 0; /* We don't need to do anything */
- }
- origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
- exclusive = (oldmode == LCK_EXCL) ? 1 : 0;
- revert = (lock_flags & LCK_REVERT_MODE) ? 1 : 0;
-
- if (!lv_resume_if_active(cmd, resource, origin_only, exclusive, revert, NULL))
- return EIO;
-
- return 0;
-}
-
-/* Suspend the device if active */
-static int do_suspend_lv(char *resource, unsigned char command, unsigned char lock_flags)
-{
- int oldmode;
- unsigned origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
- unsigned exclusive;
-
- /* Is it open ? */
- oldmode = get_current_lock(resource);
- if (oldmode == -1 && (command & LCK_CLUSTER_VG)) {
- DEBUGLOG("do_suspend_lv, lock not already held\n");
- return 0; /* Not active, so it's OK */
- }
-
- exclusive = (oldmode == LCK_EXCL) ? 1 : 0;
-
- /* Always call lv_suspend to read commited and precommited data */
- if (!lv_suspend_if_active(cmd, resource, origin_only, exclusive, NULL, NULL))
- return EIO;
-
- return 0;
-}
-
-static int do_deactivate_lv(char *resource, unsigned char command, unsigned char lock_flags)
-{
- int oldmode;
- int status;
-
- /* Is it open ? */
- oldmode = get_current_lock(resource);
- if (oldmode == -1 && (command & LCK_CLUSTER_VG)) {
- DEBUGLOG("do_deactivate_lock, lock not already held\n");
- return 0; /* We don't need to do anything */
- }
-
- if (!lv_deactivate(cmd, resource, NULL))
- return EIO;
-
- if (!test_mode() && command & LCK_CLUSTER_VG) {
- status = hold_unlock(resource);
- if (status)
- return errno;
- }
-
- return 0;
-}
-
-const char *do_lock_query(char *resource)
-{
- int mode;
- const char *type;
-
- mode = get_current_lock(resource);
- switch (mode) {
- case LCK_NULL: type = "NL"; break;
- case LCK_READ: type = "CR"; break;
- case LCK_PREAD:type = "PR"; break;
- case LCK_WRITE:type = "PW"; break;
- case LCK_EXCL: type = "EX"; break;
- default: type = NULL;
- }
-
- DEBUGLOG("do_lock_query: resource '%s', mode %i (%s)\n", resource, mode, type ?: "--");
-
- return type;
-}
-
-/* This is the LOCK_LV part that happens on all nodes in the cluster -
- it is responsible for the interaction with device-mapper and LVM */
-int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
-{
- int status = 0;
-
- DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s, critical_section = %d\n",
- resource, decode_locking_cmd(command), decode_flags(lock_flags), critical_section());
-
- if (!cmd->initialized.config || config_files_changed(cmd)) {
- /* Reinitialise various settings inc. logging, filters */
- if (do_refresh_cache()) {
- log_error("Updated config file invalid. Aborting.");
- return EINVAL;
- }
- }
-
- pthread_mutex_lock(&lvm_lock);
- init_test((lock_flags & LCK_TEST_MODE) ? 1 : 0);
-
- if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
- init_mirror_in_sync(1);
-
- if (lock_flags & LCK_DMEVENTD_MONITOR_IGNORE)
- init_dmeventd_monitor(DMEVENTD_MONITOR_IGNORE);
- else {
- if (lock_flags & LCK_DMEVENTD_MONITOR_MODE)
- init_dmeventd_monitor(1);
- else
- init_dmeventd_monitor(0);
- }
-
- cmd->partial_activation = (lock_flags & LCK_PARTIAL_MODE) ? 1 : 0;
-
- /* clvmd should never try to read suspended device */
- init_ignore_suspended_devices(1);
-
- switch (command & LCK_MASK) {
- case LCK_LV_EXCLUSIVE:
- status = do_activate_lv(resource, command, lock_flags, LCK_EXCL);
- break;
-
- case LCK_LV_SUSPEND:
- status = do_suspend_lv(resource, command, lock_flags);
- break;
-
- case LCK_UNLOCK:
- case LCK_LV_RESUME: /* if active */
- status = do_resume_lv(resource, command, lock_flags);
- break;
-
- case LCK_LV_ACTIVATE:
- status = do_activate_lv(resource, command, lock_flags, LCK_READ);
- break;
-
- case LCK_LV_DEACTIVATE:
- status = do_deactivate_lv(resource, command, lock_flags);
- break;
-
- default:
- DEBUGLOG("Invalid LV command 0x%x\n", command);
- status = EINVAL;
- break;
- }
-
- if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
- init_mirror_in_sync(0);
-
- cmd->partial_activation = 0;
-
- /* clean the pool for another command */
- dm_pool_empty(cmd->mem);
- init_test(0);
- pthread_mutex_unlock(&lvm_lock);
-
- DEBUGLOG("Command return is %d, critical_section is %d\n", status, critical_section());
- return status;
-}
-
-/* Functions to do on the local node only BEFORE the cluster-wide stuff above happens */
-int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
-{
- /* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the
- lock out on this node (because we are the node modifying the metadata)
- before suspending cluster-wide.
- LCKF_CONVERT is used always, local node is going to modify metadata
- */
- if ((command & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_SUSPEND &&
- (command & LCK_CLUSTER_VG)) {
- DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n",
- resource, decode_locking_cmd(command), decode_flags(lock_flags));
-
- if (!(lock_flags & LCK_TEST_MODE) &&
- hold_lock(resource, LCK_WRITE, LCKF_NOQUEUE | LCKF_CONVERT))
- return errno;
- }
- return 0;
-}
-
-/* Functions to do on the local node only AFTER the cluster-wide stuff above happens */
-int post_lock_lv(unsigned char command, unsigned char lock_flags,
- char *resource)
-{
- int status;
- unsigned origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
-
- /* Opposite of above, done on resume after a metadata update */
- if ((command & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_RESUME &&
- (command & LCK_CLUSTER_VG)) {
- int oldmode;
-
- DEBUGLOG("post_lock_lv: resource '%s', cmd = %s, flags = %s\n",
- resource, decode_locking_cmd(command), decode_flags(lock_flags));
-
- /* If the lock state is PW then restore it to what it was */
- oldmode = get_current_lock(resource);
- if (oldmode == LCK_WRITE) {
- struct lvinfo lvi;
-
- pthread_mutex_lock(&lvm_lock);
- status = lv_info_by_lvid(cmd, resource, origin_only, &lvi, 0, 0);
- pthread_mutex_unlock(&lvm_lock);
- if (!status)
- return EIO;
-
- if (!(lock_flags & LCK_TEST_MODE)) {
- if (lvi.exists) {
- if (hold_lock(resource, LCK_READ, LCKF_CONVERT))
- return errno;
- } else if (hold_unlock(resource))
- return errno;
- }
- }
- }
- return 0;
-}
-
-int do_refresh_cache(void)
-{
- DEBUGLOG("Refreshing context\n");
- log_notice("Refreshing context");
-
- pthread_mutex_lock(&lvm_lock);
-
- if (!refresh_toolcontext(cmd)) {
- pthread_mutex_unlock(&lvm_lock);
- return -1;
- }
-
- init_ignore_suspended_devices(1);
- lvmcache_label_scan(cmd);
- label_scan_destroy(cmd); /* destroys bcache (to close devs), keeps lvmcache */
- dm_pool_empty(cmd->mem);
-
- pthread_mutex_unlock(&lvm_lock);
-
- return 0;
-}
-
-/*
- * Handle VG lock - drop metadata or update lvmcache state
- */
-void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
-{
- uint32_t lock_cmd = command;
- char *vgname = resource + 2;
-
- lock_cmd &= (LCK_SCOPE_MASK | LCK_TYPE_MASK | LCK_HOLD);
-
- /*
- * Check if LCK_CACHE should be set. All P_ locks except # are cache related.
- */
- if (strncmp(resource, "P_#", 3) && !strncmp(resource, "P_", 2))
- lock_cmd |= LCK_CACHE;
-
- DEBUGLOG("do_lock_vg: resource '%s', cmd = %s, flags = %s, critical_section = %d\n",
- resource, decode_full_locking_cmd(lock_cmd), decode_flags(lock_flags), critical_section());
-
- /* P_#global causes a full cache refresh */
- if (!strcmp(resource, "P_" VG_GLOBAL)) {
- do_refresh_cache();
- return;
- }
-
- pthread_mutex_lock(&lvm_lock);
- init_test((lock_flags & LCK_TEST_MODE) ? 1 : 0);
-
- switch (lock_cmd) {
- case LCK_VG_COMMIT:
- DEBUGLOG("vg_commit notification for VG %s\n", vgname);
- lvmcache_commit_metadata(vgname);
- break;
- case LCK_VG_REVERT:
- DEBUGLOG("vg_revert notification for VG %s\n", vgname);
- lvmcache_drop_metadata(vgname, 1);
- break;
- case LCK_VG_DROP_CACHE:
- default:
- DEBUGLOG("Invalidating cached metadata for VG %s\n", vgname);
- lvmcache_drop_metadata(vgname, 0);
- }
-
- init_test(0);
- pthread_mutex_unlock(&lvm_lock);
-}
-
-/*
- * Ideally, clvmd should be started before any LVs are active
- * but this may not be the case...
- * I suppose this also comes in handy if clvmd crashes, not that it would!
- */
-static int get_initial_state(struct dm_hash_table *excl_uuid)
-{
- int lock_mode;
- char lv[65], vg[65], flags[26], vg_flags[26]; /* with space for '\0' */
- char uuid[65];
- char line[255];
- char *lvs_cmd;
- const char *lvm_binary = getenv("LVM_BINARY") ? : LVM_PATH;
- FILE *lvs;
-
- if (dm_asprintf(&lvs_cmd, "%s lvs --config 'log{command_names=0 prefix=\"\"}' "
- "--nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
- lvm_binary) < 0)
- return_0;
-
- /* FIXME: Maybe link and use liblvm2cmd directly instead of fork */
- if (!(lvs = popen(lvs_cmd, "r"))) {
- dm_free(lvs_cmd);
- return 0;
- }
-
- while (fgets(line, sizeof(line), lvs)) {
- if (sscanf(line, "%64s %64s %25s %25s\n", vg, lv, flags, vg_flags) == 4) {
-
- /* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
- if (strlen(vg) == 38 && /* is is a valid UUID ? */
- (flags[4] == 'a' || flags[4] == 's') && /* is it active or suspended? */
- vg_flags[5] == 'c') { /* is it clustered ? */
- /* Convert hyphen-separated UUIDs into one */
- memcpy(&uuid[0], &vg[0], 6);
- memcpy(&uuid[6], &vg[7], 4);
- memcpy(&uuid[10], &vg[12], 4);
- memcpy(&uuid[14], &vg[17], 4);
- memcpy(&uuid[18], &vg[22], 4);
- memcpy(&uuid[22], &vg[27], 4);
- memcpy(&uuid[26], &vg[32], 6);
- memcpy(&uuid[32], &lv[0], 6);
- memcpy(&uuid[38], &lv[7], 4);
- memcpy(&uuid[42], &lv[12], 4);
- memcpy(&uuid[46], &lv[17], 4);
- memcpy(&uuid[50], &lv[22], 4);
- memcpy(&uuid[54], &lv[27], 4);
- memcpy(&uuid[58], &lv[32], 6);
- uuid[64] = '\0';
-
- /* Look for this lock in the list of EX locks
- we were passed on the command-line */
- lock_mode = (dm_hash_lookup(excl_uuid, uuid)) ?
- LCK_EXCL : LCK_READ;
-
- DEBUGLOG("getting initial lock for %s\n", uuid);
- if (hold_lock(uuid, lock_mode, LCKF_NOQUEUE))
- DEBUGLOG("Failed to hold lock %s\n", uuid);
- }
- }
- }
- if (pclose(lvs))
- DEBUGLOG("lvs pclose failed: %s\n", strerror(errno));
-
- dm_free(lvs_cmd);
-
- return 1;
-}
-
-static void lvm2_log_fn(int level, const char *file, int line, int dm_errno,
- const char *message)
-{
-
- /* Send messages to the normal LVM2 logging system too,
- so we get debug output when it's asked for.
- We need to NULL the function ptr otherwise it will just call
- back into here! */
- init_log_fn(NULL);
- print_log(level, file, line, dm_errno, "%s", message);
- init_log_fn(lvm2_log_fn);
-
- /*
- * Ignore non-error messages, but store the latest one for returning
- * to the user.
- */
- if (level != _LOG_ERR && level != _LOG_FATAL)
- return;
-
- (void) dm_strncpy(last_error, message, sizeof(last_error));
-}
-
-/* This checks some basic cluster-LVM configuration stuff */
-static void check_config(void)
-{
- int locking_type;
-
- locking_type = find_config_tree_int(cmd, global_locking_type_CFG, NULL);
-
- if (locking_type == 3) /* compiled-in cluster support */
- return;
-
- if (locking_type == 2) { /* External library, check name */
- const char *libname;
-
- libname = find_config_tree_str(cmd, global_locking_library_CFG, NULL);
- if (libname && 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.");
-}
-
-/* Backups up the LVM metadata if it's changed */
-void lvm_do_backup(const char *vgname)
-{
- struct volume_group * vg;
- int consistent = 0;
-
- DEBUGLOG("Triggering backup of VG metadata for %s.\n", vgname);
-
- pthread_mutex_lock(&lvm_lock);
-
- vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, 0, WARN_PV_READ, &consistent);
-
- if (vg && consistent)
- check_current_backup(vg);
- else
- log_error("Error backing up metadata, can't find VG for group %s", vgname);
-
- release_vg(vg);
- dm_pool_empty(cmd->mem);
-
- pthread_mutex_unlock(&lvm_lock);
-}
-
-struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name)
-{
- struct lv_info *lvi;
-
- *name = NULL;
- if (!v)
- v = dm_hash_get_first(lv_hash);
-
- do {
- if (v) {
- lvi = dm_hash_get_data(lv_hash, v);
- DEBUGLOG("Looking for EX locks. found %x mode %d\n", lvi->lock_id, lvi->lock_mode);
-
- if (lvi->lock_mode == LCK_EXCL) {
- *name = dm_hash_get_key(lv_hash, v);
- }
- v = dm_hash_get_next(lv_hash, v);
- }
- } while (v && !*name);
-
- if (*name)
- DEBUGLOG("returning EXclusive UUID %s\n", *name);
- return v;
-}
-
-void lvm_do_fs_unlock(void)
-{
- pthread_mutex_lock(&lvm_lock);
- DEBUGLOG("Syncing device names\n");
- fs_unlock();
- pthread_mutex_unlock(&lvm_lock);
-}
-
-/* Called to initialise the LVM context of the daemon */
-int init_clvm(struct dm_hash_table *excl_uuid)
-{
- /* Use LOG_DAEMON for syslog messages instead of LOG_USER */
- init_syslog(LOG_DAEMON);
- openlog("clvmd", LOG_PID, LOG_DAEMON);
-
- /* Initialise already held locks */
- if (!get_initial_state(excl_uuid))
- log_error("Cannot load initial lock states.");
-
- if (!udev_init_library_context())
- stack;
-
- if (!(cmd = create_toolcontext(1, NULL, 0, 1, 1, 1))) {
- log_error("Failed to allocate command context");
- udev_fin_library_context();
- return 0;
- }
-
- if (stored_errno()) {
- destroy_toolcontext(cmd);
- return 0;
- }
-
- cmd->cmd_line = "clvmd";
-
- /* Check lvm.conf is setup for cluster-LVM */
- check_config();
- init_ignore_suspended_devices(1);
-
- /* Trap log messages so we can pass them back to the user */
- init_log_fn(lvm2_log_fn);
- memlock_inc_daemon(cmd);
-
- return 1;
-}
-
-void destroy_lvm(void)
-{
- if (cmd) {
- memlock_dec_daemon(cmd);
- destroy_toolcontext(cmd);
- udev_fin_library_context();
- cmd = NULL;
- }
-}
diff --git a/daemons/clvmd/lvm-functions.h b/daemons/clvmd/lvm-functions.h
deleted file mode 100644
index 6785997a2..000000000
--- a/daemons/clvmd/lvm-functions.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* Functions in lvm-functions.c */
-
-#ifndef _LVM_FUNCTIONS_H
-#define _LVM_FUNCTIONS_H
-
-extern int pre_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
- char *resource);
-extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
- char *resource);
-extern const char *do_lock_query(char *resource);
-extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
- char *resource);
-extern int do_refresh_cache(void);
-extern int init_clvm(struct dm_hash_table *excl_uuid);
-extern void destroy_lvm(void);
-extern void init_lvhash(void);
-extern void destroy_lvhash(void);
-extern void lvm_do_backup(const char *vgname);
-extern char *get_last_lvm_error(void);
-extern void do_lock_vg(unsigned char command, unsigned char lock_flags,
- char *resource);
-extern struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name);
-void lvm_do_fs_unlock(void);
-
-#endif
diff --git a/daemons/clvmd/refresh_clvmd.c b/daemons/clvmd/refresh_clvmd.c
deleted file mode 100644
index c80e09f5b..000000000
--- a/daemons/clvmd/refresh_clvmd.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* FIXME Remove duplicated functions from this file. */
-
-/*
- * Send a command to a running clvmd from the command-line
- */
-
-#include "clvmd-common.h"
-
-#include "daemons/clvmd/clvm.h"
-#include "refresh_clvmd.h"
-
-#include <stddef.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-typedef struct lvm_response {
- char node[255];
- char *response;
- int status;
- int len;
-} lvm_response_t;
-
-/*
- * This gets stuck at the start of memory we allocate so we
- * can sanity-check it at deallocation time
- */
-#define LVM_SIGNATURE 0x434C564D
-
-static int _clvmd_sock = -1;
-
-/* Open connection to the clvm daemon */
-static int _open_local_sock(void)
-{
- int local_socket;
- struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
-
- if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
- fprintf(stderr, "%s: clvmd socket name too long.", CLVMD_SOCKNAME);
- return -1;
- }
-
- /* Open local socket */
- if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "Local socket creation failed: %s", strerror(errno));
- return -1;
- }
-
- if (connect(local_socket,(struct sockaddr *) &sockaddr,
- sizeof(sockaddr))) {
- int saved_errno = errno;
-
- fprintf(stderr, "connect() failed on local socket: %s\n",
- strerror(errno));
- if (close(local_socket))
- return -1;
-
- errno = saved_errno;
- return -1;
- }
-
- return local_socket;
-}
-
-/* Send a request and return the status */
-static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_response)
-{
- char outbuf[PIPE_BUF];
- struct clvm_header *outheader = (struct clvm_header *) outbuf;
- int len;
- unsigned off;
- int buflen;
- int err;
-
- /* Send it to CLVMD */
- rewrite:
- if ( (err = write(_clvmd_sock, inbuf, inlen)) != inlen) {
- if (err == -1 && errno == EINTR)
- goto rewrite;
- fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
- return 0;
- }
- if (no_response)
- return 1;
-
- /* Get the response */
- reread:
- if ((len = read(_clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
- if (errno == EINTR)
- goto reread;
- fprintf(stderr, "Error reading data from clvmd: %s", strerror(errno));
- return 0;
- }
-
- if (len == 0) {
- fprintf(stderr, "EOF reading CLVMD");
- errno = ENOTCONN;
- return 0;
- }
-
- /* Allocate buffer */
- buflen = len + outheader->arglen;
- *retbuf = dm_malloc(buflen);
- if (!*retbuf) {
- errno = ENOMEM;
- return 0;
- }
-
- /* 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,
- buflen - off - offsetof(struct clvm_header, args));
- if (len > 0)
- off += len;
- }
-
- /* Was it an error ? */
- 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)) {
- fprintf(stderr, "cluster request failed: %s\n", strerror(errno));
- return 0;
- }
-
- }
-
- return 1;
-}
-
-/* Build the structure header and parse-out wildcard node names */
-static void _build_header(struct clvm_header *head, int cmd, const char *node,
- unsigned int len)
-{
- head->cmd = cmd;
- head->status = 0;
- head->flags = 0;
- head->xid = 0;
- head->clientid = 0;
- if (len)
- /* 1 byte is used from struct clvm_header.args[1], so -> len - 1 */
- head->arglen = len - 1;
- else {
- head->arglen = 0;
- *head->args = '\0';
- }
-
- /*
- * Translate special node names.
- */
- if (!node || !strcmp(node, NODE_ALL))
- head->node[0] = '\0';
- else if (!strcmp(node, NODE_LOCAL)) {
- head->node[0] = '\0';
- head->flags = CLVMD_FLAG_LOCAL;
- } else
- strcpy(head->node, node);
-}
-
-/*
- * Send a message to a(or all) node(s) in the cluster and wait for replies
- */
-static int _cluster_request(char cmd, const char *node, void *data, int len,
- lvm_response_t ** response, int *num, int no_response)
-{
- char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
- 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 0;
-
- _build_header(head, cmd, node, len);
- if (len)
- memcpy(head->node + strlen(head->node) + 1, data, len);
-
- status = _send_request(outbuf, sizeof(struct clvm_header) +
- strlen(head->node) + len, &retbuf, no_response);
- if (!status || no_response)
- goto out;
-
- /* 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
- */
- *response = NULL;
- if (!(rarray = dm_malloc(sizeof(lvm_response_t) * num_responses +
- sizeof(int) * 2))) {
- errno = ENOMEM;
- status = 0;
- goto out;
- }
-
- /* 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;
-
- memcpy(&rarray[i].status, inptr, sizeof(int));
- inptr += sizeof(int);
-
- rarray[i].response = dm_malloc(strlen(inptr) + 1);
- if (rarray[i].response == NULL) {
- /* Free up everything else and return error */
- int j;
- for (j = 0; j < i; j++)
- dm_free(rarray[i].response);
- dm_free(rarray);
- errno = ENOMEM;
- status = 0;
- goto out;
- }
-
- strcpy(rarray[i].response, inptr);
- rarray[i].len = strlen(inptr);
- inptr += strlen(inptr) + 1;
- i++;
- }
- *num = num_responses;
- *response = rarray;
-
- out:
- dm_free(retbuf);
-
- return status;
-}
-
-/* Free reply array */
-static int _cluster_free_request(lvm_response_t * response, int num)
-{
- int i;
-
- for (i = 0; i < num; i++) {
- dm_free(response[i].response);
- }
-
- dm_free(response);
-
- return 1;
-}
-
-int refresh_clvmd(int all_nodes)
-{
- int num_responses;
- char args[1]; // No args really.
- lvm_response_t *response = NULL;
- int saved_errno;
- int status;
- int i;
-
- status = _cluster_request(CLVMD_CMD_REFRESH, all_nodes ? NODE_ALL : NODE_LOCAL, args, 0, &response, &num_responses, 0);
-
- /* If any nodes were down then display them and return an error */
- for (i = 0; i < num_responses; i++) {
- if (response[i].status == EHOSTDOWN) {
- fprintf(stderr, "clvmd not running on node %s",
- response[i].node);
- status = 0;
- errno = response[i].status;
- } else if (response[i].status) {
- fprintf(stderr, "Error resetting node %s: %s",
- response[i].node,
- response[i].response[0] ?
- response[i].response :
- strerror(response[i].status));
- status = 0;
- errno = response[i].status;
- }
- }
-
- saved_errno = errno;
- _cluster_free_request(response, num_responses);
- errno = saved_errno;
-
- return status;
-}
-
-int restart_clvmd(int all_nodes)
-{
- int dummy, status;
-
- status = _cluster_request(CLVMD_CMD_RESTART, all_nodes ? NODE_ALL : NODE_LOCAL, NULL, 0, NULL, &dummy, 1);
-
- /*
- * FIXME: we cannot receive response, clvmd re-exec before it.
- * but also should not close socket too early (the whole rq is dropped then).
- * FIXME: This should be handled this way:
- * - client waits for RESTART ack (and socket close)
- * - server restarts
- * - client checks that server is ready again (VERSION command?)
- */
- usleep(500000);
-
- return status;
-}
-
-int debug_clvmd(int level, int clusterwide)
-{
- int num_responses;
- char args[1];
- const char *nodes;
- lvm_response_t *response = NULL;
- int saved_errno;
- int status;
- int i;
-
- args[0] = level;
- if (clusterwide)
- nodes = NODE_ALL;
- else
- nodes = NODE_LOCAL;
-
- status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses, 0);
-
- /* If any nodes were down then display them and return an error */
- for (i = 0; i < num_responses; i++) {
- if (response[i].status == EHOSTDOWN) {
- fprintf(stderr, "clvmd not running on node %s",
- response[i].node);
- status = 0;
- errno = response[i].status;
- } else if (response[i].status) {
- fprintf(stderr, "Error setting debug on node %s: %s",
- response[i].node,
- response[i].response[0] ?
- response[i].response :
- strerror(response[i].status));
- status = 0;
- errno = response[i].status;
- }
- }
-
- saved_errno = errno;
- _cluster_free_request(response, num_responses);
- errno = saved_errno;
-
- return status;
-}
diff --git a/daemons/clvmd/refresh_clvmd.h b/daemons/clvmd/refresh_clvmd.h
deleted file mode 100644
index b9d775e3d..000000000
--- a/daemons/clvmd/refresh_clvmd.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-int refresh_clvmd(int all_nodes);
-int restart_clvmd(int all_nodes);
-int debug_clvmd(int level, int clusterwide);
-
diff --git a/daemons/cmirrord/Makefile.in b/daemons/cmirrord/Makefile.in
index fc0ef6d5a..b6bab2d60 100644
--- a/daemons/cmirrord/Makefile.in
+++ b/daemons/cmirrord/Makefile.in
@@ -17,8 +17,6 @@ top_builddir = @top_builddir@
CPG_LIBS = @CPG_LIBS@
CPG_CFLAGS = @CPG_CFLAGS@
-SACKPT_LIBS = @SACKPT_LIBS@
-SACKPT_CFLAGS = @SACKPT_CFLAGS@
SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
@@ -26,8 +24,8 @@ TARGETS = cmirrord
include $(top_builddir)/make.tmpl
-LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
-CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) $(EXTRA_EXEC_CFLAGS)
+LMLIBS += $(CPG_LIBS)
+CFLAGS += $(CPG_CFLAGS) $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
diff --git a/daemons/cmirrord/cluster.c b/daemons/cmirrord/cluster.c
index 6bb9d6347..c51644790 100644
--- a/daemons/cmirrord/cluster.c
+++ b/daemons/cmirrord/cluster.c
@@ -18,6 +18,9 @@
#include "local.h"
#include "lib/mm/xlate.h"
+/* FIXME: remove this and the code */
+#define CMIRROR_HAS_CHECKPOINT 0
+
#include <corosync/cpg.h>
#include <errno.h>
#include <signal.h>
diff --git a/include/configure.h.in b/include/configure.h.in
index 15fd150ed..65a2a6aeb 100644
--- a/include/configure.h.in
+++ b/include/configure.h.in
@@ -25,15 +25,6 @@
/* Define to 1 if the `closedir' function returns void instead of `int'. */
#undef CLOSEDIR_VOID
-/* Define to 1 to include built-in support for clustered LVM locking. */
-#undef CLUSTER_LOCKING_INTERNAL
-
-/* Path to clvmd binary. */
-#undef CLVMD_PATH
-
-/* Path to clvmd pidfile. */
-#undef CLVMD_PIDFILE
-
/* Path to cmirrord pidfile. */
#undef CMIRRORD_PIDFILE
@@ -178,12 +169,6 @@
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
-/* Define to 1 if you have the <corosync/cmap.h> header file. */
-#undef HAVE_COROSYNC_CMAP_H
-
-/* Define to 1 if you have the <corosync/confdb.h> header file. */
-#undef HAVE_COROSYNC_CONFDB_H
-
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
@@ -248,9 +233,6 @@
/* Define to 1 if you have the <libaio.h> header file. */
#undef HAVE_LIBAIO_H
-/* Define to 1 if you have the <libcman.h> header file. */
-#undef HAVE_LIBCMAN_H
-
/* Define to 1 if dynamic libraries are available. */
#undef HAVE_LIBDL
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 1d422354c..4b64ce0a1 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -16,10 +16,6 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
-ifeq ("@CLUSTER@", "shared")
- SUBDIRS += locking
-endif
-
SOURCES =\
activate/activate.c \
cache/lvmcache.c \
@@ -66,7 +62,6 @@ SOURCES =\
label/label.c \
locking/file_locking.c \
locking/locking.c \
- locking/no_locking.c \
log/log.c \
metadata/cache_manip.c \
metadata/lv.c \
@@ -107,10 +102,6 @@ SOURCES =\
uuid/uuid.c \
zero/zero.c
-ifeq ("@CLUSTER@", "internal")
- SOURCES += locking/cluster_locking.c
-endif
-
ifeq ("@DEVMAPPER@", "yes")
SOURCES +=\
activate/dev_manager.c \
@@ -118,9 +109,7 @@ ifeq ("@DEVMAPPER@", "yes")
endif
ifeq ("@HAVE_LIBDL@", "yes")
- SOURCES +=\
- locking/external_locking.c \
- misc/sharedlib.c
+ SOURCES += misc/sharedlib.c
endif
ifeq ("@BUILD_LVMETAD@", "yes")
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index a15a2d72d..4c7044368 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -669,9 +669,7 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
* in progress - as only those could lead to opened files
*/
if (with_open_count) {
- if (locking_is_clustered() && !sync_local_dev_names(cmd)) /* Wait to have udev in sync */
- return_0;
- else if (fs_has_non_delete_ops())
+ if (fs_has_non_delete_ops())
fs_unlock(); /* For non clustered - wait if there are non-delete ops */
}
@@ -724,21 +722,6 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la
return _lv_info(cmd, lv, use_layer, info, NULL, NULL, with_open_count, with_read_ahead);
}
-int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
- struct lvinfo *info, int with_open_count, int with_read_ahead)
-{
- int r;
- struct logical_volume *lv;
-
- if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
- return 0;
-
- r = lv_info(cmd, lv, use_layer, info, with_open_count, with_read_ahead);
- release_vg(lv->vg);
-
- return r;
-}
-
/*
* Returns 1 if lv_with_info_and_seg_status info structure populated,
* else 0 on failure or if device not active locally.
@@ -1521,47 +1504,9 @@ static int _lv_is_active(const struct logical_volume *lv,
if (_lv_active(lv->vg->cmd, lv))
l = 1;
- if (!vg_is_clustered(lv->vg)) {
- if (l)
- e = 1; /* exclusive by definition */
- goto out;
- }
-
- /* Active locally, and the caller doesn't care about exclusive or remotely */
- if (l && !exclusive && !remotely)
- skip_cluster_query = 1;
-
- if (skip_cluster_query)
- goto out;
-
- if ((r = cluster_lock_held(lv->lvid.s, "", &e)) >= 0) {
- if (l && e)
- r = 0; /* exclusive locally */
- goto out;
- }
-
- /*
- * If lock query is not supported (due to interfacing with old
- * code), then we cannot evaluate exclusivity properly.
- *
- * Old users of this function will never be affected by this,
- * since they are only concerned about active vs. not active.
- * New users of this function who specifically ask for 'exclusive'
- * will be given a warning message.
- */
- log_warn("WARNING: Unable to determine exclusivity of %s.", display_lvname(lv));
-
- e = 0;
+ if (l)
+ e = 1; /* exclusive by definition */
- /* Also set remotely as a precaution, as we don't know */
- r = 1;
-
- /*
- * We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
- * but it's unreliable.
- */
-
-out:
if (locally)
*locally = l;
if (exclusive)
@@ -2146,75 +2091,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
struct dm_pool *mem = NULL;
struct dm_list suspend_lvs;
struct lv_list *lvl;
- const union lvid *lvid = (const union lvid *) lvid_s;
- const char *vgid = (const char *)lvid->id[0].uuid;
- struct volume_group *vg;
- struct volume_group *vg_pre;
int found;
if (!activation())
return 1;
- if (!cmd->is_clvmd)
- goto skip_read;
-
- if (lv && lv_pre)
- goto skip_read;
-
- if (!(vg = lvmcache_get_saved_vg(vgid, 0))) {
- log_debug("lv_suspend did not find saved_vg %.8s so reading", vgid);
- if (!(vg = vg_read_by_vgid(cmd, vgid, 0))) {
- log_error("lv_suspend could not read vgid %.8s", vgid);
- goto out;
- }
- log_debug("lv_suspend using read vg %s %d %p", vg->name, vg->seqno, vg);
- } else {
- log_debug("lv_suspend using saved_vg %s %d %p", vg->name, vg->seqno, vg);
- }
-
- if (!(vg_pre = lvmcache_get_saved_vg(vgid, 1))) {
- log_debug("lv_suspend did not find pre saved_vg %.8s so reading", vgid);
- if (!(vg_pre = vg_read_by_vgid(cmd, vgid, 1))) {
- log_error("lv_suspend could not read pre vgid %.8s", vgid);
- goto out;
- }
- log_debug("lv_suspend using pre read vg %s %d %p", vg_pre->name, vg_pre->seqno, vg_pre);
- } else {
- log_debug("lv_suspend using pre saved_vg %s %d %p", vg_pre->name, vg_pre->seqno, vg_pre);
- }
-
- /*
- * Note that vg and vg_pre returned by vg_read_by_vgid will
- * not be the same as saved_vg_old/saved_vg_new that would
- * be returned by lvmcache_get_saved_vg() because the saved_vg's
- * are copies of the vg struct that is created by _vg_read.
- * (Should we grab and use the saved_vg to use here instead of
- * the vg returned by vg_read_by_vgid?)
- */
-
- if ((vg->status & EXPORTED_VG) || (vg_pre->status & EXPORTED_VG)) {
- log_error("Volume group \"%s\" is exported", vg->name);
- goto out;
- }
-
- lv = lv_to_free = find_lv_in_vg_by_lvid(vg, lvid);
- lv_pre = lv_pre_to_free = find_lv_in_vg_by_lvid(vg_pre, lvid);
-
- if (!lv || !lv_pre) {
- log_error("lv_suspend could not find lv %p lv_pre %p vg %p vg_pre %p vgid %s",
- lv, lv_pre, vg, vg_pre, vgid);
- goto out;
- }
-
-skip_read:
- /* lv comes from committed metadata */
- if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
- goto_out;
-
- /* Use precommitted metadata if present */
- if (!lv_pre && !(lv_pre_to_free = lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
- goto_out;
-
/* Ignore origin_only unless LV is origin in both old and new metadata */
/* or LV is thin or thin pool volume */
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
@@ -2231,19 +2112,6 @@ skip_read:
if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
goto_out;
- /*
- * Save old and new (current and precommitted) versions of the
- * VG metadata for lv_resume() to use, since lv_resume can't
- * read metadata given that devices are suspended. lv_resume()
- * will resume LVs using the old/current metadata if the vg_commit
- * did happen (or failed), and it will resume LVs using the
- * new/precommitted metadata if the vg_commit succeeded.
- */
- if (cmd->is_clvmd) {
- lvmcache_save_vg(lv->vg, 0);
- lvmcache_save_vg(lv_pre->vg, 1);
- }
-
if (!info.exists || info.suspended) {
if (!error_if_not_suspended) {
r = 1;
@@ -2451,55 +2319,12 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
const struct logical_volume *lv)
{
struct dm_list *snh;
- struct volume_group *vg = NULL;
- struct logical_volume *lv_found = NULL;
- const union lvid *lvid;
- const char *vgid;
struct lvinfo info;
int r = 0;
if (!activation())
return 1;
- /*
- * When called in clvmd, lvid_s is set and lv is not. We need to
- * get the VG metadata without reading disks because devs are
- * suspended. lv_suspend() saved old and new VG metadata for us
- * to use here. If vg_commit() happened, lvmcache_get_saved_vg_latest
- * will return the new metadata for us to use in resuming LVs.
- * If vg_commit() did not happen, lvmcache_get_saved_vg_latest
- * returns the old metadata which we use to resume LVs.
- */
- if (!lv && lvid_s) {
- lvid = (const union lvid *) lvid_s;
- vgid = (const char *)lvid->id[0].uuid;
-
- if ((vg = lvmcache_get_saved_vg_latest(vgid))) {
- log_debug_activation("Resuming LVID %s found saved vg seqno %d %s", lvid_s, vg->seqno, vg->name);
- if ((lv_found = find_lv_in_vg_by_lvid(vg, lvid))) {
- log_debug_activation("Resuming LVID %s found saved LV %s", lvid_s, display_lvname(lv_found));
- lv = lv_found;
- } else
- log_debug_activation("Resuming LVID %s did not find saved LV", lvid_s);
- } else
- log_debug_activation("Resuming LVID %s did not find saved VG", lvid_s);
-
- /*
- * resume must have been called without a preceding suspend,
- * so we need to read the vg.
- */
-
- if (!lv) {
- log_debug_activation("Resuming LVID %s reading VG", lvid_s);
- if (!(lv_found = lv_from_lvid(cmd, lvid_s, 0))) {
- log_debug_activation("Resuming LVID %s failed to read VG", lvid_s);
- goto out;
- }
-
- lv = lv_found;
- }
- }
-
if (!lv_is_origin(lv) && !lv_is_thin_volume(lv) && !lv_is_thin_pool(lv))
laopts->origin_only = 0;
@@ -2620,9 +2445,6 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
if (!activation())
return 1;
- if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
- goto out;
-
if (test_mode()) {
_skip("Deactivating %s.", display_lvname(lv));
r = 1;
@@ -2694,45 +2516,31 @@ out:
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv, const struct logical_volume *lv)
{
- const struct logical_volume *lv_to_free = NULL;
- int r = 0;
-
if (!activation()) {
*activate_lv = 1;
return 1;
}
- if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
- goto_out;
-
if (!_passes_activation_filter(cmd, lv)) {
log_verbose("Not activating %s since it does not pass "
"activation filter.", display_lvname(lv));
*activate_lv = 0;
} else
*activate_lv = 1;
- r = 1;
-out:
- if (lv_to_free)
- release_vg(lv_to_free->vg);
- return r;
+ return 1;
}
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int filter,
const struct logical_volume *lv)
{
- const struct logical_volume *lv_to_free = NULL;
struct lvinfo info;
int r = 0;
if (!activation())
return 1;
- if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
- goto out;
-
if (!laopts->exclusive &&
(lv_is_origin(lv) ||
seg_only_exclusive(first_seg(lv)))) {
@@ -2771,16 +2579,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
goto out;
}
- /*
- * Check if cmirrord is running for clustered mirrors.
- */
- if (!laopts->exclusive && vg_is_clustered(lv->vg) &&
- lv_is_mirror(lv) && !lv_is_raid(lv) &&
- !cluster_mirror_is_available(lv->vg->cmd)) {
- log_error("Shared cluster mirrors are not available.");
- goto out;
- }
-
if (test_mode()) {
_skip("Activating %s.", display_lvname(lv));
r = 1;
@@ -2823,11 +2621,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
if (r && !monitor_dev_for_events(cmd, lv, laopts, 1))
stack;
-
out:
- if (lv_to_free)
- release_vg(lv_to_free->vg);
-
return r;
}
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 527f0a624..b9aa8a0d9 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -65,38 +65,10 @@ struct lvmcache_vginfo {
int scan_summary_mismatch; /* vgsummary from devs had mismatching seqno or checksum */
};
-struct saved_vg {
- /*
- * saved_vg_* are used only by clvmd.
- * It is not related to lvmcache or vginfo.
- *
- * For activation/deactivation, these are used to avoid
- * clvmd rereading a VG for each LV that is activated.
- *
- * For suspend/resume, this is used to avoid disk reads
- * while devices are suspended:
- * In suspend, both old (current) and new (precommitted)
- * metadata is saved. (Each in three forms: buffer, cft,
- * and vg). In resume, if the vg was committed
- * (saved_vg_committed is set), then LVs are resumed
- * using the new metadata, but if the vg wasn't committed,
- * then LVs are resumed using the old metadata.
- *
- * saved_vg_committed is set to 1 when clvmd gets
- * LCK_VG_COMMIT from vg_commit().
- */
- char vgid[ID_LEN + 1];
- int saved_vg_committed;
- struct volume_group *saved_vg_old;
- struct volume_group *saved_vg_new;
- struct dm_list saved_vg_to_free;
-};
-
static struct dm_hash_table *_pvid_hash = NULL;
static struct dm_hash_table *_vgid_hash = NULL;
static struct dm_hash_table *_vgname_hash = NULL;
static struct dm_hash_table *_lock_hash = NULL;
-static struct dm_hash_table *_saved_vg_hash = NULL;
static DM_LIST_INIT(_vginfos);
static DM_LIST_INIT(_found_duplicate_devs);
static DM_LIST_INIT(_unused_duplicate_devs);
@@ -131,11 +103,6 @@ int lvmcache_init(struct cmd_context *cmd)
if (!(_lock_hash = dm_hash_create(128)))
return 0;
- if (cmd->is_clvmd) {
- if (!(_saved_vg_hash = dm_hash_create(128)))
- return 0;
- }
-
/*
* Reinitialising the cache clears the internal record of
* which locks are held. The global lock can be held during
@@ -191,357 +158,6 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
-static struct saved_vg *_saved_vg_from_vgid(const char *vgid)
-{
- struct saved_vg *svg;
- char id[ID_LEN + 1] __attribute__((aligned(8)));
-
- /* vgid not necessarily NULL-terminated */
- (void) dm_strncpy(id, vgid, sizeof(id));
-
- if (!(svg = dm_hash_lookup(_saved_vg_hash, id))) {
- log_debug_cache("lvmcache: no saved_vg for vgid \"%s\"", id);
- return NULL;
- }
-
- return svg;
-}
-
-static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
-{
- struct vg_list *vgl;
-
- /*
- * In practice there appears to only ever be a single invalidated vg,
- * so making saved_vg_to_free a list instead of a pointer is overkill.
- * But, without proof otherwise, safer to keep the list.
- */
-
- if (inval_old && svg->saved_vg_old) {
- log_debug_cache("lvmcache: inval saved_vg %s old %p",
- svg->saved_vg_old->name, svg->saved_vg_old);
-
- if ((vgl = dm_zalloc(sizeof(*vgl)))) {
- vgl->vg = svg->saved_vg_old;
- dm_list_add(&svg->saved_vg_to_free, &vgl->list);
- }
-
- svg->saved_vg_old = NULL;
- }
-
- if (inval_new && svg->saved_vg_new) {
- log_debug_cache("lvmcache: inval saved_vg %s new pre %p",
- svg->saved_vg_new->name, svg->saved_vg_new);
-
- if ((vgl = dm_zalloc(sizeof(*vgl)))) {
- vgl->vg = svg->saved_vg_new;
- dm_list_add(&svg->saved_vg_to_free, &vgl->list);
- }
- svg->saved_vg_new = NULL;
- }
-}
-
-static void _saved_vg_free(struct saved_vg *svg, int free_old, int free_new)
-{
- struct vg_list *vgl, *vgl2;
- struct volume_group *vg;
-
- if (free_old) {
- if ((vg = svg->saved_vg_old)) {
- log_debug_cache("lvmcache: free saved_vg old %s %.8s %d old %p",
- vg->name, (char *)&vg->id, vg->seqno, vg);
-
- vg->saved_in_clvmd = 0;
- release_vg(vg);
- svg->saved_vg_old = NULL;
- vg = NULL;
- }
-
- dm_list_iterate_items_safe(vgl, vgl2, &svg->saved_vg_to_free) {
- log_debug_cache("lvmcache: free saved_vg_to_free %s %.8s %d %p",
- vgl->vg->name, (char *)&vgl->vg->id, vgl->vg->seqno, vgl->vg);
-
- dm_list_del(&vgl->list);
- vgl->vg->saved_in_clvmd = 0;
- release_vg(vgl->vg);
- }
- }
-
- if (free_new) {
- if ((vg = svg->saved_vg_new)) {
- log_debug_cache("lvmcache: free saved_vg pre %s %.8s %d %p",
- vg->name, (char *)&vg->id, vg->seqno, vg);
-
- vg->saved_in_clvmd = 0;
- release_vg(vg);
- svg->saved_vg_new = NULL;
- vg = NULL;
- }
- }
-}
-
-static void _drop_metadata(const char *vgname, int drop_precommitted)
-{
- struct lvmcache_vginfo *vginfo;
- struct saved_vg *svg;
-
- if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)))
- return;
-
- if (!(svg = _saved_vg_from_vgid(vginfo->vgid)))
- return;
-
- if (drop_precommitted)
- _saved_vg_free(svg, 0, 1);
- else
- _saved_vg_free(svg, 1, 1);
-}
-
-void lvmcache_save_vg(struct volume_group *vg, int precommitted)
-{
- struct saved_vg *svg;
- struct format_instance *fid;
- struct format_instance_ctx fic;
- struct volume_group *save_vg = NULL;
- struct dm_config_tree *save_cft = NULL;
- const struct format_type *fmt;
- char *save_buf = NULL;
- size_t size;
- int new = precommitted;
- int old = !precommitted;
-
- if (!(svg = _saved_vg_from_vgid((const char *)&vg->id))) {
- /* Nothing is saved yet for this vg */
-
- if (!(svg = dm_zalloc(sizeof(*svg))))
- return;
-
- dm_list_init(&svg->saved_vg_to_free);
-
- dm_strncpy(svg->vgid, (const char *)vg->id.uuid, sizeof(svg->vgid));
-
- if (!dm_hash_insert(_saved_vg_hash, svg->vgid, svg)) {
- log_error("lvmcache: failed to insert saved_vg %s", svg->vgid);
- return;
- }
- } else {
- /* Nothing to do if we've already saved this seqno */
-
- if (old && svg->saved_vg_old && (svg->saved_vg_old->seqno == vg->seqno))
- return;
-
- if (new && svg->saved_vg_new && (svg->saved_vg_new->seqno == vg->seqno))
- return;
-
- /* Invalidate the existing saved_vg that will be replaced */
-
- _saved_vg_inval(svg, old, new);
- }
-
-
- if (!(size = export_vg_to_buffer(vg, &save_buf)))
- goto_bad;
-
- fmt = vg->fid->fmt;
- fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
- fic.context.vg_ref.vg_name = vg->name;
- fic.context.vg_ref.vg_id = svg->vgid;
-
- if (!(fid = fmt->ops->create_instance(fmt, &fic)))
- goto_bad;
-
- if (!(save_cft = config_tree_from_string_without_dup_node_check(save_buf)))
- goto_bad;
-
- if (!(save_vg = import_vg_from_config_tree(save_cft, fid)))
- goto_bad;
-
- dm_free(save_buf);
- dm_config_destroy(save_cft);
-
- save_vg->saved_in_clvmd = 1;
-
- if (old) {
- svg->saved_vg_old = save_vg;
- log_debug_cache("lvmcache: saved old vg %s seqno %d %p",
- save_vg->name, save_vg->seqno, save_vg);
- } else {
- svg->saved_vg_new = save_vg;
- log_debug_cache("lvmcache: saved pre vg %s seqno %d %p",
- save_vg->name, save_vg->seqno, save_vg);
- }
- return;
-
-bad:
- if (save_buf)
- dm_free(save_buf);
- if (save_cft)
- dm_config_destroy(save_cft);
-
- _saved_vg_inval(svg, old, new);
- log_debug_cache("lvmcache: failed to save pre %d vg %s", precommitted, vg->name);
-}
-
-struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted)
-{
- struct saved_vg *svg;
- struct volume_group *vg = NULL;
- int new = precommitted;
- int old = !precommitted;
-
- if (!(svg = _saved_vg_from_vgid(vgid)))
- goto out;
-
- /*
- * Once new is returned, then also return new if old is requested,
- * i.e. new becomes both old and new once it's used.
- */
-
- if (new)
- vg = svg->saved_vg_new;
- else if (old)
- vg = svg->saved_vg_old;
-
- if (vg && old) {
- if (!svg->saved_vg_new)
- log_debug_cache("lvmcache: get old saved_vg %d %s %p",
- vg->seqno, vg->name, vg);
- else
- log_debug_cache("lvmcache: get old saved_vg %d %s %p new is %d %p",
- vg->seqno, vg->name, vg,
- svg->saved_vg_new->seqno,
- svg->saved_vg_new);
- }
-
- if (vg && new) {
- if (!svg->saved_vg_old)
- log_debug_cache("lvmcache: get new saved_vg %d %s %p",
- vg->seqno, vg->name, vg);
- else
- log_debug_cache("lvmcache: get new saved_vg %d %s %p old is %d %p",
- vg->seqno, vg->name, vg,
- svg->saved_vg_old->seqno,
- svg->saved_vg_old);
-
- if (svg->saved_vg_old && (svg->saved_vg_old->seqno < vg->seqno)) {
- log_debug_cache("lvmcache: inval saved_vg_old %d %p for new %d %p %s",
- svg->saved_vg_old->seqno, svg->saved_vg_old,
- vg->seqno, vg, vg->name);
-
- _saved_vg_inval(svg, 1, 0);
- }
- }
-
- if (!vg && new && svg->saved_vg_old)
- log_warn("lvmcache_get_saved_vg pre %d wanted new but only have old %d %s",
- precommitted,
- svg->saved_vg_old->seqno,
- svg->saved_vg_old->name);
-
- if (!vg && old && svg->saved_vg_new)
- log_warn("lvmcache_get_saved_vg pre %d wanted old but only have new %d %s",
- precommitted,
- svg->saved_vg_new->seqno,
- svg->saved_vg_new->name);
-out:
- if (!vg)
- log_debug_cache("lvmcache: no saved pre %d %s", precommitted, vgid);
- return vg;
-}
-
-struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid)
-{
- struct saved_vg *svg;
- struct volume_group *vg = NULL;
- int old = 0;
- int new = 0;
-
- if (!(svg = _saved_vg_from_vgid(vgid)))
- goto out;
-
- if (svg->saved_vg_committed) {
- vg = svg->saved_vg_new;
- new = 1;
- } else {
- vg = svg->saved_vg_old;
- old = 1;
- }
-
- if (vg && old) {
- if (!svg->saved_vg_new)
- log_debug_cache("lvmcache: get_latest old saved_vg %d %s %p",
- vg->seqno, vg->name, vg);
- else
- log_debug_cache("lvmcache: get_latest old saved_vg %d %s %p new is %d %p",
- vg->seqno, vg->name, vg,
- svg->saved_vg_new->seqno,
- svg->saved_vg_new);
- }
-
- if (vg && new) {
- if (!svg->saved_vg_old)
- log_debug_cache("lvmcache: get_latest new saved_vg %d %s %p",
- vg->seqno, vg->name, vg);
- else
- log_debug_cache("lvmcache: get_latest new saved_vg %d %s %p old is %d %p",
- vg->seqno, vg->name, vg,
- svg->saved_vg_old->seqno,
- svg->saved_vg_old);
-
- if (svg->saved_vg_old && (svg->saved_vg_old->seqno < vg->seqno)) {
- log_debug_cache("lvmcache: inval saved_vg_old %d %p for new %d %p %s",
- svg->saved_vg_old->seqno, svg->saved_vg_old,
- vg->seqno, vg, vg->name);
-
- _saved_vg_inval(svg, 1, 0);
- }
- }
-out:
- if (!vg)
- log_debug_cache("lvmcache: no saved vg latest %s", vgid);
- return vg;
-}
-
-void lvmcache_drop_saved_vgid(const char *vgid)
-{
- struct saved_vg *svg;
-
- if ((svg = _saved_vg_from_vgid(vgid)))
- _saved_vg_inval(svg, 1, 1);
-}
-
-/*
- * Remote node uses this to upgrade precommitted metadata to commited state
- * when receives vg_commit notification.
- * (Note that devices can be suspended here, if so, precommitted metadata are already read.)
- */
-void lvmcache_commit_metadata(const char *vgname)
-{
- struct lvmcache_vginfo *vginfo;
- struct saved_vg *svg;
-
- if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)))
- return;
-
- if ((svg = _saved_vg_from_vgid(vginfo->vgid)))
- svg->saved_vg_committed = 1;
-}
-
-void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
-{
- if (!_saved_vg_hash)
- return;
-
- if (lvmcache_vgname_is_locked(VG_GLOBAL))
- return;
-
- /* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
- if (!strcmp(vgname, VG_ORPHANS)) {
- _drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0);
- } else
- _drop_metadata(vgname, drop_precommitted);
-}
-
/*
* Ensure vgname2 comes after vgname1 alphabetically.
* Orphan locks come last.
@@ -2514,11 +2130,6 @@ static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
dm_hash_get_key(_lock_hash, n));
}
-static void _destroy_saved_vg(struct saved_vg *svg)
-{
- _saved_vg_free(svg, 1, 1);
-}
-
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
{
struct dm_hash_node *n;
@@ -2555,12 +2166,6 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
_lock_hash = NULL;
}
- if (_saved_vg_hash) {
- dm_hash_iter(_saved_vg_hash, (dm_hash_iterate_fn) _destroy_saved_vg);
- dm_hash_destroy(_saved_vg_hash);
- _saved_vg_hash = NULL;
- }
-
if (!dm_list_empty(&_vginfos))
log_error(INTERNAL_ERROR "_vginfos list should be empty");
dm_list_init(&_vginfos);
diff --git a/lib/locking/Makefile.in b/lib/locking/Makefile.in
deleted file mode 100644
index 78f380ffa..000000000
--- a/lib/locking/Makefile.in
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
-# Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-top_builddir = @top_builddir@
-
-SOURCES = cluster_locking.c
-
-LIB_SHARED = liblvm2clusterlock.$(LIB_SUFFIX)
-LIB_VERSION = $(LIB_VERSION_LVM)
-
-include $(top_builddir)/make.tmpl
-
-install install_cluster: install_lvm2_plugin
diff --git a/lib/locking/cluster_locking.c b/lib/locking/cluster_locking.c
deleted file mode 100644
index 0830b4861..000000000
--- a/lib/locking/cluster_locking.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2009 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Locking functions for LVM.
- * The main purpose of this part of the library is to serialise LVM
- * management operations across a cluster.
- */
-
-#include "lib/misc/lib.h"
-#include "daemons/clvmd/clvm.h"
-#include "lib/misc/lvm-string.h"
-#include "lib/locking/locking.h"
-#include "locking_types.h"
-#include "lib/commands/toolcontext.h"
-
-#include <assert.h>
-#include <stddef.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#ifndef CLUSTER_LOCKING_INTERNAL
-int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags, const struct logical_volume *lv __attribute__((unused)));
-int query_resource(const char *resource, const char *node, int *mode);
-void locking_end(void);
-int locking_init(int type, struct dm_config_tree *cf, uint32_t *flags);
-#endif
-
-typedef struct lvm_response {
- char node[255];
- char *response;
- int status;
- int len;
-} lvm_response_t;
-
-/*
- * This gets stuck at the start of memory we allocate so we
- * can sanity-check it at deallocation time
- */
-#define LVM_SIGNATURE 0x434C564D
-
-/*
- * 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;
-
-/* FIXME Install SIGPIPE handler? */
-
-/* Open connection to the Cluster Manager daemon */
-static int _open_local_sock(int suppress_messages)
-{
- int local_socket;
- struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
-
- if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
- log_error("%s: clvmd socket name too long.", CLVMD_SOCKNAME);
- return -1;
- }
-
- /* Open local socket */
- if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
- log_error_suppress(suppress_messages, "Local socket "
- "creation failed: %s", strerror(errno));
- return -1;
- }
-
-
- if (connect(local_socket,(struct sockaddr *) &sockaddr,
- sizeof(sockaddr))) {
- int saved_errno = errno;
-
- log_error_suppress(suppress_messages, "connect() failed "
- "on local socket: %s", strerror(errno));
- if (close(local_socket))
- stack;
-
- 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] __attribute__((aligned(8)));
- struct clvm_header *outheader = (struct clvm_header *) outbuf;
- int len;
- unsigned off;
- int buflen;
- int err;
-
- /* Send it to CLVMD */
- rewrite:
- if ( (err = write(_clvmd_sock, inbuf, inlen)) != inlen) {
- if (err == -1 && errno == EINTR)
- goto rewrite;
- log_error("Error writing data to clvmd: %s", strerror(errno));
- return 0;
- }
-
- /* Get the response */
- reread:
- if ((len = read(_clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
- if (errno == EINTR)
- goto reread;
- log_error("Error reading data from clvmd: %s", strerror(errno));
- return 0;
- }
-
- if (len == 0) {
- log_error("EOF reading CLVMD");
- errno = ENOTCONN;
- return 0;
- }
-
- /* Allocate buffer */
- buflen = len + outheader->arglen;
- *retbuf = dm_malloc(buflen);
- if (!*retbuf) {
- errno = ENOMEM;
- return 0;
- }
-
- /* 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,
- buflen - off - offsetof(struct clvm_header, args));
- if (len > 0)
- off += len;
- }
-
- /* Was it an error ? */
- 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;
-}
-
-/* Build the structure header and parse-out wildcard node names */
-/* FIXME: Cleanup implicit casts of clvmd_cmd (int, char, uint8_t, etc). */
-static void _build_header(struct clvm_header *head, int clvmd_cmd, const char *node,
- int len)
-{
- head->cmd = clvmd_cmd;
- head->status = 0;
- head->flags = 0;
- head->xid = 0;
- head->clientid = 0;
- head->arglen = len;
-
- /*
- * Handle special node names.
- */
- if (!node || !strcmp(node, NODE_ALL))
- head->node[0] = '\0';
- else if (!strcmp(node, NODE_LOCAL)) {
- head->node[0] = '\0';
- head->flags = CLVMD_FLAG_LOCAL;
- } else if (!strcmp(node, NODE_REMOTE)) {
- head->node[0] = '\0';
- head->flags = CLVMD_FLAG_REMOTE;
- } else
- strcpy(head->node, node);
-}
-
-/*
- * Send a message to a(or all) node(s) in the cluster and wait for replies
- */
-static int _cluster_request(char clvmd_cmd, const char *node, void *data, int len,
- lvm_response_t ** response, int *num)
-{
- char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1] __attribute__((aligned(8)));
- 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) {
- if ((_clvmd_sock = _open_local_sock(0)) == -1)
- return_0;
- }
-
- /* 1 byte is used from struct clvm_header.args[1], so -> len - 1 */
- _build_header(head, clvmd_cmd, node, len - 1);
- memcpy(head->node + strlen(head->node) + 1, data, len);
-
- status = _send_request(outbuf, sizeof(struct clvm_header) +
- strlen(head->node) + len - 1, &retbuf);
- if (!status)
- goto_out;
-
- /* 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
- */
- *response = NULL;
- if (!(rarray = dm_malloc(sizeof(lvm_response_t) * num_responses))) {
- errno = ENOMEM;
- status = 0;
- goto_out;
- }
-
- /* 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;
-
- memcpy(&rarray[i].status, inptr, sizeof(int));
- inptr += sizeof(int);
-
- rarray[i].response = dm_malloc(strlen(inptr) + 1);
- if (rarray[i].response == NULL) {
- /* Free up everything else and return error */
- int j;
- for (j = 0; j < i; j++)
- dm_free(rarray[i].response);
- dm_free(rarray);
- errno = ENOMEM;
- status = 0;
- goto_out;
- }
-
- strcpy(rarray[i].response, inptr);
- rarray[i].len = strlen(inptr);
- inptr += strlen(inptr) + 1;
- i++;
- }
- *num = num_responses;
- *response = rarray;
-
- out:
- dm_free(retbuf);
-
- return status;
-}
-
-/* Free reply array */
-static int _cluster_free_request(lvm_response_t * response, int num)
-{
- int i;
-
- for (i = 0; i < num; i++) {
- dm_free(response[i].response);
- }
-
- dm_free(response);
-
- return 1;
-}
-
-static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
- uint32_t flags, const char *name)
-{
- /* TODO: convert to global usable solution and move static into cmd */
- static unsigned char last_clvmd_cmd = 0;
- int status;
- int i;
- char *args;
- const char *node = "";
- int len;
- int dmeventd_mode;
- int saved_errno;
- lvm_response_t *response = NULL;
- int num_responses;
-
- assert(name);
-
- len = strlen(name) + 3;
- args = alloca(len);
- strcpy(args + 2, name);
-
- /* args[0] holds bottom 8 bits except LCK_LOCAL (0x40). */
- args[0] = flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK | LCK_NONBLOCK | LCK_HOLD | LCK_CLUSTER_VG);
-
- args[1] = 0;
-
- if (flags & LCK_ORIGIN_ONLY)
- args[1] |= LCK_ORIGIN_ONLY_MODE;
-
- if (flags & LCK_REVERT)
- args[1] |= LCK_REVERT_MODE;
-
- if (mirror_in_sync())
- args[1] |= LCK_MIRROR_NOSYNC_MODE;
-
- if (test_mode())
- args[1] |= LCK_TEST_MODE;
-
- /*
- * We propagate dmeventd_monitor_mode() to clvmd faithfully, since
- * dmeventd monitoring is tied to activation which happens inside clvmd
- * when locking_type = 3.
- */
- dmeventd_mode = dmeventd_monitor_mode();
- if (dmeventd_mode == DMEVENTD_MONITOR_IGNORE)
- args[1] |= LCK_DMEVENTD_MONITOR_IGNORE;
-
- if (dmeventd_mode)
- args[1] |= LCK_DMEVENTD_MONITOR_MODE;
-
- if (cmd->partial_activation)
- args[1] |= LCK_PARTIAL_MODE;
-
- /*
- * 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.
- *
- * P_ locks /do/ get distributed across the cluster because they might
- * have side-effects.
- *
- * SYNC_NAMES and VG_BACKUP use the VG name directly without prefix.
- */
- if (clvmd_cmd == CLVMD_CMD_SYNC_NAMES) {
- if (flags & LCK_LOCAL) {
- node = NODE_LOCAL;
- if (clvmd_cmd == last_clvmd_cmd) {
- log_debug("Skipping redundant local sync command.");
- return 1;
- }
- }
- } else if (clvmd_cmd != CLVMD_CMD_VG_BACKUP) {
- if (strncmp(name, "P_", 2) &&
- (clvmd_cmd == CLVMD_CMD_LOCK_VG ||
- (flags & LCK_LOCAL) ||
- !(flags & LCK_CLUSTER_VG)))
- node = NODE_LOCAL;
- else if (flags & LCK_REMOTE)
- node = NODE_REMOTE;
- }
-
- last_clvmd_cmd = clvmd_cmd;
- status = _cluster_request(clvmd_cmd, node, 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) {
- 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,
- response[i].response[0] ?
- response[i].response :
- strerror(response[i].status));
- status = 0;
- errno = response[i].status;
- }
- }
-
- saved_errno = errno;
- _cluster_free_request(response, num_responses);
- errno = saved_errno;
-
- return status;
-}
-
-/* API entry point for LVM */
-#ifdef CLUSTER_LOCKING_INTERNAL
-static int _lock_resource(struct cmd_context *cmd, const char *resource,
- uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
-#else
- int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
-#endif
-{
- char lockname[PATH_MAX];
- int clvmd_cmd = 0;
- const char *lock_scope;
- const char *lock_type;
-
- assert(strlen(resource) < sizeof(lockname));
- assert(resource);
-
- switch (flags & LCK_SCOPE_MASK) {
- case LCK_ACTIVATION:
- return 1;
- case LCK_VG:
- if (!strcmp(resource, VG_SYNC_NAMES)) {
- log_very_verbose("Requesting sync names.");
- return _lock_for_cluster(cmd, CLVMD_CMD_SYNC_NAMES,
- flags & ~LCK_HOLD, resource);
- }
- if (flags == LCK_VG_BACKUP) {
- log_very_verbose("Requesting backup of VG metadata for %s",
- resource);
- return _lock_for_cluster(cmd, CLVMD_CMD_VG_BACKUP,
- LCK_CLUSTER_VG, resource);
- }
-
- /* If the VG name is empty then lock the unused PVs */
- if (dm_snprintf(lockname, sizeof(lockname), "%c_%s",
- (is_orphan_vg(resource) ||
- is_global_vg(resource) ||
- (flags & LCK_CACHE)) ? 'P' : 'V',
- resource) < 0) {
- log_error("Locking resource %s too long.", resource);
- return 0;
- }
-
- lock_scope = "VG";
- clvmd_cmd = CLVMD_CMD_LOCK_VG;
- /*
- * Old clvmd does not expect LCK_HOLD which was already processed
- * in lock_vol, mask it for compatibility reasons.
- */
- if (flags != LCK_VG_COMMIT && flags != LCK_VG_REVERT)
- flags &= ~LCK_HOLD;
-
- break;
-
- case LCK_LV:
- clvmd_cmd = CLVMD_CMD_LOCK_LV;
- strcpy(lockname, resource);
- lock_scope = "LV";
- flags &= ~LCK_HOLD; /* Mask off HOLD flag */
- break;
-
- default:
- log_error("Unrecognised lock scope: %d",
- flags & LCK_SCOPE_MASK);
- return 0;
- }
-
- switch(flags & LCK_TYPE_MASK) {
- case LCK_UNLOCK:
- lock_type = "UN";
- break;
- case LCK_NULL:
- lock_type = "NL";
- break;
- case LCK_READ:
- lock_type = "CR";
- break;
- case LCK_PREAD:
- lock_type = "PR";
- break;
- case LCK_WRITE:
- lock_type = "PW";
- break;
- case LCK_EXCL:
- lock_type = "EX";
- break;
- default:
- log_error("Unrecognised lock type: %u",
- flags & LCK_TYPE_MASK);
- return 0;
- }
-
- log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
- lock_type, lock_scope,
- flags & LCK_NONBLOCK ? "|NONBLOCK" : "",
- flags & LCK_HOLD ? "|HOLD" : "",
- flags & LCK_CLUSTER_VG ? "|CLUSTER" : "",
- flags & LCK_LOCAL ? "|LOCAL" : "",
- flags & LCK_REMOTE ? "|REMOTE" : "",
- flags & LCK_CACHE ? "|CACHE" : "",
- flags & LCK_ORIGIN_ONLY ? "|ORIGIN_ONLY" : "",
- flags & LCK_REVERT ? "|REVERT" : "",
- flags);
-
- /* Send a message to the cluster manager */
- return _lock_for_cluster(cmd, clvmd_cmd, flags, lockname);
-}
-
-static int _decode_lock_type(const char *response)
-{
- if (!response)
- return LCK_NULL;
-
- if (!strcmp(response, "EX"))
- return LCK_EXCL;
-
- if (!strcmp(response, "CR"))
- return LCK_READ;
-
- if (!strcmp(response, "PR"))
- return LCK_PREAD;
-
- return_0;
-}
-
-#ifdef CLUSTER_LOCKING_INTERNAL
-static int _query_resource(const char *resource, const char *node, int *mode)
-#else
-int query_resource(const char *resource, const char *node, int *mode)
-#endif
-{
- int i, status, len, num_responses, saved_errno;
- char *args;
- lvm_response_t *response = NULL;
-
- saved_errno = errno;
- len = strlen(resource) + 3;
- args = alloca(len);
- strcpy(args + 2, resource);
-
- args[0] = 0;
- args[1] = 0;
-
- status = _cluster_request(CLVMD_CMD_LOCK_QUERY, node, args, len,
- &response, &num_responses);
- *mode = LCK_NULL;
- for (i = 0; i < num_responses; i++) {
- if (response[i].status == EHOSTDOWN)
- continue;
-
- if (!response[i].response[0])
- continue;
-
- /*
- * All nodes should use CR, or exactly one node
- * should hold EX. (PR is obsolete)
- * If two nodes report different locks,
- * something is broken - just return more important mode.
- */
- if (_decode_lock_type(response[i].response) > *mode)
- *mode = _decode_lock_type(response[i].response);
-
- log_debug_locking("Lock held for %s, node %s : %s", resource,
- response[i].node, response[i].response);
- }
-
- _cluster_free_request(response, num_responses);
- errno = saved_errno;
-
- return status;
-}
-
-#ifdef CLUSTER_LOCKING_INTERNAL
-static void _locking_end(void)
-#else
-void locking_end(void)
-#endif
-{
- if (_clvmd_sock != -1 && close(_clvmd_sock))
- stack;
-
- _clvmd_sock = -1;
-}
-
-#ifdef CLUSTER_LOCKING_INTERNAL
-static void _reset_locking(void)
-#else
-void reset_locking(void)
-#endif
-{
- if (close(_clvmd_sock))
- stack;
-
- _clvmd_sock = _open_local_sock(0);
- if (_clvmd_sock == -1)
- stack;
-}
-
-#ifdef CLUSTER_LOCKING_INTERNAL
-int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd,
- int suppress_messages)
-{
- locking->lock_resource = _lock_resource;
- locking->query_resource = _query_resource;
- locking->fin_locking = _locking_end;
- locking->reset_locking = _reset_locking;
- locking->flags = LCK_PRE_MEMLOCK | LCK_CLUSTERED | LCK_SUPPORTS_REMOTE_QUERIES;
-
- _clvmd_sock = _open_local_sock(suppress_messages);
- if (_clvmd_sock == -1)
- return 0;
-
- return 1;
-}
-#else
-int locking_init(int type, struct dm_config_tree *cf, uint32_t *flags)
-{
- _clvmd_sock = _open_local_sock(0);
- if (_clvmd_sock == -1)
- return 0;
-
- /* Ask LVM to lock memory before calling us */
- *flags |= LCK_PRE_MEMLOCK;
- *flags |= LCK_CLUSTERED;
-
- return 1;
-}
-#endif
diff --git a/lib/locking/external_locking.c b/lib/locking/external_locking.c
deleted file mode 100644
index a1169a561..000000000
--- a/lib/locking/external_locking.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2006 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "lib/misc/lib.h"
-#include "locking_types.h"
-#include "lib/config/defaults.h"
-#include "lib/misc/sharedlib.h"
-#include "lib/commands/toolcontext.h"
-#include "lib/activate/activate.h"
-
-static void *_locking_lib = NULL;
-static void (*_reset_fn) (void) = NULL;
-static void (*_end_fn) (void) = NULL;
-static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
- uint32_t flags) = NULL;
-static int (*_init_fn) (int type, struct dm_config_tree * cft,
- uint32_t *flags) = NULL;
-static int (*_lock_query_fn) (const char *resource, int *mode) = NULL;
-
-static int _lock_resource(struct cmd_context *cmd, const char *resource,
- uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
-{
- if (!_lock_fn)
- return 0;
-
- if (!strcmp(resource, VG_SYNC_NAMES)) {
- /* Hide this lock request from external locking */
- fs_unlock();
- return 1;
- }
-
- return _lock_fn(cmd, resource, flags);
-}
-
-static void _fin_external_locking(void)
-{
- if (_end_fn)
- _end_fn();
-
- dlclose(_locking_lib);
-
- _locking_lib = NULL;
- _init_fn = NULL;
- _end_fn = NULL;
- _lock_fn = NULL;
- _reset_fn = NULL;
-}
-
-static void _reset_external_locking(void)
-{
- if (_reset_fn)
- _reset_fn();
-}
-
-int init_external_locking(struct locking_type *locking, struct cmd_context *cmd,
- int suppress_messages)
-{
- const char *libname;
-
- if (_locking_lib) {
- log_error_suppress(suppress_messages, "External locking already initialised");
- return 1;
- }
-
- locking->lock_resource = _lock_resource;
- locking->fin_locking = _fin_external_locking;
- locking->reset_locking = _reset_external_locking;
- locking->flags = 0;
-
- if (!(libname = find_config_tree_str(cmd, global_locking_library_CFG, NULL)))
- return_0;
-
- if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1)))
- return_0;
-
- /* Get the functions we need */
- if (!(_init_fn = dlsym(_locking_lib, "locking_init")) ||
- !(_lock_fn = dlsym(_locking_lib, "lock_resource")) ||
- !(_reset_fn = dlsym(_locking_lib, "reset_locking")) ||
- !(_end_fn = dlsym(_locking_lib, "locking_end"))) {
- log_error_suppress(suppress_messages, "Shared library %s does "
- "not contain locking functions", libname);
- dlclose(_locking_lib);
- _locking_lib = NULL;
- return 0;
- }
-
- if (!(_lock_query_fn = dlsym(_locking_lib, "query_resource")))
- log_warn_suppress(suppress_messages, "WARNING: %s: _query_resource() "
- "missing: Using inferior activation method.", libname);
-
- log_verbose("Loaded external locking library %s", libname);
- return _init_fn(2, cmd->cft, &locking->flags);
-}
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index db6233b2a..0e5658fdc 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -116,101 +116,16 @@ int init_locking(int type, struct cmd_context *cmd, int suppress_messages)
_blocking_supported = find_config_tree_bool(cmd, global_wait_for_locks_CFG, NULL);
- switch (type) {
- case 0:
- init_no_locking(&_locking, cmd, suppress_messages);
- log_warn_suppress(suppress_messages,
- "WARNING: Locking disabled. Be careful! "
- "This could corrupt your metadata.");
- return 1;
-
- case 1:
- log_very_verbose("%sFile-based locking selected.",
- _blocking_supported ? "" : "Non-blocking ");
+ if (type != 1)
+ log_warn("WARNING: locking_type deprecated, using file locking.");
- if (!init_file_locking(&_locking, cmd, suppress_messages)) {
- log_error_suppress(suppress_messages,
- "File-based locking initialisation failed.");
- break;
- }
- return 1;
-
-#ifdef HAVE_LIBDL
- case 2:
- if (!is_static()) {
- log_very_verbose("External locking selected.");
- if (init_external_locking(&_locking, cmd, suppress_messages))
- return 1;
- }
- if (!find_config_tree_bool(cmd, global_fallback_to_clustered_locking_CFG, NULL)) {
- log_error_suppress(suppress_messages, "External locking initialisation failed.");
- break;
- }
-#endif
-
- log_very_verbose("Falling back to internal clustered locking.");
- /* Fall through */
-
- case 3:
-#ifdef CLUSTER_LOCKING_INTERNAL
- log_very_verbose("Cluster locking selected.");
- if (!init_cluster_locking(&_locking, cmd, suppress_messages)) {
- log_error_suppress(suppress_messages,
- "Internal cluster locking initialisation failed.");
- break;
- }
- return 1;
-#else
- log_warn("WARNING: Using locking_type=1, ignoring locking_type=3.");
+ if (type == 3)
log_warn("WARNING: See lvmlockd(8) for information on using cluster/clvm VGs.");
- type = 1;
- log_very_verbose("%sFile-based locking selected.",
- _blocking_supported ? "" : "Non-blocking ");
+ log_very_verbose("%sFile-based locking selected.", _blocking_supported ? "" : "Non-blocking ");
- if (!init_file_locking(&_locking, cmd, suppress_messages)) {
- log_error_suppress(suppress_messages,
- "File-based locking initialisation failed.");
- break;
- }
- return 1;
-#endif
-
- case 4:
- log_verbose("Read-only locking selected. "
- "Only read operations permitted.");
- if (!init_readonly_locking(&_locking, cmd, suppress_messages))
- break;
- return 1;
-
- case 5:
- init_dummy_locking(&_locking, cmd, suppress_messages);
- log_verbose("Locking disabled for read-only access.");
- return 1;
-
- default:
- log_error("Unknown locking type requested.");
- return 0;
- }
-
- if ((type == 2 || type == 3) &&
- find_config_tree_bool(cmd, global_fallback_to_local_locking_CFG, NULL)) {
- log_warn_suppress(suppress_messages, "WARNING: Falling back to local file-based locking.");
- log_warn_suppress(suppress_messages,
- "Volume Groups with the clustered attribute will "
- "be inaccessible.");
- if (init_file_locking(&_locking, cmd, suppress_messages))
- return 1;
-
- log_error_suppress(suppress_messages,
- "File-based locking initialisation failed.");
- }
-
- if (!ignorelockingfailure())
- return 0;
-
- log_verbose("Locking disabled - only read operations permitted.");
- init_readonly_locking(&_locking, cmd, suppress_messages);
+ if (!init_file_locking(&_locking, cmd, suppress_messages))
+ log_error_suppress(suppress_messages, "File-based locking initialisation failed.");
return 1;
}
@@ -325,13 +240,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
!lvmcache_verify_lock_order(vol))
return_0;
- if ((flags == LCK_VG_DROP_CACHE) ||
- (strcmp(vol, VG_GLOBAL) && strcmp(vol, VG_SYNC_NAMES))) {
- /* Skip dropping cache for internal VG names #global, #sync_names */
- log_debug_locking("Dropping cache for %s.", vol);
- lvmcache_drop_metadata(vol, 0);
- }
-
break;
case LCK_LV:
/* All LV locks are non-blocking. */
@@ -372,24 +280,7 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
*/
int activate_lv_excl(struct cmd_context *cmd, const struct logical_volume *lv)
{
- /* Non-clustered VGs are only activated locally. */
- if (!vg_is_clustered(lv->vg))
- return activate_lv_excl_local(cmd, lv);
-
- if (lv_is_active_exclusive_locally(lv))
- return 1;
-
- if (!activate_lv_excl_local(cmd, lv))
- return_0;
-
- if (lv_is_active_exclusive(lv))
- return 1;
-
- /* FIXME Deal with error return codes. */
- if (!activate_lv_excl_remote(cmd, lv))
- return_0;
-
- return 1;
+ return activate_lv_excl_local(cmd, lv);
}
/* Lock a list of LVs */
@@ -428,35 +319,6 @@ int locking_is_clustered(void)
return (_locking.flags & LCK_CLUSTERED) ? 1 : 0;
}
-int locking_supports_remote_queries(void)
-{
- return (_locking.flags & LCK_SUPPORTS_REMOTE_QUERIES) ? 1 : 0;
-}
-
-int cluster_lock_held(const char *vol, const char *node, int *exclusive)
-{
- int mode = LCK_NULL;
-
- if (!locking_is_clustered())
- return 0;
-
- if (!_locking.query_resource)
- return -1;
-
- /*
- * If an error occured, expect that volume is active
- */
- if (!_locking.query_resource(vol, node, &mode)) {
- stack;
- return 1;
- }
-
- if (exclusive)
- *exclusive = (mode == LCK_EXCL);
-
- return mode == LCK_NULL ? 0 : 1;
-}
-
int sync_local_dev_names(struct cmd_context* cmd)
{
memlock_unlock(cmd);
diff --git a/lib/locking/locking_types.h b/lib/locking/locking_types.h
index c4c832aea..99aa9640d 100644
--- a/lib/locking/locking_types.h
+++ b/lib/locking/locking_types.h
@@ -50,9 +50,3 @@ int init_readonly_locking(struct locking_type *locking, struct cmd_context *cmd,
int init_file_locking(struct locking_type *locking, struct cmd_context *cmd,
int suppress_messages);
-
-int init_external_locking(struct locking_type *locking, struct cmd_context *cmd,
- int suppress_messages);
-
-int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd,
- int suppress_messages);
diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c
deleted file mode 100644
index fa066cc7a..000000000
--- a/lib/locking/no_locking.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2007 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 Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "lib/misc/lib.h"
-#include "lib/locking/locking.h"
-#include "locking_types.h"
-#include "lib/misc/lvm-string.h"
-#include "lib/activate/activate.h"
-
-/*
- * No locking
- */
-
-static void _no_fin_locking(void)
-{
-}
-
-static void _no_reset_locking(void)
-{
-}
-
-static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
- uint32_t flags, const struct logical_volume *lv)
-{
- switch (flags & LCK_SCOPE_MASK) {
- case LCK_ACTIVATION:
- break;
- case LCK_VG:
- if (!strcmp(resource, VG_SYNC_NAMES))
- fs_unlock();
- break;
- case LCK_LV:
- switch (flags & LCK_TYPE_MASK) {
- case LCK_NULL:
- return lv_deactivate(cmd, resource, lv_committed(lv));
- case LCK_UNLOCK:
- return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0, 0,
- (flags & LCK_REVERT) ? 1 : 0, lv_committed(lv));
- case LCK_READ:
- return lv_activate_with_filter(cmd, resource, 0, (lv->status & LV_NOSCAN) ? 1 : 0,
- (lv->status & LV_TEMPORARY) ? 1 : 0, lv_committed(lv));
- case LCK_WRITE:
- return lv_suspend_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1 : 0, 0,
- lv_committed(lv), lv);
- case LCK_EXCL:
- return lv_activate_with_filter(cmd, resource, 1, (lv->status & LV_NOSCAN) ? 1 : 0,
- (lv->status & LV_TEMPORARY) ? 1 : 0, lv_committed(lv));
- default:
- break;
- }
- break;
- default:
- log_error("Unrecognised lock scope: %d",
- flags & LCK_SCOPE_MASK);
- return 0;
- }
-
- return 1;
-}
-
-static int _no_query_resource(const char *resource, const char *node, int *mode)
-{
- log_very_verbose("Locking is disabled: Treating lock %s as not held.",
- resource);
- return 1;
-}
-
-static int _readonly_lock_resource(struct cmd_context *cmd,
- const char *resource,
- uint32_t flags, const struct logical_volume *lv)
-{
- if ((flags & LCK_TYPE_MASK) == LCK_WRITE &&
- (flags & LCK_SCOPE_MASK) == LCK_VG &&
- !(flags & LCK_CACHE) &&
- strcmp(resource, VG_GLOBAL)) {
- log_error("Read-only locking type set. "
- "Write locks are prohibited.");
- return 0;
- }
-
- return _no_lock_resource(cmd, resource, flags, lv);
-}
-
-void init_no_locking(struct locking_type *locking, struct cmd_context *cmd __attribute__((unused)),
- int suppress_messages)
-{
- locking->lock_resource = _no_lock_resource;
- locking->query_resource = _no_query_resource;
- locking->reset_locking = _no_reset_locking;
- locking->fin_locking = _no_fin_locking;
- locking->flags = LCK_CLUSTERED;
-}
-
-int init_readonly_locking(struct locking_type *locking, struct cmd_context *cmd __attribute__((unused)),
- int suppress_messages)
-{
- locking->lock_resource = _readonly_lock_resource;
- locking->query_resource = _no_query_resource;
- locking->reset_locking = _no_reset_locking;
- locking->fin_locking = _no_fin_locking;
- locking->flags = 0;
-
- return 1;
-}
-
-void init_dummy_locking(struct locking_type *locking, struct cmd_context *cmd __attribute__((unused)),
- int suppress_messages)
-{
- locking->lock_resource = _readonly_lock_resource;
- locking->query_resource = _no_query_resource;
- locking->reset_locking = _no_reset_locking;
- locking->fin_locking = _no_fin_locking;
- locking->flags = LCK_CLUSTERED;
-}
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 68507dc79..f930633c7 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -1478,21 +1478,11 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
switch (activate) {
case CHANGE_AN:
-deactivate:
log_verbose("Deactivating logical volume %s.", display_lvname(lv));
if (!deactivate_lv(cmd, lv))
return_0;
break;
case CHANGE_ALN:
- if (vg_is_clustered(lv->vg) && (needs_exclusive || _lv_is_exclusive(lv))) {
- if (!lv_is_active_locally(lv)) {
- log_error("Cannot deactivate remotely exclusive device %s locally.",
- display_lvname(lv));
- return 0;
- }
- /* Unlock whole exclusive activation */
- goto deactivate;
- }
log_verbose("Deactivating logical volume %s locally.",
display_lvname(lv));
if (!deactivate_lv_local(cmd, lv))
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index b78e5d00e..e02313244 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7366,7 +7366,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
struct logical_volume *lv, *origin_lv = NULL;
struct logical_volume *pool_lv = NULL;
struct logical_volume *tmp_lv;
- const struct logical_volume *lock_lv;
struct lv_segment *seg, *pool_seg;
int thin_pool_was_active = -1; /* not scanned, inactive, active */
int historical;
@@ -7528,18 +7527,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
log_error("Caching of origin cache volume smaller then chunk size is unsupported.");
return NULL;
}
-
- /* Validate cache origin is exclusively active */
- lock_lv = lv_lock_holder(origin_lv);
- if (vg_is_clustered(origin_lv->vg) &&
- locking_is_clustered() &&
- locking_supports_remote_queries() &&
- lv_is_active(lock_lv) &&
- !lv_is_active_exclusive(lock_lv)) {
- log_error("Cannot cache not exclusively active origin volume %s.",
- display_lvname(origin_lv));
- return NULL;
- }
} else if (seg_is_cache(lp)) {
if (!pool_lv) {
log_error(INTERNAL_ERROR "Pool LV for cache is missing.");
@@ -7555,13 +7542,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (!(create_segtype = get_segtype_from_string(vg->cmd, SEG_TYPE_NAME_STRIPED)))
return_0;
} else if (seg_is_mirrored(lp) || (seg_is_raid(lp) && !seg_is_any_raid0(lp))) {
- if (is_change_activating(lp->activate) && (lp->activate != CHANGE_AEY) &&
- vg_is_clustered(vg) && seg_is_mirrored(lp) && !seg_is_raid(lp) &&
- !cluster_mirror_is_available(vg->cmd)) {
- log_error("Shared cluster mirrors are not available.");
- return NULL;
- }
-
if (!(lp->region_size = adjusted_mirror_region_size(vg->cmd,
vg->extent_size,
lp->extents,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 1bbea19a7..3f177b061 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1843,13 +1843,6 @@ int vgs_are_compatible(struct cmd_context *cmd __attribute__((unused)),
return 0;
}
- /* Clustering attribute must be the same */
- if (vg_is_clustered(vg_to) != vg_is_clustered(vg_from)) {
- log_error("Clustered attribute differs for \"%s\" and \"%s\"",
- vg_to->name, vg_from->name);
- return 0;
- }
-
/* Check no conflicts with LV names */
dm_list_iterate_items(lvl1, &vg_to->lvs) {
name1 = lvl1->lv->name;
@@ -4564,123 +4557,6 @@ void free_pv_fid(struct physical_volume *pv)
pv_set_fid(pv, NULL);
}
-/* This is only called by lv_from_lvid, which is only called from
- * activate.c so we know the appropriate VG lock is already held and
- * the vg_read_internal is therefore safe.
- */
-struct volume_group *vg_read_by_vgid(struct cmd_context *cmd,
- const char *vgid,
- unsigned precommitted)
-{
- const char *vgname;
- struct volume_group *vg;
- uint32_t warn_flags = WARN_PV_READ | WARN_INCONSISTENT;
- int consistent = 0;
-
- /*
- * When using lvmlockd we should never reach this point.
- * The VG is locked, then vg_read() is done, which gets
- * the latest VG from lvmetad, or disk if lvmetad has
- * been invalidated. When we get here the VG should
- * always be cached and returned above.
- */
- if (lvmlockd_use())
- log_error(INTERNAL_ERROR "vg_read_by_vgid failed with lvmlockd");
-
- if ((vg = lvmcache_get_saved_vg(vgid, precommitted))) {
- log_debug_metadata("lvmcache: using saved_vg %s seqno %d pre %d %p",
- vg->name, vg->seqno, precommitted, vg);
- return vg;
- }
-
- /* Mustn't scan if memory locked: ensure cache gets pre-populated! */
- if (critical_section())
- log_debug_metadata("Reading VG by vgid in critical section pre %d vgid %.8s", precommitted, vgid);
-
- if (!(vgname = lvmcache_vgname_from_vgid(cmd->mem, vgid))) {
- log_debug_metadata("Reading VG by vgid %.8s no VG name found, retrying.", vgid);
- lvmcache_destroy(cmd, 1, 0);
- label_scan_destroy(cmd);
- lvmcache_label_scan(cmd);
- warn_flags |= SKIP_RESCAN;
- }
-
- if (!(vgname = lvmcache_vgname_from_vgid(cmd->mem, vgid))) {
- log_debug_metadata("Reading VG by vgid %.8s no VG name found.", vgid);
- return NULL;
- }
-
- consistent = 0;
-
- label_scan_setup_bcache();
-
- if (!(vg = _vg_read(cmd, vgname, vgid, 0, warn_flags, &consistent, precommitted))) {
- log_error("Rescan devices to look for missing VG.");
- goto scan;
- }
-
- if (vg_missing_pv_count(vg)) {
- log_error("Rescan devices to look for missing PVs.");
- release_vg(vg);
- goto scan;
- }
-
- label_scan_destroy(cmd); /* drop bcache to close devs, keep lvmcache */
- lvmcache_save_vg(vg, precommitted);
- return vg;
-
- scan:
- lvmcache_destroy(cmd, 1, 0);
- label_scan_destroy(cmd);
- lvmcache_label_scan(cmd);
- warn_flags |= SKIP_RESCAN;
-
- if (!(vg = _vg_read(cmd, vgname, vgid, 0, warn_flags, &consistent, precommitted)))
- goto fail;
-
- label_scan_destroy(cmd); /* drop bcache to close devs, keep lvmcache */
-
- lvmcache_save_vg(vg, precommitted);
- return vg;
-
- fail:
- label_scan_destroy(cmd); /* drop bache to close devs, keep lvmcache */
- log_debug_metadata("Reading VG by vgid %.8s not found.", vgid);
- return NULL;
-}
-
-/* Only called by activate.c */
-struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s,
- unsigned precommitted)
-{
- struct logical_volume *lv;
- struct volume_group *vg;
- const union lvid *lvid;
-
- lvid = (const union lvid *) lvid_s;
-
- log_very_verbose("Finding %svolume group for uuid %s", precommitted ? "precommitted " : "", lvid_s);
- if (!(vg = vg_read_by_vgid(cmd, (const char *)lvid->id[0].uuid, precommitted))) {
- log_error("Reading VG not found for LVID %s", lvid_s);
- return NULL;
- }
-
- log_verbose("Found volume group \"%s\" %p", vg->name, vg);
- if (vg->status & EXPORTED_VG) {
- log_error("Volume group \"%s\" is exported", vg->name);
- goto out;
- }
- if (!(lv = find_lv_in_vg_by_lvid(vg, lvid))) {
- log_very_verbose("Can't find logical volume id %s", lvid_s);
- goto out;
- }
-
- return lv;
-out:
- release_vg(vg);
- return NULL;
-}
-
const char *find_vgname_from_pvid(struct cmd_context *cmd,
const char *pvid)
{
@@ -5127,7 +5003,7 @@ int vg_flag_write_locked(struct volume_group *vg)
static int _access_vg_clustered(struct cmd_context *cmd, const struct volume_group *vg)
{
- if (vg_is_clustered(vg) && !locking_is_clustered()) {
+ if (vg_is_clustered(vg)) {
if (!cmd->ignore_clustered_vgs)
log_error("Skipping clustered volume group %s", vg->name);
else
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 3d6750f90..129267ce4 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -374,18 +374,9 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
struct logical_volume *find_lv_in_vg_by_lvid(struct volume_group *vg,
const union lvid *lvid);
-struct volume_group *vg_read_by_vgid(struct cmd_context *cmd,
- const char *vgid,
- unsigned precommitted);
-
struct lv_list *find_lv_in_lv_list(const struct dm_list *ll,
const struct logical_volume *lv);
-/* Find LV with given lvid (used during activation) */
-struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
- const char *lvid_s,
- unsigned precommitted);
-
/* FIXME Merge these functions with ones above */
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index b44c7ca53..db382d0a2 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -612,56 +612,6 @@ int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc)
return 1;
}
-/*
- * Setting the cluster attribute marks active volumes exclusive.
- *
- * FIXME: resolve logic with reacquiring proper top-level LV locks
- * and we likely can't giveup DLM locks for active LVs...
- */
-int vg_set_clustered(struct volume_group *vg, int clustered)
-{
- struct lv_list *lvl;
- int fail = 0;
-
- if (vg_is_clustered(vg) &&
- locking_is_clustered() &&
- locking_supports_remote_queries() &&
- !clustered) {
- /*
- * If the volume is locally active but not exclusively
- * we cannot determine when other nodes also use
- * locally active (CR lock), so refuse conversion.
- */
- dm_list_iterate_items(lvl, &vg->lvs)
- if ((lv_lock_holder(lvl->lv) == lvl->lv) &&
- lv_is_active(lvl->lv) &&
- !lv_is_active_exclusive_locally(lvl->lv)) {
- /* Show all non-local-exclusively active LVs
- * this includes i.e. clustered mirrors */
- log_error("Can't change cluster attribute with "
- "active logical volume %s.",
- display_lvname(lvl->lv));
- fail = 1;
- }
-
- if (fail) {
- log_print_unless_silent("Conversion is supported only for "
- "locally exclusive volumes.");
- return 0;
- }
- }
-
- if (clustered)
- vg->status |= CLUSTERED;
- else
- vg->status &= ~CLUSTERED;
-
- log_debug_metadata("Setting volume group %s as %sclustered.",
- vg->name, clustered ? "" : "not " );
-
- return 1;
-}
-
/* The input string has already been validated. */
int vg_set_system_id(struct volume_group *vg, const char *system_id)
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 3d24bba7d..620815956 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -181,7 +181,6 @@ char *vg_lock_args_dup(const struct volume_group *vg);
uint32_t vg_seqno(const struct volume_group *vg);
uint64_t vg_status(const struct volume_group *vg);
int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc);
-int vg_set_clustered(struct volume_group *vg, int clustered);
int vg_set_system_id(struct volume_group *vg, const char *system_id);
int vg_set_lock_type(struct volume_group *vg, const char *lock_type);
uint64_t vg_size(const struct volume_group *vg);
diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
index 6746b1a89..4110dec24 100644
--- a/lib/mirror/mirrored.c
+++ b/lib/mirror/mirrored.c
@@ -278,14 +278,7 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
char *log_dlid = NULL;
uint32_t log_flags = 0;
- /*
- * Use clustered mirror log for non-exclusive activation
- * in clustered VG.
- */
- if (!laopts->exclusive && vg_is_clustered(seg->lv->vg))
- clustered = 1;
-
- else if (seg->lv->vg->lock_type && !strcmp(seg->lv->vg->lock_type, "dlm")) {
+ if (seg->lv->vg->lock_type && !strcmp(seg->lv->vg->lock_type, "dlm")) {
/*
* If shared lock was used due to -asy, then we set clustered
* to use a clustered mirror log with cmirrod.
@@ -521,12 +514,6 @@ static int _mirrored_modules_needed(struct dm_pool *mem,
!list_segment_modules(mem, first_seg(seg->log_lv), modules))
return_0;
- if (vg_is_clustered(seg->lv->vg) &&
- !str_list_add(mem, modules, MODULE_NAME_CLUSTERED_MIRROR)) {
- log_error("cluster log string list allocation failed");
- return 0;
- }
-
if (!str_list_add(mem, modules, MODULE_NAME_MIRROR)) {
log_error("mirror string list allocation failed");
return 0;
diff --git a/tools/args.h b/tools/args.h
index 603a0cf49..2434f4bed 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -949,17 +949,8 @@ arg(chunksize_ARG, 'c', "chunksize", sizekb_VAL, 0, 0,
"See \\fBlvmthin\\fP(7) and \\fBlvmcache\\fP(7) for more information.\n")
arg(clustered_ARG, 'c', "clustered", bool_VAL, 0, 0,
- "#vgcreate\n"
- "Create a clustered VG using clvmd if LVM is compiled with cluster support.\n"
- "This allows multiple hosts to share a VG on shared devices.\n"
- "clvmd and a lock manager must be configured and running.\n"
- "(A clustered VG using clvmd is different from a shared VG using lvmlockd.)\n"
- "See \\fBclvmd\\fP(8) for more information about clustered VGs.\n"
- "#vgchange\n"
- "Change the clustered property of a VG using clvmd.\n"
- "See \\fBclvmd\\fP(8) for more information about clustered VGs.\n"
- "#vgsplit\n"
- "Specifies the clustered property of the new VG.\n")
+ "This option was specific to clvm and is now replaced by\n"
+ "the --shared option with \\fBlvmlockd\\fP(8).\n")
arg(colon_ARG, 'c', "colon", 0, 0, 0,
"Generate colon separated output for easier parsing in scripts or programs.\n"
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 9d407d08a..409f01c97 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1482,7 +1482,7 @@ OO_VGCHANGE: --autobackup Bool, --ignoremonitoring, --ignoreskippedcluster,
OO_VGCHANGE_META: --addtag Tag, --deltag Tag,
--logicalvolume Uint32, --maxphysicalvolumes Uint32, --alloc Alloc, --uuid,
---clustered Bool, --pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
+--pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
--physicalextentsize SizeMB, --resizeable Bool,
--profile String, --detachprofile, --metadataprofile String
@@ -1692,7 +1692,7 @@ ID: vgscan_general
OO_VGSPLIT: --autobackup Bool
# used only when the destination VG is new
-OO_VGSPLIT_NEW: --alloc Alloc, --clustered Bool,
+OO_VGSPLIT_NEW: --alloc Alloc,
--maxlogicalvolumes Uint32, --maxphysicalvolumes Uint32,
--metadatatype MetadataType, --vgmetadatacopies MetadataCopiesVG
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 036b851b5..481cb4cce 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -74,13 +74,6 @@ static int _lvchange_permission(struct cmd_context *cmd,
return 0;
}
- if (lv_is_mirrored(lv) && vg_is_clustered(lv->vg) &&
- lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) {
- log_error("Cannot change permissions of mirror %s while active.",
- display_lvname(lv));
- return 0;
- }
-
if (lv_access & LVM_WRITE) {
lv->status |= LVM_WRITE;
log_verbose("Setting logical volume %s read/write.",
@@ -362,12 +355,6 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
- if (vg_is_clustered(lv->vg) && lv_is_active(lv)) {
- log_error("Can't get exclusive access to clustered volume %s.",
- display_lvname(lv));
- return 0;
- }
-
if (monitored != DMEVENTD_MONITOR_IGNORE)
init_dmeventd_monitor(monitored);
init_mirror_in_sync(0);
@@ -617,16 +604,6 @@ static int _lvchange_persistent(struct cmd_context *cmd,
}
activate = CHANGE_AEY;
- if (vg_is_clustered(lv->vg) &&
- locking_is_clustered() &&
- locking_supports_remote_queries() &&
- !lv_is_active_exclusive_locally(lv)) {
- /* Reliable reactivate only locally */
- log_print_unless_silent("Remotely active LV %s needs "
- "individual reactivation.",
- display_lvname(lv));
- activate = CHANGE_ALY;
- }
}
/* Ensuring LV is not active */
@@ -1255,12 +1232,6 @@ static int _lvchange_properties_check(struct cmd_context *cmd,
return 0;
}
- if (vg_is_clustered(lv->vg) && lv_is_cache_origin(lv) && lv_is_raid(lv)) {
- log_error("Unable to change internal LV %s directly in a cluster.",
- display_lvname(lv));
- return 0;
- }
-
return 1;
}
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 536b92589..aebf3e981 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -780,15 +780,6 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
*new_log_count = arg_int_value(cmd, mirrorlog_ARG, lp->corelog ? MIRROR_LOG_CORE : DEFAULT_MIRRORLOG);
- /*
- * No mirrored logs for cluster mirrors until
- * log daemon is multi-threaded.
- */
- if ((*new_log_count == MIRROR_LOG_MIRRORED) && vg_is_clustered(lv->vg)) {
- log_error("Log type, \"mirrored\", is unavailable to cluster mirrors.");
- return 0;
- }
-
log_verbose("Setting logging type to %s.", get_mirror_log_name(*new_log_count));
/*
@@ -2054,10 +2045,6 @@ static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
log_print_unless_silent("Delaying merge since snapshot is open.");
merge_on_activate = 1;
}
- } else if (vg_is_clustered(origin->vg) && lv_is_active(origin)) {
- /* When it's active somewhere else */
- log_print_unless_silent("Delaying merge since origin is remotely active.");
- merge_on_activate = 1;
}
init_snapshot_merge(snap_seg, origin);
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index be2a31b0a..4f4e917b0 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2698,11 +2698,6 @@ static int _init_lvmlockd(struct cmd_context *cmd)
}
}
- if (use_lvmlockd && locking_is_clustered()) {
- log_error("ERROR: configuration setting use_lvmlockd cannot be used with clustered locking_type 3.");
- return 0;
- }
-
lvmlockd_disconnect(); /* start over when tool context is refreshed */
lvmlockd_socket = getenv("LVM_LVMLOCKD_SOCKET");
if (!lvmlockd_socket)
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 1daf3640a..0fcabb31f 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -67,10 +67,6 @@ static int _pvmove_target_present(struct cmd_context *cmd, int clustered)
static unsigned _pvmove_is_exclusive(struct cmd_context *cmd,
struct volume_group *vg)
{
- if (vg_is_clustered(vg))
- if (!_pvmove_target_present(cmd, 1))
- return 1;
-
return 0;
}
diff --git a/tools/toollib.c b/tools/toollib.c
index 832fae644..baf84ad2a 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -726,7 +726,6 @@ int vgcreate_params_set_defaults(struct cmd_context *cmd,
vp_def->max_pv = vg->max_pv;
vp_def->max_lv = vg->max_lv;
vp_def->alloc = vg->alloc;
- vp_def->clustered = vg_is_clustered(vg);
vp_def->vgmetadatacopies = vg->mda_copies;
vp_def->system_id = vg->system_id; /* No need to clone this */
} else {
@@ -741,7 +740,6 @@ int vgcreate_params_set_defaults(struct cmd_context *cmd,
vp_def->max_pv = DEFAULT_MAX_PV;
vp_def->max_lv = DEFAULT_MAX_LV;
vp_def->alloc = DEFAULT_ALLOC_POLICY;
- vp_def->clustered = DEFAULT_CLUSTERED;
vp_def->vgmetadatacopies = DEFAULT_VGMETADATACOPIES;
vp_def->system_id = cmd->system_id;
}
@@ -761,11 +759,14 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
{
const char *system_id_arg_str;
const char *lock_type = NULL;
- int locking_type;
int use_lvmlockd;
- int use_clvmd;
lock_type_t lock_type_num;
+ if (arg_is_set(cmd, clustered_ARG)) {
+ log_error("The clustered option is deprecated, see --shared.");
+ return 0;
+ }
+
vp_new->vg_name = skip_dev_dir(cmd, vp_def->vg_name, NULL);
vp_new->max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG,
vp_def->max_lv);
@@ -904,16 +905,9 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
* - 'vgcreate' (neither option) creates a local VG
*/
- locking_type = find_config_tree_int(cmd, global_locking_type_CFG, NULL);
use_lvmlockd = find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL);
- use_clvmd = (locking_type == 3);
if (arg_is_set(cmd, locktype_ARG)) {
- if (arg_is_set(cmd, clustered_ARG)) {
- log_error("A lock type cannot be specified with --clustered.");
- return 0;
- }
-
lock_type = arg_str_value(cmd, locktype_ARG, "");
if (arg_is_set(cmd, shared_ARG) && !is_lockd_type(lock_type)) {
@@ -921,26 +915,6 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
return 0;
}
- } else if (arg_is_set(cmd, clustered_ARG)) {
- const char *arg_str = arg_str_value(cmd, clustered_ARG, "");
- int clustery = strcmp(arg_str, "y") ? 0 : 1;
-
- if (use_clvmd) {
- lock_type = clustery ? "clvm" : "none";
-
- } else if (use_lvmlockd) {
- log_error("lvmlockd is configured, use --shared with lvmlockd, and --clustered with clvmd.");
- return 0;
-
- } else {
- if (clustery) {
- log_error("The --clustered option requires clvmd (locking_type=3).");
- return 0;
- }
-
- lock_type = "none";
- }
-
} else if (arg_is_set(cmd, shared_ARG)) {
int found_multiple = 0;
@@ -953,20 +927,13 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
return 0;
}
- } else if (use_clvmd) {
- log_error("Use --shared with lvmlockd, and --clustered with clvmd.");
- return 0;
-
} else {
log_error("Using a shared lock type requires lvmlockd.");
return 0;
}
} else {
- if (use_clvmd)
- lock_type = locking_is_clustered() ? "clvm" : "none";
- else
- lock_type = "none";
+ lock_type = "none";
}
/*
@@ -977,6 +944,7 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
switch (lock_type_num) {
case LOCK_TYPE_INVALID:
+ case LOCK_TYPE_CLVM:
log_error("lock_type %s is invalid", lock_type);
return 0;
@@ -987,12 +955,6 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
return 0;
}
break;
- case LOCK_TYPE_CLVM:
- if (!use_clvmd) {
- log_error("Using clvm requires locking_type 3.");
- return 0;
- }
- break;
case LOCK_TYPE_NONE:
break;
};
@@ -1001,16 +963,11 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
* The vg is not owned by one host/system_id.
* Locking coordinates access from multiple hosts.
*/
- if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK || lock_type_num == LOCK_TYPE_CLVM)
+ if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK)
vp_new->system_id = NULL;
vp_new->lock_type = lock_type;
- if (lock_type_num == LOCK_TYPE_CLVM)
- vp_new->clustered = 1;
- else
- vp_new->clustered = 0;
-
log_debug("Setting lock_type to %s", vp_new->lock_type);
return 1;
}
diff --git a/tools/vgchange.c b/tools/vgchange.c
index ee6c3b929..e87277fb8 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -308,84 +308,6 @@ static int _vgchange_resizeable(struct cmd_context *cmd,
return 1;
}
-static int _vgchange_clustered(struct cmd_context *cmd,
- struct volume_group *vg)
-{
- int clustered = arg_int_value(cmd, clustered_ARG, 0);
- const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
- struct lv_list *lvl;
- struct lv_segment *mirror_seg;
-
- if (find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL)) {
- log_error("lvmlockd requires using the vgchange --lock-type option.");
- return 0;
- }
-
- if (lock_type && !strcmp(lock_type, "clvm"))
- clustered = 1;
-
- if (clustered && vg_is_clustered(vg)) {
- if (vg->system_id && *vg->system_id)
- log_warn("WARNING: Clearing invalid system ID %s from volume group %s.",
- vg->system_id, vg->name);
- else {
- log_error("Volume group \"%s\" is already clustered", vg->name);
- return 0;
- }
- }
-
- if (!clustered && !vg_is_clustered(vg)) {
- if ((!vg->system_id || !*vg->system_id) && cmd->system_id && *cmd->system_id)
- log_warn("Setting missing system ID on Volume Group %s to %s.",
- vg->name, cmd->system_id);
- else {
- log_error("Volume group \"%s\" is already not clustered",
- vg->name);
- return 0;
- }
- }
-
- if (clustered && !arg_is_set(cmd, yes_ARG)) {
- if (!clvmd_is_running()) {
- if (yes_no_prompt("LVM cluster daemon (clvmd) is not running. "
- "Make volume group \"%s\" clustered "
- "anyway? [y/n]: ", vg->name) == 'n') {
- log_error("No volume groups changed.");
- return 0;
- }
-
- } else if (!locking_is_clustered() &&
- (yes_no_prompt("LVM locking type is not clustered. "
- "Make volume group \"%s\" clustered "
- "anyway? [y/n]: ", vg->name) == 'n')) {
- log_error("No volume groups changed.");
- return 0;
- }
-#ifdef CMIRROR_REGION_COUNT_LIMIT
- dm_list_iterate_items(lvl, &vg->lvs) {
- if (!lv_is_mirror(lvl->lv))
- continue;
- mirror_seg = first_seg(lvl->lv);
- if ((lvl->lv->size / mirror_seg->region_size) >
- CMIRROR_REGION_COUNT_LIMIT) {
- log_error("Unable to convert %s to clustered mode:"
- " Mirror region size of %s is too small.",
- vg->name, lvl->lv->name);
- return 0;
- }
- }
-#endif
- }
-
- if (!vg_set_system_id(vg, clustered ? NULL : cmd->system_id))
- return_0;
-
- if (!vg_set_clustered(vg, clustered))
- return_0;
-
- return 1;
-}
-
static int _vgchange_logicalvolume(struct cmd_context *cmd,
struct volume_group *vg)
{
@@ -676,7 +598,6 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
{
int ret = ECMD_PROCESSED;
unsigned i;
- struct lv_list *lvl;
static const struct {
int arg;
@@ -690,7 +611,6 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
{ physicalextentsize_ARG, &_vgchange_pesize },
{ uuid_ARG, &_vgchange_uuid },
{ alloc_ARG, &_vgchange_alloc },
- { clustered_ARG, &_vgchange_clustered },
{ vgmetadatacopies_ARG, &_vgchange_metadata_copies },
{ metadataprofile_ARG, &_vgchange_profile },
{ profile_ARG, &_vgchange_profile },
@@ -731,31 +651,6 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
backup(vg);
log_print_unless_silent("Volume group \"%s\" successfully changed", vg->name);
-
- /* FIXME: fix clvmd bug and take DLM lock for non clustered VGs. */
- if (arg_is_set(cmd, clustered_ARG) &&
- vg_is_clustered(vg) && /* just switched to clustered */
- locking_is_clustered() &&
- locking_supports_remote_queries())
- dm_list_iterate_items(lvl, &vg->lvs) {
- if ((lv_lock_holder(lvl->lv) != lvl->lv) ||
- !lv_is_active(lvl->lv))
- continue;
-
- if (!activate_lv_excl_local(cmd, lvl->lv) ||
- !lv_is_active_exclusive_locally(lvl->lv)) {
- log_error("Can't reactive logical volume %s, "
- "please fix manually.",
- display_lvname(lvl->lv));
- ret = ECMD_FAILED;
- }
-
- if (lv_is_mirror(lvl->lv))
- /* Give hint for clustered mirroring */
- log_print_unless_silent("For clustered mirroring of %s "
- "deactivation and activation is needed.",
- display_lvname(lvl->lv));
- }
}
if (arg_is_set(cmd, activate_ARG)) {
@@ -810,7 +705,6 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
arg_is_set(cmd, resizeable_ARG) ||
arg_is_set(cmd, uuid_ARG) ||
arg_is_set(cmd, physicalextentsize_ARG) ||
- arg_is_set(cmd, clustered_ARG) ||
arg_is_set(cmd, alloc_ARG) ||
arg_is_set(cmd, vgmetadatacopies_ARG);
@@ -965,22 +859,6 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
}
/*
- * When lvm is currently using clvm, this function is just an alternative
- * to vgchange -c{y,n}, and can:
- * - change none to clvm
- * - change clvm to none
- * - it CANNOT change to or from a lockd type
- */
- if (locking_is_clustered()) {
- if (is_lockd_type(lock_type)) {
- log_error("Changing to lock type %s requires lvmlockd.", lock_type);
- return 0;
- }
-
- return _vgchange_clustered(cmd, vg);
- }
-
- /*
* When lvm is currently using lvmlockd, this function can:
* - change none to lockd type
* - change none to clvm (with warning about not being able to use it)
@@ -996,14 +874,6 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
return 0;
}
- /* none to clvm */
- if (!strcmp(vg->lock_type, "none") && !strcmp(lock_type, "clvm")) {
- log_warn("New clvm lock type will not be usable with lvmlockd.");
- vg->status |= CLUSTERED;
- vg->lock_type = "clvm"; /* this is optional */
- return 1;
- }
-
/* clvm to none */
if (!strcmp(vg->lock_type, "clvm") && !strcmp(lock_type, "none")) {
vg->status &= ~CLUSTERED;
@@ -1033,15 +903,6 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
lvl->lv->lock_args = NULL;
}
- /* ... to clvm */
- if (!strcmp(lock_type, "clvm")) {
- log_warn("New clvm lock type will not be usable with lvmlockd.");
- vg->status |= CLUSTERED;
- vg->lock_type = "clvm"; /* this is optional */
- vg->system_id = NULL;
- return 1;
- }
-
/* ... to lockd type */
if (is_lockd_type(lock_type)) {
/*
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 52c4825b5..94f95ec0c 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -23,7 +23,6 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
struct vgcreate_params vp_def;
struct volume_group *vg;
const char *tag;
- const char *clustered_message = "";
char *vg_name;
struct arg_value_group_list *current_group;
@@ -135,7 +134,6 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
!vg_set_max_lv(vg, vp_new.max_lv) ||
!vg_set_max_pv(vg, vp_new.max_pv) ||
!vg_set_alloc_policy(vg, vp_new.alloc) ||
- !vg_set_clustered(vg, vp_new.clustered) ||
!vg_set_system_id(vg, vp_new.system_id) ||
!vg_set_mda_copies(vg, vp_new.vgmetadatacopies))
goto_bad;
@@ -167,11 +165,6 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
}
- if (vg_is_clustered(vg))
- clustered_message = "Clustered ";
- else if (locking_is_clustered())
- clustered_message = "Non-clustered ";
-
if (!archive(vg))
goto_bad;
@@ -197,8 +190,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
backup(vg);
- log_print_unless_silent("%s%colume group \"%s\" successfully created%s%s",
- clustered_message, *clustered_message ? 'v' : 'V', vg->name,
+ log_print_unless_silent("Volume group \"%s\" successfully created%s%s",
+ vg->name,
vg->system_id ? " with system ID " : "", vg->system_id ? : "");
/*
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index e30a6717f..1e46e7ed3 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -646,7 +646,6 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
!vg_set_max_lv(vg_to, vp_new.max_lv) ||
!vg_set_max_pv(vg_to, vp_new.max_pv) ||
!vg_set_alloc_policy(vg_to, vp_new.alloc) ||
- !vg_set_clustered(vg_to, vp_new.clustered) ||
!vg_set_system_id(vg_to, vp_new.system_id) ||
!vg_set_mda_copies(vg_to, vp_new.vgmetadatacopies))
goto_bad;