It's useful to have both the good image created
at unattended install time and, when the image
gets corrupted, the bad image, both with the same
unique suffix. So expand the backup image method
to handle this behavior accordingly, and also
simplify the logic used on that method.

CC: Cleber Rosa <[email protected]>
CC: Kevin Wolf <[email protected]>
Signed-off-by: Lucas Meneghel Rodrigues <[email protected]>
---
 client/virt/storage.py | 98 +++++++++++++++++++++++++++++---------------------
 1 file changed, 57 insertions(+), 41 deletions(-)

diff --git a/client/virt/storage.py b/client/virt/storage.py
index 1ff6f22..37579ac 100644
--- a/client/virt/storage.py
+++ b/client/virt/storage.py
@@ -176,23 +176,53 @@ class QemuImg(object):
                image_format -- the format of the image (qcow2, raw etc)
         """
         def backup_raw_device(src, dst):
-            utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))
+            if os.path.exists(src):
+                utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))
+            else:
+                logging.info("No source %s, skipping dd...", src)
 
         def backup_image_file(src, dst):
             logging.debug("Copying %s -> %s", src, dst)
-            shutil.copy(src, dst)
+            if os.path.isfile(src):
+                shutil.copy(src, dst)
+            else:
+                logging.info("No source file %s, skipping copy...", src)
 
-        def get_backup_name(filename, backup_dir, good):
+        def get_backup_set(filename, backup_dir, action, good):
+            """
+            Get all sources and destinations required for each backup.
+            """
             if not os.path.isdir(backup_dir):
                 os.makedirs(backup_dir)
             basename = os.path.basename(filename)
+            bkp_set = []
             if good:
-                backup_filename = "%s.backup" % basename
+                src = filename
+                dst = os.path.join(backup_dir, "%s.backup" % basename)
+                if action == 'backup':
+                    bkp_set = [[src, dst]]
+                elif action == 'restore':
+                    bkp_set = [[dst, src]]
             else:
-                backup_filename = ("%s.bad.%s" %
-                                   (basename,
-                                    utils_misc.generate_random_string(4)))
-            return os.path.join(backup_dir, backup_filename)
+                # We have to make 2 backups, one of the bad image, another one
+                # of the good image
+                src_bad = filename
+                src_good = filename + ".backup"
+                hsh = utils_misc.generate_random_string(4)
+                dst_bad = (os.path.join(backup_dir, "%s.bad.%s" %
+                                        (basename, hsh)))
+                dst_good = (os.path.join(backup_dir, "%s.good.%s" %
+                                         (basename, hsh)))
+                if action == 'backup':
+                    bkp_set = [[src_bad, dst_bad], [src_good, dst_good]]
+                elif action == 'restore':
+                    bkp_set = [[src_good, src_bad]]
+
+            if not bkp_set:
+                logging.error("No backup sets for action: %s, state: %s",
+                              action, good)
+
+            return bkp_set
 
 
         image_filename = self.image_filename
@@ -202,51 +232,37 @@ class QemuImg(object):
             iformat = params.get("image_format", "qcow2")
             ifilename = "%s.%s" % (iname, iformat)
             ifilename = utils_misc.get_path(root_dir, ifilename)
-            image_filename_backup = get_backup_name(ifilename, backup_dir, 
good)
+            backup_set = get_backup_set(ifilename, backup_dir, action, good)
             backup_func = backup_raw_device
         else:
-            image_filename_backup = get_backup_name(image_filename, backup_dir,
-                                                    good)
+            backup_set = get_backup_set(image_filename, backup_dir, action, 
good)
             backup_func = backup_image_file
 
         if action == 'backup':
             image_dir = os.path.dirname(image_filename)
             image_dir_disk_free = utils.freespace(image_dir)
-            image_filename_size = os.path.getsize(image_filename)
-            image_filename_backup_size = 0
-            if os.path.isfile(image_filename_backup):
-                image_filename_backup_size = os.path.getsize(
-                                                        image_filename_backup)
-            disk_free = image_dir_disk_free + image_filename_backup_size
-            minimum_disk_free = 1.2 * image_filename_size
-            if disk_free < minimum_disk_free:
+
+            backup_size = 0
+            for src, dst in backup_set:
+                if os.path.isfile(src):
+                    backup_size += os.path.getsize(src)
+
+            minimum_disk_free = 1.2 * backup_size
+            if image_dir_disk_free < minimum_disk_free:
                 image_dir_disk_free_gb = float(image_dir_disk_free) / 10**9
+                backup_size_gb = float(backup_size) / 10**9
                 minimum_disk_free_gb = float(minimum_disk_free) / 10**9
-                logging.error("Dir %s has %.1f GB free, less than the minimum "
-                              "required to store a backup, defined to be 120%% 
"
-                              "of the backup size, %.1f GB. Skipping 
backup...",
-                              image_dir, image_dir_disk_free_gb,
+                logging.error("Free space on %s: %.1f GB", image_dir,
+                              image_dir_disk_free_gb)
+                logging.error("Backup size: %.1f GB", backup_size_gb)
+                logging.error("Minimum free space acceptable: %.1f GB",
                               minimum_disk_free_gb)
+                logging.error("Available disk space is not sufficient for a"
+                              "full backup. Skipping backup...")
                 return
-            if good:
-                # In case of qemu-img check return 1, we will make 2 backups,
-                # one for investigation and other, to use as a 'pristine'
-                # image for further tests
-                state = 'good'
-            else:
-                state = 'bad'
-            logging.info("Backing up %s image file %s", state, image_filename)
-            src, dst = image_filename, image_filename_backup
-        elif action == 'restore':
-            if not os.path.isfile(image_filename_backup):
-                logging.error('Image backup %s not found, skipping restore...',
-                              image_filename_backup)
-                return
-            logging.info("Restoring image file %s from backup",
-                         image_filename)
-            src, dst = image_filename_backup, image_filename
 
-        backup_func(src, dst)
+        for src, dst in backup_set:
+            backup_func(src, dst)
 
 
     def clone_image(self, params, vm_name, image_name, root_dir):
-- 
1.7.11.4

_______________________________________________
Autotest-kernel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/autotest-kernel

Reply via email to