[Libguestfs] [PATCH] Correctly detect the size of a block device over SSH

Matthew Booth mbooth at redhat.com
Wed Aug 4 15:14:45 UTC 2010


When fetching a storage volume over SSH, we were detecting its size with a
simple 'stat -c %s'. While this works fine for files, it won't return the
correct size of a block device.

This patch uses the output of 'blockdev --getsize64' for block devices, and stat
as before for regular files.

Fixes RHBZ#620698
---
 lib/Sys/VirtV2V/Transfer/SSH.pm |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/lib/Sys/VirtV2V/Transfer/SSH.pm b/lib/Sys/VirtV2V/Transfer/SSH.pm
index 66ec294..5f54f0e 100644
--- a/lib/Sys/VirtV2V/Transfer/SSH.pm
+++ b/lib/Sys/VirtV2V/Transfer/SSH.pm
@@ -138,7 +138,21 @@ sub _connect
         push(@command, 'ssh');
         push(@command, '-l', $username) if (defined($username));
         push(@command, $host);
-        push(@command, "stat -c %s $path; cat $path");
+
+        # Return the size of the remote path on the first line, followed by its
+        # contents.
+        # The bit arithmetic with the output of stat is a translation into shell
+        # of the S_ISBLK macro. If the remote device is a block device, stat
+        # will simply return the size of the block device inode. In this case,
+        # we use the output of blockdev --getsize64 instead.
+        push(@command,
+            "dev=$path; ".
+            'if [[ $(((0x$(stat -L -c %f $dev)&0170000)>>12)) == 6 ]]; then '.
+              'blockdev --getsize64 $dev; '.
+            'else '.
+              'stat -L -c %s $dev; '.
+            'fi; '.
+            'cat $dev');
 
         # Close the ends of the pipes we don't need
         close($stdin_write);
-- 
1.7.2.1




More information about the Libguestfs mailing list