diff --git a/base/Dockerfile b/base/Dockerfile
index 9c30986538f2149a52f0e257607b5ee8fcfc1dd6..48a3736f5363d7041489fc8c4b88604a5a198ba2 100644
--- a/base/Dockerfile
+++ b/base/Dockerfile
@@ -7,6 +7,16 @@
 # Use CentOS 7 as base image
 FROM centos:7 
 
+# Copy the repository file to the container
+COPY vault.repo /root/vault.repo
+
+# Update the system and install basic utilities
+RUN yum-config-manager --disable base && \
+    yum-config-manager --disable updates && \
+    yum-config-manager --disable extras && \
+    cat /root/vault.repo >> /etc/yum.repos.d/Centos-Vault.repo && \
+    yum clean all && yum makecache
+
 # Install epel repo
 RUN yum update -y && yum -y install epel-release
 
diff --git a/base/vault.repo b/base/vault.repo
new file mode 100644
index 0000000000000000000000000000000000000000..5c1d6910bd6eaf195c6010757dff56cac06bfc79
--- /dev/null
+++ b/base/vault.repo
@@ -0,0 +1,15 @@
+[Vault-base]
+name=Vault - CentOS-$releasever Base
+baseurl=http://vault.centos.org/centos/$releasever/os/$basearch/
+gpgcheck=0
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
+[Vault-updates]
+name=Vault - CentOS-$releasever Updates
+baseurl=http://vault.centos.org/centos/$releasever/updates/$basearch/
+gpgcheck=0
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
+[Vault-extras]
+name=Vault - CentOS-$releasever Extras
+baseurl=http://vault.centos.org/centos/$releasever/extras/$basearch/
+gpgcheck=0
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
diff --git a/client/vos_storage b/client/vos_storage
index 5f1e31e070176484c6b15f3b416d2f3e97f3b99c..9d43221d9ef649daa02b3fa8967e565ff1120d88 100644
--- a/client/vos_storage
+++ b/client/vos_storage
@@ -28,8 +28,8 @@ class VOSStorage(RedisRPCClient):
         storageType = None
         storageBasePath = None
         storageHostname = None
-        tapePool = None
-        tapePoolList = []
+        tapeHSMFilesystem = None
+        tapeHSMFilesystemList = []
         while storageType not in ("cold", "hot"):
             try:
                 storageType = input("\nStorage type ['cold' or 'hot']: ")
@@ -40,17 +40,17 @@ class VOSStorage(RedisRPCClient):
             except KeyboardInterrupt:
                 sys.exit("\nCTRL+C detected. Exiting...")
         if storageType == "cold":
-            storageRequest = { "requestType": "TAPE_POOL_LST" }
+            storageRequest = { "requestType": "TAPE_HSM_FS_LST" }
             storageResponse = self.call(storageRequest)
             if "responseType" not in storageResponse:
                 sys.exit("FATAL: Malformed response, storage acknowledge expected.\n")
-            elif storageResponse["responseType"] == "TAPE_POOL_LST_DONE":
-                tapePoolList = storageResponse["tapePoolList"]
-                while tapePool not in tapePoolList:
-                    print("\nSelect one of the available tape pools:")
-                    print("\n" + tabulate([ [t] for t in tapePoolList ], headers = ["tape_pool"], tablefmt = "pretty") + "\n")
+            elif storageResponse["responseType"] == "TAPE_HSM_FS_LST_DONE":
+                tapeHSMFilesystemList = storageResponse["tapeHSMFilesystemList"]
+                while tapeHSMFilesystem not in tapeHSMFilesystemList:
+                    print("\nSelect one of the available tape HSM filesystems:")
+                    print("\n" + tabulate([ [t] for t in tapeHSMFilesystemList ], headers = ["tape_hsm_fs"], tablefmt = "pretty") + "\n")
                     try:
-                       tapePool = input("Please, insert a tape pool: ")
+                       tapeHSMFilesystem = input("Please, insert a tape HSM filesystem: ")
                     except ValueError:
                         print("Input type is not valid!")
                     except EOFError:
@@ -81,7 +81,7 @@ class VOSStorage(RedisRPCClient):
                            "storageType": storageType,
                            "basePath": storageBasePath,
                            "hostname": storageHostname,
-                           "tapePool": tapePool }
+                           "tapeHSMFilesystem": tapeHSMFilesystem }
         storageResponse = self.call(storageRequest)
 
         if "responseType" not in storageResponse:
@@ -202,8 +202,8 @@ DESCRIPTION
        Adding 'hot' or 'cold' storage points requires a base path
        to be specified (e.g. '/mnt/my_storage/users').
 
