Extend procedure annotation in the .x file for stream handling. Adds a missing remoteStreamRelease call to remoteDomainScreenshot error path. --- daemon/remote.c | 238 ------------------------------------------ daemon/remote_generator.pl | 114 +++++++++++++++++---- src/remote/remote_driver.c | 207 ------------------------------------ src/remote/remote_protocol.x | 38 +++++--- 4 files changed, 120 insertions(+), 477 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index fcda2c5..6ca4daa 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1176,50 +1176,6 @@ cleanup: } static int -remoteDispatchDomainMigratePrepareTunnel(struct qemud_server *server ATTRIBUTE_UNUSED, - struct qemud_client *client, - virConnectPtr conn, - remote_message_header *hdr, - remote_error *rerr, - remote_domain_migrate_prepare_tunnel_args *args, - void *ret ATTRIBUTE_UNUSED) -{ - char *dname; - struct qemud_client_stream *stream = NULL; - int rv = -1; - - if (!conn) { - virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); - goto cleanup; - } - - dname = args->dname == NULL ? NULL : *args->dname; - - if (!(stream = remoteCreateClientStream(conn, hdr))) - goto cleanup; - - if (virDomainMigratePrepareTunnel(conn, stream->st, - args->flags, dname, args->resource, - args->dom_xml) < 0) - goto cleanup; - - if (remoteAddClientStream(client, stream, 0) < 0) - goto cleanup; - - rv = 0; - -cleanup: - if (rv < 0) { - remoteDispatchError(rerr); - if (stream) { - virStreamAbort(stream->st); - remoteFreeClientStream(client, stream); - } - } - return rv; -} - -static int remoteDispatchDomainPinVcpu(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, @@ -2612,96 +2568,6 @@ cleanup: return rv; } -static int remoteDispatchStorageVolUpload(struct qemud_server *server ATTRIBUTE_UNUSED, - struct qemud_client *client, - virConnectPtr conn, - remote_message_header *hdr, - remote_error *rerr, - remote_storage_vol_upload_args *args, - void *ret ATTRIBUTE_UNUSED) -{ - struct qemud_client_stream *stream = NULL; - virStorageVolPtr vol = NULL; - int rv = -1; - - if (!conn) { - virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); - goto cleanup; - } - - if (!(vol = get_nonnull_storage_vol(conn, args->vol))) - goto cleanup; - - if (!(stream = remoteCreateClientStream(conn, hdr))) - goto cleanup; - - if (virStorageVolUpload(vol, stream->st, - args->offset, args->length, - args->flags) < 0) - goto cleanup; - - if (remoteAddClientStream(client, stream, 0) < 0) - goto cleanup; - - rv = 0; - -cleanup: - if (rv < 0) - remoteDispatchError(rerr); - if (vol) - virStorageVolFree(vol); - if (stream && rv != 0) { - virStreamAbort(stream->st); - remoteFreeClientStream(client, stream); - } - return rv; -} - -static int remoteDispatchStorageVolDownload(struct qemud_server *server ATTRIBUTE_UNUSED, - struct qemud_client *client, - virConnectPtr conn, - remote_message_header *hdr, - remote_error *rerr, - remote_storage_vol_download_args *args, - void *ret ATTRIBUTE_UNUSED) -{ - struct qemud_client_stream *stream = NULL; - virStorageVolPtr vol = NULL; - int rv = -1; - - if (!conn) { - virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); - goto cleanup; - } - - if (!(vol = get_nonnull_storage_vol(conn, args->vol))) - goto cleanup; - - if (!(stream = remoteCreateClientStream(conn, hdr))) - goto cleanup; - - if (virStorageVolDownload(vol, stream->st, - args->offset, args->length, - args->flags) < 0) - goto cleanup; - - if (remoteAddClientStream(client, stream, 1) < 0) - goto cleanup; - - rv = 0; - -cleanup: - if (rv < 0) - remoteDispatchError(rerr); - if (vol) - virStorageVolFree(vol); - if (stream && rv != 0) { - virStreamAbort(stream->st); - remoteFreeClientStream(client, stream); - } - return rv; -} - /*************************** * Register / deregister events @@ -3035,53 +2901,6 @@ cleanup: } -static int -remoteDispatchDomainOpenConsole(struct qemud_server *server ATTRIBUTE_UNUSED, - struct qemud_client *client, - virConnectPtr conn, - remote_message_header *hdr, - remote_error *rerr, - remote_domain_open_console_args *args, - void *ret ATTRIBUTE_UNUSED) -{ - struct qemud_client_stream *stream = NULL; - virDomainPtr dom = NULL; - int rv = -1; - - if (!conn) { - virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); - goto cleanup; - } - - if (!(dom = get_nonnull_domain(conn, args->dom))) - goto cleanup; - - if (!(stream = remoteCreateClientStream(conn, hdr))) - goto cleanup; - - if (virDomainOpenConsole(dom, - args->devname ? *args->devname : NULL, - stream->st, - args->flags) < 0) - goto cleanup; - - if (remoteAddClientStream(client, stream, 1) < 0) - goto cleanup; - - rv = 0; - -cleanup: - if (rv < 0) - remoteDispatchError(rerr); - if (stream && rv < 0) { - virStreamAbort(stream->st); - remoteFreeClientStream(client, stream); - } - if (dom) - virDomainFree(dom); - return rv; -} - #include "remote_dispatch_bodies.h" #include "qemu_dispatch_bodies.h" @@ -3192,63 +3011,6 @@ cleanup: } static int -remoteDispatchDomainMigratePrepareTunnel3(struct qemud_server *server ATTRIBUTE_UNUSED, - struct qemud_client *client, - virConnectPtr conn, - remote_message_header *hdr, - remote_error *rerr, - remote_domain_migrate_prepare_tunnel3_args *args, - remote_domain_migrate_prepare_tunnel3_ret *ret) -{ - char *dname; - char *cookieout = NULL; - int cookieoutlen = 0; - struct qemud_client_stream *stream = NULL; - int rv = -1; - - if (!conn) { - virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); - goto cleanup; - } - - dname = args->dname == NULL ? NULL : *args->dname; - - if (!(stream = remoteCreateClientStream(conn, hdr))) { - virReportOOMError(); - goto cleanup; - } - - if (virDomainMigratePrepareTunnel3(conn, stream->st, - args->cookie_in.cookie_in_val, - args->cookie_in.cookie_in_len, - &cookieout, &cookieoutlen, - args->flags, dname, args->resource, - args->dom_xml) < 0) - goto cleanup; - - if (remoteAddClientStream(client, stream, 0) < 0) - goto cleanup; - - /* remoteDispatchClientRequest will free cookie - */ - ret->cookie_out.cookie_out_len = cookieoutlen; - ret->cookie_out.cookie_out_val = cookieout; - - rv = 0; - -cleanup: - if (rv < 0) { - remoteDispatchError(rerr); - VIR_FREE(cookieout); - } - if (stream && rv < 0) { - virStreamAbort(stream->st); - remoteFreeClientStream(client, stream); - } - return rv; -} - -static int remoteDispatchDomainMigratePerform3(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, diff --git a/daemon/remote_generator.pl b/daemon/remote_generator.pl index 8b3794f..c405dc8 100755 --- a/daemon/remote_generator.pl +++ b/daemon/remote_generator.pl @@ -43,7 +43,7 @@ sub name_to_ProcName { # Read the input file (usually remote_protocol.x) and form an # opinion about the name, args and return type of each RPC. -my ($name, $ProcName, $id, $flags, $gen, %calls, @calls); +my ($name, $ProcName, $id, $flags, %calls, @calls); # only generate a close method if -c was passed if ($opt_c) { @@ -135,19 +135,31 @@ while (<PROTOCOL>) { $ProcName = name_to_ProcName ($name); if ($opt_b or $opt_k) { - if (!($flags =~ m/^\s*\/\*\s*(\S+)\s+(\S+)\s*\*\/\s*$/)) { + if (!($flags =~ m/^\s*\/\*\s*(\S+)\s+(\S+)\s*(.*)\*\/\s*$/)) { die "invalid generator flags for ${procprefix}_PROC_${name}" } - $gen = $opt_b ? $1 : $2; + my $genmode = $opt_b ? $1 : $2; + my $genflags = $3; - if ($gen eq "autogen") { + if ($genmode eq "autogen") { push(@autogen, $ProcName); - } elsif ($gen eq "skipgen") { + } elsif ($genmode eq "skipgen") { # ignore it } else { die "invalid generator flags for ${procprefix}_PROC_${name}" } + + if (defined $genflags and $genflags ne "") { + if ($genflags =~ m/^\|\s*(read|write)stream@(\d+)\s*$/) { + $calls{$name}->{streamflag} = $1; + $calls{$name}->{streamoffset} = int($2); + } else { + die "invalid generator flags for ${procprefix}_PROC_${name}" + } + } else { + $calls{$name}->{streamflag} = "none"; + } } $calls[$id] = $calls{$name}; @@ -531,6 +543,18 @@ elsif ($opt_b) { } else { $single_ret_by_ref = 1; } + } elsif ($ret_member =~ m/^opaque (\S+)<(\S+)>;\s*\/\*\s*insert@(\d+)\s*\*\//) { + push(@vars_list, "char *$1 = NULL"); + push(@vars_list, "int $1_len = 0"); + splice(@args_list, int($3), 0, ("&$1", "&$1_len")); + push(@ret_list, "ret->$1.$1_val = $1;"); + push(@ret_list, "ret->$1.$1_len = $1_len;"); + push(@free_list_on_error, "VIR_FREE($1);"); + $single_ret_var = undef; + $single_ret_by_ref = 1; + } elsif ($ret_member =~ m/^opaque (\S+)<\S+>;/) { + # error out on unannotated arrays + die "opaque array without insert@<offset> annotation: $ret_member"; } elsif ($ret_member =~ m/^(\/)?\*/) { # ignore comments } else { @@ -569,6 +593,14 @@ elsif ($opt_b) { push(@vars_list, "vir$struct_name tmp"); } + if ($call->{streamflag} ne "none") { + splice(@args_list, $call->{streamoffset}, 0, ("stream->st")); + push(@free_list_on_error, "if (stream) {"); + push(@free_list_on_error, " virStreamAbort(stream->st);"); + push(@free_list_on_error, " remoteFreeClientStream(client, stream);"); + push(@free_list_on_error, "}"); + } + # print functions signature print "\n"; print "static int\n"; @@ -601,6 +633,10 @@ elsif ($opt_b) { print " $var;\n"; } + if ($call->{streamflag} ne "none") { + print " struct qemud_client_stream *stream = NULL;\n"; + } + print "\n"; print " if (!conn) {\n"; print " virNetError(VIR_ERR_INTERNAL_ERROR, \"%s\", _(\"connection not open\"));\n"; @@ -631,6 +667,12 @@ elsif ($opt_b) { print "\n"; } + if ($call->{streamflag} ne "none") { + print " if (!(stream = remoteCreateClientStream(conn, hdr)))\n"; + print " goto cleanup;\n"; + print "\n"; + } + if ($call->{ret} eq "void") { print " if (vir$call->{ProcName}("; print join(', ', @args_list); @@ -691,25 +733,30 @@ elsif ($opt_b) { print " goto cleanup;\n"; print "\n"; - - if (@ret_list) { - print " "; - } - - print join("\n ", @ret_list); - print "\n"; } else { print " if (vir$call->{ProcName}("; print join(', ', @args_list); print ") < 0)\n"; - print " goto cleanup;\n"; print "\n"; + } + + if ($call->{streamflag} ne "none") { + print " if (remoteAddClientStream(client, stream, "; - if (@ret_list) { - print " "; + if ($call->{streamflag} eq "write") { + print "0"; + } else { + print "1"; } + print ") < 0)\n"; + print " goto cleanup;\n"; + print "\n"; + } + + if (@ret_list) { + print " "; print join("\n ", @ret_list); print "\n"; } @@ -865,9 +912,14 @@ elsif ($opt_k) { } } - if ($call->{ProcName} eq "DomainMigrateSetMaxDowntime" and - $arg_name eq "downtime") { - $type_name = "unsigned long long"; + # SPECIAL: some hyper parameters map to long longs + if (($call->{ProcName} eq "DomainMigrateSetMaxDowntime" and + $arg_name eq "downtime") or + ($call->{ProcName} eq "StorageVolUpload" and + ($arg_name eq "offset" or $arg_name eq "length")) or + ($call->{ProcName} eq "StorageVolDownload" and + ($arg_name eq "offset" or $arg_name eq "length"))) { + $type_name .= " long"; } push(@args_list, "$type_name $arg_name"); @@ -1004,6 +1056,7 @@ elsif ($opt_k) { $single_ret_type = "int"; } elsif ($ret_member =~ m/^unsigned hyper (\S+);/) { my $arg_name = $1; + if ($call->{ProcName} =~ m/Get(Lib)?Version/) { push(@args_list, "unsigned long *$arg_name"); push(@ret_list, "if ($arg_name) *$arg_name = ret.$arg_name;"); @@ -1053,6 +1106,10 @@ elsif ($opt_k) { } } + if ($call->{streamflag} ne "none") { + splice(@args_list, $call->{streamoffset}, 0, ("virStreamPtr st")); + } + # print function print "\n"; print "static $single_ret_type\n"; @@ -1073,9 +1130,22 @@ elsif ($opt_k) { print " int i;\n"; } + if ($call->{streamflag} ne "none") { + print " struct private_stream_data *privst = NULL;\n"; + } + print "\n"; print " remoteDriverLock(priv);\n"; + if ($call->{streamflag} ne "none") { + print "\n"; + print " if (!(privst = remoteStreamOpen(st, REMOTE_PROC_$call->{UC_NAME}, priv->counter)))\n"; + print " goto done;\n"; + print "\n"; + print " st->driver = &remoteStreamDrv;\n"; + print " st->privateData = privst;\n"; + } + if ($call->{ProcName} eq "SupportsFeature") { # SPECIAL: VIR_DRV_FEATURE_REMOTE feature is handled directly print "\n"; @@ -1124,8 +1194,14 @@ elsif ($opt_k) { print "\n"; print " if (call($priv_src, priv, 0, ${procprefix}_PROC_$call->{UC_NAME},\n"; print " (xdrproc_t)xdr_$call->{args}, (char *)$call_args,\n"; - print " (xdrproc_t)xdr_$call->{ret}, (char *)$call_ret) == -1)\n"; + print " (xdrproc_t)xdr_$call->{ret}, (char *)$call_ret) == -1) {\n"; + + if ($call->{streamflag} ne "none") { + print " remoteStreamRelease(st);\n"; + } + print " goto done;\n"; + print " }\n"; print "\n"; if ($single_ret_as_list) { diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index fb542c5..3556b85 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -4607,48 +4607,6 @@ static virStreamDriver remoteStreamDrv = { .streamRemoveCallback = remoteStreamEventRemoveCallback, }; - -static int -remoteDomainMigratePrepareTunnel(virConnectPtr conn, - virStreamPtr st, - unsigned long flags, - const char *dname, - unsigned long resource, - const char *dom_xml) -{ - struct private_data *priv = conn->privateData; - struct private_stream_data *privst = NULL; - int rv = -1; - remote_domain_migrate_prepare_tunnel_args args; - - remoteDriverLock(priv); - - if (!(privst = remoteStreamOpen(st, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL, priv->counter))) - goto done; - - st->driver = &remoteStreamDrv; - st->privateData = privst; - - args.flags = flags; - args.dname = dname == NULL ? NULL : (char **) &dname; - args.resource = resource; - args.dom_xml = (char *) dom_xml; - - if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL, - (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel_args, (char *) &args, - (xdrproc_t) xdr_void, NULL) == -1) { - remoteStreamRelease(st); - goto done; - } - - rv = 0; - -done: - remoteDriverUnlock(priv); - - return rv; -} - static int remoteDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eventID, @@ -4743,171 +4701,6 @@ done: return rv; } -static char * -remoteDomainScreenshot (virDomainPtr domain, - virStreamPtr st, - unsigned int screen, - unsigned int flags) -{ - struct private_data *priv = domain->conn->privateData; - struct private_stream_data *privst = NULL; - remote_domain_screenshot_args args; - remote_domain_screenshot_ret ret; - char *rv = NULL; - - remoteDriverLock(priv); - - if (!(privst = remoteStreamOpen(st, - REMOTE_PROC_DOMAIN_SCREENSHOT, - priv->counter))) - goto done; - - st->driver = &remoteStreamDrv; - st->privateData = privst; - - make_nonnull_domain(&args.dom, domain); - args.flags = flags; - args.screen = screen; - - memset(&ret, 0, sizeof(ret)); - if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SCREENSHOT, - (xdrproc_t) xdr_remote_domain_screenshot_args, (char *) &args, - (xdrproc_t) xdr_remote_domain_screenshot_ret, (char *) &ret) == -1) - goto done; - - rv = ret.mime ? *ret.mime : NULL; - VIR_FREE(ret.mime); - -done: - remoteDriverUnlock(priv); - return rv; -} - -static int -remoteStorageVolUpload(virStorageVolPtr vol, - virStreamPtr st, - unsigned long long offset, - unsigned long long length, - unsigned int flags) -{ - struct private_data *priv = vol->conn->privateData; - struct private_stream_data *privst = NULL; - int rv = -1; - remote_storage_vol_upload_args args; - - remoteDriverLock(priv); - - if (!(privst = remoteStreamOpen(st, - REMOTE_PROC_STORAGE_VOL_UPLOAD, - priv->counter))) - goto done; - - st->driver = &remoteStreamDrv; - st->privateData = privst; - - make_nonnull_storage_vol(&args.vol, vol); - args.offset = offset; - args.length = length; - args.flags = flags; - - if (call (vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_UPLOAD, - (xdrproc_t) xdr_remote_storage_vol_upload_args, (char *) &args, - (xdrproc_t) xdr_void, NULL) == -1) { - remoteStreamRelease(st); - goto done; - } - - rv = 0; - -done: - remoteDriverUnlock(priv); - - return rv; -} - - -static int -remoteStorageVolDownload(virStorageVolPtr vol, - virStreamPtr st, - unsigned long long offset, - unsigned long long length, - unsigned int flags) -{ - struct private_data *priv = vol->conn->privateData; - struct private_stream_data *privst = NULL; - int rv = -1; - remote_storage_vol_download_args args; - - remoteDriverLock(priv); - - if (!(privst = remoteStreamOpen(st, - REMOTE_PROC_STORAGE_VOL_DOWNLOAD, - priv->counter))) - goto done; - - st->driver = &remoteStreamDrv; - st->privateData = privst; - - make_nonnull_storage_vol(&args.vol, vol); - args.offset = offset; - args.length = length; - args.flags = flags; - - if (call (vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_DOWNLOAD, - (xdrproc_t) xdr_remote_storage_vol_download_args, (char *) &args, - (xdrproc_t) xdr_void, NULL) == -1) { - remoteStreamRelease(st); - goto done; - } - - rv = 0; - -done: - remoteDriverUnlock(priv); - - return rv; -} - - -static int -remoteDomainOpenConsole(virDomainPtr dom, - const char *devname, - virStreamPtr st, - unsigned int flags) -{ - struct private_data *priv = dom->conn->privateData; - struct private_stream_data *privst = NULL; - int rv = -1; - remote_domain_open_console_args args; - - remoteDriverLock(priv); - - if (!(privst = remoteStreamOpen(st, REMOTE_PROC_DOMAIN_OPEN_CONSOLE, priv->counter))) - goto done; - - st->driver = &remoteStreamDrv; - st->privateData = privst; - - make_nonnull_domain (&args.dom, dom); - args.devname = devname ? (char **)&devname : NULL; - args.flags = flags; - - if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_OPEN_CONSOLE, - (xdrproc_t) xdr_remote_domain_open_console_args, (char *) &args, - (xdrproc_t) xdr_void, NULL) == -1) { - remoteStreamRelease(st); - goto done; - } - - rv = 0; - -done: - remoteDriverUnlock(priv); - - return rv; -} - - /*----------------------------------------------------------------------*/ static int diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 63f7ebb..5b9300a 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2054,7 +2054,14 @@ const REMOTE_PROTOCOL_VERSION = 1; enum remote_procedure { /* Each function must have a two-word comment. The first word is * whether remote_generator.pl handles daemon, the second whether - * it handles src/remote. */ + * it handles src/remote. Additional flags can be specified after a + * pipe. + * + * The (readstream|writestream)@<offset> flag lets daemon and src/remote + * create a stream. The direction is defined from the src/remote point + * of view. A readstream transfers data from daemon to src/remote. The + * <offset> specifies at which offset the stream parameter is inserted + * in the function parameter list. */ REMOTE_PROC_OPEN = 1, /* skipgen skipgen */ REMOTE_PROC_CLOSE = 2, /* skipgen skipgen */ REMOTE_PROC_GET_TYPE = 3, /* autogen skipgen */ @@ -2216,7 +2223,7 @@ enum remote_procedure { REMOTE_PROC_SECRET_GET_VALUE = 145, /* skipgen skipgen */ REMOTE_PROC_SECRET_UNDEFINE = 146, /* autogen autogen */ REMOTE_PROC_SECRET_LOOKUP_BY_USAGE = 147, /* autogen autogen */ - REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL = 148, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL = 148, /* autogen autogen | writestream@1 */ REMOTE_PROC_IS_SECURE = 149, /* autogen skipgen */ REMOTE_PROC_DOMAIN_IS_ACTIVE = 150, /* autogen autogen */ @@ -2275,35 +2282,40 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199, /* autogen autogen */ REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200, /* autogen autogen */ - REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, /* autogen autogen | readstream@2 */ REMOTE_PROC_DOMAIN_IS_UPDATED = 202, /* autogen autogen */ REMOTE_PROC_GET_SYSINFO = 203, /* autogen autogen */ REMOTE_PROC_DOMAIN_SET_MEMORY_FLAGS = 204, /* autogen autogen */ REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 205, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, /* autogen autogen */ - REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, /* skipgen skipgen */ - REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, /* skipgen skipgen */ + REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, /* autogen autogen | writestream@1 */ + REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, /* autogen autogen | readstream@1 */ REMOTE_PROC_DOMAIN_INJECT_NMI = 210, /* autogen autogen */ - REMOTE_PROC_DOMAIN_SCREENSHOT = 211, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_SCREENSHOT = 211, /* skipgen autogen | readstream@1 */ REMOTE_PROC_DOMAIN_GET_STATE = 212, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3 = 213, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3 = 214, /* skipgen skipgen */ - REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3 = 215, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3 = 215, /* autogen skipgen | writestream@1 */ REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3 = 216, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_FINISH3 = 217, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3 = 218, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS = 219 /* skipgen skipgen */ - /* - * Notice how the entries are grouped in sets of 10 ? + /* Notice how the entries are grouped in sets of 10 ? * Nice isn't it. Please keep it this way when adding more. - */ - - /* Each function must have a two-word comment. The first word is + * + * Each function must have a two-word comment. The first word is * whether remote_generator.pl handles daemon, the second whether - * it handles src/remote. */ + * it handles src/remote. Additional flags can be specified after a + * pipe. + * + * The (readstream|writestream)@<offset> flag lets daemon and src/remote + * create a stream. The direction is defined from the src/remote point + * of view. A readstream transfers data from daemon to src/remote. The + * <offset> specifies at which offset the stream parameter is inserted + * in the function parameter list. */ }; /* -- 1.7.0.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list