On Wed, Aug 04, 2010 at 04:14:45PM +0100, Matthew Booth wrote:
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);
Yikes.
Not an easier way to ask if a filename is a block device? Like
maybe: test -b $dev
ACK either way.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages.
http://et.redhat.com/~rjones/libguestfs/
See what it can do:
http://et.redhat.com/~rjones/libguestfs/recipes.html