-       Adding a 'cold' storage point requires selecting a tape pool
-       (a tape pool list is provided).
+       Adding a 'cold' storage point requires selecting a tape HSM
+       filesystem (a tape HSM filesystem list is provided).
 
        All storage points require a valid hostname or IP address.
     """)
diff --git a/transfer_service/config/vos_ts.conf.sample b/transfer_service/config/vos_ts.conf.sample
index 6f9adf43c522a23c79a4268c0b028a2e528c83ae..14e6c4e432d5ab4132c963c9d39cfe5c57f0e615 100644
--- a/transfer_service/config/vos_ts.conf.sample
+++ b/transfer_service/config/vos_ts.conf.sample
@@ -30,8 +30,8 @@ port = 6379
 ; db index representing the db that stores the scheduling queues, default is 0
 db_sched = 0
 
-# Spectrum Archive
-[spectrum_archive]
+# IBM Spectrum Protect
+[spectrum_protect]
 ; hostname or IP address of the tape library frontend
 host = <tape_frontend_hostname>
 ; SSH port
diff --git a/transfer_service/db_connector.py b/transfer_service/db_connector.py
index 179dfcfd25ff3a62497a3adb8387156632bc7b0e..15a82bc7d938d0232fecf5bf3a257a3140e86c0f 100644
--- a/transfer_service/db_connector.py
+++ b/transfer_service/db_connector.py
@@ -171,7 +171,7 @@ class DbConnector(object):
             conn = self.getConnection()
             cursor = conn.cursor(cursor_factory = RealDictCursor)
             cursor.execute("""
-                SELECT storage_type, base_path, user_name, tstamp_wrapper_dir, '/' || fs_path AS os_path, content_length, tape_pool
+                SELECT storage_type, base_path, user_name, tstamp_wrapper_dir, '/' || fs_path AS os_path, content_length, tape_hsm_fs
                 FROM node n
                 JOIN location l ON n.location_id = l.location_id
                 JOIN storage s ON s.storage_id = l.storage_src_id
@@ -192,7 +192,7 @@ class DbConnector(object):
             tstampWrappedDir = result[0]["tstamp_wrapper_dir"]
             osPath = result[0]["os_path"]
             contentLength = result[0]["content_length"]
-            tapePool = result[0]["tape_pool"]
+            tapeHSMFilesystem = result[0]["tape_hsm_fs"]
             if tstampWrappedDir is None:
                 baseSrcPath = basePath + "/" + userName
             else:
@@ -205,7 +205,7 @@ class DbConnector(object):
                             "username": userName,
                             "osPath": osPath,
                             "contentLength": contentLength,
-                            "tapePool": tapePool
+                            "tapeHSMFilesystem": tapeHSMFilesystem
                        }
             return fileInfo
         finally:
@@ -824,12 +824,12 @@ class DbConnector(object):
         finally:
             self.connPool.putconn(conn, close = False)
 
-    def getTapePool(self, storageId):
-        """Returns the tape pool for a given storage id, if the storage is cold. Otherwise it returns 'False'."""
+    def getTapeHSMFilesystem(self, storageId):
+        """Returns the tape HSM filesystem for a given storage id, if the storage is cold. Otherwise it returns 'False'."""
         try:
             conn = self.getConnection()
             cursor = conn.cursor(cursor_factory = RealDictCursor)
-            cursor.execute("SELECT tape_pool FROM storage WHERE storage_id = %s;", (storageId,))
+            cursor.execute("SELECT tape_hsm_fs FROM storage WHERE storage_id = %s;", (storageId,))
             result = cursor.fetchall()
             cursor.close()
         except Exception:
@@ -838,7 +838,7 @@ class DbConnector(object):
             raise
         else:
             if result:
-                return result[0]["tape_pool"]
+                return result[0]["tape_hsm_fs"]
             else:
                 return False
         finally:
@@ -1250,7 +1250,7 @@ class DbConnector(object):
 
     ##### Storage #####
 
-    def insertStorage(self, storageType, storageBasePath, storageHostname, vospaceUserBasePath, tapePool = None):
+    def insertStorage(self, storageType, storageBasePath, storageHostname, vospaceUserBasePath, tapeHSMFilesystem = None):
         """Inserts a storage point."""
         if not self.getStorageId(storageBasePath):
             try:
