diff --git a/.gitignore b/.gitignore
index ba01e7f..4f66cec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/targetcli-fb-2.1.fb49.tar.gz
+SOURCES/targetcli-fb-2.1.51.tar.gz
diff --git a/.targetcli.metadata b/.targetcli.metadata
index 52a4911..2a071a5 100644
--- a/.targetcli.metadata
+++ b/.targetcli.metadata
@@ -1 +1 @@
-f55bb874f9644991a042ee83f25c14d44a86d2db SOURCES/targetcli-fb-2.1.fb49.tar.gz
+3e6f8caa6fc7a2591a97fd8b5c37554c71c1dd52 SOURCES/targetcli-fb-2.1.51.tar.gz
diff --git a/SOURCES/0001-setup.py-add-the-socket-and-service-files-to-the-dat.patch b/SOURCES/0001-setup.py-add-the-socket-and-service-files-to-the-dat.patch
new file mode 100644
index 0000000..1c784e1
--- /dev/null
+++ b/SOURCES/0001-setup.py-add-the-socket-and-service-files-to-the-dat.patch
@@ -0,0 +1,26 @@
+From 9c4be0387f7ae49a85db2ab3e31eb9d7834dded1 Mon Sep 17 00:00:00 2001
+From: Maurizio Lombardi <mlombard@redhat.com>
+Date: Thu, 21 Nov 2019 09:58:55 +0100
+Subject: [PATCH] setup.py: add the socket and service files to the data_files
+ section
+
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+---
+ setup.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/setup.py b/setup.py
+index 8dff55e..4518165 100755
+--- a/setup.py
++++ b/setup.py
+@@ -34,6 +34,7 @@ setup(
+                'scripts/targetcli',
+                'daemon/targetclid'
+               ],
++    data_files = [('/usr/lib/systemd/system', ['systemd/targetclid.socket', 'systemd/targetclid.service'])],
+     classifiers = [
+         "Programming Language :: Python",
+         "Programming Language :: Python :: 3",
+-- 
+2.21.0
+
diff --git a/SOURCES/0002-Use-StringIO-as-a-buffer-instead-of-a-file.patch b/SOURCES/0002-Use-StringIO-as-a-buffer-instead-of-a-file.patch
new file mode 100644
index 0000000..220bed8
--- /dev/null
+++ b/SOURCES/0002-Use-StringIO-as-a-buffer-instead-of-a-file.patch
@@ -0,0 +1,55 @@
+From 3db75315b7e436e57943efb132f7b331a7a7744c Mon Sep 17 00:00:00 2001
+From: Matt Coleman <matt@datto.com>
+Date: Thu, 7 Nov 2019 18:21:32 -0500
+Subject: [PATCH] Use StringIO as a buffer instead of a file
+
+---
+ daemon/targetclid | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/daemon/targetclid b/daemon/targetclid
+index fb472dc..dfc22ce 100755
+--- a/daemon/targetclid
++++ b/daemon/targetclid
+@@ -32,6 +32,7 @@ import struct
+ import fcntl
+ import signal
+ import errno
++import io
+ 
+ 
+ err = sys.stderr
+@@ -153,7 +154,7 @@ class TargetCLI:
+                 connection.close()
+                 still_listen = False
+             else:
+-                self.con._stdout = self.con._stderr = f = open("/tmp/data.txt", "w")
++                self.con._stdout = self.con._stderr = f = io.StringIO()
+                 try:
+                     # extract multiple commands delimited with '%'
+                     list_data = data.decode().split('%')
+@@ -165,14 +166,14 @@ class TargetCLI:
+                 # Restore
+                 self.con._stdout = self.con_stdout_
+                 self.con._stderr = self.con_stderr_
+-                f.close()
+ 
+-                with open('/tmp/data.txt', 'r') as f:
+-                    output = f.read()
+-                    var = struct.pack('i', len(output))
+-                    connection.sendall(var) # length of string
+-                    if len(output):
+-                        connection.sendall(output.encode()) # actual string
++                output = f.getvalue()
++                var = struct.pack('i', len(output))
++                connection.sendall(var) # length of string
++                if len(output):
++                    connection.sendall(output.encode()) # actual string
++
++                f.close()
+ 
+ 
+ def usage():
+-- 
+2.21.0
+
diff --git a/SOURCES/0003-Fix-targetclid-daemon-infinite-stuck.patch b/SOURCES/0003-Fix-targetclid-daemon-infinite-stuck.patch
new file mode 100644
index 0000000..49c5113
--- /dev/null
+++ b/SOURCES/0003-Fix-targetclid-daemon-infinite-stuck.patch
@@ -0,0 +1,29 @@
+From 5349bc9d1105c71158fce8dfd6a4733eb90dbb1a Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Mon, 30 Mar 2020 19:36:26 +0530
+Subject: [PATCH] Fix targetclid daemon infinite stuck
+
+We need to open a byte IO stream because we are actually dealing with
+binary data in memory.
+
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ daemon/targetclid | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/daemon/targetclid b/daemon/targetclid
+index dfc22ce..d4c6562 100755
+--- a/daemon/targetclid
++++ b/daemon/targetclid
+@@ -154,7 +154,7 @@ class TargetCLI:
+                 connection.close()
+                 still_listen = False
+             else:
+-                self.con._stdout = self.con._stderr = f = io.StringIO()
++                self.con._stdout = self.con._stderr = f = io.BytesIO()
+                 try:
+                     # extract multiple commands delimited with '%'
+                     list_data = data.decode().split('%')
+-- 
+2.21.0
+
diff --git a/SOURCES/0004-targetclid.sock-change-SocketMode-to-0600.patch b/SOURCES/0004-targetclid.sock-change-SocketMode-to-0600.patch
new file mode 100644
index 0000000..86c6be0
--- /dev/null
+++ b/SOURCES/0004-targetclid.sock-change-SocketMode-to-0600.patch
@@ -0,0 +1,33 @@
+From 6e4f39357a90a914d11bac21cc2d2b52c07c213d Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Thu, 26 Mar 2020 17:18:47 +0530
+Subject: [PATCH] targetclid.sock: change SocketMode to 0600
+
+SocketMode=
+If listening on a file system socket or FIFO, this option specifies the
+file system access mode used when creating the file node. Takes an
+access mode in octal notation. Defaults to 0666.
+
+Thanks Alex Murray[@alexmurray], for reporting.
+
+Fixes: #162
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ systemd/targetclid.socket | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/systemd/targetclid.socket b/systemd/targetclid.socket
+index 4730fce..ba29ebb 100644
+--- a/systemd/targetclid.socket
++++ b/systemd/targetclid.socket
+@@ -4,6 +4,7 @@ Documentation=man:targetclid(8)
+ 
+ [Socket]
+ ListenStream=/var/run/targetclid.sock
++SocketMode=0600
+ 
+ [Install]
+ WantedBy=sockets.target
+-- 
+2.21.0
+
diff --git a/SOURCES/0005-Fix-StringIO-BytesIO-stuck-issue.patch b/SOURCES/0005-Fix-StringIO-BytesIO-stuck-issue.patch
new file mode 100644
index 0000000..3c752af
--- /dev/null
+++ b/SOURCES/0005-Fix-StringIO-BytesIO-stuck-issue.patch
@@ -0,0 +1,113 @@
+From 0157f74a31adc1bd999ea5e5bc3a9c34af90b98c Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Thu, 2 Apr 2020 16:03:57 +0530
+Subject: [PATCH] Fix StringIO/BytesIO stuck issue
+
+We all know the way python3 handles strings is a bit different.
+
+$ python2
+Python 2.7.16 (default, Apr 30 2019, 15:54:43)
+[GCC 9.0.1 20190312 (Red Hat 9.0.1-0.10)] on linux2
+Type "help", "copyright", "credits" or "license" for more information.
+>>> import io
+>>> s=io.BytesIO()
+>>> s.write('hello')
+5L
+>>> s.getvalue()
+'hello'
+>>> s=io.StringIO()
+>>> s.write('hello')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in <module>
+TypeError: unicode argument expected, got 'str'
+>>> s.write(u'hello')
+5L
+>>> s.getvalue()
+u'hello'
+>>>
+
+$ python3
+Python 3.6.8 (default, Dec  5 2019, 15:45:45)
+[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
+Type "help", "copyright", "credits" or "license" for more information.
+>>> import io
+>>> s=io.BytesIO()
+>>> s.write('hello')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in <module>
+TypeError: a bytes-like object is required, not 'str'
+>>> s.write(b'hello')
+5
+>>> s.getvalue()
+b'hello'
+>>> s=io.StringIO()
+>>> s.write('hello')
+5
+>>> s.getvalue()
+'hello'
+>>>
+
+The way Python2 and Python3 handles String and Bytes IO is different.
+* In Python2 BytesIO() accepts text format syntax, and StringIO() expects unicodes
+* While in Python3 StringIO() accepts text format syntax, and BytesIO() expects bytes like objects
+
+I think the compatibility of using both the IO streams with python2 and python3 is compromised.
+
+Hence this patch, uses BytesIO() and StringIO() based on python version.
+
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ daemon/targetclid | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/daemon/targetclid b/daemon/targetclid
+index d4c6562..5df6ca2 100755
+--- a/daemon/targetclid
++++ b/daemon/targetclid
+@@ -32,9 +32,13 @@ import struct
+ import fcntl
+ import signal
+ import errno
+-import io
+ 
+ 
++if sys.version_info < (3, 0):
++    from io import BytesIO as StringIO
++else:
++    from io import StringIO
++
+ err = sys.stderr
+ 
+ class TargetCLI:
+@@ -154,24 +158,23 @@ class TargetCLI:
+                 connection.close()
+                 still_listen = False
+             else:
+-                self.con._stdout = self.con._stderr = f = io.BytesIO()
++                self.con._stdout = self.con._stderr = f = StringIO()
+                 try:
+                     # extract multiple commands delimited with '%'
+                     list_data = data.decode().split('%')
+                     for cmd in list_data:
+                         self.shell.run_cmdline(cmd)
+                 except Exception as e:
+-                    print(str(e), file=f) # push error to stream
++                    print(str(e).encode(), file=f) # push error to stream
+ 
+                 # Restore
+                 self.con._stdout = self.con_stdout_
+                 self.con._stderr = self.con_stderr_
+-
+-                output = f.getvalue()
++                output = f.getvalue().encode()
+                 var = struct.pack('i', len(output))
+                 connection.sendall(var) # length of string
+                 if len(output):
+-                    connection.sendall(output.encode()) # actual string
++                    connection.sendall(output) # actual string
+ 
+                 f.close()
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/0006-Use-temp-file-objects-for-temporary-storage-area.patch b/SOURCES/0006-Use-temp-file-objects-for-temporary-storage-area.patch
new file mode 100644
index 0000000..ed82c5b
--- /dev/null
+++ b/SOURCES/0006-Use-temp-file-objects-for-temporary-storage-area.patch
@@ -0,0 +1,112 @@
+From 4f6611ed208b6029b4523ca7760a802e82b6a199 Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Fri, 3 Apr 2020 20:06:48 +0530
+Subject: [PATCH] Use temp file objects for temporary storage area
+
+happen to see yet another issue after we switch to stringIO/bytesIO:
+
+$ targetcli ls
+'unicode' does not have the buffer interface
+
+After which I felt like dealing with StringIO/BytesIO is like a
+wild goose chase and we are after all attempting to deal with python
+incompatible apis.
+
+Technically speaking, the rtslib and configshell libraries are expecting a
+string IO stream, but then for python2 with ByteIO() we are passing a
+bytestream, and stringIO() is behaving a bit different in python2 than
+expected as explained in my previous patch.
+
+Lets simply switch to temporary file in the most secure manner possible,
+opening files in string mode will assure the compatibility across the platforms.
+
+At the end we wish to have a consistent behaviour across all python versions.
+
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ daemon/targetclid | 26 +++++++++++++-------------
+ scripts/targetcli |  3 ++-
+ 2 files changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/daemon/targetclid b/daemon/targetclid
+index 5df6ca2..329cede 100755
+--- a/daemon/targetclid
++++ b/daemon/targetclid
+@@ -26,19 +26,16 @@ from configshell_fb import ConfigShell
+ from os import getuid, getenv, unlink
+ from threading import Thread
+ 
++import os
+ import sys
+ import socket
+ import struct
+ import fcntl
+ import signal
+ import errno
++import tempfile
+ 
+ 
+-if sys.version_info < (3, 0):
+-    from io import BytesIO as StringIO
+-else:
+-    from io import StringIO
+-
+ err = sys.stderr
+ 
+ class TargetCLI:
+@@ -158,26 +155,29 @@ class TargetCLI:
+                 connection.close()
+                 still_listen = False
+             else:
+-                self.con._stdout = self.con._stderr = f = StringIO()
++                self.con._stdout = self.con._stderr = f = tempfile.NamedTemporaryFile(mode='w', delete=False)
+                 try:
+                     # extract multiple commands delimited with '%'
+                     list_data = data.decode().split('%')
+                     for cmd in list_data:
+                         self.shell.run_cmdline(cmd)
+                 except Exception as e:
+-                    print(str(e).encode(), file=f) # push error to stream
++                    print(str(e), file=f) # push error to stream
+ 
+                 # Restore
+                 self.con._stdout = self.con_stdout_
+                 self.con._stderr = self.con_stderr_
+-                output = f.getvalue().encode()
+-                var = struct.pack('i', len(output))
+-                connection.sendall(var) # length of string
+-                if len(output):
+-                    connection.sendall(output) # actual string
+-
+                 f.close()
+ 
++                with open(f.name, 'r') as f:
++                    output = f.read()
++                    var = struct.pack('i', len(output))
++                    connection.sendall(var) # length of string
++                    if len(output):
++                        connection.sendall(output.encode()) # actual string
++
++                os.unlink(f.name)
++
+ 
+ def usage():
+     print("Usage: %s [--version|--help]" % sys.argv[0], file=err)
+diff --git a/scripts/targetcli b/scripts/targetcli
+index 04e5aba..f11ece4 100755
+--- a/scripts/targetcli
++++ b/scripts/targetcli
+@@ -154,8 +154,9 @@ def call_daemon(shell, req):
+     # get the actual data in chunks
+     while amount_received < amount_expected:
+         data = sock.recv(1024)
++        data = data.decode()
+         amount_received += len(data)
+-        print(data.decode(), end ="")
++        print(data, end ="")
+ 
+     sock.send(b'-END@OF@DATA-')
+     sock.close()
+-- 
+2.21.0
+
diff --git a/SOURCES/0007-daemonized-mode-add-interactive-shell-support.patch b/SOURCES/0007-daemonized-mode-add-interactive-shell-support.patch
new file mode 100644
index 0000000..bab0c85
--- /dev/null
+++ b/SOURCES/0007-daemonized-mode-add-interactive-shell-support.patch
@@ -0,0 +1,202 @@
+From 15abdd481c5babd4128f3f0a9f0ac2f983bf1c89 Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Fri, 3 Apr 2020 13:01:06 +0530
+Subject: [PATCH 1/3] daemonized-mode: add interactive shell support
+
+set interactive mode as default to make it appear similar to cli approach,
+
+$ targetcli
+targetcli shell version 2.1.51
+Entering targetcli interactive mode for daemonized approach.
+Type 'exit' to quit.
+
+/> pwd
+/
+/> cd /iscsi
+/> pwd
+/iscsi
+/> exit
+
+Here we introduce a new global option daemon_use_batch_mode for switching between
+batch and interactive modes.
+
+$ targetcli set global daemon_use_batch_mode=true
+Parameter daemon_use_batch_mode is now 'true'.
+
+$ targetcli
+targetcli shell version 2.1.51
+Entering targetcli batch mode for daemonized approach.
+Enter multiple commands separated by newline and type 'exit' to run them
+all in one go.
+
+/> pwd
+/> cd /iscsi
+/> pwd
+/
+/iscsi
+
+Fixes: #160
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ scripts/targetcli    | 57 ++++++++++++++++++++++++++++----------------
+ targetcli/ui_node.py |  3 +++
+ targetclid.8         | 31 ++++++++++++++++++++++--
+ 3 files changed, 69 insertions(+), 22 deletions(-)
+
+diff --git a/scripts/targetcli b/scripts/targetcli
+index f11ece4..3496126 100755
+--- a/scripts/targetcli
++++ b/scripts/targetcli
+@@ -64,6 +64,7 @@ class TargetCLI(ConfigShell):
+                      'max_backup_files': '10',
+                      'auto_add_default_portal': True,
+                      'auto_use_daemon': False,
++                     'daemon_use_batch_mode': False,
+                     }
+ 
+ def usage():
+@@ -160,9 +161,8 @@ def call_daemon(shell, req):
+ 
+     sock.send(b'-END@OF@DATA-')
+     sock.close()
+-    sys.exit(0)
+ 
+-def get_arguments(shell):
++def switch_to_daemon(shell, interactive):
+     readline.set_completer(completer)
+     readline.set_completer_delims('')
+ 
+@@ -173,27 +173,40 @@ def get_arguments(shell):
+ 
+     if len(sys.argv) > 1:
+         command = " ".join(sys.argv[1:])
++        call_daemon(shell, command.encode())
++        sys.exit(0)
++
++    if interactive:
++        shell.con.display("targetcli shell version %s\n"
++                          "Entering targetcli interactive mode for daemonized approach.\n"
++                          "Type 'exit' to quit.\n"
++                          % targetcli_version)
+     else:
+-        inputs = []
+         shell.con.display("targetcli shell version %s\n"
+-                        "Entering targetcli batch mode for daemonized approach.\n"
+-                        "Enter multiple commands separated by newline and "
+-                        "type 'exit' to run them all in one go.\n"
+-                        % targetcli_version)
+-        while True:
+-            shell.con.raw_write("/> ")
+-            command = six.moves.input()
+-            if command.lower() == "exit":
+-                break
++                          "Entering targetcli batch mode for daemonized approach.\n"
++                          "Enter multiple commands separated by newline and "
++                          "type 'exit' to run them all in one go.\n"
++                          % targetcli_version)
++
++    inputs = []
++    real_exit=False
++    while True:
++        shell.con.raw_write("/> ")
++        command = six.moves.input()
++        if command.lower() == "exit":
++            real_exit=True
++        if not interactive:
+             inputs.append(command)
+-        command = '%'.join(inputs)  # delimit multiple commands with '%'
+-
+-    if not command:
+-        sys.exit(1)
+-
+-    usage_version(command);
++            if real_exit:
++                command = '%'.join(inputs)  # delimit multiple commands with '%'
++                call_daemon(shell, command.encode())
++                break
++        else:
++            if real_exit:
++                break
++            call_daemon(shell, command.encode())
+ 
+-    return command
++    sys.exit(0)
+ 
+ def main():
+     '''
+@@ -225,8 +238,12 @@ def main():
+         if sys.argv[1] in ("disable-daemon", "--disable-daemon"):
+             disable_daemon=True
+ 
++    interactive_mode = True
++    if shell.prefs['daemon_use_batch_mode']:
++        interactive_mode = False
++
+     if use_daemon and not disable_daemon:
+-        call_daemon(shell, get_arguments(shell).encode())
++        switch_to_daemon(shell, interactive_mode)
+         # does not return
+ 
+     try:
+diff --git a/targetcli/ui_node.py b/targetcli/ui_node.py
+index 58a70c6..0485950 100644
+--- a/targetcli/ui_node.py
++++ b/targetcli/ui_node.py
+@@ -52,6 +52,9 @@ class UINode(ConfigNode):
+         self.define_config_group_param(
+             'global', 'auto_use_daemon', 'bool',
+             'If true, commands will be sent to targetclid.')
++        self.define_config_group_param(
++            'global', 'daemon_use_batch_mode', 'bool',
++            'If true, use batch mode for daemonized approach.')
+ 
+     def assert_root(self):
+         '''
+diff --git a/targetclid.8 b/targetclid.8
+index a783091..5760168 100644
+--- a/targetclid.8
++++ b/targetclid.8
+@@ -30,11 +30,38 @@ $ targetcli set global auto_use_daemon=true
+ .br
+ $ targetcli ls
+ .TP
+-You can use batch mode for sending multiple commands in one go,
++You can use interactive mode,
+ .br
+ $ targetcli <hit-enter>
+ .br
+-targetcli shell version 2.1.50
++targetcli shell version 2.1.51
++.br
++Entering targetcli interactive mode for daemonized approach.
++.br
++Type 'exit' to quit.
++.br
++/> pwd
++.br
++/
++.br
++/> cd /iscsi
++.br
++/> pwd
++.br
++/iscsi
++.br
++/> exit
++.br
++.TP
++You can also use batch mode for sending multiple commands in one go,
++.br
++$ targetcli set global daemon_use_batch_mode=true
++.br
++Parameter daemon_use_batch_mode is now 'true'.
++.br
++$ targetcli <hit-enter>
++.br
++targetcli shell version 2.1.51
+ .br
+ Entering targetcli batch mode for daemonized approach.
+ .br
+-- 
+2.21.0
+
diff --git a/SOURCES/0008-daemonized-mode-fix-issues-noticed-with-curser-posit.patch b/SOURCES/0008-daemonized-mode-fix-issues-noticed-with-curser-posit.patch
new file mode 100644
index 0000000..a5e035c
--- /dev/null
+++ b/SOURCES/0008-daemonized-mode-fix-issues-noticed-with-curser-posit.patch
@@ -0,0 +1,35 @@
+From 3cfd45bb22cdcb1512228c3f8101a1e3f74af3ee Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Mon, 6 Apr 2020 16:05:56 +0530
+Subject: [PATCH 2/3] daemonized-mode: fix issues noticed with curser position
+
+* get/set x and y postions of the curser dynamically
+* skip accepting command if no command is provided
+  eg: just hit enter with no command
+
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ scripts/targetcli | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/scripts/targetcli b/scripts/targetcli
+index 3496126..97f41eb 100755
+--- a/scripts/targetcli
++++ b/scripts/targetcli
+@@ -192,9 +192,13 @@ def switch_to_daemon(shell, interactive):
+     real_exit=False
+     while True:
+         shell.con.raw_write("/> ")
++        pos = shell.con.get_cursor_xy()
++        shell.con.set_cursor_xy(pos[0], pos[1])
+         command = six.moves.input()
+         if command.lower() == "exit":
+             real_exit=True
++        elif not command:
++            continue
+         if not interactive:
+             inputs.append(command)
+             if real_exit:
+-- 
+2.21.0
+
diff --git a/SOURCES/0009-daemon-interactive-show-path-on-prompt.patch b/SOURCES/0009-daemon-interactive-show-path-on-prompt.patch
new file mode 100644
index 0000000..3db9b39
--- /dev/null
+++ b/SOURCES/0009-daemon-interactive-show-path-on-prompt.patch
@@ -0,0 +1,140 @@
+From 853bbc4f85427206bb27e5d63727d8b9fbe10972 Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+Date: Mon, 6 Apr 2020 19:33:20 +0530
+Subject: [PATCH 3/3] daemon-interactive: show path on prompt
+
+$ targetcli
+targetcli shell version 2.1.51
+Entering targetcli interactive mode for daemonized approach.
+Type 'exit' to quit.
+
+/> pwd
+/
+/> cd /iscsi
+/iscsi> ls
+o- iscsi .......................................... [Targets: 0]
+/iscsi> exit
+
+Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+---
+ scripts/targetcli | 52 ++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 45 insertions(+), 7 deletions(-)
+
+diff --git a/scripts/targetcli b/scripts/targetcli
+index 97f41eb..e1ec178 100755
+--- a/scripts/targetcli
++++ b/scripts/targetcli
+@@ -122,7 +122,7 @@ def completer(text, state):
+     except IndexError:
+         return None
+ 
+-def call_daemon(shell, req):
++def call_daemon(shell, req, interactive):
+     try:
+         sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+     except socket.error as err:
+@@ -140,9 +140,23 @@ def call_daemon(shell, req):
+                 "then run '#targetcli --disable-daemon'", 'red'))
+         sys.exit(1)
+ 
++    # Two cases where we want to get pwd:
++    # 1. Before starting shell in interactive mode, needed for setting terminal
++    # 2. And only in Interactive mode, having command 'cd'
++    get_pwd = False
++    if interactive:
++        if not req:
++            req = "pwd"
++            get_pwd = True
++        elif "cd " in req:
++            req += "%pwd"
++            get_pwd = True
++    else:
++        req = "cd /%" + req # Non-interactive modes always consider start at '/'
++
+     try:
+         # send request
+-        sock.sendall(req)
++        sock.sendall(req.encode())
+     except socket.error as err:
+         shell.con.display(shell.con.render_text(err, 'red'))
+         sys.exit(1)
+@@ -153,15 +167,30 @@ def call_daemon(shell, req):
+     amount_received = 0
+ 
+     # get the actual data in chunks
++    output = ""
++    path = ""
+     while amount_received < amount_expected:
+         data = sock.recv(1024)
+         data = data.decode()
+         amount_received += len(data)
+-        print(data, end ="")
++        output += data
++
++    if get_pwd:
++        output_split = output.splitlines()
++        lines = len(output_split)
++        for i in range(0, lines):
++            if i == lines-1:
++                path = str(output_split[i])
++            else:
++                print(str(output_split[i]), end ="\n")
++    else:
++        print(output, end ="")
+ 
+     sock.send(b'-END@OF@DATA-')
+     sock.close()
+ 
++    return path
++
+ def switch_to_daemon(shell, interactive):
+     readline.set_completer(completer)
+     readline.set_completer_delims('')
+@@ -173,7 +202,7 @@ def switch_to_daemon(shell, interactive):
+ 
+     if len(sys.argv) > 1:
+         command = " ".join(sys.argv[1:])
+-        call_daemon(shell, command.encode())
++        call_daemon(shell, command, False)
+         sys.exit(0)
+ 
+     if interactive:
+@@ -188,10 +217,14 @@ def switch_to_daemon(shell, interactive):
+                           "type 'exit' to run them all in one go.\n"
+                           % targetcli_version)
+ 
++    prompt_path = "/"
++    if interactive:
++        prompt_path = call_daemon(shell, None, interactive) # get the initial path
++
+     inputs = []
+     real_exit=False
+     while True:
+-        shell.con.raw_write("/> ")
++        shell.con.raw_write("%s> " %prompt_path)
+         pos = shell.con.get_cursor_xy()
+         shell.con.set_cursor_xy(pos[0], pos[1])
+         command = six.moves.input()
+@@ -203,12 +236,17 @@ def switch_to_daemon(shell, interactive):
+             inputs.append(command)
+             if real_exit:
+                 command = '%'.join(inputs)  # delimit multiple commands with '%'
+-                call_daemon(shell, command.encode())
++                call_daemon(shell, command, interactive)
+                 break
+         else:
+             if real_exit:
+                 break
+-            call_daemon(shell, command.encode())
++            path = call_daemon(shell, command, interactive)
++            if path:
++                if path[0] == "/":
++                    prompt_path = path
++                else:
++                    print(path)  # Error No Path ...
+ 
+     sys.exit(0)
+ 
+-- 
+2.21.0
+
diff --git a/SPECS/targetcli.spec b/SPECS/targetcli.spec
index 932dcb2..24f179f 100644
--- a/SPECS/targetcli.spec
+++ b/SPECS/targetcli.spec
@@ -4,10 +4,19 @@ Name:           targetcli
 License:        ASL 2.0
 Group:          System Environment/Libraries
 Summary:        An administration shell for storage targets
