mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-24 06:03:52 +03:00
Defines the basics of a generic RPC protocol in XDR
This patch defines the basics of a generic RPC protocol in XDR. This is wire ABI compatible with the original remote_protocol.x. It takes everything except for the RPC calls / events from that protocol - The basic header virNetMessageHeader (aka remote_message_header) - The error object virNetMessageError (aka remote_error) - Two dummy objects virNetMessageDomain & virNetMessageNetwork sadly needed to keep virNetMessageError ABI compatible with the old remote_error The RPC protocol supports method calls, async events and bidirectional data streams as before * src/Makefile.am: Add rules for generating RPC code from protocol & define a new libvirt-net-rpc.la helper library * src/rpc/virnetprotocol.x: New generic RPC protocol
This commit is contained in:
parent
178bab1c53
commit
980a132a24
1
.gitignore
vendored
1
.gitignore
vendored
@ -53,6 +53,7 @@
|
|||||||
/src/libvirt_iohelper
|
/src/libvirt_iohelper
|
||||||
/src/remote/*_client_bodies.h
|
/src/remote/*_client_bodies.h
|
||||||
/src/remote/*_protocol.[ch]
|
/src/remote/*_protocol.[ch]
|
||||||
|
/src/rpc/virnetprotocol.[ch]
|
||||||
/tests/*.log
|
/tests/*.log
|
||||||
/tests/cputest
|
/tests/cputest
|
||||||
/tests/hashtest
|
/tests/hashtest
|
||||||
|
@ -571,13 +571,11 @@ $(srcdir)/remote/remote_driver.c: $(REMOTE_DRIVER_GENERATED)
|
|||||||
|
|
||||||
endif WITH_REMOTE
|
endif WITH_REMOTE
|
||||||
|
|
||||||
$(srcdir)/remote/%_protocol.c: $(srcdir)/remote/%_protocol.x \
|
%protocol.c: %protocol.x %protocol.h $(srcdir)/remote/rpcgen_fix.pl
|
||||||
$(srcdir)/remote/%_protocol.h $(srcdir)/remote/rpcgen_fix.pl
|
|
||||||
$(AM_V_GEN)perl -w $(srcdir)/remote/rpcgen_fix.pl $(RPCGEN) -c \
|
$(AM_V_GEN)perl -w $(srcdir)/remote/rpcgen_fix.pl $(RPCGEN) -c \
|
||||||
$< $@
|
$< $@
|
||||||
|
|
||||||
$(srcdir)/remote/%_protocol.h: $(srcdir)/remote/%_protocol.x \
|
%protocol.h: %protocol.x $(srcdir)/remote/rpcgen_fix.pl
|
||||||
$(srcdir)/remote/rpcgen_fix.pl
|
|
||||||
$(AM_V_GEN)perl -w $(srcdir)/remote/rpcgen_fix.pl $(RPCGEN) -h \
|
$(AM_V_GEN)perl -w $(srcdir)/remote/rpcgen_fix.pl $(RPCGEN) -h \
|
||||||
$< $@
|
$< $@
|
||||||
|
|
||||||
@ -1190,6 +1188,19 @@ else
|
|||||||
EXTRA_DIST += $(LOCK_DRIVER_SANLOCK_SOURCES)
|
EXTRA_DIST += $(LOCK_DRIVER_SANLOCK_SOURCES)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES += libvirt-net-rpc.la
|
||||||
|
|
||||||
|
libvirt_net_rpc_la_SOURCES = \
|
||||||
|
rpc/virnetprotocol.h rpc/virnetprotocol.c
|
||||||
|
libvirt_net_rpc_la_CFLAGS = \
|
||||||
|
$(AM_CFLAGS)
|
||||||
|
libvirt_net_rpc_la_LDFLAGS = \
|
||||||
|
$(AM_LDFLAGS) \
|
||||||
|
$(CYGWIN_EXTRA_LDFLAGS) \
|
||||||
|
$(MINGW_EXTRA_LDFLAGS)
|
||||||
|
libvirt_net_rpc_la_LIBADD = \
|
||||||
|
$(CYGWIN_EXTRA_LIBADD)
|
||||||
|
|
||||||
libexec_PROGRAMS =
|
libexec_PROGRAMS =
|
||||||
|
|
||||||
if WITH_LIBVIRTD
|
if WITH_LIBVIRTD
|
||||||
|
217
src/rpc/virnetprotocol.x
Normal file
217
src/rpc/virnetprotocol.x
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/* -*- c -*-
|
||||||
|
* virnetprotocol.x: basic protocol for all RPC services.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Author: Richard Jones <rjones@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
%#include "internal.h"
|
||||||
|
%#include <arpa/inet.h>
|
||||||
|
|
||||||
|
/* cygwin's xdr implementation defines xdr_u_int64_t instead of xdr_uint64_t
|
||||||
|
* and lacks IXDR_PUT_INT32 and IXDR_GET_INT32
|
||||||
|
*/
|
||||||
|
%#ifdef HAVE_XDR_U_INT64_T
|
||||||
|
%# define xdr_uint64_t xdr_u_int64_t
|
||||||
|
%#endif
|
||||||
|
%#ifndef IXDR_PUT_INT32
|
||||||
|
%# define IXDR_PUT_INT32 IXDR_PUT_LONG
|
||||||
|
%#endif
|
||||||
|
%#ifndef IXDR_GET_INT32
|
||||||
|
%# define IXDR_GET_INT32 IXDR_GET_LONG
|
||||||
|
%#endif
|
||||||
|
%#ifndef IXDR_PUT_U_INT32
|
||||||
|
%# define IXDR_PUT_U_INT32 IXDR_PUT_U_LONG
|
||||||
|
%#endif
|
||||||
|
%#ifndef IXDR_GET_U_INT32
|
||||||
|
%# define IXDR_GET_U_INT32 IXDR_GET_U_LONG
|
||||||
|
%#endif
|
||||||
|
|
||||||
|
/*----- Data types. -----*/
|
||||||
|
|
||||||
|
/* Maximum total message size (serialised). */
|
||||||
|
const VIR_NET_MESSAGE_MAX = 262144;
|
||||||
|
|
||||||
|
/* Size of struct virNetMessageHeader (serialised)*/
|
||||||
|
const VIR_NET_MESSAGE_HEADER_MAX = 24;
|
||||||
|
|
||||||
|
/* Size of message payload */
|
||||||
|
const VIR_NET_MESSAGE_PAYLOAD_MAX = 262120;
|
||||||
|
|
||||||
|
/* Size of message length field. Not counted in VIR_NET_MESSAGE_MAX */
|
||||||
|
const VIR_NET_MESSAGE_LEN_MAX = 4;
|
||||||
|
|
||||||
|
/* Length of long, but not unbounded, strings.
|
||||||
|
* This is an arbitrary limit designed to stop the decoder from trying
|
||||||
|
* to allocate unbounded amounts of memory when fed with a bad message.
|
||||||
|
*/
|
||||||
|
const VIR_NET_MESSAGE_STRING_MAX = 65536;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RPC wire format
|
||||||
|
*
|
||||||
|
* Each message consists of:
|
||||||
|
*
|
||||||
|
* Name | Type | Description
|
||||||
|
* -----------+-----------------------+------------------
|
||||||
|
* Length | int | Total number of bytes in message _including_ length.
|
||||||
|
* Header | virNetMessageHeader | Control information about procedure call
|
||||||
|
* Payload | - | Variable payload data per procedure
|
||||||
|
*
|
||||||
|
* In header, the 'serial' field varies according to:
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_CALL
|
||||||
|
* * serial is set by client, incrementing by 1 each time
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_REPLY
|
||||||
|
* * serial matches that from the corresponding VIR_NET_CALL
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_MESSAGE
|
||||||
|
* * serial is always zero
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_STREAM
|
||||||
|
* * serial matches that from the corresponding VIR_NET_CALL
|
||||||
|
*
|
||||||
|
* and the 'status' field varies according to:
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_CALL
|
||||||
|
* * VIR_NET_OK always
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_REPLY
|
||||||
|
* * VIR_NET_OK if RPC finished successfully
|
||||||
|
* * VIR_NET_ERROR if something failed
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_MESSAGE
|
||||||
|
* * VIR_NET_OK always
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_STREAM
|
||||||
|
* * VIR_NET_CONTINUE if more data is following
|
||||||
|
* * VIR_NET_OK if stream is complete
|
||||||
|
* * VIR_NET_ERROR if stream had an error
|
||||||
|
*
|
||||||
|
* Payload varies according to type and status:
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_CALL
|
||||||
|
* XXX_args for procedure
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_REPLY
|
||||||
|
* * status == VIR_NET_OK
|
||||||
|
* XXX_ret for procedure
|
||||||
|
* * status == VIR_NET_ERROR
|
||||||
|
* remote_error Error information
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_MESSAGE
|
||||||
|
* * status == VIR_NET_OK
|
||||||
|
* XXX_msg for event information
|
||||||
|
*
|
||||||
|
* - type == VIR_NET_STREAM
|
||||||
|
* * status == VIR_NET_CONTINUE
|
||||||
|
* byte[] raw stream data
|
||||||
|
* * status == VIR_NET_ERROR
|
||||||
|
* remote_error error information
|
||||||
|
* * status == VIR_NET_OK
|
||||||
|
* <empty>
|
||||||
|
*/
|
||||||
|
enum virNetMessageType {
|
||||||
|
/* client -> server. args from a method call */
|
||||||
|
VIR_NET_CALL = 0,
|
||||||
|
/* server -> client. reply/error from a method call */
|
||||||
|
VIR_NET_REPLY = 1,
|
||||||
|
/* either direction. async notification */
|
||||||
|
VIR_NET_MESSAGE = 2,
|
||||||
|
/* either direction. stream data packet */
|
||||||
|
VIR_NET_STREAM = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum virNetMessageStatus {
|
||||||
|
/* Status is always VIR_NET_OK for calls.
|
||||||
|
* For replies, indicates no error.
|
||||||
|
*/
|
||||||
|
VIR_NET_OK = 0,
|
||||||
|
|
||||||
|
/* For replies, indicates that an error happened, and a struct
|
||||||
|
* remote_error follows.
|
||||||
|
*/
|
||||||
|
VIR_NET_ERROR = 1,
|
||||||
|
|
||||||
|
/* For streams, indicates that more data is still expected
|
||||||
|
*/
|
||||||
|
VIR_NET_CONTINUE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 4 byte length word per header */
|
||||||
|
const VIR_NET_MESSAGE_HEADER_XDR_LEN = 4;
|
||||||
|
|
||||||
|
struct virNetMessageHeader {
|
||||||
|
unsigned prog; /* Unique ID for the program */
|
||||||
|
unsigned vers; /* Program version number */
|
||||||
|
int proc; /* Unique ID for the procedure within the program */
|
||||||
|
virNetMessageType type; /* Type of message */
|
||||||
|
unsigned serial; /* Serial number of message. */
|
||||||
|
virNetMessageStatus status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Error message. See <virterror.h> for explanation of fields. */
|
||||||
|
|
||||||
|
/* Most of these don't really belong here. There are sadly needed
|
||||||
|
* for wire ABI backwards compatibility with the rather crazy
|
||||||
|
* error struct we previously defined :-(
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef opaque virNetMessageUUID[VIR_UUID_BUFLEN];
|
||||||
|
typedef string virNetMessageNonnullString<VIR_NET_MESSAGE_STRING_MAX>;
|
||||||
|
|
||||||
|
/* A long string, which may be NULL. */
|
||||||
|
typedef virNetMessageNonnullString *virNetMessageString;
|
||||||
|
|
||||||
|
/* A domain which may not be NULL. */
|
||||||
|
struct virNetMessageNonnullDomain {
|
||||||
|
virNetMessageNonnullString name;
|
||||||
|
virNetMessageUUID uuid;
|
||||||
|
int id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A network which may not be NULL. */
|
||||||
|
struct virNetMessageNonnullNetwork {
|
||||||
|
virNetMessageNonnullString name;
|
||||||
|
virNetMessageUUID uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef virNetMessageNonnullDomain *virNetMessageDomain;
|
||||||
|
typedef virNetMessageNonnullNetwork *virNetMessageNetwork;
|
||||||
|
|
||||||
|
/* NB. Fields "code", "domain" and "level" are really enums. The
|
||||||
|
* numeric value should remain compatible between libvirt and
|
||||||
|
* libvirtd. This means, no changing or reordering the enums as
|
||||||
|
* defined in <virterror.h> (but we don't do that anyway, for separate
|
||||||
|
* ABI reasons).
|
||||||
|
*/
|
||||||
|
struct virNetMessageError {
|
||||||
|
int code;
|
||||||
|
int domain;
|
||||||
|
virNetMessageString message;
|
||||||
|
int level;
|
||||||
|
virNetMessageDomain dom; /* unused */
|
||||||
|
virNetMessageString str1;
|
||||||
|
virNetMessageString str2;
|
||||||
|
virNetMessageString str3;
|
||||||
|
int int1;
|
||||||
|
int int2;
|
||||||
|
virNetMessageNetwork net; /* unused */
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user