NAME

Protocol::Sys::Virt::Transport - Low level Libvirt connection protocol

VERSION

v10.10.13

Based on LibVirt tag v10.10.0

SYNOPSIS

use Protocol::Sys::Virt::Transport;
use Protocol::Sys::Virt::Remote;

open my $fh, 'rw', '/run/libvirt/libvirt.sock';
my $transport = Protocol::Sys::Virt::Transport->new(
     role => 'client',
     on_send => sub { my $opaque = shift; syswrite( $fh, $_ ) for @_; $opaque }
);

my $remote = Protocol::Sys::Virt::Remote->new;
$remote->register( $transport );

DESCRIPTION

This module implements an abstract transport with the low level mechanics to talk to (remote) LibVirt deamons like libvirtd, libvirt-qemud, libvirt-lockd or libvirtd-admin. Instances do not directly communicate over a connection stream; instead, they expect the caller to handle incoming data and call the receive method for handling by the protocol. Similarly, the on_send event is invoked with data to be transmitted.

EVENTS

on_send

$on_send->( $opaque, $chunk [, ..., $chunkN ] );

Invoked with any number of arguments, each a chunk of data to be transmitted over the connection stream, except the first ($opaque) value.

In case the chunk is an arrayref, the chunk contains file descriptors to be transferred.

Must return the $opaque value after transferring the data, or die in case of an error.

CONSTRUCTOR

new

my $transport = Protocol::Sys::Virt::Transport->new(
   role => 'client',
   on_send => sub { ... }
);

Creates an instance on the client side (role => 'client') or server (role => 'server') side of the connection.

The on_send event is triggered with data to be transmitted. It may be called with multiple arguments:

sub _transmitter {
   my $opaque = shift;
   syswrite( $fh, $_ ) for (@_);
   return $opaque;
}

The first argument must be returned when the routine finishes transmitting its data.

METHODS

need

my ($length, $type) = $transport->need;

Returns the $type of data expected by the next call to receive (values are data and fd) as well as the number of file handles (in case of fd type) or bytes (in case of data type) expected.

When the fd type is indicated, the protocol expects a file descriptor as the next $data argument. File descriptors can only be passed over Unix domain sockets; over any other connection, this should result in a fatal error at the caller.

receive

my @cb_values = $transport->receive( $data, [ type => 'fd' ] );

Feed data received on the connection stream to the protocol transport instance. When $data is a file descriptor, the type => 'fd' should be passed.

The function collects and returns the values of the event callbacks as they are invoked as part of processing the protocol input.

register

 my $sender = $transport->register($remote->PROG, $remote->PROTOCOL_VERSION, {
    on_call    => ...,
    on_reply   => ...,
    on_message => ...,
    on_stream  => ...
 });

my $serial = $sender->($proc, $type, data => $data,
              [status => $status], [fds => $fds], [serial => $serial]);

Registers callbacks for a 'program' (remote, keep alive, admin, ...) with a version of the protocol and a series of callbacks to be invoked when the specific type of input is received.

In case where $type is CALL or CALL_WITH_FDS, the $serial returned by the sender function must be used to link messages passed to on_reply or on_stream to the call that triggered the replies.

Note: the on_send function may be marked async (as in Future::AsyncAwait), in which case the $sender function returns a Future which eventually resolves to the $serial.

The callbacks are called as follows, with any return values collected and returned by the receive function:

  • on_call

    my $rv = $on_call->(header => $hdr, data => $data, [fds => $fds]);

    Called for messages of type CALL and CALL_WITH_FDS. The difference between the two is that the latter is passed an array of file descriptors in the fds key. The header key contains the deserialized header.

    The data key contains the undecoded data of the *_args structure associated with $hdr->{proc}.

  • on_reply

    my $rv = $on_reply->(header => $hdr, data  => $data, [fds => $fds]);
    my $rv = $on_reply->(header => $hdr, error => $err);

    Called for messages of type REPLY or REPLY_WITH_FDS. The difference between the two is that the latter is passed an array of file descriptors in the fds key. The header key contains the deserialized header.

    The data key contains the undecoded data of the *_ret structure associated with $hdr-{proc}>.

    In case the server sends an error, the error key contains the deserialized error structure and neither data nor fds keys are supplied.

  • on_message

    my $rv = $on_message->(header => $hdr, data  => $data);

    Called for messages of type MESSAGE. The data key contains the undecoded data of the *_msg structure associated with $hdr-{proc}>.

  • on_stream

    my $rv = $on_stream->(header => $hdr, data => $data);
    my $rv = $on_stream->(header => $hdr, hole => $hole);
    my $rv = $on_stream->(header => $hdr, error => $err);

    Called for messages of type STREAM or STREAM_HOLE. $data is the raw stream data to be written to the stream. $hole is the deserialized stream hole structure. $err is the deserialized error structure.

LICENSE AND COPYRIGHT

See the LICENSE file in this distribution.