104 lines
4.3 KiB
Diff
104 lines
4.3 KiB
Diff
|
From 34baef58db442148b8e067509d2cdd37b7a91ef4 Mon Sep 17 00:00:00 2001
|
||
|
From: "sreejit.mohanan" <sreejit.mohanan@nutanix.com>
|
||
|
Date: Thu, 7 Sep 2023 15:57:51 -0700
|
||
|
Subject: [PATCH] fence_scsi: fix registration handling in device 'off'
|
||
|
workflows
|
||
|
|
||
|
ISID (Initiator Session ID) belonging to I_T Nexus changes for
|
||
|
RHEL based on the session ID. This means that the connection to
|
||
|
the device can be set up with different ISID on reconnects.
|
||
|
|
||
|
When a device is powered off, fence_scsi assumes that the client
|
||
|
has a registration to the device and sends a preempt-and-abort
|
||
|
request which ends up failing due to reservation conflict.
|
||
|
|
||
|
Fixing this by registering the host key with the device and preempting
|
||
|
the old registration (if it exists). This should make sure that the
|
||
|
host is able to preempt the other key successfully.
|
||
|
---
|
||
|
agents/scsi/fence_scsi.py | 29 +++++++++++++++--------------
|
||
|
1 file changed, 15 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py
|
||
|
index 42530ceb5..519319bf5 100644
|
||
|
--- a/agents/scsi/fence_scsi.py
|
||
|
+++ b/agents/scsi/fence_scsi.py
|
||
|
@@ -41,7 +41,7 @@ def set_status(conn, options):
|
||
|
for dev in options["devices"]:
|
||
|
is_block_device(dev)
|
||
|
|
||
|
- register_dev(options, dev)
|
||
|
+ register_dev(options, dev, options["--key"])
|
||
|
if options["--key"] not in get_registration_keys(options, dev):
|
||
|
count += 1
|
||
|
logging.debug("Failed to register key "\
|
||
|
@@ -62,7 +62,7 @@ def set_status(conn, options):
|
||
|
fail_usage("Failed: keys cannot be same. You can not fence yourself.")
|
||
|
for dev in options["devices"]:
|
||
|
is_block_device(dev)
|
||
|
-
|
||
|
+ register_dev(options, dev, host_key)
|
||
|
if options["--key"] in get_registration_keys(options, dev):
|
||
|
preempt_abort(options, host_key, dev)
|
||
|
|
||
|
@@ -131,11 +131,11 @@ def reset_dev(options, dev):
|
||
|
return run_cmd(options, options["--sg_turs-path"] + " " + dev)["rc"]
|
||
|
|
||
|
|
||
|
-def register_dev(options, dev):
|
||
|
+def register_dev(options, dev, key):
|
||
|
dev = os.path.realpath(dev)
|
||
|
if re.search(r"^dm", dev[5:]):
|
||
|
for slave in get_mpath_slaves(dev):
|
||
|
- register_dev(options, slave)
|
||
|
+ register_dev(options, slave, key)
|
||
|
return True
|
||
|
|
||
|
# Check if any registration exists for the key already. We track this in
|
||
|
@@ -143,34 +143,35 @@ def register_dev(options, dev):
|
||
|
# This is needed since the previous registration could be for a
|
||
|
# different I_T nexus (different ISID).
|
||
|
registration_key_exists = False
|
||
|
- if options["--key"] in get_registration_keys(options, dev):
|
||
|
+ if key in get_registration_keys(options, dev):
|
||
|
+ logging.debug("Registration key exists for device " + dev)
|
||
|
registration_key_exists = True
|
||
|
- if not register_helper(options, options["--key"], dev):
|
||
|
+ if not register_helper(options, dev, key):
|
||
|
return False
|
||
|
|
||
|
if registration_key_exists:
|
||
|
# If key matches, make sure it matches with the connection that
|
||
|
# exists right now. To do this, we can issue a preempt with same key
|
||
|
# which should replace the old invalid entries from the target.
|
||
|
- if not preempt(options, options["--key"], dev):
|
||
|
+ if not preempt(options, key, dev, key):
|
||
|
return False
|
||
|
|
||
|
# If there was no reservation, we need to issue another registration
|
||
|
# since the previous preempt would clear registration made above.
|
||
|
- if get_reservation_key(options, dev, False) != options["--key"]:
|
||
|
- return register_helper(options, options["--key"], dev)
|
||
|
+ if get_reservation_key(options, dev, False) != key:
|
||
|
+ return register_helper(options, dev, key)
|
||
|
return True
|
||
|
|
||
|
-# cancel registration without aborting tasks
|
||
|
-def preempt(options, host, dev):
|
||
|
+# helper function to preempt host with 'key' using 'host_key' without aborting tasks
|
||
|
+def preempt(options, host_key, dev, key):
|
||
|
reset_dev(options,dev)
|
||
|
- cmd = options["--sg_persist-path"] + " -n -o -P -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev
|
||
|
+ cmd = options["--sg_persist-path"] + " -n -o -P -T 5 -K " + host_key + " -S " + key + " -d " + dev
|
||
|
return not bool(run_cmd(options, cmd)["rc"])
|
||
|
|
||
|
# helper function to send the register command
|
||
|
-def register_helper(options, host, dev):
|
||
|
+def register_helper(options, dev, key):
|
||
|
reset_dev(options, dev)
|
||
|
- cmd = options["--sg_persist-path"] + " -n -o -I -S " + options["--key"] + " -d " + dev
|
||
|
+ cmd = options["--sg_persist-path"] + " -n -o -I -S " + key + " -d " + dev
|
||
|
cmd += " -Z" if "--aptpl" in options else ""
|
||
|
return not bool(run_cmd(options, cmd)["rc"])
|
||
|
|