-Version:        2.1.fb49
-Release:        1%{?dist}
-URL:            https://fedorahosted.org/targetcli-fb/
-Source:         https://fedorahosted.org/released/targetcli-fb/%{oname}-%{version}.tar.gz
+Version:        2.1.51
+Release:        2%{?dist}
+URL:            https://github.com/open-iscsi/%{oname}
+Source:         %{url}/archive/v%{version}/%{oname}-%{version}.tar.gz
+Patch0:         0001-setup.py-add-the-socket-and-service-files-to-the-dat.patch
+Patch1:         0002-Use-StringIO-as-a-buffer-instead-of-a-file.patch
+Patch2:         0003-Fix-targetclid-daemon-infinite-stuck.patch
+Patch3:         0004-targetclid.sock-change-SocketMode-to-0600.patch
+Patch4:         0005-Fix-StringIO-BytesIO-stuck-issue.patch
+Patch5:         0006-Use-temp-file-objects-for-temporary-storage-area.patch
+Patch6:         0007-daemonized-mode-add-interactive-shell-support.patch
+Patch7:         0008-daemonized-mode-fix-issues-noticed-with-curser-posit.patch
+Patch8:         0009-daemon-interactive-show-path-on-prompt.patch
 BuildArch:      noarch
 BuildRequires:  python-devel python-setuptools
 Requires:       python-rtslib >= 2.1.fb41, python-configshell, python-ethtool