@@ -1260,14 +1260,14 @@ class DbConnector(object):
                     INSERT INTO storage(storage_type,
                                         base_path,
                                         hostname,
-                                        tape_pool)
+                                        tape_hsm_fs)
                     VALUES (%s, %s, %s, %s)
                     RETURNING storage_id;
                     """,
                     (storageType,
                      storageBasePath,
                      storageHostname,
-                     tapePool,))
+                     tapeHSMFilesystem,))
                 storageSrcId = cursor.fetchall()[0]["storage_id"]
             except Exception:
                 if not conn.closed:
diff --git a/transfer_service/doi_executor.py b/transfer_service/doi_executor.py
index 14a999461e365117d302479f1170374765415a96..8d3ea79859c71ca5ef007c2a7e8843101a725d1c 100644
--- a/transfer_service/doi_executor.py
+++ b/transfer_service/doi_executor.py
@@ -71,7 +71,7 @@ class DOIExecutor(TaskExecutor):
                                   1,
                                   1,
                                   self.logger)
-        params = config.loadSection("spectrum_archive")
+        params = config.loadSection("spectrum_protect")
         #self.tapePool = params["tape_pool"]
         self.tapeClient = TapeClient(params["host"],
                                      params.getint("port"),
diff --git a/transfer_service/import_executor.py b/transfer_service/import_executor.py
index 6deb10c47593756bf0dcc4b010eb61e7d1146458..ed9c43008b02a29395aa849a4c79b7bcd4f5da7a 100644
--- a/transfer_service/import_executor.py
+++ b/transfer_service/import_executor.py
@@ -50,7 +50,7 @@ class ImportExecutor(TaskExecutor):
                                   1,
                                   1,
                                   self.logger)
-        params = config.loadSection("spectrum_archive")
+        params = config.loadSection("spectrum_protect")
         self.tapeClient = TapeClient(params["host"],
                                      params.getint("port"),
                                      params["user"],
diff --git a/transfer_service/retrieve_executor.py b/transfer_service/retrieve_executor.py
index 0b5378a42fd9eef374280e034df51ac9bd19c2b7..0eac4ea6608d5c33cf729574c87bf4bcec488429 100644
--- a/transfer_service/retrieve_executor.py
+++ b/transfer_service/retrieve_executor.py
@@ -75,13 +75,13 @@ class RetrieveExecutor(TaskExecutor):
                                   1,
                                   1,
                                   self.logger)
-        params = config.loadSection("spectrum_archive")
+        params = config.loadSection("spectrum_protect")
         self.tapeClient = TapeClient(params["host"],
                                      params.getint("port"),
                                      params["user"],
                                      params["pkey_file_path"],
                                      self.logger)
-        self.tapePool = None
+        self.tapeHSMFilesystem = None
         self.storageType = None
         self.jobObj = None
         self.jobId = None
@@ -125,7 +125,7 @@ class RetrieveExecutor(TaskExecutor):
                 #self.storageType = self.dbConn.getOSPath(self.nodeList[0])["storageType"]
                 fileInfo = self.dbConn.getOSPath(self.nodeList[0])
                 self.storageType = fileInfo["storageType"]
-                self.tapePool = fileInfo["tapePool"]
+                self.tapeHSMFilesystem = fileInfo["tapeHSMFilesystem"]
             except Exception:
                 self.logger.exception("FATAL: unable to obtain the storage type.")
                 return False
@@ -321,7 +321,7 @@ class RetrieveExecutor(TaskExecutor):
                 # is 'cold'
                 if self.storageType == "cold":
                     self.tapeClient.connect()
-                    self.tapeClient.migrate([ f["fullPath"] for f in blockFileList if f["fileSize"] > 0 ], self.tapePool, self.jobId)
+                    self.tapeClient.migrate([ f["fullPath"] for f in blockFileList if f["fileSize"] > 0 ], self.tapeHSMFilesystem, self.jobId)
                     self.tapeClient.disconnect()
 
                 blockFileList.clear()
diff --git a/transfer_service/storage_rpc_server.py b/transfer_service/storage_rpc_server.py
index d04b9eedadb7c73ed294607da9afb7df65961902..6ee804a90c68cefbd1c063225a8febdc5016429e 100644
--- a/transfer_service/storage_rpc_server.py
+++ b/transfer_service/storage_rpc_server.py
@@ -40,7 +40,7 @@ class StorageRPCServer(RedisRPCServer):
                                   1,
                                   2,
                                   self.logger)
-        params = config.loadSection("spectrum_archive")
+        params = config.loadSection("spectrum_protect")
         self.tapeClient = TapeClient(params["host"],
                                      params.getint("port"),
                                      params["user"],
@@ -135,21 +135,20 @@ class StorageRPCServer(RedisRPCServer):
             else:
                 response = { "responseType": "STORAGE_LST_DONE",
                              "storageList": result }
-        elif requestBody["requestType"] == "TAPE_POOL_LST":
+        elif requestBody["requestType"] == "TAPE_HSM_FS_LST":
             try:
                 self.tapeClient.connect()
-                tapePools = self.tapeClient.getPoolList()
+                tapeHSMFilesystemList = self.tapeClient.getHSMFilesystemList()
                 self.tapeClient.disconnect()
-                tapePoolList = [ p.getName() for p in tapePools ]
             except Exception:
-                errorMsg = "Unable to get tape pool list."
+                errorMsg = "Unable to get tape HSM filesystem list."
                 self.logger.exception(errorMsg)
                 response = { "responseType": "ERROR",
                              "errorCode": 6,
                              "errorMsg": errorMsg }
             else:
-                response = { "responseType": "TAPE_POOL_LST_DONE",
-                             "tapePoolList": tapePoolList }
+                response = { "responseType": "TAPE_HSM_FS_LST_DONE",
+                             "tapeHSMFilesystemList": tapeHSMFilesystemList }
         else:
             errorMsg = "Unkown request type."
             self.logger.error(errorMsg)
diff --git a/transfer_service/store_executor.py b/transfer_service/store_executor.py
index 1767e24ebc557c6345b089a3cf2c0a3d9cf1f322..4f7aac290329ebb29679799a88927e83f0fd3015 100644
--- a/transfer_service/store_executor.py
+++ b/transfer_service/store_executor.py
@@ -24,7 +24,7 @@ from task_executor import TaskExecutor
 
 
 class StoreExecutor(TaskExecutor):
-    
+
     # We use 10 GB of tolerance when we calculate
     # the free space in our storage point
     TOL = 10 * (2**30)
@@ -32,7 +32,7 @@ class StoreExecutor(TaskExecutor):
     def __init__(self):
         self.type = "store_executor"
         self.systemUtils = SystemUtils()
-        config = Config("/etc/vos_ts/vos_ts.conf")        
+        config = Config("/etc/vos_ts/vos_ts.conf")
         params = config.loadSection("transfer_node")
         self.storageStorePath = params["store_path"]
         params = config.loadSection("transfer")
@@ -60,7 +60,7 @@ class StoreExecutor(TaskExecutor):
                                   1,
                                   1,
                                   self.logger)
-        params = config.loadSection("spectrum_archive")
+        params = config.loadSection("spectrum_protect")
         self.tapeClient = TapeClient(params["host"],
                                      params.getint("port"),
                                      params["user"],
@@ -104,18 +104,15 @@ class StoreExecutor(TaskExecutor):
                 storageFreeSpace = free - self.TOL
                 self.logger.debug(f"storageFreeSpace (hot): {storageFreeSpace} B")
             else:
-                self.tapeClient.connect()
-                tapePoolList = self.tapeClient.getPoolList()
-                self.tapeClient.disconnect()
                 try:
-                    self.tapePool = self.dbConn.getTapePool(self.storageId)
+                    self.tapeHSMFilesystem = self.dbConn.getTapeHSMFilesystem(self.storageId)
                 except Exception:
-                    self.logger.exception("FATAL: unable to obtain the tape pool.")
+                    self.logger.exception("FATAL: unable to obtain the tape HSM filesystem.")
                     return False
                 else:
-                    for el in tapePoolList:
-                        if el.getName() == self.tapePool:
-                            storageFreeSpace = el.getFreeSpace() - self.TOL
+                    self.tapeClient.connect()
+                    storageFreeSpace = self.tapeClient.getHSMFilesystemFreeSpace(self.tapeHSMFilesystem) - self.TOL
+                    self.tapeClient.disconnect()
                     self.logger.debug(f"storageFreeSpace (cold): {storageFreeSpace} B")
             if storageFreeSpace < self.dataSize:
                 self.logger.error("FATAL: space available on the storage point is not enough.")
diff --git a/transfer_service/tape_client.py b/transfer_service/tape_client.py
index 2c46e75cb29e2cb60749a4dd2357be4f032a3c2c..37f0dec7043f980004087de7a50b1010413e4370 100644
--- a/transfer_service/tape_client.py
+++ b/transfer_service/tape_client.py
@@ -16,13 +16,19 @@ from config import Config
 from exceptions import ScpInvalidFileException
 from exceptions import TapeClientException
 from redis_log_handler import RedisLogHandler
-from tape_pool import TapePool
-from tape_task import TapeTask
+from system_utils import SystemUtils
 
 
 class TapeClient(object):
-    # 'eeadm' command location on the tape library frontend
-    EEADM = "/opt/ibm/ltfsee/bin/eeadm"
+    # 'dsmdf' command location on the tape library frontend
+    DSMDF = "/usr/bin/dsmdf"
+
+    # 'dsmrecall' command location on the tape library frontend
+    DSMRECALL = "/usr/bin/dsmrecall"
+
+    # 'dsmmigrate' command location on the tape library frontend
+    DSMMIGRATE = "/usr/bin/dsmmigrate"
+
     # destination for the files containing the lists of files to recall or migrate
     VOSPACE_WD = "/tmp/vospace"
 
@@ -35,8 +41,8 @@ class TapeClient(object):
         self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         self.keyFile = keyFile
         self.scp = None
-        self.taskList = []
-        self.poolList = []
+        self.systemUtils = SystemUtils()
+        self.HSMFilesystemList = []
 
     def connect(self):
         """Connects to the tape library frontend."""
@@ -51,51 +57,28 @@ class TapeClient(object):
             self.logger.exception("Unable to establish SSH connection with tape library frontend.")
             raise
 
-    def getPoolList(self):
-        """Returns a list of 'TapePool' objects."""
-        cmd = f"{self.EEADM} pool list --json"
+    def copy(self, srcPath, destPath):
+        """Copies files/dirs recursively by passing their absolute paths."""
         try:
-            stdin, stdout, stderr = self.client.exec_command(cmd)
+            self.scp = scp.SCPClient(self.client.get_transport())
         except Exception:
-            self.logger.exception(f"Unable to execute command: '{cmd}'")
+            self.logger.error("Unable to get transport from SSH client.")
             raise
         else:
-            exitCode = stdout.channel.recv_exit_status()
-            if not exitCode:
-                result = json.loads(stdout.readlines()[0].rstrip('\n'))
-                for el in result["payload"]:
-                    pool = TapePool()
-                    pool.id = el["id"]
-                    pool.name = el["name"]
-                    pool.mediaRestriction = el["media_restriction"]
-                    pool.capacity = el["capacity"]
-                    pool.usedSpace = el["used_space"]
-                    pool.freeSpace = el["free_space"]
-                    pool.reclaimableSpace = el["reclaimable_space"]
-                    pool.activeSpace = el["active_space"]
-                    pool.nonAppendableSpace = el["non_appendable_space"]
-                    pool.numOfTapes = el["num_of_tapes"]
-                    pool.formatClass = el["format_class"]
-                    pool.libraryName = el["library_name"]
-                    pool.libraryId = el["library_id"]
-                    pool.nodeGroupName = el["nodegroup_name"]
-                    pool.deviceType = el["device_type"]
-                    pool.worm = el["worm"]
-                    pool.fillPolicy = el["fill_policy"]
-                    pool.owner = el["owner"]
-                    pool.mountLimit = el["mount_limit"]
-                    pool.lowSpaceWarningEnable = el["low_space_warning_enable"]
-                    pool.lowSpaceWarningThreshold = el["low_space_warning_threshold"]
-                    pool.noSpaceWarningEnable = el["no_space_warning_enable"]
-                    pool.mode = el["mode"]
-                    self.poolList.append(pool)
-                return self.poolList.copy()
+            self.logger.debug(f"Copying {srcPath} in {destPath}")
+            if os.path.isdir(srcPath):
+                self.scp.put(srcPath, recursive = True, remote_path = destPath)
+            elif os.path.isfile(srcPath):
+                self.scp.put(srcPath, destPath)
             else:
-                raise TapeClientException(cmd, exitCode, stderr)
+                self.logger.error("FATAL: invalid file/dir.")
+                raise ScpInvalidFileException
+        finally:
+            self.scp.close()
 
-    def getTaskList(self):
-        """Returns the whole task list."""
-        cmd = f"{self.EEADM} task list --json"
+    def getHSMFilesystemList(self):
+        """Returns a list containing all the available HSM filesystems."""
+        cmd = f"{self.DSMDF} -detail | grep \"HSM Filesystem\" | awk '{{ print $3 }}'"
         try:
             stdin, stdout, stderr = self.client.exec_command(cmd)
         except Exception:
@@ -104,55 +87,37 @@ class TapeClient(object):
         else:
             exitCode = stdout.channel.recv_exit_status()
             if not exitCode:
-                result = json.loads(stdout.readlines()[0].rstrip('\n'))
-                for el in result["payload"]:
-                    task = TapeTask()
-                    task.inUseTapes = el["inuse_tapes"]
-                    task.inUsePools = el["inuse_pools"]
-                    task.inUseNodeGroups = el["inuse_node_groups"]
-                    task.inUseDrives = el["inuse_drives"]
-                    task.cmdParam = el["cmd_param"]
-                    task.result = el["result"]
-                    task.status = el["status"]
-                    task.completedTime = el["completed_time"]
-                    task.startedTime = el["started_time"]
-                    task.createdTime = el["created_time"]
-                    task.setInUseLibs = el["inuse_libs"]
-                    task.type = el["type"]
-                    task.taskId = el["task_id"]
-                    task.id = el["id"]
-                    self.taskList.append(task)
-                return self.taskList.copy()
+                result = stdout.readlines()[0].rstrip('\n')
+                self.HSMFilesystemList = result.splitlines()
+                return self.HSMFilesystemList.copy()
             else:
                 raise TapeClientException(cmd, exitCode, stderr)
 
-    def copy(self, srcPath, destPath):
-        """Copies files/dirs recursively by passing their absolute paths."""
+    def getHSMFilesystemFreeSpace(self, HSMFilesystem):
+        "Returns the free space in bytes for a given HSM filesystem."
+        cmd = f"{self.DSMDF} -detail {HSMFilesystem} | grep \"Free Size\" | awk '{{ print $3 }}'"
         try:
-            self.scp = scp.SCPClient(self.client.get_transport())
+            stdin, stdout, stderr = self.client.exec_command(cmd)
         except Exception:
-            self.logger.error("Unable to get transport from SSH client.")
+            self.logger.exception(f"Unable to execute command: '{cmd}'")
             raise
         else:
-            self.logger.debug(f"Copying {srcPath} in {destPath}")
-            if os.path.isdir(srcPath):
-                self.scp.put(srcPath, recursive = True, remote_path = destPath)
-            elif os.path.isfile(srcPath):
-                self.scp.put(srcPath, destPath)
+            exitCode = stdout.channel.recv_exit_status()
+            if not exitCode:
+                result = stdout.readlines()[0].rstrip('\n') + " KB"
+                freeSpace = self.systemUtils.convertSizeToBytes(result)
+                return freeSpace
             else:
-                self.logger.error("FATAL: invalid file/dir.")
-                raise ScpInvalidFileException
-        finally:
-            self.scp.close()
+                raise TapeClientException(cmd, exitCode, stderr)
 
-    def migrate(self, fileList, tapePool, jobId):
+    def migrate(self, fileList, tapeHSMFilesystem, jobId):
         """
         Migrates to tape all files whose absolute path is
         contained in 'fileList'.
