From 9d0d0d013c7edae43a4ebc5f46bf2e7a4f127654 Mon Sep 17 00:00:00 2001 From: "sreejit.mohanan" Date: Fri, 17 Feb 2023 18:04:03 -0800 Subject: [PATCH] fence_scsi: fix registration handling if ISID conflicts 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. fence_scsi treats same key as a tip to ignore issuing registration to the device but if the device was registered using a different ISID, the key would be the same but the I_T Nexus (new ISID) would not have access to the device. Fixing this by preempting the old key and replacing with the current one. --- agents/scsi/fence_scsi.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py index f9e6823b2..85e4f29e6 100644 --- a/agents/scsi/fence_scsi.py +++ b/agents/scsi/fence_scsi.py @@ -137,12 +137,41 @@ def register_dev(options, dev): for slave in get_mpath_slaves(dev): register_dev(options, slave) return True - if get_reservation_key(options, dev, False) == options["--key"]: - return True + + # Check if any registration exists for the key already. We track this in + # order to decide whether the existing registration needs to be cleared. + # 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): + registration_key_exists = True + if not register_helper(options, options["--key"], dev): + 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): + 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) + return True + +# cancel registration without aborting tasks +def preempt(options, host, dev): + reset_dev(options,dev) + cmd = options["--sg_persist-path"] + " -n -o -P -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev + return not bool(run_cmd(options, cmd)["rc"]) + +# helper function to send the register command +def register_helper(options, host, dev): reset_dev(options, dev) cmd = options["--sg_persist-path"] + " -n -o -I -S " + options["--key"] + " -d " + dev cmd += " -Z" if "--aptpl" in options else "" - #cmd return code != 0 but registration can be successful return not bool(run_cmd(options, cmd)["rc"])