提交 23ad665c 编写于 作者: D Daniel P. Berrange

Added QEMU support

上级 ed022901
Tue Feb 13 19:29:35 EST 2007 Daniel Berrange <berrange@redhat.com>
* src/qemu_internal.h, src/qemu_internal.c, src/Makefile.am,
src/driver.h, src/libvirt.c: Added a new driver to talk to
the QEMU daemon
* src/virterror.c, include/libvirt/virterror.c: Added new
error domain for QEMU.
* qemud/*: Added a daemon service for managing QEMU machines
via the libvirt qemu_internal driver
* src/virsh.c: use a read-write connection by default for QEMU
urls.
* configure.in, Makefile.am: Added qemud subdirectory.
Thu Feb 8 12:59:14 EST 2007 Daniel Berrange <berrange@redhat.com>
* src/xml.c, src/xend_internal.c, src/xend_internal.h: Remove
......
## Process this file with automake to produce Makefile.in
SUBDIRS = src include docs @PYTHON_SUBDIR@ tests proxy po
SUBDIRS = src qemud proxy include docs @PYTHON_SUBDIR@ tests po
ACLOCAL_AMFLAGS = -I m4
......
......@@ -288,6 +288,7 @@ AC_OUTPUT(Makefile src/Makefile include/Makefile docs/Makefile \
po/Makefile.in \
include/libvirt/Makefile include/libvirt/libvirt.h \
python/Makefile python/tests/Makefile \
qemud/Makefile \
tests/Makefile proxy/Makefile \
tests/xml2sexprdata/Makefile \
tests/sexpr2xmldata/Makefile \
......
......@@ -46,7 +46,8 @@ typedef enum {
VIR_FROM_DOM, /* Error when operating on a domain */
VIR_FROM_RPC, /* Error in the XML-RPC code */
VIR_FROM_PROXY, /* Error in the proxy code */
VIR_FROM_CONF /* Error in the configuration file handling */
VIR_FROM_CONF, /* Error in the configuration file handling */
VIR_FROM_QEMU, /* Error at the QEMU daemon */
} virErrorDomain;
......
Makefile
Makefile.in
.deps
.libs
*.lo
*.la
libvirt_qemud
## Process this file with automake to produce Makefile.in
INCLUDES = @LIBXML_CFLAGS@
libexec_PROGRAMS = libvirt_qemud
libvirt_qemud_SOURCES = qemud.c internal.h protocol.h \
driver.c driver.h \
dispatch.c dispatch.h \
config.c config.h
#-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) \
-Werror -Wall -Wextra -DLOCAL_STATE_DIR="\"$(localstatedir)\"" \
-DSYSCONF_DIR="\"$(sysconfdir)\""
libvirt_qemud_LDFLAGS = $(LIBXML_LIBS)
libvirt_qemud_DEPENDENCIES =
libvirt_qemud_LDADD =
此差异已折叠。
/*
* config.h: VM configuration management
*
* 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 <berrange@redhat.com>
*/
#ifndef __QEMUD_CONFIG_H
#define __QEMUD_CONFIG_H
#include "internal.h"
int qemudBuildCommandLine(struct qemud_server *server,
struct qemud_vm *vm,
char ***argv,
int *argc);
void qemudFreeVM(struct qemud_vm *vm);
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
int persist);
int qemudScanConfigs(struct qemud_server *server);
char *qemudGenerateXML(struct qemud_server *server,
struct qemud_vm *vm);
int qemudDeleteConfigXML(struct qemud_server *server,
struct qemud_vm *vm);
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
此差异已折叠。
/*
* config.h: VM configuration management
*
* 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 <berrange@redhat.com>
*/
#ifndef __QEMUD_CONFIG_H
#define __QEMUD_CONFIG_H
#include "internal.h"
int qemudBuildCommandLine(struct qemud_server *server,
struct qemud_vm *vm,
char ***argv,
int *argc);
void qemudFreeVM(struct qemud_vm *vm);
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
int persist);
int qemudScanConfigs(struct qemud_server *server);
char *qemudGenerateXML(struct qemud_server *server,
struct qemud_vm *vm);
int qemudDeleteConfigXML(struct qemud_server *server,
struct qemud_vm *vm);
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
此差异已折叠。
/*
* dispatch.h: (De-)marshall wire messages to driver functions.
*
* 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 <berrange@redhat.com>
*/
#ifndef QEMUD_DISPATCH_H
#define QEMUD_DISPATCH_H
#include "internal.h"
int qemudDispatch(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out);
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
/*
* driver.c: core driver methods for managing qemu guests
*
* 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 <berrange@redhat.com>
*/
#include <sys/types.h>
#include <sys/poll.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <strings.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <libvirt/virterror.h>
#include "internal.h"
#include "driver.h"
#include "config.h"
void qemudReportError(struct qemud_server *server,
int code, const char *fmt, ...) {
va_list args;
server->errorCode = code;
if (fmt) {
va_start(args, fmt);
vsnprintf(server->errorMessage, QEMUD_MAX_ERROR_LEN-1, fmt, args);
va_end(args);
} else {
server->errorMessage[0] = '\0';
}
}
int qemudMonitorCommand(struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_vm *vm,
const char *cmd,
char **reply) {
int size = 0;
char *buf = NULL;
if (write(vm->monitor, cmd, strlen(cmd)) < 0) {
return -1;
}
*reply = NULL;
for (;;) {
struct pollfd fd = { vm->monitor, POLLIN | POLLERR | POLLHUP, 0 };
char *tmp;
/* Read all the data QEMU has sent thus far */
for (;;) {
char data[1024];
int got = read(vm->monitor, data, sizeof(data));
if (got < 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN)
break;
free(buf);
return -1;
}
if (!(buf = realloc(buf, size+got+1)))
return -1;
memmove(buf+size, data, got);
buf[size+got] = '\0';
size += got;
}
if (buf)
QEMUD_DEBUG("Mon [%s]\n", buf);
/* Look for QEMU prompt to indicate completion */
if (buf && ((tmp = strstr(buf, "\n(qemu)")) != NULL)) {
tmp[0] = '\0';
break;
}
pollagain:
/* Need to wait for more data */
if (poll(&fd, 1, -1) < 0) {
if (errno == EINTR)
goto pollagain;
free(buf);
return -1;
}
}
*reply = buf;
return 0;
}
int qemudGetMemInfo(unsigned int *memory) {
FILE *meminfo = fopen("/proc/meminfo", "r");
char line[1024];
*memory = 0;
if (!meminfo) {
return -1;
}
/* XXX NUMA and hyperthreads ? */
while (fgets(line, sizeof(line), meminfo) != NULL) {
if (!strncmp(line, "MemTotal:", 9)) {
*memory = (unsigned int)strtol(line + 10, NULL, 10);
}
}
fclose(meminfo);
return 0;
}
int qemudGetCPUInfo(unsigned int *cpus, unsigned int *mhz,
unsigned int *nodes, unsigned int *sockets,
unsigned int *cores, unsigned int *threads) {
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
char line[1024];
*cpus = 0;
*mhz = 0;
*nodes = *sockets = *cores = *threads = 1;
if (!cpuinfo) {
return -1;
}
/* XXX NUMA and hyperthreads ? */
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
if (!strncmp(line, "processor\t", 10)) { /* aka a single logical CPU */
(*cpus)++;
} else if (!strncmp(line, "cpu MHz\t", 8)) {
char *offset = index(line, ':');
if (!offset)
continue;
offset++;
if (!*offset)
continue;
*mhz = (unsigned int)strtol(offset, NULL, 10);
} else if (!strncmp(line, "physical id\t", 12)) { /* aka socket */
unsigned int id;
char *offset = index(line, ':');
if (!offset)
continue;
offset++;
if (!*offset)
continue;
id = (unsigned int)strtol(offset, NULL, 10);
if ((id+1) > *sockets)
*sockets = (id + 1);
} else if (!strncmp(line, "cpu cores\t", 9)) { /* aka cores */
unsigned int id;
char *offset = index(line, ':');
if (!offset)
continue;
offset++;
if (!*offset)
continue;
id = (unsigned int)strtol(offset, NULL, 10);
if (id > *cores)
*cores = id;
}
}
fclose(cpuinfo);
return 0;
}
static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
char proc[PATH_MAX];
FILE *pidinfo;
unsigned long usertime, systime;
if (snprintf(proc, sizeof(proc), "/proc/%d/stat", pid) >= (int)sizeof(proc)) {
return -1;
}
if (!(pidinfo = fopen(proc, "r"))) {
/*printf("cannnot read pid info");*/
/* VM probably shut down, so fake 0 */
*cpuTime = 0;
return 0;
}
if (fscanf(pidinfo, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &usertime, &systime) != 2) {
QEMUD_DEBUG("not enough arg\n");
return -1;
}
/* We got jiffies
* We want nanoseconds
* _SC_CLK_TCK is jiffies per second
* So calulate thus....
*/
*cpuTime = 1000 * 1000 * 1000 * (usertime + systime) / sysconf(_SC_CLK_TCK);
QEMUD_DEBUG("Got %lu %lu %lld\n", usertime, systime, *cpuTime);
fclose(pidinfo);
return 0;
}
struct qemud_vm *qemudFindVMByID(const struct qemud_server *server, int id) {
struct qemud_vm *vm = server->activevms;
while (vm) {
if (vm->def.id == id)
return vm;
vm = vm->next;
}
return NULL;
}
struct qemud_vm *qemudFindVMByUUID(const struct qemud_server *server,
const unsigned char *uuid) {
struct qemud_vm *vm = server->activevms;
while (vm) {
if (!memcmp(vm->def.uuid, uuid, QEMUD_UUID_RAW_LEN))
return vm;
vm = vm->next;
}
vm = server->inactivevms;
while (vm) {
if (!memcmp(vm->def.uuid, uuid, QEMUD_UUID_RAW_LEN))
return vm;
vm = vm->next;
}
return NULL;
}
struct qemud_vm *qemudFindVMByName(const struct qemud_server *server,
const char *name) {
struct qemud_vm *vm = server->activevms;
while (vm) {
if (!strcmp(vm->def.name, name))
return vm;
vm = vm->next;
}
vm = server->inactivevms;
while (vm) {
if (!strcmp(vm->def.name, name))
return vm;
vm = vm->next;
}
return NULL;
}
int qemudGetVersion(struct qemud_server *server) {
return server->qemuVersion;
}
int qemudListDomains(struct qemud_server *server, int *ids, int nids) {
struct qemud_vm *vm = server->activevms;
int got = 0;
while (vm && got < nids) {
ids[got] = vm->def.id;
vm = vm->next;
got++;
}
return got;
}
int qemudNumDomains(struct qemud_server *server) {
return server->nactivevms;
}
struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
struct qemud_vm *vm;
if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0))) {
return NULL;
}
if (qemudStartVMDaemon(server, vm) < 0) {
qemudFreeVM(vm);
return NULL;
}
vm->next = server->activevms;
server->activevms = vm;
server->nactivevms++;
server->nvmfds += 2;
return vm;
}
int qemudDomainSuspend(struct qemud_server *server, int id) {
char *info;
struct qemud_vm *vm = qemudFindVMByID(server, id);
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
return -1;
}
if (vm->pid == -1) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
return -1;
}
if (qemudMonitorCommand(server, vm, "stop\n", &info) < 0) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "suspend operation failed");
return -1;
}
printf("Reply %s\n", info);
free(info);
return 0;
}
int qemudDomainResume(struct qemud_server *server, int id) {
char *info;
struct qemud_vm *vm = qemudFindVMByID(server, id);
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
return -1;
}
if (vm->pid == -1) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
return -1;
}
if (qemudMonitorCommand(server, vm, "cont\n", &info) < 0) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "resume operation failed");
return -1;
}
printf("Reply %s\n", info);
free(info);
return -1;
}
int qemudDomainDestroy(struct qemud_server *server, int id) {
struct qemud_vm *vm = qemudFindVMByID(server, id);
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
return -1;
}
if (vm->pid == -1) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
return -1;
}
if (qemudShutdownVMDaemon(server, vm) < 0)
return -1;
return 0;
}
int qemudDomainGetInfo(struct qemud_server *server, const unsigned char *uuid,
int *runstate,
unsigned long long *cputime,
unsigned long *maxmem,
unsigned long *memory,
unsigned int *nrVirtCpu) {
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
return -1;
}
if (vm->pid == -1) {
*runstate = QEMUD_STATE_STOPPED;
} else {
/* XXX in future need to add PAUSED */
*runstate = QEMUD_STATE_RUNNING;
}
if (vm->pid == -1) {
*cputime = 0;
} else {
if (qemudGetProcessInfo(cputime, vm->pid) < 0) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "cannot read cputime for domain");
return -1;
}
}
*maxmem = vm->def.maxmem;
*memory = vm->def.memory;
*nrVirtCpu = vm->def.vcpus;
return 0;
}
int qemudDomainSave(struct qemud_server *server, int id,
const char *path ATTRIBUTE_UNUSED) {
struct qemud_vm *vm = qemudFindVMByID(server, id);
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching id %d", id);
return -1;
}
if (vm->pid == -1) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "domain is not running");
return -1;
}
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "save is not supported");
return -1;
}
int qemudDomainRestore(struct qemud_server *server,
const char *path ATTRIBUTE_UNUSED) {
qemudReportError(server, VIR_ERR_OPERATION_FAILED, "restore is not supported");
return -1;
}
int qemudDomainDumpXML(struct qemud_server *server, const unsigned char *uuid, char *xml, int xmllen) {
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
char *vmxml;
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
return -1;
}
vmxml = qemudGenerateXML(server, vm);
if (!vmxml)
return -1;
strncpy(xml, vmxml, xmllen);
xml[xmllen-1] = '\0';
return 0;
}
int qemudListDefinedDomains(struct qemud_server *server, char *const*names, int nnames) {
struct qemud_vm *vm = server->inactivevms;
int got = 0;
while (vm && got < nnames) {
strncpy(names[got], vm->def.name, QEMUD_MAX_NAME_LEN-1);
names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
vm = vm->next;
got++;
}
return got;
}
int qemudNumDefinedDomains(struct qemud_server *server) {
return server->ninactivevms;
}
int qemudDomainStart(struct qemud_server *server, struct qemud_vm *vm) {
struct qemud_vm *prev = NULL, *curr = server->inactivevms;
if (qemudStartVMDaemon(server, vm) < 0) {
return 1;
}
while (curr) {
if (curr == vm) {
if (prev)
prev->next = curr->next;
else
server->inactivevms = curr->next;
server->ninactivevms--;
break;
}
prev = curr;
curr = curr->next;
}
vm->next = server->activevms;
server->activevms = vm;
server->nactivevms++;
server->nvmfds += 2;
return 0;
}
struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
struct qemud_vm *vm;
if (!(vm = qemudLoadConfigXML(server, NULL, xml, 1))) {
return NULL;
}
vm->next = server->inactivevms;
server->inactivevms = vm;
server->ninactivevms++;
return vm;
}
int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
struct qemud_vm *prev = NULL, *curr = server->inactivevms;
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
return -1;
}
if (vm->pid != -1) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot delete active domain");
return -1;
}
if (qemudDeleteConfigXML(server, vm) < 0)
return -1;
while (curr) {
if (curr == vm) {
if (prev) {
prev->next = curr->next;
} else {
server->inactivevms = curr->next;
}
server->ninactivevms--;
break;
}
prev = curr;
curr = curr->next;
}
qemudFreeVM(vm);
return 0;
}
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
/*
* driver.h: core driver methods for managing qemu guests
*
* 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 <berrange@redhat.com>
*/
#ifndef QEMUD_DRIVER_H
#define QEMUD_DRIVER_H
#include "internal.h"
void qemudReportError(struct qemud_server *server,
int code, const char *fmt, ...);
int qemudGetCPUInfo(unsigned int *cpus, unsigned int *mhz,
unsigned int *nodes, unsigned int *sockets,
unsigned int *cores, unsigned int *threads);
int qemudGetMemInfo(unsigned int *memory);
int qemudMonitorCommand(struct qemud_server *server,
struct qemud_vm *vm,
const char *cmd,
char **reply);
struct qemud_vm *qemudFindVMByID(const struct qemud_server *server,
int id);
struct qemud_vm *qemudFindVMByUUID(const struct qemud_server *server,
const unsigned char *uuid);
struct qemud_vm *qemudFindVMByName(const struct qemud_server *server,
const char *name);
int qemudGetVersion(struct qemud_server *server);
int qemudListDomains(struct qemud_server *server,
int *ids,
int nids);
int qemudNumDomains(struct qemud_server *server);
struct qemud_vm *qemudDomainCreate(struct qemud_server *server,
const char *xml);
int qemudDomainSuspend(struct qemud_server *server,
int id);
int qemudDomainResume(struct qemud_server *server,
int id);
int qemudDomainDestroy(struct qemud_server *server,
int id);
int qemudDomainGetInfo(struct qemud_server *server,
const unsigned char *uuid,
int *runstate,
unsigned long long *cputime,
unsigned long *maxmem,
unsigned long *memory,
unsigned int *nrVirtCpu);
int qemudDomainSave(struct qemud_server *server,
int id,
const char *path);
int qemudDomainRestore(struct qemud_server *server,
const char *path);
int qemudDomainDumpXML(struct qemud_server *server,
const unsigned char *uuid,
char *xml,
int xmllen);
int qemudListDefinedDomains(struct qemud_server *server,
char *const*names,
int nnames);
int qemudNumDefinedDomains(struct qemud_server *server);
int qemudDomainStart(struct qemud_server *server,
struct qemud_vm *vm);
struct qemud_vm *qemudDomainDefine(struct qemud_server *server,
const char *xml);
int qemudDomainUndefine(struct qemud_server *server,
const unsigned char *uuid);
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
/*
* internal.h: daemon data structure definitions
*
* 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 <berrange@redhat.com>
*/
#ifndef QEMUD_INTERNAL_H__
#define QEMUD_INTERNAL_H__
#include <sys/socket.h>
#include <netinet/in.h>
#include <gnutls/gnutls.h>
#include "protocol.h"
#ifdef __GNUC__
#ifdef HAVE_ANSIDECL_H
#include <ansidecl.h>
#endif
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__((unused))
#endif
#else
#define ATTRIBUTE_UNUSED
#endif
#ifdef DEBUG
#define QEMUD_DEBUG(args...) fprintf(stderr, args)
#else
#define QEMUD_DEBUG(args...) do {} while(0)
#endif
#define UUID_LEN 16
/* Different types of QEMU acceleration possible */
enum qemud_vm_virt_type {
QEMUD_VIRT_QEMU,
QEMUD_VIRT_KQEMU,
QEMUD_VIRT_KVM,
};
/* Two types of disk backends */
enum qemud_vm_disk_type {
QEMUD_DISK_BLOCK,
QEMUD_DISK_FILE
};
/* Three types of disk frontend */
enum qemud_vm_disk_device {
QEMUD_DISK_DISK,
QEMUD_DISK_CDROM,
QEMUD_DISK_FLOPPY,
};
/* Stores the virtual disk configuration */
struct qemud_vm_disk_def {
int type;
int device;
char src[PATH_MAX];
char dst[NAME_MAX];
int readonly;
struct qemud_vm_disk_def *next;
};
#define QEMUD_MAC_ADDRESS_LEN 6
#define QEMUD_OS_TYPE_MAX_LEN 10
#define QEMUD_OS_ARCH_MAX_LEN 10
#define QEMUD_OS_MACHINE_MAX_LEN 10
/* 5 different types of networking config */
enum qemud_vm_net_type {
QEMUD_NET_USER,
QEMUD_NET_TAP,
QEMUD_NET_SERVER,
QEMUD_NET_CLIENT,
QEMUD_NET_MCAST,
/* QEMUD_NET_VDE*/
};
/* Stores the virtual network interface configuration */
struct qemud_vm_net_def {
int type;
int vlan;
unsigned char mac[QEMUD_MAC_ADDRESS_LEN];
union {
struct {
char ifname[NAME_MAX];
char script[PATH_MAX];
} tap;
struct {
struct sockaddr_in listen;
int port;
} server;
struct {
struct sockaddr_in connect;
int port;
} client;
struct {
struct sockaddr_in group;
int port;
} mcast;
struct {
char vlan[PATH_MAX];
} vde;
} dst;
struct qemud_vm_net_def *next;
};
#define QEMUD_MAX_BOOT_DEVS 4
/* 3 possible boot devices */
enum qemud_vm_boot_order {
QEMUD_BOOT_FLOPPY,
QEMUD_BOOT_CDROM,
QEMUD_BOOT_DISK,
QEMUD_BOOT_NET,
};
/* 3 possible graphics console modes */
enum qemud_vm_grapics_type {
QEMUD_GRAPHICS_NONE,
QEMUD_GRAPHICS_SDL,
QEMUD_GRAPHICS_VNC,
};
enum qemud_vm_features {
QEMUD_FEATURE_ACPI = 1,
};
/* Operating system configuration data & machine / arch */
struct qemud_vm_os_def {
char type[QEMUD_OS_TYPE_MAX_LEN];
char arch[QEMUD_OS_ARCH_MAX_LEN];
char machine[QEMUD_OS_MACHINE_MAX_LEN];
int nBootDevs;
int bootDevs[QEMUD_MAX_BOOT_DEVS];
char kernel[PATH_MAX];
char initrd[PATH_MAX];
char cmdline[PATH_MAX];
char binary[PATH_MAX];
};
/* Guest VM main configuration */
struct qemud_vm_def {
int id;
int virtType;
unsigned char uuid[QEMUD_UUID_RAW_LEN];
char name[QEMUD_MAX_NAME_LEN];
int memory;
int maxmem;
int vcpus;
struct qemud_vm_os_def os;
int features;
int graphicsType;
int vncPort;
int vncActivePort;
int ndisks;
struct qemud_vm_disk_def *disks;
int nnets;
struct qemud_vm_net_def *nets;
};
/* Guest VM runtime state */
struct qemud_vm {
int stdout;
int stderr;
int monitor;
int pid;
char configFile[PATH_MAX];
struct qemud_vm_def def;
struct qemud_vm *next;
};
/* Stores the per-client connection state */
struct qemud_client {
int fd;
int readonly;
struct qemud_packet incoming;
unsigned int incomingReceived;
struct qemud_packet outgoing;
unsigned int outgoingSent;
int tx;
struct qemud_client *next;
};
struct qemud_socket {
int fd;
int readonly;
struct qemud_socket *next;
};
/* Main server state */
struct qemud_server {
int nsockets;
struct qemud_socket *sockets;
int qemuVersion;
int nclients;
struct qemud_client *clients;
int nvmfds;
int nactivevms;
struct qemud_vm *activevms;
int ninactivevms;
struct qemud_vm *inactivevms;
int nextvmid;
char configDir[PATH_MAX];
char errorMessage[QEMUD_MAX_ERROR_LEN];
int errorCode;
};
int qemudStartVMDaemon(struct qemud_server *server,
struct qemud_vm *vm);
int qemudShutdownVMDaemon(struct qemud_server *server,
struct qemud_vm *vm);
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
/*
* 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 <berrange@redhat.com>
*/
#ifndef QEMUD_PROTOCOL_H__
#define QEMUD_PROTOCOL_H__
#include <stdint.h>
/* List of different packet types which can be sent */
enum {
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_MAX,
} qemud_packet_type;
#define QEMUD_PROTOCOL_VERSION_MAJOR 1
#define QEMUD_PROTOCOL_VERSION_MINOR 0
#define QEMUD_UUID_RAW_LEN 16
#define QEMUD_MAX_NAME_LEN 50
#define QEMUD_MAX_XML_LEN 4096
#define QEMUD_MAX_NUM_DOMAINS 100
#define QEMUD_MAX_ERROR_LEN 1024
/* Possible guest VM states */
enum {
QEMUD_STATE_RUNNING = 1,
QEMUD_STATE_PAUSED,
QEMUD_STATE_STOPPED,
} qemud_domain_runstate;
/* 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;
};
/* 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 {
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;
};
/* Each packet has header & data */
struct qemud_packet {
struct qemud_packet_header header;
union qemud_packet_data data;
};
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
此差异已折叠。
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_builddir)/include -I@top_srcdir@/include @LIBXML_CFLAGS@ \
INCLUDES = -I$(top_builddir)/include -I@top_srcdir@/include @LIBXML_CFLAGS@ -I@top_srcdir@/qemud \
-DBINDIR=\""$(libexecdir)"\" -DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-DLOCAL_STATE_DIR=\""$(localstatedir)"\" \
-DGETTEXT_PACKAGE=\"$(PACKAGE)\"
DEPS = libvirt.la
LDADDS = @STATIC_BINARIES@ libvirt.la
......@@ -11,7 +12,6 @@ EXTRA_DIST = libvirt_sym.version
lib_LTLIBRARIES = libvirt.la
libvirt_la_LIBADD = @LIBXML_LIBS@
libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
-version-info @LIBVIRT_VERSION_INFO@
......@@ -28,7 +28,8 @@ libvirt_la_SOURCES = \
driver.h \
proxy_internal.c proxy_internal.h \
conf.c conf.h \
xm_internal.c xm_internal.h
xm_internal.c xm_internal.h \
qemu_internal.c qemu_internal.h
bin_PROGRAMS = virsh
......
......@@ -22,7 +22,8 @@ typedef enum {
VIR_DRV_XEN_DAEMON = 3,
VIR_DRV_TEST = 4,
VIR_DRV_XEN_PROXY = 5,
VIR_DRV_XEN_XM = 6
VIR_DRV_XEN_XM = 6,
VIR_DRV_QEMU = 7
} virDrvNo;
......
......@@ -32,6 +32,7 @@
#include "proxy_internal.h"
#include "xml.h"
#include "test.h"
#include "qemu_internal.h"
/*
* TODO:
......@@ -79,6 +80,8 @@ virInitialize(void)
xenStoreRegister();
xenXMRegister();
testRegister();
qemuRegister();
return(0);
}
......@@ -441,6 +444,7 @@ virConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
return(0);
}
}
return (-1);
}
......
此差异已折叠。
/*
* qemu_internal.h: A backend for managing QEMU machines
*
* 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 <berrange@redhat.com>
*/
#ifndef __VIR_QEMU_INTERNAL_H__
#define __VIR_QEMU_INTERNAL_H__
#include <libvirt/virterror.h>
#ifdef __cplusplus
extern "C" {
#endif
void qemuRegister(void);
#ifdef __cplusplus
}
#endif
#endif /* __VIR_QEMU_INTERNAL_H__ */
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
......@@ -2529,7 +2529,9 @@ vshInit(vshControl * ctl)
/* basic connection to hypervisor, for Xen connections unless
we're root open a read only connections. Allow 'test' HV
to be RW all the time though */
if (ctl->uid == 0 || (ctl->name && !strncmp(ctl->name, "test", 4)))
if (ctl->uid == 0 || (ctl->name &&
(!strncmp(ctl->name, "test", 4) ||
!strncmp(ctl->name, "qemu", 4))))
ctl->conn = virConnectOpen(ctl->name);
else
ctl->conn = virConnectOpenReadOnly(ctl->name);
......
......@@ -268,6 +268,9 @@ virDefaultErrorFunc(virErrorPtr err)
case VIR_FROM_RPC:
dom = "XML-RPC ";
break;
case VIR_FROM_QEMU:
dom = "QEMU ";
break;
}
if ((err->dom != NULL) && (err->code != VIR_ERR_INVALID_DOMAIN)) {
domain = err->dom->name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册