master - tests: system_id remove clustered vg test
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=55521be2cbe28b0580f...
Commit: 55521be2cbe28b0580fafafff6151cf4b6a219ea
Parent: 802382e21ff600307f7c16f4651966d9a7c21252
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 6 14:35:27 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 14:35:27 2018 -0500
tests: system_id remove clustered vg test
---
test/shell/system_id.sh | 24 ------------------------
1 files changed, 0 insertions(+), 24 deletions(-)
diff --git a/test/shell/system_id.sh b/test/shell/system_id.sh
index 21c5bd0..ec7953d 100644
--- a/test/shell/system_id.sh
+++ b/test/shell/system_id.sh
@@ -275,30 +275,6 @@ grep $vg1 err
grep "$SID1" err
vgremove $vg1
-# vgchange -cy clears system_id, vgchange -cn sets system_id
-
-SID1=sidfoofile1
-echo "$SID1" > "$SIDFILE"
-aux lvmconf "global/system_id_source = file" \
- "global/system_id_file = \"$SIDFILE\""
-# create a vg
-vgcreate $vg1 "$dev1"
-# normal vgs sees the vg
-vgs -o+systemid >err
-grep $vg1 err
-grep "$SID1" err
-# after vgchange -cy there is no systemid
-vgchange --yes -cy $vg1
-vgs --config 'global { locking_type=0 }' -o+systemid $vg1 >err
-grep $vg1 err
-not grep "$SID1" err
-# after vgchange -cn there is a systemid
-vgchange --config 'global { locking_type=0 }' -cn $vg1
-vgs -o+systemid >err
-grep $vg1 err
-grep "$SID1" err
-vgremove $vg1
-
# Test max system_id length (128) and invalid system_id characters.
# The 128 length limit is imposed before invalid characters are omitted.
5 years, 11 months
master - Remove locking infrastructure from activation paths
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b7da704566a6542c86c...
Commit: b7da704566a6542c86cc1fcc186a66aa016b6802
Parent: 58a9254252a4c837601c15aabdae53d2f3c06edc
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 5 16:47:24 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 13:58:34 2018 -0500
Remove locking infrastructure from activation paths
Basic LV functions:
activate_lv(), deactivate_lv(),
suspend_lv(), resume_lv()
were routed through the locking infrastruture on the way to:
lv_activate_with_filter(), lv_deactivate(),
lv_suspend_if_active(), lv_resume_if_active()
This commit removes the locking infrastructure from the
middle and calls the later functions directly from the former.
There were a couple of ancillary steps that the locking
infrastructure added along the way which are still included:
- critical section inc/dec during suspend/resume
- checking for active component LVs during activate
The "activation" file lock (serializing activation) has not
been kept because activation commands have been changed to
take the VG file lock exclusively which makes the activation
lock unused and unnecessary.
---
lib/activate/activate.c | 103 ++++++++++++++++++++++++++++++++++++++++----
lib/activate/activate.h | 8 +++
lib/locking/file_locking.c | 48 --------------------
lib/locking/locking.c | 65 ++-------------------------
lib/locking/locking.h | 76 --------------------------------
5 files changed, 107 insertions(+), 193 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index c9ead42..a7e5fe3 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2424,15 +2424,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
if (!activation())
return 1;
- if (!laopts->exclusive &&
- (lv_is_origin(lv) ||
- seg_only_exclusive(first_seg(lv)))) {
- log_error(INTERNAL_ERROR "Trying non-exlusive activation of %s with "
- "a volume type %s requiring exclusive activation.",
- display_lvname(lv), lvseg_name(first_seg(lv)));
- return 0;
- }
-
if (filter && !_passes_activation_filter(cmd, lv)) {
log_verbose("Not activating %s since it does not pass "
"activation filter.", display_lvname(lv));
@@ -2765,3 +2756,97 @@ int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
return 1;
}
+
+int activate_lv(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ const struct logical_volume *active_lv;
+ int ret;
+
+ /*
+ * When trying activating component LV, make sure none of sub component
+ * LV or LVs that are using it are active.
+ */
+ if (!lv_is_visible(lv))
+ active_lv = lv_holder_is_active(lv);
+ else
+ active_lv = lv_component_is_active(lv);
+
+ if (active_lv) {
+ log_error("Activation of logical volume %s is prohibited while logical volume %s is active.",
+ display_lvname(lv), display_lvname(active_lv));
+ ret = 0;
+ goto out;
+ }
+
+ ret = lv_activate_with_filter(cmd, NULL, 0,
+ (lv->status & LV_NOSCAN) ? 1 : 0,
+ (lv->status & LV_TEMPORARY) ? 1 : 0,
+ lv_committed(lv));
+out:
+ return ret;
+}
+
+int deactivate_lv(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ int ret;
+
+ ret = lv_deactivate(cmd, NULL, lv_committed(lv));
+
+ return ret;
+}
+
+int suspend_lv(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ int ret;
+
+ critical_section_inc(cmd, "locking for suspend");
+
+ ret = lv_suspend_if_active(cmd, NULL, 0, 0, lv_committed(lv), lv);
+
+ return ret;
+}
+
+int suspend_lv_origin(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ int ret;
+
+ critical_section_inc(cmd, "locking for suspend");
+
+ ret = lv_suspend_if_active(cmd, NULL, 1, 0, lv_committed(lv), lv);
+
+ return ret;
+}
+
+int resume_lv(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ int ret;
+
+ ret = lv_resume_if_active(cmd, NULL, 0, 0, 0, lv_committed(lv));
+
+ critical_section_dec(cmd, "unlocking on resume");
+
+ return ret;
+}
+
+int resume_lv_origin(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ int ret;
+
+ ret = lv_resume_if_active(cmd, NULL, 1, 0, 0, lv_committed(lv));
+
+ critical_section_dec(cmd, "unlocking on resume");
+
+ return ret;
+}
+
+int revert_lv(struct cmd_context *cmd, const struct logical_volume *lv)
+{
+ int ret;
+
+ ret = lv_resume_if_active(cmd, NULL, 0, 0, 1, lv_committed(lv));
+
+ critical_section_dec(cmd, "unlocking on resume");
+
+ return ret;
+}
+
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 8b6c4ad..2f0b0a0 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -126,6 +126,14 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
int lv_deactivate_any_missing_subdevs(const struct logical_volume *lv);
+int activate_lv(struct cmd_context *cmd, const struct logical_volume *lv);
+int deactivate_lv(struct cmd_context *cmd, const struct logical_volume *lv);
+int suspend_lv(struct cmd_context *cmd, const struct logical_volume *lv);
+int suspend_lv_origin(struct cmd_context *cmd, const struct logical_volume *lv);
+int resume_lv(struct cmd_context *cmd, const struct logical_volume *lv);
+int resume_lv_origin(struct cmd_context *cmd, const struct logical_volume *lv);
+int revert_lv(struct cmd_context *cmd, const struct logical_volume *lv);
+
/*
* Returns 1 if info structure has been populated, else 0 on failure.
* When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c
index d4f47c6..a60a3e5 100644
--- a/lib/locking/file_locking.c
+++ b/lib/locking/file_locking.c
@@ -44,20 +44,8 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
uint32_t flags, const struct logical_volume *lv)
{
char lockfile[PATH_MAX];
- unsigned origin_only = (flags & LCK_ORIGIN_ONLY) ? 1 : 0;
- unsigned revert = (flags & LCK_REVERT) ? 1 : 0;
switch (flags & LCK_SCOPE_MASK) {
- case LCK_ACTIVATION:
- if (dm_snprintf(lockfile, sizeof(lockfile),
- "%s/A_%s", _lock_dir, resource) < 0) {
- log_error("Too long locking filename %s/A_%s.", _lock_dir, resource);
- return 0;
- }
-
- if (!lock_file(lockfile, flags))
- return_0;
- break;
case LCK_VG:
if (!strcmp(resource, VG_SYNC_NAMES))
fs_unlock();
@@ -84,42 +72,6 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
if (!lock_file(lockfile, flags))
return_0;
break;
- case LCK_LV:
- switch (flags & LCK_TYPE_MASK) {
- case LCK_UNLOCK:
- log_very_verbose("Unlocking LV %s%s%s", resource, origin_only ? " without snapshots" : "", revert ? " (reverting)" : "");
- if (!lv_resume_if_active(cmd, resource, origin_only, 0, revert, lv_committed(lv)))
- return 0;
- break;
- case LCK_NULL:
- log_very_verbose("Locking LV %s (NL)", resource);
- if (!lv_deactivate(cmd, resource, lv_committed(lv)))
- return 0;
- break;
- case LCK_READ:
- log_very_verbose("Locking LV %s (R)", resource);
- if (!lv_activate_with_filter(cmd, resource, 0, (lv->status & LV_NOSCAN) ? 1 : 0,
- (lv->status & LV_TEMPORARY) ? 1 : 0, lv_committed(lv)))
- return 0;
- break;
- case LCK_PREAD:
- log_very_verbose("Locking LV %s (PR) - ignored", resource);
- break;
- case LCK_WRITE:
- log_very_verbose("Locking LV %s (W)%s", resource, origin_only ? " without snapshots" : "");
- if (!lv_suspend_if_active(cmd, resource, origin_only, 0, lv_committed(lv), lv))
- return 0;
- break;
- case LCK_EXCL:
- log_very_verbose("Locking LV %s (EX)", resource);
- if (!lv_activate_with_filter(cmd, resource, 1, (lv->status & LV_NOSCAN) ? 1 : 0,
- (lv->status & LV_TEMPORARY) ? 1 : 0, lv_committed(lv)))
- return 0;
- break;
- default:
- break;
- }
- break;
default:
log_error("Unrecognised lock scope: %d",
flags & LCK_SCOPE_MASK);
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 5e28452..4b7d7eb 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -35,30 +35,6 @@ static int _vg_lock_count = 0; /* Number of locks held */
static int _vg_write_lock_held = 0; /* VG write lock held? */
static int _blocking_supported = 0;
-typedef enum {
- LV_NOOP,
- LV_SUSPEND,
- LV_RESUME
-} lv_operation_t;
-
-static void _lock_memory(struct cmd_context *cmd, lv_operation_t lv_op)
-{
- if (!(_locking.flags & LCK_PRE_MEMLOCK))
- return;
-
- if (lv_op == LV_SUSPEND)
- critical_section_inc(cmd, "locking for suspend");
-}
-
-static void _unlock_memory(struct cmd_context *cmd, lv_operation_t lv_op)
-{
- if (!(_locking.flags & LCK_PRE_MEMLOCK))
- return;
-
- if (lv_op == LV_RESUME)
- critical_section_dec(cmd, "unlocking on resume");
-}
-
static void _unblock_signals(void)
{
/* Don't unblock signals while any locks are held */
@@ -139,16 +115,13 @@ void fin_locking(void)
* VG locking is by VG name.
* FIXME This should become VG uuid.
*/
-static int _lock_vol(struct cmd_context *cmd, const char *resource,
- uint32_t flags, lv_operation_t lv_op, const struct logical_volume *lv)
+static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t flags)
{
uint32_t lck_type = flags & LCK_TYPE_MASK;
uint32_t lck_scope = flags & LCK_SCOPE_MASK;
int ret = 0;
- const struct logical_volume *active_lv;
block_signals(flags);
- _lock_memory(cmd, lv_op);
assert(resource);
@@ -162,23 +135,13 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource,
goto out;
}
- /* When trying activating component LV, make sure none of
- * sub component LV or LVs that are using it are active */
- if (lv && ((lck_type == LCK_READ) || (lck_type == LCK_EXCL)) &&
- ((!lv_is_visible(lv) && (active_lv = lv_holder_is_active(lv))) ||
- (active_lv = lv_component_is_active(lv)))) {
- log_error("Activation of logical volume %s is prohibited while logical volume %s is active.",
- display_lvname(lv), display_lvname(active_lv));
- goto out;
- }
-
if (cmd->metadata_read_only && lck_type == LCK_WRITE &&
strcmp(resource, VG_GLOBAL)) {
log_error("Operation prohibited while global/metadata_read_only is set.");
goto out;
}
- if ((ret = _locking.lock_resource(cmd, resource, flags, lv))) {
+ if ((ret = _locking.lock_resource(cmd, resource, flags, NULL))) {
if (lck_scope == LCK_VG && !(flags & LCK_CACHE)) {
if (lck_type != LCK_UNLOCK)
lvmcache_lock_vgname(resource, lck_type == LCK_READ);
@@ -196,7 +159,6 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource,
_update_vg_lock_count(resource, flags);
}
out:
- _unlock_memory(cmd, lv_op);
_unblock_signals();
return ret;
@@ -205,28 +167,14 @@ out:
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const struct logical_volume *lv)
{
char resource[258] __attribute__((aligned(8)));
- lv_operation_t lv_op;
int lck_type = flags & LCK_TYPE_MASK;
- switch (flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) {
- case LCK_LV_SUSPEND:
- lv_op = LV_SUSPEND;
- break;
- case LCK_LV_RESUME:
- lv_op = LV_RESUME;
- break;
- default: lv_op = LV_NOOP;
- }
-
-
if (flags == LCK_NONE) {
log_debug_locking(INTERNAL_ERROR "%s: LCK_NONE lock requested", vol);
return 1;
}
switch (flags & LCK_SCOPE_MASK) {
- case LCK_ACTIVATION:
- break;
case LCK_VG:
if (!_blocking_supported)
flags |= LCK_NONBLOCK;
@@ -235,10 +183,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
if (is_orphan_vg(vol))
vol = VG_ORPHANS;
break;
- case LCK_LV:
- /* All LV locks are non-blocking. */
- flags |= LCK_NONBLOCK;
- break;
default:
log_error("Unrecognised lock scope: %d",
flags & LCK_SCOPE_MASK);
@@ -250,7 +194,7 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
return 0;
}
- if (!_lock_vol(cmd, resource, flags, lv_op, lv))
+ if (!_lock_vol(cmd, resource, flags))
return_0;
/*
@@ -261,7 +205,7 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
(flags & (LCK_CACHE | LCK_HOLD)))
return 1;
- if (!_lock_vol(cmd, resource, (flags & ~LCK_TYPE_MASK) | LCK_UNLOCK, lv_op, lv))
+ if (!_lock_vol(cmd, resource, (flags & ~LCK_TYPE_MASK) | LCK_UNLOCK))
return_0;
return 1;
@@ -312,3 +256,4 @@ int sync_dev_names(struct cmd_context* cmd)
return lock_vol(cmd, VG_SYNC_NAMES, LCK_VG_SYNC, NULL);
}
+
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index f3956c2..6d7d8e8 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -94,8 +94,6 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
*/
#define LCK_SCOPE_MASK 0x00001008U
#define LCK_VG 0x00000000U /* Volume Group */
-#define LCK_LV 0x00000008U /* Logical Volume */
-#define LCK_ACTIVATION 0x00001000U /* Activation */
/*
* Lock bits.
@@ -138,9 +136,6 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
*/
#define LCK_NONE (LCK_VG | LCK_NULL)
-#define LCK_ACTIVATE_LOCK (LCK_ACTIVATION | LCK_WRITE | LCK_HOLD)
-#define LCK_ACTIVATE_UNLOCK (LCK_ACTIVATION | LCK_UNLOCK)
-
#define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
@@ -155,51 +150,8 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_VG_SYNC (LCK_NONE | LCK_CACHE)
#define LCK_VG_SYNC_LOCAL (LCK_NONE | LCK_CACHE | LCK_LOCAL)
-#define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL)
-#define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE)
-#define LCK_LV_RESUME (LCK_LV | LCK_UNLOCK)
-#define LCK_LV_ACTIVATE (LCK_LV | LCK_READ)
-#define LCK_LV_DEACTIVATE (LCK_LV | LCK_NULL)
-
#define LCK_MASK (LCK_TYPE_MASK | LCK_SCOPE_MASK)
-#define lock_lv_vol(cmd, lv, flags) lock_vol(cmd, (lv)->lvid.s, flags, lv)
-
-/*
- * Activation locks are wrapped around activation commands that have to
- * be processed atomically one-at-a-time.
- * If a VG WRITE lock is held or clustered activation activates simple LV
- * an activation lock is redundant.
- *
- * Some LV types do require taking a lock common for whole group of LVs.
- * TODO: For simplicity reasons ATM take a VG activation global lock and
- * later more fine-grained component detection algorithm can be added
- */
-
-#define lv_type_requires_activation_lock(lv) ((lv_is_thin_type(lv) || lv_is_cache_type(lv) || lv_is_mirror_type(lv) || lv_is_raid_type(lv) || lv_is_origin(lv) || lv_is_snapshot(lv)) ? 1 : 0)
-
-#define lv_activation_lock_name(lv) (lv_type_requires_activation_lock(lv) ? (lv)->vg->name : (lv)->lvid.s)
-
-#define lv_requires_activation_lock_now(lv) ((!vg_write_lock_held() && (!vg_is_clustered((lv)->vg) || !lv_type_requires_activation_lock(lv))) ? 1 : 0)
-
-#define lock_activation(cmd, lv) (lv_requires_activation_lock_now(lv) ? lock_vol(cmd, lv_activation_lock_name(lv), LCK_ACTIVATE_LOCK, lv) : 1)
-#define unlock_activation(cmd, lv) (lv_requires_activation_lock_now(lv) ? lock_vol(cmd, lv_activation_lock_name(lv), LCK_ACTIVATE_UNLOCK, lv) : 1)
-
-/*
- * Place temporary exclusive 'activation' lock around an LV locking operation
- * to serialise it.
- */
-#define lock_lv_vol_serially(cmd, lv, flags) \
-({ \
- int rr = 0; \
-\
- if (lock_activation((cmd), (lv))) { \
- rr = lock_lv_vol((cmd), (lv), (flags)); \
- unlock_activation((cmd), (lv)); \
- } \
- rr; \
-})
-
#define unlock_vg(cmd, vg, vol) \
do { \
if (vg && !lvmetad_vg_update_finish(vg)) \
@@ -215,34 +167,6 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
release_vg(vg); \
} while (0)
-#define resume_lv(cmd, lv) \
-({ \
- int rr = lock_lv_vol((cmd), (lv), LCK_LV_RESUME); \
- unlock_activation((cmd), (lv)); \
- rr; \
-})
-#define resume_lv_origin(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_RESUME | LCK_ORIGIN_ONLY)
-#define revert_lv(cmd, lv) \
-({ \
- int rr = lock_lv_vol((cmd), (lv), LCK_LV_RESUME | LCK_REVERT); \
-\
- unlock_activation((cmd), (lv)); \
- rr; \
-})
-#define suspend_lv(cmd, lv) \
- (lock_activation((cmd), (lv)) ? lock_lv_vol((cmd), (lv), LCK_LV_SUSPEND | LCK_HOLD) : 0)
-
-#define suspend_lv_origin(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD | LCK_ORIGIN_ONLY)
-
-#define deactivate_lv(cmd, lv) lock_lv_vol_serially(cmd, lv, LCK_LV_DEACTIVATE)
-
-#define activate_lv(cmd, lv) lock_lv_vol_serially(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
-
-struct logical_volume;
-
-#define deactivate_lv_local(cmd, lv) \
- lock_lv_vol_serially(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
-
#define drop_cached_metadata(vg) \
lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE, NULL)
5 years, 11 months
master - tests: remove -cn option from some commands
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=802382e21ff600307f7...
Commit: 802382e21ff600307f7c16f4651966d9a7c21252
Parent: b7da704566a6542c86cc1fcc186a66aa016b6802
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 6 14:04:19 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 14:04:19 2018 -0500
tests: remove -cn option from some commands
---
test/shell/vgcfgbackup-lvm1.sh | 2 +-
test/shell/vgchange-usage.sh | 8 ++++----
test/shell/vgsplit-usage.sh | 6 +++---
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/test/shell/vgcfgbackup-lvm1.sh b/test/shell/vgcfgbackup-lvm1.sh
index a148ec1..9b81e28 100644
--- a/test/shell/vgcfgbackup-lvm1.sh
+++ b/test/shell/vgcfgbackup-lvm1.sh
@@ -28,7 +28,7 @@ aux lvmconf "backup/backup = 0"
# vgcfgbackup correctly stores metadata LVM1 with missing PVs
pvcreate -M1 "${DEVICES[@]}"
-vgcreate $SHARED -M1 -c n "$vg" "${DEVICES[@]}"
+vgcreate $SHARED -M1 "$vg" "${DEVICES[@]}"
lvcreate -l1 -n $lv1 $vg "$dev1"
pvremove -ff -y "$dev2"
not lvcreate -l1 -n $lv1 $vg "$dev3"
diff --git a/test/shell/vgchange-usage.sh b/test/shell/vgchange-usage.sh
index 1885a64..9fe9bc5 100644
--- a/test/shell/vgchange-usage.sh
+++ b/test/shell/vgchange-usage.sh
@@ -101,7 +101,7 @@ vgremove -ff $vg
test -n "$LVM_TEST_LVMLOCKD" && exit 0
# set cluster bit
-vgcreate -cn $vg "$dev1" "$dev2" "$dev3"
+vgcreate $vg "$dev1" "$dev2" "$dev3"
# check prompt to change cluster bit without giving explicit vg name
fail vgchange -cy 2>&1 | tee out
grep "y/n" out
@@ -121,10 +121,10 @@ if test -e LOCAL_CLVMD ; then
# check we do not support conversion of just locally active LVs
lvchange -an $vg
lvchange -ay $vg
- not vgchange -cn $vg
+ not vgchange $vg
lvchange -an $vg
lvchange -aey $vg
- vgchange -cn $vg
+ vgchange $vg
else
# no clvmd is running
fail vgchange -cy $vg
@@ -136,7 +136,7 @@ else
vgs --ignoreskippedcluster $vg 2>&1 | tee out
not grep "Skipping clustered volume group" out
# reset back to non-clustered VG with disabled locking
- vgchange -cn $vg --config 'global{locking_type=0}' $vg
+ vgchange $vg --config 'global{locking_type=0}' $vg
fi
check vg_attr_bit cluster $vg "-"
diff --git a/test/shell/vgsplit-usage.sh b/test/shell/vgsplit-usage.sh
index a112e86..38f3964 100644
--- a/test/shell/vgsplit-usage.sh
+++ b/test/shell/vgsplit-usage.sh
@@ -96,9 +96,9 @@ grep "Volume group \"$vg2\" exists, but new VG option specified" err
vgremove $vg1 $vg2
# vgsplit rejects split because clustered given with existing vg
-vgcreate -M$mdatype --clustered n $vg1 "$dev1" "$dev2"
-vgcreate -M$mdatype --clustered n $vg2 "$dev3" "$dev4"
-not vgsplit --clustered n $vg1 $vg2 "$dev1" 2>err
+vgcreate -M$mdatype $vg1 "$dev1" "$dev2"
+vgcreate -M$mdatype $vg2 "$dev3" "$dev4"
+not vgsplit $vg1 $vg2 "$dev1" 2>err
grep "Volume group \"$vg2\" exists, but new VG option specified" err
vgremove $vg1 $vg2
5 years, 11 months
master - use exclusive file lock on VG for activation
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=58a9254252a4c837601...
Commit: 58a9254252a4c837601c15aabdae53d2f3c06edc
Parent: d2d8dd7f7f21798cac37d9cc6a7cdcb290a63f4f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 6 11:14:39 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 13:58:34 2018 -0500
use exclusive file lock on VG for activation
Make activation commands:
vgchange -ay, lvchange -ay, pvscan -aay
take an exclusive file lock on the VG to serialize
multiple concurrent activation commands which could
otherwise interfere with each other.
---
tools/lvchange.c | 2 +-
tools/pvscan.c | 2 +-
tools/vgchange.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index a90174e..3ed6b06 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -1386,7 +1386,7 @@ int lvchange_activate_cmd(struct cmd_context *cmd, int argc, char **argv)
} else /* Component LVs might be active, support easy deactivation */
cmd->process_component_lvs = 1;
- ret = process_each_lv(cmd, argc, argv, NULL, NULL, 0,
+ ret = process_each_lv(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE,
NULL, &_lvchange_activate_check, &_lvchange_activate_single);
if (ret != ECMD_PROCESSED)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 7cba0f4..61626e6 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -288,7 +288,7 @@ static int _pvscan_autoactivate(struct cmd_context *cmd, struct pvscan_aa_params
pp->refresh_all = 1;
}
- ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, 0, 0, handle, _pvscan_autoactivate_single);
+ ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_UPDATE, 0, handle, _pvscan_autoactivate_single);
destroy_processing_handle(cmd, handle);
diff --git a/tools/vgchange.c b/tools/vgchange.c
index a67c3be..b07057f 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -791,7 +791,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
cmd->lockd_vg_enforce_sh = 1;
}
- if (update)
+ if (update || arg_is_set(cmd, activate_ARG))
flags |= READ_FOR_UPDATE;
if (!(handle = init_processing_handle(cmd, NULL))) {
5 years, 11 months
master - Remove VG lock ordering check
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=d2d8dd7f7f21798cac3...
Commit: d2d8dd7f7f21798cac37d9cc6a7cdcb290a63f4f
Parent: c157c43f7cca085651fab13937ee11e526fe88cf
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 5 15:16:58 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 13:58:34 2018 -0500
Remove VG lock ordering check
Four commands lock two VGs at a time:
- vgsplit and vgmerge already have their own logic to
acquire the locks in the correct order.
- vgimportclone and vgrename disable this ordering check.
---
lib/cache/lvmcache.c | 66 -------------------------------------------------
lib/cache/lvmcache.h | 1 -
lib/locking/locking.c | 6 ----
tools/toollib.c | 8 ------
tools/vgimportclone.c | 4 ---
tools/vgrename.c | 5 ---
6 files changed, 0 insertions(+), 90 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index b9aa8a0..774d687 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -77,7 +77,6 @@ static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
-static int _suppress_lock_ordering = 0;
int lvmcache_init(struct cmd_context *cmd)
{
@@ -158,71 +157,6 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
-/*
- * Ensure vgname2 comes after vgname1 alphabetically.
- * Orphan locks come last.
- * VG_GLOBAL comes first.
- */
-static int _vgname_order_correct(const char *vgname1, const char *vgname2)
-{
- if (is_global_vg(vgname1))
- return 1;
-
- if (is_global_vg(vgname2))
- return 0;
-
- if (is_orphan_vg(vgname1))
- return 0;
-
- if (is_orphan_vg(vgname2))
- return 1;
-
- if (strcmp(vgname1, vgname2) < 0)
- return 1;
-
- return 0;
-}
-
-void lvmcache_lock_ordering(int enable)
-{
- _suppress_lock_ordering = !enable;
-}
-
-/*
- * Ensure VG locks are acquired in alphabetical order.
- */
-int lvmcache_verify_lock_order(const char *vgname)
-{
- struct dm_hash_node *n;
- const char *vgname2;
-
- if (_suppress_lock_ordering)
- return 1;
-
- if (!_lock_hash)
- return 1;
-
- dm_hash_iterate(n, _lock_hash) {
- if (!dm_hash_get_data(_lock_hash, n))
- return_0;
-
- if (!(vgname2 = dm_hash_get_key(_lock_hash, n))) {
- log_error(INTERNAL_ERROR "VG lock %s hits NULL.",
- vgname);
- return 0;
- }
-
- if (!_vgname_order_correct(vgname2, vgname)) {
- log_errno(EDEADLK, INTERNAL_ERROR "VG lock %s must "
- "be requested before %s, not after.",
- vgname, vgname2);
- return 0;
- }
- }
-
- return 1;
-}
-
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unused)))
{
if (dm_hash_lookup(_lock_hash, vgname))
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 5891757..4808a0d 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -87,7 +87,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
-int lvmcache_verify_lock_order(const char *vgname);
/* Queries */
const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd, const char *vgname, const char *vgid, unsigned revalidate_labels);
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index a4fcaf7..5e28452 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -234,12 +234,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
/* Global VG_ORPHANS lock covers all orphan formats. */
if (is_orphan_vg(vol))
vol = VG_ORPHANS;
- /* VG locks alphabetical, ORPHAN lock last */
- if ((lck_type != LCK_UNLOCK) &&
- !(flags & LCK_CACHE) &&
- !lvmcache_verify_lock_order(vol))
- return_0;
-
break;
case LCK_LV:
/* All LV locks are non-blocking. */
diff --git a/tools/toollib.c b/tools/toollib.c
index 236e2b1..a4dddd3 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -5414,14 +5414,6 @@ int pvcreate_each_device(struct cmd_context *cmd,
}
/*
- * This function holds the orphans lock while reading VGs to look for
- * devices. This means the orphans lock is held while VG locks are
- * acquired, which is against lvmcache lock ordering rules, so disable
- * the lvmcache lock ordering checks.
- */
- lvmcache_lock_ordering(0);
-
- /*
* Clear the cache before acquiring the orphan lock. (Clearing the
* cache with locks held is an error.) We want the orphan lock
* acquired before process_each_pv. If the orphan lock is not held
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 7421912..e37b897 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -342,9 +342,6 @@ retry_name:
log_debug("Changing VG %s to %s.", vp.old_vgname, vp.new_vgname);
- /* We don't care if the new name comes before the old in lock order. */
- lvmcache_lock_ordering(0);
-
if (!lock_vol(cmd, vp.new_vgname, LCK_VG_WRITE, NULL)) {
log_error("Can't get lock for new VG name %s", vp.new_vgname);
goto out;
@@ -363,7 +360,6 @@ out:
unlock_vg(cmd, NULL, VG_GLOBAL);
internal_filter_clear();
init_internal_filtering(0);
- lvmcache_lock_ordering(1);
destroy_processing_handle(cmd, handle);
/* Enable lvmetad again if no duplicates are left. */
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 4f2a08b..bbc3087 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -99,13 +99,8 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
* this uuid-for-name case.
*/
if (vp->lock_vg_old_first || vp->old_name_is_uuid) {
- if (vp->old_name_is_uuid)
- lvmcache_lock_ordering(0);
-
if (!_lock_new_vg_for_rename(cmd, vp->vg_name_new))
return ECMD_FAILED;
-
- lvmcache_lock_ordering(1);
}
dev_dir = cmd->dev_dir;
5 years, 11 months
master - Remove unused clvm variations for active LVs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c157c43f7cca085651f...
Commit: c157c43f7cca085651fab13937ee11e526fe88cf
Parent: eb600292455b1b2b2e88db74e13b7db848701b92
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 5 13:21:28 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 13:58:34 2018 -0500
Remove unused clvm variations for active LVs
Different flavors of activate_lv() and lv_is_active()
which are meaningful in a clustered VG can be eliminated
and replaced with whatever that flavor already falls back
to in a local VG.
e.g. lv_is_active_exclusive_locally() is distinct from
lv_is_active() in a clustered VG, but in a local VG they
are equivalent. So, all instances of the variant are
replaced with the basic local equivalent.
For local VGs, the same behavior remains as before.
For shared VGs, lvmlockd was written with the explicit
requirement of local behavior from these functions
(lvmlockd requires locking_type 1), so the behavior
in shared VGs also remains the same.
---
lib/activate/activate.c | 131 ++--------------------------------------
lib/activate/activate.h | 6 --
lib/locking/locking.c | 18 +-----
lib/locking/locking.h | 10 +---
lib/metadata/cache_manip.c | 6 +-
lib/metadata/lv.c | 64 ++------------------
lib/metadata/lv.h | 2 +-
lib/metadata/lv_manip.c | 36 +++++-------
lib/metadata/mirror.c | 65 ++------------------
lib/metadata/pool_manip.c | 2 +-
lib/metadata/raid_manip.c | 46 ++++----------
lib/metadata/snapshot_manip.c | 6 --
lib/metadata/thin_manip.c | 4 +-
lib/report/report.c | 40 +------------
tools/lvchange.c | 11 +--
tools/lvconvert.c | 27 ++++-----
tools/lvcreate.c | 4 +-
tools/polldaemon.c | 4 +-
tools/pvmove.c | 8 +--
tools/toollib.c | 4 +-
tools/vgchange.c | 16 +-----
21 files changed, 88 insertions(+), 422 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 4c70443..c9ead42 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -374,31 +374,6 @@ int lv_is_active(const struct logical_volume *lv)
{
return 0;
}
-int lv_is_active_locally(const struct logical_volume *lv)
-{
- return 0;
-}
-int lv_is_active_remotely(const struct logical_volume *lv)
-{
- return 0;
-}
-int lv_is_active_but_not_locally(const struct logical_volume *lv)
-{
- return 0;
-}
-int lv_is_active_exclusive(const struct logical_volume *lv)
-{
- return 0;
-}
-int lv_is_active_exclusive_locally(const struct logical_volume *lv)
-{
- return 0;
-}
-int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
-{
- return 0;
-}
-
int lv_check_transient(struct logical_volume *lv)
{
return 1;
@@ -1471,61 +1446,6 @@ int lvs_in_vg_opened(const struct volume_group *vg)
}
/*
- * _lv_is_active
- * @lv: logical volume being queried
- * @locally: set if active locally (when provided)
- * @remotely: set if active remotely (when provided)
- * @exclusive: set if active exclusively (when provided)
- *
- * Determine whether an LV is active locally or in a cluster.
- * In addition to the return code which indicates whether or
- * not the LV is active somewhere, two other values are set
- * to yield more information about the status of the activation:
- *
- * return locally exclusively status
- * ====== ======= =========== ======
- * 0 0 0 not active
- * 1 0 0 active remotely
- * 1 0 1 exclusive remotely
- * 1 1 0 active locally and possibly remotely
- * 1 1 1 exclusive locally (or local && !cluster)
- * The VG lock must be held to call this function.
- *
- * Returns: 0 or 1
- */
-static int _lv_is_active(const struct logical_volume *lv,
- int *locally, int *remotely, int *exclusive)
-{
- int r, l, e; /* remote, local, and exclusive */
- int skip_cluster_query = 0;
-
- r = l = e = 0;
-
- if (_lv_active(lv->vg->cmd, lv))
- l = 1;
-
- if (l)
- e = 1; /* exclusive by definition */
-
- if (locally)
- *locally = l;
- if (exclusive)
- *exclusive = e;
- if (remotely)
- *remotely = r;
-
- log_very_verbose("%s is %sactive%s%s%s%s",
- display_lvname(lv),
- (r || l) ? "" : "not ",
- (exclusive && e) ? " exclusive" : "",
- l ? " locally" : "",
- (!skip_cluster_query && l && r) ? " and" : "",
- (!skip_cluster_query && r) ? " remotely" : "");
-
- return r || l;
-}
-
-/*
* Check if "raid4" @segtype is supported by kernel.
*
* if segment type is not raid4, return 1.
@@ -1545,51 +1465,14 @@ int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segty
return 1;
}
+/*
+ * The VG lock must be held to call this function.
+ *
+ * Returns: 0 or 1
+ */
int lv_is_active(const struct logical_volume *lv)
{
- return _lv_is_active(lv, NULL, NULL, NULL);
-}
-
-int lv_is_active_locally(const struct logical_volume *lv)
-{
- int l;
-
- return _lv_is_active(lv, &l, NULL, NULL) && l;
-}
-
-int lv_is_active_remotely(const struct logical_volume *lv)
-{
- int r;
-
- return _lv_is_active(lv, NULL, &r, NULL) && r;
-}
-
-int lv_is_active_but_not_locally(const struct logical_volume *lv)
-{
- int l;
-
- return _lv_is_active(lv, &l, NULL, NULL) && !l;
-}
-
-int lv_is_active_exclusive(const struct logical_volume *lv)
-{
- int e;
-
- return _lv_is_active(lv, NULL, NULL, &e) && e;
-}
-
-int lv_is_active_exclusive_locally(const struct logical_volume *lv)
-{
- int l, e;
-
- return _lv_is_active(lv, &l, NULL, &e) && l && e;
-}
-
-int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
-{
- int l, e;
-
- return _lv_is_active(lv, &l, NULL, &e) && !l && e;
+ return _lv_active(lv->vg->cmd, lv);
}
#ifdef DMEVENTD
@@ -1991,7 +1874,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
continue;
if (!vg_write_lock_held() && lv_is_mirror(lv)) {
- mirr_laopts.exclusive = lv_is_active_exclusive_locally(lv) ? 1 : 0;
+ mirr_laopts.exclusive = lv_is_active(lv) ? 1 : 0;
/*
* Commands vgchange and lvchange do use read-only lock when changing
* monitoring (--monitor y|n). All other use cases hold 'write-lock'
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 8175f68..8b6c4ad 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -191,12 +191,6 @@ int lvs_in_vg_activated(const struct volume_group *vg);
int lvs_in_vg_opened(const struct volume_group *vg);
int lv_is_active(const struct logical_volume *lv);
-int lv_is_active_locally(const struct logical_volume *lv);
-int lv_is_active_remotely(const struct logical_volume *lv);
-int lv_is_active_but_not_locally(const struct logical_volume *lv);
-int lv_is_active_exclusive(const struct logical_volume *lv);
-int lv_is_active_exclusive_locally(const struct logical_volume *lv);
-int lv_is_active_exclusive_remotely(const struct logical_volume *lv);
/* Check is any component LV is active */
const struct logical_volume *lv_component_is_active(const struct logical_volume *lv);
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 0e5658f..a4fcaf7 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -273,16 +273,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
return 1;
}
-/*
- * First try to activate exclusively locally.
- * Then if the VG is clustered and the LV is not yet active (e.g. due to
- * an activation filter) try activating on remote nodes.
- */
-int activate_lv_excl(struct cmd_context *cmd, const struct logical_volume *lv)
-{
- return activate_lv_excl_local(cmd, lv);
-}
-
/* Lock a list of LVs */
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
{
@@ -290,13 +280,9 @@ int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusiv
struct lv_list *lvl;
dm_list_iterate_items(lvl, lvs) {
- if (!exclusive && !lv_is_active_exclusive(lvl->lv)) {
- if (!activate_lv(cmd, lvl->lv)) {
- log_error("Failed to activate %s", display_lvname(lvl->lv));
- return 0;
- }
- } else if (!activate_lv_excl(cmd, lvl->lv)) {
+ if (!activate_lv(cmd, lvl->lv)) {
log_error("Failed to activate %s", display_lvname(lvl->lv));
+
dm_list_uniterate(lvh, lvs, &lvl->list) {
lvl = dm_list_item(lvh, struct lv_list);
if (!deactivate_lv(cmd, lvl->lv))
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 8b2bced..f3956c2 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -231,20 +231,14 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
})
#define suspend_lv(cmd, lv) \
(lock_activation((cmd), (lv)) ? lock_lv_vol((cmd), (lv), LCK_LV_SUSPEND | LCK_HOLD) : 0)
+
#define suspend_lv_origin(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD | LCK_ORIGIN_ONLY)
+
#define deactivate_lv(cmd, lv) lock_lv_vol_serially(cmd, lv, LCK_LV_DEACTIVATE)
#define activate_lv(cmd, lv) lock_lv_vol_serially(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
-#define activate_lv_excl_local(cmd, lv) \
- lock_lv_vol_serially(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_LOCAL)
-#define activate_lv_excl_remote(cmd, lv) \
- lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_REMOTE)
struct logical_volume;
-int activate_lv_excl(struct cmd_context *cmd, const struct logical_volume *lv);
-
-#define activate_lv_local(cmd, lv) \
- lock_lv_vol_serially(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
#define deactivate_lv_local(cmd, lv) \
lock_lv_vol_serially(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 0768e6f..fe91fee 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -566,8 +566,8 @@ int lv_cache_remove(struct logical_volume *cache_lv)
default:
/* Otherwise localy activate volume to sync dirty blocks */
cache_lv->status |= LV_TEMPORARY;
- if (!activate_lv_excl_local(cache_lv->vg->cmd, cache_lv) ||
- !lv_is_active_locally(cache_lv)) {
+ if (!activate_lv(cache_lv->vg->cmd, cache_lv) ||
+ !lv_is_active(cache_lv)) {
log_error("Failed to active cache locally %s.",
display_lvname(cache_lv));
return 0;
@@ -969,7 +969,7 @@ int wipe_cache_pool(struct logical_volume *cache_pool_lv)
}
cache_pool_lv->status |= LV_TEMPORARY;
- if (!activate_lv_excl_local(cache_pool_lv->vg->cmd, cache_pool_lv)) {
+ if (!activate_lv(cache_pool_lv->vg->cmd, cache_pool_lv)) {
log_error("Aborting. Failed to activate cache pool %s.",
display_lvname(cache_pool_lv));
return 0;
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index f930633..14d7312 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -1023,7 +1023,7 @@ int lv_raid_image_in_sync(const struct logical_volume *lv)
* If the LV is not active locally,
* it doesn't make sense to check status
*/
- if (!lv_is_active_locally(lv))
+ if (!lv_is_active(lv))
return 0; /* Assume not in-sync */
if (!lv_is_raid_image(lv)) {
@@ -1081,7 +1081,7 @@ int lv_raid_healthy(const struct logical_volume *lv)
* If the LV is not active locally,
* it doesn't make sense to check status
*/
- if (!lv_is_active_locally(lv))
+ if (!lv_is_active(lv))
return 1; /* assume healthy */
if (!lv_is_raid_type(lv)) {
@@ -1446,22 +1446,8 @@ char *lv_host_dup(struct dm_pool *mem, const struct logical_volume *lv)
return dm_pool_strdup(mem, lv->hostname ? : "");
}
-static int _lv_is_exclusive(struct logical_volume *lv)
-{
- struct lv_segment *seg;
-
- /* Some seg types require exclusive activation */
- /* FIXME Scan recursively */
- dm_list_iterate_items(seg, &lv->segments)
- if (seg_only_exclusive(seg))
- return 1;
-
- /* Origin has no seg type require exlusiveness */
- return lv_is_origin(lv);
-}
-
int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
- enum activation_change activate, int needs_exclusive)
+ enum activation_change activate)
{
const char *ay_with_mode = NULL;
@@ -1478,45 +1464,22 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
switch (activate) {
case CHANGE_AN:
+ case CHANGE_ALN:
log_verbose("Deactivating logical volume %s.", display_lvname(lv));
if (!deactivate_lv(cmd, lv))
return_0;
break;
- case CHANGE_ALN:
- log_verbose("Deactivating logical volume %s locally.",
- display_lvname(lv));
- if (!deactivate_lv_local(cmd, lv))
- return_0;
- break;
+
case CHANGE_ALY:
case CHANGE_AAY:
- if (needs_exclusive || _lv_is_exclusive(lv)) {
- log_verbose("Activating logical volume %s exclusively locally.",
- display_lvname(lv));
- if (!activate_lv_excl_local(cmd, lv))
- return_0;
- } else {
- log_verbose("Activating logical volume %s locally.",
- display_lvname(lv));
- if (!activate_lv_local(cmd, lv))
- return_0;
- }
- break;
case CHANGE_AEY:
-exclusive:
- log_verbose("Activating logical volume %s exclusively.",
- display_lvname(lv));
- if (!activate_lv_excl(cmd, lv))
- return_0;
- break;
case CHANGE_ASY:
case CHANGE_AY:
default:
- if (needs_exclusive || _lv_is_exclusive(lv))
- goto exclusive;
log_verbose("Activating logical volume %s.", display_lvname(lv));
if (!activate_lv(cmd, lv))
return_0;
+ break;
}
if (!is_change_activating(activate) &&
@@ -1535,23 +1498,10 @@ char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
goto out;
}
- if (vg_is_clustered(lv->vg)) {
- //const struct logical_volume *lvo = lv;
- lv = lv_lock_holder(lv);
- //log_debug("Holder for %s => %s.", lvo->name, lv->name);
- }
-
if (!lv_is_active(lv))
s = ""; /* not active */
- else if (!vg_is_clustered(lv->vg))
+ else
s = "active";
- else if (lv_is_active_exclusive(lv))
- /* exclusive cluster activation */
- s = lv_is_active_exclusive_locally(lv) ?
- "local exclusive" : "remote exclusive";
- else /* locally active */
- s = lv_is_active_but_not_locally(lv) ?
- "remotely" : "locally";
out:
return dm_pool_strdup(mem, s);
}
diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h
index 920bcb5..e2e640f 100644
--- a/lib/metadata/lv.h
+++ b/lib/metadata/lv.h
@@ -153,7 +153,7 @@ char *lvseg_kernel_discards_dup(struct dm_pool *mem, const struct lv_segment *se
int lv_set_creation(struct logical_volume *lv,
const char *hostname, uint64_t timestamp);
int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
- enum activation_change activate, int needs_exclusive);
+ enum activation_change activate);
/* LV dup functions */
char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm);
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index e023132..dad5953 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4058,7 +4058,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
for (s = 0; !fail && s < seg->area_count; s++) {
meta_lv = seg_metalv(seg, s);
- if (!activate_lv_local(meta_lv->vg->cmd, meta_lv)) {
+ if (!activate_lv(meta_lv->vg->cmd, meta_lv)) {
log_error("Failed to activate %s for clearing.",
display_lvname(meta_lv));
fail = 1;
@@ -4228,7 +4228,7 @@ int lv_extend(struct logical_volume *lv,
(lv_is_not_synced(lv))) {
dm_percent_t sync_percent = DM_PERCENT_INVALID;
- if (!lv_is_active_locally(lv)) {
+ if (!lv_is_active(lv)) {
log_error("Unable to read sync percent while LV %s "
"is not locally active.", display_lvname(lv));
/* FIXME Support --force */
@@ -4711,7 +4711,7 @@ static int _lvresize_adjust_policy(const struct logical_volume *lv,
return 0;
}
- if (!lv_is_active_locally(lv)) {
+ if (!lv_is_active(lv)) {
log_error("Can't read state of locally inactive LV %s.",
display_lvname(lv));
return 0;
@@ -5571,7 +5571,7 @@ int lv_resize(struct logical_volume *lv,
* then use suspend and resume and deactivate pool LV,
* instead of searching for an active thin volume.
*/
- if (!activate_lv_excl(cmd, lock_lv)) {
+ if (!activate_lv(cmd, lock_lv)) {
log_error("Failed to activate %s.", display_lvname(lock_lv));
return 0;
}
@@ -6788,7 +6788,7 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
struct segment_type *segtype;
struct lv_segment *mapseg;
struct lv_names lv_names;
- unsigned exclusive = 0, i;
+ unsigned i;
/* create an empty layer LV */
if (dm_snprintf(name, sizeof(name), "%s%s", lv_where->name, layer_suffix) < 0) {
@@ -6804,9 +6804,6 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
return NULL;
}
- if (lv_is_active_exclusive_locally(lv_where))
- exclusive = 1;
-
if (lv_is_active(lv_where) && strstr(name, MIRROR_SYNC_LAYER)) {
log_very_verbose("Creating transient LV %s for mirror conversion in VG %s.", name, lv_where->vg->name);
@@ -6835,10 +6832,7 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
return NULL;
}
- if (exclusive)
- r = activate_lv_excl(cmd, layer_lv);
- else
- r = activate_lv(cmd, layer_lv);
+ r = activate_lv(cmd, layer_lv);
if (!r) {
log_error("Failed to resume transient LV"
@@ -7125,7 +7119,7 @@ int wipe_lv(struct logical_volume *lv, struct wipe_params wp)
/* nothing to do */
return 1;
- if (!lv_is_active_locally(lv)) {
+ if (!lv_is_active(lv)) {
log_error("Volume \"%s/%s\" is not active locally (volume_list activation filter?).",
lv->vg->name, lv->name);
return 0;
@@ -7491,7 +7485,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return_NULL;
/* New pool is now inactive */
} else {
- if (!activate_lv_excl_local(cmd, pool_lv)) {
+ if (!activate_lv(cmd, pool_lv)) {
log_error("Aborting. Failed to locally activate thin pool %s.",
display_lvname(pool_lv));
return NULL;
@@ -7783,7 +7777,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (seg_is_cache(lp)) {
if (vg_is_shared(vg)) {
if (is_change_activating(lp->activate)) {
- if (!lv_active_change(cmd, lv, CHANGE_AEY, 0)) {
+ if (!lv_active_change(cmd, lv, CHANGE_AEY)) {
log_error("Aborting. Failed to activate LV %s.",
display_lvname(lv));
goto revert_new_lv;
@@ -7794,7 +7788,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
/* FIXME Support remote exclusive activation? */
/* Not yet 'cache' LV, it is stripe volume for wiping */
- else if (is_change_activating(lp->activate) && !activate_lv_excl_local(cmd, lv)) {
+ else if (is_change_activating(lp->activate) && !activate_lv(cmd, lv)) {
log_error("Aborting. Failed to activate LV %s locally exclusively.",
display_lvname(lv));
goto revert_new_lv;
@@ -7827,7 +7821,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
/* Avoid multiple thin-pool activations in this case */
if (thin_pool_was_active < 0)
thin_pool_was_active = 0;
- if (!activate_lv_excl(cmd, pool_lv)) {
+ if (!activate_lv(cmd, pool_lv)) {
log_error("Failed to activate thin pool %s.",
display_lvname(pool_lv));
goto revert_new_lv;
@@ -7846,7 +7840,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
}
backup(vg);
- if (!lv_active_change(cmd, lv, lp->activate, 0)) {
+ if (!lv_active_change(cmd, lv, lp->activate)) {
log_error("Failed to activate thin %s.", lv->name);
goto deactivate_and_revert_new_lv;
}
@@ -7860,13 +7854,13 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
}
} else if (lp->snapshot) {
lv->status |= LV_TEMPORARY;
- if (!activate_lv_local(cmd, lv)) {
+ if (!activate_lv(cmd, lv)) {
log_error("Aborting. Failed to activate snapshot "
"exception store.");
goto revert_new_lv;
}
lv->status &= ~LV_TEMPORARY;
- } else if (!lv_active_change(cmd, lv, lp->activate, 0)) {
+ } else if (!lv_active_change(cmd, lv, lp->activate)) {
log_error("Failed to activate new LV.");
goto deactivate_and_revert_new_lv;
}
@@ -7968,7 +7962,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
*/
/* Activate spare snapshot once it is a complete LV */
- if (!lv_active_change(cmd, origin_lv, lp->activate, 1)) {
+ if (!lv_active_change(cmd, origin_lv, lp->activate)) {
log_error("Failed to activate sparce volume %s.",
display_lvname(origin_lv));
return NULL;
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 9c775c4..8de1440 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -354,7 +354,7 @@ static int _init_mirror_log(struct cmd_context *cmd,
} else if (!lv_update_and_reload((struct logical_volume*) lock_holder))
return_0;
- if (!activate_lv_excl_local(cmd, log_lv)) {
+ if (!activate_lv(cmd, log_lv)) {
log_error("Aborting. Failed to activate mirror log.");
goto revert_new_lv;
}
@@ -427,15 +427,10 @@ static int _activate_lv_like_model(struct logical_volume *model,
/* FIXME: run all cases through lv_active_change when clvm variants are gone. */
if (vg_is_shared(lv->vg))
- return lv_active_change(lv->vg->cmd, lv, CHANGE_AEY, 0);
+ return lv_active_change(lv->vg->cmd, lv, CHANGE_AEY);
- if (lv_is_active_exclusive(model)) {
- if (!activate_lv_excl(lv->vg->cmd, lv))
- return_0;
- } else {
- if (!activate_lv(lv->vg->cmd, lv))
- return_0;
- }
+ if (!activate_lv(lv->vg->cmd, lv))
+ return_0;
return 1;
}
@@ -610,14 +605,7 @@ static int _mirrored_lv_in_sync(struct logical_volume *lv)
if (!lv_mirror_percent(lv->vg->cmd, lv, 0, &sync_percent,
NULL)) {
- if (lv_is_active_but_not_locally(lv))
- log_error("Unable to determine mirror sync status of"
- " remotely active LV, %s",
- display_lvname(lv));
- else
- log_error("Unable to determine mirror "
- "sync status of %s.",
- display_lvname(lv));
+ log_error("Unable to determine mirror sync status of %s.", display_lvname(lv));
return 0;
}
@@ -1668,7 +1656,6 @@ int remove_mirror_log(struct cmd_context *cmd,
int force)
{
dm_percent_t sync_percent;
- struct volume_group *vg = lv->vg;
/* Unimplemented features */
if (dm_list_size(&lv->segments) != 1) {
@@ -1677,20 +1664,12 @@ int remove_mirror_log(struct cmd_context *cmd,
}
/* Had disk log, switch to core. */
- if (lv_is_active_locally(lv)) {
+ if (lv_is_active(lv)) {
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent,
NULL)) {
log_error("Unable to determine mirror sync status.");
return 0;
}
- } else if (lv_is_active(lv)) {
- log_error("Unable to determine sync status of "
- "remotely active mirror volume %s.", display_lvname(lv));
- return 0;
- } else if (vg_is_clustered(vg)) {
- log_error("Unable to convert the log of an inactive "
- "cluster mirror volume %s.", display_lvname(lv));
- return 0;
} else if (force || yes_no_prompt("Full resync required to convert inactive "
"mirror volume %s to core log. "
"Proceed? [y/n]: ", display_lvname(lv)) == 'y')
@@ -1910,22 +1889,11 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
unsigned old_log_count;
int r = 0;
- if (vg_is_clustered(lv->vg) && (log_count > 1)) {
- log_error("Log type, \"mirrored\", is unavailable to cluster mirrors.");
- return 0;
- }
-
if (dm_list_size(&lv->segments) != 1) {
log_error("Multiple-segment mirror is not supported.");
return 0;
}
- if (lv_is_active_but_not_locally(lv)) {
- log_error("Unable to convert the log of a mirror, %s, that is "
- "active remotely but not locally.", display_lvname(lv));
- return 0;
- }
-
log_lv = first_seg(lv)->log_lv;
old_log_count = (log_lv) ? lv_mirror_count(log_lv) : 0;
if (old_log_count == log_count) {
@@ -2079,27 +2047,6 @@ int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
- if (vg_is_clustered(lv->vg)) {
- /* FIXME: move this test out of this function */
- /* Skip test for pvmove mirrors, it can use local mirror */
- if (!lv_is_pvmove(lv) && !lv_is_locked(lv) &&
- lv_is_active(lv) &&
- !lv_is_active_exclusive_locally(lv) && /* lv_is_active_remotely */
- !cluster_mirror_is_available(lv->vg->cmd)) {
- log_error("Shared cluster mirrors are not available.");
- return 0;
- }
-
- /*
- * No mirrored logs for cluster mirrors until
- * log daemon is multi-threaded.
- */
- if (log_count > 1) {
- log_error("Log type, \"mirrored\", is unavailable to cluster mirrors.");
- return 0;
- }
- }
-
if (lv->vg->lock_type && !strcmp(lv->vg->lock_type, "dlm") && cmd->lockd_lv_sh) {
if (!cluster_mirror_is_available(cmd)) {
log_error("Shared cluster mirrors are not available.");
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index 20224d1..80d2e07 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -526,7 +526,7 @@ int create_pool(struct logical_volume *pool_lv,
* or directly converted to invisible device via suspend/resume
*/
pool_lv->status |= LV_TEMPORARY;
- if (!activate_lv_excl_local(pool_lv->vg->cmd, pool_lv)) {
+ if (!activate_lv(pool_lv->vg->cmd, pool_lv)) {
log_error("Aborting. Failed to activate pool metadata %s.",
display_lvname(pool_lv));
goto bad;
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 53aa4f1..92e01a2 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -319,7 +319,7 @@ static int _deactivate_and_remove_lvs(struct volume_group *vg, struct dm_list *r
return 0;
}
/* Must get a cluster lock on SubLVs that will be removed. */
- if (!activate_lv_excl_local(vg->cmd, lvl->lv))
+ if (!activate_lv(vg->cmd, lvl->lv))
return_0;
}
@@ -669,7 +669,7 @@ static int _lv_update_and_reload_list(struct logical_volume *lv, int origin_only
dm_list_iterate_items(lvl, lv_list) {
log_very_verbose("Activating logical volume %s before %s in kernel.",
display_lvname(lvl->lv), display_lvname(lock_lv));
- if (!activate_lv_excl_local(vg->cmd, lvl->lv)) {
+ if (!activate_lv(vg->cmd, lvl->lv)) {
log_error("Failed to activate %s before resuming %s.",
display_lvname(lvl->lv), display_lvname(lock_lv));
r = 0; /* But lets try with the rest */
@@ -732,9 +732,9 @@ static int _clear_lvs(struct dm_list *lv_list)
was_active = alloca(sz);
dm_list_iterate_items(lvl, lv_list)
- if (!(was_active[i++] = lv_is_active_locally(lvl->lv))) {
+ if (!(was_active[i++] = lv_is_active(lvl->lv))) {
lvl->lv->status |= LV_TEMPORARY;
- if (!activate_lv_excl_local(vg->cmd, lvl->lv)) {
+ if (!activate_lv(vg->cmd, lvl->lv)) {
log_error("Failed to activate localy %s for clearing.",
display_lvname(lvl->lv));
r = 0;
@@ -2276,7 +2276,7 @@ static int _vg_write_lv_suspend_vg_commit(struct logical_volume *lv, int origin_
/* Helper: function to activate @lv exclusively local */
static int _activate_sub_lv_excl_local(struct logical_volume *lv)
{
- if (lv && !activate_lv_excl_local(lv->vg->cmd, lv)) {
+ if (lv && !activate_lv(lv->vg->cmd, lv)) {
log_error("Failed to activate %s.", display_lvname(lv));
return 0;
}
@@ -3258,16 +3258,6 @@ static int _lv_raid_change_image_count(struct logical_volume *lv, int yes, uint3
return r;
}
- /*
- * LV must be either in-active or exclusively active
- */
- if (lv_is_active(lv_lock_holder(lv)) && vg_is_clustered(lv->vg) &&
- !lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
- log_error("%s must be active exclusive locally to "
- "perform this operation.", display_lvname(lv));
- return 0;
- }
-
if (old_count > new_count)
return _raid_remove_images(lv, yes, new_count, allocate_pvs, removal_lvs, commit);
@@ -3427,13 +3417,13 @@ int lv_raid_split(struct logical_volume *lv, int yes, const char *split_name,
/* FIXME: run all cases through lv_active_change when clvm variants are gone. */
if (vg_is_shared(lvl->lv->vg)) {
- if (!lv_active_change(lv->vg->cmd, lvl->lv, CHANGE_AEY, 0))
+ if (!lv_active_change(lv->vg->cmd, lvl->lv, CHANGE_AEY))
return_0;
- } else if (!activate_lv_excl_local(cmd, lvl->lv))
+ } else if (!activate_lv(cmd, lvl->lv))
return_0;
dm_list_iterate_items(lvl, &removal_lvs)
- if (!activate_lv_excl_local(cmd, lvl->lv))
+ if (!activate_lv(cmd, lvl->lv))
return_0;
if (!resume_lv(cmd, lv_lock_holder(lv))) {
@@ -3539,7 +3529,7 @@ int lv_raid_split_and_track(struct logical_volume *lv,
/* Activate the split (and tracking) LV */
/* Preserving exclusive local activation also for tracked LV */
- if (!activate_lv_excl_local(lv->vg->cmd, seg_lv(seg, s)))
+ if (!activate_lv(lv->vg->cmd, seg_lv(seg, s)))
return_0;
if (seg->area_count == 2)
@@ -5001,7 +4991,7 @@ static int _clear_meta_lvs(struct logical_volume *lv)
/* Grab locks first in case of clustered VG */
if (vg_is_clustered(lv->vg))
dm_list_iterate_items(lvl, &meta_lvs)
- if (!activate_lv_excl_local(lv->vg->cmd, lvl->lv))
+ if (!activate_lv(lv->vg->cmd, lvl->lv))
return_0;
/*
* Now deactivate the MetaLVs before clearing, so
@@ -6520,14 +6510,6 @@ int lv_raid_convert(struct logical_volume *lv,
return 0;
}
- if (vg_is_clustered(lv->vg) &&
- !lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
- /* In clustered VGs, the LV must be active on this node exclusively. */
- log_error("%s must be active exclusive locally to "
- "perform this operation.", display_lvname(lv));
- return 0;
- }
-
new_segtype = new_segtype ? : seg->segtype;
if (!new_segtype) {
log_error(INTERNAL_ERROR "New segtype not specified.");
@@ -6810,10 +6792,8 @@ static int _lv_raid_rebuild_or_replace(struct logical_volume *lv,
if (lv_is_partial(lv))
lv->vg->cmd->partial_activation = 1;
- if (!lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
- log_error("%s must be active %sto perform this operation.",
- display_lvname(lv),
- vg_is_clustered(lv->vg) ? "exclusive locally " : "");
+ if (!lv_is_active(lv_lock_holder(lv))) {
+ log_error("%s must be active to perform this operation.", display_lvname(lv));
return 0;
}
@@ -7013,7 +6993,7 @@ try_again:
* of their new names.
*/
dm_list_iterate_items(lvl, &old_lvs)
- if (!activate_lv_excl_local(lv->vg->cmd, lvl->lv))
+ if (!activate_lv(lv->vg->cmd, lvl->lv))
return_0;
/*
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c
index e3669ef..5ccf251 100644
--- a/lib/metadata/snapshot_manip.c
+++ b/lib/metadata/snapshot_manip.c
@@ -411,11 +411,5 @@ int validate_snapshot_origin(const struct logical_volume *origin_lv)
return 0;
}
- if (vg_is_clustered(origin_lv->vg) && lv_is_active(origin_lv) &&
- !lv_is_active_exclusive_locally(origin_lv)) {
- log_error("Snapshot origin must be active exclusively.");
- return 0;
- }
-
return 1;
}
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index e1522d3..6b2b1e7 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -504,7 +504,7 @@ int update_pool_lv(struct logical_volume *lv, int activate)
* as this version has major problem when it does not know
* which Node has pool active.
*/
- if (!activate_lv_excl(lv->vg->cmd, lv)) {
+ if (!activate_lv(lv->vg->cmd, lv)) {
init_dmeventd_monitor(monitored);
return_0;
}
@@ -857,7 +857,7 @@ int check_new_thin_pool(const struct logical_volume *pool_lv)
uint64_t transaction_id;
/* For transaction_id check LOCAL activation is required */
- if (!activate_lv_excl_local(cmd, pool_lv)) {
+ if (!activate_lv(cmd, pool_lv)) {
log_error("Aborting. Failed to locally activate thin pool %s.",
display_lvname(pool_lv));
return 0;
diff --git a/lib/report/report.c b/lib/report/report.c
index 4a957a7..8039820 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -3559,11 +3559,7 @@ static int _lvactivelocally_disp(struct dm_report *rh, struct dm_pool *mem,
if (!activation())
return _binary_undef_disp(rh, mem, field, private);
- if (vg_is_clustered(lv->vg)) {
- lv = lv_lock_holder(lv);
- active_locally = lv_is_active_locally(lv);
- } else
- active_locally = lv_is_active(lv);
+ active_locally = lv_is_active(lv);
return _binary_disp(rh, mem, field, active_locally, GET_FIRST_RESERVED_NAME(lv_active_locally_y), private);
}
@@ -3572,38 +3568,12 @@ static int _lvactiveremotely_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
- const struct logical_volume *lv = (const struct logical_volume *) data;
int active_remotely;
if (!activation())
return _binary_undef_disp(rh, mem, field, private);
- if (vg_is_clustered(lv->vg)) {
- lv = lv_lock_holder(lv);
- /* FIXME: It seems we have no way to get this info correctly
- * with current interface - we'd need to check number
- * of responses from the cluster:
- * - if number of nodes that responded == 1
- * - and LV is active on local node
- * ..then we may say that LV is *not* active remotely.
- *
- * Otherwise ((responses > 1 && LV active locally) ||
- * (responses == 1 && LV not active locally)), it's
- * active remotely.
- *
- * We have this info, but hidden underneath the
- * locking interface (locking_type.query_resource fn).
- *
- * For now, let's use 'unknown' for remote status if
- * the LV is found active locally until we find a way to
- * smuggle the proper information out of the interface.
- */
- if (lv_is_active_locally(lv))
- return _binary_undef_disp(rh, mem, field, private);
-
- active_remotely = lv_is_active_but_not_locally(lv);
- } else
- active_remotely = 0;
+ active_remotely = 0;
return _binary_disp(rh, mem, field, active_remotely, GET_FIRST_RESERVED_NAME(lv_active_remotely_y), private);
}
@@ -3618,11 +3588,7 @@ static int _lvactiveexclusively_disp(struct dm_report *rh, struct dm_pool *mem,
if (!activation())
return _binary_undef_disp(rh, mem, field, private);
- if (vg_is_clustered(lv->vg)) {
- lv = lv_lock_holder(lv);
- active_exclusively = lv_is_active_exclusive(lv);
- } else
- active_exclusively = lv_is_active(lv);
+ active_exclusively = lv_is_active(lv);
return _binary_disp(rh, mem, field, active_exclusively, GET_FIRST_RESERVED_NAME(lv_active_exclusively_y), private);
}
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 481cb4c..a90174e 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -294,9 +294,6 @@ static int _reactivate_lv(struct logical_volume *lv,
if (!active)
return 1;
- if (exclusive)
- return activate_lv_excl_local(cmd, lv);
-
return activate_lv(cmd, lv);
}
@@ -318,7 +315,7 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
dm_list_init(&device_list);
- if (lv_is_active_locally(lv)) {
+ if (lv_is_active(lv)) {
if (!lv_check_not_in_use(lv, 1)) {
log_error("Can't resync open logical volume %s.",
display_lvname(lv));
@@ -335,7 +332,7 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
}
active = 1;
- if (lv_is_active_exclusive_locally(lv))
+ if (lv_is_active(lv))
exclusive = 1;
}
@@ -411,7 +408,7 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
memlock_unlock(lv->vg->cmd);
dm_list_iterate_items(lvl, &device_list) {
- if (!activate_lv_excl_local(cmd, lvl->lv)) {
+ if (!activate_lv(cmd, lvl->lv)) {
log_error("Unable to activate %s for %s clearing.",
display_lvname(lvl->lv), (seg_is_raid(seg)) ?
"metadata area" : "mirror log");
@@ -621,7 +618,7 @@ static int _lvchange_persistent(struct cmd_context *cmd,
if (activate != CHANGE_AN) {
log_verbose("Re-activating logical volume %s.", display_lvname(lv));
- if (!lv_active_change(cmd, lv, activate, 0)) {
+ if (!lv_active_change(cmd, lv, activate)) {
log_error("%s: reactivation failed.", display_lvname(lv));
backup(lv->vg);
return 0;
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index aebf3e9..11f7cee 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1767,7 +1767,7 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
return 0;
}
- if (lv_is_active_locally(cow)) {
+ if (lv_is_active(cow)) {
if (!lv_check_not_in_use(cow, 1))
return_0;
@@ -1950,7 +1950,7 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
log_warn("WARNING: %s not zeroed.", snap_name);
else {
lv->status |= LV_TEMPORARY;
- if (!activate_lv_excl_local(cmd, lv) ||
+ if (!activate_lv(cmd, lv) ||
!wipe_lv(lv, (struct wipe_params) { .do_zero = 1 })) {
log_error("Aborting. Failed to wipe snapshot exception store.");
return 0;
@@ -2037,7 +2037,7 @@ static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
* constructor and DM should prevent appropriate devices from
* being open.
*/
- if (lv_is_active_locally(origin)) {
+ if (lv_is_active(origin)) {
if (!lv_check_not_in_use(origin, 0)) {
log_print_unless_silent("Delaying merge since origin is open.");
merge_on_activate = 1;
@@ -2146,7 +2146,7 @@ static int _lvconvert_merge_thin_snapshot(struct cmd_context *cmd,
log_print_unless_silent("Volume %s replaced origin %s.",
display_lvname(origin), display_lvname(lv));
- if (origin_is_active && !activate_lv_excl_local(cmd, lv)) {
+ if (origin_is_active && !activate_lv(cmd, lv)) {
log_error("Failed to reactivate origin %s.",
display_lvname(lv));
return 0;
@@ -2254,13 +2254,13 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
return 0;
}
- if (!activate_lv_excl_local(cmd, pmslv)) {
+ if (!activate_lv(cmd, pmslv)) {
log_error("Cannot activate pool metadata spare volume %s.",
pmslv->name);
return 0;
}
- if (!activate_lv_excl_local(cmd, mlv)) {
+ if (!activate_lv(cmd, mlv)) {
log_error("Cannot activate thin pool metadata volume %s.",
mlv->name);
goto deactivate_pmslv;
@@ -2452,13 +2452,13 @@ static int _lvconvert_cache_repair(struct cmd_context *cmd,
return 0;
}
- if (!activate_lv_excl_local(cmd, pmslv)) {
+ if (!activate_lv(cmd, pmslv)) {
log_error("Cannot activate pool metadata spare volume %s.",
pmslv->name);
return 0;
}
- if (!activate_lv_excl_local(cmd, mlv)) {
+ if (!activate_lv(cmd, mlv)) {
log_error("Cannot activate cache pool metadata volume %s.",
mlv->name);
goto deactivate_pmslv;
@@ -3106,7 +3106,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
if (zero_metadata) {
metadata_lv->status |= LV_TEMPORARY;
- if (!activate_lv_excl_local(cmd, metadata_lv)) {
+ if (!activate_lv(cmd, metadata_lv)) {
log_error("Aborting. Failed to activate metadata lv.");
goto bad;
}
@@ -3248,7 +3248,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
}
if (activate_pool &&
- !activate_lv_excl(cmd, pool_lv)) {
+ !activate_lv(cmd, pool_lv)) {
log_error("Failed to activate pool logical volume %s.",
display_lvname(pool_lv));
/* Deactivate subvolumes */
@@ -3461,11 +3461,8 @@ static int _lvconvert_repair_pvs_raid(struct cmd_context *cmd, struct logical_vo
struct dm_list *failed_pvs;
int do_it;
- if (!lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
- log_error("%s must be active %sto perform this operation.",
- display_lvname(lv),
- vg_is_clustered(lv->vg) ?
- "exclusive locally " : "");
+ if (!lv_is_active(lv_lock_holder(lv))) {
+ log_error("%s must be active to perform this operation.", display_lvname(lv));
return 0;
}
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 5c9d448..4009ea5 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1232,13 +1232,13 @@ static int _determine_cache_argument(struct volume_group *vg,
return 1;
} else if (vg_is_shared(vg)) {
- if (!lv_active_change(cmd, lv, CHANGE_AEY, 0)) {
+ if (!lv_active_change(cmd, lv, CHANGE_AEY)) {
log_error("Cannot activate cache origin %s.",
display_lvname(lv));
return 0;
}
- } else if (!activate_lv_excl_local(cmd, lv)) {
+ } else if (!activate_lv(cmd, lv)) {
log_error("Cannot activate cache origin %s.",
display_lvname(lv));
return 0;
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
index bd99c7b..7ad45ca 100644
--- a/tools/polldaemon.c
+++ b/tools/polldaemon.c
@@ -200,7 +200,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
* If the LV is not active locally, the kernel cannot be
* queried for its status. We must exit in this case.
*/
- if (!lv_is_active_locally(lv)) {
+ if (!lv_is_active(lv)) {
log_print_unless_silent("%s: Interrupted: No longer active.", id->display_name);
ret = 1;
goto out;
@@ -440,7 +440,7 @@ static int _report_progress(struct cmd_context *cmd, struct poll_operation_id *i
goto out;
}
- if (!lv_is_active_locally(lv)) {
+ if (!lv_is_active(lv)) {
log_verbose("%s: Interrupted: No longer active.", id->display_name);
ret = 1;
goto out;
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 0fcabb3..c5e3929 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -466,8 +466,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
* in the case it's NOT active anywhere else, since LOCKED LVs cannot be
* later activated by user.
*/
- if (lv_is_active_remotely(holder) ||
- (!lv_is_active_locally(holder) && !activate_lv_excl_local(cmd, holder))) {
+ if ((!lv_is_active(holder) && !activate_lv(cmd, holder))) {
lv_skipped = 1;
log_print_unless_silent("Skipping LV %s which is not locally exclusive%s.",
display_lvname(lv),
@@ -532,10 +531,7 @@ static int _activate_lv(struct cmd_context *cmd, struct logical_volume *lv_mirr,
{
int r = 0;
- if (exclusive || lv_is_active_exclusive(lv_mirr))
- r = activate_lv_excl(cmd, lv_mirr);
- else
- r = activate_lv(cmd, lv_mirr);
+ r = activate_lv(cmd, lv_mirr);
if (!r)
stack;
diff --git a/tools/toollib.c b/tools/toollib.c
index baf84ad..236e2b1 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1034,7 +1034,7 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
- if (!lv_active_change(cmd, lv, activate, 0))
+ if (!lv_active_change(cmd, lv, activate))
return_0;
set_lv_notify(lv->vg->cmd);
@@ -1066,7 +1066,7 @@ int lv_refresh(struct cmd_context *cmd, struct logical_volume *lv)
* - fortunately: polldaemon will immediately shutdown if the
* origin doesn't have a status with a snapshot percentage
*/
- if (background_polling() && lv_is_merging_origin(lv) && lv_is_active_locally(lv))
+ if (background_polling() && lv_is_merging_origin(lv) && lv_is_active(lv))
lv_spawn_background_polling(cmd, lv);
return 1;
diff --git a/tools/vgchange.c b/tools/vgchange.c
index e87277f..a67c3be 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -63,7 +63,7 @@ static int _poll_lvs_in_vg(struct cmd_context *cmd,
dm_list_iterate_items(lvl, &vg->lvs) {
lv = lvl->lv;
- if (lv_is_active_locally(lv) &&
+ if (lv_is_active(lv) &&
(lv_is_pvmove(lv) || lv_is_converting(lv) || lv_is_merging(lv))) {
lv_spawn_background_polling(cmd, lv);
count++;
@@ -116,20 +116,8 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd, struct volume_group *vg,
expected_count++;
- if (!lv_change_activate(cmd, lv, activate)) {
- if (!lv_is_active_exclusive_remotely(lv))
- stack;
- else {
- /*
- * If the LV is active exclusive remotely,
- * then ignore it here
- */
- log_verbose("%s is exclusively active on a remote node.",
- display_lvname(lv));
- expected_count--; /* not accounted */
- }
+ if (!lv_change_activate(cmd, lv, activate))
continue;
- }
count++;
}
5 years, 11 months
master - Remove more clvm code
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=eb600292455b1b2b2e8...
Commit: eb600292455b1b2b2e88db74e13b7db848701b92
Parent: 3c657adc0a2c9026fef3186147f0d9a11b071c3b
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 5 11:39:07 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 13:58:34 2018 -0500
Remove more clvm code
---
lib/format_text/archiver.c | 4 ----
lib/locking/locking.h | 15 +++++----------
lib/metadata/metadata.c | 7 -------
3 files changed, 5 insertions(+), 21 deletions(-)
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 9d7be95..ab80117 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -275,10 +275,6 @@ int backup(struct volume_group *vg)
if (is_orphan_vg(vg->name))
return 1;
- if (vg_is_clustered(vg))
- if (!remote_backup_metadata(vg))
- stack;
-
return backup_locally(vg);
}
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 8322bae..8b2bced 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -163,10 +163,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_MASK (LCK_TYPE_MASK | LCK_SCOPE_MASK)
-#define LCK_LV_CLUSTERED(lv) \
- (vg_is_clustered((lv)->vg) ? LCK_CLUSTER_VG : 0)
-
-#define lock_lv_vol(cmd, lv, flags) lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv), lv)
+#define lock_lv_vol(cmd, lv, flags) lock_vol(cmd, (lv)->lvid.s, flags, lv)
/*
* Activation locks are wrapped around activation commands that have to
@@ -180,7 +177,9 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
*/
#define lv_type_requires_activation_lock(lv) ((lv_is_thin_type(lv) || lv_is_cache_type(lv) || lv_is_mirror_type(lv) || lv_is_raid_type(lv) || lv_is_origin(lv) || lv_is_snapshot(lv)) ? 1 : 0)
+
#define lv_activation_lock_name(lv) (lv_type_requires_activation_lock(lv) ? (lv)->vg->name : (lv)->lvid.s)
+
#define lv_requires_activation_lock_now(lv) ((!vg_write_lock_held() && (!vg_is_clustered((lv)->vg) || !lv_type_requires_activation_lock(lv))) ? 1 : 0)
#define lock_activation(cmd, lv) (lv_requires_activation_lock_now(lv) ? lock_vol(cmd, lv_activation_lock_name(lv), LCK_ACTIVATE_LOCK, lv) : 1)
@@ -246,16 +245,12 @@ int activate_lv_excl(struct cmd_context *cmd, const struct logical_volume *lv);
#define activate_lv_local(cmd, lv) \
lock_lv_vol_serially(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
+
#define deactivate_lv_local(cmd, lv) \
lock_lv_vol_serially(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
+
#define drop_cached_metadata(vg) \
lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE, NULL)
-#define remote_commit_cached_metadata(vg) \
- lock_vol((vg)->cmd, (vg)->name, LCK_VG_COMMIT, NULL)
-#define remote_revert_cached_metadata(vg) \
- lock_vol((vg)->cmd, (vg)->name, LCK_VG_REVERT, NULL)
-#define remote_backup_metadata(vg) \
- lock_vol((vg)->cmd, (vg)->name, LCK_VG_BACKUP, NULL)
int sync_local_dev_names(struct cmd_context* cmd);
int sync_dev_names(struct cmd_context* cmd);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 3f177b0..7c41d78 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3130,10 +3130,6 @@ int vg_commit(struct volume_group *vg)
set_vg_notify(vg->cmd);
if (cache_updated) {
- /* Instruct remote nodes to upgrade cached metadata. */
- if (!remote_commit_cached_metadata(vg))
- stack; // FIXME: What should we do?
-
/*
* We need to clear old_name after a successful commit.
* The volume_group structure could be reused later.
@@ -3188,9 +3184,6 @@ void vg_revert(struct volume_group *vg)
if (!drop_cached_metadata(vg))
log_error("Attempt to drop cached metadata failed "
"after reverted update for VG %s.", vg->name);
-
- if (!remote_revert_cached_metadata(vg))
- stack; // FIXME: What should we do?
}
static int _check_mda_in_use(struct metadata_area *mda, void *_in_use)
5 years, 11 months
master - lvmlockd: fix missing lock_type null check
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3c657adc0a2c9026fef...
Commit: 3c657adc0a2c9026fef3186147f0d9a11b071c3b
Parent: c67bd8b47b755a33104e942abc49e516d2a6dace
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 6 13:56:02 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 13:58:03 2018 -0500
lvmlockd: fix missing lock_type null check
Missed checking if vg->lock_type is NULL in commit db8d3bdfa:
lvmlockd: enable mirror split and merge with dlm lock_type
---
lib/metadata/raid_manip.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 4d58d74..53aa4f1 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -3395,7 +3395,7 @@ int lv_raid_split(struct logical_volume *lv, int yes, const char *split_name,
lvl->lv->name = split_name;
- if (!strcmp(lv->vg->lock_type, "dlm"))
+ if (lv->vg->lock_type && !strcmp(lv->vg->lock_type, "dlm"))
lvl->lv->lock_args = lv->lock_args;
if (!vg_write(lv->vg)) {
5 years, 11 months
master - devices: clean up io error messages
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c67bd8b47b755a33104...
Commit: c67bd8b47b755a33104e942abc49e516d2a6dace
Parent: 3e781ea446bb7ddc9a494cbba6b6104dd51c3910
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 6 10:05:08 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 6 10:08:25 2018 -0500
devices: clean up io error messages
Remove the io error message from bcache.c since it is not
very useful without the device path.
Make the io error messages from dev_read_bytes/dev_write_bytes
more user friendly.
---
lib/device/bcache.c | 1 -
lib/label/label.c | 40 ++++++++++++++++++++++------------------
2 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 8fda0bd..561f68e 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -623,7 +623,6 @@ static void _complete_io(void *context, int err)
dm_list_del(&b->list);
if (b->error) {
- log_warn("bcache io error %d fd %d", b->error, b->fd);
dm_list_add(&cache->errored, &b->list);
} else {
diff --git a/lib/label/label.c b/lib/label/label.c
index f36c706..ce995d6 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1122,14 +1122,15 @@ bool dev_read_bytes(struct device *dev, uint64_t start, size_t len, void *data)
if (dev->bcache_fd <= 0) {
/* This is not often needed, perhaps only with lvmetad. */
if (!label_scan_open(dev)) {
- log_error("dev_read_bytes %s cannot open dev", dev_name(dev));
+ log_error("Error opening device %s for reading at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
return false;
}
}
if (!bcache_read_bytes(scan_bcache, dev->bcache_fd, start, len, data)) {
- log_error("dev_read_bytes %s at %u failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error reading device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
@@ -1151,21 +1152,22 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
if (dev->bcache_fd <= 0) {
/* This is not often needed, perhaps only with lvmetad. */
if (!label_scan_open(dev)) {
- log_error("dev_write_bytes %s cannot open dev", dev_name(dev));
+ log_error("Error opening device %s for writing at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
return false;
}
}
if (!bcache_write_bytes(scan_bcache, dev->bcache_fd, start, len, data)) {
- log_error("dev_write_bytes %s at %u bcache write failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error writing device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
if (!bcache_flush(scan_bcache)) {
- log_error("dev_write_bytes %s at %u bcache flush failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error writing device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
@@ -1185,21 +1187,22 @@ bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
if (dev->bcache_fd <= 0) {
/* This is not often needed, perhaps only with lvmetad. */
if (!label_scan_open(dev)) {
- log_error("dev_write_zeros %s cannot open dev", dev_name(dev));
+ log_error("Error opening device %s for writing at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
return false;
}
}
if (!bcache_zero_bytes(scan_bcache, dev->bcache_fd, start, len)) {
- log_error("dev_write_zeros %s at %u bcache write failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error writing device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
if (!bcache_flush(scan_bcache)) {
- log_error("dev_write_zeros %s at %u bcache flush failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error writing device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
@@ -1219,21 +1222,22 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
if (dev->bcache_fd <= 0) {
/* This is not often needed, perhaps only with lvmetad. */
if (!label_scan_open(dev)) {
- log_error("dev_set_bytes %s cannot open dev", dev_name(dev));
+ log_error("Error opening device %s for writing at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
return false;
}
}
if (!bcache_set_bytes(scan_bcache, dev->bcache_fd, start, len, val)) {
- log_error("dev_set_bytes %s at %u bcache write failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error writing device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
if (!bcache_flush(scan_bcache)) {
- log_error("dev_set_bytes %s at %u bcache flush failed invalidate fd %d",
- dev_name(dev), (uint32_t)start, dev->bcache_fd);
+ log_error("Error writing device %s at %llu length %u.",
+ dev_name(dev), (unsigned long long)start, (uint32_t)len);
label_scan_invalidate(dev);
return false;
}
5 years, 11 months
master - Remove clvmd and associated code
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3e781ea446bb7ddc9a4...
Commit: 3e781ea446bb7ddc9a494cbba6b6104dd51c3910
Parent: 11384637fb57c0fdefe5940cf27285ebdcc1dbc6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 5 10:47:01 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Jun 5 11:09:13 2018 -0500
Remove clvmd and associated code
More code reduction and simplification can follow.
---
configure.ac | 289 +-----
daemons/Makefile.in | 8 +-
daemons/clvmd/.gitignore | 1 -
daemons/clvmd/Makefile.in | 94 --
daemons/clvmd/clvm.h | 85 --
daemons/clvmd/clvmd-cman.c | 505 --------
daemons/clvmd/clvmd-command.c | 415 -------
daemons/clvmd/clvmd-common.h | 27 -
daemons/clvmd/clvmd-comms.h | 119 --
daemons/clvmd/clvmd-corosync.c | 662 -----------
daemons/clvmd/clvmd-openais.c | 687 -----------
daemons/clvmd/clvmd-singlenode.c | 382 ------
daemons/clvmd/clvmd.c | 2422 --------------------------------------
daemons/clvmd/clvmd.h | 126 --
daemons/clvmd/lvm-functions.c | 927 ---------------
daemons/clvmd/lvm-functions.h | 40 -
daemons/clvmd/refresh_clvmd.c | 382 ------
daemons/clvmd/refresh_clvmd.h | 19 -
daemons/cmirrord/Makefile.in | 6 +-
daemons/cmirrord/cluster.c | 3 +
include/configure.h.in | 18 -
lib/Makefile.in | 13 +-
lib/activate/activate.c | 214 +----
lib/cache/lvmcache.c | 395 -------
lib/locking/Makefile.in | 26 -
lib/locking/cluster_locking.c | 636 ----------
lib/locking/external_locking.c | 106 --
lib/locking/locking.c | 152 +---
lib/locking/locking_types.h | 6 -
lib/locking/no_locking.c | 126 --
lib/metadata/lv.c | 10 -
lib/metadata/lv_manip.c | 20 -
lib/metadata/metadata.c | 126 +--
lib/metadata/metadata.h | 9 -
lib/metadata/vg.c | 50 -
lib/metadata/vg.h | 1 -
lib/mirror/mirrored.c | 15 +-
tools/args.h | 13 +-
tools/command-lines.in | 4 +-
tools/lvchange.c | 29 -
tools/lvconvert.c | 13 -
tools/lvmcmdline.c | 5 -
tools/pvmove.c | 4 -
tools/toollib.c | 59 +-
tools/vgchange.c | 139 ---
tools/vgcreate.c | 11 +-
tools/vgsplit.c | 1 -
47 files changed, 36 insertions(+), 9364 deletions(-)
diff --git a/configure.ac b/configure.ac
index 751a784..67f2462 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 ebbd740..8edaefa 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 816032f..0000000
--- 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 622a603..0000000
--- 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,, "@CLVMD@,"))
- 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 ae0a13a..0000000
--- 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 8cf7f17..0000000
--- 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 342adda..0000000
--- 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 fb1c487..0000000
--- 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 f94077c..0000000
--- 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 6a9705d..0000000
--- 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 6b4fb10..0000000
--- 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 2d53f13..0000000
--- 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 73f4711..0000000
--- 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 edaee88..0000000
--- 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 ed82959..0000000
--- 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 6785997..0000000
--- 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 c80e09f..0000000
--- 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 b9d775e..0000000
--- 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 fc0ef6d..b6bab2d 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 6bb9d63..c516447 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 15fd150..65a2a6a 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 1d42235..4b64ce0 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 a15a2d7..4c70443 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 527f0a6..b9aa8a0 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 78f380f..0000000
--- 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 0830b48..0000000
--- 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 a1169a5..0000000
--- 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 db6233b..0e5658f 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 c4c832a..99aa964 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 fa066cc..0000000
--- 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 68507dc..f930633 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 b78e5d0..e023132 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 1bbea19..3f177b0 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 3d6750f..129267c 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 b44c7ca..db382d0 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 3d24bba..6208159 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 6746b1a..4110dec 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 603a0cf..2434f4b 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 9d407d0..409f01c 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 036b851..481cb4c 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 536b925..aebf3e9 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 be2a31b..4f4e917 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 1daf364..0fcabb3 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 832fae6..baf84ad 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 ee6c3b9..e87277f 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 52c4825..94f95ec 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 e30a671..1e46e7e 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;
5 years, 11 months