Matthew Booth
2010-Aug-04 15:14 UTC
[Libguestfs] [PATCH] Correctly detect the size of a block device over SSH
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
Richard W.M. Jones
2010-Aug-17 11:18 UTC
[Libguestfs] [PATCH] Correctly detect the size of a block device over SSH
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
Apparently Analagous Threads
- [PREVIEW ONLY] Refactor data transfer code
- [PATCH] LocalCopy: Use blockdev to get the size of block devices
- Wrong deficit calculation in virt-resize.
- [PATCH] Add SSH transfer method
- [PATCH] Don't use libvirt for volume information when converting with libvirtxml