mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
Fri Feb 23 08:41:34 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.[ch]: significantly re-factor qemudLoadConfigXML() so that "parse the XML", "assign the def to a VM" and "save the XML" operations are in separate functions. Add qemudRemoveInactiveVM() and qemudRemoveInactiveNetwork(). Report errors when loading config files at startup. Check that a domain/network's name matches the config filename. * qemud/driver.c: update the Create() and Define() functions to explicitly parse/assign/save. Also, fix bug where if Create() failed, we would free the VM without removing it from the inactive list. * qemud/qemud.c: use qemudRemoveInactiveVM/Network()
This commit is contained in:
parent
593d20d400
commit
d954480892
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
|||||||
|
Fri Feb 23 08:41:34 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
|
* qemud/conf.[ch]: significantly re-factor qemudLoadConfigXML()
|
||||||
|
so that "parse the XML", "assign the def to a VM" and
|
||||||
|
"save the XML" operations are in separate functions.
|
||||||
|
Add qemudRemoveInactiveVM() and qemudRemoveInactiveNetwork().
|
||||||
|
Report errors when loading config files at startup. Check
|
||||||
|
that a domain/network's name matches the config filename.
|
||||||
|
|
||||||
|
* qemud/driver.c: update the Create() and Define() functions
|
||||||
|
to explicitly parse/assign/save. Also, fix bug where if
|
||||||
|
Create() failed, we would free the VM without removing it
|
||||||
|
from the inactive list.
|
||||||
|
|
||||||
|
* qemud/qemud.c: use qemudRemoveInactiveVM/Network()
|
||||||
|
|
||||||
Fri Feb 23 08:40:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
Fri Feb 23 08:40:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
* qemud/driver.[ch], qemud/dispatch.c: fix the fact that
|
* qemud/driver.[ch], qemud/dispatch.c: fix the fact that
|
||||||
|
435
qemud/conf.c
435
qemud/conf.c
@ -1140,22 +1140,14 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
|
|
||||||
/* Save a guest's config data into a persistent file */
|
/* Save a guest's config data into a persistent file */
|
||||||
static int qemudSaveConfig(struct qemud_server *server,
|
static int qemudSaveConfig(struct qemud_server *server,
|
||||||
struct qemud_vm *vm) {
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_def *def) {
|
||||||
char *xml;
|
char *xml;
|
||||||
int fd = -1, ret = -1;
|
int fd = -1, ret = -1;
|
||||||
int towrite;
|
int towrite;
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!(xml = qemudGenerateXML(server, vm, 0))) {
|
if (!(xml = qemudGenerateXML(server, vm, def, 0)))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = qemudEnsureDir(server->configDir))) {
|
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"cannot create config directory %s: %s",
|
|
||||||
server->configDir, strerror(err));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fd = open(vm->configFile,
|
if ((fd = open(vm->configFile,
|
||||||
O_WRONLY | O_CREAT | O_TRUNC,
|
O_WRONLY | O_CREAT | O_TRUNC,
|
||||||
@ -1192,31 +1184,33 @@ static int qemudSaveConfig(struct qemud_server *server,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct qemud_vm_def *
|
||||||
/* Create a qemud_vm instance, populating it based on the data
|
qemudParseVMDef(struct qemud_server *server,
|
||||||
* in a libvirt XML document describing the guest */
|
const char *xmlStr,
|
||||||
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
|
const char *displayName) {
|
||||||
const char *file,
|
|
||||||
const char *doc,
|
|
||||||
int save) {
|
|
||||||
struct qemud_vm_def *def = NULL;
|
|
||||||
struct qemud_vm *vm = NULL;
|
|
||||||
xmlDocPtr xml;
|
xmlDocPtr xml;
|
||||||
int newVM = 0;
|
struct qemud_vm_def *def = NULL;
|
||||||
|
|
||||||
if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "domain.xml", NULL,
|
if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "domain.xml", NULL,
|
||||||
XML_PARSE_NOENT | XML_PARSE_NONET |
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
||||||
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
||||||
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
|
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(def = qemudParseXML(server, xml))) {
|
def = qemudParseXML(server, xml);
|
||||||
xmlFreeDoc(xml);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct qemud_vm *
|
||||||
|
qemudAssignVMDef(struct qemud_server *server,
|
||||||
|
struct qemud_vm_def *def)
|
||||||
|
{
|
||||||
|
struct qemud_vm *vm = NULL;
|
||||||
|
|
||||||
if ((vm = qemudFindVMByName(server, def->name))) {
|
if ((vm = qemudFindVMByName(server, def->name))) {
|
||||||
if (!qemudIsActiveVM(vm)) {
|
if (!qemudIsActiveVM(vm)) {
|
||||||
qemudFreeVMDef(vm->def);
|
qemudFreeVMDef(vm->def);
|
||||||
@ -1226,63 +1220,87 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
|
|||||||
qemudFreeVMDef(vm->newDef);
|
qemudFreeVMDef(vm->newDef);
|
||||||
vm->newDef = def;
|
vm->newDef = def;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
|
|
||||||
qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
|
|
||||||
qemudFreeVMDef(def);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vm->stdout = -1;
|
return vm;
|
||||||
vm->stderr = -1;
|
|
||||||
vm->monitor = -1;
|
|
||||||
vm->pid = -1;
|
|
||||||
vm->id = -1;
|
|
||||||
vm->def = def;
|
|
||||||
newVM = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file) {
|
if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
|
||||||
strncpy(vm->configFile, file, PATH_MAX);
|
qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
|
||||||
vm->configFile[PATH_MAX-1] = '\0';
|
return NULL;
|
||||||
} else {
|
|
||||||
if (save) {
|
|
||||||
if (qemudMakeConfigPath(server->configDir, vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
|
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"cannot construct config file path");
|
|
||||||
if (newVM)
|
|
||||||
qemudFreeVM(vm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qemudSaveConfig(server, vm) < 0) {
|
|
||||||
if (newVM)
|
|
||||||
qemudFreeVM(vm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vm->configFile[0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newVM) {
|
vm->stdout = -1;
|
||||||
vm->next = server->vms;
|
vm->stderr = -1;
|
||||||
server->vms = vm;
|
vm->monitor = -1;
|
||||||
server->ninactivevms++;
|
vm->pid = -1;
|
||||||
}
|
vm->id = -1;
|
||||||
|
vm->def = def;
|
||||||
|
vm->next = server->vms;
|
||||||
|
|
||||||
|
server->vms = vm;
|
||||||
|
server->ninactivevms++;
|
||||||
|
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qemudRemoveInactiveVM(struct qemud_server *server,
|
||||||
|
struct qemud_vm *vm)
|
||||||
|
{
|
||||||
|
struct qemud_vm *prev = NULL, *curr;
|
||||||
|
|
||||||
|
curr = server->vms;
|
||||||
|
while (curr != vm) {
|
||||||
|
prev = curr;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr) {
|
||||||
|
if (prev)
|
||||||
|
prev->next = curr->next;
|
||||||
|
else
|
||||||
|
server->vms = curr->next;
|
||||||
|
|
||||||
|
server->ninactivevms--;
|
||||||
|
}
|
||||||
|
|
||||||
|
qemudFreeVM(vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemudSaveVMDef(struct qemud_server *server,
|
||||||
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_def *def) {
|
||||||
|
if (vm->configFile[0] == '\0') {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((err = qemudEnsureDir(server->configDir))) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"cannot create config directory %s: %s",
|
||||||
|
server->configDir, strerror(err));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemudMakeConfigPath(server->configDir, def->name, ".xml",
|
||||||
|
vm->configFile, PATH_MAX) < 0) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"cannot construct config file path");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return qemudSaveConfig(server, vm, def);
|
||||||
|
}
|
||||||
|
|
||||||
static int qemudSaveNetworkConfig(struct qemud_server *server,
|
static int qemudSaveNetworkConfig(struct qemud_server *server,
|
||||||
struct qemud_network *network) {
|
struct qemud_network *network,
|
||||||
|
struct qemud_network_def *def) {
|
||||||
char *xml;
|
char *xml;
|
||||||
int fd, ret = -1;
|
int fd, ret = -1;
|
||||||
int towrite;
|
int towrite;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!(xml = qemudGenerateNetworkXML(server, network, 0))) {
|
if (!(xml = qemudGenerateNetworkXML(server, network, def))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1550,28 +1568,32 @@ static struct qemud_network_def *qemudParseNetworkXML(struct qemud_server *serve
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
|
struct qemud_network_def *
|
||||||
const char *file,
|
qemudParseNetworkDef(struct qemud_server *server,
|
||||||
const char *doc,
|
const char *xmlStr,
|
||||||
int save) {
|
const char *displayName) {
|
||||||
struct qemud_network_def *def = NULL;
|
|
||||||
struct qemud_network *network = NULL;
|
|
||||||
xmlDocPtr xml;
|
xmlDocPtr xml;
|
||||||
int newNetwork = 0;
|
struct qemud_network_def *def;
|
||||||
|
|
||||||
if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "network.xml", NULL,
|
if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "network.xml", NULL,
|
||||||
XML_PARSE_NOENT | XML_PARSE_NONET |
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
||||||
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
||||||
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
|
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(def = qemudParseNetworkXML(server, xml))) {
|
def = qemudParseNetworkXML(server, xml);
|
||||||
xmlFreeDoc(xml);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct qemud_network *
|
||||||
|
qemudAssignNetworkDef(struct qemud_server *server,
|
||||||
|
struct qemud_network_def *def) {
|
||||||
|
struct qemud_network *network;
|
||||||
|
|
||||||
if ((network = qemudFindNetworkByName(server, def->name))) {
|
if ((network = qemudFindNetworkByName(server, def->name))) {
|
||||||
if (!qemudIsActiveNetwork(network)) {
|
if (!qemudIsActiveNetwork(network)) {
|
||||||
qemudFreeNetworkDef(network->def);
|
qemudFreeNetworkDef(network->def);
|
||||||
@ -1581,87 +1603,202 @@ struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
|
|||||||
qemudFreeNetworkDef(network->newDef);
|
qemudFreeNetworkDef(network->newDef);
|
||||||
network->newDef = def;
|
network->newDef = def;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!(network = calloc(1, sizeof(struct qemud_network)))) {
|
|
||||||
qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
network->def = def;
|
return network;
|
||||||
newNetwork = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file) {
|
if (!(network = calloc(1, sizeof(struct qemud_network)))) {
|
||||||
strncpy(network->configFile, file, PATH_MAX);
|
qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
|
||||||
network->configFile[PATH_MAX-1] = '\0';
|
return NULL;
|
||||||
} else {
|
|
||||||
if (save) {
|
|
||||||
if (qemudMakeConfigPath(server->networkConfigDir, network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
|
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
|
|
||||||
if (newNetwork)
|
|
||||||
qemudFreeNetwork(network);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qemudSaveNetworkConfig(server, network) < 0) {
|
|
||||||
if (newNetwork)
|
|
||||||
qemudFreeNetwork(network);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
network->configFile[0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newNetwork) {
|
network->def = def;
|
||||||
network->next = server->networks;
|
network->next = server->networks;
|
||||||
server->networks = network;
|
|
||||||
server->ninactivenetworks++;
|
server->networks = network;
|
||||||
}
|
server->ninactivenetworks++;
|
||||||
|
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qemudRemoveInactiveNetwork(struct qemud_server *server,
|
||||||
|
struct qemud_network *network)
|
||||||
|
{
|
||||||
|
struct qemud_network *prev = NULL, *curr;
|
||||||
|
|
||||||
/* Load a guest from its persistent config file */
|
curr = server->networks;
|
||||||
static void qemudLoadConfig(struct qemud_server *server,
|
while (curr != network) {
|
||||||
const char *file,
|
prev = curr;
|
||||||
int isGuest) {
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr) {
|
||||||
|
if (prev)
|
||||||
|
prev->next = curr->next;
|
||||||
|
else
|
||||||
|
server->networks = curr->next;
|
||||||
|
|
||||||
|
server->ninactivenetworks--;
|
||||||
|
}
|
||||||
|
|
||||||
|
qemudFreeNetwork(network);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemudSaveNetworkDef(struct qemud_server *server,
|
||||||
|
struct qemud_network *network,
|
||||||
|
struct qemud_network_def *def) {
|
||||||
|
|
||||||
|
if (network->configFile[0] == '\0') {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((err = qemudEnsureDir(server->networkConfigDir))) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"cannot create config directory %s: %s",
|
||||||
|
server->networkConfigDir, strerror(err));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemudMakeConfigPath(server->networkConfigDir, def->name, ".xml",
|
||||||
|
network->configFile, PATH_MAX) < 0) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"cannot construct config file path");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return qemudSaveNetworkConfig(server, network, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemudReadFile(const char *path,
|
||||||
|
char *buf,
|
||||||
|
int maxlen) {
|
||||||
FILE *fh;
|
FILE *fh;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char xml[QEMUD_MAX_XML_LEN];
|
int ret = 0;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!(fh = fopen(file, "r"))) {
|
if (!(fh = fopen(path, "r"))) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open config file %s", file);
|
qemudLog(QEMUD_WARN, "Failed to open file '%s': %s",
|
||||||
return;
|
path, strerror(errno));
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fileno(fh), &st) < 0) {
|
if (fstat(fileno(fh), &st) < 0) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot stat config file %s", file);
|
qemudLog(QEMUD_WARN, "Failed to stat file '%s': %s",
|
||||||
goto cleanup;
|
path, strerror(errno));
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size >= QEMUD_MAX_XML_LEN) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "config too large in file %s", file);
|
qemudDebug("Ignoring directory '%s' - clearly not a config file", path);
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = fread(xml, st.st_size, 1, fh)) != 1) {
|
if (st.st_size >= maxlen) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot read config file %s", file);
|
qemudLog(QEMUD_WARN, "File '%s' is too large", path);
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
}
|
||||||
xml[st.st_size] = '\0';
|
|
||||||
|
|
||||||
if (isGuest) {
|
if ((ret = fread(buf, st.st_size, 1, fh)) != 1) {
|
||||||
qemudLoadConfigXML(server, file, xml, 1);
|
qemudLog(QEMUD_WARN, "Failed to read config file '%s': %s",
|
||||||
} else {
|
path, strerror(errno));
|
||||||
qemudLoadNetworkConfigXML(server, file, xml, 1);
|
goto error;
|
||||||
}
|
}
|
||||||
cleanup:
|
|
||||||
fclose(fh);
|
buf[st.st_size] = '\0';
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fh)
|
||||||
|
fclose(fh);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compareFileToNameSuffix(const char *file,
|
||||||
|
const char *name,
|
||||||
|
const char *suffix) {
|
||||||
|
int filelen = strlen(file);
|
||||||
|
int namelen = strlen(name);
|
||||||
|
int suffixlen = strlen(suffix);
|
||||||
|
|
||||||
|
if (filelen == (namelen + suffixlen) &&
|
||||||
|
!strncmp(file, name, namelen) &&
|
||||||
|
!strncmp(file + namelen, suffix, suffixlen))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct qemud_vm *
|
||||||
|
qemudLoadConfig(struct qemud_server *server,
|
||||||
|
const char *file,
|
||||||
|
const char *path,
|
||||||
|
const char *xml) {
|
||||||
|
struct qemud_vm_def *def;
|
||||||
|
struct qemud_vm *vm;
|
||||||
|
|
||||||
|
if (!(def = qemudParseVMDef(server, xml, file))) {
|
||||||
|
qemudLog(QEMUD_WARN, "Error parsing QEMU guest config '%s' : %s",
|
||||||
|
path, server->errorMessage);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compareFileToNameSuffix(file, def->name, ".xml")) {
|
||||||
|
qemudLog(QEMUD_WARN, "QEMU guest config filename '%s' does not match guest name '%s'",
|
||||||
|
path, def->name);
|
||||||
|
qemudFreeVMDef(def);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(vm = qemudAssignVMDef(server, def))) {
|
||||||
|
qemudLog(QEMUD_WARN, "Failed to load QEMU guest config '%s': out of memory", path);
|
||||||
|
qemudFreeVMDef(def);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(vm->configFile, path, PATH_MAX);
|
||||||
|
vm->configFile[PATH_MAX-1] = '\0';
|
||||||
|
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct qemud_network *
|
||||||
|
qemudLoadNetworkConfig(struct qemud_server *server,
|
||||||
|
const char *file,
|
||||||
|
const char *path,
|
||||||
|
const char *xml) {
|
||||||
|
struct qemud_network_def *def;
|
||||||
|
struct qemud_network *network;
|
||||||
|
|
||||||
|
if (!(def = qemudParseNetworkDef(server, xml, file))) {
|
||||||
|
qemudLog(QEMUD_WARN, "Error parsing network config '%s' : %s",
|
||||||
|
path, server->errorMessage);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compareFileToNameSuffix(file, def->name, ".xml")) {
|
||||||
|
qemudLog(QEMUD_WARN, "Network config filename '%s' does not match network name '%s'",
|
||||||
|
path, def->name);
|
||||||
|
qemudFreeNetworkDef(def);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(network = qemudAssignNetworkDef(server, def))) {
|
||||||
|
qemudLog(QEMUD_WARN, "Failed to load network config '%s': out of memory", path);
|
||||||
|
qemudFreeNetworkDef(def);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(network->configFile, path, PATH_MAX);
|
||||||
|
network->configFile[PATH_MAX-1] = '\0';
|
||||||
|
|
||||||
|
return network;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int qemudScanConfigDir(struct qemud_server *server,
|
int qemudScanConfigDir(struct qemud_server *server,
|
||||||
@ -1679,14 +1816,25 @@ int qemudScanConfigDir(struct qemud_server *server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((entry = readdir(dir))) {
|
while ((entry = readdir(dir))) {
|
||||||
char file[PATH_MAX];
|
char xml[QEMUD_MAX_XML_LEN];
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
if (entry->d_name[0] == '.')
|
if (entry->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) < 0)
|
if (qemudMakeConfigPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) {
|
||||||
|
qemudLog(QEMUD_WARN, "Config filename '%s/%s' is too long",
|
||||||
|
configDir, entry->d_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qemudReadFile(path, xml, QEMUD_MAX_XML_LEN))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
qemudLoadConfig(server, file, isGuest);
|
if (isGuest)
|
||||||
|
qemudLoadConfig(server, entry->d_name, path, xml);
|
||||||
|
else
|
||||||
|
qemudLoadNetworkConfig(server, entry->d_name, path, xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
@ -1751,8 +1899,10 @@ int qemudBufferPrintf(struct qemudBuffer *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generate an XML document describing the guest's configuration */
|
/* Generate an XML document describing the guest's configuration */
|
||||||
char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm, int live) {
|
char *qemudGenerateXML(struct qemud_server *server,
|
||||||
struct qemud_vm_def *def = live ? vm->def : (vm->newDef ? vm->newDef : vm->def);
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_def *def,
|
||||||
|
int live) {
|
||||||
struct qemudBuffer buf;
|
struct qemudBuffer buf;
|
||||||
unsigned char *uuid;
|
unsigned char *uuid;
|
||||||
struct qemud_vm_disk_def *disk;
|
struct qemud_vm_disk_def *disk;
|
||||||
@ -1986,9 +2136,8 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm, int liv
|
|||||||
|
|
||||||
|
|
||||||
char *qemudGenerateNetworkXML(struct qemud_server *server,
|
char *qemudGenerateNetworkXML(struct qemud_server *server,
|
||||||
struct qemud_network *network,
|
struct qemud_network *network ATTRIBUTE_UNUSED,
|
||||||
int live) {
|
struct qemud_network_def *def) {
|
||||||
struct qemud_network_def *def = live ? network->def : (network->newDef ? network->newDef : network->def);
|
|
||||||
struct qemudBuffer buf;
|
struct qemudBuffer buf;
|
||||||
unsigned char *uuid;
|
unsigned char *uuid;
|
||||||
|
|
||||||
|
70
qemud/conf.h
70
qemud/conf.h
@ -26,33 +26,55 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
int qemudBuildCommandLine(struct qemud_server *server,
|
int qemudBuildCommandLine (struct qemud_server *server,
|
||||||
struct qemud_vm *vm,
|
struct qemud_vm *vm,
|
||||||
char ***argv);
|
char ***argv);
|
||||||
|
|
||||||
int qemudScanConfigs(struct qemud_server *server);
|
int qemudScanConfigs (struct qemud_server *server);
|
||||||
int qemudDeleteConfig(struct qemud_server *server,
|
int qemudDeleteConfig (struct qemud_server *server,
|
||||||
const char *configFile,
|
const char *configFile,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
void qemudFreeVMDef(struct qemud_vm_def *vm);
|
void qemudFreeVMDef (struct qemud_vm_def *vm);
|
||||||
void qemudFreeVM(struct qemud_vm *vm);
|
void qemudFreeVM (struct qemud_vm *vm);
|
||||||
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
|
|
||||||
const char *file,
|
|
||||||
const char *doc,
|
|
||||||
int persist);
|
|
||||||
char *qemudGenerateXML(struct qemud_server *server,
|
|
||||||
struct qemud_vm *vm, int live);
|
|
||||||
|
|
||||||
void qemudFreeNetworkDef(struct qemud_network_def *def);
|
struct qemud_vm *
|
||||||
void qemudFreeNetwork(struct qemud_network *network);
|
qemudAssignVMDef (struct qemud_server *server,
|
||||||
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
|
struct qemud_vm_def *def);
|
||||||
const char *file,
|
void qemudRemoveInactiveVM (struct qemud_server *server,
|
||||||
const char *doc,
|
struct qemud_vm *vm);
|
||||||
int persist);
|
|
||||||
char *qemudGenerateNetworkXML(struct qemud_server *server,
|
struct qemud_vm_def *
|
||||||
struct qemud_network *network,
|
qemudParseVMDef (struct qemud_server *server,
|
||||||
int live);
|
const char *xmlStr,
|
||||||
|
const char *displayName);
|
||||||
|
int qemudSaveVMDef (struct qemud_server *server,
|
||||||
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_def *def);
|
||||||
|
char * qemudGenerateXML (struct qemud_server *server,
|
||||||
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_def *def,
|
||||||
|
int live);
|
||||||
|
|
||||||
|
void qemudFreeNetworkDef (struct qemud_network_def *def);
|
||||||
|
void qemudFreeNetwork (struct qemud_network *network);
|
||||||
|
|
||||||
|
struct qemud_network *
|
||||||
|
qemudAssignNetworkDef (struct qemud_server *server,
|
||||||
|
struct qemud_network_def *def);
|
||||||
|
void qemudRemoveInactiveNetwork (struct qemud_server *server,
|
||||||
|
struct qemud_network *network);
|
||||||
|
|
||||||
|
struct qemud_network_def *
|
||||||
|
qemudParseNetworkDef (struct qemud_server *server,
|
||||||
|
const char *xmlStr,
|
||||||
|
const char *displayName);
|
||||||
|
int qemudSaveNetworkDef (struct qemud_server *server,
|
||||||
|
struct qemud_network *network,
|
||||||
|
struct qemud_network_def *def);
|
||||||
|
char * qemudGenerateNetworkXML (struct qemud_server *server,
|
||||||
|
struct qemud_network *network,
|
||||||
|
struct qemud_network_def *def);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -279,14 +279,20 @@ int qemudNumDomains(struct qemud_server *server) {
|
|||||||
return server->nactivevms;
|
return server->nactivevms;
|
||||||
}
|
}
|
||||||
struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
|
struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
|
||||||
|
|
||||||
|
struct qemud_vm_def *def;
|
||||||
struct qemud_vm *vm;
|
struct qemud_vm *vm;
|
||||||
|
|
||||||
if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0))) {
|
if (!(def = qemudParseVMDef(server, xml, NULL)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(vm = qemudAssignVMDef(server, def))) {
|
||||||
|
qemudFreeVMDef(def);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemudStartVMDaemon(server, vm) < 0) {
|
if (qemudStartVMDaemon(server, vm) < 0) {
|
||||||
qemudFreeVM(vm);
|
qemudRemoveInactiveVM(server, vm);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +422,7 @@ int qemudDomainDumpXML(struct qemud_server *server, const unsigned char *uuid, c
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmxml = qemudGenerateXML(server, vm, 1);
|
vmxml = qemudGenerateXML(server, vm, vm->def, 1);
|
||||||
if (!vmxml)
|
if (!vmxml)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -461,12 +467,27 @@ struct qemud_vm *qemudDomainStart(struct qemud_server *server, const unsigned ch
|
|||||||
|
|
||||||
|
|
||||||
struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
|
struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
|
||||||
return qemudLoadConfigXML(server, NULL, xml, 1);
|
struct qemud_vm_def *def;
|
||||||
|
struct qemud_vm *vm;
|
||||||
|
|
||||||
|
if (!(def = qemudParseVMDef(server, xml, NULL)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(vm = qemudAssignVMDef(server, def))) {
|
||||||
|
qemudFreeVMDef(def);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemudSaveVMDef(server, vm, def) < 0) {
|
||||||
|
qemudRemoveInactiveVM(server, vm);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
|
int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
|
||||||
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
|
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
|
||||||
struct qemud_vm *prev = NULL, *curr = server->vms;
|
|
||||||
|
|
||||||
if (!vm) {
|
if (!vm) {
|
||||||
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
|
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
|
||||||
@ -483,22 +504,7 @@ int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid)
|
|||||||
|
|
||||||
vm->configFile[0] = '\0';
|
vm->configFile[0] = '\0';
|
||||||
|
|
||||||
while (curr) {
|
qemudRemoveInactiveVM(server, vm);
|
||||||
if (curr == vm) {
|
|
||||||
if (prev) {
|
|
||||||
prev->next = curr->next;
|
|
||||||
} else {
|
|
||||||
server->vms = curr->next;
|
|
||||||
}
|
|
||||||
server->ninactivevms--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
qemudFreeVM(vm);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -566,14 +572,19 @@ int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
|
struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
|
||||||
|
struct qemud_network_def *def;
|
||||||
struct qemud_network *network;
|
struct qemud_network *network;
|
||||||
|
|
||||||
if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0))) {
|
if (!(def = qemudParseNetworkDef(server, xml, NULL)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(network = qemudAssignNetworkDef(server, def))) {
|
||||||
|
qemudFreeNetworkDef(def);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemudStartNetworkDaemon(server, network) < 0) {
|
if (qemudStartNetworkDaemon(server, network) < 0) {
|
||||||
qemudFreeNetwork(network);
|
qemudRemoveInactiveNetwork(server, network);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,12 +592,27 @@ struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
|
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
|
||||||
return qemudLoadNetworkConfigXML(server, NULL, xml, 1);
|
struct qemud_network_def *def;
|
||||||
|
struct qemud_network *network;
|
||||||
|
|
||||||
|
if (!(def = qemudParseNetworkDef(server, xml, NULL)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(network = qemudAssignNetworkDef(server, def))) {
|
||||||
|
qemudFreeNetworkDef(def);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemudSaveNetworkDef(server, network, def) < 0) {
|
||||||
|
qemudRemoveInactiveNetwork(server, network);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
|
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
|
||||||
struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
|
struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
|
||||||
struct qemud_network *prev = NULL, *curr = server->networks;
|
|
||||||
|
|
||||||
if (!network) {
|
if (!network) {
|
||||||
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching uuid");
|
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching uuid");
|
||||||
@ -598,22 +624,7 @@ int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid)
|
|||||||
|
|
||||||
network->configFile[0] = '\0';
|
network->configFile[0] = '\0';
|
||||||
|
|
||||||
while (curr) {
|
qemudRemoveInactiveNetwork(server, network);
|
||||||
if (curr == network) {
|
|
||||||
if (prev) {
|
|
||||||
prev->next = curr->next;
|
|
||||||
} else {
|
|
||||||
server->networks = curr->next;
|
|
||||||
}
|
|
||||||
server->ninactivenetworks--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
qemudFreeNetwork(network);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -650,7 +661,7 @@ int qemudNetworkDumpXML(struct qemud_server *server, const unsigned char *uuid,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkxml = qemudGenerateNetworkXML(server, network, 1);
|
networkxml = qemudGenerateNetworkXML(server, network, network->def);
|
||||||
if (!networkxml)
|
if (!networkxml)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -1255,8 +1255,7 @@ static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) {
|
|||||||
struct qemud_socket *sock = server->sockets;
|
struct qemud_socket *sock = server->sockets;
|
||||||
struct qemud_client *client = server->clients;
|
struct qemud_client *client = server->clients;
|
||||||
struct qemud_vm *vm;
|
struct qemud_vm *vm;
|
||||||
struct qemud_vm *tmp;
|
struct qemud_network *network;
|
||||||
struct qemud_network *network, *prevnet;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
|
|
||||||
@ -1336,42 +1335,24 @@ static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) {
|
|||||||
/* Cleanup any VMs which shutdown & dont have an associated
|
/* Cleanup any VMs which shutdown & dont have an associated
|
||||||
config file */
|
config file */
|
||||||
vm = server->vms;
|
vm = server->vms;
|
||||||
tmp = NULL;
|
|
||||||
while (vm) {
|
while (vm) {
|
||||||
if (!qemudIsActiveVM(vm) && !vm->configFile[0]) {
|
struct qemud_vm *next = vm->next;
|
||||||
struct qemud_vm *next = vm->next;
|
|
||||||
if (tmp) {
|
if (!qemudIsActiveVM(vm) && !vm->configFile[0])
|
||||||
tmp->next = next;
|
qemudRemoveInactiveVM(server, vm);
|
||||||
} else {
|
|
||||||
server->vms = next;
|
vm = next;
|
||||||
}
|
|
||||||
qemudFreeVM(vm);
|
|
||||||
server->ninactivevms--;
|
|
||||||
vm = next;
|
|
||||||
} else {
|
|
||||||
tmp = vm;
|
|
||||||
vm = vm->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup any networks too */
|
/* Cleanup any networks too */
|
||||||
network = server->networks;
|
network = server->networks;
|
||||||
prevnet = NULL;
|
|
||||||
while (network) {
|
while (network) {
|
||||||
if (!qemudIsActiveNetwork(network) && !network->configFile[0]) {
|
struct qemud_network *next = network->next;
|
||||||
struct qemud_network *next = network->next;
|
|
||||||
if (prevnet) {
|
if (!qemudIsActiveNetwork(network) && !network->configFile[0])
|
||||||
prevnet->next = next;
|
qemudRemoveInactiveNetwork(server, network);
|
||||||
} else {
|
|
||||||
server->networks = next;
|
network = next;
|
||||||
}
|
|
||||||
qemudFreeNetwork(network);
|
|
||||||
server->ninactivenetworks--;
|
|
||||||
network = next;
|
|
||||||
} else {
|
|
||||||
prevnet = network;
|
|
||||||
network = network->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user