From 9172d0ec2734ea40d1dacf70305762fb4335f836 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 11 Jun 2007 12:04:54 +0000 Subject: [PATCH] Mon Jun 11 12:49:00 BST 2007 Richard W.M. Jones * qemud/Makefile.am, qemud/dispatch.c, qemud/dispatch.h, qemud/internal.h, qemud/protocol.c, qemud/protocol.h, qemud/protocol.x, qemud/qemud.c: libvirt_qemud server-side modifications to use XDR-based protocol instead of homebrew (Dan Berrange). QEMUD server modified to dispatch calls from remote clients (Richard Jones). Added TLS support (Richard Jones). Added TCP & IPv6 support (Richard Jones). Additional configuration file, command-line handling, and usage (Richard Jones). * qemud/conf.c: Remove unnecessary header file. --- ChangeLog | 14 + qemud/Makefile.am | 51 +- qemud/conf.c | 1 - qemud/dispatch.c | 536 +++++++----------- qemud/dispatch.h | 2 +- qemud/internal.h | 65 ++- qemud/protocol.c | 969 ++++++++++++++++++++++++++++++++ qemud/protocol.h | 939 +++++++++++++++++++++---------- qemud/protocol.x | 614 ++++++++++++++++++++ qemud/qemud.c | 1356 ++++++++++++++++++++++++++++++++++++++------- 10 files changed, 3664 insertions(+), 883 deletions(-) create mode 100644 qemud/protocol.c create mode 100644 qemud/protocol.x diff --git a/ChangeLog b/ChangeLog index 869c4da1dc..32bffa8a51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Mon Jun 11 12:49:00 BST 2007 Richard W.M. Jones + + * qemud/Makefile.am, qemud/dispatch.c, qemud/dispatch.h, + qemud/internal.h, qemud/protocol.c, + qemud/protocol.h, qemud/protocol.x, qemud/qemud.c: + libvirt_qemud server-side modifications to use + XDR-based protocol instead of homebrew (Dan Berrange). + QEMUD server modified to dispatch calls from remote + clients (Richard Jones). Added TLS support (Richard Jones). + Added TCP & IPv6 support (Richard Jones). + Additional configuration file, command-line handling, and + usage (Richard Jones). + * qemud/conf.c: Remove unnecessary header file. + Mon Jun 11 12:48:00 BST 2007 Richard W.M. Jones * src/qemu_internal.c: QEMU client-side modifications to diff --git a/qemud/Makefile.am b/qemud/Makefile.am index d2dbc80caa..09c09594d6 100644 --- a/qemud/Makefile.am +++ b/qemud/Makefile.am @@ -5,23 +5,28 @@ UUID=$(shell uuidgen) sbin_PROGRAMS = libvirt_qemud -libvirt_qemud_SOURCES = qemud.c internal.h protocol.h \ +libvirt_qemud_SOURCES = \ + qemud.c internal.h \ driver.c driver.h \ dispatch.c dispatch.h \ conf.c conf.h \ bridge.c bridge.h \ iptables.c iptables.h \ uuid.c uuid.h \ - buf.c buf.h + buf.c buf.h \ + protocol.h protocol.c \ + remote_protocol.h remote_protocol.c \ + remote.c #-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L libvirt_qemud_CFLAGS = \ -I$(top_srcdir)/include -I$(top_builddir)/include $(LIBXML_CFLAGS) \ $(WARN_CFLAGS) -DLOCAL_STATE_DIR="\"$(localstatedir)\"" \ -DSYSCONF_DIR="\"$(sysconfdir)\"" \ - -DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" + -DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" \ + -DREMOTE_PID_FILE="\"$(REMOTE_PID_FILE)\"" libvirt_qemud_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS) $(SYSFS_LIBS) -libvirt_qemud_DEPENDENCIES = -libvirt_qemud_LDADD = +libvirt_qemud_DEPENDENCIES = ../src/libvirt.la +libvirt_qemud_LDADD = ../src/libvirt.la install-data-local: mkdir -p $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart @@ -41,7 +46,41 @@ uninstall-local: rmdir $(DESTDIR)$(localstatedir)/run/libvirt || : rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || : -EXTRA_DIST = libvirtd.in default-network.xml +# Distribute the generated files so that rpcgen isn't required on the +# target machine (although almost any Unix machine will have it). +EXTRA_DIST = libvirtd.in default-network.xml \ + protocol.x remote_protocol.x \ + protocol.c protocol.h \ + remote_protocol.c remote_protocol.h \ + remote_dispatch_prototypes.h \ + remote_dispatch_localvars.h \ + remote_dispatch_proc_switch.h + +.x.c: + rm -f $@ + rpcgen -c -o $@ $< + mv $@ $@.bak + perl -w rpcgen_fix.pl < $@.bak > $@ + +.x.h: + rm -f $@ + rpcgen -h -o $@ $< + +protocol.c: protocol.h +remote_protocol.c: remote_protocol.h + +remote.c: remote_dispatch_prototypes.h \ + remote_dispatch_localvars.h \ + remote_dispatch_proc_switch.h + +remote_dispatch_prototypes.h: remote_generate_stubs.pl remote_protocol.x + perl -w remote_generate_stubs.pl -i remote_protocol.x > $@ + +remote_dispatch_localvars.h: remote_generate_stubs.pl remote_protocol.x + perl -w remote_generate_stubs.pl -v remote_protocol.x > $@ + +remote_dispatch_proc_switch.h: remote_generate_stubs.pl remote_protocol.x + perl -w remote_generate_stubs.pl -w remote_protocol.x > $@ if LIBVIRT_INIT_SCRIPTS_RED_HAT initdir = $(sysconfdir)/rc.d/init.d diff --git a/qemud/conf.c b/qemud/conf.c index c2fe4f41f1..d70c0c294b 100644 --- a/qemud/conf.c +++ b/qemud/conf.c @@ -42,7 +42,6 @@ #include -#include "protocol.h" #include "internal.h" #include "conf.h" #include "driver.h" diff --git a/qemud/dispatch.c b/qemud/dispatch.c index bb6d51a425..faeb20f3fb 100644 --- a/qemud/dispatch.c +++ b/qemud/dispatch.c @@ -40,65 +40,56 @@ static int qemudDispatchFailure(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, - struct qemud_packet *out) { - out->header.type = QEMUD_PKT_FAILURE; - out->header.dataSize = sizeof(out->data.failureReply); - out->data.failureReply.code = server->errorCode; - strcpy(out->data.failureReply.message, server->errorMessage); + struct qemud_packet_server_data *out) { + out->type = QEMUD_SERVER_PKT_FAILURE; + out->qemud_packet_server_data_u.failureReply.code = server->errorCode; + strcpy(out->qemud_packet_server_data_u.failureReply.message, server->errorMessage); return 0; } static int qemudDispatchGetVersion(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != 0) - return -1; - + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { int version = qemudGetVersion(server); if (version < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_GET_VERSION; - out->header.dataSize = sizeof(out->data.getVersionReply); - out->data.getVersionReply.version = version; + out->type = QEMUD_SERVER_PKT_GET_VERSION; + out->qemud_packet_server_data_u.getVersionReply.versionNum = version; } return 0; } static int qemudDispatchGetNodeInfo(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { struct utsname info; - if (in->header.dataSize != 0) - return -1; - if (uname(&info) < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; return 0; } - if (qemudGetCPUInfo(&out->data.getNodeInfoReply.cpus, - &out->data.getNodeInfoReply.mhz, - &out->data.getNodeInfoReply.nodes, - &out->data.getNodeInfoReply.sockets, - &out->data.getNodeInfoReply.cores, - &out->data.getNodeInfoReply.threads) < 0) { + if (qemudGetCPUInfo(&out->qemud_packet_server_data_u.getNodeInfoReply.cpus, + &out->qemud_packet_server_data_u.getNodeInfoReply.mhz, + &out->qemud_packet_server_data_u.getNodeInfoReply.nodes, + &out->qemud_packet_server_data_u.getNodeInfoReply.sockets, + &out->qemud_packet_server_data_u.getNodeInfoReply.cores, + &out->qemud_packet_server_data_u.getNodeInfoReply.threads) < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; return 0; } - if (qemudGetMemInfo(&out->data.getNodeInfoReply.memory) < 0) { + if (qemudGetMemInfo(&out->qemud_packet_server_data_u.getNodeInfoReply.memory) < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; return 0; } - out->header.type = QEMUD_PKT_GET_NODEINFO; - out->header.dataSize = sizeof(out->data.getNodeInfoReply); - strncpy(out->data.getNodeInfoReply.model, info.machine, sizeof(out->data.getNodeInfoReply.model)); - out->data.getNodeInfoReply.model[sizeof(out->data.getNodeInfoReply.model)-1] = '\0'; + out->type = QEMUD_SERVER_PKT_GET_NODEINFO; + strncpy(out->qemud_packet_server_data_u.getNodeInfoReply.model, info.machine, sizeof(out->qemud_packet_server_data_u.getNodeInfoReply.model)); + out->qemud_packet_server_data_u.getNodeInfoReply.model[sizeof(out->qemud_packet_server_data_u.getNodeInfoReply.model)-1] = '\0'; return 0; } @@ -106,8 +97,8 @@ static int qemudDispatchGetNodeInfo(struct qemud_server *server, struct qemud_cl static int qemudDispatchGetCapabilities (struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, - struct qemud_packet *out) + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, + struct qemud_packet_server_data *out) { struct utsname utsname; int i, j, r; @@ -116,8 +107,6 @@ qemudDispatchGetCapabilities (struct qemud_server *server, bufferPtr xml; int len; - if (in->header.dataSize != 0) return -1; - /* Really, this never fails - look at the man-page. */ uname (&utsname); @@ -268,18 +257,15 @@ qemudDispatchGetCapabilities (struct qemud_server *server, qemudDispatchFailure (server, client, out); return 0; } - out->header.type = QEMUD_PKT_GET_CAPABILITIES; - out->header.dataSize = sizeof(out->data.getCapabilitiesReply); - strcpy (out->data.getCapabilitiesReply.xml, xml->content); + out->type = QEMUD_SERVER_PKT_GET_CAPABILITIES; + strcpy (out->qemud_packet_server_data_u.getCapabilitiesReply.xml, xml->content); bufferFree (xml); return 0; } static int qemudDispatchListDomains(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { int i, ndomains, domains[QEMUD_MAX_NUM_DOMAINS]; - if (in->header.dataSize != 0) - return -1; ndomains = qemudListDomains(server, domains, @@ -288,172 +274,136 @@ static int qemudDispatchListDomains(struct qemud_server *server, struct qemud_cl if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_LIST_DOMAINS; - out->header.dataSize = sizeof(out->data.listDomainsReply); + out->type = QEMUD_SERVER_PKT_LIST_DOMAINS; for (i = 0 ; i < ndomains ; i++) { - out->data.listDomainsReply.domains[i] = domains[i]; + out->qemud_packet_server_data_u.listDomainsReply.domains[i] = domains[i]; } - out->data.listDomainsReply.numDomains = ndomains; + out->qemud_packet_server_data_u.listDomainsReply.numDomains = ndomains; } return 0; } static int qemudDispatchNumDomains(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != 0) - return -1; - + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { int ndomains = qemudNumDomains(server); if (ndomains < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NUM_DOMAINS; - out->header.dataSize = sizeof(out->data.numDomainsReply); - out->data.numDomainsReply.numDomains = ndomains; + out->type = QEMUD_SERVER_PKT_NUM_DOMAINS; + out->qemud_packet_server_data_u.numDomainsReply.numDomains = ndomains; } return 0; } static int qemudDispatchDomainCreate(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainCreateRequest)) - return -1; + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + in->qemud_packet_client_data_u.domainCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - in->data.domainCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - - struct qemud_vm *vm = qemudDomainCreate(server, in->data.domainCreateRequest.xml); + struct qemud_vm *vm = qemudDomainCreate(server, in->qemud_packet_client_data_u.domainCreateRequest.xml); if (!vm) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_CREATE; - out->header.dataSize = sizeof(out->data.domainCreateReply); - out->data.domainCreateReply.id = vm->id; - memcpy(out->data.domainCreateReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); - strncpy(out->data.domainCreateReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.domainCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_DOMAIN_CREATE; + out->qemud_packet_server_data_u.domainCreateReply.id = vm->id; + memcpy(out->qemud_packet_server_data_u.domainCreateReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); + strncpy(out->qemud_packet_server_data_u.domainCreateReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.domainCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchDomainLookupByID(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainLookupByIDRequest)) - return -1; - - struct qemud_vm *vm = qemudFindVMByID(server, in->data.domainLookupByIDRequest.id); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + struct qemud_vm *vm = qemudFindVMByID(server, in->qemud_packet_client_data_u.domainLookupByIDRequest.id); if (!vm) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_ID; - out->header.dataSize = sizeof(out->data.domainLookupByIDReply); - memcpy(out->data.domainLookupByIDReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); - strncpy(out->data.domainLookupByIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.domainLookupByIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_ID; + memcpy(out->qemud_packet_server_data_u.domainLookupByIDReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); + strncpy(out->qemud_packet_server_data_u.domainLookupByIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.domainLookupByIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchDomainLookupByUUID(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainLookupByUUIDRequest)) - return -1; - - struct qemud_vm *vm = qemudFindVMByUUID(server, in->data.domainLookupByUUIDRequest.uuid); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + struct qemud_vm *vm = qemudFindVMByUUID(server, in->qemud_packet_client_data_u.domainLookupByUUIDRequest.uuid); if (!vm) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_UUID; - out->header.dataSize = sizeof(out->data.domainLookupByUUIDReply); - out->data.domainLookupByUUIDReply.id = vm->id; - strncpy(out->data.domainLookupByUUIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.domainLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_UUID; + out->qemud_packet_server_data_u.domainLookupByUUIDReply.id = vm->id; + strncpy(out->qemud_packet_server_data_u.domainLookupByUUIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.domainLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchDomainLookupByName(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainLookupByNameRequest)) - return -1; - + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { /* Paranoia NULL termination */ - in->data.domainLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0'; - struct qemud_vm *vm = qemudFindVMByName(server, in->data.domainLookupByNameRequest.name); + in->qemud_packet_client_data_u.domainLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + struct qemud_vm *vm = qemudFindVMByName(server, in->qemud_packet_client_data_u.domainLookupByNameRequest.name); if (!vm) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_NAME; - out->header.dataSize = sizeof(out->data.domainLookupByNameReply); - out->data.domainLookupByNameReply.id = vm->id; - memcpy(out->data.domainLookupByNameReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); + out->type = QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_NAME; + out->qemud_packet_server_data_u.domainLookupByNameReply.id = vm->id; + memcpy(out->qemud_packet_server_data_u.domainLookupByNameReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); } return 0; } static int qemudDispatchDomainSuspend(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainSuspendRequest)) - return -1; - - int ret = qemudDomainSuspend(server, in->data.domainSuspendRequest.id); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + int ret = qemudDomainSuspend(server, in->qemud_packet_client_data_u.domainSuspendRequest.id); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_SUSPEND; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_DOMAIN_SUSPEND; } return 0; } static int qemudDispatchDomainResume(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainResumeRequest)) - return -1; - - int ret = qemudDomainResume(server, in->data.domainResumeRequest.id); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + int ret = qemudDomainResume(server, in->qemud_packet_client_data_u.domainResumeRequest.id); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_RESUME; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_DOMAIN_RESUME; } return 0; } static int qemudDispatchDomainDestroy(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainDestroyRequest)) - return -1; - - if (qemudDomainDestroy(server, in->data.domainDestroyRequest.id) < 0) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + if (qemudDomainDestroy(server, in->qemud_packet_client_data_u.domainDestroyRequest.id) < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_DESTROY; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_DOMAIN_DESTROY; } return 0; } static int qemudDispatchDomainGetInfo(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int runstate; unsigned long long cpuTime; unsigned long memory; unsigned long maxmem; unsigned int nrVirtCpu; - if (in->header.dataSize != sizeof(in->data.domainGetInfoRequest)) - return -1; - - int ret = qemudDomainGetInfo(server, in->data.domainGetInfoRequest.uuid, + int ret = qemudDomainGetInfo(server, in->qemud_packet_client_data_u.domainGetInfoRequest.uuid, &runstate, &cpuTime, &maxmem, @@ -463,91 +413,77 @@ static int qemudDispatchDomainGetInfo(struct qemud_server *server, struct qemud_ if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_GET_INFO; - out->header.dataSize = sizeof(out->data.domainGetInfoReply); - out->data.domainGetInfoReply.runstate = runstate; - out->data.domainGetInfoReply.cpuTime = cpuTime; - out->data.domainGetInfoReply.maxmem = maxmem; - out->data.domainGetInfoReply.memory = memory; - out->data.domainGetInfoReply.nrVirtCpu = nrVirtCpu; + out->type = QEMUD_SERVER_PKT_DOMAIN_GET_INFO; + out->qemud_packet_server_data_u.domainGetInfoReply.runstate = runstate; + out->qemud_packet_server_data_u.domainGetInfoReply.cpuTime = cpuTime; + out->qemud_packet_server_data_u.domainGetInfoReply.maxmem = maxmem; + out->qemud_packet_server_data_u.domainGetInfoReply.memory = memory; + out->qemud_packet_server_data_u.domainGetInfoReply.nrVirtCpu = nrVirtCpu; } return 0; } static int qemudDispatchDomainSave(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainSaveRequest)) - return -1; - + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { /* Paranoia NULL termination */ - in->data.domainSaveRequest.file[PATH_MAX-1] ='\0'; + in->qemud_packet_client_data_u.domainSaveRequest.file[PATH_MAX-1] ='\0'; int ret = qemudDomainSave(server, - in->data.domainSaveRequest.id, - in->data.domainSaveRequest.file); + in->qemud_packet_client_data_u.domainSaveRequest.id, + in->qemud_packet_client_data_u.domainSaveRequest.file); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_SAVE; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_DOMAIN_SAVE; } return 0; } static int qemudDispatchDomainRestore(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int id; - if (in->header.dataSize != sizeof(in->data.domainRestoreRequest)) - return -1; /* Paranoia null termination */ - in->data.domainRestoreRequest.file[PATH_MAX-1] ='\0'; + in->qemud_packet_client_data_u.domainRestoreRequest.file[PATH_MAX-1] ='\0'; - id = qemudDomainRestore(server, in->data.domainRestoreRequest.file); + id = qemudDomainRestore(server, in->qemud_packet_client_data_u.domainRestoreRequest.file); if (id < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_RESTORE; - out->header.dataSize = sizeof(out->data.domainRestoreReply); - out->data.domainRestoreReply.id = id; + out->type = QEMUD_SERVER_PKT_DOMAIN_RESTORE; + out->qemud_packet_server_data_u.domainRestoreReply.id = id; } return 0; } static int qemudDispatchDumpXML(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret; - if (in->header.dataSize != sizeof(in->data.domainDumpXMLRequest)) - return -1; - ret = qemudDomainDumpXML(server, - in->data.domainDumpXMLRequest.uuid, - out->data.domainDumpXMLReply.xml, + in->qemud_packet_client_data_u.domainDumpXMLRequest.uuid, + out->qemud_packet_server_data_u.domainDumpXMLReply.xml, QEMUD_MAX_XML_LEN); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DUMP_XML; - out->header.dataSize = sizeof(out->data.domainDumpXMLReply); + out->type = QEMUD_SERVER_PKT_DUMP_XML; } return 0; } static int qemudDispatchListDefinedDomains(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { char **names; int i, ndomains; - if (in->header.dataSize != 0) - return -1; if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_DOMAINS))) return -1; for (i = 0 ; i < QEMUD_MAX_NUM_DOMAINS ; i++) { - names[i] = out->data.listDefinedDomainsReply.domains[i]; + names[i] = &out->qemud_packet_server_data_u.listDefinedDomainsReply.domains[i*QEMUD_MAX_NAME_LEN]; } ndomains = qemudListDefinedDomains(server, @@ -558,114 +494,95 @@ static int qemudDispatchListDefinedDomains(struct qemud_server *server, struct q if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_LIST_DEFINED_DOMAINS; - out->header.dataSize = sizeof(out->data.listDefinedDomainsReply); - out->data.listDefinedDomainsReply.numDomains = ndomains; + out->type = QEMUD_SERVER_PKT_LIST_DEFINED_DOMAINS; + out->qemud_packet_server_data_u.listDefinedDomainsReply.numDomains = ndomains; + } + printf("%d %d\n", out->type, out->qemud_packet_server_data_u.listDefinedDomainsReply.numDomains); + for (i = 0 ; i < ndomains;i++) { + printf("[%s]\n", &out->qemud_packet_server_data_u.listDefinedDomainsReply.domains[i*QEMUD_MAX_NAME_LEN]); } return 0; } static int qemudDispatchNumDefinedDomains(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != 0) - return -1; - + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { int ndomains = qemudNumDefinedDomains(server); if (ndomains < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NUM_DEFINED_DOMAINS; - out->header.dataSize = sizeof(out->data.numDefinedDomainsReply); - out->data.numDefinedDomainsReply.numDomains = ndomains; + out->type = QEMUD_SERVER_PKT_NUM_DEFINED_DOMAINS; + out->qemud_packet_server_data_u.numDefinedDomainsReply.numDomains = ndomains; } return 0; } static int qemudDispatchDomainStart(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { struct qemud_vm *vm; - if (in->header.dataSize != sizeof(in->data.domainStartRequest)) - return -1; - - if (!(vm = qemudDomainStart(server, in->data.domainStartRequest.uuid))) { + if (!(vm = qemudDomainStart(server, in->qemud_packet_client_data_u.domainStartRequest.uuid))) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_START; - out->header.dataSize = sizeof(out->data.domainStartReply); - out->data.domainStartReply.id = vm->id; + out->type = QEMUD_SERVER_PKT_DOMAIN_START; + out->qemud_packet_server_data_u.domainStartReply.id = vm->id; } return 0; } static int qemudDispatchDomainDefine(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainDefineRequest)) - return -1; + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + in->qemud_packet_client_data_u.domainDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - in->data.domainDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - - struct qemud_vm *vm = qemudDomainDefine(server, in->data.domainDefineRequest.xml); + struct qemud_vm *vm = qemudDomainDefine(server, in->qemud_packet_client_data_u.domainDefineRequest.xml); if (!vm) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_DEFINE; - out->header.dataSize = sizeof(out->data.domainDefineReply); - memcpy(out->data.domainDefineReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); - strncpy(out->data.domainDefineReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.domainDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_DOMAIN_DEFINE; + memcpy(out->qemud_packet_server_data_u.domainDefineReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN); + strncpy(out->qemud_packet_server_data_u.domainDefineReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.domainDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchDomainUndefine(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.domainUndefineRequest)) - return -1; - - int ret = qemudDomainUndefine(server, in->data.domainUndefineRequest.uuid); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + int ret = qemudDomainUndefine(server, in->qemud_packet_client_data_u.domainUndefineRequest.uuid); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_UNDEFINE; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_DOMAIN_UNDEFINE; } return 0; } static int qemudDispatchNumNetworks(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != 0) - return -1; - + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { int nnetworks = qemudNumNetworks(server); if (nnetworks < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NUM_NETWORKS; - out->header.dataSize = sizeof(out->data.numNetworksReply); - out->data.numNetworksReply.numNetworks = nnetworks; + out->type = QEMUD_SERVER_PKT_NUM_NETWORKS; + out->qemud_packet_server_data_u.numNetworksReply.numNetworks = nnetworks; } return 0; } static int qemudDispatchListNetworks(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { char **names; int i; - if (in->header.dataSize != 0) - return -1; if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_NETWORKS))) return -1; for (i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i++) { - names[i] = out->data.listNetworksReply.networks[i]; + names[i] = &out->qemud_packet_server_data_u.listNetworksReply.networks[i*QEMUD_MAX_NAME_LEN]; } int nnetworks = qemudListNetworks(server, @@ -676,42 +593,35 @@ static int qemudDispatchListNetworks(struct qemud_server *server, struct qemud_c if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_LIST_NETWORKS; - out->header.dataSize = sizeof(out->data.listNetworksReply); - out->data.listNetworksReply.numNetworks = nnetworks; + out->type = QEMUD_SERVER_PKT_LIST_NETWORKS; + out->qemud_packet_server_data_u.listNetworksReply.numNetworks = nnetworks; } return 0; } static int qemudDispatchNumDefinedNetworks(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != 0) - return -1; - + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { int nnetworks = qemudNumDefinedNetworks(server); if (nnetworks < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NUM_DEFINED_NETWORKS; - out->header.dataSize = sizeof(out->data.numDefinedNetworksReply); - out->data.numDefinedNetworksReply.numNetworks = nnetworks; + out->type = QEMUD_SERVER_PKT_NUM_DEFINED_NETWORKS; + out->qemud_packet_server_data_u.numDefinedNetworksReply.numNetworks = nnetworks; } return 0; } static int qemudDispatchListDefinedNetworks(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) { char **names; int i; - if (in->header.dataSize != 0) - return -1; if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_NETWORKS))) return -1; for (i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i++) { - names[i] = out->data.listDefinedNetworksReply.networks[i]; + names[i] = &out->qemud_packet_server_data_u.listDefinedNetworksReply.networks[i*QEMUD_MAX_NAME_LEN]; } int nnetworks = qemudListDefinedNetworks(server, @@ -722,276 +632,222 @@ static int qemudDispatchListDefinedNetworks(struct qemud_server *server, struct if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_LIST_DEFINED_NETWORKS; - out->header.dataSize = sizeof(out->data.listDefinedNetworksReply); - out->data.listDefinedNetworksReply.numNetworks = nnetworks; + out->type = QEMUD_SERVER_PKT_LIST_DEFINED_NETWORKS; + out->qemud_packet_server_data_u.listDefinedNetworksReply.numNetworks = nnetworks; } return 0; } static int qemudDispatchNetworkLookupByName(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkLookupByNameRequest)) - return -1; - + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { /* Paranoia NULL termination */ - in->data.networkLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0'; - struct qemud_network *network = qemudFindNetworkByName(server, in->data.networkLookupByNameRequest.name); + in->qemud_packet_client_data_u.networkLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + struct qemud_network *network = qemudFindNetworkByName(server, in->qemud_packet_client_data_u.networkLookupByNameRequest.name); if (!network) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_NAME; - out->header.dataSize = sizeof(out->data.networkLookupByNameReply); - memcpy(out->data.networkLookupByNameReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN); + out->type = QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_NAME; + memcpy(out->qemud_packet_server_data_u.networkLookupByNameReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN); } return 0; } static int qemudDispatchNetworkLookupByUUID(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkLookupByUUIDRequest)) - return -1; - - struct qemud_network *network = qemudFindNetworkByUUID(server, in->data.networkLookupByUUIDRequest.uuid); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + struct qemud_network *network = qemudFindNetworkByUUID(server, in->qemud_packet_client_data_u.networkLookupByUUIDRequest.uuid); if (!network) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID; - out->header.dataSize = sizeof(out->data.networkLookupByUUIDReply); - strncpy(out->data.networkLookupByUUIDReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_UUID; + strncpy(out->qemud_packet_server_data_u.networkLookupByUUIDReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchNetworkCreate(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkCreateRequest)) - return -1; + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + in->qemud_packet_client_data_u.networkCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - in->data.networkCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - - struct qemud_network *network = qemudNetworkCreate(server, in->data.networkCreateRequest.xml); + struct qemud_network *network = qemudNetworkCreate(server, in->qemud_packet_client_data_u.networkCreateRequest.xml); if (!network) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_CREATE; - out->header.dataSize = sizeof(out->data.networkCreateReply); - memcpy(out->data.networkCreateReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN); - strncpy(out->data.networkCreateReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_NETWORK_CREATE; + memcpy(out->qemud_packet_server_data_u.networkCreateReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN); + strncpy(out->qemud_packet_server_data_u.networkCreateReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchNetworkDefine(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkDefineRequest)) - return -1; + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + in->qemud_packet_client_data_u.networkDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - in->data.networkDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0'; - - struct qemud_network *network = qemudNetworkDefine(server, in->data.networkDefineRequest.xml); + struct qemud_network *network = qemudNetworkDefine(server, in->qemud_packet_client_data_u.networkDefineRequest.xml); if (!network) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_DEFINE; - out->header.dataSize = sizeof(out->data.networkDefineReply); - memcpy(out->data.networkDefineReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN); - strncpy(out->data.networkDefineReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1); - out->data.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; + out->type = QEMUD_SERVER_PKT_NETWORK_DEFINE; + memcpy(out->qemud_packet_server_data_u.networkDefineReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN); + strncpy(out->qemud_packet_server_data_u.networkDefineReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1); + out->qemud_packet_server_data_u.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; } return 0; } static int qemudDispatchNetworkUndefine(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkUndefineRequest)) - return -1; - - int ret = qemudNetworkUndefine(server, in->data.networkUndefineRequest.uuid); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + int ret = qemudNetworkUndefine(server, in->qemud_packet_client_data_u.networkUndefineRequest.uuid); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_UNDEFINE; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_NETWORK_UNDEFINE; } return 0; } static int qemudDispatchNetworkStart(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { struct qemud_network *network; - if (in->header.dataSize != sizeof(in->data.networkStartRequest)) - return -1; - - if (!(network = qemudNetworkStart(server, in->data.networkStartRequest.uuid))) { + if (!(network = qemudNetworkStart(server, in->qemud_packet_client_data_u.networkStartRequest.uuid))) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_START; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_NETWORK_START; } return 0; } static int qemudDispatchNetworkDestroy(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkDestroyRequest)) - return -1; - - if (qemudNetworkDestroy(server, in->data.networkDestroyRequest.uuid) < 0) { + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { + if (qemudNetworkDestroy(server, in->qemud_packet_client_data_u.networkDestroyRequest.uuid) < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_DESTROY; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_NETWORK_DESTROY; } return 0; } static int qemudDispatchNetworkDumpXML(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkDumpXMLRequest)) - return -1; - + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret = qemudNetworkDumpXML(server, - in->data.networkDumpXMLRequest.uuid, - out->data.networkDumpXMLReply.xml, QEMUD_MAX_XML_LEN); + in->qemud_packet_client_data_u.networkDumpXMLRequest.uuid, + out->qemud_packet_server_data_u.networkDumpXMLReply.xml, QEMUD_MAX_XML_LEN); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_DUMP_XML; - out->header.dataSize = sizeof(out->data.networkDumpXMLReply); + out->type = QEMUD_SERVER_PKT_NETWORK_DUMP_XML; } return 0; } static int qemudDispatchNetworkGetBridgeName(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { - if (in->header.dataSize != sizeof(in->data.networkGetBridgeNameRequest)) - return -1; - + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret = qemudNetworkGetBridgeName(server, - in->data.networkDumpXMLRequest.uuid, - out->data.networkGetBridgeNameReply.ifname, QEMUD_MAX_IFNAME_LEN); + in->qemud_packet_client_data_u.networkDumpXMLRequest.uuid, + out->qemud_packet_server_data_u.networkGetBridgeNameReply.ifname, QEMUD_MAX_IFNAME_LEN); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_GET_BRIDGE_NAME; - out->header.dataSize = sizeof(out->data.networkGetBridgeNameReply); + out->type = QEMUD_SERVER_PKT_NETWORK_GET_BRIDGE_NAME; } return 0; } static int qemudDispatchDomainGetAutostart(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret; int autostart; - if (in->header.dataSize != sizeof(in->data.domainGetAutostartRequest)) - return -1; - autostart = 0; ret = qemudDomainGetAutostart(server, - in->data.domainGetAutostartRequest.uuid, + in->qemud_packet_client_data_u.domainGetAutostartRequest.uuid, &autostart); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_GET_AUTOSTART; - out->header.dataSize = sizeof(out->data.networkGetAutostartReply); - out->data.networkGetAutostartReply.autostart = (autostart != 0); + out->type = QEMUD_SERVER_PKT_DOMAIN_GET_AUTOSTART; + out->qemud_packet_server_data_u.networkGetAutostartReply.autostart = (autostart != 0); } return 0; } static int qemudDispatchDomainSetAutostart(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret; - if (in->header.dataSize != sizeof(in->data.domainSetAutostartRequest)) - return -1; - ret = qemudDomainSetAutostart(server, - in->data.domainGetAutostartRequest.uuid, - in->data.domainSetAutostartRequest.autostart); + in->qemud_packet_client_data_u.domainGetAutostartRequest.uuid, + in->qemud_packet_client_data_u.domainSetAutostartRequest.autostart); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_DOMAIN_SET_AUTOSTART; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_DOMAIN_SET_AUTOSTART; } return 0; } static int qemudDispatchNetworkGetAutostart(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret; int autostart; - if (in->header.dataSize != sizeof(in->data.networkGetAutostartRequest)) - return -1; - autostart = 0; ret = qemudNetworkGetAutostart(server, - in->data.networkGetAutostartRequest.uuid, + in->qemud_packet_client_data_u.networkGetAutostartRequest.uuid, &autostart); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_GET_AUTOSTART; - out->header.dataSize = sizeof(out->data.networkGetAutostartReply); - out->data.networkGetAutostartReply.autostart = (autostart != 0); + out->type = QEMUD_SERVER_PKT_NETWORK_GET_AUTOSTART; + out->qemud_packet_server_data_u.networkGetAutostartReply.autostart = (autostart != 0); } return 0; } static int qemudDispatchNetworkSetAutostart(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) { int ret; - if (in->header.dataSize != sizeof(in->data.networkSetAutostartRequest)) - return -1; - ret = qemudNetworkSetAutostart(server, - in->data.networkGetAutostartRequest.uuid, - in->data.networkSetAutostartRequest.autostart); + in->qemud_packet_client_data_u.networkGetAutostartRequest.uuid, + in->qemud_packet_client_data_u.networkSetAutostartRequest.autostart); if (ret < 0) { if (qemudDispatchFailure(server, client, out) < 0) return -1; } else { - out->header.type = QEMUD_PKT_NETWORK_SET_AUTOSTART; - out->header.dataSize = 0; + out->type = QEMUD_SERVER_PKT_NETWORK_SET_AUTOSTART; } return 0; } typedef int (*clientFunc)(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out); /* One per message type recorded in qemud_packet_type enum */ -clientFunc funcsTransmitRW[QEMUD_PKT_MAX] = { - NULL, /* FAILURE code */ +clientFunc funcsTransmitRW[QEMUD_CLIENT_PKT_MAX] = { qemudDispatchGetVersion, qemudDispatchGetNodeInfo, qemudDispatchListDomains, @@ -1032,8 +888,7 @@ clientFunc funcsTransmitRW[QEMUD_PKT_MAX] = { qemudDispatchGetCapabilities, }; -clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = { - NULL, /* FAILURE code */ +clientFunc funcsTransmitRO[QEMUD_CLIENT_PKT_MAX] = { qemudDispatchGetVersion, qemudDispatchGetNodeInfo, qemudDispatchListDomains, @@ -1084,22 +939,18 @@ clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = { * incoming type, or is QEMUD_PKT_FAILURE */ int qemudDispatch(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out) { + qemud_packet_client_data *in, qemud_packet_server_data *out) { clientFunc *funcs; - unsigned int type = in->header.type; - qemudDebug("> Dispatching request %d readonly ? %d", type, client->readonly); + unsigned int type = in->type; + qemudDebug("> Dispatching request type %d, readonly ? %d", + in->type, client->readonly); server->errorCode = 0; server->errorMessage[0] = '\0'; - memset(out, 0, sizeof(struct qemud_packet)); + memset(out, 0, sizeof(*out)); - if (type >= QEMUD_PKT_MAX) { - qemudDebug("Illegal request type"); - return -1; - } - - if (type == QEMUD_PKT_FAILURE) { + if (type >= QEMUD_CLIENT_PKT_MAX) { qemudDebug("Illegal request type"); return -1; } @@ -1120,14 +971,11 @@ int qemudDispatch(struct qemud_server *server, struct qemud_client *client, } } - qemudDebug("< Returning reply %d (%d bytes)", - out->header.type, - out->header.dataSize); + qemudDebug("< Returning reply %d", out->type); return 0; } - /* * Local variables: * indent-tabs-mode: nil diff --git a/qemud/dispatch.h b/qemud/dispatch.h index 9e1dbd7d37..8b494f65fb 100644 --- a/qemud/dispatch.h +++ b/qemud/dispatch.h @@ -29,7 +29,7 @@ int qemudDispatch(struct qemud_server *server, struct qemud_client *client, - struct qemud_packet *in, struct qemud_packet *out); + struct qemud_packet_client_data *in, struct qemud_packet_server_data *out); #endif diff --git a/qemud/internal.h b/qemud/internal.h index 3d7a926665..276ae4721b 100644 --- a/qemud/internal.h +++ b/qemud/internal.h @@ -27,8 +27,11 @@ #include #include +#include +#include #include "protocol.h" +#include "remote_protocol.h" #include "bridge.h" #include "iptables.h" @@ -58,15 +61,6 @@ typedef enum { #endif } qemudLogPriority; -typedef enum { - QEMUD_DIR_CONFIG = 0, - QEMUD_DIR_AUTOSTART, - QEMUD_DIR_NETWORK_CONFIG, - QEMUD_DIR_NETWORK_AUTOSTART, - - QEMUD_N_CONFIG_DIRS -} qemudConfigDirType; - /* Different types of QEMU acceleration possible */ enum qemud_vm_virt_type { QEMUD_VIRT_QEMU, @@ -277,22 +271,61 @@ struct qemud_network { struct qemud_network *next; }; + +enum qemud_mode { + QEMUD_MODE_RX_HEADER, + QEMUD_MODE_RX_PAYLOAD, + QEMUD_MODE_TX_PACKET, + QEMUD_MODE_TLS_HANDSHAKE, +}; + +/* These have to remain compatible with gnutls_record_get_direction. */ +enum qemud_tls_direction { + QEMUD_TLS_DIRECTION_READ = 0, + QEMUD_TLS_DIRECTION_WRITE = 1, +}; + /* Stores the per-client connection state */ struct qemud_client { + int magic; + int fd; int readonly; - struct qemud_packet incoming; - unsigned int incomingReceived; - struct qemud_packet outgoing; - unsigned int outgoingSent; - int tx; + enum qemud_mode mode; + + struct sockaddr_storage addr; + socklen_t addrlen; + + /* If set, TLS is required on this socket. */ + int tls; + gnutls_session_t session; + enum qemud_tls_direction direction; + + unsigned int incomingSerial; + unsigned int outgoingSerial; + + char buffer [REMOTE_MESSAGE_MAX]; + unsigned int bufferLength; + unsigned int bufferOffset; + + /* This is only valid if a remote open call has been made on this + * connection, otherwise it will be NULL. Also if remote close is + * called, it will be set back to NULL if that succeeds. + */ + virConnectPtr conn; + struct qemud_client *next; }; +#define QEMUD_CLIENT_MAGIC 0x7788aaee + struct qemud_socket { int fd; int readonly; + /* If set, TLS is required on this socket. */ + int tls; + struct qemud_socket *next; }; @@ -315,7 +348,6 @@ struct qemud_server { struct qemud_network *networks; brControl *brctl; iptablesContext *iptables; - char configDirs[QEMUD_N_CONFIG_DIRS][PATH_MAX]; char *configDir; char *autostartDir; char *networkConfigDir; @@ -347,6 +379,9 @@ void qemudLog(int priority, const char *fmt, ...) #define qemudDebug(fmt, ...) do {} while(0) #endif +void remoteDispatchClientRequest (struct qemud_server *server, + struct qemud_client *client); + static inline int qemudIsActiveVM(struct qemud_vm *vm) { diff --git a/qemud/protocol.c b/qemud/protocol.c new file mode 100644 index 0000000000..a9db9295e9 --- /dev/null +++ b/qemud/protocol.c @@ -0,0 +1,969 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "protocol.h" + +bool_t +xdr_qemud_domain_runstate (XDR *xdrs, qemud_domain_runstate *objp) +{ + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_client_data_type (XDR *xdrs, qemud_packet_client_data_type *objp) +{ + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_server_data_type (XDR *xdrs, qemud_packet_server_data_type *objp) +{ + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_failure_reply (XDR *xdrs, qemud_packet_failure_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->code)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->message, QEMUD_MAX_ERROR_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_get_version_reply (XDR *xdrs, qemud_packet_get_version_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->versionNum)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_get_node_info_reply (XDR *xdrs, qemud_packet_get_node_info_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->model, 32, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->memory)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->cpus)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->mhz)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->nodes)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->sockets)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->cores)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->threads)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_get_capabilities_reply (XDR *xdrs, qemud_packet_get_capabilities_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_list_domains_reply (XDR *xdrs, qemud_packet_list_domains_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->numDomains)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->domains, QEMUD_MAX_NUM_DOMAINS, + sizeof (int32_t), (xdrproc_t) xdr_int32_t)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_num_domains_reply (XDR *xdrs, qemud_packet_num_domains_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->numDomains)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_create_request (XDR *xdrs, qemud_packet_domain_create_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_create_reply (XDR *xdrs, qemud_packet_domain_create_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_lookup_by_id_request (XDR *xdrs, qemud_packet_domain_lookup_by_id_request *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_lookup_by_id_reply (XDR *xdrs, qemud_packet_domain_lookup_by_id_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_lookup_by_name_request (XDR *xdrs, qemud_packet_domain_lookup_by_name_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_lookup_by_name_reply (XDR *xdrs, qemud_packet_domain_lookup_by_name_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_lookup_by_uuid_request (XDR *xdrs, qemud_packet_domain_lookup_by_uuid_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_lookup_by_uuid_reply (XDR *xdrs, qemud_packet_domain_lookup_by_uuid_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_suspend_request (XDR *xdrs, qemud_packet_domain_suspend_request *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_resume_request (XDR *xdrs, qemud_packet_domain_resume_request *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_destroy_request (XDR *xdrs, qemud_packet_domain_destroy_request *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_get_info_request (XDR *xdrs, qemud_packet_domain_get_info_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_get_info_reply (XDR *xdrs, qemud_packet_domain_get_info_reply *objp) +{ + + if (!xdr_uint64_t (xdrs, &objp->cpuTime)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->runstate)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->memory)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->maxmem)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->nrVirtCpu)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_save_request (XDR *xdrs, qemud_packet_domain_save_request *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->file, PATH_MAX, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_restore_request (XDR *xdrs, qemud_packet_domain_restore_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->file, PATH_MAX, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_restore_reply (XDR *xdrs, qemud_packet_domain_restore_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_dump_xml_request (XDR *xdrs, qemud_packet_domain_dump_xml_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_dump_xml_reply (XDR *xdrs, qemud_packet_domain_dump_xml_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_list_defined_domains_reply (XDR *xdrs, qemud_packet_list_defined_domains_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->numDomains)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->domains, QEMUD_MAX_DOMAINS_NAME_BUF, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_num_defined_domains_reply (XDR *xdrs, qemud_packet_num_defined_domains_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->numDomains)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_start_request (XDR *xdrs, qemud_packet_domain_start_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_start_reply (XDR *xdrs, qemud_packet_domain_start_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_define_request (XDR *xdrs, qemud_packet_domain_define_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_define_reply (XDR *xdrs, qemud_packet_domain_define_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_undefine_request (XDR *xdrs, qemud_packet_domain_undefine_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_num_networks_reply (XDR *xdrs, qemud_packet_num_networks_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->numNetworks)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_list_networks_reply (XDR *xdrs, qemud_packet_list_networks_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->numNetworks)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->networks, QEMUD_MAX_NETWORKS_NAME_BUF, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_num_defined_networks_reply (XDR *xdrs, qemud_packet_num_defined_networks_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->numNetworks)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_list_defined_networks_reply (XDR *xdrs, qemud_packet_list_defined_networks_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->numNetworks)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->networks, QEMUD_MAX_NETWORKS_NAME_BUF, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_lookup_by_name_request (XDR *xdrs, qemud_packet_network_lookup_by_name_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_lookup_by_name_reply (XDR *xdrs, qemud_packet_network_lookup_by_name_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_lookup_by_uuid_request (XDR *xdrs, qemud_packet_network_lookup_by_uuid_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_lookup_by_uuid_reply (XDR *xdrs, qemud_packet_network_lookup_by_uuid_reply *objp) +{ + + if (!xdr_int32_t (xdrs, &objp->id)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_create_request (XDR *xdrs, qemud_packet_network_create_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_create_reply (XDR *xdrs, qemud_packet_network_create_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_define_request (XDR *xdrs, qemud_packet_network_define_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_define_reply (XDR *xdrs, qemud_packet_network_define_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_vector (xdrs, (char *)objp->name, QEMUD_MAX_NAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_undefine_request (XDR *xdrs, qemud_packet_network_undefine_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_start_request (XDR *xdrs, qemud_packet_network_start_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_destroy_request (XDR *xdrs, qemud_packet_network_destroy_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_dump_xml_request (XDR *xdrs, qemud_packet_network_dump_xml_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_dump_xml_reply (XDR *xdrs, qemud_packet_network_dump_xml_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->xml, QEMUD_MAX_XML_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_get_bridge_name_request (XDR *xdrs, qemud_packet_network_get_bridge_name_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_get_bridge_name_reply (XDR *xdrs, qemud_packet_network_get_bridge_name_reply *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->ifname, QEMUD_MAX_IFNAME_LEN, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_get_autostart_request (XDR *xdrs, qemud_packet_domain_get_autostart_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_get_autostart_reply (XDR *xdrs, qemud_packet_domain_get_autostart_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->autostart)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_domain_set_autostart_request (XDR *xdrs, qemud_packet_domain_set_autostart_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->autostart)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_get_autostart_request (XDR *xdrs, qemud_packet_network_get_autostart_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_get_autostart_reply (XDR *xdrs, qemud_packet_network_get_autostart_reply *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->autostart)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_network_set_autostart_request (XDR *xdrs, qemud_packet_network_set_autostart_request *objp) +{ + + if (!xdr_vector (xdrs, (char *)objp->uuid, QEMUD_UUID_RAW_LEN, + sizeof (u_char), (xdrproc_t) xdr_u_char)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->autostart)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_client_data (XDR *xdrs, qemud_packet_client_data *objp) +{ + + if (!xdr_qemud_packet_client_data_type (xdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case QEMUD_CLIENT_PKT_GET_VERSION: + break; + case QEMUD_CLIENT_PKT_GET_NODEINFO: + break; + case QEMUD_CLIENT_PKT_LIST_DOMAINS: + break; + case QEMUD_CLIENT_PKT_NUM_DOMAINS: + break; + case QEMUD_CLIENT_PKT_DOMAIN_CREATE: + if (!xdr_qemud_packet_domain_create_request (xdrs, &objp->qemud_packet_client_data_u.domainCreateRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_ID: + if (!xdr_qemud_packet_domain_lookup_by_id_request (xdrs, &objp->qemud_packet_client_data_u.domainLookupByIDRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_UUID: + if (!xdr_qemud_packet_domain_lookup_by_uuid_request (xdrs, &objp->qemud_packet_client_data_u.domainLookupByUUIDRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_NAME: + if (!xdr_qemud_packet_domain_lookup_by_name_request (xdrs, &objp->qemud_packet_client_data_u.domainLookupByNameRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_SUSPEND: + if (!xdr_qemud_packet_domain_suspend_request (xdrs, &objp->qemud_packet_client_data_u.domainSuspendRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_RESUME: + if (!xdr_qemud_packet_domain_resume_request (xdrs, &objp->qemud_packet_client_data_u.domainResumeRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_DESTROY: + if (!xdr_qemud_packet_domain_destroy_request (xdrs, &objp->qemud_packet_client_data_u.domainDestroyRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_GET_INFO: + if (!xdr_qemud_packet_domain_get_info_request (xdrs, &objp->qemud_packet_client_data_u.domainGetInfoRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_SAVE: + if (!xdr_qemud_packet_domain_save_request (xdrs, &objp->qemud_packet_client_data_u.domainSaveRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_RESTORE: + if (!xdr_qemud_packet_domain_restore_request (xdrs, &objp->qemud_packet_client_data_u.domainRestoreRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DUMP_XML: + if (!xdr_qemud_packet_domain_dump_xml_request (xdrs, &objp->qemud_packet_client_data_u.domainDumpXMLRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_LIST_DEFINED_DOMAINS: + break; + case QEMUD_CLIENT_PKT_NUM_DEFINED_DOMAINS: + break; + case QEMUD_CLIENT_PKT_DOMAIN_START: + if (!xdr_qemud_packet_domain_start_request (xdrs, &objp->qemud_packet_client_data_u.domainStartRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_DEFINE: + if (!xdr_qemud_packet_domain_define_request (xdrs, &objp->qemud_packet_client_data_u.domainDefineRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_UNDEFINE: + if (!xdr_qemud_packet_domain_undefine_request (xdrs, &objp->qemud_packet_client_data_u.domainUndefineRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NUM_NETWORKS: + break; + case QEMUD_CLIENT_PKT_LIST_NETWORKS: + break; + case QEMUD_CLIENT_PKT_NUM_DEFINED_NETWORKS: + break; + case QEMUD_CLIENT_PKT_LIST_DEFINED_NETWORKS: + break; + case QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_UUID: + if (!xdr_qemud_packet_network_lookup_by_uuid_request (xdrs, &objp->qemud_packet_client_data_u.networkLookupByUUIDRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_NAME: + if (!xdr_qemud_packet_network_lookup_by_name_request (xdrs, &objp->qemud_packet_client_data_u.networkLookupByNameRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_CREATE: + if (!xdr_qemud_packet_network_create_request (xdrs, &objp->qemud_packet_client_data_u.networkCreateRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_DEFINE: + if (!xdr_qemud_packet_network_define_request (xdrs, &objp->qemud_packet_client_data_u.networkDefineRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_UNDEFINE: + if (!xdr_qemud_packet_network_undefine_request (xdrs, &objp->qemud_packet_client_data_u.networkUndefineRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_START: + if (!xdr_qemud_packet_network_start_request (xdrs, &objp->qemud_packet_client_data_u.networkStartRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_DESTROY: + if (!xdr_qemud_packet_network_destroy_request (xdrs, &objp->qemud_packet_client_data_u.networkDestroyRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_DUMP_XML: + if (!xdr_qemud_packet_network_dump_xml_request (xdrs, &objp->qemud_packet_client_data_u.networkDumpXMLRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_GET_BRIDGE_NAME: + if (!xdr_qemud_packet_network_get_bridge_name_request (xdrs, &objp->qemud_packet_client_data_u.networkGetBridgeNameRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_GET_AUTOSTART: + if (!xdr_qemud_packet_domain_get_autostart_request (xdrs, &objp->qemud_packet_client_data_u.domainGetAutostartRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_DOMAIN_SET_AUTOSTART: + if (!xdr_qemud_packet_domain_set_autostart_request (xdrs, &objp->qemud_packet_client_data_u.domainSetAutostartRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_GET_AUTOSTART: + if (!xdr_qemud_packet_network_get_autostart_request (xdrs, &objp->qemud_packet_client_data_u.networkGetAutostartRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_NETWORK_SET_AUTOSTART: + if (!xdr_qemud_packet_network_set_autostart_request (xdrs, &objp->qemud_packet_client_data_u.networkSetAutostartRequest)) + return FALSE; + break; + case QEMUD_CLIENT_PKT_GET_CAPABILITIES: + break; + default: + return FALSE; + } + return TRUE; +} + +bool_t +xdr_qemud_packet_server_data (XDR *xdrs, qemud_packet_server_data *objp) +{ + + if (!xdr_qemud_packet_server_data_type (xdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case QEMUD_SERVER_PKT_FAILURE: + if (!xdr_qemud_packet_failure_reply (xdrs, &objp->qemud_packet_server_data_u.failureReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_GET_VERSION: + if (!xdr_qemud_packet_get_version_reply (xdrs, &objp->qemud_packet_server_data_u.getVersionReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_GET_NODEINFO: + if (!xdr_qemud_packet_get_node_info_reply (xdrs, &objp->qemud_packet_server_data_u.getNodeInfoReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_LIST_DOMAINS: + if (!xdr_qemud_packet_list_domains_reply (xdrs, &objp->qemud_packet_server_data_u.listDomainsReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NUM_DOMAINS: + if (!xdr_qemud_packet_num_domains_reply (xdrs, &objp->qemud_packet_server_data_u.numDomainsReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_CREATE: + if (!xdr_qemud_packet_domain_create_reply (xdrs, &objp->qemud_packet_server_data_u.domainCreateReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_ID: + if (!xdr_qemud_packet_domain_lookup_by_id_reply (xdrs, &objp->qemud_packet_server_data_u.domainLookupByIDReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_UUID: + if (!xdr_qemud_packet_domain_lookup_by_uuid_reply (xdrs, &objp->qemud_packet_server_data_u.domainLookupByUUIDReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_NAME: + if (!xdr_qemud_packet_domain_lookup_by_name_reply (xdrs, &objp->qemud_packet_server_data_u.domainLookupByNameReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_SUSPEND: + break; + case QEMUD_SERVER_PKT_DOMAIN_RESUME: + break; + case QEMUD_SERVER_PKT_DOMAIN_DESTROY: + break; + case QEMUD_SERVER_PKT_DOMAIN_GET_INFO: + if (!xdr_qemud_packet_domain_get_info_reply (xdrs, &objp->qemud_packet_server_data_u.domainGetInfoReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_SAVE: + break; + case QEMUD_SERVER_PKT_DOMAIN_RESTORE: + if (!xdr_qemud_packet_domain_restore_reply (xdrs, &objp->qemud_packet_server_data_u.domainRestoreReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DUMP_XML: + if (!xdr_qemud_packet_domain_dump_xml_reply (xdrs, &objp->qemud_packet_server_data_u.domainDumpXMLReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_LIST_DEFINED_DOMAINS: + if (!xdr_qemud_packet_list_defined_domains_reply (xdrs, &objp->qemud_packet_server_data_u.listDefinedDomainsReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NUM_DEFINED_DOMAINS: + if (!xdr_qemud_packet_num_defined_domains_reply (xdrs, &objp->qemud_packet_server_data_u.numDefinedDomainsReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_START: + if (!xdr_qemud_packet_domain_start_reply (xdrs, &objp->qemud_packet_server_data_u.domainStartReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_DEFINE: + if (!xdr_qemud_packet_domain_define_reply (xdrs, &objp->qemud_packet_server_data_u.domainDefineReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_UNDEFINE: + break; + case QEMUD_SERVER_PKT_NUM_NETWORKS: + if (!xdr_qemud_packet_num_networks_reply (xdrs, &objp->qemud_packet_server_data_u.numNetworksReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_LIST_NETWORKS: + if (!xdr_qemud_packet_list_networks_reply (xdrs, &objp->qemud_packet_server_data_u.listNetworksReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NUM_DEFINED_NETWORKS: + if (!xdr_qemud_packet_num_defined_networks_reply (xdrs, &objp->qemud_packet_server_data_u.numDefinedNetworksReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_LIST_DEFINED_NETWORKS: + if (!xdr_qemud_packet_list_defined_networks_reply (xdrs, &objp->qemud_packet_server_data_u.listDefinedNetworksReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_UUID: + if (!xdr_qemud_packet_network_lookup_by_uuid_reply (xdrs, &objp->qemud_packet_server_data_u.networkLookupByUUIDReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_NAME: + if (!xdr_qemud_packet_network_lookup_by_name_reply (xdrs, &objp->qemud_packet_server_data_u.networkLookupByNameReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_CREATE: + if (!xdr_qemud_packet_network_create_reply (xdrs, &objp->qemud_packet_server_data_u.networkCreateReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_DEFINE: + if (!xdr_qemud_packet_network_define_reply (xdrs, &objp->qemud_packet_server_data_u.networkDefineReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_UNDEFINE: + break; + case QEMUD_SERVER_PKT_NETWORK_START: + break; + case QEMUD_SERVER_PKT_NETWORK_DESTROY: + break; + case QEMUD_SERVER_PKT_NETWORK_DUMP_XML: + if (!xdr_qemud_packet_network_dump_xml_reply (xdrs, &objp->qemud_packet_server_data_u.networkDumpXMLReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_GET_BRIDGE_NAME: + if (!xdr_qemud_packet_network_get_bridge_name_reply (xdrs, &objp->qemud_packet_server_data_u.networkGetBridgeNameReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_GET_AUTOSTART: + if (!xdr_qemud_packet_domain_get_autostart_reply (xdrs, &objp->qemud_packet_server_data_u.domainGetAutostartReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_DOMAIN_SET_AUTOSTART: + break; + case QEMUD_SERVER_PKT_NETWORK_GET_AUTOSTART: + if (!xdr_qemud_packet_network_get_autostart_reply (xdrs, &objp->qemud_packet_server_data_u.networkGetAutostartReply)) + return FALSE; + break; + case QEMUD_SERVER_PKT_NETWORK_SET_AUTOSTART: + break; + case QEMUD_SERVER_PKT_GET_CAPABILITIES: + if (!xdr_qemud_packet_get_capabilities_reply (xdrs, &objp->qemud_packet_server_data_u.getCapabilitiesReply)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +bool_t +xdr_qemud_packet_client (XDR *xdrs, qemud_packet_client *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->serial)) + return FALSE; + if (!xdr_qemud_packet_client_data (xdrs, &objp->data)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_server (XDR *xdrs, qemud_packet_server *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->serial)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->inReplyTo)) + return FALSE; + if (!xdr_qemud_packet_server_data (xdrs, &objp->data)) + return FALSE; + return TRUE; +} + +bool_t +xdr_qemud_packet_header (XDR *xdrs, qemud_packet_header *objp) +{ + + if (!xdr_uint32_t (xdrs, &objp->length)) + return FALSE; + if (!xdr_uint32_t (xdrs, &objp->prog)) + return FALSE; + return TRUE; +} diff --git a/qemud/protocol.h b/qemud/protocol.h index 8826df750b..0454253028 100644 --- a/qemud/protocol.h +++ b/qemud/protocol.h @@ -1,329 +1,660 @@ /* - * protocol.h: wire protocol message format & data structures - * - * Copyright (C) 2006, 2007 Red Hat, Inc. - * Copyright (C) 2006 Daniel P. Berrange - * - * 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: Daniel P. Berrange + * Please do not edit this file. + * It was generated using rpcgen. */ +#ifndef _PROTOCOL_H_RPCGEN +#define _PROTOCOL_H_RPCGEN -#ifndef QEMUD_PROTOCOL_H__ -#define QEMUD_PROTOCOL_H__ - -#include -#include /* for IF_NAMESIZE */ - -/* List of different packet types which can be sent */ -enum qemud_packet_type { - QEMUD_PKT_FAILURE = 0, - QEMUD_PKT_GET_VERSION, - QEMUD_PKT_GET_NODEINFO, - QEMUD_PKT_LIST_DOMAINS, - QEMUD_PKT_NUM_DOMAINS, - QEMUD_PKT_DOMAIN_CREATE, - QEMUD_PKT_DOMAIN_LOOKUP_BY_ID, - QEMUD_PKT_DOMAIN_LOOKUP_BY_UUID, - QEMUD_PKT_DOMAIN_LOOKUP_BY_NAME, - QEMUD_PKT_DOMAIN_SUSPEND, - QEMUD_PKT_DOMAIN_RESUME, - QEMUD_PKT_DOMAIN_DESTROY, - QEMUD_PKT_DOMAIN_GET_INFO, - QEMUD_PKT_DOMAIN_SAVE, - QEMUD_PKT_DOMAIN_RESTORE, - QEMUD_PKT_DUMP_XML, - QEMUD_PKT_LIST_DEFINED_DOMAINS, - QEMUD_PKT_NUM_DEFINED_DOMAINS, - QEMUD_PKT_DOMAIN_START, - QEMUD_PKT_DOMAIN_DEFINE, - QEMUD_PKT_DOMAIN_UNDEFINE, - QEMUD_PKT_NUM_NETWORKS, - QEMUD_PKT_LIST_NETWORKS, - QEMUD_PKT_NUM_DEFINED_NETWORKS, - QEMUD_PKT_LIST_DEFINED_NETWORKS, - QEMUD_PKT_NETWORK_LOOKUP_BY_UUID, - QEMUD_PKT_NETWORK_LOOKUP_BY_NAME, - QEMUD_PKT_NETWORK_CREATE, - QEMUD_PKT_NETWORK_DEFINE, - QEMUD_PKT_NETWORK_UNDEFINE, - QEMUD_PKT_NETWORK_START, - QEMUD_PKT_NETWORK_DESTROY, - QEMUD_PKT_NETWORK_DUMP_XML, - QEMUD_PKT_NETWORK_GET_BRIDGE_NAME, - QEMUD_PKT_DOMAIN_GET_AUTOSTART, - QEMUD_PKT_DOMAIN_SET_AUTOSTART, - QEMUD_PKT_NETWORK_GET_AUTOSTART, - QEMUD_PKT_NETWORK_SET_AUTOSTART, - QEMUD_PKT_GET_CAPABILITIES, - - QEMUD_PKT_MAX, -}; +#include -#define QEMUD_PROTOCOL_VERSION_MAJOR 1 -#define QEMUD_PROTOCOL_VERSION_MINOR 0 +#ifdef __cplusplus +extern "C" { +#endif #define QEMUD_UUID_RAW_LEN 16 #define QEMUD_MAX_NAME_LEN 50 #define QEMUD_MAX_XML_LEN 4096 -#define QEMUD_MAX_IFNAME_LEN IF_NAMESIZE +#define QEMUD_MAX_IFNAME_LEN 50 #define QEMUD_MAX_NUM_DOMAINS 100 #define QEMUD_MAX_NUM_NETWORKS 100 +#define QEMUD_MAX_DOMAINS_NAME_BUF 5000 +#define QEMUD_MAX_NETWORKS_NAME_BUF 5000 #define QEMUD_MAX_ERROR_LEN 1024 -/* Possible guest VM states */ enum qemud_domain_runstate { - QEMUD_STATE_RUNNING = 1, - QEMUD_STATE_PAUSED, - QEMUD_STATE_STOPPED, + QEMUD_STATE_RUNNING = 1, + QEMUD_STATE_PAUSED = 1 + 1, + QEMUD_STATE_STOPPED = 1 + 2, }; +typedef enum qemud_domain_runstate qemud_domain_runstate; + +enum qemud_packet_client_data_type { + QEMUD_CLIENT_PKT_GET_VERSION = 0, + QEMUD_CLIENT_PKT_GET_NODEINFO = 1, + QEMUD_CLIENT_PKT_LIST_DOMAINS = 2, + QEMUD_CLIENT_PKT_NUM_DOMAINS = 3, + QEMUD_CLIENT_PKT_DOMAIN_CREATE = 4, + QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_ID = 5, + QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_UUID = 6, + QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_NAME = 7, + QEMUD_CLIENT_PKT_DOMAIN_SUSPEND = 8, + QEMUD_CLIENT_PKT_DOMAIN_RESUME = 9, + QEMUD_CLIENT_PKT_DOMAIN_DESTROY = 10, + QEMUD_CLIENT_PKT_DOMAIN_GET_INFO = 11, + QEMUD_CLIENT_PKT_DOMAIN_SAVE = 12, + QEMUD_CLIENT_PKT_DOMAIN_RESTORE = 13, + QEMUD_CLIENT_PKT_DUMP_XML = 14, + QEMUD_CLIENT_PKT_LIST_DEFINED_DOMAINS = 15, + QEMUD_CLIENT_PKT_NUM_DEFINED_DOMAINS = 16, + QEMUD_CLIENT_PKT_DOMAIN_START = 17, + QEMUD_CLIENT_PKT_DOMAIN_DEFINE = 18, + QEMUD_CLIENT_PKT_DOMAIN_UNDEFINE = 19, + QEMUD_CLIENT_PKT_NUM_NETWORKS = 20, + QEMUD_CLIENT_PKT_LIST_NETWORKS = 21, + QEMUD_CLIENT_PKT_NUM_DEFINED_NETWORKS = 22, + QEMUD_CLIENT_PKT_LIST_DEFINED_NETWORKS = 23, + QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_UUID = 24, + QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_NAME = 25, + QEMUD_CLIENT_PKT_NETWORK_CREATE = 26, + QEMUD_CLIENT_PKT_NETWORK_DEFINE = 27, + QEMUD_CLIENT_PKT_NETWORK_UNDEFINE = 28, + QEMUD_CLIENT_PKT_NETWORK_START = 29, + QEMUD_CLIENT_PKT_NETWORK_DESTROY = 30, + QEMUD_CLIENT_PKT_NETWORK_DUMP_XML = 31, + QEMUD_CLIENT_PKT_NETWORK_GET_BRIDGE_NAME = 32, + QEMUD_CLIENT_PKT_DOMAIN_GET_AUTOSTART = 33, + QEMUD_CLIENT_PKT_DOMAIN_SET_AUTOSTART = 34, + QEMUD_CLIENT_PKT_NETWORK_GET_AUTOSTART = 35, + QEMUD_CLIENT_PKT_NETWORK_SET_AUTOSTART = 36, + QEMUD_CLIENT_PKT_GET_CAPABILITIES = 37, + QEMUD_CLIENT_PKT_MAX = 38, +}; +typedef enum qemud_packet_client_data_type qemud_packet_client_data_type; + +enum qemud_packet_server_data_type { + QEMUD_SERVER_PKT_FAILURE = 0, + QEMUD_SERVER_PKT_GET_VERSION = 0 + 1, + QEMUD_SERVER_PKT_GET_NODEINFO = 0 + 2, + QEMUD_SERVER_PKT_LIST_DOMAINS = 0 + 3, + QEMUD_SERVER_PKT_NUM_DOMAINS = 0 + 4, + QEMUD_SERVER_PKT_DOMAIN_CREATE = 0 + 5, + QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_ID = 0 + 6, + QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_UUID = 0 + 7, + QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_NAME = 0 + 8, + QEMUD_SERVER_PKT_DOMAIN_SUSPEND = 0 + 9, + QEMUD_SERVER_PKT_DOMAIN_RESUME = 0 + 10, + QEMUD_SERVER_PKT_DOMAIN_DESTROY = 0 + 11, + QEMUD_SERVER_PKT_DOMAIN_GET_INFO = 0 + 12, + QEMUD_SERVER_PKT_DOMAIN_SAVE = 0 + 13, + QEMUD_SERVER_PKT_DOMAIN_RESTORE = 0 + 14, + QEMUD_SERVER_PKT_DUMP_XML = 0 + 15, + QEMUD_SERVER_PKT_LIST_DEFINED_DOMAINS = 0 + 16, + QEMUD_SERVER_PKT_NUM_DEFINED_DOMAINS = 0 + 17, + QEMUD_SERVER_PKT_DOMAIN_START = 0 + 18, + QEMUD_SERVER_PKT_DOMAIN_DEFINE = 0 + 19, + QEMUD_SERVER_PKT_DOMAIN_UNDEFINE = 0 + 20, + QEMUD_SERVER_PKT_NUM_NETWORKS = 0 + 21, + QEMUD_SERVER_PKT_LIST_NETWORKS = 0 + 22, + QEMUD_SERVER_PKT_NUM_DEFINED_NETWORKS = 0 + 23, + QEMUD_SERVER_PKT_LIST_DEFINED_NETWORKS = 0 + 24, + QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_UUID = 0 + 25, + QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_NAME = 0 + 26, + QEMUD_SERVER_PKT_NETWORK_CREATE = 0 + 27, + QEMUD_SERVER_PKT_NETWORK_DEFINE = 0 + 28, + QEMUD_SERVER_PKT_NETWORK_UNDEFINE = 0 + 29, + QEMUD_SERVER_PKT_NETWORK_START = 0 + 30, + QEMUD_SERVER_PKT_NETWORK_DESTROY = 0 + 31, + QEMUD_SERVER_PKT_NETWORK_DUMP_XML = 0 + 32, + QEMUD_SERVER_PKT_NETWORK_GET_BRIDGE_NAME = 0 + 33, + QEMUD_SERVER_PKT_DOMAIN_GET_AUTOSTART = 0 + 34, + QEMUD_SERVER_PKT_DOMAIN_SET_AUTOSTART = 0 + 35, + QEMUD_SERVER_PKT_NETWORK_GET_AUTOSTART = 0 + 36, + QEMUD_SERVER_PKT_NETWORK_SET_AUTOSTART = 0 + 37, + QEMUD_SERVER_PKT_GET_CAPABILITIES = 0 + 38, + QEMUD_SERVER_PKT_MAX = 0 + 39, +}; +typedef enum qemud_packet_server_data_type qemud_packet_server_data_type; + +struct qemud_packet_failure_reply { + uint32_t code; + char message[QEMUD_MAX_ERROR_LEN]; +}; +typedef struct qemud_packet_failure_reply qemud_packet_failure_reply; + +struct qemud_packet_get_version_reply { + uint32_t versionNum; +}; +typedef struct qemud_packet_get_version_reply qemud_packet_get_version_reply; + +struct qemud_packet_get_node_info_reply { + char model[32]; + uint32_t memory; + uint32_t cpus; + uint32_t mhz; + uint32_t nodes; + uint32_t sockets; + uint32_t cores; + uint32_t threads; +}; +typedef struct qemud_packet_get_node_info_reply qemud_packet_get_node_info_reply; + +struct qemud_packet_get_capabilities_reply { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_get_capabilities_reply qemud_packet_get_capabilities_reply; + +struct qemud_packet_list_domains_reply { + int32_t numDomains; + int32_t domains[QEMUD_MAX_NUM_DOMAINS]; +}; +typedef struct qemud_packet_list_domains_reply qemud_packet_list_domains_reply; + +struct qemud_packet_num_domains_reply { + int32_t numDomains; +}; +typedef struct qemud_packet_num_domains_reply qemud_packet_num_domains_reply; + +struct qemud_packet_domain_create_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_domain_create_request qemud_packet_domain_create_request; + +struct qemud_packet_domain_create_reply { + int32_t id; + u_char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_domain_create_reply qemud_packet_domain_create_reply; + +struct qemud_packet_domain_lookup_by_id_request { + int32_t id; +}; +typedef struct qemud_packet_domain_lookup_by_id_request qemud_packet_domain_lookup_by_id_request; + +struct qemud_packet_domain_lookup_by_id_reply { + u_char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_domain_lookup_by_id_reply qemud_packet_domain_lookup_by_id_reply; + +struct qemud_packet_domain_lookup_by_name_request { + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_domain_lookup_by_name_request qemud_packet_domain_lookup_by_name_request; + +struct qemud_packet_domain_lookup_by_name_reply { + int32_t id; + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_lookup_by_name_reply qemud_packet_domain_lookup_by_name_reply; + +struct qemud_packet_domain_lookup_by_uuid_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_lookup_by_uuid_request qemud_packet_domain_lookup_by_uuid_request; + +struct qemud_packet_domain_lookup_by_uuid_reply { + int32_t id; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_domain_lookup_by_uuid_reply qemud_packet_domain_lookup_by_uuid_reply; + +struct qemud_packet_domain_suspend_request { + int32_t id; +}; +typedef struct qemud_packet_domain_suspend_request qemud_packet_domain_suspend_request; + +struct qemud_packet_domain_resume_request { + int32_t id; +}; +typedef struct qemud_packet_domain_resume_request qemud_packet_domain_resume_request; + +struct qemud_packet_domain_destroy_request { + int32_t id; +}; +typedef struct qemud_packet_domain_destroy_request qemud_packet_domain_destroy_request; + +struct qemud_packet_domain_get_info_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_get_info_request qemud_packet_domain_get_info_request; + +struct qemud_packet_domain_get_info_reply { + uint64_t cpuTime; + uint32_t runstate; + uint32_t memory; + uint32_t maxmem; + uint32_t nrVirtCpu; +}; +typedef struct qemud_packet_domain_get_info_reply qemud_packet_domain_get_info_reply; + +struct qemud_packet_domain_save_request { + int32_t id; + char file[PATH_MAX]; +}; +typedef struct qemud_packet_domain_save_request qemud_packet_domain_save_request; + +struct qemud_packet_domain_restore_request { + char file[PATH_MAX]; +}; +typedef struct qemud_packet_domain_restore_request qemud_packet_domain_restore_request; + +struct qemud_packet_domain_restore_reply { + int32_t id; +}; +typedef struct qemud_packet_domain_restore_reply qemud_packet_domain_restore_reply; + +struct qemud_packet_domain_dump_xml_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_dump_xml_request qemud_packet_domain_dump_xml_request; + +struct qemud_packet_domain_dump_xml_reply { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_domain_dump_xml_reply qemud_packet_domain_dump_xml_reply; + +struct qemud_packet_list_defined_domains_reply { + uint32_t numDomains; + char domains[QEMUD_MAX_DOMAINS_NAME_BUF]; +}; +typedef struct qemud_packet_list_defined_domains_reply qemud_packet_list_defined_domains_reply; + +struct qemud_packet_num_defined_domains_reply { + uint32_t numDomains; +}; +typedef struct qemud_packet_num_defined_domains_reply qemud_packet_num_defined_domains_reply; + +struct qemud_packet_domain_start_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_start_request qemud_packet_domain_start_request; + +struct qemud_packet_domain_start_reply { + int32_t id; +}; +typedef struct qemud_packet_domain_start_reply qemud_packet_domain_start_reply; + +struct qemud_packet_domain_define_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_domain_define_request qemud_packet_domain_define_request; + +struct qemud_packet_domain_define_reply { + u_char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_domain_define_reply qemud_packet_domain_define_reply; + +struct qemud_packet_domain_undefine_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_undefine_request qemud_packet_domain_undefine_request; + +struct qemud_packet_num_networks_reply { + uint32_t numNetworks; +}; +typedef struct qemud_packet_num_networks_reply qemud_packet_num_networks_reply; + +struct qemud_packet_list_networks_reply { + uint32_t numNetworks; + char networks[QEMUD_MAX_NETWORKS_NAME_BUF]; +}; +typedef struct qemud_packet_list_networks_reply qemud_packet_list_networks_reply; + +struct qemud_packet_num_defined_networks_reply { + uint32_t numNetworks; +}; +typedef struct qemud_packet_num_defined_networks_reply qemud_packet_num_defined_networks_reply; + +struct qemud_packet_list_defined_networks_reply { + uint32_t numNetworks; + char networks[QEMUD_MAX_NETWORKS_NAME_BUF]; +}; +typedef struct qemud_packet_list_defined_networks_reply qemud_packet_list_defined_networks_reply; + +struct qemud_packet_network_lookup_by_name_request { + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_network_lookup_by_name_request qemud_packet_network_lookup_by_name_request; + +struct qemud_packet_network_lookup_by_name_reply { + int32_t id; + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_lookup_by_name_reply qemud_packet_network_lookup_by_name_reply; + +struct qemud_packet_network_lookup_by_uuid_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_lookup_by_uuid_request qemud_packet_network_lookup_by_uuid_request; + +struct qemud_packet_network_lookup_by_uuid_reply { + int32_t id; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_network_lookup_by_uuid_reply qemud_packet_network_lookup_by_uuid_reply; + +struct qemud_packet_network_create_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_network_create_request qemud_packet_network_create_request; + +struct qemud_packet_network_create_reply { + u_char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_network_create_reply qemud_packet_network_create_reply; + +struct qemud_packet_network_define_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_network_define_request qemud_packet_network_define_request; + +struct qemud_packet_network_define_reply { + u_char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +typedef struct qemud_packet_network_define_reply qemud_packet_network_define_reply; + +struct qemud_packet_network_undefine_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_undefine_request qemud_packet_network_undefine_request; + +struct qemud_packet_network_start_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_start_request qemud_packet_network_start_request; + +struct qemud_packet_network_destroy_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_destroy_request qemud_packet_network_destroy_request; + +struct qemud_packet_network_dump_xml_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_dump_xml_request qemud_packet_network_dump_xml_request; + +struct qemud_packet_network_dump_xml_reply { + char xml[QEMUD_MAX_XML_LEN]; +}; +typedef struct qemud_packet_network_dump_xml_reply qemud_packet_network_dump_xml_reply; + +struct qemud_packet_network_get_bridge_name_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_get_bridge_name_request qemud_packet_network_get_bridge_name_request; + +struct qemud_packet_network_get_bridge_name_reply { + char ifname[QEMUD_MAX_IFNAME_LEN]; +}; +typedef struct qemud_packet_network_get_bridge_name_reply qemud_packet_network_get_bridge_name_reply; + +struct qemud_packet_domain_get_autostart_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_domain_get_autostart_request qemud_packet_domain_get_autostart_request; + +struct qemud_packet_domain_get_autostart_reply { + uint32_t autostart; +}; +typedef struct qemud_packet_domain_get_autostart_reply qemud_packet_domain_get_autostart_reply; + +struct qemud_packet_domain_set_autostart_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; + uint32_t autostart; +}; +typedef struct qemud_packet_domain_set_autostart_request qemud_packet_domain_set_autostart_request; + +struct qemud_packet_network_get_autostart_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; +}; +typedef struct qemud_packet_network_get_autostart_request qemud_packet_network_get_autostart_request; + +struct qemud_packet_network_get_autostart_reply { + uint32_t autostart; +}; +typedef struct qemud_packet_network_get_autostart_reply qemud_packet_network_get_autostart_reply; + +struct qemud_packet_network_set_autostart_request { + u_char uuid[QEMUD_UUID_RAW_LEN]; + uint32_t autostart; +}; +typedef struct qemud_packet_network_set_autostart_request qemud_packet_network_set_autostart_request; + +struct qemud_packet_client_data { + qemud_packet_client_data_type type; + union { + qemud_packet_domain_create_request domainCreateRequest; + qemud_packet_domain_lookup_by_id_request domainLookupByIDRequest; + qemud_packet_domain_lookup_by_uuid_request domainLookupByUUIDRequest; + qemud_packet_domain_lookup_by_name_request domainLookupByNameRequest; + qemud_packet_domain_suspend_request domainSuspendRequest; + qemud_packet_domain_resume_request domainResumeRequest; + qemud_packet_domain_destroy_request domainDestroyRequest; + qemud_packet_domain_get_info_request domainGetInfoRequest; + qemud_packet_domain_save_request domainSaveRequest; + qemud_packet_domain_restore_request domainRestoreRequest; + qemud_packet_domain_dump_xml_request domainDumpXMLRequest; + qemud_packet_domain_start_request domainStartRequest; + qemud_packet_domain_define_request domainDefineRequest; + qemud_packet_domain_undefine_request domainUndefineRequest; + qemud_packet_network_lookup_by_uuid_request networkLookupByUUIDRequest; + qemud_packet_network_lookup_by_name_request networkLookupByNameRequest; + qemud_packet_network_create_request networkCreateRequest; + qemud_packet_network_define_request networkDefineRequest; + qemud_packet_network_undefine_request networkUndefineRequest; + qemud_packet_network_start_request networkStartRequest; + qemud_packet_network_destroy_request networkDestroyRequest; + qemud_packet_network_dump_xml_request networkDumpXMLRequest; + qemud_packet_network_get_bridge_name_request networkGetBridgeNameRequest; + qemud_packet_domain_get_autostart_request domainGetAutostartRequest; + qemud_packet_domain_set_autostart_request domainSetAutostartRequest; + qemud_packet_network_get_autostart_request networkGetAutostartRequest; + qemud_packet_network_set_autostart_request networkSetAutostartRequest; + } qemud_packet_client_data_u; +}; +typedef struct qemud_packet_client_data qemud_packet_client_data; + +struct qemud_packet_server_data { + qemud_packet_server_data_type type; + union { + qemud_packet_failure_reply failureReply; + qemud_packet_get_version_reply getVersionReply; + qemud_packet_get_node_info_reply getNodeInfoReply; + qemud_packet_list_domains_reply listDomainsReply; + qemud_packet_num_domains_reply numDomainsReply; + qemud_packet_domain_create_reply domainCreateReply; + qemud_packet_domain_lookup_by_id_reply domainLookupByIDReply; + qemud_packet_domain_lookup_by_uuid_reply domainLookupByUUIDReply; + qemud_packet_domain_lookup_by_name_reply domainLookupByNameReply; + qemud_packet_domain_get_info_reply domainGetInfoReply; + qemud_packet_domain_restore_reply domainRestoreReply; + qemud_packet_domain_dump_xml_reply domainDumpXMLReply; + qemud_packet_list_defined_domains_reply listDefinedDomainsReply; + qemud_packet_num_defined_domains_reply numDefinedDomainsReply; + qemud_packet_domain_start_reply domainStartReply; + qemud_packet_domain_define_reply domainDefineReply; + qemud_packet_num_networks_reply numNetworksReply; + qemud_packet_list_networks_reply listNetworksReply; + qemud_packet_num_defined_networks_reply numDefinedNetworksReply; + qemud_packet_list_defined_networks_reply listDefinedNetworksReply; + qemud_packet_network_lookup_by_uuid_reply networkLookupByUUIDReply; + qemud_packet_network_lookup_by_name_reply networkLookupByNameReply; + qemud_packet_network_create_reply networkCreateReply; + qemud_packet_network_define_reply networkDefineReply; + qemud_packet_network_dump_xml_reply networkDumpXMLReply; + qemud_packet_network_get_bridge_name_reply networkGetBridgeNameReply; + qemud_packet_domain_get_autostart_reply domainGetAutostartReply; + qemud_packet_network_get_autostart_reply networkGetAutostartReply; + qemud_packet_get_capabilities_reply getCapabilitiesReply; + } qemud_packet_server_data_u; +}; +typedef struct qemud_packet_server_data qemud_packet_server_data; + +struct qemud_packet_client { + uint32_t serial; + struct qemud_packet_client_data data; +}; +typedef struct qemud_packet_client qemud_packet_client; + +struct qemud_packet_server { + uint32_t serial; + uint32_t inReplyTo; + struct qemud_packet_server_data data; +}; +typedef struct qemud_packet_server qemud_packet_server; +#define QEMUD_PROGRAM 0x20001A64 +#define QEMUD_PKT_HEADER_XDR_LEN 8 -/* Each packets has at least a fixed size header. - * - * All data required to be network byte order - * to 32-bit boundaries */ struct qemud_packet_header { - uint32_t type; - /* Stores the size of the data struct matching - the type arg. - Must be <= sizeof(union qemudPacketData) */ - uint32_t dataSize; + uint32_t length; + uint32_t prog; }; +typedef struct qemud_packet_header qemud_packet_header; -/* Most packets also have some message specific data - * All data required to be network byte order, padded - * to 32-bit boundaries */ -union qemud_packet_data { - struct { - int32_t code; - char message[QEMUD_MAX_ERROR_LEN]; - } failureReply; - struct { - int32_t version; - } getVersionReply; - struct { - char model[32]; - uint32_t memory; - uint32_t cpus; - uint32_t mhz; - uint32_t nodes; - uint32_t sockets; - uint32_t cores; - uint32_t threads; - } getNodeInfoReply; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } getCapabilitiesReply; - struct { - int32_t numDomains; - int32_t domains[QEMUD_MAX_NUM_DOMAINS]; - } listDomainsReply; - struct { - int32_t numDomains; - } numDomainsReply; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } domainCreateRequest; - struct { - int32_t id; - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - char name[QEMUD_MAX_NAME_LEN]; - } domainCreateReply; - struct { - int32_t id; - } domainLookupByIDRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - char name[QEMUD_MAX_NAME_LEN]; - } domainLookupByIDReply; - struct { - char name[QEMUD_MAX_NAME_LEN]; - } domainLookupByNameRequest; - struct { - int32_t id; - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainLookupByNameReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainLookupByUUIDRequest; - struct { - int32_t id; - char name[QEMUD_MAX_NAME_LEN]; - } domainLookupByUUIDReply; - struct { - int32_t id; - } domainSuspendRequest; - struct { - int32_t id; - } domainResumeRequest; - struct { - } domainResumeReply; - struct { - int32_t id; - } domainDestroyRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainGetInfoRequest; - struct { - uint64_t cpuTime; - int32_t runstate; - uint32_t memory; - uint32_t maxmem; - uint32_t nrVirtCpu; - } domainGetInfoReply; - struct { - int32_t id; - char file[PATH_MAX]; - } domainSaveRequest; - struct { - char file[PATH_MAX]; - } domainRestoreRequest; - struct { - int32_t id; - } domainRestoreReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainDumpXMLRequest; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } domainDumpXMLReply; - struct { - int32_t numDomains; - char domains[QEMUD_MAX_NUM_DOMAINS][QEMUD_MAX_NAME_LEN]; - } listDefinedDomainsReply; - struct { - int32_t numDomains; - } numDefinedDomainsReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainStartRequest; - struct { - int32_t id; - } domainStartReply; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } domainDefineRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - char name[QEMUD_MAX_NAME_LEN]; - } domainDefineReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainUndefineRequest; - struct { - int32_t numNetworks; - } numNetworksReply; - struct { - int32_t numNetworks; - char networks[QEMUD_MAX_NUM_NETWORKS][QEMUD_MAX_NAME_LEN]; - } listNetworksReply; - struct { - int32_t numNetworks; - } numDefinedNetworksReply; - struct { - int32_t numNetworks; - char networks[QEMUD_MAX_NUM_NETWORKS][QEMUD_MAX_NAME_LEN]; - } listDefinedNetworksReply; - struct { - char name[QEMUD_MAX_NAME_LEN]; - } networkLookupByNameRequest; - struct { - int32_t id; - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkLookupByNameReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkLookupByUUIDRequest; - struct { - int32_t id; - char name[QEMUD_MAX_NAME_LEN]; - } networkLookupByUUIDReply; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } networkCreateRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - char name[QEMUD_MAX_NAME_LEN]; - } networkCreateReply; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } networkDefineRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - char name[QEMUD_MAX_NAME_LEN]; - } networkDefineReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkUndefineRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkStartRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkDestroyRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkDumpXMLRequest; - struct { - char xml[QEMUD_MAX_XML_LEN]; - } networkDumpXMLReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkGetBridgeNameRequest; - struct { - char ifname[QEMUD_MAX_IFNAME_LEN]; - } networkGetBridgeNameReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } domainGetAutostartRequest; - struct { - int autostart; - } domainGetAutostartReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - unsigned int autostart : 1; - } domainSetAutostartRequest; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - } networkGetAutostartRequest; - struct { - unsigned int autostart : 1; - } networkGetAutostartReply; - struct { - unsigned char uuid[QEMUD_UUID_RAW_LEN]; - unsigned int autostart : 1; - } networkSetAutostartRequest; -}; +/* the xdr functions */ -/* Each packet has header & data */ -struct qemud_packet { - struct qemud_packet_header header; - union qemud_packet_data data; -}; +#if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_qemud_domain_runstate (XDR *, qemud_domain_runstate*); +extern bool_t xdr_qemud_packet_client_data_type (XDR *, qemud_packet_client_data_type*); +extern bool_t xdr_qemud_packet_server_data_type (XDR *, qemud_packet_server_data_type*); +extern bool_t xdr_qemud_packet_failure_reply (XDR *, qemud_packet_failure_reply*); +extern bool_t xdr_qemud_packet_get_version_reply (XDR *, qemud_packet_get_version_reply*); +extern bool_t xdr_qemud_packet_get_node_info_reply (XDR *, qemud_packet_get_node_info_reply*); +extern bool_t xdr_qemud_packet_get_capabilities_reply (XDR *, qemud_packet_get_capabilities_reply*); +extern bool_t xdr_qemud_packet_list_domains_reply (XDR *, qemud_packet_list_domains_reply*); +extern bool_t xdr_qemud_packet_num_domains_reply (XDR *, qemud_packet_num_domains_reply*); +extern bool_t xdr_qemud_packet_domain_create_request (XDR *, qemud_packet_domain_create_request*); +extern bool_t xdr_qemud_packet_domain_create_reply (XDR *, qemud_packet_domain_create_reply*); +extern bool_t xdr_qemud_packet_domain_lookup_by_id_request (XDR *, qemud_packet_domain_lookup_by_id_request*); +extern bool_t xdr_qemud_packet_domain_lookup_by_id_reply (XDR *, qemud_packet_domain_lookup_by_id_reply*); +extern bool_t xdr_qemud_packet_domain_lookup_by_name_request (XDR *, qemud_packet_domain_lookup_by_name_request*); +extern bool_t xdr_qemud_packet_domain_lookup_by_name_reply (XDR *, qemud_packet_domain_lookup_by_name_reply*); +extern bool_t xdr_qemud_packet_domain_lookup_by_uuid_request (XDR *, qemud_packet_domain_lookup_by_uuid_request*); +extern bool_t xdr_qemud_packet_domain_lookup_by_uuid_reply (XDR *, qemud_packet_domain_lookup_by_uuid_reply*); +extern bool_t xdr_qemud_packet_domain_suspend_request (XDR *, qemud_packet_domain_suspend_request*); +extern bool_t xdr_qemud_packet_domain_resume_request (XDR *, qemud_packet_domain_resume_request*); +extern bool_t xdr_qemud_packet_domain_destroy_request (XDR *, qemud_packet_domain_destroy_request*); +extern bool_t xdr_qemud_packet_domain_get_info_request (XDR *, qemud_packet_domain_get_info_request*); +extern bool_t xdr_qemud_packet_domain_get_info_reply (XDR *, qemud_packet_domain_get_info_reply*); +extern bool_t xdr_qemud_packet_domain_save_request (XDR *, qemud_packet_domain_save_request*); +extern bool_t xdr_qemud_packet_domain_restore_request (XDR *, qemud_packet_domain_restore_request*); +extern bool_t xdr_qemud_packet_domain_restore_reply (XDR *, qemud_packet_domain_restore_reply*); +extern bool_t xdr_qemud_packet_domain_dump_xml_request (XDR *, qemud_packet_domain_dump_xml_request*); +extern bool_t xdr_qemud_packet_domain_dump_xml_reply (XDR *, qemud_packet_domain_dump_xml_reply*); +extern bool_t xdr_qemud_packet_list_defined_domains_reply (XDR *, qemud_packet_list_defined_domains_reply*); +extern bool_t xdr_qemud_packet_num_defined_domains_reply (XDR *, qemud_packet_num_defined_domains_reply*); +extern bool_t xdr_qemud_packet_domain_start_request (XDR *, qemud_packet_domain_start_request*); +extern bool_t xdr_qemud_packet_domain_start_reply (XDR *, qemud_packet_domain_start_reply*); +extern bool_t xdr_qemud_packet_domain_define_request (XDR *, qemud_packet_domain_define_request*); +extern bool_t xdr_qemud_packet_domain_define_reply (XDR *, qemud_packet_domain_define_reply*); +extern bool_t xdr_qemud_packet_domain_undefine_request (XDR *, qemud_packet_domain_undefine_request*); +extern bool_t xdr_qemud_packet_num_networks_reply (XDR *, qemud_packet_num_networks_reply*); +extern bool_t xdr_qemud_packet_list_networks_reply (XDR *, qemud_packet_list_networks_reply*); +extern bool_t xdr_qemud_packet_num_defined_networks_reply (XDR *, qemud_packet_num_defined_networks_reply*); +extern bool_t xdr_qemud_packet_list_defined_networks_reply (XDR *, qemud_packet_list_defined_networks_reply*); +extern bool_t xdr_qemud_packet_network_lookup_by_name_request (XDR *, qemud_packet_network_lookup_by_name_request*); +extern bool_t xdr_qemud_packet_network_lookup_by_name_reply (XDR *, qemud_packet_network_lookup_by_name_reply*); +extern bool_t xdr_qemud_packet_network_lookup_by_uuid_request (XDR *, qemud_packet_network_lookup_by_uuid_request*); +extern bool_t xdr_qemud_packet_network_lookup_by_uuid_reply (XDR *, qemud_packet_network_lookup_by_uuid_reply*); +extern bool_t xdr_qemud_packet_network_create_request (XDR *, qemud_packet_network_create_request*); +extern bool_t xdr_qemud_packet_network_create_reply (XDR *, qemud_packet_network_create_reply*); +extern bool_t xdr_qemud_packet_network_define_request (XDR *, qemud_packet_network_define_request*); +extern bool_t xdr_qemud_packet_network_define_reply (XDR *, qemud_packet_network_define_reply*); +extern bool_t xdr_qemud_packet_network_undefine_request (XDR *, qemud_packet_network_undefine_request*); +extern bool_t xdr_qemud_packet_network_start_request (XDR *, qemud_packet_network_start_request*); +extern bool_t xdr_qemud_packet_network_destroy_request (XDR *, qemud_packet_network_destroy_request*); +extern bool_t xdr_qemud_packet_network_dump_xml_request (XDR *, qemud_packet_network_dump_xml_request*); +extern bool_t xdr_qemud_packet_network_dump_xml_reply (XDR *, qemud_packet_network_dump_xml_reply*); +extern bool_t xdr_qemud_packet_network_get_bridge_name_request (XDR *, qemud_packet_network_get_bridge_name_request*); +extern bool_t xdr_qemud_packet_network_get_bridge_name_reply (XDR *, qemud_packet_network_get_bridge_name_reply*); +extern bool_t xdr_qemud_packet_domain_get_autostart_request (XDR *, qemud_packet_domain_get_autostart_request*); +extern bool_t xdr_qemud_packet_domain_get_autostart_reply (XDR *, qemud_packet_domain_get_autostart_reply*); +extern bool_t xdr_qemud_packet_domain_set_autostart_request (XDR *, qemud_packet_domain_set_autostart_request*); +extern bool_t xdr_qemud_packet_network_get_autostart_request (XDR *, qemud_packet_network_get_autostart_request*); +extern bool_t xdr_qemud_packet_network_get_autostart_reply (XDR *, qemud_packet_network_get_autostart_reply*); +extern bool_t xdr_qemud_packet_network_set_autostart_request (XDR *, qemud_packet_network_set_autostart_request*); +extern bool_t xdr_qemud_packet_client_data (XDR *, qemud_packet_client_data*); +extern bool_t xdr_qemud_packet_server_data (XDR *, qemud_packet_server_data*); +extern bool_t xdr_qemud_packet_client (XDR *, qemud_packet_client*); +extern bool_t xdr_qemud_packet_server (XDR *, qemud_packet_server*); +extern bool_t xdr_qemud_packet_header (XDR *, qemud_packet_header*); +#else /* K&R C */ +extern bool_t xdr_qemud_domain_runstate (); +extern bool_t xdr_qemud_packet_client_data_type (); +extern bool_t xdr_qemud_packet_server_data_type (); +extern bool_t xdr_qemud_packet_failure_reply (); +extern bool_t xdr_qemud_packet_get_version_reply (); +extern bool_t xdr_qemud_packet_get_node_info_reply (); +extern bool_t xdr_qemud_packet_get_capabilities_reply (); +extern bool_t xdr_qemud_packet_list_domains_reply (); +extern bool_t xdr_qemud_packet_num_domains_reply (); +extern bool_t xdr_qemud_packet_domain_create_request (); +extern bool_t xdr_qemud_packet_domain_create_reply (); +extern bool_t xdr_qemud_packet_domain_lookup_by_id_request (); +extern bool_t xdr_qemud_packet_domain_lookup_by_id_reply (); +extern bool_t xdr_qemud_packet_domain_lookup_by_name_request (); +extern bool_t xdr_qemud_packet_domain_lookup_by_name_reply (); +extern bool_t xdr_qemud_packet_domain_lookup_by_uuid_request (); +extern bool_t xdr_qemud_packet_domain_lookup_by_uuid_reply (); +extern bool_t xdr_qemud_packet_domain_suspend_request (); +extern bool_t xdr_qemud_packet_domain_resume_request (); +extern bool_t xdr_qemud_packet_domain_destroy_request (); +extern bool_t xdr_qemud_packet_domain_get_info_request (); +extern bool_t xdr_qemud_packet_domain_get_info_reply (); +extern bool_t xdr_qemud_packet_domain_save_request (); +extern bool_t xdr_qemud_packet_domain_restore_request (); +extern bool_t xdr_qemud_packet_domain_restore_reply (); +extern bool_t xdr_qemud_packet_domain_dump_xml_request (); +extern bool_t xdr_qemud_packet_domain_dump_xml_reply (); +extern bool_t xdr_qemud_packet_list_defined_domains_reply (); +extern bool_t xdr_qemud_packet_num_defined_domains_reply (); +extern bool_t xdr_qemud_packet_domain_start_request (); +extern bool_t xdr_qemud_packet_domain_start_reply (); +extern bool_t xdr_qemud_packet_domain_define_request (); +extern bool_t xdr_qemud_packet_domain_define_reply (); +extern bool_t xdr_qemud_packet_domain_undefine_request (); +extern bool_t xdr_qemud_packet_num_networks_reply (); +extern bool_t xdr_qemud_packet_list_networks_reply (); +extern bool_t xdr_qemud_packet_num_defined_networks_reply (); +extern bool_t xdr_qemud_packet_list_defined_networks_reply (); +extern bool_t xdr_qemud_packet_network_lookup_by_name_request (); +extern bool_t xdr_qemud_packet_network_lookup_by_name_reply (); +extern bool_t xdr_qemud_packet_network_lookup_by_uuid_request (); +extern bool_t xdr_qemud_packet_network_lookup_by_uuid_reply (); +extern bool_t xdr_qemud_packet_network_create_request (); +extern bool_t xdr_qemud_packet_network_create_reply (); +extern bool_t xdr_qemud_packet_network_define_request (); +extern bool_t xdr_qemud_packet_network_define_reply (); +extern bool_t xdr_qemud_packet_network_undefine_request (); +extern bool_t xdr_qemud_packet_network_start_request (); +extern bool_t xdr_qemud_packet_network_destroy_request (); +extern bool_t xdr_qemud_packet_network_dump_xml_request (); +extern bool_t xdr_qemud_packet_network_dump_xml_reply (); +extern bool_t xdr_qemud_packet_network_get_bridge_name_request (); +extern bool_t xdr_qemud_packet_network_get_bridge_name_reply (); +extern bool_t xdr_qemud_packet_domain_get_autostart_request (); +extern bool_t xdr_qemud_packet_domain_get_autostart_reply (); +extern bool_t xdr_qemud_packet_domain_set_autostart_request (); +extern bool_t xdr_qemud_packet_network_get_autostart_request (); +extern bool_t xdr_qemud_packet_network_get_autostart_reply (); +extern bool_t xdr_qemud_packet_network_set_autostart_request (); +extern bool_t xdr_qemud_packet_client_data (); +extern bool_t xdr_qemud_packet_server_data (); +extern bool_t xdr_qemud_packet_client (); +extern bool_t xdr_qemud_packet_server (); +extern bool_t xdr_qemud_packet_header (); +#endif /* K&R C */ + +#ifdef __cplusplus +} #endif - -/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ +#endif /* !_PROTOCOL_H_RPCGEN */ diff --git a/qemud/protocol.x b/qemud/protocol.x new file mode 100644 index 0000000000..d88519b97f --- /dev/null +++ b/qemud/protocol.x @@ -0,0 +1,614 @@ +/* -*- c -*- + * protocol_xdr.x: wire protocol message format & data structures + * + * Copyright (C) 2006, 2007 Red Hat, Inc. + * Copyright (C) 2006 Daniel P. Berrange + * + * 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: Daniel P. Berrange + */ + +const QEMUD_UUID_RAW_LEN = 16; +const QEMUD_MAX_NAME_LEN = 50; +const QEMUD_MAX_XML_LEN = 4096; +/*#define QEMUD_MAX_IFNAME_LEN IF_NAMESIZE */ +const QEMUD_MAX_IFNAME_LEN = 50; + +const QEMUD_MAX_NUM_DOMAINS = 100; +const QEMUD_MAX_NUM_NETWORKS = 100; + +/* + * Damn, we can't do multiplcation when declaring + * constants with XDR ! + * These two should be QEMUD_MAX_NUM_DOMAIN * QEMUD_MAX_NAME_LEN + */ +const QEMUD_MAX_DOMAINS_NAME_BUF = 5000; +const QEMUD_MAX_NETWORKS_NAME_BUF = 5000; + +const QEMUD_MAX_ERROR_LEN = 1024; + +/* Possible guest VM states */ +enum qemud_domain_runstate { + QEMUD_STATE_RUNNING = 1, + QEMUD_STATE_PAUSED, + QEMUD_STATE_STOPPED +}; + +/* Message sent by a client */ +enum qemud_packet_client_data_type { + QEMUD_CLIENT_PKT_GET_VERSION, + QEMUD_CLIENT_PKT_GET_NODEINFO, + QEMUD_CLIENT_PKT_LIST_DOMAINS, + QEMUD_CLIENT_PKT_NUM_DOMAINS, + QEMUD_CLIENT_PKT_DOMAIN_CREATE, + QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_ID, + QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_UUID, + QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_NAME, + QEMUD_CLIENT_PKT_DOMAIN_SUSPEND, + QEMUD_CLIENT_PKT_DOMAIN_RESUME, + QEMUD_CLIENT_PKT_DOMAIN_DESTROY, + QEMUD_CLIENT_PKT_DOMAIN_GET_INFO, + QEMUD_CLIENT_PKT_DOMAIN_SAVE, + QEMUD_CLIENT_PKT_DOMAIN_RESTORE, + QEMUD_CLIENT_PKT_DUMP_XML, + QEMUD_CLIENT_PKT_LIST_DEFINED_DOMAINS, + QEMUD_CLIENT_PKT_NUM_DEFINED_DOMAINS, + QEMUD_CLIENT_PKT_DOMAIN_START, + QEMUD_CLIENT_PKT_DOMAIN_DEFINE, + QEMUD_CLIENT_PKT_DOMAIN_UNDEFINE, + QEMUD_CLIENT_PKT_NUM_NETWORKS, + QEMUD_CLIENT_PKT_LIST_NETWORKS, + QEMUD_CLIENT_PKT_NUM_DEFINED_NETWORKS, + QEMUD_CLIENT_PKT_LIST_DEFINED_NETWORKS, + QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_UUID, + QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_NAME, + QEMUD_CLIENT_PKT_NETWORK_CREATE, + QEMUD_CLIENT_PKT_NETWORK_DEFINE, + QEMUD_CLIENT_PKT_NETWORK_UNDEFINE, + QEMUD_CLIENT_PKT_NETWORK_START, + QEMUD_CLIENT_PKT_NETWORK_DESTROY, + QEMUD_CLIENT_PKT_NETWORK_DUMP_XML, + QEMUD_CLIENT_PKT_NETWORK_GET_BRIDGE_NAME, + QEMUD_CLIENT_PKT_DOMAIN_GET_AUTOSTART, + QEMUD_CLIENT_PKT_DOMAIN_SET_AUTOSTART, + QEMUD_CLIENT_PKT_NETWORK_GET_AUTOSTART, + QEMUD_CLIENT_PKT_NETWORK_SET_AUTOSTART, + QEMUD_CLIENT_PKT_GET_CAPABILITIES, + + QEMUD_CLIENT_PKT_MAX +}; + +/* Messages sent by a server */ +enum qemud_packet_server_data_type { + QEMUD_SERVER_PKT_FAILURE = 0, + QEMUD_SERVER_PKT_GET_VERSION, + QEMUD_SERVER_PKT_GET_NODEINFO, + QEMUD_SERVER_PKT_LIST_DOMAINS, + QEMUD_SERVER_PKT_NUM_DOMAINS, + QEMUD_SERVER_PKT_DOMAIN_CREATE, + QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_ID, + QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_UUID, + QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_NAME, + QEMUD_SERVER_PKT_DOMAIN_SUSPEND, + QEMUD_SERVER_PKT_DOMAIN_RESUME, + QEMUD_SERVER_PKT_DOMAIN_DESTROY, + QEMUD_SERVER_PKT_DOMAIN_GET_INFO, + QEMUD_SERVER_PKT_DOMAIN_SAVE, + QEMUD_SERVER_PKT_DOMAIN_RESTORE, + QEMUD_SERVER_PKT_DUMP_XML, + QEMUD_SERVER_PKT_LIST_DEFINED_DOMAINS, + QEMUD_SERVER_PKT_NUM_DEFINED_DOMAINS, + QEMUD_SERVER_PKT_DOMAIN_START, + QEMUD_SERVER_PKT_DOMAIN_DEFINE, + QEMUD_SERVER_PKT_DOMAIN_UNDEFINE, + QEMUD_SERVER_PKT_NUM_NETWORKS, + QEMUD_SERVER_PKT_LIST_NETWORKS, + QEMUD_SERVER_PKT_NUM_DEFINED_NETWORKS, + QEMUD_SERVER_PKT_LIST_DEFINED_NETWORKS, + QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_UUID, + QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_NAME, + QEMUD_SERVER_PKT_NETWORK_CREATE, + QEMUD_SERVER_PKT_NETWORK_DEFINE, + QEMUD_SERVER_PKT_NETWORK_UNDEFINE, + QEMUD_SERVER_PKT_NETWORK_START, + QEMUD_SERVER_PKT_NETWORK_DESTROY, + QEMUD_SERVER_PKT_NETWORK_DUMP_XML, + QEMUD_SERVER_PKT_NETWORK_GET_BRIDGE_NAME, + QEMUD_SERVER_PKT_DOMAIN_GET_AUTOSTART, + QEMUD_SERVER_PKT_DOMAIN_SET_AUTOSTART, + QEMUD_SERVER_PKT_NETWORK_GET_AUTOSTART, + QEMUD_SERVER_PKT_NETWORK_SET_AUTOSTART, + QEMUD_SERVER_PKT_GET_CAPABILITIES, + + QEMUD_SERVER_PKT_MAX +}; + + + +struct qemud_packet_failure_reply { + uint32_t code; + char message[QEMUD_MAX_ERROR_LEN]; +}; + +struct qemud_packet_get_version_reply { + uint32_t versionNum; +}; + +struct qemud_packet_get_node_info_reply { + char model[32]; + uint32_t memory; + uint32_t cpus; + uint32_t mhz; + uint32_t nodes; + uint32_t sockets; + uint32_t cores; + uint32_t threads; +}; + +struct qemud_packet_get_capabilities_reply { + char xml[QEMUD_MAX_XML_LEN]; +}; + +struct qemud_packet_list_domains_reply { + int32_t numDomains; + int32_t domains[QEMUD_MAX_NUM_DOMAINS]; +}; + +struct qemud_packet_num_domains_reply{ + int32_t numDomains; +}; + +struct qemud_packet_domain_create_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +struct qemud_packet_domain_create_reply { + int32_t id; + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_domain_lookup_by_id_request { + int32_t id; +}; + +struct qemud_packet_domain_lookup_by_id_reply { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; + +struct qemud_packet_domain_lookup_by_name_request { + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_domain_lookup_by_name_reply { + int32_t id; + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_domain_lookup_by_uuid_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; + +struct qemud_packet_domain_lookup_by_uuid_reply { + int32_t id; + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_domain_suspend_request { + int32_t id; +}; +struct qemud_packet_domain_resume_request { + int32_t id; +}; +struct qemud_packet_domain_destroy_request { + int32_t id; +}; +struct qemud_packet_domain_get_info_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_domain_get_info_reply { + uint64_t cpuTime; + uint32_t runstate; + uint32_t memory; + uint32_t maxmem; + uint32_t nrVirtCpu; +}; +struct qemud_packet_domain_save_request { + int32_t id; + char file[PATH_MAX]; +}; +struct qemud_packet_domain_restore_request { + char file[PATH_MAX]; +}; +struct qemud_packet_domain_restore_reply { + int32_t id; +}; +struct qemud_packet_domain_dump_xml_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_domain_dump_xml_reply { + char xml[QEMUD_MAX_XML_LEN]; +}; +struct qemud_packet_list_defined_domains_reply{ + uint32_t numDomains; + char domains[QEMUD_MAX_DOMAINS_NAME_BUF]; +}; +struct qemud_packet_num_defined_domains_reply{ + uint32_t numDomains; +}; +struct qemud_packet_domain_start_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_domain_start_reply { + int32_t id; +}; +struct qemud_packet_domain_define_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +struct qemud_packet_domain_define_reply { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_domain_undefine_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_num_networks_reply { + uint32_t numNetworks; +}; + +struct qemud_packet_list_networks_reply { + uint32_t numNetworks; + char networks[QEMUD_MAX_NETWORKS_NAME_BUF]; +}; + +struct qemud_packet_num_defined_networks_reply { + uint32_t numNetworks; +}; + +struct qemud_packet_list_defined_networks_reply { + uint32_t numNetworks; + char networks[QEMUD_MAX_NETWORKS_NAME_BUF]; +}; +struct qemud_packet_network_lookup_by_name_request { + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_network_lookup_by_name_reply { + int32_t id; + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_lookup_by_uuid_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_lookup_by_uuid_reply { + int32_t id; + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_network_create_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +struct qemud_packet_network_create_reply { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_network_define_request { + char xml[QEMUD_MAX_XML_LEN]; +}; +struct qemud_packet_network_define_reply { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + char name[QEMUD_MAX_NAME_LEN]; +}; +struct qemud_packet_network_undefine_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_start_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_destroy_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_dump_xml_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_dump_xml_reply { + char xml[QEMUD_MAX_XML_LEN]; +}; +struct qemud_packet_network_get_bridge_name_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_get_bridge_name_reply { + char ifname[QEMUD_MAX_IFNAME_LEN]; +}; +struct qemud_packet_domain_get_autostart_request{ + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_domain_get_autostart_reply { + uint32_t autostart; +}; +struct qemud_packet_domain_set_autostart_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + uint32_t autostart; +}; + +struct qemud_packet_network_get_autostart_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; +}; +struct qemud_packet_network_get_autostart_reply { + uint32_t autostart; +}; +struct qemud_packet_network_set_autostart_request { + unsigned char uuid[QEMUD_UUID_RAW_LEN]; + uint32_t autostart; +}; + +union qemud_packet_client_data switch (qemud_packet_client_data_type type) { + case QEMUD_CLIENT_PKT_GET_VERSION: + void; + + case QEMUD_CLIENT_PKT_GET_NODEINFO: + void; + + case QEMUD_CLIENT_PKT_LIST_DOMAINS: + void; + + case QEMUD_CLIENT_PKT_NUM_DOMAINS: + void; + + case QEMUD_CLIENT_PKT_DOMAIN_CREATE: + qemud_packet_domain_create_request domainCreateRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_ID: + qemud_packet_domain_lookup_by_id_request domainLookupByIDRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_UUID: + qemud_packet_domain_lookup_by_uuid_request domainLookupByUUIDRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_LOOKUP_BY_NAME: + qemud_packet_domain_lookup_by_name_request domainLookupByNameRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_SUSPEND: + qemud_packet_domain_suspend_request domainSuspendRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_RESUME: + qemud_packet_domain_resume_request domainResumeRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_DESTROY: + qemud_packet_domain_destroy_request domainDestroyRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_GET_INFO: + qemud_packet_domain_get_info_request domainGetInfoRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_SAVE: + qemud_packet_domain_save_request domainSaveRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_RESTORE: + qemud_packet_domain_restore_request domainRestoreRequest; + + case QEMUD_CLIENT_PKT_DUMP_XML: + qemud_packet_domain_dump_xml_request domainDumpXMLRequest; + + case QEMUD_CLIENT_PKT_LIST_DEFINED_DOMAINS: + void; + + case QEMUD_CLIENT_PKT_NUM_DEFINED_DOMAINS: + void; + + case QEMUD_CLIENT_PKT_DOMAIN_START: + qemud_packet_domain_start_request domainStartRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_DEFINE: + qemud_packet_domain_define_request domainDefineRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_UNDEFINE: + qemud_packet_domain_undefine_request domainUndefineRequest; + + case QEMUD_CLIENT_PKT_NUM_NETWORKS: + void; + + case QEMUD_CLIENT_PKT_LIST_NETWORKS: + void; + + case QEMUD_CLIENT_PKT_NUM_DEFINED_NETWORKS: + void; + + case QEMUD_CLIENT_PKT_LIST_DEFINED_NETWORKS: + void; + + case QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_UUID: + qemud_packet_network_lookup_by_uuid_request networkLookupByUUIDRequest; + + case QEMUD_CLIENT_PKT_NETWORK_LOOKUP_BY_NAME: + qemud_packet_network_lookup_by_name_request networkLookupByNameRequest; + + case QEMUD_CLIENT_PKT_NETWORK_CREATE: + qemud_packet_network_create_request networkCreateRequest; + + case QEMUD_CLIENT_PKT_NETWORK_DEFINE: + qemud_packet_network_define_request networkDefineRequest; + + case QEMUD_CLIENT_PKT_NETWORK_UNDEFINE: + qemud_packet_network_undefine_request networkUndefineRequest; + + case QEMUD_CLIENT_PKT_NETWORK_START: + qemud_packet_network_start_request networkStartRequest; + + case QEMUD_CLIENT_PKT_NETWORK_DESTROY: + qemud_packet_network_destroy_request networkDestroyRequest; + + case QEMUD_CLIENT_PKT_NETWORK_DUMP_XML: + qemud_packet_network_dump_xml_request networkDumpXMLRequest; + + case QEMUD_CLIENT_PKT_NETWORK_GET_BRIDGE_NAME: + qemud_packet_network_get_bridge_name_request networkGetBridgeNameRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_GET_AUTOSTART: + qemud_packet_domain_get_autostart_request domainGetAutostartRequest; + + case QEMUD_CLIENT_PKT_DOMAIN_SET_AUTOSTART: + qemud_packet_domain_set_autostart_request domainSetAutostartRequest; + + case QEMUD_CLIENT_PKT_NETWORK_GET_AUTOSTART: + qemud_packet_network_get_autostart_request networkGetAutostartRequest; + + case QEMUD_CLIENT_PKT_NETWORK_SET_AUTOSTART: + qemud_packet_network_set_autostart_request networkSetAutostartRequest; + + case QEMUD_CLIENT_PKT_GET_CAPABILITIES: + void; + +}; + +union qemud_packet_server_data switch (qemud_packet_server_data_type type) { + case QEMUD_SERVER_PKT_FAILURE: + qemud_packet_failure_reply failureReply; + + case QEMUD_SERVER_PKT_GET_VERSION: + qemud_packet_get_version_reply getVersionReply; + + case QEMUD_SERVER_PKT_GET_NODEINFO: + qemud_packet_get_node_info_reply getNodeInfoReply; + + case QEMUD_SERVER_PKT_LIST_DOMAINS: + qemud_packet_list_domains_reply listDomainsReply; + + case QEMUD_SERVER_PKT_NUM_DOMAINS: + qemud_packet_num_domains_reply numDomainsReply; + + case QEMUD_SERVER_PKT_DOMAIN_CREATE: + qemud_packet_domain_create_reply domainCreateReply; + + case QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_ID: + qemud_packet_domain_lookup_by_id_reply domainLookupByIDReply; + + case QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_UUID: + qemud_packet_domain_lookup_by_uuid_reply domainLookupByUUIDReply; + + case QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_NAME: + qemud_packet_domain_lookup_by_name_reply domainLookupByNameReply; + + case QEMUD_SERVER_PKT_DOMAIN_SUSPEND: + void; + + case QEMUD_SERVER_PKT_DOMAIN_RESUME: + void; + + case QEMUD_SERVER_PKT_DOMAIN_DESTROY: + void; + + case QEMUD_SERVER_PKT_DOMAIN_GET_INFO: + qemud_packet_domain_get_info_reply domainGetInfoReply; + + case QEMUD_SERVER_PKT_DOMAIN_SAVE: + void; + + case QEMUD_SERVER_PKT_DOMAIN_RESTORE: + qemud_packet_domain_restore_reply domainRestoreReply; + + case QEMUD_SERVER_PKT_DUMP_XML: + qemud_packet_domain_dump_xml_reply domainDumpXMLReply; + + case QEMUD_SERVER_PKT_LIST_DEFINED_DOMAINS: + qemud_packet_list_defined_domains_reply listDefinedDomainsReply; + + case QEMUD_SERVER_PKT_NUM_DEFINED_DOMAINS: + qemud_packet_num_defined_domains_reply numDefinedDomainsReply; + + case QEMUD_SERVER_PKT_DOMAIN_START: + qemud_packet_domain_start_reply domainStartReply; + + case QEMUD_SERVER_PKT_DOMAIN_DEFINE: + qemud_packet_domain_define_reply domainDefineReply; + + case QEMUD_SERVER_PKT_DOMAIN_UNDEFINE: + void; + + case QEMUD_SERVER_PKT_NUM_NETWORKS: + qemud_packet_num_networks_reply numNetworksReply; + + case QEMUD_SERVER_PKT_LIST_NETWORKS: + qemud_packet_list_networks_reply listNetworksReply; + + case QEMUD_SERVER_PKT_NUM_DEFINED_NETWORKS: + qemud_packet_num_defined_networks_reply numDefinedNetworksReply; + + case QEMUD_SERVER_PKT_LIST_DEFINED_NETWORKS: + qemud_packet_list_defined_networks_reply listDefinedNetworksReply; + + case QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_UUID: + qemud_packet_network_lookup_by_uuid_reply networkLookupByUUIDReply; + + case QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_NAME: + qemud_packet_network_lookup_by_name_reply networkLookupByNameReply; + + case QEMUD_SERVER_PKT_NETWORK_CREATE: + qemud_packet_network_create_reply networkCreateReply; + + case QEMUD_SERVER_PKT_NETWORK_DEFINE: + qemud_packet_network_define_reply networkDefineReply; + + case QEMUD_SERVER_PKT_NETWORK_UNDEFINE: + void; + + case QEMUD_SERVER_PKT_NETWORK_START: + void; + + case QEMUD_SERVER_PKT_NETWORK_DESTROY: + void; + + case QEMUD_SERVER_PKT_NETWORK_DUMP_XML: + qemud_packet_network_dump_xml_reply networkDumpXMLReply; + + case QEMUD_SERVER_PKT_NETWORK_GET_BRIDGE_NAME: + qemud_packet_network_get_bridge_name_reply networkGetBridgeNameReply; + + case QEMUD_SERVER_PKT_DOMAIN_GET_AUTOSTART: + qemud_packet_domain_get_autostart_reply domainGetAutostartReply; + + case QEMUD_SERVER_PKT_DOMAIN_SET_AUTOSTART: + void; + + case QEMUD_SERVER_PKT_NETWORK_GET_AUTOSTART: + qemud_packet_network_get_autostart_reply networkGetAutostartReply; + + case QEMUD_SERVER_PKT_NETWORK_SET_AUTOSTART: + void; + + case QEMUD_SERVER_PKT_GET_CAPABILITIES: + qemud_packet_get_capabilities_reply getCapabilitiesReply; +}; + +struct qemud_packet_client { + uint32_t serial; + struct qemud_packet_client_data data; +}; + +struct qemud_packet_server { + uint32_t serial; + uint32_t inReplyTo; + struct qemud_packet_server_data data; +}; + +/* The first two words in the messages are length and program number + * (previously called "magic"). This makes the protocol compatible + * with the remote protocol, although beyond the first two words + * the protocols are completely different. + * + * Note the length is the total number of bytes in the message + * _including_ the length and program number. + */ + +const QEMUD_PROGRAM = 0x20001A64; +const QEMUD_PKT_HEADER_XDR_LEN = 8; + +struct qemud_packet_header { + uint32_t length; + uint32_t prog; +}; diff --git a/qemud/qemud.c b/qemud/qemud.c index 171da4a0b6..5a6180f2a7 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -23,6 +23,8 @@ #include +#define _GNU_SOURCE /* for asprintf */ + #include #include #include @@ -34,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -44,19 +47,48 @@ #include #include #include - +#include +#include +#include +#include #include #include "internal.h" +#include "../src/remote_internal.h" +#include "../src/conf.h" #include "dispatch.h" #include "driver.h" #include "conf.h" #include "iptables.h" -static int godaemon = 0; -static int verbose = 0; -static int sigwrite = -1; +static int godaemon = 0; /* -d: Be a daemon */ +static int verbose = 0; /* -v: Verbose mode */ +static int remote = 0; /* -r: Remote mode */ +static int sys = 0; /* -s: (QEMUD only) system mode */ +static int timeout = -1; /* -t: (QEMUD only) timeout */ +static int sigwrite = -1; /* Signal handler pipe */ + +/* Defaults for configuration file elements (remote only). */ +static int listen_tls = 1; +static int listen_tcp = 0; +static const char *tls_port = LIBVIRTD_TLS_PORT; +static const char *tcp_port = LIBVIRTD_TCP_PORT; + +static int tls_no_verify_certificate = 0; +static int tls_no_verify_address = 0; +static const char **tls_allowed_ip_list = 0; +static const char **tls_allowed_dn_list = 0; + +static const char *key_file = LIBVIRT_SERVERKEY; +static const char *cert_file = LIBVIRT_SERVERCERT; +static const char *ca_file = LIBVIRT_CACERT; +static const char *crl_file = ""; + +static gnutls_certificate_credentials_t x509_cred; +static gnutls_dh_params_t dh_params; + +#define DH_BITS 1024 static sig_atomic_t sig_errors = 0; static int sig_lasterrno = 0; @@ -78,6 +110,80 @@ static void sig_handler(int sig) { errno = origerrno; } +static int +remoteInitializeGnuTLS (void) +{ + int err; + + /* Initialise GnuTLS. */ + gnutls_global_init (); + + err = gnutls_certificate_allocate_credentials (&x509_cred); + if (err) { + qemudLog (QEMUD_ERR, "gnutls_certificate_allocate_credentials: %s", + gnutls_strerror (err)); + return -1; + } + + if (ca_file && ca_file[0] != '\0') { + qemudDebug ("loading CA cert from %s", ca_file); + err = gnutls_certificate_set_x509_trust_file (x509_cred, ca_file, + GNUTLS_X509_FMT_PEM); + if (err < 0) { + qemudLog (QEMUD_ERR, "gnutls_certificate_set_x509_trust_file: %s", + gnutls_strerror (err)); + return -1; + } + } + + if (crl_file && crl_file[0] != '\0') { + qemudDebug ("loading CRL from %s", crl_file); + err = gnutls_certificate_set_x509_crl_file (x509_cred, crl_file, + GNUTLS_X509_FMT_PEM); + if (err < 0) { + qemudLog (QEMUD_ERR, "gnutls_certificate_set_x509_crl_file: %s", + gnutls_strerror (err)); + return -1; + } + } + + if (cert_file && cert_file[0] != '\0' && key_file && key_file[0] != '\0') { + qemudDebug ("loading cert and key from %s and %s", + cert_file, key_file); + err = + gnutls_certificate_set_x509_key_file (x509_cred, + cert_file, key_file, + GNUTLS_X509_FMT_PEM); + if (err < 0) { + qemudLog (QEMUD_ERR, "gnutls_certificate_set_x509_key_file: %s", + gnutls_strerror (err)); + return -1; + } + } + + /* Generate Diffie Hellman parameters - for use with DHE + * kx algorithms. These should be discarded and regenerated + * once a day, once a week or once a month. Depending on the + * security requirements. + */ + err = gnutls_dh_params_init (&dh_params); + if (err < 0) { + qemudLog (QEMUD_ERR, "gnutls_dh_params_init: %s", + gnutls_strerror (err)); + return -1; + } + err = gnutls_dh_params_generate2 (dh_params, DH_BITS); + if (err < 0) { + qemudLog (QEMUD_ERR, "gnutls_dh_params_generate2: %s", + gnutls_strerror (err)); + return -1; + } + + gnutls_certificate_set_dh_params (x509_cred, dh_params); + + return 0; +} + static int qemudDispatchSignal(struct qemud_server *server) { unsigned char sigc; @@ -96,11 +202,13 @@ static int qemudDispatchSignal(struct qemud_server *server) switch (sigc) { case SIGHUP: qemudLog(QEMUD_INFO, "Reloading configuration on SIGHUP"); - ret = qemudScanConfigs(server); + if (!remote) { + ret = qemudScanConfigs(server); - if (server->iptables) { - qemudLog(QEMUD_INFO, "Reloading iptables rules"); - iptablesReloadRules(server->iptables); + if (server->iptables) { + qemudLog(QEMUD_INFO, "Reloading iptables rules"); + iptablesReloadRules(server->iptables); + } } break; @@ -109,45 +217,47 @@ static int qemudDispatchSignal(struct qemud_server *server) case SIGTERM: qemudLog(QEMUD_WARN, "Shutting down on signal %d", sigc); - /* shutdown active VMs */ - vm = server->vms; - while (vm) { - struct qemud_vm *next = vm->next; - if (qemudIsActiveVM(vm)) - qemudShutdownVMDaemon(server, vm); - vm = next; - } + if (!remote) { + /* shutdown active VMs */ + vm = server->vms; + while (vm) { + struct qemud_vm *next = vm->next; + if (qemudIsActiveVM(vm)) + qemudShutdownVMDaemon(server, vm); + vm = next; + } - /* free inactive VMs */ - vm = server->vms; - while (vm) { - struct qemud_vm *next = vm->next; - qemudFreeVM(vm); - vm = next; - } - server->vms = NULL; - server->nactivevms = 0; - server->ninactivevms = 0; + /* free inactive VMs */ + vm = server->vms; + while (vm) { + struct qemud_vm *next = vm->next; + qemudFreeVM(vm); + vm = next; + } + server->vms = NULL; + server->nactivevms = 0; + server->ninactivevms = 0; - /* shutdown active networks */ - network = server->networks; - while (network) { - struct qemud_network *next = network->next; - if (qemudIsActiveNetwork(network)) - qemudShutdownNetworkDaemon(server, network); - network = next; - } + /* shutdown active networks */ + network = server->networks; + while (network) { + struct qemud_network *next = network->next; + if (qemudIsActiveNetwork(network)) + qemudShutdownNetworkDaemon(server, network); + network = next; + } - /* free inactive networks */ - network = server->networks; - while (network) { - struct qemud_network *next = network->next; - qemudFreeNetwork(network); - network = next; + /* free inactive networks */ + network = server->networks; + while (network) { + struct qemud_network *next = network->next; + qemudFreeNetwork(network); + network = next; + } + server->networks = NULL; + server->nactivenetworks = 0; + server->ninactivenetworks = 0; } - server->networks = NULL; - server->nactivenetworks = 0; - server->ninactivenetworks = 0; server->shutdown = 1; break; @@ -405,72 +515,206 @@ static int qemudListenUnix(struct qemud_server *server, return 0; } -static int qemudInitPaths(struct qemud_server *server, - int sys, - char *sockname, - char *roSockname, - int maxlen) { - const char *paths[] = { - "libvirt/qemu", /* QEMUD_DIR_DOMAINS */ - "libvirt/qemu/autostart", /* QEMUD_DIR_AUTO_DOMAINS */ - "libvirt/qemu/networks", /* QEMUD_DIR_NETWORKS */ - "libvirt/qemu/networks/autostart", /* QEMUD_DIR_AUTO_NETWORKS */ - }; +// See: http://people.redhat.com/drepper/userapi-ipv6.html +static int +remoteMakeSockets (int *fds, int max_fds, int *nfds_r, const char *service) +{ + struct addrinfo *ai; + struct addrinfo hints; + memset (&hints, 0, sizeof hints); + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + hints.ai_socktype = SOCK_STREAM; - uid_t uid; - struct passwd *pw; - char base[PATH_MAX] = SYSCONF_DIR "/"; - int i; + int e = getaddrinfo (NULL, service, &hints, &ai); + if (e != 0) { + qemudLog (QEMUD_ERR, "getaddrinfo: %s\n", gai_strerror (e)); + return -1; + } - uid = geteuid(); - - if (sys) { - if (uid != 0) { - qemudLog(QEMUD_ERR, "You must run the daemon as root to use system mode"); + struct addrinfo *runp = ai; + while (runp && *nfds_r < max_fds) { + fds[*nfds_r] = socket (runp->ai_family, runp->ai_socktype, + runp->ai_protocol); + if (fds[*nfds_r] == -1) { + qemudLog (QEMUD_ERR, "socket: %s", strerror (errno)); return -1; } - if (snprintf(sockname, maxlen, "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= maxlen) + int opt = 1; + setsockopt (fds[*nfds_r], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt); + + if (bind (fds[*nfds_r], runp->ai_addr, runp->ai_addrlen) == -1) { + if (errno != EADDRINUSE) { + qemudLog (QEMUD_ERR, "bind: %s", strerror (errno)); + return -1; + } + close (fds[*nfds_r]); + } + else { + if (listen (fds[*nfds_r], SOMAXCONN) == -1) { + qemudLog (QEMUD_ERR, "listen: %s", strerror (errno)); + return -1; + } + ++*nfds_r; + } + runp = runp->ai_next; + } + + freeaddrinfo (ai); + return 0; +} + +/* Listen on the named/numbered TCP port. On a machine with IPv4 and + * IPv6 interfaces this may generate several sockets. + */ +static int +remoteListenTCP (struct qemud_server *server, + const char *port, + int tls) +{ + int fds[2]; + int nfds = 0; + int i; + struct qemud_socket *sock; + + if (remoteMakeSockets (fds, 2, &nfds, port) == -1) + return -1; + + for (i = 0; i < nfds; ++i) { + sock = calloc (1, sizeof *sock); + + if (!sock) { + qemudLog (QEMUD_ERR, + "remoteListenTCP: calloc: %s", strerror (errno)); + return -1; + } + + sock->readonly = 0; + sock->next = server->sockets; + server->sockets = sock; + server->nsockets++; + + sock->fd = fds[i]; + sock->tls = tls; + + if (qemudSetCloseExec(sock->fd) < 0 || + qemudSetNonBlock(sock->fd) < 0) + return -1; + + if (listen (sock->fd, 30) < 0) { + qemudLog (QEMUD_ERR, + "remoteListenTCP: listen: %s", strerror (errno)); + return -1; + } + } + + return 0; +} + +static int qemudInitPaths(struct qemud_server *server, + char *sockname, + char *roSockname, + int maxlen) { + char *base = 0; + + if (remote) { /* Remote daemon */ + /* I'm not sure if it's meaningful to have a "session remote daemon" + * so currently this code ignores the --system flag. - RWMJ. + */ + + if (snprintf (sockname, maxlen, "%s/run/libvirt/libvirt-sock", + LOCAL_STATE_DIR) >= maxlen) goto snprintf_error; unlink(sockname); - if (snprintf(roSockname, maxlen, "%s/run/libvirt/qemud-sock-ro", LOCAL_STATE_DIR) >= maxlen) + if (snprintf (roSockname, maxlen, "%s/run/libvirt/libvirt-sock-ro", + LOCAL_STATE_DIR) >= maxlen) goto snprintf_error; unlink(roSockname); + server->configDir = + server->autostartDir = + server->networkConfigDir = + server->networkAutostartDir = NULL; + if (snprintf(server->logDir, PATH_MAX, "%s/log/libvirt/qemu", LOCAL_STATE_DIR) >= PATH_MAX) goto snprintf_error; } else { - if (!(pw = getpwuid(uid))) { - qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s", - uid, strerror(errno)); - return -1; + uid_t uid = geteuid(); + struct passwd *pw; + + if (sys) { /* QEMUD, system */ + if (uid != 0) { + qemudLog (QEMUD_ERR, + "You must run the daemon as root to use system mode"); + return -1; + } + + if (snprintf(sockname, maxlen, "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= maxlen) + goto snprintf_error; + + unlink(sockname); + + if (snprintf(roSockname, maxlen, "%s/run/libvirt/qemud-sock-ro", LOCAL_STATE_DIR) >= maxlen) + goto snprintf_error; + + unlink(roSockname); + + if ((base = strdup (SYSCONF_DIR "/libvirt/qemu")) == NULL) + goto out_of_memory; + } else { /* QEMUD, session */ + if (!(pw = getpwuid(uid))) { + qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s", + uid, strerror(errno)); + return -1; + } + + if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen) + goto snprintf_error; + + if (asprintf (&base, "%s/.libvirt/qemu", pw->pw_dir) == -1) { + qemudLog (QEMUD_ERR, "out of memory in asprintf"); + return -1; + } } - if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen) - goto snprintf_error; + /* Configuration paths are either ~/.libvirt/qemu/... (session) or + * /etc/libvirt/qemu/... (system). + */ + if (asprintf (&server->configDir, "%s", base) == -1) + goto out_of_memory; - if (snprintf(base, PATH_MAX, "%s/.", pw->pw_dir) >= PATH_MAX) - goto snprintf_error; + if (asprintf (&server->autostartDir, "%s/autostart", base) == -1) + goto out_of_memory; - if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/qemu/log", pw->pw_dir) >= PATH_MAX) - goto snprintf_error; - } + if (asprintf (&server->networkConfigDir, "%s/networks", base) == -1) + goto out_of_memory; - for (i = 0; i < QEMUD_N_CONFIG_DIRS; i++) - if (snprintf(server->configDirs[i], PATH_MAX, "%s%s", base, paths[i]) >= PATH_MAX) + if (asprintf (&server->networkAutostartDir, "%s/networks/autostart", + base) == -1) + goto out_of_memory; + + if (snprintf(server->logDir, PATH_MAX, "%s/log", base) >= PATH_MAX) goto snprintf_error; + } /* !remote */ + + if (base) free (base); return 0; snprintf_error: qemudLog(QEMUD_ERR, "Resulting path to long for buffer in qemudInitPaths()"); return -1; + + out_of_memory: + qemudLog (QEMUD_ERR, "qemudInitPaths: out of memory"); + if (base) free (base); + return -1; } -static struct qemud_server *qemudInitialize(int sys, int sigread) { +static struct qemud_server *qemudInitialize(int sigread) { struct qemud_server *server; char sockname[PATH_MAX]; char roSockname[PATH_MAX]; @@ -486,22 +730,30 @@ static struct qemud_server *qemudInitialize(int sys, int sigread) { roSockname[0] = '\0'; - if (qemudInitPaths(server, sys, sockname, roSockname, PATH_MAX) < 0) + if (qemudInitPaths(server, sockname, roSockname, PATH_MAX) < 0) goto cleanup; - server->configDir = server->configDirs[QEMUD_DIR_CONFIG]; - server->autostartDir = server->configDirs[QEMUD_DIR_AUTOSTART]; - server->networkConfigDir = server->configDirs[QEMUD_DIR_NETWORK_CONFIG]; - server->networkAutostartDir = server->configDirs[QEMUD_DIR_NETWORK_AUTOSTART]; - if (qemudListenUnix(server, sockname, 0) < 0) goto cleanup; if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1) < 0) goto cleanup; - if (qemudScanConfigs(server) < 0) { - goto cleanup; + if (!remote) /* qemud only */ { + if (qemudScanConfigs(server) < 0) { + goto cleanup; + } + } else /* remote only */ { + if (listen_tcp && remoteListenTCP (server, tcp_port, 0) < 0) + goto cleanup; + + if (listen_tls) { + if (remoteInitializeGnuTLS () < 0) + goto cleanup; + + if (remoteListenTCP (server, tls_port, 1) < 0) + goto cleanup; + } } return server; @@ -514,17 +766,235 @@ static struct qemud_server *qemudInitialize(int sys, int sigread) { sock = sock->next; } + if (server->configDir) free (server->configDir); + if (server->autostartDir) free (server->autostartDir); + if (server->networkConfigDir) free (server->networkConfigDir); + if (server->networkAutostartDir) free (server->networkAutostartDir); + free(server); } return NULL; } +static gnutls_session_t +remoteInitializeTLSSession (void) +{ + gnutls_session_t session; + int err; + + err = gnutls_init (&session, GNUTLS_SERVER); + if (err != 0) goto failed; + + /* avoid calling all the priority functions, since the defaults + * are adequate. + */ + err = gnutls_set_default_priority (session); + if (err != 0) goto failed; + + err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred); + if (err != 0) goto failed; + + /* request client certificate if any. + */ + gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST); + + gnutls_dh_set_prime_bits (session, DH_BITS); + + return session; + + failed: + qemudLog (QEMUD_ERR, "remoteInitializeTLSSession: %s", + gnutls_strerror (err)); + return NULL; +} + +/* Check DN is on tls_allowed_dn_list. */ +static int +remoteCheckDN (gnutls_x509_crt_t cert) +{ + char name[256]; + size_t namesize = sizeof name; + const char **wildcards; + int err; + + err = gnutls_x509_crt_get_dn (cert, name, &namesize); + if (err != 0) { + qemudLog (QEMUD_ERR, + "remoteCheckDN: gnutls_x509_cert_get_dn: %s", + gnutls_strerror (err)); + return 0; + } + + /* If the list is not set, allow any DN. */ + wildcards = tls_allowed_dn_list; + if (!wildcards) + return 1; + + while (*wildcards) { + if (fnmatch (*wildcards, name, 0) == 0) + return 1; + wildcards++; + } + + /* Print the client's DN. */ + qemudLog (QEMUD_DEBUG, + "remoteCheckDN: failed: client DN is %s", name); + + return 0; // Not found. +} + +static int +remoteCheckCertificate (gnutls_session_t session) +{ + int ret; + unsigned int status; + const gnutls_datum_t *certs; + unsigned int nCerts, i; + time_t now; + + if ((ret = gnutls_certificate_verify_peers2 (session, &status)) < 0){ + qemudLog (QEMUD_ERR, "remoteCheckCertificate: verify failed: %s", + gnutls_strerror (ret)); + return -1; + } + + if (status != 0) { + if (status & GNUTLS_CERT_INVALID) + qemudLog (QEMUD_ERR, "remoteCheckCertificate: the client certificate is not trusted."); + + if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) + qemudLog (QEMUD_ERR, "remoteCheckCertificate: the client certificate hasn't got a known issuer."); + + if (status & GNUTLS_CERT_REVOKED) + qemudLog (QEMUD_ERR, "remoteCheckCertificate: the client certificate has been revoked."); + + if (status & GNUTLS_CERT_INSECURE_ALGORITHM) + qemudLog (QEMUD_ERR, "remoteCheckCertificate: the client certificate uses an insecure algorithm."); + + return -1; + } + + if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { + qemudLog (QEMUD_ERR, "remoteCheckCertificate: certificate is not X.509"); + return -1; + } + + if (!(certs = gnutls_certificate_get_peers(session, &nCerts))) { + qemudLog (QEMUD_ERR, "remoteCheckCertificate: no peers"); + return -1; + } + + now = time (NULL); + + for (i = 0; i < nCerts; i++) { + gnutls_x509_crt_t cert; + + if (gnutls_x509_crt_init (&cert) < 0) { + qemudLog (QEMUD_ERR, "remoteCheckCertificate: gnutls_x509_crt_init failed"); + return -1; + } + + if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) { + gnutls_x509_crt_deinit (cert); + return -1; + } + + if (gnutls_x509_crt_get_expiration_time (cert) < now) { + qemudLog (QEMUD_ERR, "remoteCheckCertificate: the client certificate has expired"); + gnutls_x509_crt_deinit (cert); + return -1; + } + + if (gnutls_x509_crt_get_activation_time (cert) > now) { + qemudLog (QEMUD_ERR, "remoteCheckCertificate: the client certificate is not yet activated"); + gnutls_x509_crt_deinit (cert); + return -1; + } + + if (i == 0) { + if (!remoteCheckDN (cert)) { + /* This is the most common error: make it informative. */ + qemudLog (QEMUD_ERR, "remoteCheckCertificate: client's Distinguished Name is not on the list of allowed clients (tls_allowed_dn_list). Use 'openssl x509 -in clientcert.pem -text' to view the Distinguished Name field in the client certificate, or run this daemon with --verbose option."); + gnutls_x509_crt_deinit (cert); + return -1; + } + } + } + + return 0; +} + +/* Check the client's access. */ +static int +remoteCheckAccess (struct qemud_client *client) +{ + char addr[NI_MAXHOST]; + const char **wildcards; + int found, err; + + /* Verify client certificate. */ + if (remoteCheckCertificate (client->session) == -1) { + qemudLog (QEMUD_ERR, "remoteCheckCertificate: failed to verify client's certificate"); + if (!tls_no_verify_certificate) return -1; + else qemudLog (QEMUD_INFO, "remoteCheckCertificate: tls_no_verify_certificate is set so the bad certificate is ignored"); + } + + /*----- IP address check, similar to tcp wrappers -----*/ + + /* Convert IP address to printable string (eg. "127.0.0.1" or "::1"). */ + err = getnameinfo ((struct sockaddr *) &client->addr, client->addrlen, + addr, sizeof addr, NULL, 0, + NI_NUMERICHOST); + if (err != 0) { + qemudLog (QEMUD_ERR, "getnameinfo: %s", gai_strerror (err)); + return -1; + } + + /* Verify the client is on the list of allowed clients. + * + * NB: No tls_allowed_ip_list in config file means anyone can access. + * If tls_allowed_ip_list is in the config file but empty, means no + * one can access (not particularly useful, but it's what the sysadmin + * would expect). + */ + wildcards = tls_allowed_ip_list; + if (wildcards) { + found = 0; + + while (*wildcards) { + if (fnmatch (*wildcards, addr, 0) == 0) { + found = 1; + break; + } + wildcards++; + } + } else + found = 1; + + if (!found) { + qemudLog (QEMUD_ERR, "remoteCheckAccess: client's IP address (%s) is not on the list of allowed clients (tls_allowed_ip_list)", addr); + if (!tls_no_verify_address) return -1; + else qemudLog (QEMUD_INFO, "remoteCheckAccess: tls_no_verify_address is set so the client's IP address is ignored"); + } + + /* Checks have succeeded. Write a '\1' byte back to the client to + * indicate this (otherwise the socket is abruptly closed). + * (NB. The '\1' byte is sent in an encrypted record). + */ + client->bufferLength = 1; + client->bufferOffset = 0; + client->buffer[0] = '\1'; + client->mode = QEMUD_MODE_TX_PACKET; + client->direction = QEMUD_TLS_DIRECTION_WRITE; + return 0; +} static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket *sock) { int fd; struct sockaddr_storage addr; - unsigned int addrlen = sizeof(addr); + socklen_t addrlen = (socklen_t) (sizeof addr); struct qemud_client *client; + int no_slow_start = 1; if ((fd = accept(sock->fd, (struct sockaddr *)&addr, &addrlen)) < 0) { if (errno == EAGAIN) @@ -533,6 +1003,10 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket return -1; } + /* Disable Nagle. Unix sockets will ignore this. */ + setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_slow_start, + sizeof no_slow_start); + if (qemudSetCloseExec(fd) < 0 || qemudSetNonBlock(fd) < 0) { close(fd); @@ -540,14 +1014,54 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket } client = calloc(1, sizeof(struct qemud_client)); + client->magic = QEMUD_CLIENT_MAGIC; client->fd = fd; client->readonly = sock->readonly; + client->tls = sock->tls; + memcpy (&client->addr, &addr, sizeof addr); + client->addrlen = addrlen; + + if (!client->tls) { + client->mode = QEMUD_MODE_RX_HEADER; + client->bufferLength = QEMUD_PKT_HEADER_XDR_LEN; + } else { + int ret; + + client->session = remoteInitializeTLSSession (); + if (client->session == NULL) goto tls_failed; + + gnutls_transport_set_ptr (client->session, + (gnutls_transport_ptr_t) (long) fd); + + /* Begin the TLS handshake. */ + ret = gnutls_handshake (client->session); + if (ret == 0) { + /* Unlikely, but ... Next step is to check the certificate. */ + if (remoteCheckAccess (client) == -1) + goto tls_failed; + } else if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { + /* Most likely. */ + client->mode = QEMUD_MODE_TLS_HANDSHAKE; + client->bufferLength = -1; + client->direction = gnutls_record_get_direction (client->session); + } else { + qemudLog (QEMUD_ERR, "TLS handshake failed: %s", + gnutls_strerror (ret)); + goto tls_failed; + } + } client->next = server->clients; server->clients = client; server->nclients++; return 0; + + tls_failed: + if (client->session) gnutls_deinit (client->session); + close (fd); + free (client); + return -1; } @@ -980,113 +1494,310 @@ static void qemudDispatchClientFailure(struct qemud_server *server, struct qemud prev = tmp; tmp = tmp->next; } + + if (client->tls && client->session) gnutls_deinit (client->session); close(client->fd); free(client); } -static int qemudDispatchClientRequest(struct qemud_server *server, struct qemud_client *client) { - if (qemudDispatch(server, - client, - &client->incoming, - &client->outgoing) < 0) { - return -1; +static void qemudDispatchClientRequest(struct qemud_server *server, + struct qemud_client *client, + qemud_packet_client *req) { + qemud_packet_server res; + qemud_packet_header h; + XDR x; + + assert (client->magic == QEMUD_CLIENT_MAGIC); + + if (req->serial != ++client->incomingSerial) { + qemudDebug("Invalid serial number. Got %d expect %d", + req->serial, client->incomingSerial); + qemudDispatchClientFailure(server, client); + return; } - client->outgoingSent = 0; - client->tx = 1; - client->incomingReceived = 0; + if (qemudDispatch(server, + client, + &req->data, + &res.data) < 0) { + qemudDispatchClientFailure(server, client); + return; + } - return 0; + res.serial = ++client->outgoingSerial; + res.inReplyTo = req->serial; + + xdrmem_create(&x, client->buffer, sizeof client->buffer, + XDR_ENCODE); + + /* Encode a dummy header. We'll come back to encode the real header. */ + if (!xdr_qemud_packet_header (&x, &h)) { + qemudDebug ("failed to encode dummy header"); + qemudDispatchClientFailure (server, client); + return; + } + + /* Real payload. */ + if (!xdr_qemud_packet_server(&x, &res)) { + qemudDebug("Failed to XDR encode reply payload"); + qemudDispatchClientFailure(server, client); + return; + } + + /* Go back and encode the real header. */ + h.length = xdr_getpos (&x); + h.prog = QEMUD_PROGRAM; + + if (xdr_setpos (&x, 0) == 0) { + qemudDebug("xdr_setpos failed"); + qemudDispatchClientFailure(server, client); + return; + } + + if (!xdr_qemud_packet_header(&x, &h)) { + qemudDebug("Failed to XDR encode reply header"); + qemudDispatchClientFailure(server, client); + return; + } + + client->mode = QEMUD_MODE_TX_PACKET; + client->bufferLength = h.length; + client->bufferOffset = 0; } static int qemudClientRead(struct qemud_server *server, - struct qemud_client *client, - char *buf, size_t want) { - int ret; - if ((ret = read(client->fd, buf, want)) <= 0) { - qemudDebug("Plain read error %d", ret); - if (!ret || errno != EAGAIN) - qemudDispatchClientFailure(server, client); - return -1; + struct qemud_client *client) { + int ret, len; + char *data; + + data = client->buffer + client->bufferOffset; + len = client->bufferLength - client->bufferOffset; + + /*qemudDebug ("qemudClientRead: len = %d", len);*/ + + if (!client->tls) { + if ((ret = read (client->fd, data, len)) <= 0) { + if (ret == 0 || errno != EAGAIN) { + if (ret != 0) + qemudLog (QEMUD_ERR, "read: %s", strerror (errno)); + qemudDispatchClientFailure(server, client); + } + return -1; + } + } else { + ret = gnutls_record_recv (client->session, data, len); + client->direction = gnutls_record_get_direction (client->session); + if (ret <= 0) { + if (ret == 0 || (ret != GNUTLS_E_AGAIN && + ret != GNUTLS_E_INTERRUPTED)) { + if (ret != 0) + qemudLog (QEMUD_ERR, "gnutls_record_recv: %s", + gnutls_strerror (ret)); + qemudDispatchClientFailure (server, client); + } + return -1; + } } - qemudDebug("Plain data read %d", ret); - return ret; + + client->bufferOffset += ret; + return 0; } static void qemudDispatchClientRead(struct qemud_server *server, struct qemud_client *client) { - char *data = (char *)&client->incoming; - unsigned int got = client->incomingReceived; - int want; - int ret; - restart: - if (got >= sizeof(struct qemud_packet_header)) { - want = sizeof(struct qemud_packet_header) + client->incoming.header.dataSize - got; - } else { - want = sizeof(struct qemud_packet_header) - got; - } + /*qemudDebug ("qemudDispatchClientRead: mode = %d", client->mode);*/ - if ((ret = qemudClientRead(server, client, data+got, want)) < 0) { - return; - } - got += ret; - client->incomingReceived += ret; + switch (client->mode) { + case QEMUD_MODE_RX_HEADER: { + XDR x; + qemud_packet_header h; - /* If we've finished header, move onto body */ - if (client->incomingReceived == sizeof(struct qemud_packet_header)) { - qemudDebug("Type %d, data %d", - client->incoming.header.type, - client->incoming.header.dataSize); - /* Client lied about dataSize */ - if (client->incoming.header.dataSize > sizeof(union qemud_packet_data)) { - qemudDebug("Bogus data size %u", client->incoming.header.dataSize); + if (qemudClientRead(server, client) < 0) + return; /* Error, or blocking */ + + if (client->bufferOffset < client->bufferLength) + return; /* Not read enough */ + + xdrmem_create(&x, client->buffer, client->bufferLength, XDR_DECODE); + + if (!xdr_qemud_packet_header(&x, &h)) { + qemudDebug("Failed to decode packet header"); qemudDispatchClientFailure(server, client); return; } - if (client->incoming.header.dataSize) { - qemudDebug("- Restarting recv to process body (%d bytes)", - client->incoming.header.dataSize); - goto restart; + + /* We're expecting either QEMUD_PROGRAM or REMOTE_PROGRAM, + * corresponding to qemud or remote calls respectively. + */ + if ((!remote && h.prog != QEMUD_PROGRAM) + || (remote && h.prog != REMOTE_PROGRAM)) { + qemudDebug("Header magic %x mismatch", h.prog); + qemudDispatchClientFailure(server, client); + return; } + + /* NB: h.length is unsigned. */ + if (h.length > REMOTE_MESSAGE_MAX) { + qemudDebug("Packet length %u too large", h.length); + qemudDispatchClientFailure(server, client); + return; + } + + client->mode = QEMUD_MODE_RX_PAYLOAD; + client->bufferLength = h.length; + if (client->tls) client->direction = QEMUD_TLS_DIRECTION_READ; + /* Note that we don't reset bufferOffset here because we want + * to retain the whole message, including header. + */ + + xdr_destroy (&x); + + /* Fall through */ } - /* If we've finished body, dispatch the request */ - if (ret == want) { - if (qemudDispatchClientRequest(server, client) < 0) + case QEMUD_MODE_RX_PAYLOAD: { + XDR x; + qemud_packet_header h; + + if (qemudClientRead(server, client) < 0) + return; /* Error, or blocking */ + + if (client->bufferOffset < client->bufferLength) + return; /* Not read enough */ + + /* Reparse the header to decide if this is for qemud or remote. */ + xdrmem_create(&x, client->buffer, client->bufferLength, XDR_DECODE); + + if (!xdr_qemud_packet_header(&x, &h)) { + qemudDebug("Failed to decode packet header"); qemudDispatchClientFailure(server, client); - qemudDebug("Dispatch"); + return; + } + + if (remote && h.prog == REMOTE_PROGRAM) { + remoteDispatchClientRequest (server, client); + } else if (!remote && h.prog == QEMUD_PROGRAM) { + qemud_packet_client p; + + if (!xdr_qemud_packet_client(&x, &p)) { + qemudDebug("Failed to decode client packet"); + qemudDispatchClientFailure(server, client); + return; + } + + qemudDispatchClientRequest(server, client, &p); + } else { + /* An internal error. */ + qemudDebug ("Not REMOTE_PROGRAM or QEMUD_PROGRAM"); + qemudDispatchClientFailure(server, client); + } + + xdr_destroy (&x); + + break; + } + + case QEMUD_MODE_TLS_HANDSHAKE: { + int ret; + + /* Continue the handshake. */ + ret = gnutls_handshake (client->session); + if (ret == 0) { + /* Finished. Next step is to check the certificate. */ + if (remoteCheckAccess (client) == -1) + qemudDispatchClientFailure (server, client); + } else if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) { + qemudLog (QEMUD_ERR, "TLS handshake failed: %s", + gnutls_strerror (ret)); + qemudDispatchClientFailure (server, client); + } else + client->direction = gnutls_record_get_direction (client->session); + + break; + } + + default: + qemudDebug("Got unexpected data read while in %d mode", client->mode); + qemudDispatchClientFailure(server, client); } } static int qemudClientWrite(struct qemud_server *server, - struct qemud_client *client, - char *buf, size_t want) { - int ret; - if ((ret = write(client->fd, buf, want)) < 0) { - qemudDebug("Plain write error %d", ret); - if (errno != EAGAIN) - qemudDispatchClientFailure(server, client); - return -1; + struct qemud_client *client) { + int ret, len; + char *data; + + data = client->buffer + client->bufferOffset; + len = client->bufferLength - client->bufferOffset; + + if (!client->tls) { + if ((ret = write(client->fd, data, len)) == -1) { + if (errno != EAGAIN) { + qemudLog (QEMUD_ERR, "write: %s", strerror (errno)); + qemudDispatchClientFailure(server, client); + } + return -1; + } + } else { + ret = gnutls_record_send (client->session, data, len); + client->direction = gnutls_record_get_direction (client->session); + if (ret < 0) { + if (ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN) { + qemudLog (QEMUD_ERR, "gnutls_record_send: %s", + gnutls_strerror (ret)); + qemudDispatchClientFailure (server, client); + } + return -1; + } } - qemudDebug("Plain data write %d", ret); - return ret; + + client->bufferOffset += ret; + return 0; } static void qemudDispatchClientWrite(struct qemud_server *server, struct qemud_client *client) { - char *data = (char *)&client->outgoing; - int sent = client->outgoingSent; - int todo = sizeof(struct qemud_packet_header) + client->outgoing.header.dataSize - sent; - int ret; - if ((ret = qemudClientWrite(server, client, data+sent, todo)) < 0) { - return; + switch (client->mode) { + case QEMUD_MODE_TX_PACKET: { + if (qemudClientWrite(server, client) < 0) + return; + + if (client->bufferOffset == client->bufferLength) { + /* Done writing, switch back to receive */ + client->mode = QEMUD_MODE_RX_HEADER; + client->bufferLength = QEMUD_PKT_HEADER_XDR_LEN; + client->bufferOffset = 0; + if (client->tls) client->direction = QEMUD_TLS_DIRECTION_READ; + } + /* Still writing */ + break; + } + + case QEMUD_MODE_TLS_HANDSHAKE: { + int ret; + + /* Continue the handshake. */ + ret = gnutls_handshake (client->session); + if (ret == 0) { + /* Finished. Next step is to check the certificate. */ + if (remoteCheckAccess (client) == -1) + qemudDispatchClientFailure (server, client); + } else if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) { + qemudLog (QEMUD_ERR, "TLS handshake failed: %s", + gnutls_strerror (ret)); + qemudDispatchClientFailure (server, client); + } else + client->direction = gnutls_record_get_direction (client->session); + + break; + } + + default: + qemudDebug("Got unexpected data write while in %d mode", client->mode); + qemudDispatchClientFailure(server, client); } - client->outgoingSent += ret; - qemudDebug("Done %d %d", todo, ret); - if (todo == ret) - client->tx = 0; } static int qemudVMData(struct qemud_server *server ATTRIBUTE_UNUSED, @@ -1685,6 +2396,9 @@ static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) { } while (client) { struct qemud_client *next = client->next; + + assert (client->magic == QEMUD_CLIENT_MAGIC); + if (fds[fd].revents) { qemudDebug("Poll data normal"); if (fds[fd].revents == POLLOUT) @@ -1759,12 +2473,19 @@ static void qemudPreparePoll(struct qemud_server *server, struct pollfd *fds) { } for (client = server->clients ; client ; client = client->next) { fds[fd].fd = client->fd; - /* Refuse to read more from client if tx is pending to - rate limit */ - if (client->tx) - fds[fd].events = POLLOUT | POLLERR | POLLHUP; - else - fds[fd].events = POLLIN | POLLERR | POLLHUP; + if (!client->tls) { + /* Refuse to read more from client if tx is pending to + rate limit */ + if (client->mode == QEMUD_MODE_TX_PACKET) + fds[fd].events = POLLOUT | POLLERR | POLLHUP; + else + fds[fd].events = POLLIN | POLLERR | POLLHUP; + } else { + qemudDebug ("direction = %s", + client->direction ? "WRITE" : "READ"); + fds[fd].events = client->direction ? POLLOUT : POLLIN; + fds[fd].events |= POLLERR | POLLHUP; + } fd++; } for (sock = server->sockets ; sock ; sock = sock->next) { @@ -1776,7 +2497,7 @@ static void qemudPreparePoll(struct qemud_server *server, struct pollfd *fds) { -static int qemudOneLoop(struct qemud_server *server, int timeout) { +static int qemudOneLoop(struct qemud_server *server) { int nfds = server->nsockets + server->nclients + server->nvmfds + 1; /* server->sigread */ struct pollfd fds[nfds]; int thistimeout = -1; @@ -1825,10 +2546,10 @@ static int qemudOneLoop(struct qemud_server *server, int timeout) { return 0; } -static int qemudRunLoop(struct qemud_server *server, int timeout) { +static int qemudRunLoop(struct qemud_server *server) { int ret; - while ((ret = qemudOneLoop(server, timeout)) == 0 && !server->shutdown) + while ((ret = qemudOneLoop(server)) == 0 && !server->shutdown) ; return ret == -1 ? -1 : 0; @@ -1852,60 +2573,250 @@ static void qemudCleanup(struct qemud_server *server) { if (server->iptables) iptablesContextFree(server->iptables); + if (server->configDir) free (server->configDir); + if (server->autostartDir) free (server->autostartDir); + if (server->networkConfigDir) free (server->networkConfigDir); + if (server->networkAutostartDir) free (server->networkAutostartDir); + free(server); } +/* Read the config file if it exists. + * Only used in the remote case, hence the name. + */ +static int +remoteReadConfigFile (const char *filename) +{ + virConfPtr conf; + + /* Just check the file is readable before opening it, otherwise + * libvirt emits an error. + */ + if (access (filename, R_OK) == -1) return 0; + + conf = virConfReadFile (filename); + if (!conf) return 0; + + virConfValuePtr p; + +#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) { \ + qemudLog (QEMUD_ERR, \ + "remoteReadConfigFile: %s: %s: expected type " #typ "\n", \ + filename, (name)); \ + return -1; \ + } + + p = virConfGetValue (conf, "listen_tls"); + CHECK_TYPE ("listen_tls", VIR_CONF_LONG); + listen_tls = p ? p->l : listen_tls; + + p = virConfGetValue (conf, "listen_tcp"); + CHECK_TYPE ("listen_tcp", VIR_CONF_LONG); + listen_tcp = p ? p->l : listen_tcp; + + p = virConfGetValue (conf, "tls_port"); + CHECK_TYPE ("tls_port", VIR_CONF_STRING); + tls_port = p ? strdup (p->str) : tls_port; + + p = virConfGetValue (conf, "tcp_port"); + CHECK_TYPE ("tcp_port", VIR_CONF_STRING); + tcp_port = p ? strdup (p->str) : tcp_port; + + p = virConfGetValue (conf, "tls_no_verify_certificate"); + CHECK_TYPE ("tls_no_verify_certificate", VIR_CONF_LONG); + tls_no_verify_certificate = p ? p->l : tls_no_verify_certificate; + + p = virConfGetValue (conf, "tls_no_verify_address"); + CHECK_TYPE ("tls_no_verify_address", VIR_CONF_LONG); + tls_no_verify_address = p ? p->l : tls_no_verify_address; + + p = virConfGetValue (conf, "key_file"); + CHECK_TYPE ("key_file", VIR_CONF_STRING); + key_file = p ? strdup (p->str) : key_file; + + p = virConfGetValue (conf, "cert_file"); + CHECK_TYPE ("cert_file", VIR_CONF_STRING); + cert_file = p ? strdup (p->str) : cert_file; + + p = virConfGetValue (conf, "ca_file"); + CHECK_TYPE ("ca_file", VIR_CONF_STRING); + ca_file = p ? strdup (p->str) : ca_file; + + p = virConfGetValue (conf, "crl_file"); + CHECK_TYPE ("crl_file", VIR_CONF_STRING); + crl_file = p ? strdup (p->str) : crl_file; + + p = virConfGetValue (conf, "tls_allowed_dn_list"); + if (p) { + switch (p->type) { + case VIR_CONF_STRING: + tls_allowed_dn_list = malloc (2 * sizeof (char *)); + tls_allowed_dn_list[0] = strdup (p->str); + tls_allowed_dn_list[1] = 0; + break; + + case VIR_CONF_LIST: { + int i, len = 0; + virConfValuePtr pp; + for (pp = p->list; pp; pp = p->next) + len++; + tls_allowed_dn_list = + malloc ((1+len) * sizeof (char *)); + for (i = 0, pp = p->list; pp; ++i, pp = p->next) { + if (pp->type != VIR_CONF_STRING) { + qemudLog (QEMUD_ERR, "remoteReadConfigFile: %s: tls_allowed_dn_list: should be a string or list of strings\n", filename); + return -1; + } + tls_allowed_dn_list[i] = strdup (pp->str); + } + tls_allowed_dn_list[i] = 0; + break; + } + + default: + qemudLog (QEMUD_ERR, "remoteReadConfigFile: %s: tls_allowed_dn_list: should be a string or list of strings\n", filename); + return -1; + } + } + + p = virConfGetValue (conf, "tls_allowed_ip_list"); + if (p) { + switch (p->type) { + case VIR_CONF_STRING: + tls_allowed_ip_list = malloc (2 * sizeof (char *)); + tls_allowed_ip_list[0] = strdup (p->str); + tls_allowed_ip_list[1] = 0; + break; + + case VIR_CONF_LIST: { + int i, len = 0; + virConfValuePtr pp; + for (pp = p->list; pp; pp = p->next) + len++; + tls_allowed_ip_list = + malloc ((1+len) * sizeof (char *)); + for (i = 0, pp = p->list; pp; ++i, pp = p->next) { + if (pp->type != VIR_CONF_STRING) { + qemudLog (QEMUD_ERR, "remoteReadConfigFile: %s: tls_allowed_ip_list: should be a string or list of strings\n", filename); + return -1; + } + tls_allowed_ip_list[i] = strdup (pp->str); + } + tls_allowed_ip_list[i] = 0; + break; + } + + default: + qemudLog (QEMUD_ERR, "remoteReadConfigFile: %s: tls_allowed_ip_list: should be a string or list of strings\n", filename); + return -1; + } + } + + virConfFree (conf); + return 0; +} + /* Print command-line usage. */ static void usage (const char *argv0) { fprintf (stderr, - "\n" - "Usage:\n" - " %s [options]\n" - "\n" - "Options:\n" - " -v | --verbose Verbose messages.\n" - " -d | --daemon Run as a daemon & write PID file.\n" - " -s | --system Run as system daemon.\n" - " -t | --timeout Exit after timeout period.\n" - " -p | --pid-file Change name of PID file.\n" - "\n" - "Notes:\n" - "\n" - "For '--system' option you must be running this daemon as root.\n" - "\n" - "The '--timeout' applies only when the daemon is not servicing\n" - "clients.\n" - "\n" - "Default paths:\n" - "\n" - " Sockets (in system mode):\n" - " " LOCAL_STATE_DIR "/run/libvirt/qemud-sock\n" - " " LOCAL_STATE_DIR "/run/libvirt/qemud-sock-ro\n" - "\n" - " Sockets (not in system mode):\n" - " $HOME/.libvirt/qemud-sock (in Unix abstract namespace)\n" - "\n" - " PID file (unless overridden by --pid-file):\n" - " " QEMUD_PID_FILE "\n" - "\n", - argv0); + "\n\ +Usage:\n\ + %s [options]\n\ +\n\ +Options:\n\ + -v | --verbose Verbose messages.\n\ + -d | --daemon Run as a daemon & write PID file.\n\ + -r | --remote Act as remote server.\n\ + -s | --system Run as system daemon (QEMUD only).\n\ + -t | --timeout Exit after timeout period (QEMUD only).\n\ + -f | --config Configuration file (remote only).\n\ + -p | --pid-file Change name of PID file.\n\ +\n\ +Remote and QEMU/network management:\n\ +\n\ +The '--remote' flag selects between running as a remote server\n\ +for remote libvirt requests, versus running as a QEMU\n\ +and network management daemon.\n\ +\n\ +Normally you need to have one daemon of each type.\n\ +\n\ +See also http://libvirt.org/remote.html\n\ +\n\ +For remote daemon:\n\ +\n\ + Default paths:\n\ +\n\ + Configuration file (unless overridden by -f):\n\ + " SYSCONF_DIR "/libvirt/libvirtd.conf\n\ +\n\ + Sockets:\n\ + " LOCAL_STATE_DIR "/run/libvirt/libvirt-sock\n\ + " LOCAL_STATE_DIR "/run/libvirt/libvirt-sock-ro\n\ +\n\ + TLS:\n\ + CA certificate: " LIBVIRT_CACERT "\n\ + Server certificate: " LIBVIRT_SERVERCERT "\n\ + Server private key: " LIBVIRT_SERVERKEY "\n\ +\n\ + PID file (unless overridden by --pid-file):\n\ + %s\n\ +\n\ +For QEMU and network management daemon:\n\ +\n\ + For '--system' option you must be running this daemon as root.\n\ +\n\ + The '--timeout' applies only when the daemon is not servicing\n\ + clients.\n\ +\n\ + Default paths:\n\ +\n\ + Configuration files (in system mode):\n\ + " SYSCONF_DIR "/libvirt/qemu\n\ + " SYSCONF_DIR "/libvirt/qemu/autostart\n\ + " SYSCONF_DIR "/libvirt/qemu/networkd\n\ + " SYSCONF_DIR "/libvirt/qemu/networks/autostart\n\ +\n\ + Configuration files (not in system mode):\n\ + $HOME/.libvirt/qemu\n\ + $HOME/.libvirt/qemu/autostart\n\ + $HOME/.libvirt/qemu/networks\n\ + $HOME/.libvirt/qemu/networks/autostart\n\ +\n\ + Sockets (in system mode):\n\ + " LOCAL_STATE_DIR "/run/libvirt/qemud-sock\n\ + " LOCAL_STATE_DIR "/run/libvirt/qemud-sock-ro\n\ +\n\ + Sockets (not in system mode):\n\ + $HOME/.libvirt/qemud-sock (in Unix abstract namespace)\n\ +\n\ + PID file (unless overridden by --pid-file):\n\ + %s\n\ +\n", + argv0, + REMOTE_PID_FILE[0] != '\0' + ? REMOTE_PID_FILE + : "(disabled in ./configure)", + QEMUD_PID_FILE[0] != '\0' + ? QEMUD_PID_FILE + : "(disabled in ./configure)"); } #define MAX_LISTEN 5 int main(int argc, char **argv) { - int sys = 0; - int timeout = -1; struct qemud_server *server; struct sigaction sig_action; int sigpipe[2]; - char *pid_file = NULL; + const char *pid_file = NULL; + const char *remote_config_file = SYSCONF_DIR "/libvirt/libvirtd.conf"; int ret = 1; struct option opts[] = { { "verbose", no_argument, &verbose, 1}, { "daemon", no_argument, &godaemon, 1}, + { "remote", no_argument, &remote, 1}, + { "config", required_argument, NULL, 'f'}, { "system", no_argument, &sys, 1}, { "timeout", required_argument, NULL, 't'}, { "pid-file", required_argument, NULL, 'p'}, @@ -1918,7 +2829,7 @@ int main(int argc, char **argv) { int c; char *tmp; - c = getopt_long(argc, argv, "vsdt:p:", opts, &optidx); + c = getopt_long(argc, argv, "dfp:s:t:v", opts, &optidx); if (c == -1) { break; @@ -1934,6 +2845,9 @@ int main(int argc, char **argv) { case 'd': godaemon = 1; break; + case 'r': + remote = 1; + break; case 's': sys = 1; break; @@ -1947,7 +2861,11 @@ int main(int argc, char **argv) { break; case 'p': - pid_file = strdup(optarg); + pid_file = optarg; + break; + + case 'f': + remote_config_file = optarg; break; case '?': @@ -1959,6 +2877,12 @@ int main(int argc, char **argv) { } } + /* In remote mode only, now read the config file (if it exists). */ + if (remote) { + if (remoteReadConfigFile (remote_config_file) < 0) + goto error1; + } + if (godaemon) openlog("libvirt-qemud", 0, 0); @@ -1995,16 +2919,27 @@ int main(int argc, char **argv) { if (pid > 0) goto out; - if (qemudWritePidFile(pid_file ? pid_file : QEMUD_PID_FILE) < 0) + /* Choose the name of the PID file. */ + if (!pid_file) { + if (remote) { + if (REMOTE_PID_FILE[0] != '\0') + pid_file = REMOTE_PID_FILE; + } else { + if (QEMUD_PID_FILE[0] != '\0') + pid_file = QEMUD_PID_FILE; + } + } + + if (pid_file && qemudWritePidFile (pid_file) < 0) goto error1; } - if (!(server = qemudInitialize(sys, sigpipe[0]))) { + if (!(server = qemudInitialize(sigpipe[0]))) { ret = 2; goto error2; } - qemudRunLoop(server, timeout); + qemudRunLoop(server); qemudCleanup(server); @@ -2017,13 +2952,10 @@ int main(int argc, char **argv) { ret = 0; error2: - if (godaemon) - unlink(pid_file ? pid_file : QEMUD_PID_FILE); + if (godaemon && pid_file) + unlink (pid_file); error1: - if (pid_file) - free(pid_file); - return ret; }