Let VirtualFilesystemImage restore loop device ownership and permissions.

VirtualFilesystemImage sets up a loop-mounted virtual filesystem image
for the platform_CrosDisksFilesystem tests to verify the D-Bus API
exposed by cros-disks. As the ownership and permissions of the loop
device may be changed during the tests, this CL updates
VirtualFilesystemImage to properly restore the ownership and permissions
of the loop device.

BUG=None
TEST=Run platform_CrosDisksFilesystem tests and manually check that
VirtualFilesystemImage properly restores the ownership and permissions
of the loop device.

Change-Id: I9e1d23ff12e2b449462df6276643b3b0731a6769
Reviewed-on: https://chromium-review.googlesource.com/624664
Commit-Ready: Ben Chan <[email protected]>
Tested-by: Ben Chan <[email protected]>
Reviewed-by: Mike Frysinger <[email protected]>
diff --git a/client/cros/cros_disks.py b/client/cros/cros_disks.py
index d7f6ffe..1935997 100644
--- a/client/cros/cros_disks.py
+++ b/client/cros/cros_disks.py
@@ -538,6 +538,7 @@
             self._mkfs_options = []
         self._image_file = None
         self._loop_device = None
+        self._loop_device_stat = None
         self._mount_dir = None
 
     def __del__(self):
@@ -651,6 +652,13 @@
         self._loop_device = output.split(':')[0]
         logging.debug('Attached image file "%s" to loop device "%s"',
                       self._image_file.name, self._loop_device)
+
+        self._loop_device_stat = os.stat(self._loop_device)
+        logging.debug('Loop device "%s" (uid=%d, gid=%d, permissions=%04o)',
+                      self._loop_device,
+                      self._loop_device_stat.st_uid,
+                      self._loop_device_stat.st_gid,
+                      stat.S_IMODE(self._loop_device_stat.st_mode))
         return self._loop_device
 
     def detach_from_loop_device(self):
@@ -664,6 +672,13 @@
                       self._loop_device)
         utils.run('umount -f %s' % self._loop_device, ignore_status=True)
 
+        logging.debug('Restore ownership/permissions of loop device "%s"',
+                      self._loop_device)
+        os.chmod(self._loop_device,
+                 stat.S_IMODE(self._loop_device_stat.st_mode))
+        os.chown(self._loop_device,
+                 self._loop_device_stat.st_uid, self._loop_device_stat.st_gid)
+
         logging.debug('Detaching image file "%s" from loop device "%s"',
                       self._image_file.name, self._loop_device)
         utils.run('losetup -d %s' % self._loop_device)