On Wed, Jan 25, 2017 at 08:48:10PM -0600, Eric Blake wrote:
On 01/24/2017 09:16 AM, Richard W.M. Jones wrote:
In Perl, old code to raise an error would look like:
sub pread { my $h = shift; my $count = shift; my $offset = shift; my $ret; read ($FH, $ret, $count, $offset) || die "read: $!" return $ret; }
(Note that die does not exit the program, it raises an exception which is caught and turned into nbdkit_error in the Perl nbdkit plugin).
This would continue to work fine, but new code which cared about the errno could do this instead:
sub pread { my $h = shift; my $count = shift; my $offset = shift; my $ret; read ($FH, $ret, $count, $offset) || { nbdkit_set_errno (POSIX::errno ()); die "read: $!" } return $ret; }
Except I can't even figure out how to expose nbdkit_set_error (hmm, I named it set_error instead of set_errno in my v2 series) to the perl code.
Apparently you have to use XS for this, which seems like a PITA ... I'm sure there must be an easier way to do it where you create a coderef directly in the main:: package.
In fact, with just this change to example.pl:
diff --git i/plugins/perl/example.pl w/plugins/perl/example.pl index fcdac33..64f6de3 100644 --- i/plugins/perl/example.pl +++ w/plugins/perl/example.pl @@ -1,4 +1,5 @@ use strict; +use POSIX ();
# Example Perl plugin. # @@ -80,6 +81,8 @@ sub pwrite my $buf = shift; my $count = length ($buf); my $offset = shift; + my $err = POSIX::EPERM;
substr ($disk, $offset, $count) = $buf; + die "forced write failure"; }
I'm getting this failure:
$ ./src/nbdkit -e foo -fv plugins/perl/.libs/nbdkit-perl-plugin.so \ script=plugins/perl/example.pl nbdkit: debug: registering plugins/perl/.libs/nbdkit-perl-plugin.so nbdkit: debug: registered plugins/perl/.libs/nbdkit-perl-plugin.so (name perl) nbdkit: debug: plugins/perl/.libs/nbdkit-perl-plugin.so: load nbdkit: debug: plugins/perl/.libs/nbdkit-perl-plugin.so: config key=script, value=plugins/perl/example.pl Can't load module Fcntl, dynamic loading not available in this perl. (You may need to build a new perl executable which either supports dynamic loading or has the Fcntl module statically linked into it.) at /usr/lib64/perl5/POSIX.pm line 17. Compilation failed in require at /usr/lib64/perl5/POSIX.pm line 17. BEGIN failed--compilation aborted at /usr/lib64/perl5/POSIX.pm line 17. Compilation failed in require at plugins/perl/example.pl line 2. BEGIN failed--compilation aborted at plugins/perl/example.pl line 2. nbdkit: error: plugins/perl/example.pl: one of the required callbacks 'open', 'get_size' or 'pread' is not defined by this Perl script. nbdkit requires these callbacks.
So I'm not sure how anyone else is doing anything fancy in an NBD perl script.
This is a bug - I guess it reflects how little used the Perl bindings are ... It looks like how to fix it is described in perlembed(1) section "Using Perl modules, which themselves use C libraries, from your C program" Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/