-        A tape pool and a VOSpace jobId are also required
-        as parameters.
+        A HSM filesystem and a VOSpace jobId are also
+        required as parameters.
         """
-        self.logger.info(f"Starting MIGRATE operation (tape pool = '{tapePool}')...")
+        self.logger.info(f"Starting MIGRATE operation (tape HSM filesystem = '{tapeHSMFilesystem}')...")
         migrateFileList = f"vos_migrate-{jobId}.lst"
         try:
             fp = open(migrateFileList, "a")
@@ -164,7 +129,7 @@ class TapeClient(object):
             fp.close()
             self.copy(f"./{migrateFileList}", f"{self.VOSPACE_WD}/{migrateFileList}")
             os.remove(f"./{migrateFileList}")
-            cmd = f"{self.EEADM} migrate {self.VOSPACE_WD}/{migrateFileList} -p {tapePool} > /dev/null 2>&1"
+            cmd = f"{self.DSMMIGRATE} -filelist={self.VOSPACE_WD}/{migrateFileList} > /dev/null 2>&1"
             try:
                 stdin, stdout, stderr = self.client.exec_command(cmd)
             except Exception:
@@ -172,7 +137,7 @@ class TapeClient(object):
                 raise
             else:
                 exitCode = stdout.channel.recv_exit_status()
-                if not exitCode:
+                if exitCode == 0 or exitCode == 4:
                     self.logger.info("MIGRATE operation COMPLETED.")
                 else:
                     self.logger.error("MIGRATE operation FAILED.")
@@ -197,7 +162,7 @@ class TapeClient(object):
             fp.close()
             self.copy(f"./{recallFileList}", f"{self.VOSPACE_WD}/{recallFileList}")
             os.remove(f"./{recallFileList}")
-            cmd = f"{self.EEADM} recall {self.VOSPACE_WD}/{recallFileList} > /dev/null 2>&1"
+            cmd = f"{self.DSMRECALL} -filelist={self.VOSPACE_WD}/{recallFileList} > /dev/null 2>&1"
             try:
                 stdin, stdout, stderr = self.client.exec_command(cmd)
             except Exception:
@@ -205,7 +170,7 @@ class TapeClient(object):
                 raise
             else:
                 exitCode = stdout.channel.recv_exit_status()
-                if not exitCode:
+                if exitCode == 0 or exitCode == 4:
                     self.logger.info("RECALL operation COMPLETED.")
                 else:
                     self.logger.error("RECALL operation FAILED.")
@@ -218,7 +183,8 @@ class TapeClient(object):
         the 'dirName' directory.
         """
         self.logger.info("Starting RECALL_CHECKSUM operation...")
