Add daemon and client code to serialize/deserialize
virDomainGetGuestInfo().
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
---
src/remote/remote_daemon_dispatch.c | 41 ++++++++++++++++++++++
src/remote/remote_driver.c | 53 +++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 21 +++++++++++-
src/remote_protocol-structs | 12 +++++++
4 files changed, 126 insertions(+), 1 deletion(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index 1bd281dd6d..665d938a99 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -7650,3 +7650,44 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
}
return -1;
}
+
+static int
+remoteDispatchDomainGetGuestInfo(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_domain_get_guest_info_args *args,
+ remote_domain_get_guest_info_ret *ret)
+{
+ int rv = -1;
+ struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+ virDomainPtr dom = NULL;
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+
+ if (!priv->conn) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+ goto cleanup;
+
+ if (virDomainGetGuestInfo(dom, args->types, ¶ms, &nparams, args->flags) < 0)
+ goto cleanup;
+
+ if (virTypedParamsSerialize(params, nparams,
+ (virTypedParameterRemotePtr *) &ret->params.params_val,
+ &ret->params.params_len,
+ VIR_TYPED_PARAM_STRING_OKAY) < 0)
+ goto cleanup;
+
+ rv = 0;
+
+ cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ virObjectUnref(dom);
+
+ return rv;
+}
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index daac506672..5ba144648a 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8306,6 +8306,58 @@ remoteNetworkPortGetParameters(virNetworkPortPtr port,
return rv;
}
+static int
+remoteDomainGetGuestInfo(virDomainPtr dom,
+ unsigned int types,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
+{
+ int rv = -1;
+ struct private_data *priv = dom->conn->privateData;
+ remote_domain_get_guest_info_args args;
+ remote_domain_get_guest_info_ret ret;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain(&args.dom, dom);
+
+ args.types = types;
+ args.flags = flags;
+
+ memset(&ret, 0, sizeof(ret));
+
+ if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_GUEST_INFO,
+ (xdrproc_t)xdr_remote_domain_get_guest_info_args, (char *)&args,
+ (xdrproc_t)xdr_remote_domain_get_guest_info_ret, (char *)&ret) == -1)
+ goto done;
+
+ if (ret.params.params_len > REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Too many params in guestinfo: %d for limit %d"),
+ ret.params.params_len, REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX);
+ goto cleanup;
+ }
+
+ if (params) {
+ if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
+ ret.params.params_len,
+ REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX,
+ params,
+ nparams) < 0)
+ goto cleanup;
+ }
+
+ rv = 0;
+
+ cleanup:
+ xdr_free((xdrproc_t)xdr_remote_domain_get_guest_info_ret,
+ (char *) &ret);
+
+ done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
@@ -8733,6 +8785,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainCheckpointLookupByName = remoteDomainCheckpointLookupByName, /* 5.6.0 */
.domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.6.0 */
.domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.6.0 */
+ .domainGetGuestInfo = remoteDomainGetGuestInfo, /* 5.6.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 118369e2b3..75c2bc69ff 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -269,6 +269,9 @@ const REMOTE_NODE_SEV_INFO_MAX = 64;
/* Upper limit on number of launch security information entries */
const REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX = 64;
+/* Upper limit on number of parameters describing a guest */
+const REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX = 2048;
+
/*
* Upper limit on list of network port parameters
*/
@@ -3723,6 +3726,16 @@ struct remote_domain_checkpoint_delete_args {
unsigned int flags;
};
+struct remote_domain_get_guest_info_args {
+ remote_nonnull_domain dom;
+ unsigned int types;
+ unsigned int flags;
+};
+
+struct remote_domain_get_guest_info_ret {
+ remote_typed_param params<REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX>;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -6584,5 +6597,11 @@ enum remote_procedure {
* @generate: both
* @acl: domain:checkpoint
*/
- REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417
+ REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417,
+
+ /**
+ * @generate: none
+ * @acl: domain:write
+ */
+ REMOTE_PROC_DOMAIN_GET_GUEST_INFO = 418
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index a42b4a9671..616c3d5d52 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -3105,6 +3105,17 @@ struct remote_domain_checkpoint_delete_args {
remote_nonnull_domain_checkpoint checkpoint;
u_int flags;
};
+struct remote_domain_get_guest_info_args {
+ remote_nonnull_domain dom;
+ u_int types;
+ u_int flags;
+};
+struct remote_domain_get_guest_info_ret {
+ struct {
+ u_int params_len;
+ remote_typed_param * params_val;
+ } params;
+};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3523,4 +3534,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME = 415,
REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT = 416,
REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417,
+ REMOTE_PROC_DOMAIN_GET_GUEST_INFO = 418,
};
--
2.21.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 8/23/19 6:31 PM, Jonathon Jongsma wrote: > Add daemon and client code to serialize/deserialize > virDomainGetGuestInfo(). > > Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> > --- > src/remote/remote_daemon_dispatch.c | 41 ++++++++++++++++++++++ > src/remote/remote_driver.c | 53 +++++++++++++++++++++++++++++ > src/remote/remote_protocol.x | 21 +++++++++++- > src/remote_protocol-structs | 12 +++++++ > 4 files changed, 126 insertions(+), 1 deletion(-) > > diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c > index 1bd281dd6d..665d938a99 100644 > --- a/src/remote/remote_daemon_dispatch.c > +++ b/src/remote/remote_daemon_dispatch.c > @@ -7650,3 +7650,44 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, > } > return -1; > } > + > +static int > +remoteDispatchDomainGetGuestInfo(virNetServerPtr server ATTRIBUTE_UNUSED, > + virNetServerClientPtr client, > + virNetMessagePtr msg ATTRIBUTE_UNUSED, > + virNetMessageErrorPtr rerr, > + remote_domain_get_guest_info_args *args, > + remote_domain_get_guest_info_ret *ret) > +{ > + int rv = -1; > + struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); We prefer remoteGetHypervisorConn() ... > + virDomainPtr dom = NULL; > + virTypedParameterPtr params = NULL; > + int nparams = 0; > + > + if (!priv->conn) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); .. which also reports an error. So no need to invent a new one. > + goto cleanup; > + } > + > + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) > + goto cleanup; > + > + if (virDomainGetGuestInfo(dom, args->types, ¶ms, &nparams, args->flags) < 0) > + goto cleanup; 1: here > + > + if (virTypedParamsSerialize(params, nparams, > + (virTypedParameterRemotePtr *) &ret->params.params_val, > + &ret->params.params_len, > + VIR_TYPED_PARAM_STRING_OKAY) < 0) > + goto cleanup; > + > + rv = 0; > + > + cleanup: > + if (rv < 0) > + virNetMessageSaveError(rerr); > + virObjectUnref(dom); You need to free @params here. > + > + return rv; > +} > diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c > index daac506672..5ba144648a 100644 > --- a/src/remote/remote_driver.c > +++ b/src/remote/remote_driver.c > @@ -8306,6 +8306,58 @@ remoteNetworkPortGetParameters(virNetworkPortPtr port, > return rv; > } > > +static int > +remoteDomainGetGuestInfo(virDomainPtr dom, > + unsigned int types, > + virTypedParameterPtr *params, > + int *nparams, > + unsigned int flags) > +{ > + int rv = -1; > + struct private_data *priv = dom->conn->privateData; > + remote_domain_get_guest_info_args args; > + remote_domain_get_guest_info_ret ret; > + > + remoteDriverLock(priv); > + > + make_nonnull_domain(&args.dom, dom); > + > + args.types = types; > + args.flags = flags; > + > + memset(&ret, 0, sizeof(ret)); > + > + if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_GUEST_INFO, > + (xdrproc_t)xdr_remote_domain_get_guest_info_args, (char *)&args, > + (xdrproc_t)xdr_remote_domain_get_guest_info_ret, (char *)&ret) == -1) > + goto done; > + > + if (ret.params.params_len > REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Too many params in guestinfo: %d for limit %d"), > + ret.params.params_len, REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX); > + goto cleanup; > + } No need to check for this here. It's checked for in virTypedParamsDeserialize(). That's why you need to pass _MAX argument. In fact, the check should go to [1]. > + > + if (params) { The @params can't be NULL here, can they? I mean, in the public API you check for: virCheckNonNullArgGoto(params, error); But I agree that our RPC infrastructure is complicated and it's not easy to understand it at the first glance. Basically, it works like this: at client side on virConnectOpen() the conn->driver is initialized to remote driver (@hypervisor_driver from remote_driver.c). So calling any public API ends up calling the callback from remote_driver.c (remoteDomainGetGuestInfo() in this case). That is the reason why these callbacks in remote driver need to look exactly like the public APIs (and hence you need to create typedef for every public API). In the end, these callbacks do mere arg serialization and reply deserialization. On server, things are a bit different. We have a code which deserializes incoming RPC packet and then we have this huge array of pairs PROC_NR + dispatch callback (look at the end of src/remote/remote_daemon_dispatch_stubs.h you'll find the array there). Yeah, yeah, it's not list of pairs, rather than tuples, but for our case we can safely ignore the other members of the tuple. So, after server has decoded the incoming RPC it learned what procedure the client wants to call and thus it calls the associated callback (remoteDispatchDomainGetGuestInfoHelper() in this case). And this callback will then call the public API again, but this time conn->driver points to actual driver (qemu driver from instance). It is only here where all the interesting work is done. It's more or less documented here: https://libvirt.org/api.html https://libvirt.org/internals/rpc.html https://libvirt.org/api_extension.html (looks like you've followed this one) Please let me know if you want me to expand on something. > + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val, > + ret.params.params_len, > + REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX, > + params, > + nparams) < 0) > + goto cleanup; > + } > + > + rv = 0; > + > + cleanup: > + xdr_free((xdrproc_t)xdr_remote_domain_get_guest_info_ret, > + (char *) &ret); > + > + done: > + remoteDriverUnlock(priv); > + return rv; > +} > > /* get_nonnull_domain and get_nonnull_network turn an on-wire > * (name, uuid) pair into virDomainPtr or virNetworkPtr object. > @@ -8733,6 +8785,7 @@ static virHypervisorDriver hypervisor_driver = { > .domainCheckpointLookupByName = remoteDomainCheckpointLookupByName, /* 5.6.0 */ > .domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.6.0 */ > .domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.6.0 */ > + .domainGetGuestInfo = remoteDomainGetGuestInfo, /* 5.6.0 */ Ooops, s/6/7/ :D Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 8/23/19 1:31 PM, Jonathon Jongsma wrote: > Add daemon and client code to serialize/deserialize > virDomainGetGuestInfo(). > > Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> > --- Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com> > src/remote/remote_daemon_dispatch.c | 41 ++++++++++++++++++++++ > src/remote/remote_driver.c | 53 +++++++++++++++++++++++++++++ > src/remote/remote_protocol.x | 21 +++++++++++- > src/remote_protocol-structs | 12 +++++++ > 4 files changed, 126 insertions(+), 1 deletion(-) > > diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c > index 1bd281dd6d..665d938a99 100644 > --- a/src/remote/remote_daemon_dispatch.c > +++ b/src/remote/remote_daemon_dispatch.c > @@ -7650,3 +7650,44 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, > } > return -1; > } > + > +static int > +remoteDispatchDomainGetGuestInfo(virNetServerPtr server ATTRIBUTE_UNUSED, > + virNetServerClientPtr client, > + virNetMessagePtr msg ATTRIBUTE_UNUSED, > + virNetMessageErrorPtr rerr, > + remote_domain_get_guest_info_args *args, > + remote_domain_get_guest_info_ret *ret) > +{ > + int rv = -1; > + struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); > + virDomainPtr dom = NULL; > + virTypedParameterPtr params = NULL; > + int nparams = 0; > + > + if (!priv->conn) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); > + goto cleanup; > + } > + > + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) > + goto cleanup; > + > + if (virDomainGetGuestInfo(dom, args->types, ¶ms, &nparams, args->flags) < 0) > + goto cleanup; > + > + if (virTypedParamsSerialize(params, nparams, > + (virTypedParameterRemotePtr *) &ret->params.params_val, > + &ret->params.params_len, > + VIR_TYPED_PARAM_STRING_OKAY) < 0) > + goto cleanup; > + > + rv = 0; > + > + cleanup: > + if (rv < 0) > + virNetMessageSaveError(rerr); > + virObjectUnref(dom); > + > + return rv; > +} > diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c > index daac506672..5ba144648a 100644 > --- a/src/remote/remote_driver.c > +++ b/src/remote/remote_driver.c > @@ -8306,6 +8306,58 @@ remoteNetworkPortGetParameters(virNetworkPortPtr port, > return rv; > } > > +static int > +remoteDomainGetGuestInfo(virDomainPtr dom, > + unsigned int types, > + virTypedParameterPtr *params, > + int *nparams, > + unsigned int flags) > +{ > + int rv = -1; > + struct private_data *priv = dom->conn->privateData; > + remote_domain_get_guest_info_args args; > + remote_domain_get_guest_info_ret ret; > + > + remoteDriverLock(priv); > + > + make_nonnull_domain(&args.dom, dom); > + > + args.types = types; > + args.flags = flags; > + > + memset(&ret, 0, sizeof(ret)); > + > + if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_GUEST_INFO, > + (xdrproc_t)xdr_remote_domain_get_guest_info_args, (char *)&args, > + (xdrproc_t)xdr_remote_domain_get_guest_info_ret, (char *)&ret) == -1) > + goto done; > + > + if (ret.params.params_len > REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Too many params in guestinfo: %d for limit %d"), > + ret.params.params_len, REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX); > + goto cleanup; > + } > + > + if (params) { > + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val, > + ret.params.params_len, > + REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX, > + params, > + nparams) < 0) > + goto cleanup; > + } > + > + rv = 0; > + > + cleanup: > + xdr_free((xdrproc_t)xdr_remote_domain_get_guest_info_ret, > + (char *) &ret); > + > + done: > + remoteDriverUnlock(priv); > + return rv; > +} > > /* get_nonnull_domain and get_nonnull_network turn an on-wire > * (name, uuid) pair into virDomainPtr or virNetworkPtr object. > @@ -8733,6 +8785,7 @@ static virHypervisorDriver hypervisor_driver = { > .domainCheckpointLookupByName = remoteDomainCheckpointLookupByName, /* 5.6.0 */ > .domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.6.0 */ > .domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.6.0 */ > + .domainGetGuestInfo = remoteDomainGetGuestInfo, /* 5.6.0 */ > }; > > static virNetworkDriver network_driver = { > diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x > index 118369e2b3..75c2bc69ff 100644 > --- a/src/remote/remote_protocol.x > +++ b/src/remote/remote_protocol.x > @@ -269,6 +269,9 @@ const REMOTE_NODE_SEV_INFO_MAX = 64; > /* Upper limit on number of launch security information entries */ > const REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX = 64; > > +/* Upper limit on number of parameters describing a guest */ > +const REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX = 2048; > + > /* > * Upper limit on list of network port parameters > */ > @@ -3723,6 +3726,16 @@ struct remote_domain_checkpoint_delete_args { > unsigned int flags; > }; > > +struct remote_domain_get_guest_info_args { > + remote_nonnull_domain dom; > + unsigned int types; > + unsigned int flags; > +}; > + > +struct remote_domain_get_guest_info_ret { > + remote_typed_param params<REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX>; > +}; > + > /*----- Protocol. -----*/ > > /* Define the program number, protocol version and procedure numbers here. */ > @@ -6584,5 +6597,11 @@ enum remote_procedure { > * @generate: both > * @acl: domain:checkpoint > */ > - REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417 > + REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417, > + > + /** > + * @generate: none > + * @acl: domain:write > + */ > + REMOTE_PROC_DOMAIN_GET_GUEST_INFO = 418 > }; > diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs > index a42b4a9671..616c3d5d52 100644 > --- a/src/remote_protocol-structs > +++ b/src/remote_protocol-structs > @@ -3105,6 +3105,17 @@ struct remote_domain_checkpoint_delete_args { > remote_nonnull_domain_checkpoint checkpoint; > u_int flags; > }; > +struct remote_domain_get_guest_info_args { > + remote_nonnull_domain dom; > + u_int types; > + u_int flags; > +}; > +struct remote_domain_get_guest_info_ret { > + struct { > + u_int params_len; > + remote_typed_param * params_val; > + } params; > +}; > enum remote_procedure { > REMOTE_PROC_CONNECT_OPEN = 1, > REMOTE_PROC_CONNECT_CLOSE = 2, > @@ -3523,4 +3534,5 @@ enum remote_procedure { > REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME = 415, > REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT = 416, > REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417, > + REMOTE_PROC_DOMAIN_GET_GUEST_INFO = 418, > }; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2024 Red Hat, Inc.