2007-02-14 01:40:09 +00:00
|
|
|
/*
|
|
|
|
* config.c: VM configuration management
|
|
|
|
*
|
2008-02-07 16:49:29 +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
|
|
|
|
|
|
|
#ifdef WITH_QEMU
|
2007-02-14 15:42:55 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
2007-02-23 17:15:18 +00:00
|
|
|
#include <sys/wait.h>
|
2007-04-10 23:17:46 +00:00
|
|
|
#include <arpa/inet.h>
|
2007-04-16 13:14:28 +00:00
|
|
|
#include <sys/utsname.h>
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
#include <libxml/parser.h>
|
|
|
|
#include <libxml/tree.h>
|
|
|
|
#include <libxml/xpath.h>
|
|
|
|
#include <libxml/uri.h>
|
|
|
|
|
2008-05-22 15:29:50 +00:00
|
|
|
#if HAVE_NUMACTL
|
|
|
|
#include <numa.h>
|
|
|
|
#endif
|
|
|
|
|
Standardize use of header files, making internal.h primary.
* qemud/internal.h, qemud/qemud.h: Rename this file so it
doesn't conflict with src/internal.h.
* HACKING: Document how header files should be used.
* qemud/Makefile.am: Add src/ directory to includes.
* qemud/event.c, qemud/mdns.c, qemud/qemud.c, qemud/remote.c,
qemud/remote_protocol.c, qemud/remote_protocol.h,
qemud/remote_protocol.x, src/buf.c, src/libvirt.c,
src/nodeinfo.c, src/qemu_conf.c, src/qemu_driver.c,
src/stats_linux.c, src/storage_backend.c, src/storage_backend_fs.c,
src/storage_backend_iscsi.c, src/storage_backend_logical.c,
src/storage_conf.c, src/storage_driver.c, src/util.c,
src/util.h, src/virsh.c, src/virterror.c, src/xend_internal.c,
src/xml.c, tests/reconnect.c, tests/xmlrpctest.c,
tests/qparamtest.c: Standardize use of header files.
* docs/*, po/*: Rebuild docs.
2008-05-23 08:24:41 +00:00
|
|
|
#include "internal.h"
|
2007-06-27 00:12:29 +00:00
|
|
|
#include "qemu_conf.h"
|
2007-02-26 15:32:27 +00:00
|
|
|
#include "uuid.h"
|
2007-06-27 00:12:29 +00:00
|
|
|
#include "buf.h"
|
2007-10-12 16:05:44 +00:00
|
|
|
#include "conf.h"
|
2007-12-03 14:30:46 +00:00
|
|
|
#include "util.h"
|
2008-05-22 15:29:50 +00:00
|
|
|
#include "memory.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 "verify.h"
|
|
|
|
#include "c-ctype.h"
|
2008-05-22 16:27:20 +00:00
|
|
|
#include "xml.h"
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2007-06-26 23:48:46 +00:00
|
|
|
#define qemudLog(level, msg...) fprintf(stderr, msg)
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
void qemudReportError(virConnectPtr conn,
|
|
|
|
virDomainPtr dom,
|
|
|
|
virNetworkPtr net,
|
|
|
|
int code, const char *fmt, ...) {
|
|
|
|
va_list args;
|
|
|
|
char errorMessage[QEMUD_MAX_ERROR_LEN];
|
2008-02-28 11:17:49 +00:00
|
|
|
const char *virerr;
|
2007-06-26 22:13:21 +00:00
|
|
|
|
|
|
|
if (fmt) {
|
|
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(errorMessage, QEMUD_MAX_ERROR_LEN-1, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
} else {
|
|
|
|
errorMessage[0] = '\0';
|
|
|
|
}
|
2008-02-28 11:17:49 +00:00
|
|
|
|
2008-03-03 18:11:16 +00:00
|
|
|
virerr = __virErrorMsg(code, (errorMessage[0] ? errorMessage : NULL));
|
2007-06-26 22:13:21 +00:00
|
|
|
__virRaiseError(conn, dom, net, VIR_FROM_QEMU, code, VIR_ERR_ERROR,
|
2008-02-28 11:17:49 +00:00
|
|
|
virerr, errorMessage, NULL, -1, -1, virerr, errorMessage);
|
2007-06-26 22:13:21 +00:00
|
|
|
}
|
|
|
|
|
2007-10-12 16:05:44 +00:00
|
|
|
int qemudLoadDriverConfig(struct qemud_driver *driver,
|
|
|
|
const char *filename) {
|
|
|
|
virConfPtr conf;
|
|
|
|
virConfValuePtr p;
|
|
|
|
|
|
|
|
/* Setup 2 critical defaults */
|
|
|
|
strcpy(driver->vncListen, "127.0.0.1");
|
|
|
|
if (!(driver->vncTLSx509certdir = strdup(SYSCONF_DIR "/pki/libvirt-vnc"))) {
|
|
|
|
qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY,
|
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
|
|
|
"%s", _("failed to allocate vncTLSx509certdir"));
|
2007-10-12 16:05:44 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Just check the file is readable before opening it, otherwise
|
|
|
|
* libvirt emits an error.
|
|
|
|
*/
|
|
|
|
if (access (filename, R_OK) == -1) return 0;
|
|
|
|
|
|
|
|
conf = virConfReadFile (filename);
|
|
|
|
if (!conf) return 0;
|
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) { \
|
|
|
|
qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, \
|
|
|
|
"remoteReadConfigFile: %s: %s: expected type " #typ "\n", \
|
|
|
|
filename, (name)); \
|
|
|
|
virConfFree(conf); \
|
|
|
|
return -1; \
|
|
|
|
}
|
|
|
|
|
|
|
|
p = virConfGetValue (conf, "vnc_tls");
|
|
|
|
CHECK_TYPE ("vnc_tls", VIR_CONF_LONG);
|
|
|
|
if (p) driver->vncTLS = p->l;
|
|
|
|
|
|
|
|
p = virConfGetValue (conf, "vnc_tls_x509_verify");
|
|
|
|
CHECK_TYPE ("vnc_tls_x509_verify", VIR_CONF_LONG);
|
|
|
|
if (p) driver->vncTLSx509verify = p->l;
|
|
|
|
|
|
|
|
p = virConfGetValue (conf, "vnc_tls_x509_cert_dir");
|
|
|
|
CHECK_TYPE ("vnc_tls_x509_cert_dir", VIR_CONF_STRING);
|
|
|
|
if (p && p->str) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(driver->vncTLSx509certdir);
|
2007-10-12 16:05:44 +00:00
|
|
|
if (!(driver->vncTLSx509certdir = strdup(p->str))) {
|
|
|
|
qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY,
|
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
|
|
|
"%s", _("failed to allocate vncTLSx509certdir"));
|
2007-10-12 16:05:44 +00:00
|
|
|
virConfFree(conf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p = virConfGetValue (conf, "vnc_listen");
|
|
|
|
CHECK_TYPE ("vnc_listen", VIR_CONF_STRING);
|
|
|
|
if (p && p->str) {
|
|
|
|
strncpy(driver->vncListen, p->str, sizeof(driver->vncListen));
|
|
|
|
driver->vncListen[sizeof(driver->vncListen)-1] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
virConfFree (conf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-26 22:42:47 +00:00
|
|
|
struct qemud_vm *qemudFindVMByID(const struct qemud_driver *driver, int id) {
|
|
|
|
struct qemud_vm *vm = driver->vms;
|
|
|
|
|
|
|
|
while (vm) {
|
|
|
|
if (qemudIsActiveVM(vm) && vm->id == id)
|
|
|
|
return vm;
|
|
|
|
vm = vm->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct qemud_vm *qemudFindVMByUUID(const struct qemud_driver *driver,
|
|
|
|
const unsigned char *uuid) {
|
|
|
|
struct qemud_vm *vm = driver->vms;
|
|
|
|
|
|
|
|
while (vm) {
|
2007-08-09 20:19:12 +00:00
|
|
|
if (!memcmp(vm->def->uuid, uuid, VIR_UUID_BUFLEN))
|
2007-06-26 22:42:47 +00:00
|
|
|
return vm;
|
|
|
|
vm = vm->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver,
|
|
|
|
const char *name) {
|
|
|
|
struct qemud_vm *vm = driver->vms;
|
|
|
|
|
|
|
|
while (vm) {
|
2008-05-14 19:51:24 +00:00
|
|
|
if (STREQ(vm->def->name, name))
|
2007-06-26 22:42:47 +00:00
|
|
|
return vm;
|
|
|
|
vm = vm->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
|
2007-02-14 17:05:55 +00:00
|
|
|
/* Free all memory associated with a struct qemud_vm object */
|
|
|
|
void qemudFreeVMDef(struct qemud_vm_def *def) {
|
|
|
|
struct qemud_vm_disk_def *disk = def->disks;
|
|
|
|
struct qemud_vm_net_def *net = def->nets;
|
2007-07-31 14:27:12 +00:00
|
|
|
struct qemud_vm_input_def *input = def->inputs;
|
2008-04-25 20:46:13 +00:00
|
|
|
struct qemud_vm_chr_def *serial = def->serials;
|
|
|
|
struct qemud_vm_chr_def *parallel = def->parallels;
|
2008-05-29 15:28:28 +00:00
|
|
|
struct qemud_vm_sound_def *sound = def->sounds;
|
2007-02-14 17:05:55 +00:00
|
|
|
|
|
|
|
while (disk) {
|
|
|
|
struct qemud_vm_disk_def *prev = disk;
|
|
|
|
disk = disk->next;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prev);
|
2007-02-14 17:05:55 +00:00
|
|
|
}
|
|
|
|
while (net) {
|
|
|
|
struct qemud_vm_net_def *prev = net;
|
|
|
|
net = net->next;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prev);
|
2007-02-14 17:05:55 +00:00
|
|
|
}
|
2007-07-31 14:27:12 +00:00
|
|
|
while (input) {
|
|
|
|
struct qemud_vm_input_def *prev = input;
|
|
|
|
input = input->next;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prev);
|
2007-07-31 14:27:12 +00:00
|
|
|
}
|
2008-04-25 20:46:13 +00:00
|
|
|
while (serial) {
|
|
|
|
struct qemud_vm_chr_def *prev = serial;
|
|
|
|
serial = serial->next;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prev);
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
while (parallel) {
|
|
|
|
struct qemud_vm_chr_def *prev = parallel;
|
|
|
|
parallel = parallel->next;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prev);
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
2008-05-29 15:28:28 +00:00
|
|
|
while (sound) {
|
|
|
|
struct qemud_vm_sound_def *prev = sound;
|
|
|
|
sound = sound->next;
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prev);
|
2008-05-29 15:28:28 +00:00
|
|
|
}
|
2008-01-15 15:18:33 +00:00
|
|
|
xmlFree(def->keymap);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(def);
|
2007-02-14 17:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void qemudFreeVM(struct qemud_vm *vm) {
|
|
|
|
qemudFreeVMDef(vm->def);
|
|
|
|
if (vm->newDef)
|
|
|
|
qemudFreeVMDef(vm->newDef);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(vm);
|
2007-02-14 17:05:55 +00:00
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-14 15:53:14 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/* The list of possible machine types for various architectures,
|
|
|
|
as supported by QEMU - taken from 'qemu -M ?' for each arch */
|
2008-02-27 04:35:08 +00:00
|
|
|
static const char *const arch_info_hvm_x86_machines[] = {
|
|
|
|
"pc", "isapc"
|
2007-02-14 01:40:09 +00:00
|
|
|
};
|
2008-02-27 04:35:08 +00:00
|
|
|
static const char *const arch_info_hvm_mips_machines[] = {
|
|
|
|
"mips"
|
2007-02-14 01:40:09 +00:00
|
|
|
};
|
2008-02-27 04:35:08 +00:00
|
|
|
static const char *const arch_info_hvm_sparc_machines[] = {
|
|
|
|
"sun4m"
|
2007-02-14 01:40:09 +00:00
|
|
|
};
|
2008-02-27 04:35:08 +00:00
|
|
|
static const char *const arch_info_hvm_ppc_machines[] = {
|
|
|
|
"g3bw", "mac99", "prep"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *const arch_info_xen_x86_machines[] = {
|
|
|
|
"xenner"
|
|
|
|
};
|
|
|
|
|
|
|
|
struct qemu_feature_flags {
|
|
|
|
const char *name;
|
|
|
|
const int default_on;
|
|
|
|
const int toggle;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct qemu_arch_info {
|
|
|
|
const char *arch;
|
|
|
|
int wordsize;
|
|
|
|
const char *const *machines;
|
|
|
|
int nmachines;
|
|
|
|
const char *binary;
|
|
|
|
const struct qemu_feature_flags *flags;
|
|
|
|
int nflags;
|
2007-02-14 01:40:09 +00:00
|
|
|
};
|
|
|
|
|
2007-07-30 09:59:05 +00:00
|
|
|
/* Feature flags for the architecture info */
|
2008-01-14 14:05:25 +00:00
|
|
|
static const struct qemu_feature_flags const arch_info_i686_flags [] = {
|
2008-02-27 04:35:08 +00:00
|
|
|
{ "pae", 1, 0 },
|
|
|
|
{ "nonpae", 1, 0 },
|
2007-07-30 09:59:05 +00:00
|
|
|
{ "acpi", 1, 1 },
|
|
|
|
{ "apic", 1, 0 },
|
|
|
|
};
|
|
|
|
|
2008-01-14 14:05:25 +00:00
|
|
|
static const struct qemu_feature_flags const arch_info_x86_64_flags [] = {
|
2007-07-30 09:59:05 +00:00
|
|
|
{ "acpi", 1, 1 },
|
|
|
|
{ "apic", 1, 0 },
|
|
|
|
};
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/* The archicture tables for supported QEMU archs */
|
2008-02-27 04:35:08 +00:00
|
|
|
static const struct qemu_arch_info const arch_info_hvm[] = {
|
|
|
|
{ "i686", 32, arch_info_hvm_x86_machines, 2,
|
|
|
|
"/usr/bin/qemu", arch_info_i686_flags, 4 },
|
|
|
|
{ "x86_64", 64, arch_info_hvm_x86_machines, 2,
|
|
|
|
"/usr/bin/qemu-system-x86_64", arch_info_x86_64_flags, 2 },
|
|
|
|
{ "mips", 32, arch_info_hvm_mips_machines, 1,
|
|
|
|
"/usr/bin/qemu-system-mips", NULL, 0 },
|
|
|
|
{ "mipsel", 32, arch_info_hvm_mips_machines, 1,
|
|
|
|
"/usr/bin/qemu-system-mipsel", NULL, 0 },
|
|
|
|
{ "sparc", 32, arch_info_hvm_sparc_machines, 1,
|
|
|
|
"/usr/bin/qemu-system-sparc", NULL, 0 },
|
|
|
|
{ "ppc", 32, arch_info_hvm_ppc_machines, 3,
|
|
|
|
"/usr/bin/qemu-system-ppc", NULL, 0 },
|
2007-02-14 01:40:09 +00:00
|
|
|
};
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
static const struct qemu_arch_info const arch_info_xen[] = {
|
|
|
|
{ "i686", 32, arch_info_xen_x86_machines, 1,
|
|
|
|
"/usr/bin/xenner", arch_info_i686_flags, 4 },
|
|
|
|
{ "x86_64", 64, arch_info_xen_x86_machines, 1,
|
|
|
|
"/usr/bin/xenner", arch_info_x86_64_flags, 2 },
|
|
|
|
};
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
static int
|
|
|
|
qemudCapsInitGuest(virCapsPtr caps,
|
|
|
|
const char *hostmachine,
|
|
|
|
const struct qemu_arch_info *info,
|
|
|
|
int hvm) {
|
|
|
|
virCapsGuestPtr guest;
|
2007-02-14 01:40:09 +00:00
|
|
|
int i;
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
if ((guest = virCapabilitiesAddGuest(caps,
|
|
|
|
hvm ? "hvm" : "xen",
|
|
|
|
info->arch,
|
|
|
|
info->wordsize,
|
|
|
|
info->binary,
|
|
|
|
NULL,
|
|
|
|
info->nmachines,
|
|
|
|
info->machines)) == NULL)
|
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
if (hvm) {
|
|
|
|
/* Check for existance of base emulator */
|
|
|
|
if (access(info->binary, X_OK) == 0 &&
|
|
|
|
virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"qemu",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
/* If guest & host match, then we can accelerate */
|
|
|
|
if (STREQ(info->arch, hostmachine)) {
|
|
|
|
if (access("/dev/kqemu", F_OK) == 0 &&
|
|
|
|
virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"kqemu",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (access("/dev/kvm", F_OK) == 0 &&
|
|
|
|
virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"kvm",
|
|
|
|
"/usr/bin/qemu-kvm",
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"kvm",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
return -1;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
if (info->nflags) {
|
|
|
|
for (i = 0 ; i < info->nflags ; i++) {
|
|
|
|
if (virCapabilitiesAddGuestFeature(guest,
|
|
|
|
info->flags[i].name,
|
|
|
|
info->flags[i].default_on,
|
|
|
|
info->flags[i].toggle) == NULL)
|
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
return 0;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-05-22 15:29:50 +00:00
|
|
|
#if HAVE_NUMACTL
|
|
|
|
#define MAX_CPUS 4096
|
|
|
|
#define MAX_CPUS_MASK_SIZE (sizeof(unsigned long))
|
|
|
|
#define MAX_CPUS_MASK_LEN (MAX_CPUS / MAX_CPUS_MASK_SIZE)
|
|
|
|
#define MAX_CPUS_MASK_BYTES (MAX_CPUS / 8)
|
|
|
|
|
|
|
|
#define MASK_CPU_ISSET(mask, cpu) \
|
|
|
|
(((mask)[((cpu) / MAX_CPUS_MASK_SIZE)] >> ((cpu) % MAX_CPUS_MASK_SIZE)) & 1)
|
|
|
|
|
|
|
|
static int
|
|
|
|
qemudCapsInitNUMA(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
int n, i;
|
|
|
|
unsigned long *mask = NULL;
|
|
|
|
int ncpus;
|
|
|
|
int *cpus = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (numa_available() < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(mask, MAX_CPUS_MASK_LEN) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (n = 0 ; n <= numa_max_node() ; n++) {
|
|
|
|
if (numa_node_to_cpus(n, mask, MAX_CPUS_MASK_BYTES) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (ncpus = 0, i = 0 ; i < MAX_CPUS ; i++)
|
|
|
|
if (MASK_CPU_ISSET(mask, i))
|
|
|
|
ncpus++;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(cpus, ncpus) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (ncpus = 0, i = 0 ; i < MAX_CPUS ; i++)
|
|
|
|
if (MASK_CPU_ISSET(mask, i))
|
|
|
|
cpus[ncpus++] = i;
|
|
|
|
|
|
|
|
if (virCapabilitiesAddHostNUMACell(caps,
|
|
|
|
n,
|
|
|
|
ncpus,
|
|
|
|
cpus) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
VIR_FREE(cpus);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(cpus);
|
|
|
|
VIR_FREE(mask);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static int qemudCapsInitNUMA(virCapsPtr caps ATTRIBUTE_UNUSED) { return 0; }
|
|
|
|
#endif
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
virCapsPtr qemudCapsInit(void) {
|
|
|
|
struct utsname utsname;
|
|
|
|
virCapsPtr caps;
|
|
|
|
int i;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
/* Really, this never fails - look at the man-page. */
|
|
|
|
uname (&utsname);
|
|
|
|
|
|
|
|
if ((caps = virCapabilitiesNew(utsname.machine,
|
|
|
|
0, 0)) == NULL)
|
|
|
|
goto no_memory;
|
|
|
|
|
2008-05-22 15:29:50 +00:00
|
|
|
if (qemudCapsInitNUMA(caps) < 0)
|
|
|
|
goto no_memory;
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
for (i = 0 ; i < (sizeof(arch_info_hvm)/sizeof(arch_info_hvm[0])) ; i++)
|
|
|
|
if (qemudCapsInitGuest(caps,
|
|
|
|
utsname.machine,
|
|
|
|
&arch_info_hvm[i], 1) < 0)
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
if (access("/usr/bin/xenner", X_OK) == 0 &&
|
|
|
|
access("/dev/kvm", F_OK) == 0) {
|
|
|
|
for (i = 0 ; i < (sizeof(arch_info_xen)/sizeof(arch_info_xen[0])) ; i++)
|
|
|
|
/* Allow Xen 32-on-32, 32-on-64 and 64-on-64 */
|
|
|
|
if (STREQ(arch_info_xen[i].arch, utsname.machine) ||
|
|
|
|
(STREQ(utsname.machine, "x86_64") &&
|
|
|
|
STREQ(arch_info_xen[i].arch, "i686"))) {
|
|
|
|
if (qemudCapsInitGuest(caps,
|
|
|
|
utsname.machine,
|
|
|
|
&arch_info_xen[i], 0) < 0)
|
|
|
|
goto no_memory;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
return caps;
|
|
|
|
|
|
|
|
no_memory:
|
|
|
|
virCapabilitiesFree(caps);
|
|
|
|
return NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 17:15:18 +00:00
|
|
|
|
|
|
|
static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
|
|
|
|
pid_t child;
|
|
|
|
int newstdout[2];
|
|
|
|
|
|
|
|
*flags = 0;
|
|
|
|
*version = 0;
|
|
|
|
|
|
|
|
if (pipe(newstdout) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((child = fork()) < 0) {
|
|
|
|
close(newstdout[0]);
|
|
|
|
close(newstdout[1]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child == 0) { /* Kid */
|
2008-05-21 19:43:39 +00:00
|
|
|
/* Just in case QEMU is translated someday we force to C locale.. */
|
|
|
|
const char *const qemuenv[] = { "LANG=C", NULL };
|
|
|
|
|
2007-02-23 17:15:18 +00:00
|
|
|
if (close(STDIN_FILENO) < 0)
|
|
|
|
goto cleanup1;
|
|
|
|
if (close(STDERR_FILENO) < 0)
|
|
|
|
goto cleanup1;
|
|
|
|
if (close(newstdout[0]) < 0)
|
|
|
|
goto cleanup1;
|
|
|
|
if (dup2(newstdout[1], STDOUT_FILENO) < 0)
|
|
|
|
goto cleanup1;
|
|
|
|
|
2008-05-21 19:43:39 +00:00
|
|
|
/* Passing -help, rather than relying on no-args which doesn't
|
|
|
|
always work */
|
|
|
|
execle(qemu, qemu, "-help", (char*)NULL, qemuenv);
|
2007-02-23 17:15:18 +00:00
|
|
|
|
|
|
|
cleanup1:
|
|
|
|
_exit(-1); /* Just in case */
|
|
|
|
} else { /* Parent */
|
2007-05-03 16:10:40 +00:00
|
|
|
char help[8192]; /* Ought to be enough to hold QEMU help screen */
|
2007-05-14 15:41:57 +00:00
|
|
|
int got = 0, ret = -1;
|
2007-02-23 17:15:18 +00:00
|
|
|
int major, minor, micro;
|
|
|
|
|
|
|
|
if (close(newstdout[1]) < 0)
|
|
|
|
goto cleanup2;
|
|
|
|
|
2007-05-03 16:10:40 +00:00
|
|
|
while (got < (sizeof(help)-1)) {
|
|
|
|
int len;
|
|
|
|
if ((len = read(newstdout[0], help+got, sizeof(help)-got-1)) <= 0) {
|
|
|
|
if (!len)
|
|
|
|
break;
|
|
|
|
if (errno == EINTR)
|
|
|
|
continue;
|
|
|
|
goto cleanup2;
|
|
|
|
}
|
|
|
|
got += len;
|
2007-02-23 17:15:18 +00:00
|
|
|
}
|
|
|
|
help[got] = '\0';
|
|
|
|
|
|
|
|
if (sscanf(help, "QEMU PC emulator version %d.%d.%d", &major,&minor, µ) != 3) {
|
|
|
|
goto cleanup2;
|
|
|
|
}
|
|
|
|
|
|
|
|
*version = (major * 1000 * 1000) + (minor * 1000) + micro;
|
|
|
|
if (strstr(help, "-no-kqemu"))
|
|
|
|
*flags |= QEMUD_CMD_FLAG_KQEMU;
|
2007-05-03 16:10:40 +00:00
|
|
|
if (strstr(help, "-no-reboot"))
|
|
|
|
*flags |= QEMUD_CMD_FLAG_NO_REBOOT;
|
2008-05-15 16:15:17 +00:00
|
|
|
if (strstr(help, "-name"))
|
|
|
|
*flags |= QEMUD_CMD_FLAG_NAME;
|
|
|
|
if (strstr(help, "-drive"))
|
|
|
|
*flags |= QEMUD_CMD_FLAG_DRIVE;
|
2008-05-09 16:41:19 +00:00
|
|
|
if (strstr(help, "boot=on"))
|
2008-05-15 16:15:17 +00:00
|
|
|
*flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
|
2007-02-23 17:15:18 +00:00
|
|
|
if (*version >= 9000)
|
|
|
|
*flags |= QEMUD_CMD_FLAG_VNC_COLON;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
qemudDebug("Version %d %d %d Cooked version: %d, with flags ? %d",
|
|
|
|
major, minor, micro, *version, *flags);
|
|
|
|
|
|
|
|
cleanup2:
|
|
|
|
if (close(newstdout[0]) < 0)
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
rewait:
|
|
|
|
if (waitpid(child, &got, 0) != child) {
|
|
|
|
if (errno == EINTR) {
|
|
|
|
goto rewait;
|
|
|
|
}
|
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
|
|
|
qemudLog(QEMUD_ERR,
|
|
|
|
_("Unexpected exit status from qemu %d pid %lu"),
|
|
|
|
got, (unsigned long)child);
|
2007-02-23 17:15:18 +00:00
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
/* Check & log unexpected exit status, but don't fail,
|
|
|
|
* as there's really no need to throw an error if we did
|
|
|
|
* actually read a valid version number above */
|
2008-05-21 21:14:36 +00:00
|
|
|
if (WEXITSTATUS(got) != 0) {
|
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
|
|
|
qemudLog(QEMUD_WARN,
|
|
|
|
_("Unexpected exit status '%d', qemu probably failed"),
|
|
|
|
got);
|
2007-02-23 17:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
int qemudExtractVersion(virConnectPtr conn,
|
2008-02-27 04:35:08 +00:00
|
|
|
struct qemud_driver *driver) {
|
|
|
|
const char *binary;
|
2007-04-16 13:14:28 +00:00
|
|
|
struct stat sb;
|
2007-09-21 21:20:32 +00:00
|
|
|
int ignored;
|
2007-02-23 17:15:18 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if (driver->qemuVersion > 0)
|
2007-02-23 17:15:18 +00:00
|
|
|
return 0;
|
|
|
|
|
2008-02-27 04:35:08 +00:00
|
|
|
if ((binary = virCapabilitiesDefaultGuestEmulator(driver->caps,
|
|
|
|
"hvm",
|
|
|
|
"i686",
|
|
|
|
"qemu")) == NULL)
|
2007-02-23 17:15:18 +00:00
|
|
|
return -1;
|
|
|
|
|
2007-04-16 13:14:28 +00:00
|
|
|
if (stat(binary, &sb) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("Cannot find QEMU binary %s: %s"), binary,
|
2007-04-16 13:14:28 +00:00
|
|
|
strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-09-21 21:20:32 +00:00
|
|
|
if (qemudExtractVersionInfo(binary, &driver->qemuVersion, &ignored) < 0) {
|
2007-02-23 17:15:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
/* Converts def->virtType to applicable string type
|
|
|
|
* @param type integer virt type
|
|
|
|
* @return string type on success, NULL on fail
|
|
|
|
*/
|
|
|
|
const char * qemudVirtTypeToString(int type) {
|
|
|
|
switch (type) {
|
|
|
|
case QEMUD_VIRT_QEMU:
|
|
|
|
return "qemu";
|
|
|
|
case QEMUD_VIRT_KQEMU:
|
|
|
|
return "kqemu";
|
|
|
|
case QEMUD_VIRT_KVM:
|
|
|
|
return "kvm";
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-02-23 17:15:18 +00:00
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
/* Parse the XML definition for a disk
|
|
|
|
* @param disk pre-allocated & zero'd disk record
|
|
|
|
* @param node XML nodeset to parse for disk definition
|
|
|
|
* @return 0 on success, -1 on failure
|
|
|
|
*/
|
|
|
|
static int qemudParseDiskXML(virConnectPtr conn,
|
|
|
|
struct qemud_vm_disk_def *disk,
|
|
|
|
xmlNodePtr node) {
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlNodePtr cur;
|
|
|
|
xmlChar *device = NULL;
|
|
|
|
xmlChar *source = NULL;
|
|
|
|
xmlChar *target = NULL;
|
|
|
|
xmlChar *type = NULL;
|
2008-05-09 16:41:19 +00:00
|
|
|
xmlChar *bus = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
int typ = 0;
|
|
|
|
|
|
|
|
type = xmlGetProp(node, BAD_CAST "type");
|
|
|
|
if (type != NULL) {
|
|
|
|
if (xmlStrEqual(type, BAD_CAST "file"))
|
|
|
|
typ = QEMUD_DISK_FILE;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "block"))
|
|
|
|
typ = QEMUD_DISK_BLOCK;
|
|
|
|
else {
|
|
|
|
typ = QEMUD_DISK_FILE;
|
|
|
|
}
|
|
|
|
xmlFree(type);
|
|
|
|
type = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
device = xmlGetProp(node, BAD_CAST "device");
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE) {
|
|
|
|
if ((source == NULL) &&
|
|
|
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (typ == QEMUD_DISK_FILE)
|
|
|
|
source = xmlGetProp(cur, BAD_CAST "file");
|
|
|
|
else
|
|
|
|
source = xmlGetProp(cur, BAD_CAST "dev");
|
|
|
|
} else if ((target == NULL) &&
|
|
|
|
(xmlStrEqual(cur->name, BAD_CAST "target"))) {
|
|
|
|
target = xmlGetProp(cur, BAD_CAST "dev");
|
2008-05-09 16:41:19 +00:00
|
|
|
bus = xmlGetProp(cur, BAD_CAST "bus");
|
2007-02-14 01:40:09 +00:00
|
|
|
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
|
|
|
|
disk->readonly = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (source == NULL) {
|
2008-03-13 09:17:45 +00:00
|
|
|
/* There is a case without the source
|
|
|
|
* to the CD-ROM device
|
|
|
|
*/
|
|
|
|
if (!device || STRNEQ((const char *) device, "cdrom")) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SOURCE,
|
|
|
|
target ? "%s" : NULL, target);
|
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-03-13 09:17:45 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (target == NULL) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_TARGET, source ? "%s" : NULL, source);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (device &&
|
2008-05-14 19:51:24 +00:00
|
|
|
STREQ((const char *)device, "floppy") &&
|
|
|
|
STRNEQ((const char *)target, "fda") &&
|
|
|
|
STRNEQ((const char *)target, "fdb")) {
|
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_INTERNAL_ERROR,
|
|
|
|
_("Invalid floppy device name: %s"), target);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (device &&
|
2008-05-14 19:51:24 +00:00
|
|
|
STREQ((const char *)device, "cdrom") &&
|
|
|
|
STRNEQ((const char *)target, "hdc")) {
|
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_INTERNAL_ERROR,
|
|
|
|
_("Invalid cdrom device name: %s"), target);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (device &&
|
2008-05-14 19:51:24 +00:00
|
|
|
STREQ((const char *)device, "cdrom"))
|
2007-02-14 01:40:09 +00:00
|
|
|
disk->readonly = 1;
|
|
|
|
|
2008-05-14 19:51:24 +00:00
|
|
|
if ((!device || STREQ((const char *)device, "disk")) &&
|
|
|
|
!STRPREFIX((const char *)target, "hd") &&
|
|
|
|
!STRPREFIX((const char *)target, "sd") &&
|
2008-05-15 16:05:41 +00:00
|
|
|
!STRPREFIX((const char *)target, "vd") &&
|
|
|
|
!STRPREFIX((const char *)target, "xvd")) {
|
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_INTERNAL_ERROR,
|
|
|
|
_("Invalid harddisk device name: %s"), target);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-03-13 09:17:45 +00:00
|
|
|
strncpy(disk->src, (source ? (const char *) source : "\0"), NAME_MAX-1);
|
2007-02-14 01:40:09 +00:00
|
|
|
disk->src[NAME_MAX-1] = '\0';
|
|
|
|
|
|
|
|
strncpy(disk->dst, (const char *)target, NAME_MAX-1);
|
|
|
|
disk->dst[NAME_MAX-1] = '\0';
|
|
|
|
disk->type = typ;
|
|
|
|
|
|
|
|
if (!device)
|
|
|
|
disk->device = QEMUD_DISK_DISK;
|
2008-05-14 19:51:24 +00:00
|
|
|
else if (STREQ((const char *)device, "disk"))
|
2007-02-14 01:40:09 +00:00
|
|
|
disk->device = QEMUD_DISK_DISK;
|
2008-05-14 19:51:24 +00:00
|
|
|
else if (STREQ((const char *)device, "cdrom"))
|
2007-02-14 01:40:09 +00:00
|
|
|
disk->device = QEMUD_DISK_CDROM;
|
2008-05-14 19:51:24 +00:00
|
|
|
else if (STREQ((const char *)device, "floppy"))
|
2007-02-14 01:40:09 +00:00
|
|
|
disk->device = QEMUD_DISK_FLOPPY;
|
|
|
|
else {
|
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_INTERNAL_ERROR,
|
|
|
|
_("Invalid device type: %s"), device);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-05-09 16:41:19 +00:00
|
|
|
if (!bus) {
|
2008-05-15 16:24:26 +00:00
|
|
|
if (disk->device == QEMUD_DISK_FLOPPY) {
|
2008-05-09 16:41:19 +00:00
|
|
|
disk->bus = QEMUD_DISK_BUS_FDC;
|
2008-05-15 16:24:26 +00:00
|
|
|
} else {
|
|
|
|
if (STRPREFIX((const char *)target, "hd"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_IDE;
|
|
|
|
else if (STRPREFIX((const char *)target, "sd"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_SCSI;
|
|
|
|
else if (STRPREFIX((const char *)target, "vd"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_VIRTIO;
|
|
|
|
else if (STRPREFIX((const char *)target, "xvd"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_XEN;
|
|
|
|
else
|
|
|
|
disk->bus = QEMUD_DISK_BUS_IDE;
|
|
|
|
}
|
2008-05-09 16:41:19 +00:00
|
|
|
} else if (STREQ((const char *)bus, "ide"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_IDE;
|
|
|
|
else if (STREQ((const char *)bus, "fdc"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_FDC;
|
|
|
|
else if (STREQ((const char *)bus, "scsi"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_SCSI;
|
|
|
|
else if (STREQ((const char *)bus, "virtio"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_VIRTIO;
|
2008-05-15 16:05:41 +00:00
|
|
|
else if (STREQ((const char *)bus, "xen"))
|
|
|
|
disk->bus = QEMUD_DISK_BUS_XEN;
|
2008-05-09 16:41:19 +00:00
|
|
|
else {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Invalid bus type: %s"), bus);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (disk->device == QEMUD_DISK_FLOPPY &&
|
|
|
|
disk->bus != QEMUD_DISK_BUS_FDC) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Invalid bus type '%s' for floppy disk"), bus);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlFree(device);
|
|
|
|
xmlFree(target);
|
|
|
|
xmlFree(source);
|
2008-05-09 16:41:19 +00:00
|
|
|
xmlFree(bus);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
return 0;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
error:
|
2008-05-09 16:41:19 +00:00
|
|
|
xmlFree(bus);
|
2008-04-29 19:43:57 +00:00
|
|
|
xmlFree(type);
|
|
|
|
xmlFree(target);
|
|
|
|
xmlFree(source);
|
|
|
|
xmlFree(device);
|
2007-10-27 01:18:38 +00:00
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
static void qemudRandomMAC(struct qemud_vm_net_def *net) {
|
|
|
|
net->mac[0] = 0x52;
|
|
|
|
net->mac[1] = 0x54;
|
|
|
|
net->mac[2] = 0x00;
|
|
|
|
net->mac[3] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
|
|
|
|
net->mac[4] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
|
|
|
|
net->mac[5] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
|
|
|
|
}
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
/* Parse the XML definition for a network interface
|
|
|
|
* @param net pre-allocated & zero'd net record
|
|
|
|
* @param node XML nodeset to parse for net definition
|
|
|
|
* @return 0 on success, -1 on failure
|
|
|
|
*/
|
|
|
|
static int qemudParseInterfaceXML(virConnectPtr conn,
|
|
|
|
struct qemud_vm_net_def *net,
|
|
|
|
xmlNodePtr node) {
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlNodePtr cur;
|
|
|
|
xmlChar *macaddr = NULL;
|
|
|
|
xmlChar *type = NULL;
|
2007-02-14 16:09:37 +00:00
|
|
|
xmlChar *network = NULL;
|
2007-03-13 22:43:22 +00:00
|
|
|
xmlChar *bridge = NULL;
|
|
|
|
xmlChar *ifname = NULL;
|
|
|
|
xmlChar *script = NULL;
|
|
|
|
xmlChar *address = NULL;
|
|
|
|
xmlChar *port = NULL;
|
2008-04-30 12:30:55 +00:00
|
|
|
xmlChar *model = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
net->type = QEMUD_NET_USER;
|
|
|
|
|
|
|
|
type = xmlGetProp(node, BAD_CAST "type");
|
|
|
|
if (type != NULL) {
|
|
|
|
if (xmlStrEqual(type, BAD_CAST "user"))
|
|
|
|
net->type = QEMUD_NET_USER;
|
2007-03-13 22:43:22 +00:00
|
|
|
else if (xmlStrEqual(type, BAD_CAST "ethernet"))
|
|
|
|
net->type = QEMUD_NET_ETHERNET;
|
2007-02-14 01:40:09 +00:00
|
|
|
else if (xmlStrEqual(type, BAD_CAST "server"))
|
|
|
|
net->type = QEMUD_NET_SERVER;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "client"))
|
|
|
|
net->type = QEMUD_NET_CLIENT;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "mcast"))
|
|
|
|
net->type = QEMUD_NET_MCAST;
|
2007-02-14 16:09:37 +00:00
|
|
|
else if (xmlStrEqual(type, BAD_CAST "network"))
|
|
|
|
net->type = QEMUD_NET_NETWORK;
|
2007-03-13 22:43:22 +00:00
|
|
|
else if (xmlStrEqual(type, BAD_CAST "bridge"))
|
|
|
|
net->type = QEMUD_NET_BRIDGE;
|
2007-02-14 01:40:09 +00:00
|
|
|
else
|
|
|
|
net->type = QEMUD_NET_USER;
|
|
|
|
xmlFree(type);
|
|
|
|
type = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE) {
|
|
|
|
if ((macaddr == NULL) &&
|
|
|
|
(xmlStrEqual(cur->name, BAD_CAST "mac"))) {
|
|
|
|
macaddr = xmlGetProp(cur, BAD_CAST "address");
|
2007-02-14 16:09:37 +00:00
|
|
|
} else if ((network == NULL) &&
|
|
|
|
(net->type == QEMUD_NET_NETWORK) &&
|
|
|
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
|
|
|
network = xmlGetProp(cur, BAD_CAST "network");
|
2007-03-13 22:43:22 +00:00
|
|
|
} else if ((network == NULL) &&
|
|
|
|
(net->type == QEMUD_NET_BRIDGE) &&
|
|
|
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
2007-03-27 14:46:45 +00:00
|
|
|
bridge = xmlGetProp(cur, BAD_CAST "bridge");
|
2007-03-13 22:43:22 +00:00
|
|
|
} else if ((network == NULL) &&
|
|
|
|
((net->type == QEMUD_NET_SERVER) ||
|
|
|
|
(net->type == QEMUD_NET_CLIENT) ||
|
|
|
|
(net->type == QEMUD_NET_MCAST)) &&
|
|
|
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
|
|
|
address = xmlGetProp(cur, BAD_CAST "address");
|
|
|
|
port = xmlGetProp(cur, BAD_CAST "port");
|
|
|
|
} else if ((ifname == NULL) &&
|
|
|
|
((net->type == QEMUD_NET_NETWORK) ||
|
|
|
|
(net->type == QEMUD_NET_ETHERNET) ||
|
|
|
|
(net->type == QEMUD_NET_BRIDGE)) &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "target")) {
|
|
|
|
ifname = xmlGetProp(cur, BAD_CAST "dev");
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX((const char*)ifname, "vnet")) {
|
2007-12-05 15:08:23 +00:00
|
|
|
/* An auto-generated target name, blank it out */
|
|
|
|
xmlFree(ifname);
|
|
|
|
ifname = NULL;
|
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
} else if ((script == NULL) &&
|
|
|
|
(net->type == QEMUD_NET_ETHERNET) &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "script")) {
|
|
|
|
script = xmlGetProp(cur, BAD_CAST "path");
|
2008-04-30 12:30:55 +00:00
|
|
|
} else if (xmlStrEqual (cur->name, BAD_CAST "model")) {
|
|
|
|
model = xmlGetProp (cur, BAD_CAST "type");
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (macaddr) {
|
2007-02-19 15:01:20 +00:00
|
|
|
unsigned int mac[6];
|
2007-02-14 01:40:09 +00:00
|
|
|
sscanf((const char *)macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
2007-02-19 15:01:20 +00:00
|
|
|
(unsigned int*)&mac[0],
|
|
|
|
(unsigned int*)&mac[1],
|
|
|
|
(unsigned int*)&mac[2],
|
|
|
|
(unsigned int*)&mac[3],
|
|
|
|
(unsigned int*)&mac[4],
|
|
|
|
(unsigned int*)&mac[5]);
|
|
|
|
net->mac[0] = mac[0];
|
|
|
|
net->mac[1] = mac[1];
|
|
|
|
net->mac[2] = mac[2];
|
|
|
|
net->mac[3] = mac[3];
|
|
|
|
net->mac[4] = mac[4];
|
|
|
|
net->mac[5] = mac[5];
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
xmlFree(macaddr);
|
2007-03-13 22:43:22 +00:00
|
|
|
macaddr = NULL;
|
|
|
|
} else {
|
|
|
|
qemudRandomMAC(net);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-02-14 16:09:37 +00:00
|
|
|
if (net->type == QEMUD_NET_NETWORK) {
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (network == NULL) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("No <source> 'network' attribute specified with <interface type='network'/>"));
|
2007-02-14 16:09:37 +00:00
|
|
|
goto error;
|
2007-03-13 22:43:22 +00:00
|
|
|
} else if ((len = xmlStrlen(network)) >= (QEMUD_MAX_NAME_LEN-1)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("Network name '%s' too long"), network);
|
2007-02-14 16:09:37 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
strncpy(net->dst.network.name, (char *)network, len);
|
|
|
|
net->dst.network.name[len] = '\0';
|
|
|
|
}
|
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
if (network) {
|
2007-02-14 16:09:37 +00:00
|
|
|
xmlFree(network);
|
2007-03-13 22:43:22 +00:00
|
|
|
network = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ifname != NULL) {
|
|
|
|
if ((len = xmlStrlen(ifname)) >= (BR_IFNAME_MAXLEN-1)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("TAP interface name '%s' is too long"),
|
|
|
|
ifname);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
strncpy(net->dst.network.ifname, (char *)ifname, len);
|
|
|
|
net->dst.network.ifname[len] = '\0';
|
|
|
|
}
|
|
|
|
xmlFree(ifname);
|
|
|
|
ifname = NULL;
|
|
|
|
}
|
|
|
|
} else if (net->type == QEMUD_NET_ETHERNET) {
|
|
|
|
int len;
|
2007-02-14 16:09:37 +00:00
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
if (script != NULL) {
|
|
|
|
if ((len = xmlStrlen(script)) >= (PATH_MAX-1)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("TAP script path '%s' is too long"), script);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
strncpy(net->dst.ethernet.script, (char *)script, len);
|
|
|
|
net->dst.ethernet.script[len] = '\0';
|
|
|
|
}
|
|
|
|
xmlFree(script);
|
|
|
|
script = NULL;
|
|
|
|
}
|
|
|
|
if (ifname != NULL) {
|
|
|
|
if ((len = xmlStrlen(ifname)) >= (BR_IFNAME_MAXLEN-1)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("TAP interface name '%s' is too long"),
|
|
|
|
ifname);
|
2007-02-14 16:09:37 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
2007-03-13 22:43:22 +00:00
|
|
|
strncpy(net->dst.ethernet.ifname, (char *)ifname, len);
|
|
|
|
net->dst.ethernet.ifname[len] = '\0';
|
2007-02-14 16:09:37 +00:00
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
xmlFree(ifname);
|
|
|
|
}
|
|
|
|
} else if (net->type == QEMUD_NET_BRIDGE) {
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (bridge == NULL) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("No <source> 'dev' attribute specified with <interface type='bridge'/>"));
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
} else if ((len = xmlStrlen(bridge)) >= (BR_IFNAME_MAXLEN-1)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("TAP bridge path '%s' is too long"), bridge);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
strncpy(net->dst.bridge.brname, (char *)bridge, len);
|
|
|
|
net->dst.bridge.brname[len] = '\0';
|
2007-02-14 16:09:37 +00:00
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
|
|
|
|
xmlFree(bridge);
|
|
|
|
bridge = NULL;
|
|
|
|
|
|
|
|
if (ifname != NULL) {
|
|
|
|
if ((len = xmlStrlen(ifname)) >= (BR_IFNAME_MAXLEN-1)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("TAP interface name '%s' is too long"), ifname);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
strncpy(net->dst.bridge.ifname, (char *)ifname, len);
|
|
|
|
net->dst.bridge.ifname[len] = '\0';
|
|
|
|
}
|
|
|
|
xmlFree(ifname);
|
|
|
|
}
|
|
|
|
} else if (net->type == QEMUD_NET_CLIENT ||
|
|
|
|
net->type == QEMUD_NET_SERVER ||
|
|
|
|
net->type == QEMUD_NET_MCAST) {
|
2007-08-07 13:02:35 +00:00
|
|
|
int len = 0;
|
2007-03-13 22:43:22 +00:00
|
|
|
char *ret;
|
|
|
|
|
|
|
|
if (port == NULL) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("No <source> 'port' attribute specified with socket interface"));
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (!(net->dst.socket.port = strtol((char*)port, &ret, 10)) &&
|
|
|
|
ret == (char*)port) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("Cannot parse <source> 'port' attribute with socket interface"));
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlFree(port);
|
|
|
|
port = NULL;
|
|
|
|
|
|
|
|
if (address == NULL) {
|
|
|
|
if (net->type == QEMUD_NET_CLIENT ||
|
|
|
|
net->type == QEMUD_NET_MCAST) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("No <source> 'address' attribute specified with socket interface"));
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else if ((len = xmlStrlen(address)) >= (BR_INET_ADDR_MAXLEN)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("IP address '%s' is too long"), address);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (address == NULL) {
|
|
|
|
net->dst.socket.address[0] = '\0';
|
|
|
|
} else {
|
|
|
|
strncpy(net->dst.socket.address, (char*)address,len);
|
|
|
|
net->dst.socket.address[len] = '\0';
|
|
|
|
}
|
|
|
|
xmlFree(address);
|
2007-02-14 16:09:37 +00:00
|
|
|
}
|
|
|
|
|
2008-04-30 12:30:55 +00:00
|
|
|
/* NIC model (see -net nic,model=?). We only check that it looks
|
|
|
|
* reasonable, not that it is a supported NIC type. FWIW kvm
|
|
|
|
* supports these types as of April 2008:
|
|
|
|
* i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio
|
|
|
|
*/
|
|
|
|
if (model != NULL) {
|
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
|
|
|
int i, len;
|
2008-04-30 12:30:55 +00:00
|
|
|
|
|
|
|
len = xmlStrlen (model);
|
|
|
|
if (len >= QEMUD_MODEL_MAX_LEN) {
|
|
|
|
qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG,
|
|
|
|
_("Model name '%s' is too long"), model);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
for (i = 0; i < len; ++i) {
|
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
|
|
|
int char_ok = c_isalnum(model[i]) || model[i] == '_';
|
2008-04-30 12:30:55 +00:00
|
|
|
if (!char_ok) {
|
2008-05-13 09:15:11 +00:00
|
|
|
qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG, "%s",
|
2008-04-30 12:30:55 +00:00
|
|
|
_("Model name contains invalid characters"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
strncpy (net->model, (const char*) model, len);
|
|
|
|
net->model[len] = '\0';
|
|
|
|
|
|
|
|
xmlFree (model);
|
|
|
|
model = NULL;
|
|
|
|
} else
|
|
|
|
net->model[0] = '\0';
|
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
return 0;
|
2007-02-14 16:09:37 +00:00
|
|
|
|
|
|
|
error:
|
2008-04-29 19:43:57 +00:00
|
|
|
xmlFree(network);
|
|
|
|
xmlFree(address);
|
|
|
|
xmlFree(port);
|
|
|
|
xmlFree(ifname);
|
|
|
|
xmlFree(script);
|
|
|
|
xmlFree(bridge);
|
2008-04-30 12:30:55 +00:00
|
|
|
xmlFree(model);
|
2007-10-27 01:18:38 +00:00
|
|
|
return -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
/* Parse the XML definition for a character device
|
|
|
|
* @param net pre-allocated & zero'd net record
|
|
|
|
* @param node XML nodeset to parse for net definition
|
|
|
|
* @return 0 on success, -1 on failure
|
|
|
|
*
|
|
|
|
* The XML we're dealing with looks like
|
|
|
|
*
|
|
|
|
* <serial type="pty">
|
|
|
|
* <source path="/dev/pts/3"/>
|
|
|
|
* <target port="1"/>
|
|
|
|
* </serial>
|
|
|
|
*
|
|
|
|
* <serial type="dev">
|
|
|
|
* <source path="/dev/ttyS0"/>
|
|
|
|
* <target port="1"/>
|
|
|
|
* </serial>
|
|
|
|
*
|
|
|
|
* <serial type="tcp">
|
|
|
|
* <source mode="connect" host="0.0.0.0" service="2445"/>
|
|
|
|
* <target port="1"/>
|
|
|
|
* </serial>
|
|
|
|
*
|
|
|
|
* <serial type="tcp">
|
|
|
|
* <source mode="bind" host="0.0.0.0" service="2445"/>
|
|
|
|
* <target port="1"/>
|
|
|
|
* </serial>
|
|
|
|
*
|
|
|
|
* <serial type="udp">
|
|
|
|
* <source mode="bind" host="0.0.0.0" service="2445"/>
|
|
|
|
* <source mode="connect" host="0.0.0.0" service="2445"/>
|
|
|
|
* <target port="1"/>
|
|
|
|
* </serial>
|
|
|
|
*
|
|
|
|
* <serial type="unix">
|
|
|
|
* <source mode="bind" path="/tmp/foo"/>
|
|
|
|
* <target port="1"/>
|
|
|
|
* </serial>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int qemudParseCharXML(virConnectPtr conn,
|
|
|
|
struct qemud_vm_chr_def *chr,
|
|
|
|
int portNum,
|
|
|
|
xmlNodePtr node) {
|
|
|
|
xmlNodePtr cur;
|
|
|
|
xmlChar *type = NULL;
|
|
|
|
xmlChar *bindHost = NULL;
|
|
|
|
xmlChar *bindService = NULL;
|
|
|
|
xmlChar *connectHost = NULL;
|
|
|
|
xmlChar *connectService = NULL;
|
|
|
|
xmlChar *path = NULL;
|
|
|
|
xmlChar *mode = NULL;
|
|
|
|
xmlChar *protocol = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
|
|
|
|
type = xmlGetProp(node, BAD_CAST "type");
|
|
|
|
if (type != NULL) {
|
|
|
|
if (xmlStrEqual(type, BAD_CAST "null"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_NULL;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "vc"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_VC;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "pty"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "dev"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_DEV;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "file"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_FILE;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "pipe"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_PIPE;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "stdio"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_STDIO;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "udp"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_UDP;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "tcp"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_TCP;
|
|
|
|
else if (xmlStrEqual(type, BAD_CAST "unix"))
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_UNIX;
|
|
|
|
else
|
|
|
|
chr->srcType = QEMUD_CHR_SRC_TYPE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE) {
|
|
|
|
if (xmlStrEqual(cur->name, BAD_CAST "source")) {
|
|
|
|
if (mode == NULL)
|
|
|
|
mode = xmlGetProp(cur, BAD_CAST "mode");
|
|
|
|
|
|
|
|
switch (chr->srcType) {
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PTY:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_DEV:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_FILE:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PIPE:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UNIX:
|
|
|
|
if (path == NULL)
|
|
|
|
path = xmlGetProp(cur, BAD_CAST "path");
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UDP:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_TCP:
|
|
|
|
if (mode == NULL ||
|
|
|
|
STREQ((const char *)mode, "connect")) {
|
|
|
|
|
|
|
|
if (connectHost == NULL)
|
|
|
|
connectHost = xmlGetProp(cur, BAD_CAST "host");
|
|
|
|
if (connectService == NULL)
|
|
|
|
connectService = xmlGetProp(cur, BAD_CAST "service");
|
|
|
|
} else {
|
|
|
|
if (bindHost == NULL)
|
|
|
|
bindHost = xmlGetProp(cur, BAD_CAST "host");
|
|
|
|
if (bindService == NULL)
|
|
|
|
bindService = xmlGetProp(cur, BAD_CAST "service");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chr->srcType == QEMUD_CHR_SRC_TYPE_UDP) {
|
|
|
|
xmlFree(mode);
|
|
|
|
mode = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) {
|
|
|
|
if (protocol == NULL)
|
|
|
|
protocol = xmlGetProp(cur, BAD_CAST "type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
chr->dstPort = portNum;
|
|
|
|
|
|
|
|
switch (chr->srcType) {
|
|
|
|
case QEMUD_CHR_SRC_TYPE_NULL:
|
|
|
|
/* Nada */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_VC:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PTY:
|
|
|
|
/* @path attribute is an output only property - pty is auto-allocted */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_DEV:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_FILE:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PIPE:
|
|
|
|
if (path == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source path attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(chr->srcData.file.path, (const char *)path,
|
|
|
|
sizeof(chr->srcData.file.path));
|
|
|
|
NUL_TERMINATE(chr->srcData.file.path);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_STDIO:
|
|
|
|
/* Nada */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_TCP:
|
|
|
|
if (mode == NULL ||
|
|
|
|
STREQ((const char *)mode, "connect")) {
|
|
|
|
if (connectHost == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source host attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (connectService == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source service attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(chr->srcData.tcp.host, (const char *)connectHost,
|
|
|
|
sizeof(chr->srcData.tcp.host));
|
|
|
|
NUL_TERMINATE(chr->srcData.tcp.host);
|
|
|
|
strncpy(chr->srcData.tcp.service, (const char *)connectService,
|
|
|
|
sizeof(chr->srcData.tcp.service));
|
|
|
|
NUL_TERMINATE(chr->srcData.tcp.service);
|
|
|
|
|
|
|
|
chr->srcData.tcp.listen = 0;
|
|
|
|
} else {
|
|
|
|
if (bindHost == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source host attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (bindService == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source service attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(chr->srcData.tcp.host, (const char *)bindHost,
|
|
|
|
sizeof(chr->srcData.tcp.host));
|
|
|
|
NUL_TERMINATE(chr->srcData.tcp.host);
|
|
|
|
strncpy(chr->srcData.tcp.service, (const char *)bindService,
|
|
|
|
sizeof(chr->srcData.tcp.service));
|
|
|
|
NUL_TERMINATE(chr->srcData.tcp.service);
|
|
|
|
|
|
|
|
chr->srcData.tcp.listen = 1;
|
|
|
|
}
|
|
|
|
if (protocol != NULL &&
|
|
|
|
STREQ((const char *)protocol, "telnet"))
|
|
|
|
chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET;
|
|
|
|
else
|
|
|
|
chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_RAW;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UDP:
|
|
|
|
if (connectService == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source service attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (connectHost != NULL) {
|
|
|
|
strncpy(chr->srcData.udp.connectHost, (const char *)connectHost,
|
|
|
|
sizeof(chr->srcData.udp.connectHost));
|
|
|
|
NUL_TERMINATE(chr->srcData.udp.connectHost);
|
|
|
|
}
|
|
|
|
strncpy(chr->srcData.udp.connectService, (const char *)connectService,
|
|
|
|
sizeof(chr->srcData.udp.connectService));
|
|
|
|
NUL_TERMINATE(chr->srcData.udp.connectService);
|
|
|
|
|
|
|
|
if (bindHost != NULL) {
|
|
|
|
strncpy(chr->srcData.udp.bindHost, (const char *)bindHost,
|
|
|
|
sizeof(chr->srcData.udp.bindHost));
|
|
|
|
NUL_TERMINATE(chr->srcData.udp.bindHost);
|
|
|
|
}
|
|
|
|
if (bindService != NULL) {
|
|
|
|
strncpy(chr->srcData.udp.bindService, (const char *)bindService,
|
|
|
|
sizeof(chr->srcData.udp.bindService));
|
|
|
|
NUL_TERMINATE(chr->srcData.udp.bindService);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UNIX:
|
|
|
|
if (path == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Missing source path attribute for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode != NULL &&
|
|
|
|
STRNEQ((const char *)mode, "connect"))
|
|
|
|
chr->srcData.nix.listen = 1;
|
|
|
|
else
|
|
|
|
chr->srcData.nix.listen = 0;
|
|
|
|
|
|
|
|
strncpy(chr->srcData.nix.path, (const char *)path,
|
|
|
|
sizeof(chr->srcData.nix.path));
|
|
|
|
NUL_TERMINATE(chr->srcData.nix.path);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xmlFree(mode);
|
|
|
|
xmlFree(protocol);
|
|
|
|
xmlFree(type);
|
|
|
|
xmlFree(bindHost);
|
|
|
|
xmlFree(bindService);
|
|
|
|
xmlFree(connectHost);
|
|
|
|
xmlFree(connectService);
|
|
|
|
xmlFree(path);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int qemudParseCharXMLDevices(virConnectPtr conn,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
const char *xpath,
|
|
|
|
unsigned int *ndevs,
|
|
|
|
struct qemud_vm_chr_def **devs)
|
|
|
|
{
|
|
|
|
xmlXPathObjectPtr obj;
|
|
|
|
int i, ret = -1;
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
|
|
|
struct qemud_vm_chr_def *prev = *devs;
|
|
|
|
if (ndevs == NULL &&
|
|
|
|
obj->nodesetval->nodeNr > 1) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("too many character devices"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_chr_def *chr;
|
|
|
|
if (VIR_ALLOC(chr) < 0) {
|
2008-04-25 20:46:13 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s",
|
|
|
|
_("failed to allocate space for char device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemudParseCharXML(conn, chr, i, obj->nodesetval->nodeTab[i]) < 0) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(chr);
|
2008-04-25 20:46:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (ndevs)
|
|
|
|
(*ndevs)++;
|
|
|
|
chr->next = NULL;
|
|
|
|
if (i == 0) {
|
|
|
|
*devs = chr;
|
|
|
|
} else {
|
|
|
|
prev->next = chr;
|
|
|
|
}
|
|
|
|
prev = chr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-18 21:08:22 +00:00
|
|
|
/* Parse the XML definition for a network interface */
|
2007-10-27 01:18:38 +00:00
|
|
|
static int qemudParseInputXML(virConnectPtr conn,
|
2008-05-15 16:11:40 +00:00
|
|
|
const struct qemud_vm_def *vm,
|
2007-10-27 01:18:38 +00:00
|
|
|
struct qemud_vm_input_def *input,
|
|
|
|
xmlNodePtr node) {
|
2007-07-18 21:08:22 +00:00
|
|
|
xmlChar *type = NULL;
|
|
|
|
xmlChar *bus = NULL;
|
|
|
|
|
|
|
|
type = xmlGetProp(node, BAD_CAST "type");
|
|
|
|
bus = xmlGetProp(node, BAD_CAST "bus");
|
|
|
|
|
|
|
|
if (!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(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("missing input device type"));
|
2007-07-18 21:08:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-05-14 19:51:24 +00:00
|
|
|
if (STREQ((const char *)type, "mouse")) {
|
2007-07-18 21:08:22 +00:00
|
|
|
input->type = QEMU_INPUT_TYPE_MOUSE;
|
2008-05-14 19:51:24 +00:00
|
|
|
} else if (STREQ((const char *)type, "tablet")) {
|
2007-07-18 21:08:22 +00:00
|
|
|
input->type = QEMU_INPUT_TYPE_TABLET;
|
|
|
|
} else {
|
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_INTERNAL_ERROR,
|
|
|
|
_("unsupported input device type %s"),
|
|
|
|
(const char*)type);
|
2007-07-18 21:08:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bus) {
|
2008-05-15 16:11:40 +00:00
|
|
|
if (STREQ(vm->os.type, "hvm")) {
|
|
|
|
if (STREQ((const char*)bus, "ps2")) { /* Only allow mouse */
|
|
|
|
if (input->type != QEMU_INPUT_TYPE_MOUSE) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("ps2 bus does not support %s input device"),
|
|
|
|
(const char*)type);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
input->bus = QEMU_INPUT_BUS_PS2;
|
|
|
|
} else if (STREQ((const char *)bus, "usb")) { /* Allow mouse & tablet */
|
|
|
|
input->bus = QEMU_INPUT_BUS_USB;
|
|
|
|
} else {
|
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_INTERNAL_ERROR,
|
2008-05-15 16:11:40 +00:00
|
|
|
_("unsupported input bus %s"), (const char*)bus);
|
2007-07-18 21:08:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else {
|
2008-05-15 16:11:40 +00:00
|
|
|
if (STREQ((const char *)bus, "xen")) { /* Allow mouse only */
|
|
|
|
input->bus = QEMU_INPUT_BUS_XEN;
|
|
|
|
if (input->type != QEMU_INPUT_TYPE_MOUSE) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("xen bus does not support %s input device"),
|
|
|
|
(const char*)type);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unsupported input bus %s"), (const char*)bus);
|
|
|
|
goto error;
|
|
|
|
}
|
2007-07-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
} else {
|
2008-05-15 20:07:34 +00:00
|
|
|
if (STREQ(vm->os.type, "hvm")) {
|
2008-05-15 16:11:40 +00:00
|
|
|
if (input->type == QEMU_INPUT_TYPE_MOUSE)
|
|
|
|
input->bus = QEMU_INPUT_BUS_PS2;
|
|
|
|
else
|
|
|
|
input->bus = QEMU_INPUT_BUS_USB;
|
|
|
|
} else {
|
|
|
|
input->bus = QEMU_INPUT_BUS_XEN;
|
|
|
|
}
|
2007-07-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
2008-04-29 19:43:57 +00:00
|
|
|
xmlFree(type);
|
|
|
|
xmlFree(bus);
|
2007-07-18 21:08:22 +00:00
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
return 0;
|
2007-07-18 21:08:22 +00:00
|
|
|
|
|
|
|
error:
|
2008-04-29 19:43:57 +00:00
|
|
|
xmlFree(type);
|
|
|
|
xmlFree(bus);
|
2007-07-18 21:08:22 +00:00
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
return -1;
|
2007-07-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
2008-05-09 16:41:19 +00:00
|
|
|
static int qemudDiskCompare(const void *aptr, const void *bptr) {
|
|
|
|
struct qemud_vm_disk_def *a = (struct qemud_vm_disk_def *) aptr;
|
|
|
|
struct qemud_vm_disk_def *b = (struct qemud_vm_disk_def *) bptr;
|
|
|
|
if (a->bus == b->bus)
|
|
|
|
return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst);
|
|
|
|
else
|
|
|
|
return a->bus - b->bus;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *qemudBusIdToName(int busId, int qemuIF) {
|
|
|
|
const char *busnames[] = { "ide",
|
|
|
|
(qemuIF ? "floppy" : "fdc"),
|
|
|
|
"scsi",
|
2008-05-15 16:05:41 +00:00
|
|
|
"virtio",
|
|
|
|
"xen"};
|
2008-05-09 16:41:19 +00:00
|
|
|
verify_true(ARRAY_CARDINALITY(busnames) == QEMUD_DISK_BUS_LAST);
|
|
|
|
|
|
|
|
return busnames[busId];
|
|
|
|
}
|
|
|
|
|
2008-05-07 14:04:40 +00:00
|
|
|
/* Sound device helper functions */
|
|
|
|
static int qemudSoundModelFromString(const char *model) {
|
|
|
|
if (STREQ(model, "sb16")) {
|
|
|
|
return QEMU_SOUND_SB16;
|
|
|
|
} else if (STREQ(model, "es1370")) {
|
|
|
|
return QEMU_SOUND_ES1370;
|
|
|
|
} else if (STREQ(model, "pcspk")) {
|
|
|
|
return QEMU_SOUND_PCSPK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *qemudSoundModelToString(const int model) {
|
|
|
|
|
|
|
|
if (model == QEMU_SOUND_SB16) {
|
|
|
|
return "sb16";
|
|
|
|
} else if (model == QEMU_SOUND_ES1370) {
|
|
|
|
return "es1370";
|
|
|
|
} else if (model == QEMU_SOUND_PCSPK) {
|
|
|
|
return "pcspk";
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int qemudParseSoundXML(virConnectPtr conn,
|
|
|
|
struct qemud_vm_sound_def *sound,
|
|
|
|
const xmlNodePtr node) {
|
|
|
|
|
|
|
|
int err = -1;
|
|
|
|
xmlChar *model = NULL;
|
|
|
|
model = xmlGetProp(node, BAD_CAST "model");
|
|
|
|
|
|
|
|
if (!model) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("missing sound model"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if ((sound->model = qemudSoundModelFromString((char *) model)) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("invalid sound model '%s'"), (char *) model);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = 0;
|
|
|
|
error:
|
|
|
|
xmlFree(model);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/*
|
|
|
|
* Parses a libvirt XML definition of a guest, and populates the
|
|
|
|
* the qemud_vm struct with matching data about the guests config
|
|
|
|
*/
|
2007-07-12 15:09:01 +00:00
|
|
|
static struct qemud_vm_def *qemudParseXML(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-14 17:05:55 +00:00
|
|
|
xmlDocPtr xml) {
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlNodePtr root = NULL;
|
|
|
|
xmlChar *prop = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
xmlXPathObjectPtr obj = NULL;
|
|
|
|
char *conv = NULL;
|
|
|
|
int i;
|
2007-02-14 17:05:55 +00:00
|
|
|
struct qemud_vm_def *def;
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC(def) < 0) {
|
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 xmlXPathContext"));
|
2007-02-14 17:05:55 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
/* Prepare parser / xpath context */
|
|
|
|
root = xmlDocGetRootElement(xml);
|
|
|
|
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("incorrect root element"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt = xmlXPathNewContext(xml);
|
|
|
|
if (ctxt == 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 xmlXPathContext"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Find out what type of QEMU virtualization to use */
|
|
|
|
if (!(prop = xmlGetProp(root, BAD_CAST "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(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("missing domain type attribute"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-05-14 19:51:24 +00:00
|
|
|
if (STREQ((char *)prop, "qemu"))
|
2007-02-14 17:05:55 +00:00
|
|
|
def->virtType = QEMUD_VIRT_QEMU;
|
2008-05-14 19:51:24 +00:00
|
|
|
else if (STREQ((char *)prop, "kqemu"))
|
2007-02-14 17:05:55 +00:00
|
|
|
def->virtType = QEMUD_VIRT_KQEMU;
|
2008-05-14 19:51:24 +00:00
|
|
|
else if (STREQ((char *)prop, "kvm"))
|
2007-02-14 17:05:55 +00:00
|
|
|
def->virtType = QEMUD_VIRT_KVM;
|
2007-02-14 01:40:09 +00:00
|
|
|
else {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("invalid domain type attribute"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prop);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Extract domain name */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_NAME, NULL);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (strlen((const char *)obj->stringval) >= (QEMUD_MAX_NAME_LEN-1)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("domain name length too long"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
strcpy(def->name, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
|
|
|
|
|
|
|
/* Extract domain uuid */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2007-02-26 15:32:27 +00:00
|
|
|
int err;
|
2007-06-26 22:19:38 +00:00
|
|
|
if ((err = virUUIDGenerate(def->uuid))) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("Failed to generate UUID: %s"), strerror(err));
|
2007-02-26 15:32:27 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-06-26 22:19:38 +00:00
|
|
|
} else if (virUUIDParse((const char *)obj->stringval, def->uuid) < 0) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("malformed uuid element"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
|
|
|
|
|
|
|
/* Extract domain memory */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/memory[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("missing memory element"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
conv = NULL;
|
2007-02-14 17:05:55 +00:00
|
|
|
def->maxmem = strtoll((const char*)obj->stringval, &conv, 10);
|
2007-02-14 01:40:09 +00:00
|
|
|
if (conv == (const char*)obj->stringval) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("malformed memory information"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Extract domain memory */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/currentMemory[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2007-02-14 17:05:55 +00:00
|
|
|
def->memory = def->maxmem;
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
|
|
|
conv = NULL;
|
2007-02-14 17:05:55 +00:00
|
|
|
def->memory = strtoll((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (def->memory > def->maxmem)
|
|
|
|
def->memory = def->maxmem;
|
2007-02-14 01:40:09 +00:00
|
|
|
if (conv == (const char*)obj->stringval) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("malformed memory information"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
/* Extract domain vcpu info */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2007-02-14 17:05:55 +00:00
|
|
|
def->vcpus = 1;
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
|
|
|
conv = NULL;
|
2007-02-14 17:05:55 +00:00
|
|
|
def->vcpus = strtoll((const char*)obj->stringval, &conv, 10);
|
2007-02-14 01:40:09 +00:00
|
|
|
if (conv == (const char*)obj->stringval) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("malformed vcpu information"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-22 16:27:20 +00:00
|
|
|
/* Extract domain vcpu info */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1]/@cpuset)", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
/* Allow use on all CPUS */
|
|
|
|
memset(def->cpumask, 1, QEMUD_CPUMASK_LEN);
|
|
|
|
} else {
|
|
|
|
char *set = (char *)obj->stringval;
|
|
|
|
memset(def->cpumask, 0, QEMUD_CPUMASK_LEN);
|
|
|
|
if (virParseCpuSet(conn, (const char **)&set,
|
|
|
|
0, def->cpumask,
|
|
|
|
QEMUD_CPUMASK_LEN) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("malformed vcpu mask information"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/* See if ACPI feature is requested */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/features/acpi", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
2007-02-14 17:05:55 +00:00
|
|
|
def->features |= QEMUD_FEATURE_ACPI;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2007-02-20 17:51:41 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-05-03 16:10:40 +00:00
|
|
|
|
|
|
|
/* See if we disable reboots */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/on_reboot)", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
def->noReboot = 0;
|
|
|
|
} else {
|
2008-05-14 19:51:24 +00:00
|
|
|
if (STREQ((char*)obj->stringval, "destroy"))
|
2007-05-03 16:10:40 +00:00
|
|
|
def->noReboot = 1;
|
|
|
|
else
|
|
|
|
def->noReboot = 0;
|
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-05-03 16:10:40 +00:00
|
|
|
|
2007-07-16 21:30:30 +00:00
|
|
|
/* See if we set clock to localtime */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/clock/@offset)", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
def->localtime = 0;
|
|
|
|
} else {
|
2008-05-14 19:51:24 +00:00
|
|
|
if (STREQ((char*)obj->stringval, "localtime"))
|
2007-07-16 21:30:30 +00:00
|
|
|
def->localtime = 1;
|
|
|
|
else
|
|
|
|
def->localtime = 0;
|
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-07-16 21:30:30 +00:00
|
|
|
|
2007-05-03 16:10:40 +00:00
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
/* Extract bootloader */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/bootloader)", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
strncpy(def->os.bootloader, (const char*)obj->stringval, sizeof(def->os.bootloader));
|
|
|
|
NUL_TERMINATE(def->os.bootloader);
|
|
|
|
|
|
|
|
/* Set a default OS type, since <type> is optional with bootloader */
|
|
|
|
strcpy(def->os.type, "xen");
|
|
|
|
}
|
2008-05-16 16:53:44 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2008-05-15 16:21:11 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/* Extract OS type info */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2008-05-15 16:21:11 +00:00
|
|
|
if (!def->os.type[0]) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
|
|
|
|
"%s", _("no OS type"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
strcpy(def->os.type, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-05-16 16:53:44 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
obj = NULL;
|
2008-05-15 16:21:11 +00:00
|
|
|
|
|
|
|
if (!virCapabilitiesSupportsGuestOSType(driver->caps, 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(conn, NULL, NULL, VIR_ERR_OS_TYPE,
|
2008-05-15 16:21:11 +00:00
|
|
|
"%s", def->os.type);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@arch)", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2008-02-27 04:35:08 +00:00
|
|
|
const char *defaultArch = virCapabilitiesDefaultGuestArch(driver->caps, def->os.type);
|
|
|
|
if (defaultArch == 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_INTERNAL_ERROR,
|
|
|
|
"%s", _("unsupported architecture"));
|
2008-02-27 04:35:08 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
if (strlen(defaultArch) >= (QEMUD_OS_TYPE_MAX_LEN-1)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("architecture type too long"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
strcpy(def->os.arch, defaultArch);
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
|
|
|
if (strlen((const char *)obj->stringval) >= (QEMUD_OS_TYPE_MAX_LEN-1)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("architecture type too long"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
strcpy(def->os.arch, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@machine)", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2008-02-27 04:35:08 +00:00
|
|
|
const char *defaultMachine = virCapabilitiesDefaultGuestMachine(driver->caps,
|
|
|
|
def->os.type,
|
|
|
|
def->os.arch);
|
|
|
|
if (defaultMachine == 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_INTERNAL_ERROR,
|
|
|
|
"%s", _("unsupported architecture"));
|
2007-07-30 18:50:07 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
if (strlen(defaultMachine) >= (QEMUD_OS_MACHINE_MAX_LEN-1)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("machine type too long"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
strcpy(def->os.machine, defaultMachine);
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
|
|
|
if (strlen((const char *)obj->stringval) >= (QEMUD_OS_MACHINE_MAX_LEN-1)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("architecture type too long"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
strcpy(def->os.machine, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
if (!def->os.bootloader[0]) {
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/os/kernel[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("kernel path too long"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
strcpy(def->os.kernel, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-05-15 16:21:11 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/os/initrd[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("initrd path too long"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
strcpy(def->os.initrd, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-05-15 16:21:11 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/os/cmdline[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cmdline arguments too long"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
strcpy(def->os.cmdline, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-05-15 16:21:11 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
/* analysis of the disk devices */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/os/boot", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
|
|
|
for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
|
|
|
|
if (!(prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev")))
|
|
|
|
continue;
|
|
|
|
if (STREQ((char *)prop, "hd")) {
|
|
|
|
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
|
|
|
|
} else if (STREQ((char *)prop, "fd")) {
|
|
|
|
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
|
|
|
|
} else if (STREQ((char *)prop, "cdrom")) {
|
|
|
|
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
|
|
|
|
} else if (STREQ((char *)prop, "network")) {
|
|
|
|
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
|
|
|
|
} else {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unknown boot device \'%s\'"), (char*)prop);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlFree(prop);
|
|
|
|
prop = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-15 16:21:11 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
if (def->os.nBootDevs == 0) {
|
|
|
|
def->os.nBootDevs = 1;
|
|
|
|
def->os.bootDevs[0] = QEMUD_BOOT_DISK;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/devices/emulator[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2008-05-07 16:16:44 +00:00
|
|
|
const char *type = qemudVirtTypeToString(def->virtType);
|
|
|
|
if (!type) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("unknown virt type"));
|
|
|
|
goto error;
|
|
|
|
}
|
2008-02-27 04:35:08 +00:00
|
|
|
const char *emulator = virCapabilitiesDefaultGuestEmulator(driver->caps,
|
|
|
|
def->os.type,
|
|
|
|
def->os.arch,
|
|
|
|
type);
|
|
|
|
if (!emulator) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("unsupported guest type"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-02-27 04:35:08 +00:00
|
|
|
strcpy(def->os.binary, emulator);
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
|
|
|
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
|
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_INTERNAL_ERROR,
|
|
|
|
"%s", _("emulator path too long"));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
strcpy(def->os.binary, (const char *)obj->stringval);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
|
|
|
|
(obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) {
|
2007-02-14 17:05:55 +00:00
|
|
|
def->graphicsType = QEMUD_GRAPHICS_NONE;
|
2007-02-20 17:51:41 +00:00
|
|
|
} else if ((prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type"))) {
|
2008-05-14 19:51:24 +00:00
|
|
|
if (STREQ((char *)prop, "vnc")) {
|
2007-07-24 14:30:05 +00:00
|
|
|
xmlChar *vncport, *vnclisten;
|
2007-02-14 17:05:55 +00:00
|
|
|
def->graphicsType = QEMUD_GRAPHICS_VNC;
|
2007-07-24 14:30:05 +00:00
|
|
|
vncport = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "port");
|
|
|
|
if (vncport) {
|
2007-02-14 01:40:09 +00:00
|
|
|
conv = NULL;
|
2007-07-24 14:30:05 +00:00
|
|
|
def->vncPort = strtoll((const char*)vncport, &conv, 10);
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
2007-02-14 17:05:55 +00:00
|
|
|
def->vncPort = -1;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2007-07-24 14:30:05 +00:00
|
|
|
vnclisten = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "listen");
|
|
|
|
if (vnclisten && *vnclisten)
|
|
|
|
strncpy(def->vncListen, (char *)vnclisten, BR_INET_ADDR_MAXLEN-1);
|
|
|
|
else
|
2007-10-12 16:05:44 +00:00
|
|
|
strcpy(def->vncListen, driver->vncListen);
|
2007-07-24 14:30:05 +00:00
|
|
|
def->vncListen[BR_INET_ADDR_MAXLEN-1] = '\0';
|
2008-01-15 15:18:33 +00:00
|
|
|
def->keymap = (char *) xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "keymap");
|
2007-07-24 14:30:05 +00:00
|
|
|
xmlFree(vncport);
|
|
|
|
xmlFree(vnclisten);
|
2008-05-14 19:51:24 +00:00
|
|
|
} else if (STREQ((char *)prop, "sdl")) {
|
2007-02-14 17:05:55 +00:00
|
|
|
def->graphicsType = QEMUD_GRAPHICS_SDL;
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
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_INTERNAL_ERROR,
|
|
|
|
_("Unsupported graphics type %s"), prop);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-20 17:51:41 +00:00
|
|
|
xmlFree(prop);
|
2007-03-09 03:08:34 +00:00
|
|
|
prop = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
2007-02-20 17:51:41 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
/* analysis of the disk devices */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
|
|
|
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_disk_def *disk;
|
|
|
|
if (VIR_ALLOC(disk) < 0) {
|
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 disk string"));
|
2007-10-27 01:18:38 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (qemudParseDiskXML(conn, disk, obj->nodesetval->nodeTab[i]) < 0) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(disk);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
def->ndisks++;
|
2007-03-13 22:43:22 +00:00
|
|
|
if (i == 0) {
|
2008-05-09 16:41:19 +00:00
|
|
|
disk->next = NULL;
|
2007-03-13 22:43:22 +00:00
|
|
|
def->disks = disk;
|
|
|
|
} else {
|
2008-05-09 16:41:19 +00:00
|
|
|
struct qemud_vm_disk_def *ptr = def->disks;
|
|
|
|
while (ptr) {
|
|
|
|
if (!ptr->next || qemudDiskCompare(disk, ptr->next) < 0) {
|
|
|
|
disk->next = ptr->next;
|
|
|
|
ptr->next = disk;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ptr = ptr->next;
|
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2008-04-25 20:46:13 +00:00
|
|
|
obj = NULL;
|
|
|
|
|
|
|
|
/* analysis of the character devices */
|
|
|
|
if (qemudParseCharXMLDevices(conn, ctxt,
|
|
|
|
"/domain/devices/parallel",
|
|
|
|
&def->nparallels,
|
|
|
|
&def->parallels) < 0)
|
|
|
|
goto error;
|
|
|
|
if (qemudParseCharXMLDevices(conn, ctxt,
|
|
|
|
"/domain/devices/serial",
|
|
|
|
&def->nserials,
|
|
|
|
&def->serials) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If no serial devices were listed, then look for console
|
|
|
|
* devices which is the legacy syntax for the same thing
|
|
|
|
*/
|
|
|
|
if (def->nserials == 0) {
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/console", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_chr_def *chr;
|
|
|
|
if (VIR_ALLOC(chr) < 0) {
|
2008-04-25 20:46:13 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s",
|
|
|
|
_("failed to allocate space for char device"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemudParseCharXML(conn, chr, 0, obj->nodesetval->nodeTab[0]) < 0) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(chr);
|
2008-04-25 20:46:13 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
def->nserials = 1;
|
|
|
|
def->serials = chr;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* analysis of the network devices */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/interface", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
2007-03-13 22:43:22 +00:00
|
|
|
struct qemud_vm_net_def *prev = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_net_def *net;
|
|
|
|
if (VIR_ALLOC(net) < 0) {
|
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 net string"));
|
2007-10-27 01:18:38 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (qemudParseInterfaceXML(conn, net, obj->nodesetval->nodeTab[i]) < 0) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(net);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
def->nnets++;
|
2007-03-13 22:43:22 +00:00
|
|
|
net->next = NULL;
|
|
|
|
if (i == 0) {
|
|
|
|
def->nets = net;
|
|
|
|
} else {
|
|
|
|
prev->next = net;
|
|
|
|
}
|
|
|
|
prev = net;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2007-07-18 21:08:22 +00:00
|
|
|
|
|
|
|
/* analysis of the input devices */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/input", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
|
|
|
struct qemud_vm_input_def *prev = NULL;
|
|
|
|
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_input_def *input;
|
|
|
|
if (VIR_ALLOC(input) < 0) {
|
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 input string"));
|
2007-10-27 01:18:38 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-05-15 16:11:40 +00:00
|
|
|
if (qemudParseInputXML(conn, def, input, obj->nodesetval->nodeTab[i]) < 0) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(input);
|
2007-07-18 21:08:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
/* Mouse + PS/2 is implicit with graphics, so don't store it */
|
|
|
|
if (input->bus == QEMU_INPUT_BUS_PS2 &&
|
|
|
|
input->type == QEMU_INPUT_TYPE_MOUSE) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(input);
|
2007-07-18 21:08:22 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
def->ninputs++;
|
|
|
|
input->next = NULL;
|
2007-09-28 20:47:58 +00:00
|
|
|
if (def->inputs == NULL) {
|
2007-07-18 21:08:22 +00:00
|
|
|
def->inputs = input;
|
|
|
|
} else {
|
|
|
|
prev->next = input;
|
|
|
|
}
|
|
|
|
prev = input;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2008-05-07 14:04:40 +00:00
|
|
|
|
|
|
|
/* Parse sound driver xml */
|
|
|
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/sound", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
|
|
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
|
|
|
struct qemud_vm_sound_def *prev = NULL;
|
|
|
|
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_sound_def *sound;
|
2008-05-07 14:04:40 +00:00
|
|
|
struct qemud_vm_sound_def *check = def->sounds;
|
|
|
|
int collision = 0;
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC(sound) < 0) {
|
2008-05-07 14:04:40 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("failed to allocate space for sound dev"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (qemudParseSoundXML(conn, sound,
|
|
|
|
obj->nodesetval->nodeTab[i]) < 0) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(sound);
|
2008-05-07 14:04:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that model type isn't already present in sound dev list
|
|
|
|
while(check) {
|
|
|
|
if (check->model == sound->model) {
|
|
|
|
collision = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
check = check->next;
|
|
|
|
}
|
2008-05-29 15:28:28 +00:00
|
|
|
if (collision) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(sound);
|
2008-05-07 14:04:40 +00:00
|
|
|
continue;
|
2008-05-29 15:28:28 +00:00
|
|
|
}
|
2008-05-07 14:04:40 +00:00
|
|
|
|
|
|
|
def->nsounds++;
|
|
|
|
sound->next = NULL;
|
|
|
|
if (def->sounds == NULL) {
|
|
|
|
def->sounds = sound;
|
|
|
|
} else {
|
|
|
|
prev->next = sound;
|
|
|
|
}
|
|
|
|
prev = sound;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2007-07-18 21:08:22 +00:00
|
|
|
obj = NULL;
|
|
|
|
|
|
|
|
/* If graphics are enabled, there's an implicit PS2 mouse */
|
|
|
|
if (def->graphicsType != QEMUD_GRAPHICS_NONE) {
|
|
|
|
int hasPS2mouse = 0;
|
|
|
|
struct qemud_vm_input_def *input = def->inputs;
|
|
|
|
while (input) {
|
|
|
|
if (input->type == QEMU_INPUT_TYPE_MOUSE &&
|
|
|
|
input->bus == QEMU_INPUT_BUS_PS2)
|
|
|
|
hasPS2mouse = 1;
|
|
|
|
input = input->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hasPS2mouse) {
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC(input) < 0) {
|
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 input string"));
|
2007-07-18 21:08:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
input->type = QEMU_INPUT_TYPE_MOUSE;
|
|
|
|
input->bus = QEMU_INPUT_BUS_PS2;
|
|
|
|
input->next = def->inputs;
|
|
|
|
def->inputs = input;
|
|
|
|
def->ninputs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
|
2007-02-14 17:05:55 +00:00
|
|
|
return def;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
error:
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(prop);
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2008-01-29 18:23:43 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
2007-02-14 17:05:55 +00:00
|
|
|
qemudFreeVMDef(def);
|
|
|
|
return NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-14 16:09:37 +00:00
|
|
|
static char *
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudNetworkIfaceConnect(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-14 16:09:37 +00:00
|
|
|
struct qemud_vm *vm,
|
2007-03-13 22:43:22 +00:00
|
|
|
struct qemud_vm_net_def *net,
|
|
|
|
int vlan)
|
2007-02-14 16:09:37 +00:00
|
|
|
{
|
2008-07-11 17:33:45 +00:00
|
|
|
virNetworkObjPtr network = NULL;
|
2007-03-13 22:43:22 +00:00
|
|
|
char *brname;
|
|
|
|
char *ifname;
|
2007-02-14 16:09:37 +00:00
|
|
|
char tapfdstr[4+3+32+7];
|
|
|
|
char *retval = NULL;
|
|
|
|
int err;
|
|
|
|
int tapfd = -1;
|
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
if (net->type == QEMUD_NET_NETWORK) {
|
2008-07-11 17:33:45 +00:00
|
|
|
if (!(network = virNetworkFindByName(driver->networks, net->dst.network.name))) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("Network '%s' not found"),
|
|
|
|
net->dst.network.name);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
2008-07-11 17:33:45 +00:00
|
|
|
} else if (network->def->bridge == NULL) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("Network '%s' not active"),
|
|
|
|
net->dst.network.name);
|
2007-03-13 22:43:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-07-11 17:33:45 +00:00
|
|
|
brname = network->def->bridge;
|
2007-03-13 22:43:22 +00:00
|
|
|
if (net->dst.network.ifname[0] == '\0' ||
|
2008-05-15 14:21:34 +00:00
|
|
|
STRPREFIX(net->dst.network.ifname, "vnet") ||
|
2007-03-13 22:43:22 +00:00
|
|
|
strchr(net->dst.network.ifname, '%')) {
|
|
|
|
strcpy(net->dst.network.ifname, "vnet%d");
|
|
|
|
}
|
|
|
|
ifname = net->dst.network.ifname;
|
|
|
|
} else if (net->type == QEMUD_NET_BRIDGE) {
|
|
|
|
brname = net->dst.bridge.brname;
|
|
|
|
if (net->dst.bridge.ifname[0] == '\0' ||
|
2008-05-15 14:21:34 +00:00
|
|
|
STRPREFIX(net->dst.bridge.ifname, "vnet") ||
|
2007-03-13 22:43:22 +00:00
|
|
|
strchr(net->dst.bridge.ifname, '%')) {
|
|
|
|
strcpy(net->dst.bridge.ifname, "vnet%d");
|
|
|
|
}
|
|
|
|
ifname = net->dst.bridge.ifname;
|
|
|
|
} else {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("Network type %d is not supported"), net->type);
|
2007-02-14 16:09:37 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if (!driver->brctl && (err = brInit(&driver->brctl))) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("cannot initialize bridge support: %s"),
|
|
|
|
strerror(err));
|
2007-05-14 15:41:57 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if ((err = brAddTap(driver->brctl, brname,
|
2007-03-13 22:43:22 +00:00
|
|
|
ifname, BR_IFNAME_MAXLEN, &tapfd))) {
|
2008-07-09 05:24:08 +00:00
|
|
|
if (errno == ENOTSUP) {
|
|
|
|
/* In this particular case, give a better diagnostic. */
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Failed to add tap interface to bridge. "
|
|
|
|
"%s is not a bridge device"), brname);
|
|
|
|
} else {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Failed to add tap interface '%s' "
|
|
|
|
"to bridge '%s' : %s"),
|
|
|
|
ifname, brname, strerror(err));
|
|
|
|
}
|
2007-02-14 16:09:37 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-03-14 20:30:03 +00:00
|
|
|
snprintf(tapfdstr, sizeof(tapfdstr),
|
|
|
|
"tap,fd=%d,script=,vlan=%d,ifname=%s",
|
|
|
|
tapfd, vlan, ifname);
|
2007-02-14 16:09:37 +00:00
|
|
|
|
|
|
|
if (!(retval = strdup(tapfdstr)))
|
|
|
|
goto no_memory;
|
|
|
|
|
2008-06-19 10:38:36 +00:00
|
|
|
if (VIR_REALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
|
2007-02-14 16:09:37 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
vm->tapfds[vm->ntapfds++] = tapfd;
|
|
|
|
vm->tapfds[vm->ntapfds] = -1;
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
no_memory:
|
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 tapfds string"));
|
2007-02-14 16:09:37 +00:00
|
|
|
error:
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(retval);
|
2007-02-14 16:09:37 +00:00
|
|
|
if (tapfd != -1)
|
|
|
|
close(tapfd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
static int qemudBuildCommandLineChrDevStr(struct qemud_vm_chr_def *dev,
|
|
|
|
char *buf,
|
|
|
|
int buflen)
|
|
|
|
{
|
|
|
|
switch (dev->srcType) {
|
|
|
|
case QEMUD_CHR_SRC_TYPE_NULL:
|
|
|
|
strncpy(buf, "null", buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_VC:
|
|
|
|
strncpy(buf, "vc", buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PTY:
|
|
|
|
strncpy(buf, "pty", buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_DEV:
|
|
|
|
if (snprintf(buf, buflen, "%s",
|
|
|
|
dev->srcData.file.path) >= buflen)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_FILE:
|
|
|
|
if (snprintf(buf, buflen, "file:%s",
|
|
|
|
dev->srcData.file.path) >= buflen)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PIPE:
|
|
|
|
if (snprintf(buf, buflen, "pipe:%s",
|
|
|
|
dev->srcData.file.path) >= buflen)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_STDIO:
|
|
|
|
strncpy(buf, "stdio", buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UDP:
|
|
|
|
if (snprintf(buf, buflen, "udp:%s:%s@%s:%s",
|
|
|
|
dev->srcData.udp.connectHost,
|
|
|
|
dev->srcData.udp.connectService,
|
|
|
|
dev->srcData.udp.bindHost,
|
|
|
|
dev->srcData.udp.bindService) >= buflen)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_TCP:
|
|
|
|
if (snprintf(buf, buflen, "%s:%s:%s%s",
|
|
|
|
dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET ? "telnet" : "tcp",
|
|
|
|
dev->srcData.tcp.host,
|
|
|
|
dev->srcData.tcp.service,
|
|
|
|
dev->srcData.tcp.listen ? ",listen" : "") >= buflen)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UNIX:
|
|
|
|
if (snprintf(buf, buflen, "unix:%s%s",
|
|
|
|
dev->srcData.nix.path,
|
|
|
|
dev->srcData.nix.listen ? ",listen" : "") >= buflen)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/*
|
|
|
|
* Constructs a argv suitable for launching qemu with config defined
|
|
|
|
* for a given virtual machine.
|
|
|
|
*/
|
2007-07-12 15:09:01 +00:00
|
|
|
int qemudBuildCommandLine(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-14 01:40:09 +00:00
|
|
|
struct qemud_vm *vm,
|
2008-05-22 23:45:09 +00:00
|
|
|
char ***retargv) {
|
|
|
|
int i;
|
2007-02-14 01:40:09 +00:00
|
|
|
char memory[50];
|
|
|
|
char vcpus[50];
|
|
|
|
char boot[QEMUD_MAX_BOOT_DEVS+1];
|
2007-02-14 17:05:55 +00:00
|
|
|
struct qemud_vm_disk_def *disk = vm->def->disks;
|
|
|
|
struct qemud_vm_net_def *net = vm->def->nets;
|
2007-07-18 21:08:22 +00:00
|
|
|
struct qemud_vm_input_def *input = vm->def->inputs;
|
2008-05-07 14:04:40 +00:00
|
|
|
struct qemud_vm_sound_def *sound = vm->def->sounds;
|
2008-04-25 20:46:13 +00:00
|
|
|
struct qemud_vm_chr_def *serial = vm->def->serials;
|
|
|
|
struct qemud_vm_chr_def *parallel = vm->def->parallels;
|
2007-04-16 13:14:28 +00:00
|
|
|
struct utsname ut;
|
|
|
|
int disableKQEMU = 0;
|
2008-05-22 23:45:09 +00:00
|
|
|
int qargc = 0, qarga = 0;
|
|
|
|
char **qargv = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-09-21 21:20:32 +00:00
|
|
|
if (vm->qemuVersion == 0) {
|
|
|
|
if (qemudExtractVersionInfo(vm->def->os.binary,
|
|
|
|
&(vm->qemuVersion),
|
|
|
|
&(vm->qemuCmdFlags)) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
2007-02-23 17:15:18 +00:00
|
|
|
|
2007-04-16 13:14:28 +00:00
|
|
|
uname(&ut);
|
|
|
|
|
2007-05-18 18:36:24 +00:00
|
|
|
/* Nasty hack make i?86 look like i686 to simplify next comparison */
|
2007-04-16 13:14:28 +00:00
|
|
|
if (ut.machine[0] == 'i' &&
|
|
|
|
ut.machine[2] == '8' &&
|
|
|
|
ut.machine[3] == '6' &&
|
|
|
|
!ut.machine[4])
|
2007-05-18 18:36:24 +00:00
|
|
|
ut.machine[1] = '6';
|
2007-04-16 13:14:28 +00:00
|
|
|
|
|
|
|
/* Need to explicitly disable KQEMU if
|
|
|
|
* 1. Arch matches host arch
|
|
|
|
* 2. Guest is 'qemu'
|
|
|
|
* 3. The qemu binary has the -no-kqemu flag
|
|
|
|
*/
|
2007-09-21 21:20:32 +00:00
|
|
|
if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
|
2008-05-14 19:51:24 +00:00
|
|
|
STREQ(ut.machine, vm->def->os.arch) &&
|
2007-04-16 13:14:28 +00:00
|
|
|
vm->def->virtType == QEMUD_VIRT_QEMU)
|
|
|
|
disableKQEMU = 1;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
#define ADD_ARG_SPACE \
|
|
|
|
do { \
|
|
|
|
if (qargc == qarga) { \
|
|
|
|
qarga += 10; \
|
|
|
|
if (VIR_REALLOC_N(qargv, qarga) < 0) \
|
|
|
|
goto no_memory; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ADD_ARG(thisarg) \
|
|
|
|
do { \
|
|
|
|
ADD_ARG_SPACE; \
|
|
|
|
qargv[qargc++] = thisarg; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ADD_ARG_LIT(thisarg) \
|
|
|
|
do { \
|
|
|
|
ADD_ARG_SPACE; \
|
|
|
|
if ((qargv[qargc++] = strdup(thisarg)) == NULL) \
|
|
|
|
goto no_memory; \
|
|
|
|
} while (0)
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-03-19 14:32:50 +00:00
|
|
|
snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
|
2007-03-23 16:15:07 +00:00
|
|
|
snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
|
|
|
|
ADD_ARG_LIT(vm->def->os.binary);
|
|
|
|
ADD_ARG_LIT("-S");
|
|
|
|
ADD_ARG_LIT("-M");
|
|
|
|
ADD_ARG_LIT(vm->def->os.machine);
|
|
|
|
if (disableKQEMU)
|
|
|
|
ADD_ARG_LIT("-no-kqemu");
|
|
|
|
ADD_ARG_LIT("-m");
|
|
|
|
ADD_ARG_LIT(memory);
|
|
|
|
ADD_ARG_LIT("-smp");
|
|
|
|
ADD_ARG_LIT(vcpus);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-15 16:15:17 +00:00
|
|
|
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-name");
|
|
|
|
ADD_ARG_LIT(vm->def->name);
|
2008-05-15 16:15:17 +00:00
|
|
|
}
|
2007-07-24 14:30:05 +00:00
|
|
|
/*
|
|
|
|
* NB, -nographic *MUST* come before any serial, or monitor
|
|
|
|
* or parallel port flags due to QEMU craziness, where it
|
|
|
|
* decides to change the serial port & monitor to be on stdout
|
|
|
|
* if you ask for nographic. So we have to make sure we override
|
|
|
|
* these defaults ourselves...
|
|
|
|
*/
|
2008-05-22 23:45:09 +00:00
|
|
|
if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE)
|
|
|
|
ADD_ARG_LIT("-nographic");
|
2007-07-24 14:30:05 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-monitor");
|
|
|
|
ADD_ARG_LIT("pty");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
if (vm->def->localtime)
|
|
|
|
ADD_ARG_LIT("-localtime");
|
2007-07-16 21:30:30 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
|
|
|
|
vm->def->noReboot)
|
|
|
|
ADD_ARG_LIT("-no-reboot");
|
2007-05-03 16:10:40 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
if (!(vm->def->features & QEMUD_FEATURE_ACPI))
|
|
|
|
ADD_ARG_LIT("-no-acpi");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
if (!vm->def->os.bootloader[0]) {
|
|
|
|
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
|
|
|
|
switch (vm->def->os.bootDevs[i]) {
|
|
|
|
case QEMUD_BOOT_CDROM:
|
|
|
|
boot[i] = 'd';
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_FLOPPY:
|
|
|
|
boot[i] = 'a';
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_DISK:
|
|
|
|
boot[i] = 'c';
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_NET:
|
|
|
|
boot[i] = 'n';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
boot[i] = 'c';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boot[vm->def->os.nBootDevs] = '\0';
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-boot");
|
|
|
|
ADD_ARG_LIT(boot);
|
2008-05-15 16:21:11 +00:00
|
|
|
|
|
|
|
if (vm->def->os.kernel[0]) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-kernel");
|
|
|
|
ADD_ARG_LIT(vm->def->os.kernel);
|
2008-05-15 16:21:11 +00:00
|
|
|
}
|
|
|
|
if (vm->def->os.initrd[0]) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-initrd");
|
|
|
|
ADD_ARG_LIT(vm->def->os.initrd);
|
2008-05-15 16:21:11 +00:00
|
|
|
}
|
|
|
|
if (vm->def->os.cmdline[0]) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-append");
|
|
|
|
ADD_ARG_LIT(vm->def->os.cmdline);
|
2008-05-15 16:21:11 +00:00
|
|
|
}
|
|
|
|
} else {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-bootloader");
|
|
|
|
ADD_ARG_LIT(vm->def->os.bootloader);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-05-09 16:41:19 +00:00
|
|
|
/* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
|
2008-05-15 16:15:17 +00:00
|
|
|
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
|
2008-05-09 16:41:19 +00:00
|
|
|
int bootCD = 0, bootFloppy = 0, bootDisk = 0;
|
|
|
|
|
|
|
|
/* If QEMU supports boot=on for -drive param... */
|
2008-05-15 16:15:17 +00:00
|
|
|
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT) {
|
2008-05-09 16:41:19 +00:00
|
|
|
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
|
|
|
|
switch (vm->def->os.bootDevs[i]) {
|
|
|
|
case QEMUD_BOOT_CDROM:
|
|
|
|
bootCD = 1;
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_FLOPPY:
|
|
|
|
bootFloppy = 1;
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_DISK:
|
|
|
|
bootDisk = 1;
|
|
|
|
break;
|
|
|
|
}
|
2008-03-13 09:17:45 +00:00
|
|
|
}
|
2008-05-09 16:41:19 +00:00
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-09 16:41:19 +00:00
|
|
|
while (disk) {
|
|
|
|
char opt[PATH_MAX];
|
|
|
|
const char *media = NULL;
|
|
|
|
int bootable = 0;
|
|
|
|
int idx = virDiskNameToIndex(disk->dst);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-09 16:41:19 +00:00
|
|
|
if (idx < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unsupported disk type '%s'"), disk->dst);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (disk->device == QEMUD_DISK_CDROM)
|
|
|
|
media = "media=cdrom,";
|
|
|
|
|
|
|
|
switch (disk->device) {
|
|
|
|
case QEMUD_DISK_CDROM:
|
|
|
|
bootable = bootCD;
|
|
|
|
bootCD = 0;
|
|
|
|
break;
|
|
|
|
case QEMUD_DISK_FLOPPY:
|
|
|
|
bootable = bootFloppy;
|
|
|
|
bootFloppy = 0;
|
|
|
|
break;
|
|
|
|
case QEMUD_DISK_DISK:
|
|
|
|
bootable = bootDisk;
|
|
|
|
bootDisk = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf(opt, PATH_MAX, "file=%s,if=%s,%sindex=%d%s",
|
|
|
|
disk->src, qemudBusIdToName(disk->bus, 1),
|
|
|
|
media ? media : "",
|
|
|
|
idx,
|
2008-07-11 09:56:23 +00:00
|
|
|
bootable && disk->device == QEMUD_DISK_DISK
|
|
|
|
? ",boot=on" : "");
|
2008-05-09 16:41:19 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-drive");
|
|
|
|
ADD_ARG_LIT(opt);
|
2008-05-09 16:41:19 +00:00
|
|
|
disk = disk->next;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while (disk) {
|
|
|
|
char dev[NAME_MAX];
|
|
|
|
char file[PATH_MAX];
|
|
|
|
|
|
|
|
if (STREQ(disk->dst, "hdc") &&
|
|
|
|
disk->device == QEMUD_DISK_CDROM) {
|
|
|
|
if (disk->src[0]) {
|
|
|
|
snprintf(dev, NAME_MAX, "-%s", "cdrom");
|
|
|
|
} else {
|
|
|
|
disk = disk->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (STRPREFIX(disk->dst, "hd") ||
|
|
|
|
STRPREFIX(disk->dst, "fd")) {
|
|
|
|
snprintf(dev, NAME_MAX, "-%s", disk->dst);
|
|
|
|
} else {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unsupported disk type '%s'"), disk->dst);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf(file, PATH_MAX, "%s", disk->src);
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT(dev);
|
|
|
|
ADD_ARG_LIT(file);
|
2008-05-09 16:41:19 +00:00
|
|
|
|
|
|
|
disk = disk->next;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!net) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-net");
|
|
|
|
ADD_ARG_LIT("none");
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
2007-03-13 22:43:22 +00:00
|
|
|
int vlan = 0;
|
2007-02-14 01:40:09 +00:00
|
|
|
while (net) {
|
2007-03-20 16:50:42 +00:00
|
|
|
char nic[100];
|
2007-02-14 15:51:53 +00:00
|
|
|
|
2008-04-30 12:30:55 +00:00
|
|
|
if (snprintf(nic, sizeof(nic),
|
|
|
|
"nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s",
|
2007-03-20 16:50:42 +00:00
|
|
|
net->mac[0], net->mac[1],
|
|
|
|
net->mac[2], net->mac[3],
|
|
|
|
net->mac[4], net->mac[5],
|
2008-04-30 12:30:55 +00:00
|
|
|
vlan,
|
|
|
|
(net->model[0] ? ",model=" : ""), net->model) >= sizeof(nic))
|
2007-03-20 16:50:42 +00:00
|
|
|
goto error;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-net");
|
|
|
|
ADD_ARG_LIT(nic);
|
|
|
|
ADD_ARG_LIT("-net");
|
2007-02-14 16:09:37 +00:00
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
switch (net->type) {
|
|
|
|
case QEMUD_NET_NETWORK:
|
|
|
|
case QEMUD_NET_BRIDGE:
|
2008-06-12 10:19:24 +00:00
|
|
|
{
|
|
|
|
char *tap = qemudNetworkIfaceConnect(conn, driver, vm, net, vlan);
|
|
|
|
if (tap == NULL)
|
|
|
|
goto error;
|
|
|
|
ADD_ARG(tap);
|
|
|
|
break;
|
|
|
|
}
|
2007-03-13 22:43:22 +00:00
|
|
|
|
|
|
|
case QEMUD_NET_ETHERNET:
|
|
|
|
{
|
|
|
|
char arg[PATH_MAX];
|
|
|
|
if (snprintf(arg, PATH_MAX-1, "tap,ifname=%s,script=%s,vlan=%d",
|
|
|
|
net->dst.ethernet.ifname,
|
|
|
|
net->dst.ethernet.script,
|
|
|
|
vlan) >= (PATH_MAX-1))
|
|
|
|
goto error;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT(arg);
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_NET_CLIENT:
|
|
|
|
case QEMUD_NET_SERVER:
|
|
|
|
case QEMUD_NET_MCAST:
|
|
|
|
{
|
|
|
|
char arg[PATH_MAX];
|
|
|
|
const char *mode = NULL;
|
|
|
|
switch (net->type) {
|
|
|
|
case QEMUD_NET_CLIENT:
|
|
|
|
mode = "connect";
|
|
|
|
break;
|
|
|
|
case QEMUD_NET_SERVER:
|
|
|
|
mode = "listen";
|
|
|
|
break;
|
|
|
|
case QEMUD_NET_MCAST:
|
|
|
|
mode = "mcast";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (snprintf(arg, PATH_MAX-1, "socket,%s=%s:%d,vlan=%d",
|
|
|
|
mode,
|
|
|
|
net->dst.socket.address,
|
|
|
|
net->dst.socket.port,
|
|
|
|
vlan) >= (PATH_MAX-1))
|
|
|
|
goto error;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT(arg);
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_NET_USER:
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
char arg[PATH_MAX];
|
|
|
|
if (snprintf(arg, PATH_MAX-1, "user,vlan=%d", vlan) >= (PATH_MAX-1))
|
|
|
|
goto error;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT(arg);
|
2007-03-13 22:43:22 +00:00
|
|
|
}
|
2007-02-14 16:09:37 +00:00
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
net = net->next;
|
2007-03-13 22:43:22 +00:00
|
|
|
vlan++;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
if (!serial) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-serial");
|
|
|
|
ADD_ARG_LIT("none");
|
2008-04-25 20:46:13 +00:00
|
|
|
} else {
|
|
|
|
while (serial) {
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-serial");
|
|
|
|
ADD_ARG_LIT(buf);
|
2008-04-25 20:46:13 +00:00
|
|
|
|
|
|
|
serial = serial->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parallel) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-parallel");
|
|
|
|
ADD_ARG_LIT("none");
|
2008-04-25 20:46:13 +00:00
|
|
|
} else {
|
|
|
|
while (parallel) {
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-parallel");
|
|
|
|
ADD_ARG_LIT(buf);
|
2008-04-25 20:46:13 +00:00
|
|
|
|
|
|
|
parallel = parallel->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-usb");
|
2007-07-18 21:08:22 +00:00
|
|
|
while (input) {
|
|
|
|
if (input->bus == QEMU_INPUT_BUS_USB) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-usbdevice");
|
|
|
|
ADD_ARG_LIT(input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
|
2007-07-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
input = input->next;
|
|
|
|
}
|
|
|
|
|
2007-02-14 17:05:55 +00:00
|
|
|
if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) {
|
2007-10-12 16:05:44 +00:00
|
|
|
char vncdisplay[PATH_MAX];
|
2007-02-23 17:15:18 +00:00
|
|
|
int ret;
|
2007-10-12 16:05:44 +00:00
|
|
|
|
|
|
|
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
|
|
|
|
char options[PATH_MAX] = "";
|
|
|
|
if (driver->vncTLS) {
|
|
|
|
strcat(options, ",tls");
|
|
|
|
if (driver->vncTLSx509verify) {
|
|
|
|
strcat(options, ",x509verify=");
|
|
|
|
} else {
|
|
|
|
strcat(options, ",x509=");
|
|
|
|
}
|
|
|
|
strncat(options, driver->vncTLSx509certdir,
|
|
|
|
sizeof(options) - (strlen(driver->vncTLSx509certdir)-1));
|
|
|
|
options[sizeof(options)-1] = '\0';
|
|
|
|
}
|
|
|
|
ret = snprintf(vncdisplay, sizeof(vncdisplay), "%s:%d%s",
|
2007-07-24 14:30:05 +00:00
|
|
|
vm->def->vncListen,
|
2007-10-12 16:05:44 +00:00
|
|
|
vm->def->vncActivePort - 5900,
|
|
|
|
options);
|
|
|
|
} else {
|
2007-07-24 14:30:05 +00:00
|
|
|
ret = snprintf(vncdisplay, sizeof(vncdisplay), "%d",
|
|
|
|
vm->def->vncActivePort - 5900);
|
2007-10-12 16:05:44 +00:00
|
|
|
}
|
2007-07-24 14:30:05 +00:00
|
|
|
if (ret < 0 || ret >= (int)sizeof(vncdisplay))
|
2007-02-23 17:15:18 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-vnc");
|
|
|
|
ADD_ARG_LIT(vncdisplay);
|
2008-01-15 15:18:33 +00:00
|
|
|
if (vm->def->keymap) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-k");
|
|
|
|
ADD_ARG_LIT(vm->def->keymap);
|
2008-01-15 15:18:33 +00:00
|
|
|
}
|
2007-02-14 17:05:55 +00:00
|
|
|
} else if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
|
2007-07-24 14:30:05 +00:00
|
|
|
/* Nada - we added -nographic earlier in this function */
|
2007-02-14 01:40:09 +00:00
|
|
|
} else {
|
|
|
|
/* SDL is the default. no args needed */
|
|
|
|
}
|
|
|
|
|
2008-05-07 14:04:40 +00:00
|
|
|
/* Add sound hardware */
|
|
|
|
if (sound) {
|
|
|
|
int size = 100;
|
2008-05-29 19:20:22 +00:00
|
|
|
char *modstr;
|
|
|
|
if (VIR_ALLOC_N(modstr, size+1) < 0)
|
2008-05-07 14:04:40 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
while(sound && size > 0) {
|
|
|
|
const char *model = qemudSoundModelToString(sound->model);
|
|
|
|
if (!model) {
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(modstr);
|
2008-05-13 09:15:11 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("invalid sound model"));
|
|
|
|
goto error;
|
2008-05-07 14:04:40 +00:00
|
|
|
}
|
|
|
|
strncat(modstr, model, size);
|
|
|
|
size -= strlen(model);
|
|
|
|
sound = sound->next;
|
|
|
|
if (sound)
|
|
|
|
strncat(modstr, ",", size--);
|
|
|
|
}
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-soundhw");
|
|
|
|
ADD_ARG(modstr);
|
2008-05-07 14:04:40 +00:00
|
|
|
}
|
|
|
|
|
2007-08-14 01:28:47 +00:00
|
|
|
if (vm->migrateFrom[0]) {
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG_LIT("-incoming");
|
|
|
|
ADD_ARG_LIT(vm->migrateFrom);
|
2007-08-14 01:28:47 +00:00
|
|
|
}
|
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
ADD_ARG(NULL);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-22 23:45:09 +00:00
|
|
|
*retargv = qargv;
|
2007-02-14 01:40:09 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
no_memory:
|
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 argv string"));
|
2007-02-14 16:09:37 +00:00
|
|
|
error:
|
|
|
|
if (vm->tapfds) {
|
|
|
|
for (i = 0; vm->tapfds[i] != -1; i++)
|
|
|
|
close(vm->tapfds[i]);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(vm->tapfds);
|
2007-02-14 16:09:37 +00:00
|
|
|
vm->tapfds = NULL;
|
|
|
|
vm->ntapfds = 0;
|
|
|
|
}
|
2008-05-22 23:45:09 +00:00
|
|
|
if (qargv) {
|
|
|
|
for (i = 0 ; i < qargc ; i++)
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE((qargv)[i]);
|
|
|
|
VIR_FREE(qargv);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
return -1;
|
2008-05-22 23:45:09 +00:00
|
|
|
|
|
|
|
#undef ADD_ARG
|
|
|
|
#undef ADD_ARG_LIT
|
|
|
|
#undef ADD_ARG_SPACE
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Save a guest's config data into a persistent file */
|
2007-07-12 15:09:01 +00:00
|
|
|
static int qemudSaveConfig(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm *vm,
|
|
|
|
struct qemud_vm_def *def) {
|
2007-02-14 01:40:09 +00:00
|
|
|
char *xml;
|
|
|
|
int fd = -1, ret = -1;
|
|
|
|
int towrite;
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
if (!(xml = qemudGenerateXML(conn, driver, vm, def, 0)))
|
2007-02-14 01:40:09 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((fd = open(vm->configFile,
|
|
|
|
O_WRONLY | O_CREAT | O_TRUNC,
|
|
|
|
S_IRUSR | S_IWUSR )) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("cannot create config file %s: %s"),
|
2007-02-20 19:09:44 +00:00
|
|
|
vm->configFile, strerror(errno));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
towrite = strlen(xml);
|
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(fd, xml, towrite) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("cannot write config file %s: %s"),
|
2007-02-20 19:09:44 +00:00
|
|
|
vm->configFile, strerror(errno));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (close(fd) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("cannot save config file %s: %s"),
|
2007-02-20 19:09:44 +00:00
|
|
|
vm->configFile, strerror(errno));
|
2007-02-14 01:40:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (fd != -1)
|
|
|
|
close(fd);
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(xml);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-10-27 01:18:38 +00:00
|
|
|
struct qemud_vm_device_def *
|
|
|
|
qemudParseVMDeviceDef(virConnectPtr conn,
|
2008-05-15 16:11:40 +00:00
|
|
|
const struct qemud_vm_def *def,
|
2007-10-27 01:18:38 +00:00
|
|
|
const char *xmlStr)
|
|
|
|
{
|
|
|
|
xmlDocPtr xml;
|
|
|
|
xmlNodePtr node;
|
2008-05-29 19:20:22 +00:00
|
|
|
struct qemud_vm_device_def *dev;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(dev) < 0) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-10-27 01:18:38 +00:00
|
|
|
|
|
|
|
if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "device.xml", NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL);
|
2008-05-29 19:20:22 +00:00
|
|
|
goto error;
|
2007-10-27 01:18:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
node = xmlDocGetRootElement(xml);
|
|
|
|
if (node == 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_XML_ERROR,
|
|
|
|
"%s", _("missing root element"));
|
2007-10-27 01:18:38 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
|
|
|
|
dev->type = QEMUD_DEVICE_DISK;
|
|
|
|
qemudParseDiskXML(conn, &(dev->data.disk), node);
|
2008-06-13 07:56:59 +00:00
|
|
|
} else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
|
2007-10-27 01:18:38 +00:00
|
|
|
dev->type = QEMUD_DEVICE_NET;
|
|
|
|
qemudParseInterfaceXML(conn, &(dev->data.net), node);
|
|
|
|
} else if (xmlStrEqual(node->name, BAD_CAST "input")) {
|
|
|
|
dev->type = QEMUD_DEVICE_DISK;
|
2008-05-15 16:11:40 +00:00
|
|
|
qemudParseInputXML(conn, def, &(dev->data.input), node);
|
2008-05-07 14:04:40 +00:00
|
|
|
} else if (xmlStrEqual(node->name, BAD_CAST "sound")) {
|
|
|
|
dev->type = QEMUD_DEVICE_SOUND;
|
|
|
|
qemudParseSoundXML(conn, &(dev->data.sound), node);
|
2007-10-27 01:18:38 +00:00
|
|
|
} else {
|
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_XML_ERROR,
|
|
|
|
"%s", _("unknown device type"));
|
2007-10-27 01:18:38 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
|
|
|
|
return dev;
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (xml) xmlFreeDoc(xml);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(dev);
|
2007-10-27 01:18:38 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm_def *
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudParseVMDef(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-23 08:48:02 +00:00
|
|
|
const char *xmlStr,
|
|
|
|
const char *displayName) {
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlDocPtr xml;
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm_def *def = NULL;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "domain.xml", NULL,
|
2007-02-14 01:40:09 +00:00
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL);
|
2007-02-14 01:40:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
def = qemudParseXML(conn, driver, xml);
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
xmlFreeDoc(xml);
|
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct qemud_vm *
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudAssignVMDef(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm_def *def)
|
|
|
|
{
|
|
|
|
struct qemud_vm *vm = NULL;
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
if ((vm = qemudFindVMByName(driver, def->name))) {
|
2007-02-23 08:39:49 +00:00
|
|
|
if (!qemudIsActiveVM(vm)) {
|
2007-02-14 17:05:55 +00:00
|
|
|
qemudFreeVMDef(vm->def);
|
|
|
|
vm->def = def;
|
|
|
|
} else {
|
|
|
|
if (vm->newDef)
|
|
|
|
qemudFreeVMDef(vm->newDef);
|
|
|
|
vm->newDef = def;
|
|
|
|
}
|
2007-09-21 21:20:32 +00:00
|
|
|
/* Reset version, because the emulator path might have changed */
|
|
|
|
vm->qemuVersion = 0;
|
|
|
|
vm->qemuCmdFlags = 0;
|
2007-02-23 08:48:02 +00:00
|
|
|
return vm;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC(vm) < 0) {
|
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 vm string"));
|
2007-02-23 08:48:02 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-08-14 01:28:47 +00:00
|
|
|
vm->stdin = -1;
|
2007-02-23 08:48:02 +00:00
|
|
|
vm->stdout = -1;
|
|
|
|
vm->stderr = -1;
|
|
|
|
vm->monitor = -1;
|
|
|
|
vm->pid = -1;
|
|
|
|
vm->id = -1;
|
2007-06-26 22:39:53 +00:00
|
|
|
vm->state = VIR_DOMAIN_SHUTOFF;
|
2007-02-23 08:48:02 +00:00
|
|
|
vm->def = def;
|
2007-06-26 22:13:21 +00:00
|
|
|
vm->next = driver->vms;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
driver->vms = vm;
|
|
|
|
driver->ninactivevms++;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
|
|
|
return vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-06-26 22:13:21 +00:00
|
|
|
qemudRemoveInactiveVM(struct qemud_driver *driver,
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm *vm)
|
|
|
|
{
|
|
|
|
struct qemud_vm *prev = NULL, *curr;
|
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
curr = driver->vms;
|
2007-02-23 08:48:02 +00:00
|
|
|
while (curr != vm) {
|
|
|
|
prev = curr;
|
|
|
|
curr = curr->next;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
if (curr) {
|
|
|
|
if (prev)
|
|
|
|
prev->next = curr->next;
|
|
|
|
else
|
2007-06-26 22:13:21 +00:00
|
|
|
driver->vms = curr->next;
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2007-06-26 22:13:21 +00:00
|
|
|
driver->ninactivevms--;
|
2007-02-14 17:05:55 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
qemudFreeVM(vm);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
int
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudSaveVMDef(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver,
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm *vm,
|
|
|
|
struct qemud_vm_def *def) {
|
|
|
|
if (vm->configFile[0] == '\0') {
|
|
|
|
int err;
|
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if ((err = virFileMakePath(driver->configDir))) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
_("cannot create config directory %s: %s"),
|
2007-06-26 22:13:21 +00:00
|
|
|
driver->configDir, strerror(err));
|
2007-02-23 08:48:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if (virFileBuildPath(driver->configDir, def->name, ".xml",
|
|
|
|
vm->configFile, PATH_MAX) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("cannot construct config file path"));
|
2007-02-23 08:48:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2007-02-23 09:07:41 +00:00
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if (virFileBuildPath(driver->autostartDir, def->name, ".xml",
|
|
|
|
vm->autostartLink, PATH_MAX) < 0) {
|
2007-07-12 15:09:01 +00:00
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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
|
|
|
"%s", _("cannot construct autostart link path"));
|
2007-02-23 09:07:41 +00:00
|
|
|
vm->configFile[0] = '\0';
|
|
|
|
return -1;
|
|
|
|
}
|
2007-02-23 08:48:02 +00:00
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
return qemudSaveConfig(conn, driver, vm, def);
|
2007-02-23 08:48:02 +00:00
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-23 09:07:41 +00:00
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
static struct qemud_vm *
|
2007-06-26 22:13:21 +00:00
|
|
|
qemudLoadConfig(struct qemud_driver *driver,
|
2007-02-23 08:48:02 +00:00
|
|
|
const char *file,
|
|
|
|
const char *path,
|
2007-02-23 09:07:41 +00:00
|
|
|
const char *xml,
|
|
|
|
const char *autostartLink) {
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm_def *def;
|
|
|
|
struct qemud_vm *vm;
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
if (!(def = qemudParseVMDef(NULL, driver, xml, file))) {
|
2007-06-26 20:51:00 +00:00
|
|
|
virErrorPtr err = virGetLastError();
|
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
|
|
|
qemudLog(QEMUD_WARN, _("Error parsing QEMU guest config '%s' : %s"),
|
|
|
|
path, (err ? err->message :
|
|
|
|
_("BUG: unknown error - please report it\n")));
|
2007-02-23 08:48:02 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if (!virFileMatchesNameSuffix(file, def->name, ".xml")) {
|
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
|
|
|
qemudLog(QEMUD_WARN,
|
|
|
|
_("QEMU guest config filename '%s'"
|
|
|
|
" does not match guest name '%s'"),
|
2007-02-23 08:48:02 +00:00
|
|
|
path, def->name);
|
|
|
|
qemudFreeVMDef(def);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
if (!(vm = qemudAssignVMDef(NULL, driver, def))) {
|
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
|
|
|
qemudLog(QEMUD_WARN,
|
|
|
|
_("Failed to load QEMU guest config '%s': out of memory"),
|
|
|
|
path);
|
2007-02-23 08:48:02 +00:00
|
|
|
qemudFreeVMDef(def);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(vm->configFile, path, PATH_MAX);
|
|
|
|
vm->configFile[PATH_MAX-1] = '\0';
|
|
|
|
|
2007-02-23 09:07:41 +00:00
|
|
|
strncpy(vm->autostartLink, autostartLink, PATH_MAX);
|
|
|
|
vm->autostartLink[PATH_MAX-1] = '\0';
|
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
vm->autostart = virFileLinkPointsTo(vm->autostartLink, vm->configFile);
|
2007-02-23 09:07:41 +00:00
|
|
|
|
2007-02-23 08:48:02 +00:00
|
|
|
return vm;
|
|
|
|
}
|
|
|
|
|
2007-02-14 15:53:14 +00:00
|
|
|
static
|
2007-06-26 22:13:21 +00:00
|
|
|
int qemudScanConfigDir(struct qemud_driver *driver,
|
2007-02-14 16:02:40 +00:00
|
|
|
const char *configDir,
|
2008-07-11 17:33:45 +00:00
|
|
|
const char *autostartDir) {
|
2007-02-14 01:40:09 +00:00
|
|
|
DIR *dir;
|
|
|
|
struct dirent *entry;
|
|
|
|
|
2007-02-14 15:53:14 +00:00
|
|
|
if (!(dir = opendir(configDir))) {
|
2007-02-14 01:40:09 +00:00
|
|
|
if (errno == ENOENT)
|
|
|
|
return 0;
|
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
|
|
|
qemudLog(QEMUD_ERR, _("Failed to open dir '%s': %s"),
|
2007-02-16 18:30:55 +00:00
|
|
|
configDir, strerror(errno));
|
2007-02-14 01:40:09 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((entry = readdir(dir))) {
|
2008-01-07 15:21:33 +00:00
|
|
|
char *xml;
|
2007-02-23 08:48:02 +00:00
|
|
|
char path[PATH_MAX];
|
2007-02-23 09:07:41 +00:00
|
|
|
char autostartLink[PATH_MAX];
|
2007-02-23 08:48:02 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
if (entry->d_name[0] == '.')
|
|
|
|
continue;
|
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if (!virFileHasSuffix(entry->d_name, ".xml"))
|
2007-02-23 14:33:37 +00:00
|
|
|
continue;
|
|
|
|
|
2007-12-03 14:30:46 +00:00
|
|
|
if (virFileBuildPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) {
|
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
|
|
|
qemudLog(QEMUD_WARN, _("Config filename '%s/%s' is too long"),
|
2007-02-23 08:48:02 +00:00
|
|
|
configDir, entry->d_name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if (virFileBuildPath(autostartDir, entry->d_name, NULL,
|
|
|
|
autostartLink, PATH_MAX) < 0) {
|
|
|
|
qemudLog(QEMUD_WARN, _("Autostart link path '%s/%s' is too long"),
|
2007-02-23 09:07:41 +00:00
|
|
|
autostartDir, entry->d_name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:21:33 +00:00
|
|
|
if (virFileReadAll(path, QEMUD_MAX_XML_LEN, &xml) < 0)
|
2007-02-14 01:40:09 +00:00
|
|
|
continue;
|
|
|
|
|
2008-07-11 17:33:45 +00:00
|
|
|
qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink);
|
2008-01-07 15:21:33 +00:00
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(xml);
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dir);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-02-14 15:53:14 +00:00
|
|
|
/* Scan for all guest and network config files */
|
2007-06-26 22:13:21 +00:00
|
|
|
int qemudScanConfigs(struct qemud_driver *driver) {
|
2008-07-11 17:33:45 +00:00
|
|
|
if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir) < 0)
|
2007-02-23 09:11:52 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
2007-02-14 15:53:14 +00:00
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
static int qemudGenerateXMLChar(virBufferPtr buf,
|
|
|
|
const struct qemud_vm_chr_def *dev,
|
|
|
|
const char *type)
|
|
|
|
{
|
|
|
|
const char *const types[] = {
|
|
|
|
"null",
|
|
|
|
"vc",
|
|
|
|
"pty",
|
|
|
|
"dev",
|
|
|
|
"file",
|
|
|
|
"pipe",
|
|
|
|
"stdio",
|
|
|
|
"udp",
|
|
|
|
"tcp",
|
|
|
|
"unix"
|
|
|
|
};
|
2008-05-09 16:41:19 +00:00
|
|
|
verify_true(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);
|
2008-04-25 20:46:13 +00:00
|
|
|
|
|
|
|
/* Compat with legacy <console tty='/dev/pts/5'/> syntax */
|
|
|
|
if (STREQ(type, "console") &&
|
|
|
|
dev->srcType == QEMUD_CHR_SRC_TYPE_PTY &&
|
|
|
|
dev->srcData.file.path[0] != '\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <%s type='%s' tty='%s'>\n",
|
|
|
|
type, types[dev->srcType],
|
|
|
|
dev->srcData.file.path);
|
2008-04-25 20:46:13 +00:00
|
|
|
} else {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <%s type='%s'>\n",
|
|
|
|
type, types[dev->srcType]);
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (dev->srcType) {
|
|
|
|
case QEMUD_CHR_SRC_TYPE_NULL:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_VC:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_STDIO:
|
|
|
|
/* nada */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PTY:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_DEV:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_FILE:
|
|
|
|
case QEMUD_CHR_SRC_TYPE_PIPE:
|
|
|
|
if (dev->srcType != QEMUD_CHR_SRC_TYPE_PTY ||
|
|
|
|
dev->srcData.file.path[0]) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source path='%s'/>\n",
|
|
|
|
dev->srcData.file.path);
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UDP:
|
|
|
|
if (dev->srcData.udp.bindService[0] != '\0' &&
|
|
|
|
dev->srcData.udp.bindHost[0] != '\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='bind' host='%s' service='%s'/>\n",
|
|
|
|
dev->srcData.udp.bindHost,
|
|
|
|
dev->srcData.udp.bindService);
|
2008-04-25 20:46:13 +00:00
|
|
|
} else if (dev->srcData.udp.bindHost[0] !='\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='bind' host='%s'/>\n",
|
|
|
|
dev->srcData.udp.bindHost);
|
2008-04-25 20:46:13 +00:00
|
|
|
} else if (dev->srcData.udp.bindService[0] != '\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='bind' service='%s'/>\n",
|
|
|
|
dev->srcData.udp.bindService);
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dev->srcData.udp.connectService[0] != '\0' &&
|
|
|
|
dev->srcData.udp.connectHost[0] != '\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='connect' host='%s' service='%s'/>\n",
|
|
|
|
dev->srcData.udp.connectHost,
|
|
|
|
dev->srcData.udp.connectService);
|
2008-04-25 20:46:13 +00:00
|
|
|
} else if (dev->srcData.udp.connectHost[0] != '\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='connect' host='%s'/>\n",
|
|
|
|
dev->srcData.udp.connectHost);
|
2008-04-25 20:46:13 +00:00
|
|
|
} else if (dev->srcData.udp.connectService[0] != '\0') {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='connect' service='%s'/>\n",
|
|
|
|
dev->srcData.udp.connectService);
|
2008-04-25 20:46:13 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_TCP:
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='%s' host='%s' service='%s'/>\n",
|
|
|
|
dev->srcData.tcp.listen ? "bind" : "connect",
|
|
|
|
dev->srcData.tcp.host,
|
|
|
|
dev->srcData.tcp.service);
|
|
|
|
virBufferVSprintf(buf, " <protocol type='%s'/>\n",
|
|
|
|
dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET
|
|
|
|
? "telnet" : "raw");
|
2008-04-25 20:46:13 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_CHR_SRC_TYPE_UNIX:
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <source mode='%s' path='%s'/>\n",
|
|
|
|
dev->srcData.nix.listen ? "bind" : "connect",
|
|
|
|
dev->srcData.nix.path);
|
2008-04-25 20:46:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " <target port='%d'/>\n",
|
|
|
|
dev->dstPort);
|
2008-04-25 20:46:13 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(buf, " </%s>\n",
|
|
|
|
type);
|
2008-04-25 20:46:13 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
/* Generate an XML document describing the guest's configuration */
|
2007-07-12 15:09:01 +00:00
|
|
|
char *qemudGenerateXML(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver ATTRIBUTE_UNUSED,
|
2007-02-23 08:48:02 +00:00
|
|
|
struct qemud_vm *vm,
|
|
|
|
struct qemud_vm_def *def,
|
|
|
|
int live) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
2007-02-14 01:40:09 +00:00
|
|
|
unsigned char *uuid;
|
2007-08-09 20:19:12 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2008-04-25 20:46:13 +00:00
|
|
|
const struct qemud_vm_disk_def *disk;
|
|
|
|
const struct qemud_vm_net_def *net;
|
|
|
|
const struct qemud_vm_input_def *input;
|
2008-05-07 14:04:40 +00:00
|
|
|
const struct qemud_vm_sound_def *sound;
|
2008-04-25 20:46:13 +00:00
|
|
|
const struct qemud_vm_chr_def *chr;
|
2008-05-29 19:20:22 +00:00
|
|
|
const char *type = NULL, *tmp;
|
2008-05-22 16:27:20 +00:00
|
|
|
int n, allones = 1;
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-07 16:16:44 +00:00
|
|
|
if (!(type = qemudVirtTypeToString(def->virtType))) {
|
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_INTERNAL_ERROR,
|
|
|
|
_("unexpected domain type %d"), def->virtType);
|
2007-02-14 01:40:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (qemudIsActiveVM(vm) && live)
|
|
|
|
virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id);
|
|
|
|
else
|
|
|
|
virBufferVSprintf(&buf, "<domain type='%s'>\n", type);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <name>%s</name>\n", def->name);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-14 17:05:55 +00:00
|
|
|
uuid = def->uuid;
|
2007-08-09 20:19:12 +00:00
|
|
|
virUUIDFormat(uuid, uuidstr);
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <memory>%lu</memory>\n", def->maxmem);
|
|
|
|
virBufferVSprintf(&buf, " <currentMemory>%lu</currentMemory>\n", def->memory);
|
2008-05-22 16:27:20 +00:00
|
|
|
|
|
|
|
for (n = 0 ; n < QEMUD_CPUMASK_LEN ; n++)
|
|
|
|
if (def->cpumask[n] != 1)
|
|
|
|
allones = 0;
|
|
|
|
|
|
|
|
if (allones) {
|
|
|
|
virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n", def->vcpus);
|
|
|
|
} else {
|
|
|
|
char *cpumask = NULL;
|
|
|
|
if ((cpumask = virSaveCpuSet(conn, def->cpumask, QEMUD_CPUMASK_LEN)) == NULL) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
|
|
|
"%s", _("allocating cpu mask"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
virBufferVSprintf(&buf, " <vcpu cpuset='%s'>%d</vcpu>\n", cpumask, def->vcpus);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(cpumask);
|
2008-05-22 16:27:20 +00:00
|
|
|
}
|
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
if (def->os.bootloader[0])
|
|
|
|
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", def->os.bootloader);
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <os>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (def->virtType == QEMUD_VIRT_QEMU)
|
|
|
|
virBufferVSprintf(&buf, " <type arch='%s' machine='%s'>%s</type>\n",
|
|
|
|
def->os.arch, def->os.machine, def->os.type);
|
|
|
|
else
|
|
|
|
virBufferVSprintf(&buf, " <type>%s</type>\n", def->os.type);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-15 16:21:11 +00:00
|
|
|
if (!def->os.bootloader[0]) {
|
|
|
|
if (def->os.kernel[0])
|
|
|
|
virBufferVSprintf(&buf, " <kernel>%s</kernel>\n", def->os.kernel);
|
|
|
|
if (def->os.initrd[0])
|
|
|
|
virBufferVSprintf(&buf, " <initrd>%s</initrd>\n", def->os.initrd);
|
|
|
|
if (def->os.cmdline[0])
|
|
|
|
virBufferVSprintf(&buf, " <cmdline>%s</cmdline>\n", def->os.cmdline);
|
|
|
|
|
|
|
|
for (n = 0 ; n < def->os.nBootDevs ; n++) {
|
|
|
|
const char *boottype = "hd";
|
|
|
|
switch (def->os.bootDevs[n]) {
|
|
|
|
case QEMUD_BOOT_FLOPPY:
|
|
|
|
boottype = "fd";
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_DISK:
|
|
|
|
boottype = "hd";
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_CDROM:
|
|
|
|
boottype = "cdrom";
|
|
|
|
break;
|
|
|
|
case QEMUD_BOOT_NET:
|
|
|
|
boottype = "network";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
virBufferVSprintf(&buf, " <boot dev='%s'/>\n", boottype);
|
|
|
|
}
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " </os>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-14 21:47:59 +00:00
|
|
|
if (def->features & QEMUD_FEATURE_ACPI) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <features>\n");
|
|
|
|
virBufferAddLit(&buf, " <acpi/>\n");
|
|
|
|
virBufferAddLit(&buf, " </features>\n");
|
2007-02-14 21:47:59 +00:00
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
|
2007-07-16 21:30:30 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <on_poweroff>destroy</on_poweroff>\n");
|
|
|
|
if (def->noReboot)
|
|
|
|
virBufferAddLit(&buf, " <on_reboot>destroy</on_reboot>\n");
|
|
|
|
else
|
|
|
|
virBufferAddLit(&buf, " <on_reboot>restart</on_reboot>\n");
|
2007-02-14 21:47:59 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <on_crash>destroy</on_crash>\n");
|
|
|
|
virBufferAddLit(&buf, " <devices>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <emulator>%s</emulator>\n", def->os.binary);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-14 17:05:55 +00:00
|
|
|
disk = def->disks;
|
2007-02-14 01:40:09 +00:00
|
|
|
while (disk) {
|
|
|
|
const char *types[] = {
|
|
|
|
"block",
|
|
|
|
"file",
|
|
|
|
};
|
|
|
|
const char *typeAttrs[] = {
|
|
|
|
"dev",
|
|
|
|
"file",
|
|
|
|
};
|
|
|
|
const char *devices[] = {
|
|
|
|
"disk",
|
|
|
|
"cdrom",
|
|
|
|
"floppy",
|
|
|
|
};
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <disk type='%s' device='%s'>\n",
|
|
|
|
types[disk->type], devices[disk->device]);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-03-13 09:17:45 +00:00
|
|
|
if (disk->src[0])
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <source %s='%s'/>\n",
|
|
|
|
typeAttrs[disk->type], disk->src);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-05-09 16:41:19 +00:00
|
|
|
virBufferVSprintf(&buf, " <target dev='%s' bus='%s'/>\n",
|
|
|
|
disk->dst, qemudBusIdToName(disk->bus, 0));
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
if (disk->readonly)
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <readonly/>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " </disk>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
disk = disk->next;
|
|
|
|
}
|
|
|
|
|
2007-02-14 17:05:55 +00:00
|
|
|
net = def->nets;
|
2007-02-14 15:51:53 +00:00
|
|
|
while (net) {
|
2007-02-14 01:40:09 +00:00
|
|
|
const char *types[] = {
|
|
|
|
"user",
|
2007-03-13 22:43:22 +00:00
|
|
|
"ethernet",
|
2007-02-14 01:40:09 +00:00
|
|
|
"server",
|
|
|
|
"client",
|
|
|
|
"mcast",
|
2007-02-15 19:08:08 +00:00
|
|
|
"network",
|
2007-03-13 22:43:22 +00:00
|
|
|
"bridge",
|
2007-02-14 01:40:09 +00:00
|
|
|
};
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <interface type='%s'>\n",
|
|
|
|
types[net->type]);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <mac address='%02x:%02x:%02x:%02x:%02x:%02x'/>\n",
|
|
|
|
net->mac[0], net->mac[1], net->mac[2],
|
|
|
|
net->mac[3], net->mac[4], net->mac[5]);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
switch (net->type) {
|
|
|
|
case QEMUD_NET_NETWORK:
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <source network='%s'/>\n", net->dst.network.name);
|
2007-02-14 16:09:37 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (net->dst.network.ifname[0] != '\0')
|
|
|
|
virBufferVSprintf(&buf, " <target dev='%s'/>\n", net->dst.network.ifname);
|
2007-03-13 22:43:22 +00:00
|
|
|
break;
|
2007-02-14 16:09:37 +00:00
|
|
|
|
2007-03-13 22:43:22 +00:00
|
|
|
case QEMUD_NET_ETHERNET:
|
2008-04-28 15:14:59 +00:00
|
|
|
if (net->dst.ethernet.ifname[0] != '\0')
|
|
|
|
virBufferVSprintf(&buf, " <target dev='%s'/>\n", net->dst.ethernet.ifname);
|
|
|
|
if (net->dst.ethernet.script[0] != '\0')
|
|
|
|
virBufferVSprintf(&buf, " <script path='%s'/>\n", net->dst.ethernet.script);
|
2007-03-13 22:43:22 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_NET_BRIDGE:
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <source bridge='%s'/>\n", net->dst.bridge.brname);
|
|
|
|
if (net->dst.bridge.ifname[0] != '\0')
|
|
|
|
virBufferVSprintf(&buf, " <target dev='%s'/>\n", net->dst.bridge.ifname);
|
2007-03-13 22:43:22 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_NET_SERVER:
|
|
|
|
case QEMUD_NET_CLIENT:
|
|
|
|
case QEMUD_NET_MCAST:
|
2008-04-28 15:14:59 +00:00
|
|
|
if (net->dst.socket.address[0] != '\0')
|
|
|
|
virBufferVSprintf(&buf, " <source address='%s' port='%d'/>\n",
|
|
|
|
net->dst.socket.address, net->dst.socket.port);
|
|
|
|
else
|
|
|
|
virBufferVSprintf(&buf, " <source port='%d'/>\n",
|
|
|
|
net->dst.socket.port);
|
2007-02-14 16:09:37 +00:00
|
|
|
}
|
|
|
|
|
2008-04-30 12:30:55 +00:00
|
|
|
if (net->model && net->model[0] != '\0') {
|
|
|
|
virBufferVSprintf(&buf, " <model type='%s'/>\n",
|
|
|
|
net->model);
|
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " </interface>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2007-02-14 15:51:53 +00:00
|
|
|
net = net->next;
|
2007-02-14 01:40:09 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 20:46:13 +00:00
|
|
|
chr = def->serials;
|
|
|
|
while (chr) {
|
2008-04-28 15:14:59 +00:00
|
|
|
if (qemudGenerateXMLChar(&buf, chr, "serial") < 0)
|
2008-04-25 20:46:13 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
chr = chr->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
chr = def->parallels;
|
|
|
|
while (chr) {
|
2008-04-28 15:14:59 +00:00
|
|
|
if (qemudGenerateXMLChar(&buf, chr, "parallel") < 0)
|
2008-04-25 20:46:13 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
chr = chr->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* First serial device is the primary console */
|
|
|
|
if (def->nserials > 0 &&
|
2008-04-28 15:14:59 +00:00
|
|
|
qemudGenerateXMLChar(&buf, def->serials, "console") < 0)
|
2008-04-25 20:46:13 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
2007-07-18 21:08:22 +00:00
|
|
|
input = def->inputs;
|
|
|
|
while (input) {
|
2008-05-15 16:11:40 +00:00
|
|
|
if (input->bus == QEMU_INPUT_BUS_USB)
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferVSprintf(&buf, " <input type='%s' bus='usb'/>\n",
|
|
|
|
input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
|
2007-07-18 21:08:22 +00:00
|
|
|
input = input->next;
|
|
|
|
}
|
|
|
|
/* If graphics is enable, add implicit mouse */
|
|
|
|
if (def->graphicsType != QEMUD_GRAPHICS_NONE)
|
2008-05-15 16:11:40 +00:00
|
|
|
virBufferVSprintf(&buf, " <input type='mouse' bus='%s'/>\n",
|
|
|
|
STREQ(def->os.type, "hvm") ? "ps2" : "xen");
|
2007-07-18 21:08:22 +00:00
|
|
|
|
2007-02-15 19:07:06 +00:00
|
|
|
switch (def->graphicsType) {
|
|
|
|
case QEMUD_GRAPHICS_VNC:
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <graphics type='vnc'");
|
2007-02-15 19:07:06 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (def->vncPort)
|
|
|
|
virBufferVSprintf(&buf, " port='%d'",
|
|
|
|
qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort);
|
2007-02-15 19:07:06 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (def->vncListen[0])
|
|
|
|
virBufferVSprintf(&buf, " listen='%s'",
|
|
|
|
def->vncListen);
|
2007-07-24 14:30:05 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (def->keymap)
|
|
|
|
virBufferVSprintf(&buf, " keymap='%s'",
|
|
|
|
def->keymap);
|
2008-01-15 15:18:33 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, "/>\n");
|
2007-02-15 19:07:06 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_GRAPHICS_SDL:
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " <graphics type='sdl'/>\n");
|
2007-02-15 19:07:06 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QEMUD_GRAPHICS_NONE:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-05-07 14:04:40 +00:00
|
|
|
sound = def->sounds;
|
|
|
|
while(sound) {
|
|
|
|
const char *model = qemudSoundModelToString(sound->model);
|
|
|
|
if (!model) {
|
|
|
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
2008-05-13 09:15:11 +00:00
|
|
|
"%s", _("invalid sound model"));
|
2008-05-07 14:04:40 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
virBufferVSprintf(&buf, " <sound model='%s'/>\n", model);
|
|
|
|
sound = sound->next;
|
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferAddLit(&buf, " </devices>\n");
|
|
|
|
virBufferAddLit(&buf, "</domain>\n");
|
2007-02-14 01:40:09 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferError(&buf))
|
2007-02-14 01:40:09 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
return virBufferContentAndReset(&buf);
|
2007-02-14 01:40:09 +00:00
|
|
|
|
|
|
|
no_memory:
|
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 generate XML: out of memory"));
|
2007-02-14 01:40:09 +00:00
|
|
|
cleanup:
|
2008-05-29 19:20:22 +00:00
|
|
|
tmp = virBufferContentAndReset(&buf);
|
|
|
|
VIR_FREE(tmp);
|
2007-02-14 01:40:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-12 15:09:01 +00:00
|
|
|
int qemudDeleteConfig(virConnectPtr conn,
|
|
|
|
struct qemud_driver *driver ATTRIBUTE_UNUSED,
|
2007-02-14 16:02:40 +00:00
|
|
|
const char *configFile,
|
|
|
|
const char *name) {
|
|
|
|
if (!configFile[0]) {
|
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_INTERNAL_ERROR,
|
|
|
|
_("no config file for %s"), name);
|
2007-02-14 01:40:09 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-02-14 16:02:40 +00:00
|
|
|
if (unlink(configFile) < 0) {
|
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_INTERNAL_ERROR,
|
|
|
|
_("cannot remove config for %s"), name);
|
2007-02-14 16:02:40 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2007-02-14 15:58:21 +00:00
|
|
|
|
2007-02-14 01:40:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-26 11:50:16 +00:00
|
|
|
#endif /* WITH_QEMU */
|