-        cmd = f"find $(dirname {dirName}) -type f \( -iname \"*-md5sum.txt\" \) | {self.EEADM} recall > /dev/null 2>&1"
+        checksumFileList = "vos_recall_checksum_files-{jobId}.lst"
+        cmd = f"find $(dirname {dirName}) -type f \( -iname \"*-md5sum.txt\" \) > {self.VOSPACE_WD}/{checksumFileList} && {self.DSMRECALL} -filelist={self.VOSPACE_WD}/{checksumFileList} > /dev/null 2>&1"
         try:
             stdin, stdout, stderr = self.client.exec_command(cmd)
         except Exception:
@@ -226,7 +192,7 @@ class TapeClient(object):
             raise
         else:
             exitCode = stdout.channel.recv_exit_status()
-            if not exitCode:
+            if exitCode == 0 or exitCode == 4:
                 self.logger.info("RECALL_CHECKSUM operation COMPLETED.")
             else:
                 self.logger.error("RECALL_CHECKSUM operation FAILED.")
@@ -235,8 +201,7 @@ class TapeClient(object):
 
     def disconnect(self):
         """Performs a cleanup and closes the connection."""
-        self.taskList.clear()
-        self.poolList.clear()
+        self.HSMFilesystemList.clear()
         self.client.close()
 
     def getSize(self, fsMountPoint):
