From: Lee Duncan <lduncan@suse.com>
Date: Sat Dec 12 14:11:48 PST 2015
Subject: [PATCH] targetcli: refactor fileio backstore creation
Reference: bsc#910538

Allow creating fileio backstore with size supplied or not. The
logic here was a bit convoluted, so I refactored it to be more
readable and fixed a couple of corner cases in the process, such
as creating a file-based fileio backend with no size supplied,
in which case it should use the existing file's size.

Signed-off-by: Lee Duncan <lduncan@suse.com>

 ui_backstore.py |   64 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 32 insertions(+), 32 deletions(-)
---
--- targetcli-2.1.orig/targetcli/ui_backstore.py	2015-12-11 09:10:51.974495725 -0800
+++ targetcli-2.1/targetcli/ui_backstore.py	2015-12-12 14:07:56.742991151 -0800
@@ -318,31 +318,46 @@ class UIFileIOBackstore(UIBackstore):
 
         is_dev = get_block_type(file_or_dev) is not None \
                 or is_disk_partition(file_or_dev)
+        is_file = os.path.isfile(file_or_dev)
+        no_exist = not os.path.exists(file_or_dev)
 
-        if size is None and is_dev:
+        if is_dev:
+            # fileio backend to a block device
+            if size is not None:
+                raise ExecutionError("Cannot supply size for a block device")
             backstore = FileIOBackstore(self.next_hba_index(), mode='create')
             try:
-                so = FileIOStorageObject(
-                    backstore, name, file_or_dev,
-                    gen_wwn=self.prm_gen_wwn(generate_wwn),
-                    buffered_mode=self.prm_buffered(buffered))
+                so = FileIOStorageObject(backstore, name, file_or_dev,
+                        gen_wwn=self.prm_gen_wwn(generate_wwn),
+                        buffered_mode=self.prm_buffered(buffered))
             except Exception, exception:
                 backstore.delete()
                 raise exception
-            self.shell.log.info("Created fileio %s with size %s."
-                                % (name, size))
-            self.shell.log.info("Note: block backstore preferred for "
-                                " best results.")
+            self.shell.log.info("Created fileio for block device %s." % file_or_dev)
+            self.shell.log.info("Note: iblock backstore preferred for best results.")
             ui_so = UIStorageObject(so, self)
             return self.new_node(ui_so)
-        elif size is not None and not is_dev:
+        elif is_file or no_exist:
+            # fileio backend to a file
+            if no_exist and size is None:
+                raise ExecutionError("Attempting to create file for new fileio backstore, need a size")
+            if size is not None:
+                num_size = convert_human_to_bytes(size)
+            if no_exist:
+                # we know "size" has been specified
+                self._create_file(file_or_dev, num_size, sparse)
+            else:
+                actual_size = os.path.getsize(file_or_dev)
+                if size is not None and actual_size != num_size:
+                    self.shell.log.info("%s exists, using its size (%d bytes) instead" % \
+                            (file_or_dev, actual_size))
+                size = str(actual_size)
             backstore = FileIOBackstore(self.next_hba_index(), mode='create')
             try:
-                so = FileIOStorageObject(
-                    backstore, name, file_or_dev,
-                    size,
-                    gen_wwn=self.prm_gen_wwn(generate_wwn),
-                    buffered_mode=self.prm_buffered(buffered))
+                so = FileIOStorageObject(backstore, name, file_or_dev,
+                        size,
+                        gen_wwn=self.prm_gen_wwn(generate_wwn),
+                        buffered_mode=self.prm_buffered(buffered))
             except Exception, exception:
                 backstore.delete()
                 raise exception
@@ -350,23 +365,8 @@ class UIFileIOBackstore(UIBackstore):
             ui_so = UIStorageObject(so, self)
             return self.new_node(ui_so)
         else:
-            # use given file size only if backing file does not exist
-            if os.path.isfile(file_or_dev):
-                new_size = str(os.path.getsize(file_or_dev))
-                if size:
-                    self.shell.log.info("%s exists, using its size (%s bytes)"
-                                        " instead"
-                                        % (file_or_dev, new_size))
-                size = new_size
-            elif os.path.exists(file_or_dev):
-                raise ExecutionError("Path %s exists but is not a file" % file_or_dev)
-            else:
-                # create file and extend to given file size
-                if not size:
-                    raise ExecutionError("Attempting to create file for new" +
-                                         " fileio backstore, need a size")
-                self._create_file(file_or_dev, convert_human_to_bytes(size),
-                                  sparse)
+            raise ExecutionError("Path %s exists but is not a file or block device" % \
+                    file_or_dev)
 
 
 class UIIBlockBackstore(UIBackstore):
