diff options
author | mingzhe.zou@easystack.cn <mingzhe.zou@easystack.cn> | 2021-10-22 13:45:41 +0800 |
---|---|---|
committer | mingzhe.zou@easystack.cn <mingzhe.zou@easystack.cn> | 2021-10-22 14:02:05 +0800 |
commit | 963e4e9d5fbbda2f6bd4865e8f2e71d8253d8879 (patch) | |
tree | 70a65bbd1f64b4d86f719afe48cf2d4e088918b9 /scripts/targetcli | |
parent | 033cf1c2d34c73cce84c4c12c7383188167bf9e5 (diff) | |
download | targetcli-963e4e9d5fbbda2f6bd4865e8f2e71d8253d8879.tar.gz |
fix setting preference rollback error
Setting preference maybe rollback when execute multiple targetcli requests concurrently.
ConfigShell always initialization new Console object.
However, the lockfile need to be opened before requesting flock.
At this time, an exception may occur and need to be output to the console.
Currently, ConfigShell always initializes a new Console object.
So, ConfigShell is initialized first to be able to print information.
The prefs.bin file will be loaded when ConfigShell is initialized.
In this case, the old value may be read, if a new preference is being set and not saved.
In order to solve this problem we must first initialize a Console object.
This patch needs https://github.com/open-iscsi/configshell-fb/pull/62 to be merged first.
Signed-off-by: Zou Mingzhe <mingzhe.zou@easystack.cn>
Diffstat (limited to 'scripts/targetcli')
-rwxr-xr-x | scripts/targetcli | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/scripts/targetcli b/scripts/targetcli index f00bffc..490787e 100755 --- a/scripts/targetcli +++ b/scripts/targetcli @@ -23,7 +23,7 @@ from __future__ import print_function from os import getuid, getenv from targetcli import UIRoot from rtslib_fb import RTSLibError -from configshell_fb import ConfigShell, ExecutionError +from configshell_fb import Console, ConfigShell, ExecutionError from targetcli import __version__ as targetcli_version import sys @@ -88,30 +88,27 @@ def usage_version(cmd): if cmd in ("version", "--version", "-v"): version() -def try_op_lock(shell, lkfd): +def try_op_lock(console, lkfd): ''' acquire a blocking lock on lockfile, to serialize multiple requests ''' try: fcntl.flock(lkfd, fcntl.LOCK_EX) # wait here until ongoing request is finished except Exception as e: - shell.con.display( - shell.con.render_text( - "taking lock on lockfile failed: %s" %str(e), - 'red')) + text = "taking lock on lockfile failed: %s" %str(e) + console.display(console.render_text(text, 'red')) sys.exit(1) -def release_op_lock(shell, lkfd): +def release_op_lock(console, lkfd): ''' release blocking lock on lockfile, which can allow other requests process ''' try: fcntl.flock(lkfd, fcntl.LOCK_UN) # allow other requests now except Exception as e: - shell.con.display( - shell.con.render_text( - "unlock on lockfile failed: %s" %str(e), - 'red')) + text = "unlock on lockfile failed: %s" %str(e) + console.display(console.render_text(text, 'red')) + lkfd.close() sys.exit(1) lkfd.close() @@ -251,21 +248,23 @@ def main(): ''' Start the targetcli shell. ''' - shell = TargetCLI(getenv("TARGETCLI_HOME", '~/.targetcli')) + console = Console() is_root = False if getuid() == 0: is_root = True try: - lkfd = open(lock_file, 'w+'); + lkfd = open(lock_file, 'w+') except IOError as e: - shell.con.display( - shell.con.render_text("opening lockfile failed: %s" %str(e), - 'red')) + text = "opening lockfile failed: %s" %str(e) + console.display(console.render_text(text, 'red')) sys.exit(1) - try_op_lock(shell, lkfd) + try_op_lock(console, lkfd) + + targetcli_dir = getenv("TARGETCLI_HOME", '~/.targetcli') + shell = TargetCLI(targetcli_dir, console) use_daemon = False if shell.prefs['auto_use_daemon']: @@ -292,6 +291,7 @@ def main(): shell.con.display(shell.con.render_text(str(error), 'red')) if not is_root: shell.con.display(shell.con.render_text("Retry as root.", 'red')) + release_op_lock(console, lkfd) sys.exit(-1) if len(sys.argv) > 1: @@ -302,7 +302,9 @@ def main(): shell.run_cmdline(" ".join(sys.argv[1:])) except Exception as e: print(str(e), file=sys.stderr) + release_op_lock(console, lkfd) sys.exit(1) + release_op_lock(console, lkfd) sys.exit(0) shell.con.display("targetcli shell version %s\n" @@ -322,7 +324,7 @@ def main(): shell.log.info("Global pref auto_save_on_exit=true") root_node.ui_command_saveconfig() - release_op_lock(shell, lkfd) + release_op_lock(console, lkfd) if __name__ == "__main__": |