mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-26 18:41:17 +00:00
Fix crash in svirt verification, and incorrect cleanup in VM failure paths
This commit is contained in:
parent
f0817018b1
commit
9ec1a56923
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
Fri Apr 3 15:07:00 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Fix crash in svirt verification, and incorrect cleanup in
|
||||||
|
VM failure paths.
|
||||||
|
* src/domain_conf.c: Don't extract 'model' from seclabel unless
|
||||||
|
requesting 'live' config, or if its a static label. Add missing
|
||||||
|
error report
|
||||||
|
* src/qemu_driver.c: Fix cleanup in auto-reconnect to running VMs.
|
||||||
|
Fix cleanup of resources if starting a new VM fails
|
||||||
|
* src/security.c: Fix crash if no seclabel model is defined in
|
||||||
|
the virSecuriyDriverVerify method
|
||||||
|
* src/security_selinux.c: Fix error message typo & fix whitespace
|
||||||
|
|
||||||
Fri Apr 3 15:03:00 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
Fri Apr 3 15:03:00 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* src/virsh.c: Add --console arg for create & start commands
|
* src/virsh.c: Add --console arg for create & start commands
|
||||||
|
@ -1859,15 +1859,6 @@ virSecurityLabelDefParseXML(virConnectPtr conn,
|
|||||||
if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
|
if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/@model)",
|
|
||||||
VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
|
|
||||||
if (p == NULL) {
|
|
||||||
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
|
||||||
"%s", _("missing security model"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
def->seclabel.model = p;
|
|
||||||
|
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/@type)",
|
p = virXPathStringLimit(conn, "string(./seclabel/@type)",
|
||||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@ -1888,6 +1879,14 @@ virSecurityLabelDefParseXML(virConnectPtr conn,
|
|||||||
*/
|
*/
|
||||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
|
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
|
||||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||||
|
p = virXPathStringLimit(conn, "string(./seclabel/@model)",
|
||||||
|
VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
|
||||||
|
if (p == NULL) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
"%s", _("missing security model"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->seclabel.model = p;
|
||||||
|
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
|
p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
|
||||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
@ -1905,8 +1904,11 @@ virSecurityLabelDefParseXML(virConnectPtr conn,
|
|||||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||||
p = virXPathStringLimit(conn, "string(./seclabel/imagelabel[1])",
|
p = virXPathStringLimit(conn, "string(./seclabel/imagelabel[1])",
|
||||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
if (p == NULL)
|
if (p == NULL) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
|
_("security imagelabel is missing"));
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
def->seclabel.imagelabel = p;
|
def->seclabel.imagelabel = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ qemudReconnectVMs(struct qemud_driver *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((vm->logfile = qemudLogFD(NULL, driver->logDir, vm->def->name)) < 0)
|
if ((vm->logfile = qemudLogFD(NULL, driver->logDir, vm->def->name)) < 0)
|
||||||
return -1;
|
goto next_error;
|
||||||
|
|
||||||
if (vm->def->id >= driver->nextvmid)
|
if (vm->def->id >= driver->nextvmid)
|
||||||
driver->nextvmid = vm->def->id + 1;
|
driver->nextvmid = vm->def->id + 1;
|
||||||
@ -344,9 +344,12 @@ next_error:
|
|||||||
/* we failed to reconnect the vm so remove it's traces */
|
/* we failed to reconnect the vm so remove it's traces */
|
||||||
vm->def->id = -1;
|
vm->def->id = -1;
|
||||||
qemudRemoveDomainStatus(NULL, driver, vm);
|
qemudRemoveDomainStatus(NULL, driver, vm);
|
||||||
virDomainDefFree(vm->def);
|
/* Restore orignal def, if we'd loaded a live one */
|
||||||
vm->def = vm->newDef;
|
if (vm->newDef) {
|
||||||
vm->newDef = NULL;
|
virDomainDefFree(vm->def);
|
||||||
|
vm->def = vm->newDef;
|
||||||
|
vm->newDef = NULL;
|
||||||
|
}
|
||||||
next:
|
next:
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
if (status)
|
if (status)
|
||||||
@ -1319,14 +1322,6 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
hookData.vm = vm;
|
hookData.vm = vm;
|
||||||
hookData.driver = driver;
|
hookData.driver = driver;
|
||||||
|
|
||||||
/* If you are using a SecurityDriver with dynamic labelling,
|
|
||||||
then generate a security label for isolation */
|
|
||||||
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
|
||||||
driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainGenSecurityLabel &&
|
|
||||||
driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
FD_ZERO(&keepfd);
|
FD_ZERO(&keepfd);
|
||||||
|
|
||||||
if (virDomainIsActive(vm)) {
|
if (virDomainIsActive(vm)) {
|
||||||
@ -1335,6 +1330,14 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If you are using a SecurityDriver with dynamic labelling,
|
||||||
|
then generate a security label for isolation */
|
||||||
|
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
||||||
|
driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainGenSecurityLabel &&
|
||||||
|
driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (vm->def->graphics &&
|
if (vm->def->graphics &&
|
||||||
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
||||||
vm->def->graphics->data.vnc.autoport) {
|
vm->def->graphics->data.vnc.autoport) {
|
||||||
@ -1342,7 +1345,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
if (port < 0) {
|
if (port < 0) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("Unable to find an unused VNC port"));
|
"%s", _("Unable to find an unused VNC port"));
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
vm->def->graphics->data.vnc.port = port;
|
vm->def->graphics->data.vnc.port = port;
|
||||||
}
|
}
|
||||||
@ -1351,17 +1354,17 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
virReportSystemError(conn, errno,
|
virReportSystemError(conn, errno,
|
||||||
_("cannot create log directory %s"),
|
_("cannot create log directory %s"),
|
||||||
driver->logDir);
|
driver->logDir);
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((vm->logfile = qemudLogFD(conn, driver->logDir, vm->def->name)) < 0)
|
if((vm->logfile = qemudLogFD(conn, driver->logDir, vm->def->name)) < 0)
|
||||||
return -1;
|
goto cleanup;
|
||||||
|
|
||||||
emulator = vm->def->emulator;
|
emulator = vm->def->emulator;
|
||||||
if (!emulator)
|
if (!emulator)
|
||||||
emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
|
emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
|
||||||
if (!emulator)
|
if (!emulator)
|
||||||
return -1;
|
goto cleanup;
|
||||||
|
|
||||||
/* Make sure the binary we are about to try exec'ing exists.
|
/* Make sure the binary we are about to try exec'ing exists.
|
||||||
* Technically we could catch the exec() failure, but that's
|
* Technically we could catch the exec() failure, but that's
|
||||||
@ -1371,7 +1374,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
virReportSystemError(conn, errno,
|
virReportSystemError(conn, errno,
|
||||||
_("Cannot find QEMU binary %s"),
|
_("Cannot find QEMU binary %s"),
|
||||||
emulator);
|
emulator);
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemudExtractVersionInfo(emulator,
|
if (qemudExtractVersionInfo(emulator,
|
||||||
@ -1380,21 +1383,17 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Cannot determine QEMU argv syntax %s"),
|
_("Cannot determine QEMU argv syntax %s"),
|
||||||
emulator);
|
emulator);
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemuPrepareHostDevices(conn, vm->def) < 0)
|
if (qemuPrepareHostDevices(conn, vm->def) < 0)
|
||||||
return -1;
|
goto cleanup;
|
||||||
|
|
||||||
vm->def->id = driver->nextvmid++;
|
vm->def->id = driver->nextvmid++;
|
||||||
if (qemudBuildCommandLine(conn, driver, vm,
|
if (qemudBuildCommandLine(conn, driver, vm,
|
||||||
qemuCmdFlags, &argv, &progenv,
|
qemuCmdFlags, &argv, &progenv,
|
||||||
&tapfds, &ntapfds, migrateFrom) < 0) {
|
&tapfds, &ntapfds, migrateFrom) < 0)
|
||||||
close(vm->logfile);
|
goto cleanup;
|
||||||
vm->def->id = -1;
|
|
||||||
vm->logfile = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = progenv;
|
tmp = progenv;
|
||||||
while (*tmp) {
|
while (*tmp) {
|
||||||
@ -1457,12 +1456,8 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
"%s", _("Unable to daemonize QEMU process"));
|
"%s", _("Unable to daemonize QEMU process"));
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
|
vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
|
||||||
} else
|
}
|
||||||
vm->def->id = -1;
|
|
||||||
|
|
||||||
for (i = 0 ; argv[i] ; i++)
|
for (i = 0 ; argv[i] ; i++)
|
||||||
VIR_FREE(argv[i]);
|
VIR_FREE(argv[i]);
|
||||||
@ -1479,19 +1474,38 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
VIR_FREE(tapfds);
|
VIR_FREE(tapfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == -1)
|
||||||
if ((qemudWaitForMonitor(conn, driver, vm, pos) < 0) ||
|
goto cleanup;
|
||||||
(qemudDetectVcpuPIDs(conn, vm) < 0) ||
|
|
||||||
(qemudInitCpus(conn, vm, migrateFrom) < 0) ||
|
if ((qemudWaitForMonitor(conn, driver, vm, pos) < 0) ||
|
||||||
(qemudInitPasswords(conn, driver, vm) < 0) ||
|
(qemudDetectVcpuPIDs(conn, vm) < 0) ||
|
||||||
(qemudDomainSetMemoryBalloon(conn, vm, vm->def->memory) < 0) ||
|
(qemudInitCpus(conn, vm, migrateFrom) < 0) ||
|
||||||
(qemudSaveDomainStatus(conn, qemu_driver, vm) < 0)) {
|
(qemudInitPasswords(conn, driver, vm) < 0) ||
|
||||||
qemudShutdownVMDaemon(conn, driver, vm);
|
(qemudDomainSetMemoryBalloon(conn, vm, vm->def->memory) < 0) ||
|
||||||
return -1;
|
(qemudSaveDomainStatus(conn, qemu_driver, vm) < 0)) {
|
||||||
}
|
qemudShutdownVMDaemon(conn, driver, vm);
|
||||||
|
ret = -1;
|
||||||
|
/* No need for 'goto cleanup' now since qemudShutdownVMDaemon does enough */
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||||
|
VIR_FREE(vm->def->seclabel.model);
|
||||||
|
VIR_FREE(vm->def->seclabel.label);
|
||||||
|
VIR_FREE(vm->def->seclabel.imagelabel);
|
||||||
|
}
|
||||||
|
if (vm->def->graphics &&
|
||||||
|
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
||||||
|
vm->def->graphics->data.vnc.autoport)
|
||||||
|
vm->def->graphics->data.vnc.port = -1;
|
||||||
|
if (vm->logfile != -1) {
|
||||||
|
close(vm->logfile);
|
||||||
|
vm->logfile = -1;
|
||||||
|
}
|
||||||
|
vm->def->id = -1;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ virSecurityDriverVerify(virConnectPtr conn, virDomainDefPtr def)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
||||||
|
|
||||||
if (STREQ(secdef->model, "none"))
|
if (!secdef->model ||
|
||||||
|
STREQ(secdef->model, "none"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; security_drivers[i] != NULL ; i++) {
|
for (i = 0; security_drivers[i] != NULL ; i++) {
|
||||||
@ -42,7 +43,7 @@ virSecurityDriverVerify(virConnectPtr conn, virDomainDefPtr def)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
virSecurityReportError(conn, VIR_ERR_XML_ERROR,
|
virSecurityReportError(conn, VIR_ERR_XML_ERROR,
|
||||||
_("invalid security model"));
|
_("invalid security model '%s'"), secdef->model);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,11 +162,12 @@ SELinuxGenSecurityLabel(virConnectPtr conn,
|
|||||||
char *scontext = NULL;
|
char *scontext = NULL;
|
||||||
int c1 = 0;
|
int c1 = 0;
|
||||||
int c2 = 0;
|
int c2 = 0;
|
||||||
if ( ( vm->def->seclabel.label ) ||
|
|
||||||
( vm->def->seclabel.model ) ||
|
if (vm->def->seclabel.label ||
|
||||||
( vm->def->seclabel.imagelabel )) {
|
vm->def->seclabel.model ||
|
||||||
virSecurityReportError(conn, VIR_ERR_ERROR,
|
vm->def->seclabel.imagelabel) {
|
||||||
"%s", _("security labellin already defined for VM"));
|
virSecurityReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("security label already defined for VM"));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +198,7 @@ SELinuxGenSecurityLabel(virConnectPtr conn,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME);
|
vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME);
|
||||||
if (! vm->def->seclabel.model) {
|
if (!vm->def->seclabel.model) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user