summaryrefslogtreecommitdiff
path: root/lib/locking/lvmlockd.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/locking/lvmlockd.c')
-rw-r--r--lib/locking/lvmlockd.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 0098de8f3..058cca79d 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -12,6 +12,7 @@
#include "toolcontext.h"
#include "metadata.h"
#include "segtype.h"
+#include "activate.h"
#include "lvmetad.h"
#include "lvmlockd.h"
#include "lvmcache.h"
@@ -1979,3 +1980,128 @@ int lockd_update_local(struct cmd_context *cmd)
return ret;
}
+
+int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg)
+{
+ struct lv_list *lvl;
+ daemon_reply reply;
+ int result;
+ int ret;
+
+ if (!is_lockd_type(vg->lock_type))
+ return 1;
+
+ if (lvs_in_vg_activated(vg)) {
+ log_error("LVs must be inactive before vgrename.");
+ return 0;
+ }
+
+ /* Check that no LVs are active on other hosts. */
+
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ if (!lockd_lv(cmd, lvl->lv, "ex", 0)) {
+ log_error("LV %s/%s must be inactive on all hosts before vgrename.",
+ vg->name, lvl->lv->name);
+ return 0;
+ }
+
+ if (!lockd_lv(cmd, lvl->lv, "un", 0)) {
+ log_error("Failed to unlock LV %s/%s.", vg->name, lvl->lv->name);
+ return 0;
+ }
+ }
+
+ /*
+ * lvmlockd:
+ * checks for other hosts in lockspace
+ * leaves the lockspace
+ */
+
+ reply = _lockd_send("rename_vg_before",
+ "pid = %d", getpid(),
+ "vg_name = %s", vg->name,
+ "vg_lock_type = %s", vg->lock_type,
+ "vg_lock_args = %s", vg->lock_args,
+ NULL);
+
+ if (!_lockd_result(reply, &result, NULL)) {
+ ret = 0;
+ } else {
+ ret = (result < 0) ? 0 : 1;
+ }
+
+ daemon_reply_destroy(reply);
+
+ if (!ret) {
+ log_error("lockd_rename_vg_before lvmlockd result %d", result);
+ return 0;
+ }
+
+ if (!strcmp(vg->lock_type, "sanlock")) {
+ log_debug("lockd_rename_vg_before deactivate sanlock lv");
+ _deactivate_sanlock_lv(cmd, vg);
+ }
+
+ return 1;
+}
+
+int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int success)
+{
+ daemon_reply reply;
+ int result;
+ int ret;
+
+ if (!is_lockd_type(vg->lock_type))
+ return 1;
+
+ if (!success) {
+ /*
+ * Depending on the problem that caused the rename to
+ * fail, it may make sense to not restart the VG here.
+ */
+ if (!lockd_start_vg(cmd, vg))
+ log_error("Failed to restart VG %s lockspace.", vg->name);
+ return 1;
+ }
+
+ if (!strcmp(vg->lock_type, "sanlock")) {
+ if (!_activate_sanlock_lv(cmd, vg))
+ return 0;
+
+ /*
+ * lvmlockd needs to rewrite the leases on disk
+ * with the new VG (lockspace) name.
+ */
+ reply = _lockd_send("rename_vg_final",
+ "pid = %d", getpid(),
+ "vg_name = %s", vg->name,
+ "vg_lock_type = %s", vg->lock_type,
+ "vg_lock_args = %s", vg->lock_args,
+ NULL);
+
+ if (!_lockd_result(reply, &result, NULL)) {
+ ret = 0;
+ } else {
+ ret = (result < 0) ? 0 : 1;
+ }
+
+ daemon_reply_destroy(reply);
+
+ if (!ret) {
+ /*
+ * The VG has been renamed on disk, but renaming the
+ * sanlock leases failed. Cleaning this up can
+ * probably be done by converting the VG to lock_type
+ * none, then converting back to sanlock.
+ */
+ log_error("lockd_rename_vg_final lvmlockd result %d", result);
+ return 0;
+ }
+ }
+
+ if (!lockd_start_vg(cmd, vg))
+ log_error("Failed to start VG %s lockspace.", vg->name);
+
+ return 1;
+}
+