2007-02-14 01:40:09 +00:00
|
|
|
/*
|
|
|
|
* driver.c: core driver methods for managing qemu guests
|
|
|
|
*
|
Eliminate all uses of virBufferAdd with string literals.
* Makefile.maint (sc_prohibit_virBufferAdd_with_string_literal):
New rule.
* src/buf.h (virBufferAddLit): Define.
* src/conf.c (virConfSaveValue): Use virBufferAddLit, in place
of virBufferAdd everywhere possible.
(virConfSaveEntry): Likewise.
* src/qemu_conf.c (qemudGenerateXML, qemudGenerateNetworkXML): Likewise.
* src/qemu_driver.c (qemudGetFeatures, qemudGetCapabilities): Likewise.
* src/test.c (testDomainDumpXML, testNetworkDumpXML): Likewise.
* src/xen_internal.c (xenHypervisorMakeCapabilitiesXML): Likewise.
* src/xend_internal.c (xend_parse_sexp_desc_os): Likewise.
(xend_parse_sexp_desc, sexpr_to_xend_topology_xml): Likewise.
* src/xm_internal.c (xenXMDomainFormatXML, xenXMDomainPinVcpu): Likewise.
* src/xml.c (virSaveCpuSet, virParseXenCpuTopology): Likewise.
(virDomainParseXMLGraphicsDescImage): Likewise.
(virDomainParseXMLGraphicsDescVFB, virDomainParseXMLOSDescHVM): Likewise.
(virDomainParseXMLOSDescPV, virDomainParseXMLDiskDesc): Likewise.
(virDomainParseXMLIfDesc, virDomainParseXMLDesc): Likewise.
2008-02-05 14:22:28 +00:00
|
|
|
* Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
|
2007-02-14 01:40:09 +00:00
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-11-26 11:50:16 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
#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>
|
2007-06-26 19:49:50 +00:00
|
|
|
#include <sys/utsname.h>
|
2007-06-26 20:41:25 +00:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <paths.h>
|
2007-06-26 22:13:21 +00:00
|
|
|
#include <pwd.h>
|
|
|
|
#include <stdio.h>
|
2007-06-26 20:41:25 +00:00
|
|
|
#include <sys/wait.h>
|
2008-09-17 14:07:49 +00:00
|
|
|
#include <sys/ioctl.h>
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-22 15:29:50 +00:00
|
|
|
#if HAVE_NUMACTL
|
2008-11-28 11:20:27 +00:00
|
|
|
#define NUMA_VERSION1_COMPATIBILITY 1
|
2008-05-22 15:29:50 +00:00
|
|
|
#include <numa.h>
|
|
|
|
#endif
|
|
|
|
|
2008-05-22 16:20:31 +00:00
|
|
|
#if HAVE_SCHED_H
|
|
|
|
#include <sched.h>
|
|
|
|
#endif
|
|
|
|
|
2008-11-04 22:30:33 +00:00
|
|
|
#include "virterror_internal.h"
|
2008-11-06 16:36:07 +00:00
|
|
|
#include "logging.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2008-07-11 19:34:11 +00:00
|
|
|
#include "qemu_driver.h"
|
|
|
|
#include "qemu_conf.h"
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
#include "c-ctype.h"
|
2007-06-26 20:41:25 +00:00
|
|
|
#include "event.h"
|
2007-06-27 00:12:29 +00:00
|
|
|
#include "buf.h"
|
2007-07-19 16:22:40 +00:00
|
|
|
#include "util.h"
|
2007-07-25 23:16:30 +00:00
|
|
|
#include "nodeinfo.h"
|
2007-11-15 17:45:44 +00:00
|
|
|
#include "stats_linux.h"
|
2008-02-27 04:35:08 +00:00
|
|
|
#include "capabilities.h"
|
2008-05-22 16:20:31 +00:00
|
|
|
#include "memory.h"
|
2008-07-25 09:01:25 +00:00
|
|
|
#include "uuid.h"
|
2008-09-03 15:05:31 +00:00
|
|
|
#include "domain_conf.h"
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
|
|
|
|
2008-06-10 10:43:28 +00:00
|
|
|
/* For storing short-lived temporary files. */
|
|
|
|
#define TEMPDIR LOCAL_STATE_DIR "/cache/libvirt"
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudShutdown(void);
|
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
#define qemudLog(level, msg...) fprintf(stderr, msg)
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
static void qemuDriverLock(struct qemud_driver *driver)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexLock(&driver->lock);
|
2008-12-04 21:06:41 +00:00
|
|
|
}
|
|
|
|
static void qemuDriverUnlock(struct qemud_driver *driver)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexUnlock(&driver->lock);
|
2008-12-04 21:06:41 +00:00
|
|
|
}
|
|
|
|
|
2007-06-26 20:41:25 +00:00
|
|
|
static int qemudSetCloseExec(int fd) {
|
|
|
|
int flags;
|
|
|
|
if ((flags = fcntl(fd, F_GETFD)) < 0)
|
|
|
|
goto error;
|
|
|
|
flags |= FD_CLOEXEC;
|
|
|
|
if ((fcntl(fd, F_SETFD, flags)) < 0)
|
|
|
|
goto error;
|
|
|
|
return 0;
|
|
|
|
error:
|
2008-02-22 16:26:13 +00:00
|
|
|
qemudLog(QEMUD_ERR,
|
2008-08-01 11:24:04 +00:00
|
|
|
"%s", _("Failed to set close-on-exec file descriptor flag\n"));
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int qemudSetNonBlock(int fd) {
|
|
|
|
int flags;
|
|
|
|
if ((flags = fcntl(fd, F_GETFL)) < 0)
|
|
|
|
goto error;
|
|
|
|
flags |= O_NONBLOCK;
|
|
|
|
if ((fcntl(fd, F_SETFL, flags)) < 0)
|
|
|
|
goto error;
|
|
|
|
return 0;
|
|
|
|
error:
|
2008-02-22 16:26:13 +00:00
|
|
|
qemudLog(QEMUD_ERR,
|
2008-08-01 11:24:04 +00:00
|
|
|
"%s", _("Failed to set non-blocking file descriptor flag\n"));
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
|
|
|
|
static void qemuDomainEventFlush(int timer, void *opaque);
|
|
|
|
static void qemuDomainEventQueue(struct qemud_driver *driver,
|
|
|
|
virDomainEventPtr event);
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2008-11-19 16:19:36 +00:00
|
|
|
static void qemudDispatchVMEvent(int watch,
|
|
|
|
int fd,
|
2008-10-23 13:18:18 +00:00
|
|
|
int events,
|
|
|
|
void *opaque);
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
static int qemudStartVMDaemon(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
const char *migrateFrom);
|
2007-06-26 22:42:47 +00:00
|
|
|
|
2007-07-24 14:24:52 +00:00
|
|
|
static void qemudShutdownVMDaemon(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm);
|
2007-06-26 22:42:47 +00:00
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
static int qemudMonitorCommand (const virDomainObjPtr vm,
|
2008-05-22 16:20:31 +00:00
|
|
|
const char *cmd,
|
|
|
|
char **reply);
|
2008-05-07 16:16:44 +00:00
|
|
|
|
2008-01-14 14:05:25 +00:00
|
|
|
static struct qemud_driver *qemu_driver = NULL;
|
2007-06-26 22:13:21 +00:00
|
|
|
|
|
|
|
|
2009-01-11 11:18:31 +00:00
|
|
|
static int
|
|
|
|
qemudLogFD(virConnectPtr conn, const char* logDir, const char* name)
|
|
|
|
{
|
|
|
|
char logfile[PATH_MAX];
|
|
|
|
mode_t logmode;
|
|
|
|
uid_t uid = geteuid();
|
2009-01-11 11:21:29 +00:00
|
|
|
int ret, fd = -1;
|
2009-01-11 11:18:31 +00:00
|
|
|
|
2009-01-11 11:21:29 +00:00
|
|
|
if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log", logDir, name))
|
|
|
|
< 0 || ret >= sizeof(logfile)) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportOOMError(conn);
|
2009-01-11 11:18:31 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
logmode = O_CREAT | O_WRONLY;
|
|
|
|
if (uid != 0)
|
|
|
|
logmode |= O_TRUNC;
|
|
|
|
else
|
|
|
|
logmode |= O_APPEND;
|
|
|
|
if ((fd = open(logfile, logmode, S_IRUSR | S_IWUSR)) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno,
|
|
|
|
_("failed to create logfile %s"),
|
|
|
|
logfile);
|
2009-01-11 11:18:31 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (qemudSetCloseExec(fd) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno, "%s",
|
|
|
|
_("Unable to set VM logfile close-on-exec flag"));
|
2009-01-11 11:18:31 +00:00
|
|
|
close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
static int
|
|
|
|
qemudLogReadFD(virConnectPtr conn, const char* logDir, const char* name, off_t pos)
|
|
|
|
{
|
|
|
|
char logfile[PATH_MAX];
|
|
|
|
mode_t logmode = O_RDONLY;
|
|
|
|
int ret, fd = -1;
|
|
|
|
|
|
|
|
if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log", logDir, name))
|
|
|
|
< 0 || ret >= sizeof(logfile)) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("failed to build logfile name %s/%s.log"),
|
|
|
|
logDir, name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((fd = open(logfile, logmode)) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("failed to create logfile %s: %s"),
|
|
|
|
logfile, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (qemudSetCloseExec(fd) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unable to set VM logfile close-on-exec flag: %s"),
|
|
|
|
strerror(errno));
|
|
|
|
close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (lseek(fd, pos, SEEK_SET) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unable to seek to %lld in %s: %s"),
|
2009-01-20 16:39:35 +00:00
|
|
|
(long long) pos, logfile, strerror(errno));
|
2009-01-20 15:52:11 +00:00
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-10 14:20:37 +00:00
|
|
|
static void
|
|
|
|
qemudAutostartConfigs(struct qemud_driver *driver) {
|
|
|
|
unsigned int i;
|
2008-12-08 11:18:47 +00:00
|
|
|
/* XXX: Figure out a better way todo this. The domain
|
|
|
|
* startup code needs a connection handle in order
|
|
|
|
* to lookup the bridge associated with a virtual
|
|
|
|
* network
|
|
|
|
*/
|
|
|
|
virConnectPtr conn = virConnectOpen(getuid() ?
|
|
|
|
"qemu:///session" :
|
|
|
|
"qemu:///system");
|
|
|
|
/* Ignoring NULL conn which is mostly harmless here */
|
2008-10-10 14:20:37 +00:00
|
|
|
|
|
|
|
for (i = 0 ; i < driver->domains.count ; i++) {
|
2008-11-17 16:43:00 +00:00
|
|
|
virDomainObjPtr vm = driver->domains.objs[i];
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjLock(vm);
|
2008-11-17 16:43:00 +00:00
|
|
|
if (vm->autostart &&
|
|
|
|
!virDomainIsActive(vm)) {
|
2008-12-08 11:18:47 +00:00
|
|
|
int ret = qemudStartVMDaemon(conn, driver, vm, NULL);
|
2008-11-17 16:43:00 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
virErrorPtr err = virGetLastError();
|
|
|
|
qemudLog(QEMUD_ERR, _("Failed to autostart VM '%s': %s\n"),
|
|
|
|
vm->def->name,
|
|
|
|
err ? err->message : NULL);
|
|
|
|
} else {
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event =
|
|
|
|
virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-11-17 16:43:00 +00:00
|
|
|
}
|
2007-06-26 22:13:21 +00:00
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjUnlock(vm);
|
2007-06-26 22:13:21 +00:00
|
|
|
}
|
2008-12-08 11:18:47 +00:00
|
|
|
|
|
|
|
virConnectClose(conn);
|
2007-06-26 20:45:21 +00:00
|
|
|
}
|
|
|
|
|
2008-12-20 13:17:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* qemudRemoveDomainStatus
|
|
|
|
*
|
|
|
|
* remove all state files of a domain from statedir
|
|
|
|
*
|
|
|
|
* Returns 0 on success
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudRemoveDomainStatus(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
|
|
|
virDomainObjPtr vm)
|
|
|
|
{
|
|
|
|
int rc = -1;
|
|
|
|
char *file = NULL;
|
|
|
|
|
|
|
|
if (virAsprintf(&file, "%s/%s.xml", driver->stateDir, vm->def->name) < 0) {
|
|
|
|
qemudReportError(conn, vm, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("failed to allocate space for status file"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR) {
|
|
|
|
qemudReportError(conn, vm, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Failed to unlink status file %s"), file);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(virFileDeletePid(driver->stateDir, vm->def->name))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(file);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
static int qemudOpenMonitor(virConnectPtr conn,
|
|
|
|
struct qemud_driver* driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
const char *monitor,
|
|
|
|
int reconnect);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* qemudReconnectVMs
|
|
|
|
*
|
|
|
|
* Reconnect running vms to the daemon process
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudReconnectVMs(struct qemud_driver *driver)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0 ; i < driver->domains.count ; i++) {
|
|
|
|
virDomainObjPtr vm = driver->domains.objs[i];
|
|
|
|
qemudDomainStatusPtr status = NULL;
|
|
|
|
char *config = NULL;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
virDomainObjLock(vm);
|
|
|
|
if ((rc = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) == 0)
|
|
|
|
DEBUG("Found pid %d for '%s'", vm->pid, vm->def->name);
|
|
|
|
else
|
|
|
|
goto next;
|
|
|
|
|
|
|
|
if ((config = virDomainConfigFile(NULL,
|
|
|
|
driver->stateDir,
|
|
|
|
vm->def->name)) == NULL) {
|
|
|
|
qemudLog(QEMUD_ERR, _("Failed to read domain status for %s\n"),
|
|
|
|
vm->def->name);
|
|
|
|
goto next_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = qemudDomainStatusParseFile(NULL, driver->caps, config, 0);
|
|
|
|
if (status) {
|
|
|
|
vm->newDef = vm->def;
|
|
|
|
vm->def = status->def;
|
|
|
|
} else {
|
|
|
|
qemudLog(QEMUD_ERR, _("Failed to parse domain status for %s\n"),
|
|
|
|
vm->def->name);
|
|
|
|
goto next_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rc = qemudOpenMonitor(NULL, driver, vm, status->monitorpath, 1)) != 0) {
|
|
|
|
qemudLog(QEMUD_ERR, _("Failed to reconnect monitor for %s: %d\n"),
|
|
|
|
vm->def->name, rc);
|
|
|
|
goto next_error;
|
|
|
|
} else
|
|
|
|
vm->monitorpath = status->monitorpath;
|
|
|
|
|
|
|
|
if((vm->logfile = qemudLogFD(NULL, driver->logDir, vm->def->name)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (vm->def->id >= driver->nextvmid)
|
|
|
|
driver->nextvmid = vm->def->id + 1;
|
|
|
|
|
|
|
|
vm->state = status->state;
|
|
|
|
goto next;
|
|
|
|
|
|
|
|
next_error:
|
|
|
|
/* we failed to reconnect the vm so remove it's traces */
|
|
|
|
vm->def->id = -1;
|
|
|
|
qemudRemoveDomainStatus(NULL, driver, vm);
|
|
|
|
virDomainDefFree(vm->def);
|
|
|
|
vm->def = vm->newDef;
|
|
|
|
vm->newDef = NULL;
|
|
|
|
next:
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
VIR_FREE(status);
|
|
|
|
VIR_FREE(config);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* qemudStartup:
|
|
|
|
*
|
|
|
|
* Initialization function for the QEmu daemon
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudStartup(void) {
|
2007-06-26 22:13:21 +00:00
|
|
|
uid_t uid = geteuid();
|
|
|
|
struct passwd *pw;
|
|
|
|
char *base = NULL;
|
2007-10-12 16:05:44 +00:00
|
|
|
char driverConf[PATH_MAX];
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC(qemu_driver) < 0)
|
2007-06-26 22:13:21 +00:00
|
|
|
return -1;
|
|
|
|
|
2009-01-15 19:56:05 +00:00
|
|
|
if (virMutexInit(&qemu_driver->lock) < 0) {
|
|
|
|
qemudLog(QEMUD_ERROR, "%s", _("cannot initialize mutex"));
|
|
|
|
VIR_FREE(qemu_driver);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(qemu_driver);
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
/* Don't have a dom0 so start from 1 */
|
|
|
|
qemu_driver->nextvmid = 1;
|
|
|
|
|
2008-10-23 13:18:18 +00:00
|
|
|
/* Init callback list */
|
|
|
|
if(VIR_ALLOC(qemu_driver->domainEventCallbacks) < 0)
|
2008-12-04 21:06:41 +00:00
|
|
|
goto out_of_memory;
|
2008-12-04 21:09:20 +00:00
|
|
|
if (!(qemu_driver->domainEventQueue = virDomainEventQueueNew()))
|
|
|
|
goto out_of_memory;
|
|
|
|
|
|
|
|
if ((qemu_driver->domainEventTimer =
|
|
|
|
virEventAddTimeout(-1, qemuDomainEventFlush, qemu_driver, NULL)) < 0)
|
|
|
|
goto error;
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if (!uid) {
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&qemu_driver->logDir,
|
|
|
|
"%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1)
|
2008-07-11 19:34:11 +00:00
|
|
|
goto out_of_memory;
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2007-10-12 16:05:44 +00:00
|
|
|
if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL)
|
2007-06-26 22:13:21 +00:00
|
|
|
goto out_of_memory;
|
2008-12-18 15:22:49 +00:00
|
|
|
|
|
|
|
if (virAsprintf(&qemu_driver->stateDir,
|
|
|
|
"%s/run/libvirt/qemu/", LOCAL_STATE_DIR) == -1)
|
|
|
|
goto out_of_memory;
|
2007-06-26 22:13:21 +00:00
|
|
|
} else {
|
|
|
|
if (!(pw = getpwuid(uid))) {
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_ERR, _("Failed to find user record for uid '%d': %s\n"),
|
2007-06-26 22:13:21 +00:00
|
|
|
uid, strerror(errno));
|
2008-12-04 21:06:41 +00:00
|
|
|
goto error;
|
2007-06-26 22:13:21 +00:00
|
|
|
}
|
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&qemu_driver->logDir,
|
|
|
|
"%s/.libvirt/qemu/log", pw->pw_dir) == -1)
|
2008-07-11 19:34:11 +00:00
|
|
|
goto out_of_memory;
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1)
|
2007-06-26 22:13:21 +00:00
|
|
|
goto out_of_memory;
|
2008-12-18 15:22:49 +00:00
|
|
|
|
|
|
|
if (virAsprintf(&qemu_driver->stateDir, "%s/qemu/run", base) == -1)
|
|
|
|
goto out_of_memory;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virFileMakePath(qemu_driver->stateDir) < 0) {
|
|
|
|
qemudLog(QEMUD_ERR, _("Failed to create state dir '%s': %s\n"),
|
|
|
|
qemu_driver->stateDir, strerror(errno));
|
|
|
|
goto error;
|
2007-06-26 22:13:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Configuration paths are either ~/.libvirt/qemu/... (session) or
|
|
|
|
* /etc/libvirt/qemu/... (system).
|
|
|
|
*/
|
2007-10-12 16:05:44 +00:00
|
|
|
if (snprintf (driverConf, sizeof(driverConf), "%s/qemu.conf", base) == -1)
|
2007-06-26 22:13:21 +00:00
|
|
|
goto out_of_memory;
|
2007-10-12 16:05:44 +00:00
|
|
|
driverConf[sizeof(driverConf)-1] = '\0';
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&qemu_driver->configDir, "%s/qemu", base) == -1)
|
2007-06-26 22:13:21 +00:00
|
|
|
goto out_of_memory;
|
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) == -1)
|
2007-06-26 22:13:21 +00:00
|
|
|
goto out_of_memory;
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(base);
|
2008-02-27 04:35:08 +00:00
|
|
|
|
|
|
|
if ((qemu_driver->caps = qemudCapsInit()) == NULL)
|
|
|
|
goto out_of_memory;
|
2007-10-12 16:05:44 +00:00
|
|
|
|
|
|
|
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
|
2008-12-04 21:06:41 +00:00
|
|
|
goto error;
|
2007-10-12 16:05:44 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (virDomainLoadAllConfigs(NULL,
|
|
|
|
qemu_driver->caps,
|
|
|
|
&qemu_driver->domains,
|
|
|
|
qemu_driver->configDir,
|
2008-11-17 16:52:32 +00:00
|
|
|
qemu_driver->autostartDir,
|
2008-12-04 21:06:41 +00:00
|
|
|
NULL, NULL) < 0)
|
|
|
|
goto error;
|
2009-01-20 15:52:11 +00:00
|
|
|
qemudReconnectVMs(qemu_driver);
|
2007-06-26 22:13:21 +00:00
|
|
|
qemudAutostartConfigs(qemu_driver);
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(qemu_driver);
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
return 0;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
out_of_memory:
|
2008-02-22 16:26:13 +00:00
|
|
|
qemudLog (QEMUD_ERR,
|
2008-08-01 11:24:04 +00:00
|
|
|
"%s", _("qemudStartup: out of memory\n"));
|
2008-12-04 21:06:41 +00:00
|
|
|
error:
|
|
|
|
if (qemu_driver)
|
|
|
|
qemuDriverUnlock(qemu_driver);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(base);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemudShutdown();
|
2007-06-26 22:13:21 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-11-17 16:52:32 +00:00
|
|
|
static void qemudNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
|
|
|
|
{
|
|
|
|
struct qemud_driver *driver = opaque;
|
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
if (newVM) {
|
|
|
|
virDomainEventPtr event =
|
|
|
|
virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED,
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED_ADDED);
|
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
|
|
|
}
|
2008-11-17 16:52:32 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* qemudReload:
|
|
|
|
*
|
|
|
|
* Function to restart the QEmu daemon, it will recheck the configuration
|
|
|
|
* files and update its state and the networking
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudReload(void) {
|
2008-10-10 14:20:37 +00:00
|
|
|
if (!qemu_driver)
|
|
|
|
return 0;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(qemu_driver);
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainLoadAllConfigs(NULL,
|
|
|
|
qemu_driver->caps,
|
|
|
|
&qemu_driver->domains,
|
|
|
|
qemu_driver->configDir,
|
2008-11-17 16:52:32 +00:00
|
|
|
qemu_driver->autostartDir,
|
|
|
|
qemudNotifyLoadDomain, qemu_driver);
|
2008-07-11 19:34:11 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
qemudAutostartConfigs(qemu_driver);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(qemu_driver);
|
2007-06-26 22:56:14 +00:00
|
|
|
|
|
|
|
return 0;
|
2007-06-26 20:45:21 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* qemudActive:
|
|
|
|
*
|
|
|
|
* Checks if the QEmu daemon is active, i.e. has an active domain or
|
|
|
|
* an active network
|
|
|
|
*
|
|
|
|
* Returns 1 if active, 0 otherwise
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudActive(void) {
|
2008-10-10 14:20:37 +00:00
|
|
|
unsigned int i;
|
2008-12-04 21:06:41 +00:00
|
|
|
int active = 0;
|
2008-08-29 07:11:15 +00:00
|
|
|
|
2008-10-10 14:20:37 +00:00
|
|
|
if (!qemu_driver)
|
|
|
|
return 0;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(qemu_driver);
|
|
|
|
for (i = 0 ; i < qemu_driver->domains.count ; i++) {
|
|
|
|
virDomainObjPtr vm = qemu_driver->domains.objs[i];
|
|
|
|
virDomainObjLock(vm);
|
|
|
|
if (virDomainIsActive(vm))
|
|
|
|
active = 1;
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
}
|
2008-07-11 19:34:11 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(qemu_driver);
|
|
|
|
return active;
|
2007-06-26 22:56:14 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
|
|
|
* qemudShutdown:
|
|
|
|
*
|
|
|
|
* Shutdown the QEmu daemon, it will stop all active domains and networks
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudShutdown(void) {
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if (!qemu_driver)
|
2007-06-26 22:56:14 +00:00
|
|
|
return -1;
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(qemu_driver);
|
2008-02-27 04:35:08 +00:00
|
|
|
virCapabilitiesFree(qemu_driver->caps);
|
|
|
|
|
2008-10-10 14:20:37 +00:00
|
|
|
virDomainObjListFree(&qemu_driver->domains);
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
VIR_FREE(qemu_driver->logDir);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(qemu_driver->configDir);
|
|
|
|
VIR_FREE(qemu_driver->autostartDir);
|
2008-12-18 15:22:49 +00:00
|
|
|
VIR_FREE(qemu_driver->stateDir);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(qemu_driver->vncTLSx509certdir);
|
2008-11-05 14:24:21 +00:00
|
|
|
VIR_FREE(qemu_driver->vncListen);
|
2007-12-01 15:45:25 +00:00
|
|
|
|
2008-10-23 13:18:18 +00:00
|
|
|
/* Free domain callback list */
|
|
|
|
virDomainEventCallbackListFree(qemu_driver->domainEventCallbacks);
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventQueueFree(qemu_driver->domainEventQueue);
|
|
|
|
|
|
|
|
if (qemu_driver->domainEventTimer != -1)
|
|
|
|
virEventRemoveTimeout(qemu_driver->domainEventTimer);
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if (qemu_driver->brctl)
|
|
|
|
brShutdown(qemu_driver->brctl);
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(qemu_driver);
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexDestroy(&qemu_driver->lock);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(qemu_driver);
|
2007-06-26 22:56:14 +00:00
|
|
|
|
|
|
|
return 0;
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return -1 for error, 1 to continue reading and 0 for success */
|
2007-07-12 15:09:01 +00:00
|
|
|
typedef int qemudHandlerMonitorOutput(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
2007-06-26 20:41:25 +00:00
|
|
|
const char *output,
|
|
|
|
int fd);
|
|
|
|
|
|
|
|
static int
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReadMonitorOutput(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
2007-06-26 20:41:25 +00:00
|
|
|
int fd,
|
|
|
|
char *buf,
|
|
|
|
int buflen,
|
|
|
|
qemudHandlerMonitorOutput func,
|
2008-12-04 14:47:12 +00:00
|
|
|
const char *what,
|
|
|
|
int timeout)
|
2007-06-26 20:41:25 +00:00
|
|
|
{
|
|
|
|
int got = 0;
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
|
|
|
/* Consume & discard the initial greeting */
|
|
|
|
while (got < (buflen-1)) {
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = read(fd, buf+got, buflen-got-1);
|
2009-01-20 15:52:11 +00:00
|
|
|
|
2007-06-26 20:41:25 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
|
|
|
if (errno == EINTR)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (errno != EAGAIN) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno,
|
|
|
|
_("Failure while reading %s startup output"),
|
|
|
|
what);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-04 14:47:12 +00:00
|
|
|
ret = poll(&pfd, 1, timeout);
|
2007-06-26 20:41:25 +00:00
|
|
|
if (ret == 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("Timed out while reading %s startup output"), what);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
} else if (ret == -1) {
|
|
|
|
if (errno != EINTR) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno,
|
|
|
|
_("Failure while reading %s startup output"),
|
|
|
|
what);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Make sure we continue loop & read any further data
|
|
|
|
available before dealing with EOF */
|
|
|
|
if (pfd.revents & (POLLIN | POLLHUP))
|
|
|
|
continue;
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("Failure while reading %s startup output"), what);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
got += ret;
|
|
|
|
buf[got] = '\0';
|
2008-12-04 22:19:30 +00:00
|
|
|
if ((ret = func(conn, vm, buf, fd)) != 1)
|
2007-06-26 20:41:25 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("Out of space while reading %s startup output"), what);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
2007-06-26 20:41:25 +00:00
|
|
|
const char *output,
|
|
|
|
int fd)
|
|
|
|
{
|
|
|
|
if (strstr(output, "(qemu) ") == NULL)
|
|
|
|
return 1; /* keep reading */
|
|
|
|
|
|
|
|
vm->monitor = fd;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
static int qemudOpenMonitor(virConnectPtr conn,
|
2009-01-20 15:52:11 +00:00
|
|
|
struct qemud_driver* driver,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
2009-01-20 15:52:11 +00:00
|
|
|
const char *monitor,
|
|
|
|
int reconnect) {
|
2007-06-26 20:41:25 +00:00
|
|
|
int monfd;
|
|
|
|
char buf[1024];
|
|
|
|
int ret = -1;
|
|
|
|
|
2008-07-25 08:42:05 +00:00
|
|
|
if ((monfd = open(monitor, O_RDWR)) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("Unable to open monitor path %s"), monitor);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (qemudSetCloseExec(monfd) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("Unable to set monitor close-on-exec flag"));
|
2007-06-26 20:41:25 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (qemudSetNonBlock(monfd) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("Unable to put monitor into non-blocking mode"));
|
2007-06-26 20:41:25 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
if (!reconnect) {
|
|
|
|
ret = qemudReadMonitorOutput(conn,
|
|
|
|
vm, monfd,
|
|
|
|
buf, sizeof(buf),
|
|
|
|
qemudCheckMonitorPrompt,
|
|
|
|
"monitor", 10000);
|
|
|
|
} else {
|
|
|
|
vm->monitor = monfd;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret != 0)
|
|
|
|
goto error;
|
2007-07-23 18:00:33 +00:00
|
|
|
|
2008-12-20 13:17:49 +00:00
|
|
|
if (!(vm->monitorpath = strdup(monitor))) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("failed to allocate space for monitor path"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
if ((vm->monitor_watch = virEventAddHandle(vm->monitor, 0,
|
|
|
|
qemudDispatchVMEvent,
|
|
|
|
driver, NULL)) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
2007-07-23 18:00:33 +00:00
|
|
|
/* Keep monitor open upon success */
|
|
|
|
if (ret == 0)
|
|
|
|
return ret;
|
|
|
|
|
2007-06-26 20:41:25 +00:00
|
|
|
error:
|
|
|
|
close(monfd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
static int qemudExtractMonitorPath(virConnectPtr conn,
|
|
|
|
const char *haystack,
|
2008-04-25 20:46:13 +00:00
|
|
|
size_t *offset,
|
2008-07-11 19:34:11 +00:00
|
|
|
char **path) {
|
2007-06-26 20:41:25 +00:00
|
|
|
static const char needle[] = "char device redirected to";
|
2008-07-11 19:34:11 +00:00
|
|
|
char *tmp, *dev;
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
VIR_FREE(*path);
|
2008-04-25 20:46:13 +00:00
|
|
|
/* First look for our magic string */
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!(tmp = strstr(haystack + *offset, needle))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
tmp += sizeof(needle);
|
|
|
|
dev = tmp;
|
2008-07-11 09:48:51 +00:00
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
/*
|
|
|
|
* And look for first whitespace character and nul terminate
|
|
|
|
* to mark end of the pty path
|
|
|
|
*/
|
|
|
|
while (*tmp) {
|
2008-05-09 13:50:14 +00:00
|
|
|
if (c_isspace(*tmp)) {
|
2008-07-11 19:34:11 +00:00
|
|
|
if (VIR_ALLOC_N(*path, (tmp-dev)+1) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL,
|
|
|
|
VIR_ERR_NO_MEMORY, NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
strncpy(*path, dev, (tmp-dev));
|
|
|
|
(*path)[(tmp-dev)] = '\0';
|
2008-07-11 09:48:51 +00:00
|
|
|
/* ... now further update offset till we get EOL */
|
2008-10-02 14:10:20 +00:00
|
|
|
*offset = tmp - haystack;
|
2007-06-26 20:41:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-04-25 20:46:13 +00:00
|
|
|
tmp++;
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We found a path, but didn't find any whitespace,
|
|
|
|
* so it must be still incomplete - we should at
|
2008-04-25 20:46:13 +00:00
|
|
|
* least see a \n - indicate that we want to carry
|
|
|
|
* on trying again
|
2007-06-26 20:41:25 +00:00
|
|
|
*/
|
2008-07-11 19:34:11 +00:00
|
|
|
return 1;
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-04-25 20:46:13 +00:00
|
|
|
qemudFindCharDevicePTYs(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
2008-04-25 20:46:13 +00:00
|
|
|
const char *output,
|
|
|
|
int fd ATTRIBUTE_UNUSED)
|
2007-06-26 20:41:25 +00:00
|
|
|
{
|
2009-01-20 15:52:11 +00:00
|
|
|
struct qemud_driver* driver = conn->privateData;
|
2008-07-11 19:34:11 +00:00
|
|
|
char *monitor = NULL;
|
2008-04-25 20:46:13 +00:00
|
|
|
size_t offset = 0;
|
2008-10-10 16:08:01 +00:00
|
|
|
int ret, i;
|
2008-04-25 20:46:13 +00:00
|
|
|
|
|
|
|
/* The order in which QEMU prints out the PTY paths is
|
|
|
|
the order in which it procsses its monitor, serial
|
|
|
|
and parallel device args. This code must match that
|
|
|
|
ordering.... */
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
/* So first comes the monitor device */
|
2008-07-11 19:34:11 +00:00
|
|
|
if ((ret = qemudExtractMonitorPath(conn, output, &offset, &monitor)) != 0)
|
|
|
|
goto cleanup;
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
/* then the serial devices */
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < vm->def->nserials ; i++) {
|
|
|
|
virDomainChrDefPtr chr = vm->def->serials[i];
|
2008-07-11 19:34:11 +00:00
|
|
|
if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
|
|
|
|
if ((ret = qemudExtractMonitorPath(conn, output, &offset,
|
|
|
|
&chr->data.file.path)) != 0)
|
|
|
|
goto cleanup;
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* and finally the parallel devices */
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < vm->def->nparallels ; i++) {
|
|
|
|
virDomainChrDefPtr chr = vm->def->parallels[i];
|
2008-07-11 19:34:11 +00:00
|
|
|
if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
|
|
|
|
if ((ret = qemudExtractMonitorPath(conn, output, &offset,
|
|
|
|
&chr->data.file.path)) != 0)
|
|
|
|
goto cleanup;
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Got them all, so now open the monitor console */
|
2009-01-20 15:52:11 +00:00
|
|
|
ret = qemudOpenMonitor(conn, driver, vm, monitor, 0);
|
2008-07-11 19:34:11 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(monitor);
|
|
|
|
return ret;
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
static int qemudWaitForMonitor(virConnectPtr conn,
|
2009-01-20 15:52:11 +00:00
|
|
|
struct qemud_driver* driver,
|
|
|
|
virDomainObjPtr vm, off_t pos)
|
|
|
|
{
|
2007-06-26 20:41:25 +00:00
|
|
|
char buf[1024]; /* Plenty of space to get startup greeting */
|
2009-01-20 15:52:11 +00:00
|
|
|
int logfd;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if ((logfd = qemudLogReadFD(conn, driver->logDir, vm->def->name, pos))
|
|
|
|
< 0)
|
|
|
|
return logfd;
|
|
|
|
|
|
|
|
ret = qemudReadMonitorOutput(conn, vm, logfd, buf, sizeof(buf),
|
|
|
|
qemudFindCharDevicePTYs,
|
|
|
|
"console", 3000);
|
|
|
|
if (close(logfd) < 0)
|
|
|
|
qemudLog(QEMUD_WARN, _("Unable to close logfile: %s\n"),
|
2007-06-26 20:41:25 +00:00
|
|
|
strerror(errno));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-22 16:20:31 +00:00
|
|
|
static int
|
|
|
|
qemudDetectVcpuPIDs(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm) {
|
2008-05-22 16:20:31 +00:00
|
|
|
char *qemucpus = NULL;
|
|
|
|
char *line;
|
|
|
|
int lastVcpu = -1;
|
|
|
|
|
|
|
|
/* Only KVM has seperate threads for CPUs,
|
|
|
|
others just use main QEMU process for CPU */
|
2008-07-11 19:34:11 +00:00
|
|
|
if (vm->def->virtType != VIR_DOMAIN_VIRT_KVM)
|
2008-05-22 16:20:31 +00:00
|
|
|
vm->nvcpupids = 1;
|
|
|
|
else
|
|
|
|
vm->nvcpupids = vm->def->vcpus;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(vm->vcpupids, vm->nvcpupids) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("allocate cpumap"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (vm->def->virtType != VIR_DOMAIN_VIRT_KVM) {
|
2008-05-22 16:20:31 +00:00
|
|
|
vm->vcpupids[0] = vm->pid;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, "info cpus", &qemucpus) < 0) {
|
2008-05-22 16:20:31 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cannot run monitor command to fetch CPU thread info"));
|
|
|
|
VIR_FREE(vm->vcpupids);
|
|
|
|
vm->nvcpupids = 0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is the gross format we're about to parse :-{
|
|
|
|
*
|
|
|
|
* (qemu) info cpus
|
|
|
|
* * CPU #0: pc=0x00000000000f0c4a thread_id=30019
|
|
|
|
* CPU #1: pc=0x00000000fffffff0 thread_id=30020
|
|
|
|
* CPU #2: pc=0x00000000fffffff0 thread_id=30021
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
line = qemucpus;
|
|
|
|
do {
|
|
|
|
char *offset = strchr(line, '#');
|
|
|
|
char *end = NULL;
|
|
|
|
int vcpu = 0, tid = 0;
|
|
|
|
|
|
|
|
/* See if we're all done */
|
|
|
|
if (offset == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Extract VCPU number */
|
|
|
|
if (virStrToLong_i(offset + 1, &end, 10, &vcpu) < 0)
|
|
|
|
goto error;
|
|
|
|
if (end == NULL || *end != ':')
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* Extract host Thread ID */
|
|
|
|
if ((offset = strstr(line, "thread_id=")) == NULL)
|
|
|
|
goto error;
|
|
|
|
if (virStrToLong_i(offset + strlen("thread_id="), &end, 10, &tid) < 0)
|
|
|
|
goto error;
|
|
|
|
if (end == NULL || !c_isspace(*end))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* Validate the VCPU is in expected range & order */
|
|
|
|
if (vcpu > vm->nvcpupids ||
|
|
|
|
vcpu != (lastVcpu + 1))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
lastVcpu = vcpu;
|
|
|
|
vm->vcpupids[vcpu] = tid;
|
|
|
|
|
|
|
|
/* Skip to next data line */
|
|
|
|
line = strchr(offset, '\r');
|
|
|
|
if (line == NULL)
|
|
|
|
line = strchr(offset, '\n');
|
|
|
|
} while (line != NULL);
|
|
|
|
|
|
|
|
/* Validate we got data for all VCPUs we expected */
|
|
|
|
if (lastVcpu != (vm->def->vcpus - 1))
|
|
|
|
goto error;
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(qemucpus);
|
2008-05-22 16:20:31 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
VIR_FREE(vm->vcpupids);
|
2008-05-29 19:20:22 +00:00
|
|
|
vm->nvcpupids = 0;
|
|
|
|
VIR_FREE(qemucpus);
|
2008-05-22 16:20:31 +00:00
|
|
|
|
|
|
|
/* Explicitly return success, not error. Older KVM does
|
|
|
|
not have vCPU -> Thread mapping info and we don't
|
|
|
|
want to break its use. This merely disables ability
|
|
|
|
to pin vCPUS with libvirt */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-05-22 16:27:20 +00:00
|
|
|
static int
|
|
|
|
qemudInitCpus(virConnectPtr conn,
|
2008-11-14 08:42:47 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
const char *migrateFrom) {
|
2008-05-22 16:27:20 +00:00
|
|
|
char *info = NULL;
|
|
|
|
#if HAVE_SCHED_GETAFFINITY
|
|
|
|
cpu_set_t mask;
|
|
|
|
int i, maxcpu = QEMUD_CPUMASK_LEN;
|
|
|
|
virNodeInfo nodeinfo;
|
|
|
|
|
|
|
|
if (virNodeInfoPopulate(conn, &nodeinfo) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* setaffinity fails if you set bits for CPUs which
|
|
|
|
* aren't present, so we have to limit ourselves */
|
|
|
|
if (maxcpu > nodeinfo.cpus)
|
|
|
|
maxcpu = nodeinfo.cpus;
|
|
|
|
|
|
|
|
CPU_ZERO(&mask);
|
2008-07-25 09:31:24 +00:00
|
|
|
if (vm->def->cpumask) {
|
|
|
|
for (i = 0 ; i < maxcpu ; i++)
|
|
|
|
if (vm->def->cpumask[i])
|
|
|
|
CPU_SET(i, &mask);
|
|
|
|
} else {
|
|
|
|
for (i = 0 ; i < maxcpu ; i++)
|
2008-05-22 16:27:20 +00:00
|
|
|
CPU_SET(i, &mask);
|
2008-07-25 09:31:24 +00:00
|
|
|
}
|
2008-05-22 16:27:20 +00:00
|
|
|
|
|
|
|
for (i = 0 ; i < vm->nvcpupids ; i++) {
|
|
|
|
if (sched_setaffinity(vm->vcpupids[i],
|
|
|
|
sizeof(mask), &mask) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno, "%s",
|
|
|
|
_("failed to set CPU affinity"));
|
2008-05-22 16:27:20 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* HAVE_SCHED_GETAFFINITY */
|
|
|
|
|
2008-11-14 08:42:47 +00:00
|
|
|
if (migrateFrom == NULL) {
|
|
|
|
/* Allow the CPUS to start executing */
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, "cont", &info) < 0) {
|
2008-11-14 08:42:47 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("resume operation failed"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
VIR_FREE(info);
|
2008-05-22 16:27:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) {
|
2007-06-26 20:41:25 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 5900 ; i < 6000 ; i++) {
|
|
|
|
int fd;
|
|
|
|
int reuse = 1;
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
addr.sin_port = htons(i);
|
|
|
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
if (fd < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
|
|
|
|
close(fd);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
|
|
|
/* Not in use, lets grab it */
|
|
|
|
close(fd);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
if (errno == EADDRINUSE) {
|
|
|
|
/* In use, try next */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Some other bad failure, get out.. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-10-23 13:18:18 +00:00
|
|
|
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
|
|
|
|
const char *name);
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
static int qemudStartVMDaemon(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
const char *migrateFrom) {
|
2008-08-08 15:43:38 +00:00
|
|
|
const char **argv = NULL, **tmp;
|
2008-10-10 16:52:20 +00:00
|
|
|
const char **progenv = NULL;
|
2008-04-08 12:27:53 +00:00
|
|
|
int i, ret;
|
2008-05-16 16:51:30 +00:00
|
|
|
struct stat sb;
|
2008-07-11 19:34:11 +00:00
|
|
|
int *tapfds = NULL;
|
|
|
|
int ntapfds = 0;
|
2008-08-29 07:11:15 +00:00
|
|
|
unsigned int qemuCmdFlags;
|
2008-08-27 11:42:52 +00:00
|
|
|
fd_set keepfd;
|
2008-09-05 11:52:12 +00:00
|
|
|
const char *emulator;
|
2009-01-19 21:55:54 +00:00
|
|
|
pid_t child;
|
2009-01-20 15:52:11 +00:00
|
|
|
int pos = -1;
|
2008-08-27 11:42:52 +00:00
|
|
|
|
|
|
|
FD_ZERO(&keepfd);
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (virDomainIsActive(vm)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("VM is already active"));
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (vm->def->graphics &&
|
|
|
|
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
|
|
|
vm->def->graphics->data.vnc.autoport) {
|
2007-06-26 22:13:21 +00:00
|
|
|
int port = qemudNextFreeVNCPort(driver);
|
2007-06-26 20:41:25 +00:00
|
|
|
if (port < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("Unable to find an unused VNC port"));
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-07-11 19:34:11 +00:00
|
|
|
vm->def->graphics->data.vnc.port = port;
|
|
|
|
}
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if (virFileMakePath(driver->logDir) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno,
|
|
|
|
_("cannot create log directory %s"),
|
|
|
|
driver->logDir);
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-01-11 11:18:31 +00:00
|
|
|
if((vm->logfile = qemudLogFD(conn, driver->logDir, vm->def->name)) < 0)
|
2007-06-26 20:41:25 +00:00
|
|
|
return -1;
|
|
|
|
|
2008-09-05 11:52:12 +00:00
|
|
|
emulator = vm->def->emulator;
|
|
|
|
if (!emulator)
|
|
|
|
emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
|
|
|
|
if (!emulator)
|
|
|
|
return -1;
|
|
|
|
|
2008-05-16 16:51:30 +00:00
|
|
|
/* Make sure the binary we are about to try exec'ing exists.
|
|
|
|
* Technically we could catch the exec() failure, but that's
|
|
|
|
* in a sub-process so its hard to feed back a useful error
|
|
|
|
*/
|
2008-09-05 11:52:12 +00:00
|
|
|
if (stat(emulator, &sb) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(conn, errno,
|
|
|
|
_("Cannot find QEMU binary %s"),
|
|
|
|
emulator);
|
2008-05-16 16:51:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-09-05 11:52:12 +00:00
|
|
|
if (qemudExtractVersionInfo(emulator,
|
2008-07-11 19:34:11 +00:00
|
|
|
NULL,
|
|
|
|
&qemuCmdFlags) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot determine QEMU argv syntax %s"),
|
2008-09-05 11:52:12 +00:00
|
|
|
emulator);
|
2008-07-11 19:34:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-05-16 16:51:30 +00:00
|
|
|
|
2008-11-04 22:15:30 +00:00
|
|
|
vm->def->id = driver->nextvmid++;
|
2008-07-11 19:34:11 +00:00
|
|
|
if (qemudBuildCommandLine(conn, driver, vm,
|
2008-10-10 16:52:20 +00:00
|
|
|
qemuCmdFlags, &argv, &progenv,
|
2008-07-11 19:34:11 +00:00
|
|
|
&tapfds, &ntapfds, migrateFrom) < 0) {
|
2007-06-26 20:41:25 +00:00
|
|
|
close(vm->logfile);
|
2008-11-04 22:15:30 +00:00
|
|
|
vm->def->id = -1;
|
2007-06-26 20:41:25 +00:00
|
|
|
vm->logfile = -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-10-10 16:52:20 +00:00
|
|
|
tmp = progenv;
|
|
|
|
while (*tmp) {
|
|
|
|
if (safewrite(vm->logfile, *tmp, strlen(*tmp)) < 0)
|
|
|
|
qemudLog(QEMUD_WARN, _("Unable to write envv to logfile %d: %s\n"),
|
|
|
|
errno, strerror(errno));
|
|
|
|
if (safewrite(vm->logfile, " ", 1) < 0)
|
|
|
|
qemudLog(QEMUD_WARN, _("Unable to write envv to logfile %d: %s\n"),
|
|
|
|
errno, strerror(errno));
|
|
|
|
tmp++;
|
|
|
|
}
|
2007-06-26 20:41:25 +00:00
|
|
|
tmp = argv;
|
|
|
|
while (*tmp) {
|
Use safewrite in place of write, in many cases.
Also add "make syntax-check" rules to ensure no new uses sneak in.
There are many uses of write like this:
if (write (fd, xml, towrite) != towrite)
return -1;
The problem is that the syscall can succeed, yet write less than
the requested number of bytes, so the caller should retry
rather than simply failing.
This patch changes most of them to use util.c's safewrite wrapper,
which encapsulates the process. Also, there were a few cases in
which the retry loop was open-coded, and I replaced those, too.
* Makefile.maint (sc_avoid_write): New rule, to avoid recurrence.
* .x-sc_avoid_write: New file. Record two legitimate exemptions.
* qemud/qemud.c (sig_handler, qemudClientWriteBuf): Use safewrite, not write.
* src/conf.c (__virConfWriteFile): Likewise.
* src/qemu_conf.c (qemudSaveConfig, qemudSaveNetworkConfig): Likewise.
* src/qemu_driver.c (qemudWaitForMonitor, qemudStartVMDaemon)
(qemudVMData, PROC_IP_FORWARD): Likewise.
* proxy/libvirt_proxy.c: Include "util.h".
(proxyWriteClientSocket): Use safewrite.
* src/test.c (testDomainSave, testDomainCoreDump): Likewise.
* src/proxy_internal.c (virProxyWriteClientSocket): Likewise.
* src/virsh.c: Include "util-lib.h".
(vshOutputLogFile): Use safewrite.
* src/console.c: Include "util-lib.h".
(vshRunConsole): Use safewrite.
2008-02-22 15:55:04 +00:00
|
|
|
if (safewrite(vm->logfile, *tmp, strlen(*tmp)) < 0)
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
|
2007-06-26 20:41:25 +00:00
|
|
|
errno, strerror(errno));
|
Use safewrite in place of write, in many cases.
Also add "make syntax-check" rules to ensure no new uses sneak in.
There are many uses of write like this:
if (write (fd, xml, towrite) != towrite)
return -1;
The problem is that the syscall can succeed, yet write less than
the requested number of bytes, so the caller should retry
rather than simply failing.
This patch changes most of them to use util.c's safewrite wrapper,
which encapsulates the process. Also, there were a few cases in
which the retry loop was open-coded, and I replaced those, too.
* Makefile.maint (sc_avoid_write): New rule, to avoid recurrence.
* .x-sc_avoid_write: New file. Record two legitimate exemptions.
* qemud/qemud.c (sig_handler, qemudClientWriteBuf): Use safewrite, not write.
* src/conf.c (__virConfWriteFile): Likewise.
* src/qemu_conf.c (qemudSaveConfig, qemudSaveNetworkConfig): Likewise.
* src/qemu_driver.c (qemudWaitForMonitor, qemudStartVMDaemon)
(qemudVMData, PROC_IP_FORWARD): Likewise.
* proxy/libvirt_proxy.c: Include "util.h".
(proxyWriteClientSocket): Use safewrite.
* src/test.c (testDomainSave, testDomainCoreDump): Likewise.
* src/proxy_internal.c (virProxyWriteClientSocket): Likewise.
* src/virsh.c: Include "util-lib.h".
(vshOutputLogFile): Use safewrite.
* src/console.c: Include "util-lib.h".
(vshRunConsole): Use safewrite.
2008-02-22 15:55:04 +00:00
|
|
|
if (safewrite(vm->logfile, " ", 1) < 0)
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
|
2007-06-26 20:41:25 +00:00
|
|
|
errno, strerror(errno));
|
|
|
|
tmp++;
|
|
|
|
}
|
Use safewrite in place of write, in many cases.
Also add "make syntax-check" rules to ensure no new uses sneak in.
There are many uses of write like this:
if (write (fd, xml, towrite) != towrite)
return -1;
The problem is that the syscall can succeed, yet write less than
the requested number of bytes, so the caller should retry
rather than simply failing.
This patch changes most of them to use util.c's safewrite wrapper,
which encapsulates the process. Also, there were a few cases in
which the retry loop was open-coded, and I replaced those, too.
* Makefile.maint (sc_avoid_write): New rule, to avoid recurrence.
* .x-sc_avoid_write: New file. Record two legitimate exemptions.
* qemud/qemud.c (sig_handler, qemudClientWriteBuf): Use safewrite, not write.
* src/conf.c (__virConfWriteFile): Likewise.
* src/qemu_conf.c (qemudSaveConfig, qemudSaveNetworkConfig): Likewise.
* src/qemu_driver.c (qemudWaitForMonitor, qemudStartVMDaemon)
(qemudVMData, PROC_IP_FORWARD): Likewise.
* proxy/libvirt_proxy.c: Include "util.h".
(proxyWriteClientSocket): Use safewrite.
* src/test.c (testDomainSave, testDomainCoreDump): Likewise.
* src/proxy_internal.c (virProxyWriteClientSocket): Likewise.
* src/virsh.c: Include "util-lib.h".
(vshOutputLogFile): Use safewrite.
* src/console.c: Include "util-lib.h".
(vshRunConsole): Use safewrite.
2008-02-22 15:55:04 +00:00
|
|
|
if (safewrite(vm->logfile, "\n", 1) < 0)
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
|
2007-06-26 20:41:25 +00:00
|
|
|
errno, strerror(errno));
|
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
if ((pos = lseek(vm->logfile, 0, SEEK_END)) < 0)
|
|
|
|
qemudLog(QEMUD_WARN, _("Unable to seek to end of logfile %d: %s\n"),
|
|
|
|
errno, strerror(errno));
|
2008-08-20 09:08:17 +00:00
|
|
|
|
2008-08-27 11:42:52 +00:00
|
|
|
for (i = 0 ; i < ntapfds ; i++)
|
|
|
|
FD_SET(tapfds[i], &keepfd);
|
|
|
|
|
2009-01-19 21:55:54 +00:00
|
|
|
ret = virExec(conn, argv, progenv, &keepfd, &child,
|
2009-01-20 15:52:11 +00:00
|
|
|
vm->stdin_fd, &vm->logfile, &vm->logfile,
|
2009-01-19 21:55:54 +00:00
|
|
|
VIR_EXEC_NONBLOCK | VIR_EXEC_DAEMON);
|
|
|
|
|
|
|
|
/* wait for qemu process to to show up */
|
|
|
|
if (ret == 0) {
|
|
|
|
int retries = 100;
|
|
|
|
while (retries) {
|
|
|
|
if ((ret = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) == 0)
|
|
|
|
break;
|
|
|
|
usleep(100*1000);
|
|
|
|
retries--;
|
|
|
|
}
|
|
|
|
if (ret)
|
|
|
|
qemudLog(QEMUD_WARN, _("Domain %s didn't show up\n"), vm->def->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == 0) {
|
2008-07-11 19:34:11 +00:00
|
|
|
vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
|
2009-01-19 21:55:54 +00:00
|
|
|
} else
|
2008-11-04 22:15:30 +00:00
|
|
|
vm->def->id = -1;
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2007-06-26 20:45:21 +00:00
|
|
|
for (i = 0 ; argv[i] ; i++)
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(argv[i]);
|
|
|
|
VIR_FREE(argv);
|
2007-06-26 20:45:21 +00:00
|
|
|
|
2008-10-10 16:52:20 +00:00
|
|
|
for (i = 0 ; progenv[i] ; i++)
|
|
|
|
VIR_FREE(progenv[i]);
|
|
|
|
VIR_FREE(progenv);
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (tapfds) {
|
|
|
|
for (i = 0 ; i < ntapfds ; i++) {
|
|
|
|
close(tapfds[i]);
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
2008-07-11 19:34:11 +00:00
|
|
|
VIR_FREE(tapfds);
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
2008-04-08 12:27:53 +00:00
|
|
|
if (ret == 0) {
|
2009-01-20 15:52:11 +00:00
|
|
|
if ((qemudWaitForMonitor(conn, driver, vm, pos) < 0) ||
|
2008-12-04 22:19:30 +00:00
|
|
|
(qemudDetectVcpuPIDs(conn, vm) < 0) ||
|
|
|
|
(qemudInitCpus(conn, vm, migrateFrom) < 0)) {
|
2008-05-22 16:20:31 +00:00
|
|
|
qemudShutdownVMDaemon(conn, driver, vm);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-06-26 20:45:21 +00:00
|
|
|
}
|
2008-12-20 13:17:49 +00:00
|
|
|
qemudSaveDomainStatus(conn, qemu_driver, vm);
|
2007-06-26 20:45:21 +00:00
|
|
|
|
2008-04-08 12:27:53 +00:00
|
|
|
return ret;
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-24 14:24:52 +00:00
|
|
|
static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
2008-07-11 19:34:11 +00:00
|
|
|
struct qemud_driver *driver, virDomainObjPtr vm) {
|
|
|
|
if (!virDomainIsActive(vm))
|
2007-07-24 14:24:52 +00:00
|
|
|
return;
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_INFO, _("Shutting down VM '%s'\n"), vm->def->name);
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2009-01-19 21:55:54 +00:00
|
|
|
if (virKillProcess(vm->pid, 0) == 0 &&
|
|
|
|
virKillProcess(vm->pid, SIGTERM) < 0)
|
|
|
|
qemudLog(QEMUD_ERROR, _("Failed to send SIGTERM to %s (%d): %s\n"),
|
|
|
|
vm->def->name, vm->pid, strerror(errno));
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
virEventRemoveHandle(vm->monitor_watch);
|
2007-06-26 20:41:25 +00:00
|
|
|
|
|
|
|
if (close(vm->logfile) < 0)
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to close logfile %d: %s\n"),
|
Mark all qemudLog diagnostics for translation.
* po/POTFILES.in: Add names of many new files.
* Makefile.maint (err_func_re): Add qemudLog.
Mark diagnostics with _(...). Split some long lines.
* qemud/qemud.c (remoteCheckCertFile, remoteInitializeGnuTLS):
(qemudDispatchSignalEvent, qemudSetCloseExec, qemudSetNonBlock):
(qemudWritePidFile, qemudListenUnix, remoteMakeSockets):
(remoteListenTCP, qemudInitPaths, qemudInitialize):
(qemudNetworkInit, remoteInitializeTLSSession, remoteCheckDN):
(remoteCheckCertificate, remoteCheckAccess, qemudDispatchServer):
(qemudClientReadBuf, qemudDispatchClientRead):
(qemudClientWriteBuf, qemudDispatchClientWrite, qemudOneLoop):
(remoteConfigGetStringList, checkType, GET_CONF_STR):
(remoteConfigGetAuth, remoteReadConfigFile, main):
* qemud/remote.c (remoteDispatchAuthSaslInit, remoteSASLCheckSSF):
(remoteSASLCheckAccess, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchAuthSaslInit):
(remoteDispatchAuthSaslStart, remoteDispatchAuthSaslStep):
(qemudGetSocketIdentity, remoteDispatchAuthPolkit):
* src/iptables.c (notifyRulesUpdated, MAX_FILE_LEN, iptRulesSave):
(iptRulesReload):
* src/qemu_conf.c (qemudExtractVersionInfo, qemudLoadConfig):
(qemudLoadNetworkConfig, qemudScanConfigDir):
* src/qemu_driver.c (qemudSetCloseExec, qemudSetNonBlock):
(qemudAutostartConfigs, qemudStartup, qemudReload):
(qemudWaitForMonitor, qemudStartVMDaemon, qemudVMData):
(qemudShutdownVMDaemon, qemudStartNetworkDaemon):
(qemudShutdownNetworkDaemon, qemudMonitorCommand):
(qemudDomainUndefine, qemudNetworkUndefine):
* src/uuid.c (virUUIDGenerate):
* src/xm_internal.c (xenXMAttachInterface):
2008-02-07 16:50:17 +00:00
|
|
|
errno, strerror(errno));
|
2007-06-26 20:41:25 +00:00
|
|
|
if (vm->monitor != -1)
|
|
|
|
close(vm->monitor);
|
|
|
|
vm->logfile = -1;
|
|
|
|
vm->monitor = -1;
|
|
|
|
|
2009-01-19 21:55:54 +00:00
|
|
|
/* shut it off for sure */
|
|
|
|
virKillProcess(vm->pid, SIGKILL);
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2009-01-19 21:55:54 +00:00
|
|
|
qemudRemoveDomainStatus(conn, driver, vm);
|
2007-06-26 20:41:25 +00:00
|
|
|
vm->pid = -1;
|
2008-07-11 19:34:11 +00:00
|
|
|
vm->def->id = -1;
|
2007-06-26 22:39:53 +00:00
|
|
|
vm->state = VIR_DOMAIN_SHUTOFF;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(vm->vcpupids);
|
2008-05-22 16:20:31 +00:00
|
|
|
vm->nvcpupids = 0;
|
2007-06-26 20:41:25 +00:00
|
|
|
|
|
|
|
if (vm->newDef) {
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainDefFree(vm->def);
|
2007-06-26 20:41:25 +00:00
|
|
|
vm->def = vm->newDef;
|
2008-07-11 19:34:11 +00:00
|
|
|
vm->def->id = -1;
|
2007-06-26 20:41:25 +00:00
|
|
|
vm->newDef = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-23 13:18:18 +00:00
|
|
|
static void
|
2008-11-19 16:19:36 +00:00
|
|
|
qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = opaque;
|
2008-10-10 14:20:37 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-10-10 14:20:37 +00:00
|
|
|
unsigned int i;
|
2008-12-04 21:06:41 +00:00
|
|
|
int quit = 0, failed = 0;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
for (i = 0 ; i < driver->domains.count ; i++) {
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjPtr tmpvm = driver->domains.objs[i];
|
|
|
|
virDomainObjLock(tmpvm);
|
|
|
|
if (virDomainIsActive(tmpvm) &&
|
2009-01-20 15:52:11 +00:00
|
|
|
tmpvm->monitor_watch == watch) {
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = tmpvm;
|
2007-06-26 20:41:25 +00:00
|
|
|
break;
|
2008-10-10 14:20:37 +00:00
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjUnlock(tmpvm);
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!vm)
|
2008-12-04 21:06:41 +00:00
|
|
|
goto cleanup;
|
2007-06-26 20:41:25 +00:00
|
|
|
|
2009-01-20 15:52:11 +00:00
|
|
|
if (vm->monitor != fd) {
|
2008-12-04 21:06:41 +00:00
|
|
|
failed = 1;
|
|
|
|
} else {
|
2009-01-20 15:52:11 +00:00
|
|
|
if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
|
2008-12-04 21:06:41 +00:00
|
|
|
quit = 1;
|
2009-01-20 15:52:11 +00:00
|
|
|
else {
|
|
|
|
qemudLog(QEMUD_ERROR, _("unhandled fd event %d for %s"),
|
|
|
|
events, vm->def->name);
|
|
|
|
failed = 1;
|
2008-12-04 21:06:41 +00:00
|
|
|
}
|
2008-11-19 16:19:36 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
if (failed || quit) {
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
quit ?
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN :
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_FAILED);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemudShutdownVMDaemon(NULL, driver, vm);
|
|
|
|
if (!vm->persistent) {
|
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
|
|
|
vm = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
2008-02-26 18:41:43 +00:00
|
|
|
static int
|
2008-12-04 22:19:30 +00:00
|
|
|
qemudMonitorCommand (const virDomainObjPtr vm,
|
2008-02-26 18:41:43 +00:00
|
|
|
const char *cmd,
|
|
|
|
char **reply) {
|
2007-02-14 01:40:09 +00:00
|
|
|
int size = 0;
|
|
|
|
char *buf = NULL;
|
2007-10-27 01:16:53 +00:00
|
|
|
size_t cmdlen = strlen(cmd);
|
2007-03-05 17:15:20 +00:00
|
|
|
|
2007-10-27 01:16:53 +00:00
|
|
|
if (safewrite(vm->monitor, cmd, cmdlen) != cmdlen)
|
|
|
|
return -1;
|
|
|
|
if (safewrite(vm->monitor, "\r", 1) != 1)
|
2007-02-14 01:40:09 +00:00
|
|
|
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));
|
2007-03-05 17:15:20 +00:00
|
|
|
|
2007-10-27 01:16:53 +00:00
|
|
|
if (got == 0)
|
|
|
|
goto error;
|
2007-02-14 01:40:09 +00:00
|
|
|
if (got < 0) {
|
|
|
|
if (errno == EINTR)
|
|
|
|
continue;
|
|
|
|
if (errno == EAGAIN)
|
|
|
|
break;
|
2007-10-27 01:16:53 +00:00
|
|
|
goto error;
|
2007-06-22 10:14:48 +00:00
|
|
|
}
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_REALLOC_N(buf, size+got+1) < 0)
|
2007-10-27 01:16:53 +00:00
|
|
|
goto error;
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
memmove(buf+size, data, got);
|
|
|
|
buf[size+got] = '\0';
|
|
|
|
size += got;
|
|
|
|
}
|
2007-10-27 01:16:53 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/* Look for QEMU prompt to indicate completion */
|
2007-03-05 17:15:20 +00:00
|
|
|
if (buf && ((tmp = strstr(buf, "\n(qemu) ")) != NULL)) {
|
2008-12-16 22:34:13 +00:00
|
|
|
char *commptr = NULL, *nlptr = NULL;
|
|
|
|
|
|
|
|
/* Preserve the newline */
|
|
|
|
tmp[1] = '\0';
|
|
|
|
|
|
|
|
/* The monitor doesn't dump clean output after we have written to
|
|
|
|
* it. Every character we write dumps a bunch of useless stuff,
|
|
|
|
* so the result looks like "cXcoXcomXcommXcommaXcommanXcommand"
|
|
|
|
* Try to throw away everything before the first full command
|
|
|
|
* occurence, and inbetween the command and the newline starting
|
|
|
|
* the response
|
|
|
|
*/
|
|
|
|
if ((commptr = strstr(buf, cmd)))
|
|
|
|
memmove(buf, commptr, strlen(commptr)+1);
|
|
|
|
if ((nlptr = strchr(buf, '\n')))
|
|
|
|
memmove(buf+strlen(cmd), nlptr, strlen(nlptr)+1);
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
pollagain:
|
|
|
|
/* Need to wait for more data */
|
|
|
|
if (poll(&fd, 1, -1) < 0) {
|
|
|
|
if (errno == EINTR)
|
|
|
|
goto pollagain;
|
2007-10-27 01:16:53 +00:00
|
|
|
goto error;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-27 01:16:53 +00:00
|
|
|
/* Log, but ignore failures to write logfile for VM */
|
|
|
|
if (safewrite(vm->logfile, buf, strlen(buf)) < 0)
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to log VM console data: %s\n"),
|
2007-10-27 01:16:53 +00:00
|
|
|
strerror(errno));
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
*reply = buf;
|
|
|
|
return 0;
|
2007-10-27 01:16:53 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (buf) {
|
|
|
|
/* Log, but ignore failures to write logfile for VM */
|
|
|
|
if (safewrite(vm->logfile, buf, strlen(buf)) < 0)
|
2008-08-01 11:24:04 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to log VM console data: %s\n"),
|
2007-10-27 01:16:53 +00:00
|
|
|
strerror(errno));
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(buf);
|
2007-10-27 01:16:53 +00:00
|
|
|
}
|
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-02-26 07:05:18 +00:00
|
|
|
/**
|
|
|
|
* qemudProbe:
|
|
|
|
*
|
|
|
|
* Probe for the availability of the qemu driver, assume the
|
|
|
|
* presence of QEmu emulation if the binaries are installed
|
|
|
|
*/
|
2008-11-17 11:44:51 +00:00
|
|
|
static int qemudProbe(void)
|
2008-02-26 07:05:18 +00:00
|
|
|
{
|
|
|
|
if ((virFileExists("/usr/bin/qemu")) ||
|
|
|
|
(virFileExists("/usr/bin/qemu-kvm")) ||
|
2008-12-04 10:45:31 +00:00
|
|
|
(virFileExists("/usr/bin/kvm")) ||
|
2008-11-17 11:44:51 +00:00
|
|
|
(virFileExists("/usr/bin/xenner")))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
2008-02-26 07:05:18 +00:00
|
|
|
}
|
2007-06-26 19:49:50 +00:00
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static virDrvOpenStatus qemudOpen(virConnectPtr conn,
|
2007-12-05 18:28:05 +00:00
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
2007-09-21 19:32:02 +00:00
|
|
|
int flags ATTRIBUTE_UNUSED) {
|
2007-06-26 22:39:53 +00:00
|
|
|
uid_t uid = getuid();
|
|
|
|
|
|
|
|
if (qemu_driver == NULL)
|
2007-11-14 11:40:57 +00:00
|
|
|
goto decline;
|
2007-06-26 22:39:53 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
if (!qemudProbe())
|
|
|
|
goto decline;
|
|
|
|
|
|
|
|
if (conn->uri == NULL) {
|
|
|
|
conn->uri = xmlParseURI(uid ? "qemu:///session" : "qemu:///system");
|
|
|
|
if (!conn->uri) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,NULL);
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
} else if (conn->uri->scheme == NULL ||
|
|
|
|
conn->uri->path == NULL)
|
2007-09-21 19:32:02 +00:00
|
|
|
goto decline;
|
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
if (STRNEQ (conn->uri->scheme, "qemu"))
|
2007-09-21 19:32:02 +00:00
|
|
|
goto decline;
|
|
|
|
|
2007-09-20 17:13:39 +00:00
|
|
|
if (uid != 0) {
|
2008-11-17 11:44:51 +00:00
|
|
|
if (STRNEQ (conn->uri->path, "/session"))
|
2007-09-21 19:32:02 +00:00
|
|
|
goto decline;
|
2007-09-20 17:13:39 +00:00
|
|
|
} else { /* root */
|
2008-11-17 11:44:51 +00:00
|
|
|
if (STRNEQ (conn->uri->path, "/system") &&
|
|
|
|
STRNEQ (conn->uri->path, "/session"))
|
2008-02-05 19:27:37 +00:00
|
|
|
goto decline;
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
conn->privateData = qemu_driver;
|
|
|
|
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
2007-09-21 19:32:02 +00:00
|
|
|
|
|
|
|
decline:
|
2008-02-05 19:27:37 +00:00
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int qemudClose(virConnectPtr conn) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-11-21 10:17:22 +00:00
|
|
|
|
|
|
|
/* Get rid of callbacks registered for this conn */
|
|
|
|
virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
|
2007-06-26 22:39:53 +00:00
|
|
|
|
|
|
|
conn->privateData = NULL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-11-14 08:42:47 +00:00
|
|
|
/* Which features are supported by this driver? */
|
|
|
|
static int
|
|
|
|
qemudSupportsFeature (virConnectPtr conn ATTRIBUTE_UNUSED, int feature)
|
|
|
|
{
|
|
|
|
switch (feature) {
|
|
|
|
case VIR_DRV_FEATURE_MIGRATION_V2: return 1;
|
|
|
|
default: return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
static const char *qemudGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
2007-07-04 03:59:13 +00:00
|
|
|
return "QEMU";
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
2008-09-17 14:07:49 +00:00
|
|
|
|
|
|
|
static int kvmGetMaxVCPUs(void) {
|
|
|
|
int maxvcpus = 1;
|
|
|
|
|
|
|
|
int r, fd;
|
2008-09-18 08:54:23 +00:00
|
|
|
|
2008-09-17 14:07:49 +00:00
|
|
|
fd = open(KVM_DEVICE, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
2008-09-18 08:54:23 +00:00
|
|
|
qemudLog(QEMUD_WARN, _("Unable to open %s: %s\n"), KVM_DEVICE, strerror(errno));
|
2008-09-17 14:07:49 +00:00
|
|
|
return maxvcpus;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
|
|
|
|
if (r > 0)
|
|
|
|
maxvcpus = r;
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
return maxvcpus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
static int qemudGetMaxVCPUs(virConnectPtr conn, const char *type) {
|
2007-06-26 22:39:53 +00:00
|
|
|
if (!type)
|
|
|
|
return 16;
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
if (STRCASEEQ(type, "qemu"))
|
2007-06-26 22:39:53 +00:00
|
|
|
return 16;
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
if (STRCASEEQ(type, "kvm"))
|
2008-09-17 14:07:49 +00:00
|
|
|
return kvmGetMaxVCPUs();
|
2007-06-26 22:39:53 +00:00
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
if (STRCASEEQ(type, "kqemu"))
|
2007-06-26 22:39:53 +00:00
|
|
|
return 1;
|
2008-05-07 16:16:44 +00:00
|
|
|
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("unknown type '%s'"), type);
|
2007-06-26 22:39:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-07-25 23:16:30 +00:00
|
|
|
static int qemudGetNodeInfo(virConnectPtr conn,
|
|
|
|
virNodeInfoPtr nodeinfo) {
|
|
|
|
return virNodeInfoPopulate(conn, nodeinfo);
|
2007-06-26 19:49:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
static char *qemudGetCapabilities(virConnectPtr conn) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-02-27 04:35:08 +00:00
|
|
|
char *xml;
|
2007-06-26 19:49:50 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
|
qemudReportError: mark for translation string args to this function
* Makefile.maint (msg_gen_function): Add qemudReportError.
* src/qemu_conf.c (qemudLoadDriverConfig)
(qemudExtractVersion, qemudParseDiskXML, qemudParseInterfaceXML)
(qemudParseInputXML, qemudParseXML, qemudNetworkIfaceConnect)
(qemudBuildCommandLine, qemudSaveConfig, qemudParseVMDeviceDef)
(qemudAssignVMDef, qemudSaveVMDef, qemudSaveNetworkConfig)
(qemudParseDhcpRangesXML, qemudParseNetworkXML)
(qemudAssignNetworkDef, qemudSaveNetworkDef, qemudGenerateXML)
(qemudGenerateNetworkXML, qemudDeleteConfig): Mark strings.
* src/qemu_driver.c (qemudBuildDnsmasqArgv, qemudAddIptablesRules)
(qemudGetCapabilities, qemudDomainGetOSType)
(qemudListDefinedDomains, qemudListNetworks)
(qemudListDefinedNetworks, qemudNetworkGetBridgeName): Mark strings.
2008-03-27 13:53:14 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("failed to allocate space for capabilities support"));
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 19:49:50 +00:00
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
return xml;
|
2007-06-26 19:49:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-22 15:29:50 +00:00
|
|
|
#if HAVE_NUMACTL
|
|
|
|
static int
|
|
|
|
qemudNodeGetCellsFreeMemory(virConnectPtr conn,
|
|
|
|
unsigned long long *freeMems,
|
|
|
|
int startCell,
|
|
|
|
int maxCells)
|
|
|
|
{
|
|
|
|
int n, lastCell, numCells;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-05-22 15:29:50 +00:00
|
|
|
|
|
|
|
if (numa_available() < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("NUMA not supported on this host"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 15:29:50 +00:00
|
|
|
}
|
|
|
|
lastCell = startCell + maxCells - 1;
|
|
|
|
if (lastCell > numa_max_node())
|
|
|
|
lastCell = numa_max_node();
|
|
|
|
|
|
|
|
for (numCells = 0, n = startCell ; n <= lastCell ; n++) {
|
|
|
|
long long mem;
|
|
|
|
if (numa_node_size64(n, &mem) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Failed to query NUMA free memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 15:29:50 +00:00
|
|
|
}
|
|
|
|
freeMems[numCells++] = mem;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = numCells;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
2008-05-22 15:29:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long long
|
|
|
|
qemudNodeGetFreeMemory (virConnectPtr conn)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
unsigned long long freeMem = -1;
|
2008-05-22 15:29:50 +00:00
|
|
|
int n;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
2008-05-22 15:29:50 +00:00
|
|
|
if (numa_available() < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("NUMA not supported on this host"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 15:29:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (n = 0 ; n <= numa_max_node() ; n++) {
|
|
|
|
long long mem;
|
|
|
|
if (numa_node_size64(n, &mem) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Failed to query NUMA free memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 15:29:50 +00:00
|
|
|
}
|
|
|
|
freeMem += mem;
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-05-22 15:29:50 +00:00
|
|
|
return freeMem;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2007-06-26 19:49:50 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
|
|
|
|
char proc[PATH_MAX];
|
|
|
|
FILE *pidinfo;
|
2007-04-15 19:58:44 +00:00
|
|
|
unsigned long long usertime, systime;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
if (snprintf(proc, sizeof(proc), "/proc/%d/stat", pid) >= (int)sizeof(proc)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(pidinfo = fopen(proc, "r"))) {
|
2008-08-15 01:41:49 +00:00
|
|
|
/*printf("cannot read pid info");*/
|
2007-02-14 01:40:09 +00:00
|
|
|
/* VM probably shut down, so fake 0 */
|
|
|
|
*cpuTime = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-04-15 19:58:44 +00:00
|
|
|
if (fscanf(pidinfo, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu", &usertime, &systime) != 2) {
|
2007-02-16 18:30:55 +00:00
|
|
|
qemudDebug("not enough arg");
|
2007-02-14 01:40:09 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We got jiffies
|
|
|
|
* We want nanoseconds
|
|
|
|
* _SC_CLK_TCK is jiffies per second
|
|
|
|
* So calulate thus....
|
|
|
|
*/
|
2007-04-15 19:58:44 +00:00
|
|
|
*cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime) / (unsigned long long)sysconf(_SC_CLK_TCK);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-04-15 19:58:44 +00:00
|
|
|
qemudDebug("Got %llu %llu %llu", usertime, systime, *cpuTime);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
fclose(pidinfo);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static virDomainPtr qemudDomainLookupByID(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
int id) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 22:39:53 +00:00
|
|
|
|
|
|
|
if (!vm) {
|
2007-07-06 14:56:15 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (dom) dom->id = vm->def->id;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2007-06-26 22:39:53 +00:00
|
|
|
return dom;
|
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
const unsigned char *uuid) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
2007-06-26 22:39:53 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
if (!vm) {
|
2007-07-06 14:56:15 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (dom) dom->id = vm->def->id;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2007-06-26 22:39:53 +00:00
|
|
|
return dom;
|
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
|
2008-07-11 19:34:11 +00:00
|
|
|
const char *name) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
2007-06-26 22:39:53 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByName(&driver->domains, name);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
if (!vm) {
|
2007-07-06 14:56:15 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (dom) dom->id = vm->def->id;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2007-06-26 22:39:53 +00:00
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudGetVersion(virConnectPtr conn, unsigned long *version) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
int ret = -1;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2007-07-12 15:09:01 +00:00
|
|
|
if (qemudExtractVersion(conn, driver) < 0)
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 17:15:18 +00:00
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
*version = qemu_driver->qemuVersion;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-09-20 17:13:39 +00:00
|
|
|
static char *
|
|
|
|
qemudGetHostname (virConnectPtr conn)
|
|
|
|
{
|
2009-01-07 10:43:16 +00:00
|
|
|
char *result;
|
2007-09-20 17:13:39 +00:00
|
|
|
|
2009-01-07 10:43:16 +00:00
|
|
|
result = virGetHostname();
|
|
|
|
if (result == NULL) {
|
2007-09-20 17:13:39 +00:00
|
|
|
qemudReportError (conn, NULL, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Caller frees this string. */
|
2009-01-07 10:43:16 +00:00
|
|
|
return result;
|
2007-09-20 17:13:39 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-10-10 14:20:37 +00:00
|
|
|
int got = 0, i;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
|
|
|
for (i = 0 ; i < driver->domains.count && got < nids ; i++) {
|
|
|
|
virDomainObjLock(driver->domains.objs[i]);
|
2008-10-10 14:20:37 +00:00
|
|
|
if (virDomainIsActive(driver->domains.objs[i]))
|
|
|
|
ids[got++] = driver->domains.objs[i]->def->id;
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjUnlock(driver->domains.objs[i]);
|
|
|
|
}
|
|
|
|
qemuDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
return got;
|
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudNumDomains(virConnectPtr conn) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-10-10 14:20:37 +00:00
|
|
|
int n = 0, i;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
|
|
|
for (i = 0 ; i < driver->domains.count ; i++) {
|
|
|
|
virDomainObjLock(driver->domains.objs[i]);
|
2008-10-10 14:20:37 +00:00
|
|
|
if (virDomainIsActive(driver->domains.objs[i]))
|
2008-07-11 19:34:11 +00:00
|
|
|
n++;
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjUnlock(driver->domains.objs[i]);
|
|
|
|
}
|
|
|
|
qemuDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
return n;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
|
2007-07-12 15:09:01 +00:00
|
|
|
unsigned int flags ATTRIBUTE_UNUSED) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainDefPtr def;
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
virDomainPtr dom = NULL;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2009-01-08 13:54:20 +00:00
|
|
|
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE)))
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2008-10-10 14:20:37 +00:00
|
|
|
vm = virDomainFindByName(&driver->domains, def->name);
|
2008-07-28 12:52:37 +00:00
|
|
|
if (vm) {
|
2008-07-24 07:29:50 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-08-01 06:23:31 +00:00
|
|
|
_("domain '%s' is already defined"),
|
2008-07-24 07:29:50 +00:00
|
|
|
def->name);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-07-24 07:29:50 +00:00
|
|
|
}
|
2008-10-10 14:20:37 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, def->uuid);
|
2008-07-28 12:52:37 +00:00
|
|
|
if (vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
virUUIDFormat(def->uuid, uuidstr);
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-08-01 06:23:31 +00:00
|
|
|
_("domain with uuid '%s' is already defined"),
|
2008-07-28 12:52:37 +00:00
|
|
|
uuidstr);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-07-28 12:52:37 +00:00
|
|
|
}
|
2008-07-24 07:29:50 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!(vm = virDomainAssignDef(conn,
|
|
|
|
&driver->domains,
|
2008-12-04 21:04:30 +00:00
|
|
|
def)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
def = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (qemudStartVMDaemon(conn, driver, vm, NULL) < 0) {
|
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-12-04 21:09:20 +00:00
|
|
|
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (dom) dom->id = vm->def->id;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainDefFree(def);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 22:39:53 +00:00
|
|
|
return dom;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainSuspend(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
2007-02-14 01:40:09 +00:00
|
|
|
char *info;
|
2008-12-04 21:04:30 +00:00
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
2008-03-24 10:51:47 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, _("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
if (vm->state != VIR_DOMAIN_PAUSED) {
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, "stop", &info) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("suspend operation failed"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
vm->state = VIR_DOMAIN_PAUSED;
|
|
|
|
qemudDebug("Reply %s", info);
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
|
|
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
|
2008-12-04 21:04:30 +00:00
|
|
|
VIR_FREE(info);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-12-20 13:17:49 +00:00
|
|
|
qemudSaveDomainStatus(dom->conn, driver, vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
|
|
|
|
if (event) {
|
|
|
|
qemuDriverLock(driver);
|
|
|
|
qemuDomainEventQueue(driver, event);
|
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainResume(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
2007-02-14 01:40:09 +00:00
|
|
|
char *info;
|
2008-12-04 21:04:30 +00:00
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
if (vm->state == VIR_DOMAIN_PAUSED) {
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, "cont", &info) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("resume operation failed"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
vm->state = VIR_DOMAIN_RUNNING;
|
|
|
|
qemudDebug("Reply %s", info);
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_RESUMED,
|
|
|
|
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
|
2008-12-04 21:04:30 +00:00
|
|
|
VIR_FREE(info);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-12-20 13:17:49 +00:00
|
|
|
qemudSaveDomainStatus(dom->conn, driver, vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event) {
|
|
|
|
qemuDriverLock(driver);
|
|
|
|
qemuDomainEventQueue(driver, event);
|
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-09 16:05:21 +00:00
|
|
|
static int qemudDomainShutdown(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-01-09 16:05:21 +00:00
|
|
|
char* info;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-01-09 16:05:21 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-01-09 16:05:21 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-01-09 16:05:21 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, "system_powerdown", &info) < 0) {
|
2008-01-09 16:05:21 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("shutdown operation failed"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-01-09 16:05:21 +00:00
|
|
|
}
|
2008-10-08 13:44:40 +00:00
|
|
|
VIR_FREE(info);
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-01-09 16:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainDestroy(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2007-02-23 08:41:23 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2007-02-23 08:41:23 +00:00
|
|
|
|
2007-07-24 14:24:52 +00:00
|
|
|
qemudShutdownVMDaemon(dom->conn, driver, vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (!vm->persistent) {
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
static char *qemudDomainGetOSType(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char *type = NULL;
|
2007-06-26 22:39:53 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 22:39:53 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-06-26 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (!(type = strdup(vm->def->os.type)))
|
qemudReportError: mark for translation string args to this function
* Makefile.maint (msg_gen_function): Add qemudReportError.
* src/qemu_conf.c (qemudLoadDriverConfig)
(qemudExtractVersion, qemudParseDiskXML, qemudParseInterfaceXML)
(qemudParseInputXML, qemudParseXML, qemudNetworkIfaceConnect)
(qemudBuildCommandLine, qemudSaveConfig, qemudParseVMDeviceDef)
(qemudAssignVMDef, qemudSaveVMDef, qemudSaveNetworkConfig)
(qemudParseDhcpRangesXML, qemudParseNetworkXML)
(qemudAssignNetworkDef, qemudSaveNetworkDef, qemudGenerateXML)
(qemudGenerateNetworkXML, qemudDeleteConfig): Mark strings.
* src/qemu_driver.c (qemudBuildDnsmasqArgv, qemudAddIptablesRules)
(qemudGetCapabilities, qemudDomainGetOSType)
(qemudListDefinedDomains, qemudListNetworks)
(qemudListDefinedNetworks, qemudNetworkGetBridgeName): Mark strings.
2008-03-27 13:53:14 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("failed to allocate space for ostype"));
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2007-06-26 22:39:53 +00:00
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2008-03-19 14:32:50 +00:00
|
|
|
/* Returns max memory in kb, 0 if error */
|
|
|
|
static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
unsigned long ret = 0;
|
2008-03-19 14:32:50 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-03-19 14:32:50 +00:00
|
|
|
if (!vm) {
|
2008-07-25 09:01:25 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2008-03-19 14:32:50 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-07-25 09:01:25 +00:00
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = vm->def->maxmem;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2008-03-19 14:32:50 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-03-19 14:32:50 +00:00
|
|
|
if (!vm) {
|
2008-07-25 09:01:25 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2008-03-19 14:32:50 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-07-25 09:01:25 +00:00
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (newmax < vm->def->memory) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("cannot set max memory lower than current memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vm->def->maxmem = newmax;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2008-03-19 14:32:50 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-03-19 14:32:50 +00:00
|
|
|
if (!vm) {
|
2008-07-25 09:01:25 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2008-03-19 14:32:50 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-07-25 09:01:25 +00:00
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (virDomainIsActive(vm)) {
|
2008-06-12 08:55:13 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("cannot set memory of an active domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (newmem > vm->def->maxmem) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("cannot set memory higher than max memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vm->def->memory = newmem;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-03-19 14:32:50 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainGetInfo(virDomainPtr dom,
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainInfoPtr info) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
info->state = vm->state;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
2007-06-26 22:39:53 +00:00
|
|
|
info->cpuTime = 0;
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
2007-06-26 22:39:53 +00:00
|
|
|
if (qemudGetProcessInfo(&(info->cpuTime), vm->pid) < 0) {
|
2008-03-24 10:51:47 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, ("cannot read cputime for domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
info->maxMem = vm->def->maxmem;
|
|
|
|
info->memory = vm->def->memory;
|
|
|
|
info->nrVirtCpu = vm->def->vcpus;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-27 01:19:51 +00:00
|
|
|
static char *qemudEscape(const char *in, int shell)
|
2007-08-14 01:33:38 +00:00
|
|
|
{
|
|
|
|
int len = 0;
|
|
|
|
int i, j;
|
|
|
|
char *out;
|
|
|
|
|
|
|
|
/* To pass through the QEMU monitor, we need to use escape
|
|
|
|
sequences: \r, \n, \", \\
|
|
|
|
|
|
|
|
To pass through both QEMU + the shell, we need to escape
|
|
|
|
the single character ' as the five characters '\\''
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (i = 0; in[i] != '\0'; i++) {
|
|
|
|
switch(in[i]) {
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
|
|
|
case '"':
|
|
|
|
case '\\':
|
|
|
|
len += 2;
|
|
|
|
break;
|
|
|
|
case '\'':
|
2007-10-27 01:19:51 +00:00
|
|
|
if (shell)
|
|
|
|
len += 5;
|
|
|
|
else
|
|
|
|
len += 1;
|
2007-08-14 01:33:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
len += 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC_N(out, len + 1) < 0)
|
2007-08-14 01:33:38 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (i = j = 0; in[i] != '\0'; i++) {
|
|
|
|
switch(in[i]) {
|
|
|
|
case '\r':
|
|
|
|
out[j++] = '\\';
|
|
|
|
out[j++] = 'r';
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
out[j++] = '\\';
|
|
|
|
out[j++] = 'n';
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
case '\\':
|
|
|
|
out[j++] = '\\';
|
|
|
|
out[j++] = in[i];
|
|
|
|
break;
|
|
|
|
case '\'':
|
2007-10-27 01:19:51 +00:00
|
|
|
if (shell) {
|
|
|
|
out[j++] = '\'';
|
|
|
|
out[j++] = '\\';
|
|
|
|
out[j++] = '\\';
|
|
|
|
out[j++] = '\'';
|
|
|
|
out[j++] = '\'';
|
|
|
|
} else {
|
|
|
|
out[j++] = in[i];
|
|
|
|
}
|
2007-08-14 01:33:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
out[j++] = in[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out[j] = '\0';
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2007-10-27 01:21:09 +00:00
|
|
|
static char *qemudEscapeMonitorArg(const char *in)
|
|
|
|
{
|
|
|
|
return qemudEscape(in, 0);
|
|
|
|
}
|
|
|
|
|
2007-10-27 01:19:51 +00:00
|
|
|
static char *qemudEscapeShellArg(const char *in)
|
|
|
|
{
|
|
|
|
return qemudEscape(in, 1);
|
|
|
|
}
|
2007-08-14 01:33:38 +00:00
|
|
|
|
2007-08-14 01:47:24 +00:00
|
|
|
#define QEMUD_SAVE_MAGIC "LibvirtQemudSave"
|
|
|
|
#define QEMUD_SAVE_VERSION 1
|
|
|
|
|
|
|
|
struct qemud_save_header {
|
|
|
|
char magic[sizeof(QEMUD_SAVE_MAGIC)-1];
|
|
|
|
int version;
|
|
|
|
int xml_len;
|
|
|
|
int was_running;
|
|
|
|
int unused[16];
|
|
|
|
};
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainSave(virDomainPtr dom,
|
2007-08-14 01:47:24 +00:00
|
|
|
const char *path) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char *command = NULL;
|
|
|
|
char *info = NULL;
|
|
|
|
int fd = -1;
|
|
|
|
char *safe_path = NULL;
|
|
|
|
char *xml = NULL;
|
2007-08-14 01:47:24 +00:00
|
|
|
struct qemud_save_header header;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2007-08-14 01:47:24 +00:00
|
|
|
|
|
|
|
memset(&header, 0, sizeof(header));
|
|
|
|
memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
|
|
|
|
header.version = QEMUD_SAVE_VERSION;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2007-08-14 01:47:24 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2007-08-14 01:47:24 +00:00
|
|
|
|
|
|
|
/* Pause */
|
|
|
|
if (vm->state == VIR_DOMAIN_RUNNING) {
|
|
|
|
header.was_running = 1;
|
|
|
|
if (qemudDomainSuspend(dom) != 0) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to pause domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get XML for the domain */
|
2008-07-11 19:34:11 +00:00
|
|
|
xml = virDomainDefFormat(dom->conn, vm->def, VIR_DOMAIN_XML_SECURE);
|
2007-08-14 01:47:24 +00:00
|
|
|
if (!xml) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to get domain xml"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
header.xml_len = strlen(xml) + 1;
|
|
|
|
|
|
|
|
/* Write header to file, followed by XML */
|
|
|
|
if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("failed to create '%s'"), path);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (safewrite(fd, &header, sizeof(header)) != sizeof(header)) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to write save header"));
|
2008-12-04 21:06:41 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (safewrite(fd, xml, header.xml_len) != header.xml_len) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to write xml"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (close(fd) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(dom->conn, errno,
|
|
|
|
_("unable to save file %s"),
|
|
|
|
path);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
fd = -1;
|
2007-08-14 01:47:24 +00:00
|
|
|
|
|
|
|
/* Migrate to file */
|
|
|
|
safe_path = qemudEscapeShellArg(path);
|
|
|
|
if (!safe_path) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("out of memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&command, "migrate \"exec:"
|
2007-08-14 01:47:24 +00:00
|
|
|
"dd of='%s' oflag=append conv=notrunc 2>/dev/null"
|
2007-10-27 01:16:53 +00:00
|
|
|
"\"", safe_path) == -1) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("out of memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
command = NULL;
|
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, command, &info) < 0) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("migrate operation failed"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-24 07:09:45 +00:00
|
|
|
DEBUG ("migrate reply: %s", info);
|
|
|
|
|
|
|
|
/* If the command isn't supported then qemu prints:
|
|
|
|
* unknown command: migrate" */
|
|
|
|
if (strstr(info, "unknown command:")) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s",
|
|
|
|
_("'migrate' not supported by this qemu"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-07-24 07:09:45 +00:00
|
|
|
}
|
|
|
|
|
2007-08-14 01:47:24 +00:00
|
|
|
/* Shut it down */
|
|
|
|
qemudShutdownVMDaemon(dom->conn, driver, vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_SAVED);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (!vm->persistent) {
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (fd != -1)
|
|
|
|
close(fd);
|
|
|
|
VIR_FREE(xml);
|
|
|
|
VIR_FREE(safe_path);
|
|
|
|
VIR_FREE(command);
|
|
|
|
VIR_FREE(info);
|
|
|
|
if (ret != 0)
|
|
|
|
unlink(path);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-05-07 16:16:44 +00:00
|
|
|
int max;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-05-07 16:16:44 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
if (!vm) {
|
2008-07-25 09:01:25 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2008-05-07 16:16:44 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-07-25 09:01:25 +00:00
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (virDomainIsActive(vm)) {
|
2008-06-12 08:55:13 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
|
2008-05-07 16:16:44 +00:00
|
|
|
_("cannot change vcpu count of an active domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((max = qemudDomainGetMaxVcpus(dom)) < 0) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not determine max vcpus for the domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (nvcpus > max) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("requested vcpus is greater than max allowable"
|
|
|
|
" vcpus for the domain: %d > %d"), nvcpus, max);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vm->def->vcpus = nvcpus;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
2008-05-22 16:20:31 +00:00
|
|
|
|
|
|
|
#if HAVE_SCHED_GETAFFINITY
|
|
|
|
static int
|
|
|
|
qemudDomainPinVcpu(virDomainPtr dom,
|
|
|
|
unsigned int vcpu,
|
|
|
|
unsigned char *cpumap,
|
|
|
|
int maplen) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-05-22 16:20:31 +00:00
|
|
|
cpu_set_t mask;
|
|
|
|
int i, maxcpu;
|
|
|
|
virNodeInfo nodeinfo;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-05-22 16:20:31 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
2008-05-22 16:20:31 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
"%s",_("cannot pin vcpus on an inactive domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (vcpu > (vm->nvcpupids-1)) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("vcpu number out of range %d > %d"),
|
|
|
|
vcpu, vm->nvcpupids);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (virNodeInfoPopulate(dom->conn, &nodeinfo) < 0)
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
|
|
|
|
maxcpu = maplen * 8;
|
|
|
|
if (maxcpu > nodeinfo.cpus)
|
|
|
|
maxcpu = nodeinfo.cpus;
|
|
|
|
|
|
|
|
CPU_ZERO(&mask);
|
|
|
|
for (i = 0 ; i < maxcpu ; i++) {
|
|
|
|
if ((cpumap[i/8] >> (i % 8)) & 1)
|
|
|
|
CPU_SET(i, &mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vm->vcpupids != NULL) {
|
|
|
|
if (sched_setaffinity(vm->vcpupids[vcpu], sizeof(mask), &mask) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(dom->conn, errno, "%s",
|
|
|
|
_("cannot set affinity"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("cpu affinity is not supported"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
2008-05-22 16:20:31 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
qemudDomainGetVcpus(virDomainPtr dom,
|
|
|
|
virVcpuInfoPtr info,
|
|
|
|
int maxinfo,
|
|
|
|
unsigned char *cpumaps,
|
|
|
|
int maplen) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-05-22 16:20:31 +00:00
|
|
|
virNodeInfo nodeinfo;
|
|
|
|
int i, v, maxcpu;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-05-22 16:20:31 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
2008-05-22 16:20:31 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
"%s",_("cannot pin vcpus on an inactive domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (virNodeInfoPopulate(dom->conn, &nodeinfo) < 0)
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
|
|
|
|
maxcpu = maplen * 8;
|
|
|
|
if (maxcpu > nodeinfo.cpus)
|
|
|
|
maxcpu = nodeinfo.cpus;
|
|
|
|
|
|
|
|
/* Clamp to actual number of vcpus */
|
|
|
|
if (maxinfo > vm->nvcpupids)
|
|
|
|
maxinfo = vm->nvcpupids;
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (maxinfo >= 1) {
|
|
|
|
if (info != NULL) {
|
|
|
|
memset(info, 0, sizeof(*info) * maxinfo);
|
|
|
|
for (i = 0 ; i < maxinfo ; i++) {
|
|
|
|
info[i].number = i;
|
|
|
|
info[i].state = VIR_VCPU_RUNNING;
|
|
|
|
/* XXX cpu time, current pCPU mapping */
|
|
|
|
}
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (cpumaps != NULL) {
|
|
|
|
memset(cpumaps, 0, maplen * maxinfo);
|
|
|
|
if (vm->vcpupids != NULL) {
|
|
|
|
for (v = 0 ; v < maxinfo ; v++) {
|
|
|
|
cpu_set_t mask;
|
|
|
|
unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);
|
|
|
|
CPU_ZERO(&mask);
|
|
|
|
|
|
|
|
if (sched_getaffinity(vm->vcpupids[v], sizeof(mask), &mask) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(dom->conn, errno, "%s",
|
|
|
|
_("cannot get affinity"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0 ; i < maxcpu ; i++)
|
|
|
|
if (CPU_ISSET(i, &mask))
|
|
|
|
VIR_USE_CPU(cpumap, i);
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
} else {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("cpu affinity is not available"));
|
|
|
|
goto cleanup;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = maxinfo;
|
2008-05-22 16:20:31 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-05-22 16:20:31 +00:00
|
|
|
}
|
|
|
|
#endif /* HAVE_SCHED_GETAFFINITY */
|
|
|
|
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
static int qemudDomainGetMaxVcpus(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-05-07 16:16:44 +00:00
|
|
|
const char *type;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2008-05-07 16:16:44 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
if (!vm) {
|
2008-07-25 09:01:25 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2008-05-07 16:16:44 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-07-25 09:01:25 +00:00
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
|
2008-05-07 16:16:44 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unknown virt type in domain definition '%d'"),
|
|
|
|
vm->def->virtType);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-05-07 16:16:44 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = qemudGetMaxVCPUs(dom->conn, type);
|
2008-05-07 16:16:44 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-05-07 16:16:44 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainRestore(virConnectPtr conn,
|
2008-12-04 21:04:30 +00:00
|
|
|
const char *path) {
|
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
virDomainDefPtr def = NULL;
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
int fd = -1;
|
|
|
|
int ret = -1;
|
|
|
|
char *xml = NULL;
|
2007-08-14 01:47:24 +00:00
|
|
|
struct qemud_save_header header;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2007-08-14 01:47:24 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2007-08-14 01:47:24 +00:00
|
|
|
/* Verify the header and read the XML */
|
|
|
|
if ((fd = open(path, O_RDONLY)) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("cannot read domain image"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to read qemu header"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (memcmp(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic)) != 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("image magic is incorrect"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (header.version > QEMUD_SAVE_VERSION) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("image version is not supported (%d > %d)"),
|
2007-08-14 01:47:24 +00:00
|
|
|
header.version, QEMUD_SAVE_VERSION);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC_N(xml, header.xml_len) < 0) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("out of memory"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (saferead(fd, xml, header.xml_len) != header.xml_len) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to read XML"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a domain from this XML */
|
2009-01-08 13:54:20 +00:00
|
|
|
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE))) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to parse XML"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Ensure the name and UUID don't already exist in an active VM */
|
2008-10-10 14:20:37 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, def->uuid);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!vm)
|
2008-10-10 14:20:37 +00:00
|
|
|
vm = virDomainFindByName(&driver->domains, def->name);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (vm && virDomainIsActive(vm)) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("domain is already active as '%s'"), vm->def->name);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!(vm = virDomainAssignDef(conn,
|
|
|
|
&driver->domains,
|
|
|
|
def))) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to assign new VM"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
def = NULL;
|
2007-08-14 01:47:24 +00:00
|
|
|
|
|
|
|
/* Set the migration source and start it up. */
|
2008-08-12 08:38:22 +00:00
|
|
|
vm->stdin_fd = fd;
|
2008-07-11 19:34:11 +00:00
|
|
|
ret = qemudStartVMDaemon(conn, driver, vm, "stdio");
|
2007-10-10 19:46:17 +00:00
|
|
|
close(fd);
|
2008-12-04 21:04:30 +00:00
|
|
|
fd = -1;
|
2008-08-12 08:38:22 +00:00
|
|
|
vm->stdin_fd = -1;
|
2007-10-10 19:46:17 +00:00
|
|
|
if (ret < 0) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to start VM"));
|
2008-12-04 21:06:41 +00:00
|
|
|
if (!vm->persistent) {
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_RESTORED);
|
2008-11-17 16:43:00 +00:00
|
|
|
|
2007-08-14 01:47:24 +00:00
|
|
|
/* If it was running before, resume it now. */
|
|
|
|
if (header.was_running) {
|
|
|
|
char *info;
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, "cont", &info) < 0) {
|
2007-08-14 01:47:24 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("failed to resume domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-08-14 01:47:24 +00:00
|
|
|
}
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(info);
|
2007-08-14 01:47:24 +00:00
|
|
|
vm->state = VIR_DOMAIN_RUNNING;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
2007-08-14 01:47:24 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
|
|
|
virDomainDefFree(def);
|
|
|
|
VIR_FREE(xml);
|
|
|
|
if (fd != -1)
|
|
|
|
close(fd);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static char *qemudDomainDumpXML(virDomainPtr dom,
|
2008-07-11 19:34:11 +00:00
|
|
|
int flags ATTRIBUTE_UNUSED) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = virDomainDefFormat(dom->conn,
|
|
|
|
(flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef ?
|
|
|
|
vm->newDef : vm->def,
|
|
|
|
flags);
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudListDefinedDomains(virConnectPtr conn,
|
2007-06-26 22:39:53 +00:00
|
|
|
char **const names, int nnames) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2007-06-26 22:39:53 +00:00
|
|
|
int got = 0, i;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) {
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjLock(driver->domains.objs[i]);
|
2008-10-10 14:20:37 +00:00
|
|
|
if (!virDomainIsActive(driver->domains.objs[i])) {
|
|
|
|
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
|
qemudReportError: mark for translation string args to this function
* Makefile.maint (msg_gen_function): Add qemudReportError.
* src/qemu_conf.c (qemudLoadDriverConfig)
(qemudExtractVersion, qemudParseDiskXML, qemudParseInterfaceXML)
(qemudParseInputXML, qemudParseXML, qemudNetworkIfaceConnect)
(qemudBuildCommandLine, qemudSaveConfig, qemudParseVMDeviceDef)
(qemudAssignVMDef, qemudSaveVMDef, qemudSaveNetworkConfig)
(qemudParseDhcpRangesXML, qemudParseNetworkXML)
(qemudAssignNetworkDef, qemudSaveNetworkDef, qemudGenerateXML)
(qemudGenerateNetworkXML, qemudDeleteConfig): Mark strings.
* src/qemu_driver.c (qemudBuildDnsmasqArgv, qemudAddIptablesRules)
(qemudGetCapabilities, qemudDomainGetOSType)
(qemudListDefinedDomains, qemudListNetworks)
(qemudListDefinedNetworks, qemudNetworkGetBridgeName): Mark strings.
2008-03-27 13:53:14 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
2008-10-10 14:20:37 +00:00
|
|
|
"%s", _("failed to allocate space for VM name string"));
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjUnlock(driver->domains.objs[i]);
|
2007-06-26 22:39:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2007-02-23 08:39:49 +00:00
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjUnlock(driver->domains.objs[i]);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-02-14 01:40:09 +00:00
|
|
|
return got;
|
2007-06-26 22:39:53 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
for (i = 0 ; i < got ; i++)
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(names[i]);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 22:39:53 +00:00
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudNumDefinedDomains(virConnectPtr conn) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-10-10 14:20:37 +00:00
|
|
|
int n = 0, i;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
for (i = 0 ; i < driver->domains.count ; i++)
|
|
|
|
if (!virDomainIsActive(driver->domains.objs[i]))
|
2008-07-11 19:34:11 +00:00
|
|
|
n++;
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
return n;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainStart(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2007-02-23 08:41:23 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-02-23 08:41:23 +00:00
|
|
|
if (!vm) {
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 08:41:23 +00:00
|
|
|
}
|
|
|
|
|
2008-11-17 16:43:00 +00:00
|
|
|
ret = qemudStartVMDaemon(dom->conn, driver, vm, NULL);
|
2008-12-04 21:04:30 +00:00
|
|
|
if (ret != -1)
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event) {
|
|
|
|
qemuDriverLock(driver);
|
|
|
|
qemuDomainEventQueue(driver, event);
|
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainDefPtr def;
|
2008-12-04 21:06:41 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
virDomainPtr dom = NULL;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-11-17 16:52:32 +00:00
|
|
|
int newVM = 1;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2009-01-08 13:54:20 +00:00
|
|
|
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE)))
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2008-11-17 16:52:32 +00:00
|
|
|
vm = virDomainFindByName(&driver->domains, def->name);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm) {
|
|
|
|
virDomainObjUnlock(vm);
|
2008-11-17 16:52:32 +00:00
|
|
|
newVM = 0;
|
2008-12-04 21:06:41 +00:00
|
|
|
}
|
2008-11-17 16:52:32 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!(vm = virDomainAssignDef(conn,
|
|
|
|
&driver->domains,
|
|
|
|
def))) {
|
|
|
|
virDomainDefFree(def);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 08:48:02 +00:00
|
|
|
}
|
2008-08-20 19:42:36 +00:00
|
|
|
vm->persistent = 1;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (virDomainSaveConfig(conn,
|
|
|
|
driver->configDir,
|
2008-08-20 19:42:36 +00:00
|
|
|
vm->newDef ? vm->newDef : vm->def) < 0) {
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 08:48:02 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED,
|
|
|
|
newVM ?
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED_ADDED :
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED_UPDATED);
|
2008-11-17 16:52:32 +00:00
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-07-11 19:34:11 +00:00
|
|
|
if (dom) dom->id = vm->def->id;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2007-06-26 22:39:53 +00:00
|
|
|
return dom;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainUndefine(virDomainPtr dom) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (!vm) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (virDomainIsActive(vm)) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cannot delete active domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-08-20 19:42:36 +00:00
|
|
|
if (!vm->persistent) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cannot undefine transient domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-08-20 19:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainDeleteConfig(dom->conn, driver->configDir, driver->autostartDir, vm) < 0)
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_UNDEFINED,
|
|
|
|
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
|
2008-11-17 16:52:32 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains,
|
|
|
|
vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-09-03 16:05:25 +00:00
|
|
|
/* Return the disks name for use in monitor commands */
|
2008-12-04 21:04:30 +00:00
|
|
|
static char *qemudDiskDeviceName(const virConnectPtr conn,
|
2008-10-17 09:24:07 +00:00
|
|
|
const virDomainDiskDefPtr disk) {
|
2008-09-03 16:05:25 +00:00
|
|
|
|
|
|
|
int busid, devid;
|
|
|
|
int ret;
|
|
|
|
char *devname;
|
|
|
|
|
|
|
|
if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-09-03 16:05:25 +00:00
|
|
|
_("cannot convert disk '%s' to bus/device index"),
|
|
|
|
disk->dst);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (disk->bus) {
|
|
|
|
case VIR_DOMAIN_DISK_BUS_IDE:
|
2008-10-17 09:24:07 +00:00
|
|
|
if (disk->device== VIR_DOMAIN_DISK_DEVICE_DISK)
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&devname, "ide%d-hd%d", busid, devid);
|
2008-10-17 09:24:07 +00:00
|
|
|
else
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&devname, "ide%d-cd%d", busid, devid);
|
2008-09-03 16:05:25 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_DISK_BUS_SCSI:
|
2008-10-17 09:24:07 +00:00
|
|
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&devname, "scsi%d-hd%d", busid, devid);
|
2008-10-17 09:24:07 +00:00
|
|
|
else
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&devname, "scsi%d-cd%d", busid, devid);
|
2008-09-03 16:05:25 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_DISK_BUS_FDC:
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&devname, "floppy%d", devid);
|
2008-09-03 16:05:25 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_DISK_BUS_VIRTIO:
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&devname, "virtio%d", devid);
|
2008-09-03 16:05:25 +00:00
|
|
|
break;
|
|
|
|
default:
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
|
2008-09-03 16:05:25 +00:00
|
|
|
_("Unsupported disk name mapping for bus '%s'"),
|
|
|
|
virDomainDiskBusTypeToString(disk->bus));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == -1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-09-03 16:05:25 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return devname;
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm,
|
2008-09-03 16:05:25 +00:00
|
|
|
virDomainDeviceDefPtr dev)
|
|
|
|
{
|
2008-10-24 11:20:08 +00:00
|
|
|
virDomainDiskDefPtr origdisk = NULL, newdisk;
|
2007-10-27 01:21:09 +00:00
|
|
|
char *cmd, *reply, *safe_path;
|
2008-09-03 16:05:25 +00:00
|
|
|
char *devname = NULL;
|
2008-09-04 08:15:05 +00:00
|
|
|
unsigned int qemuCmdFlags;
|
2008-10-10 16:08:01 +00:00
|
|
|
int i;
|
2008-09-03 16:05:25 +00:00
|
|
|
|
2008-10-16 13:44:09 +00:00
|
|
|
origdisk = NULL;
|
2008-09-03 16:05:25 +00:00
|
|
|
newdisk = dev->data.disk;
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
|
|
if (vm->def->disks[i]->bus == newdisk->bus &&
|
|
|
|
STREQ(vm->def->disks[i]->dst, newdisk->dst)) {
|
|
|
|
origdisk = vm->def->disks[i];
|
2008-09-03 16:05:25 +00:00
|
|
|
break;
|
2008-10-10 16:08:01 +00:00
|
|
|
}
|
2008-09-03 16:05:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!origdisk) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-09-03 16:05:25 +00:00
|
|
|
_("No device with bus '%s' and target '%s'"),
|
|
|
|
virDomainDiskBusTypeToString(newdisk->bus),
|
|
|
|
newdisk->dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemudExtractVersionInfo(vm->def->emulator,
|
|
|
|
NULL,
|
|
|
|
&qemuCmdFlags) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-09-03 16:05:25 +00:00
|
|
|
_("Cannot determine QEMU argv syntax %s"),
|
|
|
|
vm->def->emulator);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
|
2008-12-04 21:04:30 +00:00
|
|
|
if (!(devname = qemudDiskDeviceName(conn, newdisk)))
|
2008-09-03 16:05:25 +00:00
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
/* Back compat for no -drive option */
|
|
|
|
if (newdisk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
|
|
|
devname = strdup(newdisk->dst);
|
|
|
|
else if (newdisk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
|
|
|
|
STREQ(newdisk->dst, "hdc"))
|
|
|
|
devname = strdup("cdrom");
|
|
|
|
else {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-09-03 16:05:25 +00:00
|
|
|
_("Emulator version does not support removable "
|
|
|
|
"media for device '%s' and target '%s'"),
|
|
|
|
virDomainDiskDeviceTypeToString(newdisk->device),
|
|
|
|
newdisk->dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!devname) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-09-03 16:05:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2007-10-27 01:21:09 +00:00
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (newdisk->src) {
|
2008-03-13 09:17:45 +00:00
|
|
|
safe_path = qemudEscapeMonitorArg(newdisk->src);
|
|
|
|
if (!safe_path) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-09-03 16:05:25 +00:00
|
|
|
VIR_FREE(devname);
|
2008-03-13 09:17:45 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&cmd, "change %s \"%s\"", devname, safe_path) == -1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(safe_path);
|
2008-09-03 16:05:25 +00:00
|
|
|
VIR_FREE(devname);
|
2008-03-13 09:17:45 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(safe_path);
|
2008-03-13 09:17:45 +00:00
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
} else if (virAsprintf(&cmd, "eject %s", devname) == -1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-09-03 16:05:25 +00:00
|
|
|
VIR_FREE(devname);
|
2007-10-27 01:21:09 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-09-03 16:05:25 +00:00
|
|
|
VIR_FREE(devname);
|
2007-10-27 01:21:09 +00:00
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-12-16 22:34:13 +00:00
|
|
|
"%s", _("could not change cdrom media"));
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(cmd);
|
2007-10-27 01:21:09 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-09-03 14:43:34 +00:00
|
|
|
|
|
|
|
/* If the command failed qemu prints:
|
|
|
|
* device not found, device is locked ...
|
|
|
|
* No message is printed on success it seems */
|
2008-09-03 16:05:25 +00:00
|
|
|
DEBUG ("ejectable media change reply: %s", reply);
|
2008-09-03 14:43:34 +00:00
|
|
|
if (strstr(reply, "\ndevice ")) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-12-16 22:34:13 +00:00
|
|
|
_("changing cdrom media failed: %s"), reply);
|
2008-09-03 14:43:34 +00:00
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
2008-09-03 12:52:27 +00:00
|
|
|
|
2008-09-03 16:05:25 +00:00
|
|
|
VIR_FREE(origdisk->src);
|
|
|
|
origdisk->src = newdisk->src;
|
2008-09-03 12:52:27 +00:00
|
|
|
newdisk->src = NULL;
|
2008-09-03 16:05:25 +00:00
|
|
|
origdisk->type = newdisk->type;
|
2007-10-27 01:21:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDeviceDefPtr dev)
|
2008-10-17 12:36:39 +00:00
|
|
|
{
|
|
|
|
int ret, i;
|
2008-10-29 14:32:40 +00:00
|
|
|
char *cmd, *reply, *s;
|
2008-10-17 12:36:39 +00:00
|
|
|
char *safe_path;
|
|
|
|
const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
|
|
|
|
|
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
|
|
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-17 12:36:39 +00:00
|
|
|
_("target %s already exists"), dev->data.disk->dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-10-17 12:36:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
safe_path = qemudEscapeMonitorArg(dev->data.disk->src);
|
|
|
|
if (!safe_path) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-17 12:36:39 +00:00
|
|
|
"%s", _("out of memory"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&cmd, "pci_add 0 storage file=%s,if=%s",
|
|
|
|
safe_path, type);
|
2008-10-17 12:36:39 +00:00
|
|
|
VIR_FREE(safe_path);
|
|
|
|
if (ret == -1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-10-17 12:36:39 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-17 12:36:39 +00:00
|
|
|
_("cannot attach %s disk"), type);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG ("pci_add reply: %s", reply);
|
|
|
|
/* If the command succeeds qemu prints:
|
|
|
|
* OK bus 0... */
|
2008-10-29 14:32:40 +00:00
|
|
|
#define PCI_ATTACH_OK_MSG "OK bus 0, slot "
|
|
|
|
if ((s=strstr(reply, PCI_ATTACH_OK_MSG))) {
|
|
|
|
char* dummy = s;
|
|
|
|
s += strlen(PCI_ATTACH_OK_MSG);
|
|
|
|
|
|
|
|
if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
|
2008-11-14 14:19:37 +00:00
|
|
|
qemudLog(QEMUD_WARN, "%s", _("Unable to parse slot number\n"));
|
2008-10-29 14:32:40 +00:00
|
|
|
} else {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-17 12:36:39 +00:00
|
|
|
_("adding %s disk failed"), type);
|
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
vm->def->disks[vm->def->ndisks++] = dev->data.disk;
|
|
|
|
qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
|
|
|
|
virDomainDiskQSort);
|
|
|
|
|
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return 0;
|
|
|
|
}
|
2007-10-27 01:21:09 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDeviceDefPtr dev)
|
2008-08-08 15:03:00 +00:00
|
|
|
{
|
2008-10-21 13:09:23 +00:00
|
|
|
int ret, i;
|
|
|
|
char *safe_path;
|
2008-08-08 15:03:00 +00:00
|
|
|
char *cmd, *reply;
|
|
|
|
|
2008-10-21 13:09:23 +00:00
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
|
|
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-21 13:09:23 +00:00
|
|
|
_("target %s already exists"), dev->data.disk->dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-10-10 16:08:01 +00:00
|
|
|
return -1;
|
2008-09-03 15:05:31 +00:00
|
|
|
}
|
|
|
|
|
2008-10-21 13:09:23 +00:00
|
|
|
safe_path = qemudEscapeMonitorArg(dev->data.disk->src);
|
|
|
|
if (!safe_path) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-21 13:09:23 +00:00
|
|
|
"%s", _("out of memory"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&cmd, "usb_add disk:%s", safe_path);
|
2008-10-21 13:09:23 +00:00
|
|
|
VIR_FREE(safe_path);
|
2008-08-08 15:03:00 +00:00
|
|
|
if (ret == -1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-08-08 15:03:00 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-09-03 15:05:31 +00:00
|
|
|
"%s", _("cannot attach usb disk"));
|
2008-08-08 15:03:00 +00:00
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG ("attach_usb reply: %s", reply);
|
|
|
|
/* If the command failed qemu prints:
|
|
|
|
* Could not add ... */
|
|
|
|
if (strstr(reply, "Could not add ")) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-08-08 15:03:00 +00:00
|
|
|
"%s",
|
2008-09-03 15:05:31 +00:00
|
|
|
_("adding usb disk failed"));
|
2008-08-08 15:03:00 +00:00
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-03 15:05:31 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
vm->def->disks[vm->def->ndisks++] = dev->data.disk;
|
|
|
|
qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
|
|
|
|
virDomainDiskQSort);
|
2008-09-03 15:05:31 +00:00
|
|
|
|
2008-08-08 15:03:00 +00:00
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDeviceDefPtr dev)
|
2008-08-08 14:27:05 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
char *cmd, *reply;
|
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-10-10 16:08:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-08-08 14:27:05 +00:00
|
|
|
|
2008-12-17 18:12:07 +00:00
|
|
|
if (dev->data.hostdev->source.subsys.u.usb.vendor) {
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&cmd, "usb_add host:%.4x:%.4x",
|
|
|
|
dev->data.hostdev->source.subsys.u.usb.vendor,
|
|
|
|
dev->data.hostdev->source.subsys.u.usb.product);
|
2008-08-08 14:27:05 +00:00
|
|
|
} else {
|
2008-12-23 13:03:29 +00:00
|
|
|
ret = virAsprintf(&cmd, "usb_add host:%.3d.%.3d",
|
|
|
|
dev->data.hostdev->source.subsys.u.usb.bus,
|
|
|
|
dev->data.hostdev->source.subsys.u.usb.device);
|
2008-08-08 14:27:05 +00:00
|
|
|
}
|
|
|
|
if (ret == -1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
2008-08-08 14:27:05 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-08-08 14:27:05 +00:00
|
|
|
"%s", _("cannot attach usb device"));
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG ("attach_usb reply: %s", reply);
|
|
|
|
/* If the command failed qemu prints:
|
|
|
|
* Could not add ... */
|
|
|
|
if (strstr(reply, "Could not add ")) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-08-08 14:27:05 +00:00
|
|
|
"%s",
|
|
|
|
_("adding usb device failed"));
|
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-03 15:05:31 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
vm->def->hostdevs[vm->def->nhostdevs++] = dev->data.hostdev;
|
2008-09-03 15:05:31 +00:00
|
|
|
|
2008-08-08 14:27:05 +00:00
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
2007-10-27 01:21:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-08 14:27:05 +00:00
|
|
|
static int qemudDomainAttachDevice(virDomainPtr dom,
|
|
|
|
const char *xml) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
|
|
|
int ret = -1;
|
2008-08-08 14:27:05 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-08-08 14:27:05 +00:00
|
|
|
if (!vm) {
|
2008-12-04 22:19:30 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-08-08 14:27:05 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-08-08 14:27:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainIsActive(vm)) {
|
2008-12-04 22:19:30 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-08-08 14:27:05 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cannot attach device on inactive domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-08-08 14:27:05 +00:00
|
|
|
}
|
|
|
|
|
2009-01-08 13:54:20 +00:00
|
|
|
dev = virDomainDeviceDefParse(dom->conn, driver->caps, vm->def, xml,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE);
|
2008-12-04 22:19:30 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
if (dev == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2008-08-08 14:27:05 +00:00
|
|
|
|
2008-10-17 12:36:39 +00:00
|
|
|
if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
|
|
|
|
switch (dev->data.disk->device) {
|
2008-12-04 21:04:30 +00:00
|
|
|
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
|
|
|
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
2008-12-04 22:19:30 +00:00
|
|
|
ret = qemudDomainChangeEjectableMedia(dom->conn, vm, dev);
|
2008-12-04 21:04:30 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
|
|
|
if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
2008-12-04 22:19:30 +00:00
|
|
|
ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, vm, dev);
|
2008-12-04 21:04:30 +00:00
|
|
|
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
|
|
|
|
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
2008-12-04 22:19:30 +00:00
|
|
|
ret = qemudDomainAttachPciDiskDevice(dom->conn, vm, dev);
|
2008-12-04 21:04:30 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("this disk device type cannot be attached"));
|
|
|
|
goto cleanup;
|
2008-10-17 12:36:39 +00:00
|
|
|
}
|
2008-08-08 14:27:05 +00:00
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
|
2008-12-04 21:04:30 +00:00
|
|
|
dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
|
|
|
|
dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
|
2008-12-04 22:19:30 +00:00
|
|
|
ret = qemudDomainAttachHostDevice(dom->conn, vm, dev);
|
2008-12-04 21:04:30 +00:00
|
|
|
} else {
|
2008-08-08 14:27:05 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
2008-09-03 15:05:31 +00:00
|
|
|
"%s", _("this device type cannot be attached"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-08-08 14:27:05 +00:00
|
|
|
}
|
|
|
|
|
2008-12-20 13:17:49 +00:00
|
|
|
qemudSaveDomainStatus(dom->conn, driver, vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-18 16:49:49 +00:00
|
|
|
if (ret < 0)
|
|
|
|
virDomainDeviceDefFree(dev);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-08-08 14:27:05 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm, virDomainDeviceDefPtr dev)
|
2008-10-29 14:32:40 +00:00
|
|
|
{
|
|
|
|
int i, ret = -1;
|
2008-12-04 21:04:30 +00:00
|
|
|
char *cmd = NULL;
|
|
|
|
char *reply = NULL;
|
2008-10-29 14:32:40 +00:00
|
|
|
virDomainDiskDefPtr detach = NULL;
|
|
|
|
|
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
|
|
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
|
|
|
|
detach = vm->def->disks[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!detach) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-29 14:32:40 +00:00
|
|
|
_("disk %s not found"), dev->data.disk->dst);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (detach->slotnum < 1) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-11-03 15:52:55 +00:00
|
|
|
_("disk %s cannot be detached - invalid slot number %d"),
|
2008-10-29 14:32:40 +00:00
|
|
|
detach->dst, detach->slotnum);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-10-29 14:32:40 +00:00
|
|
|
_("failed to execute detach disk %s command"), detach->dst);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG ("pci_del reply: %s", reply);
|
|
|
|
/* If the command fails due to a wrong slot qemu prints: invalid slot,
|
|
|
|
* nothing is printed on success */
|
|
|
|
if (strstr(reply, "invalid slot")) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-11-03 15:52:55 +00:00
|
|
|
_("failed to detach disk %s: invalid slot %d"),
|
2008-12-04 21:04:30 +00:00
|
|
|
detach->dst, detach->slotnum);
|
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (vm->def->ndisks > 1) {
|
|
|
|
vm->def->disks[i] = vm->def->disks[--vm->def->ndisks];
|
|
|
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
|
2008-12-04 21:04:30 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
|
|
|
|
virDomainDiskQSort);
|
|
|
|
} else {
|
|
|
|
VIR_FREE(vm->def->disks[0]);
|
|
|
|
vm->def->ndisks = 0;
|
|
|
|
}
|
|
|
|
ret = 0;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-10-29 14:32:40 +00:00
|
|
|
VIR_FREE(reply);
|
|
|
|
VIR_FREE(cmd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int qemudDomainDetachDevice(virDomainPtr dom,
|
|
|
|
const char *xml) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
|
|
|
int ret = -1;
|
2008-10-29 14:32:40 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-10-29 14:32:40 +00:00
|
|
|
if (!vm) {
|
2008-12-04 22:19:30 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-10-29 14:32:40 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainIsActive(vm)) {
|
2008-12-04 22:19:30 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-10-29 14:32:40 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
2009-01-06 17:20:27 +00:00
|
|
|
"%s", _("cannot detach device on inactive domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-10-29 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
2009-01-08 13:54:20 +00:00
|
|
|
dev = virDomainDeviceDefParse(dom->conn, driver->caps, vm->def, xml,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE);
|
2008-12-04 22:19:30 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
if (dev == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2008-10-29 14:32:40 +00:00
|
|
|
|
|
|
|
if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
|
|
|
|
dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
|
|
|
|
(dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
|
|
|
|
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO))
|
2008-12-04 22:19:30 +00:00
|
|
|
ret = qemudDomainDetachPciDiskDevice(dom->conn, vm, dev);
|
2008-12-04 21:04:30 +00:00
|
|
|
else
|
2008-10-29 14:32:40 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("only SCSI or virtio disk device can be detached dynamically"));
|
|
|
|
|
2008-12-20 13:17:49 +00:00
|
|
|
qemudSaveDomainStatus(dom->conn, driver, vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
|
|
|
virDomainDeviceDefFree(dev);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-10-29 14:32:40 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainGetAutostart(virDomainPtr dom,
|
2008-12-04 21:06:41 +00:00
|
|
|
int *autostart) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
2007-02-23 09:03:25 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-02-23 09:03:25 +00:00
|
|
|
if (!vm) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 09:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*autostart = vm->autostart;
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
2007-02-23 09:03:25 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2007-02-23 09:03:25 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
static int qemudDomainSetAutostart(virDomainPtr dom,
|
2008-08-20 19:42:36 +00:00
|
|
|
int autostart) {
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-08-20 19:42:36 +00:00
|
|
|
char *configFile = NULL, *autostartLink = NULL;
|
|
|
|
int ret = -1;
|
2007-02-23 09:03:25 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-02-23 09:03:25 +00:00
|
|
|
if (!vm) {
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-02-23 09:03:25 +00:00
|
|
|
}
|
|
|
|
|
2008-08-20 19:42:36 +00:00
|
|
|
if (!vm->persistent) {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cannot set autostart for transient domain"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-08-20 19:42:36 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 09:03:25 +00:00
|
|
|
autostart = (autostart != 0);
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (vm->autostart != autostart) {
|
|
|
|
if ((configFile = virDomainConfigFile(dom->conn, driver->configDir, vm->def->name)) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
if ((autostartLink = virDomainConfigFile(dom->conn, driver->autostartDir, vm->def->name)) == NULL)
|
|
|
|
goto cleanup;
|
2007-02-23 09:03:25 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (autostart) {
|
|
|
|
int err;
|
2008-08-20 19:42:36 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if ((err = virFileMakePath(driver->autostartDir))) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(dom->conn, err,
|
|
|
|
_("cannot create autostart directory %s"),
|
|
|
|
driver->autostartDir);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2007-02-23 09:07:41 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (symlink(configFile, autostartLink) < 0) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(dom->conn, errno,
|
|
|
|
_("Failed to create symlink '%s to '%s'"),
|
|
|
|
autostartLink, configFile);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
|
2009-01-20 17:13:33 +00:00
|
|
|
virReportSystemError(dom->conn, errno,
|
|
|
|
_("Failed to delete symlink '%s'"),
|
|
|
|
autostartLink);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2007-02-23 09:07:41 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
vm->autostart = autostart;
|
2007-02-23 09:07:41 +00:00
|
|
|
}
|
2008-08-20 19:42:36 +00:00
|
|
|
ret = 0;
|
2007-02-23 09:03:25 +00:00
|
|
|
|
2008-08-20 19:42:36 +00:00
|
|
|
cleanup:
|
|
|
|
VIR_FREE(configFile);
|
|
|
|
VIR_FREE(autostartLink);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-08-20 19:42:36 +00:00
|
|
|
return ret;
|
2007-02-23 09:03:25 +00:00
|
|
|
}
|
|
|
|
|
2008-02-26 18:41:43 +00:00
|
|
|
/* This uses the 'info blockstats' monitor command which was
|
|
|
|
* integrated into both qemu & kvm in late 2007. If the command is
|
|
|
|
* not supported we detect this and return the appropriate error.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudDomainBlockStats (virDomainPtr dom,
|
|
|
|
const char *path,
|
|
|
|
struct _virDomainBlockStats *stats)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
2008-10-17 09:29:29 +00:00
|
|
|
char *dummy, *info = NULL;
|
2008-02-26 18:41:43 +00:00
|
|
|
const char *p, *eol;
|
2008-10-17 09:29:29 +00:00
|
|
|
const char *qemu_dev_name = NULL;
|
2008-02-26 18:41:43 +00:00
|
|
|
size_t len;
|
2008-10-17 09:29:29 +00:00
|
|
|
int i, ret = -1;
|
2008-12-04 21:04:30 +00:00
|
|
|
virDomainObjPtr vm;
|
2008-10-17 09:29:29 +00:00
|
|
|
virDomainDiskDefPtr disk = NULL;
|
2008-02-26 18:41:43 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-02-26 18:41:43 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive (vm)) {
|
2008-02-26 18:41:43 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
|
|
|
|
2008-10-17 09:29:29 +00:00
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
|
|
if (STREQ(path, vm->def->disks[i]->dst)) {
|
|
|
|
disk = vm->def->disks[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!disk) {
|
2008-02-26 18:41:43 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("invalid path: %s"), path);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
qemu_dev_name = qemudDiskDeviceName(dom->conn, disk);
|
2008-10-17 09:29:29 +00:00
|
|
|
if (!qemu_dev_name)
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
len = strlen (qemu_dev_name);
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand (vm, "info blockstats", &info) < 0) {
|
2008-02-26 18:41:43 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("'info blockstats' command failed"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
|
|
|
DEBUG ("info blockstats reply: %s", info);
|
|
|
|
|
|
|
|
/* If the command isn't supported then qemu prints the supported
|
|
|
|
* info commands, so the output starts "info ". Since this is
|
|
|
|
* unlikely to be the name of a block device, we can use this
|
|
|
|
* to detect if qemu supports the command.
|
|
|
|
*/
|
2008-12-16 22:34:13 +00:00
|
|
|
if (strstr(info, "\ninfo ")) {
|
2008-02-26 18:41:43 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s",
|
|
|
|
_("'info blockstats' not supported by this qemu"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stats->rd_req = -1;
|
|
|
|
stats->rd_bytes = -1;
|
|
|
|
stats->wr_req = -1;
|
|
|
|
stats->wr_bytes = -1;
|
|
|
|
stats->errs = -1;
|
|
|
|
|
|
|
|
/* The output format for both qemu & KVM is:
|
|
|
|
* blockdevice: rd_bytes=% wr_bytes=% rd_operations=% wr_operations=%
|
|
|
|
* (repeated for each block device)
|
|
|
|
* where '%' is a 64 bit number.
|
|
|
|
*/
|
|
|
|
p = info;
|
|
|
|
|
|
|
|
while (*p) {
|
|
|
|
if (STREQLEN (p, qemu_dev_name, len)
|
|
|
|
&& p[len] == ':' && p[len+1] == ' ') {
|
|
|
|
|
|
|
|
eol = strchr (p, '\n');
|
|
|
|
if (!eol)
|
|
|
|
eol = p + strlen (p);
|
|
|
|
|
|
|
|
p += len+2; /* Skip to first label. */
|
|
|
|
|
|
|
|
while (*p) {
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX (p, "rd_bytes=")) {
|
2008-02-26 18:41:43 +00:00
|
|
|
p += 9;
|
|
|
|
if (virStrToLong_ll (p, &dummy, 10, &stats->rd_bytes) == -1)
|
|
|
|
DEBUG ("error reading rd_bytes: %s", p);
|
2008-05-15 14:21:34 +00:00
|
|
|
} else if (STRPREFIX (p, "wr_bytes=")) {
|
2008-02-26 18:41:43 +00:00
|
|
|
p += 9;
|
|
|
|
if (virStrToLong_ll (p, &dummy, 10, &stats->wr_bytes) == -1)
|
|
|
|
DEBUG ("error reading wr_bytes: %s", p);
|
2008-05-15 14:21:34 +00:00
|
|
|
} else if (STRPREFIX (p, "rd_operations=")) {
|
2008-02-26 18:41:43 +00:00
|
|
|
p += 14;
|
|
|
|
if (virStrToLong_ll (p, &dummy, 10, &stats->rd_req) == -1)
|
|
|
|
DEBUG ("error reading rd_req: %s", p);
|
2008-05-15 14:21:34 +00:00
|
|
|
} else if (STRPREFIX (p, "wr_operations=")) {
|
2008-02-26 18:41:43 +00:00
|
|
|
p += 14;
|
|
|
|
if (virStrToLong_ll (p, &dummy, 10, &stats->wr_req) == -1)
|
|
|
|
DEBUG ("error reading wr_req: %s", p);
|
|
|
|
} else
|
|
|
|
DEBUG ("unknown block stat near %s", p);
|
|
|
|
|
|
|
|
/* Skip to next label. */
|
|
|
|
p = strchr (p, ' ');
|
|
|
|
if (!p || p >= eol) break;
|
|
|
|
p++;
|
|
|
|
}
|
2008-10-17 09:29:29 +00:00
|
|
|
ret = 0;
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Skip to next line. */
|
|
|
|
p = strchr (p, '\n');
|
|
|
|
if (!p) break;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we reach here then the device was not found. */
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("device not found: %s (%s)"), path, qemu_dev_name);
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-10-17 09:29:29 +00:00
|
|
|
VIR_FREE(qemu_dev_name);
|
|
|
|
VIR_FREE(info);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-10-17 09:29:29 +00:00
|
|
|
return ret;
|
2008-02-26 18:41:43 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
#ifdef __linux__
|
2007-11-15 17:45:44 +00:00
|
|
|
static int
|
|
|
|
qemudDomainInterfaceStats (virDomainPtr dom,
|
|
|
|
const char *path,
|
|
|
|
struct _virDomainInterfaceStats *stats)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-10-10 16:08:01 +00:00
|
|
|
int i;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;
|
2007-11-15 17:45:44 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2007-11-15 17:45:44 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
2008-03-24 10:51:47 +00:00
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-11-15 17:45:44 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
2007-11-15 17:45:44 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-11-15 17:45:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!path || path[0] == '\0') {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
Mark many more strings for translation.
* Makefile.maint (err_func_re): Add to the list and make it readable.
* po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort.
* src/storage_backend.c: Fix comment.
* src/util.c (virFileLinkPointsTo): Mark a string.
* qemud/remote.c (remoteDispatchClientRequest): Mark strings.
(remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise.
(remoteDispatchDomainGetSchedulerType): Likewise.
(remoteDispatchDomainGetSchedulerParameters): Likewise.
(remoteDispatchDomainSetSchedulerParameters): Likewise.
(remoteDispatchDomainBlockStats): Likewise.
(remoteDispatchDomainInterfaceStats): Likewise.
(remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate):
(remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice):
(remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart):
(remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory):
(remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType):
(remoteDispatchDomainGetVcpus): Likewise.
(remoteDispatchDomainMigratePerform): Likewise.
(remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu):
(remoteDispatchDomainReboot, remoteDispatchDomainResume):
(remoteDispatchDomainSave, remoteDispatchDomainCoreDump):
(remoteDispatchDomainSetAutostart): Likewise.
(remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory):
(remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown):
(remoteDispatchDomainSuspend, remoteDispatchDomainUndefine):
(remoteDispatchListDefinedNetworks, remoteDispatchListDomains):
(remoteDispatchListNetworks, remoteDispatchNetworkCreate):
(remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml):
(remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName):
(remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine):
(addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools):
(remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate):
(remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy):
(remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh):
(remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml):
(remoteDispatchStoragePoolGetAutostart): Likewise.
(remoteDispatchStoragePoolSetAutostart):
(remoteDispatchStoragePoolListVolumes):
(remoteDispatchStoragePoolNumOfVolumes):
(remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml):
(remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo):
(remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath):
(remoteDispatchStorageVolLookupByName): Likewise.
* src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon):
(dhcpStartDhcpDaemon, qemudStartNetworkDaemon):
(qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown):
(qemudDomainGetOSType, qemudDomainSetMaxMemory):
(qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave):
(qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart):
(qemudDomainUndefine, qemudDomainChangeCDROM):
(qemudDomainAttachDevice, qemudDomainGetAutostart):
(qemudDomainSetAutostart, qemudDomainInterfaceStats):
(qemudNetworkLookupByUUID, qemudNetworkLookupByName):
(qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy):
(qemudNetworkDumpXML, qemudNetworkGetAutostart):
(qemudNetworkSetAutostart): Likewise.
* src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise.
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
|
|
|
"%s", _("NULL or empty path"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2007-11-15 17:45:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the path is one of the domain's network interfaces. */
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < vm->def->nnets ; i++) {
|
|
|
|
if (vm->def->nets[i]->ifname &&
|
2008-12-04 21:04:30 +00:00
|
|
|
STREQ (vm->def->nets[i]->ifname, path)) {
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
2007-11-15 17:45:44 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (ret == 0)
|
|
|
|
ret = linuxDomainInterfaceStats (dom->conn, path, stats);
|
|
|
|
else
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("invalid path, '%s' is not a known interface"), path);
|
2007-11-15 17:45:44 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2007-11-15 17:45:44 +00:00
|
|
|
#else
|
2008-12-04 21:04:30 +00:00
|
|
|
static int
|
|
|
|
qemudDomainInterfaceStats (virDomainPtr dom,
|
|
|
|
const char *path ATTRIBUTE_UNUSED,
|
|
|
|
struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
|
2007-11-15 17:45:44 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", __FUNCTION__);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
#endif
|
2007-11-15 17:45:44 +00:00
|
|
|
|
2008-06-05 21:12:26 +00:00
|
|
|
static int
|
|
|
|
qemudDomainBlockPeek (virDomainPtr dom,
|
|
|
|
const char *path,
|
|
|
|
unsigned long long offset, size_t size,
|
|
|
|
void *buffer,
|
|
|
|
unsigned int flags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int fd = -1, ret = -1, i;
|
2008-06-05 21:12:26 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
|
2008-06-05 21:12:26 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("no domain with matching uuid"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!path || path[0] == '\0') {
|
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("NULL or empty path"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the path belongs to this domain. */
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
|
|
if (vm->def->disks[i]->src != NULL &&
|
2008-12-04 21:04:30 +00:00
|
|
|
STREQ (vm->def->disks[i]->src, path)) {
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
if (ret == 0) {
|
|
|
|
ret = -1;
|
|
|
|
/* The path is correct, now try to open it and get its size. */
|
|
|
|
fd = open (path, O_RDONLY);
|
|
|
|
if (fd == -1) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-06-05 21:12:26 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
/* Seek and read. */
|
|
|
|
/* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
|
|
|
|
* be 64 bits on all platforms.
|
|
|
|
*/
|
|
|
|
if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
|
|
|
|
saferead (fd, buffer, size) == (ssize_t) -1) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
} else {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("invalid path"));
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
|
|
|
if (fd >= 0)
|
|
|
|
close (fd);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-06-05 21:12:26 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-06-10 10:43:28 +00:00
|
|
|
static int
|
|
|
|
qemudDomainMemoryPeek (virDomainPtr dom,
|
|
|
|
unsigned long long offset, size_t size,
|
|
|
|
void *buffer,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char cmd[256], *info = NULL;
|
2008-06-10 10:43:28 +00:00
|
|
|
char tmp[] = TEMPDIR "/qemu.mem.XXXXXX";
|
|
|
|
int fd = -1, ret = -1;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-06-10 10:43:28 +00:00
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags != VIR_MEMORY_VIRTUAL) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("QEMU driver only supports virtual memory addrs"));
|
|
|
|
goto cleanup;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 19:34:11 +00:00
|
|
|
if (!virDomainIsActive(vm)) {
|
2008-06-10 10:43:28 +00:00
|
|
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a temporary filename. */
|
|
|
|
if ((fd = mkstemp (tmp)) == -1) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Issue the memsave command. */
|
|
|
|
snprintf (cmd, sizeof cmd, "memsave %llu %zi \"%s\"", offset, size, tmp);
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand (vm, cmd, &info) < 0) {
|
2008-06-10 10:43:28 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
2008-09-04 13:20:28 +00:00
|
|
|
"%s", _("'memsave' command failed"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG ("memsave reply: %s", info);
|
|
|
|
|
|
|
|
/* Read the memory file into buffer. */
|
|
|
|
if (saferead (fd, buffer, size) == (ssize_t) -1) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(info);
|
2008-06-10 10:43:28 +00:00
|
|
|
if (fd >= 0) close (fd);
|
|
|
|
unlink (tmp);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-06-10 10:43:28 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-02-23 09:03:25 +00:00
|
|
|
|
2008-10-23 13:18:18 +00:00
|
|
|
static int
|
|
|
|
qemudDomainEventRegister (virConnectPtr conn,
|
2008-12-17 21:48:20 +00:00
|
|
|
virConnectDomainEventCallback callback,
|
2008-11-19 15:25:24 +00:00
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
2008-10-23 13:18:18 +00:00
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
int ret;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
|
|
|
|
callback, opaque, freecb);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
qemudDomainEventDeregister (virConnectPtr conn,
|
2008-12-17 21:48:20 +00:00
|
|
|
virConnectDomainEventCallback callback)
|
2008-10-23 13:18:18 +00:00
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = conn->privateData;
|
|
|
|
int ret;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (driver->domainEventDispatching)
|
|
|
|
ret = virDomainEventCallbackListMarkDelete(conn, driver->domainEventCallbacks,
|
|
|
|
callback);
|
|
|
|
else
|
|
|
|
ret = virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
|
|
|
|
callback);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
static void qemuDomainEventDispatchFunc(virConnectPtr conn,
|
|
|
|
virDomainEventPtr event,
|
|
|
|
virConnectDomainEventCallback cb,
|
|
|
|
void *cbopaque,
|
|
|
|
void *opaque)
|
2008-10-23 13:18:18 +00:00
|
|
|
{
|
2008-12-04 21:09:20 +00:00
|
|
|
struct qemud_driver *driver = opaque;
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
/* Drop the lock whle dispatching, for sake of re-entrancy */
|
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
|
|
|
|
qemuDriverLock(driver);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qemuDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
|
|
|
|
{
|
|
|
|
struct qemud_driver *driver = opaque;
|
|
|
|
virDomainEventQueue tempQueue;
|
|
|
|
|
|
|
|
qemuDriverLock(driver);
|
|
|
|
|
|
|
|
driver->domainEventDispatching = 1;
|
|
|
|
|
|
|
|
/* Copy the queue, so we're reentrant safe */
|
|
|
|
tempQueue.count = driver->domainEventQueue->count;
|
|
|
|
tempQueue.events = driver->domainEventQueue->events;
|
|
|
|
driver->domainEventQueue->count = 0;
|
|
|
|
driver->domainEventQueue->events = NULL;
|
|
|
|
|
|
|
|
virEventUpdateTimeout(driver->domainEventTimer, -1);
|
|
|
|
virDomainEventQueueDispatch(&tempQueue,
|
|
|
|
driver->domainEventCallbacks,
|
|
|
|
qemuDomainEventDispatchFunc,
|
|
|
|
driver);
|
|
|
|
|
|
|
|
/* Purge any deleted callbacks */
|
|
|
|
virDomainEventCallbackListPurgeMarked(driver->domainEventCallbacks);
|
|
|
|
|
|
|
|
driver->domainEventDispatching = 0;
|
|
|
|
qemuDriverUnlock(driver);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* driver must be locked before calling */
|
|
|
|
static void qemuDomainEventQueue(struct qemud_driver *driver,
|
|
|
|
virDomainEventPtr event)
|
|
|
|
{
|
|
|
|
if (virDomainEventQueuePush(driver->domainEventQueue,
|
|
|
|
event) < 0)
|
|
|
|
virDomainEventFree(event);
|
|
|
|
if (qemu_driver->domainEventQueue->count == 1)
|
|
|
|
virEventUpdateTimeout(driver->domainEventTimer, 0);
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 08:42:47 +00:00
|
|
|
/* Migration support. */
|
|
|
|
|
|
|
|
/* Prepare is the first step, and it runs on the destination host.
|
|
|
|
*
|
|
|
|
* This starts an empty VM listening on a TCP port.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
qemudDomainMigratePrepare2 (virConnectPtr dconn,
|
|
|
|
char **cookie ATTRIBUTE_UNUSED,
|
|
|
|
int *cookielen ATTRIBUTE_UNUSED,
|
|
|
|
const char *uri_in,
|
|
|
|
char **uri_out,
|
|
|
|
unsigned long flags ATTRIBUTE_UNUSED,
|
|
|
|
const char *dname,
|
|
|
|
unsigned long resource ATTRIBUTE_UNUSED,
|
|
|
|
const char *dom_xml)
|
|
|
|
{
|
|
|
|
static int port = 0;
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dconn->privateData;
|
|
|
|
virDomainDefPtr def = NULL;
|
2008-11-14 08:42:47 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
|
|
|
int this_port;
|
|
|
|
char hostname [HOST_NAME_MAX+1];
|
|
|
|
char migrateFrom [64];
|
|
|
|
const char *p;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:04:30 +00:00
|
|
|
int ret = -1;;
|
|
|
|
|
|
|
|
*uri_out = NULL;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-11-14 08:42:47 +00:00
|
|
|
if (!dom_xml) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("no domain XML passed"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* The URI passed in may be NULL or a string "tcp://somehostname:port".
|
|
|
|
*
|
|
|
|
* If the URI passed in is NULL then we allocate a port number
|
|
|
|
* from our pool of port numbers and return a URI of
|
|
|
|
* "tcp://ourhostname:port".
|
|
|
|
*
|
|
|
|
* If the URI passed in is not NULL then we try to parse out the
|
|
|
|
* port number and use that (note that the hostname is assumed
|
|
|
|
* to be a correct hostname which refers to the target machine).
|
|
|
|
*/
|
|
|
|
if (uri_in == NULL) {
|
|
|
|
this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
|
|
|
|
if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0;
|
|
|
|
|
|
|
|
/* Get hostname */
|
|
|
|
if (gethostname (hostname, HOST_NAME_MAX+1) == -1) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Caller frees */
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(uri_out, "tcp:%s:%d", hostname, this_port) < 0) {
|
2008-11-14 08:42:47 +00:00
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", strerror (errno));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Check the URI starts with "tcp:". We will escape the
|
|
|
|
* URI when passing it to the qemu monitor, so bad
|
|
|
|
* characters in hostname part don't matter.
|
|
|
|
*/
|
|
|
|
if (!STREQLEN (uri_in, "tcp:", 6)) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("only tcp URIs are supported for KVM migrations"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the port number. */
|
|
|
|
p = strrchr (uri_in, ':');
|
|
|
|
p++; /* definitely has a ':' in it, see above */
|
|
|
|
this_port = virParseNumber (&p);
|
|
|
|
if (this_port == -1 || p-uri_in != strlen (uri_in)) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("URI did not have ':port' at the end"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse the domain XML. */
|
2009-01-08 13:54:20 +00:00
|
|
|
if (!(def = virDomainDefParseString(dconn, driver->caps, dom_xml,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE))) {
|
2008-11-14 08:42:47 +00:00
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("failed to parse XML"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Target domain name, maybe renamed. */
|
|
|
|
dname = dname ? dname : def->name;
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
/* Ensure the name and UUID don't already exist in an active VM */
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, def->uuid);
|
|
|
|
#else
|
|
|
|
/* For TESTING ONLY you can change #if 1 -> #if 0 above and use
|
|
|
|
* this code which lets you do localhost migrations. You must still
|
|
|
|
* supply a fresh 'dname' but this code assigns a random UUID.
|
|
|
|
*/
|
|
|
|
if (virUUIDGenerate (def->uuid) == -1) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("could not generate random UUID"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!vm) vm = virDomainFindByName(&driver->domains, dname);
|
|
|
|
if (vm) {
|
|
|
|
if (virDomainIsActive(vm)) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("domain with the same name or UUID already exists as '%s'"),
|
|
|
|
vm->def->name);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(vm = virDomainAssignDef(dconn,
|
|
|
|
&driver->domains,
|
|
|
|
def))) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("failed to assign new VM"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
def = NULL;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
|
|
|
/* Domain starts inactive, even if the domain XML had an id field. */
|
|
|
|
vm->def->id = -1;
|
|
|
|
|
|
|
|
/* Start the QEMU daemon, with the same command-line arguments plus
|
|
|
|
* -incoming tcp:0.0.0.0:port
|
|
|
|
*/
|
|
|
|
snprintf (migrateFrom, sizeof (migrateFrom), "tcp:0.0.0.0:%d", this_port);
|
|
|
|
if (qemudStartVMDaemon (dconn, driver, vm, migrateFrom) < 0) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("failed to start listening VM"));
|
2008-12-04 21:06:41 +00:00
|
|
|
if (!vm->persistent) {
|
2008-11-14 08:42:47 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
2008-12-04 21:09:20 +00:00
|
|
|
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_MIGRATED);
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
|
|
|
virDomainDefFree(def);
|
|
|
|
if (ret != 0) {
|
|
|
|
VIR_FREE(*uri_out);
|
|
|
|
}
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Perform is the second step, and it runs on the source host. */
|
|
|
|
static int
|
|
|
|
qemudDomainMigratePerform (virDomainPtr dom,
|
|
|
|
const char *cookie ATTRIBUTE_UNUSED,
|
|
|
|
int cookielen ATTRIBUTE_UNUSED,
|
|
|
|
const char *uri,
|
|
|
|
unsigned long flags ATTRIBUTE_UNUSED,
|
|
|
|
const char *dname ATTRIBUTE_UNUSED,
|
|
|
|
unsigned long resource)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-11-14 08:42:47 +00:00
|
|
|
char *safe_uri;
|
|
|
|
char cmd[HOST_NAME_MAX+50];
|
2008-12-04 21:04:30 +00:00
|
|
|
char *info = NULL;
|
|
|
|
int ret = -1;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, dom->id);
|
2008-11-14 08:42:47 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainIsActive(vm)) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("domain is not running"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
2008-11-17 16:43:00 +00:00
|
|
|
if (!(flags & VIR_MIGRATE_LIVE)) {
|
|
|
|
/* Pause domain for non-live migration */
|
|
|
|
snprintf(cmd, sizeof cmd, "%s", "stop");
|
2008-12-04 22:19:30 +00:00
|
|
|
qemudMonitorCommand (vm, cmd, &info);
|
2008-11-17 16:43:00 +00:00
|
|
|
DEBUG ("stop reply: %s", info);
|
|
|
|
VIR_FREE(info);
|
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
|
|
VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED);
|
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
|
|
|
event = NULL;
|
2008-11-17 16:43:00 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 08:42:47 +00:00
|
|
|
if (resource > 0) {
|
|
|
|
/* Issue migrate_set_speed command. Don't worry if it fails. */
|
|
|
|
snprintf (cmd, sizeof cmd, "migrate_set_speed %lum", resource);
|
2008-12-04 22:19:30 +00:00
|
|
|
qemudMonitorCommand (vm, cmd, &info);
|
2008-11-14 08:42:47 +00:00
|
|
|
|
|
|
|
DEBUG ("migrate_set_speed reply: %s", info);
|
|
|
|
VIR_FREE (info);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Issue the migrate command. */
|
|
|
|
safe_uri = qemudEscapeMonitorArg (uri);
|
|
|
|
if (!safe_uri) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
|
|
|
"%s", strerror (errno));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
snprintf (cmd, sizeof cmd, "migrate \"%s\"", safe_uri);
|
|
|
|
VIR_FREE (safe_uri);
|
|
|
|
|
2008-12-04 22:19:30 +00:00
|
|
|
if (qemudMonitorCommand (vm, cmd, &info) < 0) {
|
2008-11-14 08:42:47 +00:00
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("migrate operation failed"));
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG ("migrate reply: %s", info);
|
|
|
|
|
|
|
|
/* Now check for "fail" in the output string */
|
|
|
|
if (strstr(info, "fail") != NULL) {
|
|
|
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("migrate failed: %s"), info);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clean up the source domain. */
|
|
|
|
qemudShutdownVMDaemon (dom->conn, driver, vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (!vm->persistent) {
|
2008-11-14 08:42:47 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
ret = 0;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
2008-12-04 21:04:30 +00:00
|
|
|
cleanup:
|
|
|
|
VIR_FREE(info);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return ret;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Finish is the third and final step, and it runs on the destination host. */
|
|
|
|
static virDomainPtr
|
|
|
|
qemudDomainMigrateFinish2 (virConnectPtr dconn,
|
|
|
|
const char *dname,
|
|
|
|
const char *cookie ATTRIBUTE_UNUSED,
|
|
|
|
int cookielen ATTRIBUTE_UNUSED,
|
|
|
|
const char *uri ATTRIBUTE_UNUSED,
|
|
|
|
unsigned long flags ATTRIBUTE_UNUSED,
|
|
|
|
int retcode)
|
|
|
|
{
|
2008-12-04 21:04:30 +00:00
|
|
|
struct qemud_driver *driver = dconn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
2008-12-04 21:09:20 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-11-14 08:42:47 +00:00
|
|
|
char *info = NULL;
|
|
|
|
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverLock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
vm = virDomainFindByName(&driver->domains, dname);
|
2008-11-14 08:42:47 +00:00
|
|
|
if (!vm) {
|
|
|
|
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_DOMAIN,
|
|
|
|
_("no domain with matching name %s"), dname);
|
2008-12-04 21:04:30 +00:00
|
|
|
goto cleanup;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Did the migration go as planned? If yes, return the domain
|
|
|
|
* object, but if no, clean up the empty qemu process.
|
|
|
|
*/
|
|
|
|
if (retcode == 0) {
|
|
|
|
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
|
|
|
|
VIR_FREE(info);
|
|
|
|
vm->state = VIR_DOMAIN_RUNNING;
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_RESUMED,
|
|
|
|
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
2008-11-14 08:42:47 +00:00
|
|
|
} else {
|
|
|
|
qemudShutdownVMDaemon (dconn, driver, vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_FAILED);
|
2008-12-04 21:06:41 +00:00
|
|
|
if (!vm->persistent) {
|
2008-11-14 08:42:47 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
2008-12-04 21:06:41 +00:00
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
2008-12-04 21:04:30 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:06:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
qemuDomainEventQueue(driver, event);
|
2008-12-04 21:06:41 +00:00
|
|
|
qemuDriverUnlock(driver);
|
2008-12-04 21:04:30 +00:00
|
|
|
return dom;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
2007-06-26 22:39:53 +00:00
|
|
|
static virDriver qemuDriver = {
|
|
|
|
VIR_DRV_QEMU,
|
|
|
|
"QEMU",
|
|
|
|
qemudOpen, /* open */
|
|
|
|
qemudClose, /* close */
|
2008-11-14 08:42:47 +00:00
|
|
|
qemudSupportsFeature, /* supports_feature */
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudGetType, /* type */
|
|
|
|
qemudGetVersion, /* version */
|
2007-09-20 17:13:39 +00:00
|
|
|
qemudGetHostname, /* hostname */
|
2007-11-14 11:40:57 +00:00
|
|
|
NULL, /* URI */
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudGetMaxVCPUs, /* getMaxVcpus */
|
|
|
|
qemudGetNodeInfo, /* nodeGetInfo */
|
|
|
|
qemudGetCapabilities, /* getCapabilities */
|
|
|
|
qemudListDomains, /* listDomains */
|
|
|
|
qemudNumDomains, /* numOfDomains */
|
2008-10-10 09:32:27 +00:00
|
|
|
qemudDomainCreate, /* domainCreateXML */
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudDomainLookupByID, /* domainLookupByID */
|
|
|
|
qemudDomainLookupByUUID, /* domainLookupByUUID */
|
|
|
|
qemudDomainLookupByName, /* domainLookupByName */
|
|
|
|
qemudDomainSuspend, /* domainSuspend */
|
|
|
|
qemudDomainResume, /* domainResume */
|
2008-01-09 16:05:21 +00:00
|
|
|
qemudDomainShutdown, /* domainShutdown */
|
2007-06-26 22:39:53 +00:00
|
|
|
NULL, /* domainReboot */
|
|
|
|
qemudDomainDestroy, /* domainDestroy */
|
|
|
|
qemudDomainGetOSType, /* domainGetOSType */
|
2008-03-19 14:32:50 +00:00
|
|
|
qemudDomainGetMaxMemory, /* domainGetMaxMemory */
|
|
|
|
qemudDomainSetMaxMemory, /* domainSetMaxMemory */
|
|
|
|
qemudDomainSetMemory, /* domainSetMemory */
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudDomainGetInfo, /* domainGetInfo */
|
|
|
|
qemudDomainSave, /* domainSave */
|
|
|
|
qemudDomainRestore, /* domainRestore */
|
|
|
|
NULL, /* domainCoreDump */
|
2008-05-07 16:16:44 +00:00
|
|
|
qemudDomainSetVcpus, /* domainSetVcpus */
|
2008-05-22 16:20:31 +00:00
|
|
|
#if HAVE_SCHED_GETAFFINITY
|
|
|
|
qemudDomainPinVcpu, /* domainPinVcpu */
|
|
|
|
qemudDomainGetVcpus, /* domainGetVcpus */
|
|
|
|
#else
|
2007-06-26 22:39:53 +00:00
|
|
|
NULL, /* domainPinVcpu */
|
|
|
|
NULL, /* domainGetVcpus */
|
2008-05-22 16:20:31 +00:00
|
|
|
#endif
|
2008-05-07 16:16:44 +00:00
|
|
|
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudDomainDumpXML, /* domainDumpXML */
|
|
|
|
qemudListDefinedDomains, /* listDomains */
|
|
|
|
qemudNumDefinedDomains, /* numOfDomains */
|
|
|
|
qemudDomainStart, /* domainCreate */
|
|
|
|
qemudDomainDefine, /* domainDefineXML */
|
|
|
|
qemudDomainUndefine, /* domainUndefine */
|
2007-10-27 01:21:09 +00:00
|
|
|
qemudDomainAttachDevice, /* domainAttachDevice */
|
2008-10-29 14:32:40 +00:00
|
|
|
qemudDomainDetachDevice, /* domainDetachDevice */
|
2007-06-26 22:39:53 +00:00
|
|
|
qemudDomainGetAutostart, /* domainGetAutostart */
|
|
|
|
qemudDomainSetAutostart, /* domainSetAutostart */
|
|
|
|
NULL, /* domainGetSchedulerType */
|
|
|
|
NULL, /* domainGetSchedulerParameters */
|
|
|
|
NULL, /* domainSetSchedulerParameters */
|
2008-11-14 08:42:47 +00:00
|
|
|
NULL, /* domainMigratePrepare (v1) */
|
|
|
|
qemudDomainMigratePerform, /* domainMigratePerform */
|
2007-08-21 09:31:12 +00:00
|
|
|
NULL, /* domainMigrateFinish */
|
2008-02-26 18:41:43 +00:00
|
|
|
qemudDomainBlockStats, /* domainBlockStats */
|
2007-11-15 17:45:44 +00:00
|
|
|
qemudDomainInterfaceStats, /* domainInterfaceStats */
|
2008-06-05 21:12:26 +00:00
|
|
|
qemudDomainBlockPeek, /* domainBlockPeek */
|
2008-06-10 10:43:28 +00:00
|
|
|
qemudDomainMemoryPeek, /* domainMemoryPeek */
|
2008-05-22 15:29:50 +00:00
|
|
|
#if HAVE_NUMACTL
|
|
|
|
qemudNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
|
|
|
qemudNodeGetFreeMemory, /* getFreeMemory */
|
|
|
|
#else
|
2007-09-28 14:28:12 +00:00
|
|
|
NULL, /* nodeGetCellsFreeMemory */
|
2007-09-30 13:09:07 +00:00
|
|
|
NULL, /* getFreeMemory */
|
2008-05-22 15:29:50 +00:00
|
|
|
#endif
|
2008-10-23 13:18:18 +00:00
|
|
|
qemudDomainEventRegister, /* domainEventRegister */
|
|
|
|
qemudDomainEventDeregister, /* domainEventDeregister */
|
2008-11-14 08:42:47 +00:00
|
|
|
qemudDomainMigratePrepare2, /* domainMigratePrepare2 */
|
|
|
|
qemudDomainMigrateFinish2, /* domainMigrateFinish2 */
|
2007-06-26 22:39:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-06-26 22:56:14 +00:00
|
|
|
static virStateDriver qemuStateDriver = {
|
2008-10-06 15:40:37 +00:00
|
|
|
.initialize = qemudStartup,
|
|
|
|
.cleanup = qemudShutdown,
|
|
|
|
.reload = qemudReload,
|
|
|
|
.active = qemudActive,
|
2007-06-26 22:56:14 +00:00
|
|
|
};
|
2007-06-26 22:39:53 +00:00
|
|
|
|
2008-11-21 12:16:08 +00:00
|
|
|
int qemuRegister(void) {
|
2007-06-26 23:48:46 +00:00
|
|
|
virRegisterDriver(&qemuDriver);
|
|
|
|
virRegisterStateDriver(&qemuStateDriver);
|
|
|
|
return 0;
|
|
|
|
}
|