@@ -21,26 +30,56 @@ users will also need to install and use fcoe-utils.
 
 %prep
 %setup -q -n %{oname}-%{version}
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
 
 %build
 %{__python} setup.py build
 gzip --stdout targetcli.8 > targetcli.8.gz
+gzip --stdout targetclid.8 > targetclid.8.gz
 
 %install
 %{__python} setup.py install --skip-build --root %{buildroot}
 mkdir -p %{buildroot}%{_sysconfdir}/target/backup
+mkdir -p %{buildroot}%{_sysconfdir}/target/pr
 mkdir -p %{buildroot}%{_mandir}/man8/
 install -m 644 targetcli.8.gz %{buildroot}%{_mandir}/man8/
+install -m 644 targetclid.8.gz %{buildroot}%{_mandir}/man8/
 
 %files
 %{python_sitelib}/*
 %{_bindir}/targetcli
+%{_bindir}/targetclid
 %dir %{_sysconfdir}/target
 %dir %{_sysconfdir}/target/backup
+%dir %{_sysconfdir}/target/pr
 %doc COPYING README.md
 %{_mandir}/man8/targetcli.8.gz
+%{_mandir}/man8/targetclid.8.gz
+%{_usr}/lib/systemd/system/targetclid.service
+%{_usr}/lib/systemd/system/targetclid.socket
+
 
 %changelog
+* Mon Apr 06 2020 Maurizio Lombardi <mlombard@redhat.com> - 2.1.51-2
+- Add the interactive daemon console.
+
+* Fri Apr 03 2020 Maurizio Lombardi <mlombard@redhat.com> - 2.1.fb51-1
+- Update to a new upstream version
+
+* Wed Mar 25 2020 Maurizio Lombardi <mlombard@redhat.com> - 2.1.fb49-3
+- Respin a new release of targetcli.
+
+* Mon Sep 09 2019 Maurizio Lombardi <mlombard@redhat.com> - 2.1.fb49-2
+- Get a lock to avoid the issues with concurrent backstore creation
+
 * Tue Jan 29 2019 Maurizio Lombardi <mlombard@redhat.com> - 2.1.fb49-1
 - Rebase to latest upstream version