[libvirt] [libvirt-perl][PATCH 7/7] examples: Introduce vol-sparse.pl

Michal Privoznik mprivozn at redhat.com
Tue May 23 15:05:41 UTC 2017


Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 Changes                |   1 +
 examples/vol-sparse.pl | 142 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+)
 create mode 100755 examples/vol-sparse.pl

diff --git a/Changes b/Changes
index 6c671c0..3742a8c 100644
--- a/Changes
+++ b/Changes
@@ -11,6 +11,7 @@ Revision history for perl module Sys::Virt
  - Introduce Stream::sparse_send_all()
  - Register VOL_DOWNLOAD_SPARSE_STREAM &
    VOL_UPLOAD_SPARSE_STREAM constants
+ - Add vol-sparse.pl example
 
 3.3.0 2017-05-08
 
diff --git a/examples/vol-sparse.pl b/examples/vol-sparse.pl
new file mode 100755
index 0000000..b99b57f
--- /dev/null
+++ b/examples/vol-sparse.pl
@@ -0,0 +1,142 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Sys::Virt;
+use Fcntl;
+
+my $FILE;
+
+sub downloadHandler {
+	my $st = shift;
+	my $data = shift;
+	my $nbytes = shift;
+	return syswrite FILE, $data, $nbytes;
+}
+
+sub downloadHoleHandler {
+    my $st = shift;
+    my $offset = shift;
+    my $pos = sysseek FILE, $offset, Fcntl::SEEK_CUR or die "Unable to seek in $FILE: $!";
+    truncate FILE, $pos;
+}
+
+
+sub download {
+    my $vol = shift;
+    my $st = shift;
+    my $filename = shift;
+    my $offset = 0;
+    my $length = 0;
+
+    open FILE, ">$filename" or die "unable to create $filename: $!";
+    eval {
+        $vol->download($st, $offset, $length, Sys::Virt::StorageVol::VOL_DOWNLOAD_SPARSE_STREAM);
+        $st->sparse_recv_all(\&downloadHandler, \&downloadHoleHandler);
+        $st->finish();
+    };
+    if ($@) {
+        unlink $filename if $@;
+        close FILE;
+        die $@;
+    }
+
+    close FILE or die "cannot save $filename: $!"
+}
+
+sub uploadHandler {
+    my $st = $_[0];
+    my $nbytes = $_[2];
+    return sysread FILE, $_[1], $nbytes;
+}
+
+sub uploadHoleHandler {
+    my $st = shift;
+    my $inData;
+    my $sectionLen;
+
+    # HACK, Perl lacks SEEK_DATA and SEEK_HOLE.
+    my $SEEK_DATA = 3;
+    my $SEEK_HOLE = 4;
+
+    my $cur = sysseek FILE, 0, Fcntl::SEEK_CUR;
+    eval {
+        my $data = sysseek FILE, $cur, $SEEK_DATA;
+        # There are three options:
+        # 1) $data == $cur;  $cur is in data
+        # 2) $data > $cur; $cur is in a hole, next data at $data
+        # 3) $data < 0; either $cur is in trailing hole, or $cur is beyond EOF.
+
+        if (!defined($data)) {
+            # case 3
+            $inData = 0;
+            my $end = sysseek FILE, 0, Fcntl::SEEK_END or die "Unable to get EOF position: $!";
+            $sectionLen = $end - $cur;
+        } elsif ($data > $cur) {
+            #case 2
+            $inData = 0;
+            $sectionLen = $data - $cur;
+        } else {
+            #case 1
+            my $hole = sysseek FILE, $data, $SEEK_HOLE;
+            if (!defined($hole) or $hole eq $data) {
+                die "Blah";
+            }
+            $inData = 1;
+            $sectionLen = $hole - $data;
+        }
+    };
+
+    # reposition file back
+    sysseek FILE, $cur, Fcntl::SEEK_SET;
+
+    return ($inData, $sectionLen);
+}
+
+sub uploadSkipHandler {
+    my $st = shift;
+    my $offset = shift;
+    print("uploadSkipHandler: $offset\n");
+    sysseek FILE, $offset, Fcntl::SEEK_CUR or die "Unable to seek in $FILE";
+}
+
+sub upload {
+    my $vol = shift;
+    my $st = shift;
+    my $filename = shift;
+    my $offset = 0;
+    my $length = 0;
+
+    open FILE, "<$filename" or die "unable to open $filename: $!";
+    eval {
+        $vol->upload($st, $offset, $length, Sys::Virt::StorageVol::VOL_UPLOAD_SPARSE_STREAM);
+        $st->sparse_send_all(\&uploadHandler, \&uploadHoleHandler, \&uploadSkipHandler);
+        $st->finish();
+    };
+    if ($@) {
+        close FILE;
+        die $@;
+    }
+
+    close FILE or die "cannot close $filename: $!"
+}
+
+die "syntax: $0 URI --download/--upload VOLUME FILE" unless int(@ARGV) == 4;
+
+my $uri = shift @ARGV;
+my $action = shift @ARGV;
+my $volpath = shift @ARGV;
+my $filename = shift @ARGV;
+
+my $c = Sys::Virt->new(uri => $uri) or die "Unable to connect to $uri";
+my $vol = $c->get_storage_volume_by_key($volpath) or die "No such volume";
+my $st = $c->new_stream();
+
+if ($action eq "--download") {
+    download($vol, $st, $filename);
+} elsif ($action eq "--upload") {
+    upload($vol, $st, $filename);
+} else {
+    die "unknown action $action";
+}
-- 
2.13.0




More information about the libvir-list mailing list