This patch implements the remote protocol to address the new API (virDomainGetVcpupinInfo). Signed-off-by: Taku Izumi <izumi.taku@xxxxxxxxxxxxxx> --- daemon/remote.c | 68 ++++++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 73 +++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 15 ++++++++ src/remote_protocol-structs | 13 +++++++ 4 files changed, 168 insertions(+), 1 deletion(-) Index: libvirt/src/remote/remote_protocol.x =================================================================== --- libvirt.orig/src/remote/remote_protocol.x +++ libvirt/src/remote/remote_protocol.x @@ -903,6 +903,18 @@ struct remote_domain_pin_vcpu_flags_args unsigned int flags; }; +struct remote_domain_get_vcpupin_info_args { + remote_nonnull_domain dom; + int maxinfo; + int maplen; + unsigned int flags; +}; + +struct remote_domain_get_vcpupin_info_ret { + opaque cpumaps<REMOTE_CPUMAPS_MAX>; + int num; +}; + struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo; @@ -2425,7 +2437,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_BLOCK_PULL_ABORT = 231, /* autogen autogen */ REMOTE_PROC_DOMAIN_GET_BLOCK_PULL_INFO = 232, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_BLOCK_PULL = 233, /* skipgen skipgen */ - REMOTE_PROC_DOMAIN_GET_CONTROL_INFO = 234 /* autogen autogen */ + REMOTE_PROC_DOMAIN_GET_CONTROL_INFO = 234, /* autogen autogen */ + REMOTE_PROC_DOMAIN_GET_VCPUPIN_INFO = 235 /* skipgen skipgen */ /* * Notice how the entries are grouped in sets of 10 ? Index: libvirt/src/remote/remote_driver.c =================================================================== --- libvirt.orig/src/remote/remote_driver.c +++ libvirt/src/remote/remote_driver.c @@ -2141,6 +2141,78 @@ done: } static int +remoteDomainGetVcpupinInfo (virDomainPtr domain, + int maxinfo, + unsigned char *cpumaps, + int maplen, + unsigned int flags) +{ + int rv = -1; + int i; + remote_domain_get_vcpupin_info_args args; + remote_domain_get_vcpupin_info_ret ret; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + if (maxinfo > REMOTE_VCPUINFO_MAX) { + remoteError(VIR_ERR_RPC, + _("vCPU count exceeds maximum: %d > %d"), + maxinfo, REMOTE_VCPUINFO_MAX); + goto done; + } + + if (maxinfo * maplen > REMOTE_CPUMAPS_MAX) { + remoteError(VIR_ERR_RPC, + _("vCPU map buffer length exceeds maximum: %d > %d"), + maxinfo * maplen, REMOTE_CPUMAPS_MAX); + goto done; + } + + make_nonnull_domain (&args.dom, domain); + args.maxinfo = maxinfo; + args.maplen = maplen; + args.flags = flags; + + memset (&ret, 0, sizeof ret); + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUPIN_INFO, + (xdrproc_t) xdr_remote_domain_get_vcpupin_info_args, + (char *) &args, + (xdrproc_t) xdr_remote_domain_get_vcpupin_info_ret, + (char *) &ret) == -1) + goto done; + + if (ret.num > maxinfo) { + remoteError(VIR_ERR_RPC, + _("host reports too many vCPUs: %d > %d"), + ret.num, maxinfo); + goto cleanup; + } + + if (ret.cpumaps.cpumaps_len > maxinfo * maplen) { + remoteError(VIR_ERR_RPC, + _("host reports map buffer length exceeds maximum: %d > %d"), + ret.cpumaps.cpumaps_len, maxinfo * maplen); + goto cleanup; + } + + memset (cpumaps, 0, maxinfo * maplen); + + for (i = 0; i < ret.cpumaps.cpumaps_len; ++i) + cpumaps[i] = ret.cpumaps.cpumaps_val[i]; + + rv = ret.num; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpupin_info_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainGetVcpus (virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, @@ -6452,6 +6524,7 @@ static virDriver remote_driver = { .domainGetVcpusFlags = remoteDomainGetVcpusFlags, /* 0.8.5 */ .domainPinVcpu = remoteDomainPinVcpu, /* 0.3.0 */ .domainPinVcpuFlags = remoteDomainPinVcpuFlags, /* 0.9.3 */ + .domainGetVcpupinInfo = remoteDomainGetVcpupinInfo, /* 0.9.3 */ .domainGetVcpus = remoteDomainGetVcpus, /* 0.3.0 */ .domainGetMaxVcpus = remoteDomainGetMaxVcpus, /* 0.3.0 */ .domainGetSecurityLabel = remoteDomainGetSecurityLabel, /* 0.6.1 */ Index: libvirt/src/remote_protocol-structs =================================================================== --- libvirt.orig/src/remote_protocol-structs +++ libvirt/src/remote_protocol-structs @@ -580,6 +580,19 @@ struct remote_domain_pin_vcpu_flags_args } cpumap; u_int flags; }; +struct remote_domain_get_vcpupin_info_args { + remote_nonnull_domain dom; + int maxinfo; + int maplen; + u_int flags; +}; +struct remote_domain_get_vcpupin_info_ret { + struct { + u_int cpumaps_len; + char * cpumaps_val; + } cpumaps; + int num; +}; struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo; Index: libvirt/daemon/remote.c =================================================================== --- libvirt.orig/daemon/remote.c +++ libvirt/daemon/remote.c @@ -1079,6 +1079,74 @@ cleanup: } static int +remoteDispatchDomainGetVcpupinInfo(struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_get_vcpupin_info_args *args, + remote_domain_get_vcpupin_info_ret *ret) +{ + virDomainPtr dom = NULL; + unsigned char *cpumaps = NULL; + int num; + 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 (args->maxinfo > REMOTE_VCPUINFO_MAX) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo > REMOTE_VCPUINFO_MAX")); + goto cleanup; + } + + if (args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX")); + goto cleanup; + } + + /* Allocate buffers to take the results. */ + if (args->maplen > 0 && + VIR_ALLOC_N(cpumaps, args->maxinfo * args->maplen) < 0) + goto no_memory; + + if ((num = virDomainGetVcpupinInfo(dom, + args->maxinfo, + cpumaps, + args->maplen, + args->flags)) < 0) + goto cleanup; + + ret->num = num; + /* Don't need to allocate/copy the cpumaps if we make the reasonabl + * assumption that unsigned char and char are the same size. + * Note that remoteDispatchClientRequest will free. + */ + ret->cpumaps.cpumaps_len = args->maxinfo * args->maplen; + ret->cpumaps.cpumaps_val = (char *) cpumaps; + cpumaps = NULL; + + rv = 0; + +cleanup: + if (rv < 0) + remoteDispatchError(rerr); + VIR_FREE(cpumaps); + if (dom) + virDomainFree(dom); + return rv; + +no_memory: + virReportOOMError(); + goto cleanup; +} + +static int remoteDispatchDomainGetVcpus(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list