@@ -261,7 +226,6 @@ class TapeClient(object):
 #tc.connect()
 #tc.copy("/home/curban/store/mydir", "/home/mydir")
 #tc.copy("/home/curban/store/foo2.txt", "/home/mydir/foo2.txt")
-#tl = tc.getTaskList()
 #fsSize = tc.getSize("/ia2_tape_stb_01")
 #print(fsSize)
 #tc.disconnect()
diff --git a/transfer_service/tape_pool.py b/transfer_service/tape_pool.py
deleted file mode 100644
index c73cc0ccc31ac7c3b16d8d52c01ee918a9fe23b1..0000000000000000000000000000000000000000
--- a/transfer_service/tape_pool.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python
-#
-# This file is part of vospace-transfer-service
-# Copyright (C) 2021 Istituto Nazionale di Astrofisica
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-#
-#
-# Example of JSON object obtained with "eeadm pool list --json":
-#
-# {
-#    "id": "c42ba7c9-1ec7-43a3-91af-b735a81ebbb2",
-#    "name": "pl_generic_rw_01",
-#    "media_restriction": "^.{8}$",
-#    "capacity": 130982137036800,
-#    "used_space": 61111860723712,
-#    "free_space": 69870276313088,
-#    "reclaimable_space": 263958922781,
-#    "active_space": 60847901800931,
-#    "non_appendable_space": 0,
-#    "num_of_tapes": 15,
-#    "format_class": "default",
-#    "library_name": "tape_ia2_SA",
-#    "library_id": "bc4bbe3f-b670-46e2-bba9-3fbc1fc2ce52",
-#    "nodegroup_name": "G0",
-#    "device_type": "LTO",
-#    "worm": "no",
-#    "fill_policy": "Default",
-#    "owner": "System",
-#    "mount_limit": 0,
-#    "low_space_warning_enable": false,
-#    "low_space_warning_threshold": 0,
-#    "no_space_warning_enable": false,
-#    "mode": "normal"
-#  }
-#
-
-class TapePool(object):
-    
-    def __init__(self):
-        self.id = None
-        self.name = None
-        self.mediaRestriction = None
-        self.capacity = None
-        self.usedSpace = None
-        self.freeSpace = None
-        self.reclaimableSpace = None
-        self.activeSpace = None
-        self.nonAppendableSpace = None
-        self.numOfTapes = None
-        self.formatClass = None
-        self.libraryName = None
-        self.libraryId = None
-        self.nodeGroupName = None
-        self.deviceType = None
-        self.worm = None
-        self.fillPolicy = None
-        self.owner = None
-        self.mountLimit = None
-        self.lowSpaceWarningEnable = None
-        self.lowSpaceWarningThreshold = None
-        self.noSpaceWarningEnable = None
-        self.mode = None
-        
-    """
-    Getters
-    """
-    
-    def getId(self):
-        return self.id
-    
-    def getName(self):
-        return self.name
-    
-    def getMediaRestriction(self):
-        return self.mediaRestriction
-    
-    def getCapacity(self):
-        return self.capacity
-    
-    def getUsedSpace(self):
-        return self.usedSpace
-    
-    def getFreeSpace(self):
-        return self.freeSpace
-    
-    def getReclaimableSpace(self):
-        return self.reclaimableSpace
-    
-    def getActiveSpace(self):
-        return self.activeSpace
-    
-    def getNonAppendableSpace(self):
-        return self.nonAppendableSpace
-    
-    def getNumOfTapes(self):
-        return self.numOfTapes
-    
-    def getFormatClass(self):
-        return self.formatClass
-    
-    def getLibraryName(self):
-        return self.libraryName
-    
-    def getLibraryId(self):
-        return self.libraryId
-    
-    def getNodeGroupName(self):
-        return self.nodeGroupName
-    
-    def getDeviceType(self):
-        return self.deviceType
-    
-    def worm(self):
-        return self.worm
-    
-    def getFillPolicy(self):
-        return self.fillPolicy
-    
-    def getOwner(self):
-        return self.owner
-    
-    def getMountLimit(self):        
-        return self.mountLimit
-    
-    def lowSpaceWarningEnable(self):
-        return self.lowSpaceWarningEnable
-    
-    def getLowSpaceWarningThreshold(self):
-        return self.lowSpaceWarningThreshold
-    
-    def noSpaceWarningEnable(self):
-        return self.noSpaceWarningEnable
-    
-    def getMode(self):
-        return self.mode
diff --git a/transfer_service/tape_task.py b/transfer_service/tape_task.py
deleted file mode 100644
index ed37b0516b640c182b4c3390accee2cfdd010451..0000000000000000000000000000000000000000
--- a/transfer_service/tape_task.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env python
-#
-# This file is part of vospace-transfer-service
-# Copyright (C) 2021 Istituto Nazionale di Astrofisica
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-class TapeTask(object):
-    
-    def __init__(self):
-        self.inUseTapes = None
-        self.inUsePools = None
-        self.inUseNodeGroups = None
-        self.inUseDrives = None
-        self.cmdParam = None
-        self.result = None
-        self.status = None
-        self.completedTime = None
-        self.startedTime = None
-        self.createdTime = None
-        self.setInUseLibs = None
-        self.type = None
-        self.taskId = None
-        self.id = None
-    
-    """
-    Getters
-    """
-    
-    def getResult(self):
-        return self.result
-      
-    def getStatus(self):
-        return self.status    
-      
-    def succeeded(self):
-        return self.result == "succeeded"
-      
-    def failed(self):
-        return self.result == "failed"
-      
-    def aborted(self):
-        return self.result == "aborted"
-      
-    def canceled(self):
-        return self.result == "canceled"
-      
-    def isCreated(self):
-        return self.status == "created"
-      
-    def isRunning(self):
-        return self.status == "running"
-      
-    def isWaiting(self):
-        return self.status == "waiting"
-      
-    def isCompleted(self):
-        return self.status == "completed"
-    
-    
-    """
-    Setters
-    """
-    
-    def setInUseTapes(self, inUseTapes):
-        self.inUseTapes = inUseTapes
-        
-    def setInUsePools(self, inUsePools):
-        self.inUsePools = inUsePools
-        
-    def setInUseNodeGroups(self, inUseNodeGroups):
-        self.inUseGroups = inUseGroups
-    
-    def setInUseDrives(self, inUseDrives):
-        self.inUseNodeDrives = inUseDrives
-        
-    def setCmdParam(self, cmdParam):
-        self.cmdParam = cmdParam
-        
-    def setResult(self, result):
-        self.result = result
-      
-    def setStatus(self, status):
-        self.status = status
-    
-    def setCompletedTime(self, completedTime):
-        self.completedTime = completedTime
-    
-    def setStartedTime(self, startedTime):
-        self.startedTime = startedTime
-        
-    def setCreatedTime(self, createdTime):
-        self.createdTime = createdTime
-    
-    def setInUseLibs(self, inUseLibs):
-        self.setInUseLibs = inUseLibs
-        
-    def setType(self, type):
-        self.type = type
-    
-    def setTaskId(self, taskId):
-        self.taskId = taskId
-        
-    def setId(self, id):
-        self.id = id