From dbec6de8c2db62b6ad853c1d9c7c7dcdbeec82d4 Mon Sep 17 00:00:00 2001 From: zouzhimin Date: Mon, 29 Apr 2024 17:25:31 +0800 Subject: [PATCH] fence_scsi: fix registration handling in device 'off' workflows --- fence-agents.spec | 6 +- ...ion-handling-in-device-off-workflows.patch | 106 ++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 fence_scsi-fix-registration-handling-in-device-off-workflows.patch diff --git a/fence-agents.spec b/fence-agents.spec index f4d6953..b63024f 100644 --- a/fence-agents.spec +++ b/fence-agents.spec @@ -6,13 +6,14 @@ Name: fence-agents Summary: Set of unified programs capable of host isolation ("fencing") Version: 4.12.1 -Release: 5 +Release: 6 License: GPLv2+ and LGPLv2+ Group: System Environment/Base URL: https://github.com/ClusterLabs/fence-agents Source0: https://github.com/ClusterLabs/fence-agents/archive//v%{version}/%{name}-%{version}.tar.gz Patch0: fence_ipmilan-fix-typo-in-description.patch Patch1: fence_scsi-fix-registration-handling-if-ISID-conflic.patch +Patch2: fence_scsi-fix-registration-handling-in-device-off-workflows.patch # skipped: pve, raritan, rcd-serial, virsh %global allfenceagents %(cat < - 4.12.1-6 +- fence_scsi: fix registration handling in device 'off' workflows + * Fri Apr 26 2024 zouzhimin - 4.12.1-5 - fence_scsi: fix registration handling if ISID conflict diff --git a/fence_scsi-fix-registration-handling-in-device-off-workflows.patch b/fence_scsi-fix-registration-handling-in-device-off-workflows.patch new file mode 100644 index 0000000..ee77c22 --- /dev/null +++ b/fence_scsi-fix-registration-handling-in-device-off-workflows.patch @@ -0,0 +1,106 @@ +From 34baef58db442148b8e067509d2cdd37b7a91ef4 Mon Sep 17 00:00:00 2001 +From: "sreejit.mohanan" +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 42530ceb..519319bf 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"]) + +-- +2.25.1 + -- Gitee