static void
qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
- struct qemud_driver *driver = (struct qemud_driver *)opaque;
+ struct qemud_driver *driver = opaque;
virDomainObjPtr vm = NULL;
unsigned int i;
}
static int qemudClose(virConnectPtr conn) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
/* Get rid of callbacks registered for this conn */
virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
static char *qemudGetCapabilities(virConnectPtr conn) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
char *xml;
- if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL) {
+ if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for capabilities support"));
- return NULL;
- }
return xml;
}
int maxCells)
{
int n, lastCell, numCells;
+ int ret = -1;
if (numa_available() < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("NUMA not supported on this host"));
- return -1;
+ goto cleanup;
}
lastCell = startCell + maxCells - 1;
if (lastCell > numa_max_node())
if (numa_node_size64(n, &mem) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to query NUMA free memory"));
- return -1;
+ goto cleanup;
}
freeMems[numCells++] = mem;
}
- return numCells;
+ ret = numCells;
+
+cleanup:
+ return ret;
}
static unsigned long long
qemudNodeGetFreeMemory (virConnectPtr conn)
{
- unsigned long long freeMem = 0;
+ unsigned long long freeMem = -1;
int n;
+
if (numa_available() < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("NUMA not supported on this host"));
- return -1;
+ goto cleanup;
}
for (n = 0 ; n <= numa_max_node() ; n++) {
if (numa_node_size64(n, &mem) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to query NUMA free memory"));
- return -1;
+ goto cleanup;
}
freeMem += mem;
}
+cleanup:
return freeMem;
}
static virDomainPtr qemudDomainLookupByID(virConnectPtr conn,
int id) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, id);
- virDomainPtr dom;
+ struct qemud_driver *driver = conn->privateData;
+ virDomainObjPtr vm;
+ virDomainPtr dom = NULL;
+
+ vm = virDomainFindByID(&driver->domains, id);
if (!vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
- return NULL;
+ goto cleanup;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
+
+cleanup:
return dom;
}
static virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, uuid);
- virDomainPtr dom;
+ struct qemud_driver *driver = conn->privateData;
+ virDomainObjPtr vm;
+ virDomainPtr dom = NULL;
+ vm = virDomainFindByUUID(&driver->domains, uuid);
if (!vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
- return NULL;
+ goto cleanup;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
+
+cleanup:
return dom;
}
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
const char *name) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
- virDomainObjPtr vm = virDomainFindByName(&driver->domains, name);
- virDomainPtr dom;
+ struct qemud_driver *driver = conn->privateData;
+ virDomainObjPtr vm;
+ virDomainPtr dom = NULL;
+ vm = virDomainFindByName(&driver->domains, name);
if (!vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
- return NULL;
+ goto cleanup;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
+
+cleanup:
return dom;
}
static int qemudGetVersion(virConnectPtr conn, unsigned long *version) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
+ int ret = -1;
+
if (qemudExtractVersion(conn, driver) < 0)
- return -1;
+ goto cleanup;
*version = qemu_driver->qemuVersion;
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static char *
}
static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
int got = 0, i;
for (i = 0 ; i < driver->domains.count && got < nids ; i++)
return got;
}
static int qemudNumDomains(virConnectPtr conn) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
int n = 0, i;
for (i = 0 ; i < driver->domains.count ; i++)
}
static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
unsigned int flags ATTRIBUTE_UNUSED) {
+ struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def;
virDomainObjPtr vm;
- virDomainPtr dom;
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ virDomainPtr dom = NULL;
if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
- return NULL;
+ goto cleanup;
vm = virDomainFindByName(&driver->domains, def->name);
if (vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("domain '%s' is already defined"),
def->name);
- virDomainDefFree(def);
- return NULL;
+ goto cleanup;
}
vm = virDomainFindByUUID(&driver->domains, def->uuid);
if (vm) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("domain with uuid '%s' is already defined"),
uuidstr);
- virDomainDefFree(def);
- return NULL;
+ goto cleanup;
}
if (!(vm = virDomainAssignDef(conn,
&driver->domains,
- def))) {
- virDomainDefFree(def);
- return NULL;
- }
+ def)))
+ goto cleanup;
+
+ def = NULL;
if (qemudStartVMDaemon(conn, driver, vm, NULL) < 0) {
virDomainRemoveInactive(&driver->domains,
vm);
- return NULL;
+ goto cleanup;
}
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STARTED,
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
+
+cleanup:
+ virDomainDefFree(def);
+
return dom;
}
static int qemudDomainSuspend(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+ struct qemud_driver *driver = dom->conn->privateData;
char *info;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, _("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
- if (vm->state == VIR_DOMAIN_PAUSED)
- return 0;
-
- if (qemudMonitorCommand(driver, vm, "stop", &info) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- "%s", _("suspend operation failed"));
- return -1;
+ if (vm->state != VIR_DOMAIN_PAUSED) {
+ if (qemudMonitorCommand(driver, vm, "stop", &info) < 0) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("suspend operation failed"));
+ goto cleanup;
+ }
+ vm->state = VIR_DOMAIN_PAUSED;
+ qemudDebug("Reply %s", info);
+ qemudDomainEventDispatch(driver, vm,
+ VIR_DOMAIN_EVENT_SUSPENDED,
+ VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
+ VIR_FREE(info);
}
- vm->state = VIR_DOMAIN_PAUSED;
- qemudDebug("Reply %s", info);
- qemudDomainEventDispatch(driver, vm,
- VIR_DOMAIN_EVENT_SUSPENDED,
- VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
- VIR_FREE(info);
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static int qemudDomainResume(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+ struct qemud_driver *driver = dom->conn->privateData;
char *info;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
- if (vm->state == VIR_DOMAIN_RUNNING)
- return 0;
- if (qemudMonitorCommand(driver, vm, "cont", &info) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- "%s", _("resume operation failed"));
- return -1;
+ if (vm->state == VIR_DOMAIN_PAUSED) {
+ if (qemudMonitorCommand(driver, vm, "cont", &info) < 0) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("resume operation failed"));
+ goto cleanup;
+ }
+ vm->state = VIR_DOMAIN_RUNNING;
+ qemudDebug("Reply %s", info);
+ qemudDomainEventDispatch(driver, vm,
+ VIR_DOMAIN_EVENT_RESUMED,
+ VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
+ VIR_FREE(info);
}
- vm->state = VIR_DOMAIN_RUNNING;
- qemudDebug("Reply %s", info);
- qemudDomainEventDispatch(driver, vm,
- VIR_DOMAIN_EVENT_RESUMED,
- VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
- VIR_FREE(info);
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static int qemudDomainShutdown(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
char* info;
+ int ret = -1;
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (qemudMonitorCommand(driver, vm, "system_powerdown", &info) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("shutdown operation failed"));
- return -1;
+ goto cleanup;
}
VIR_FREE(info);
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static int qemudDomainDestroy(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
qemudShutdownVMDaemon(dom->conn, driver, vm);
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains,
vm);
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static char *qemudDomainGetOSType(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
- char *type;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ char *type = NULL;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return NULL;
+ goto cleanup;
}
- if (!(type = strdup(vm->def->os.type))) {
+ if (!(type = strdup(vm->def->os.type)))
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for ostype"));
- return NULL;
- }
+
+cleanup:
return type;
}
/* Returns max memory in kb, 0 if error */
static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ unsigned long ret = 0;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->uuid, uuidstr);
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
- return 0;
+ goto cleanup;
}
- return vm->def->maxmem;
+ ret = vm->def->maxmem;
+
+cleanup:
+ return ret;
}
static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->uuid, uuidstr);
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
- return -1;
+ goto cleanup;
}
if (newmax < vm->def->memory) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s", _("cannot set max memory lower than current memory"));
- return -1;
+ goto cleanup;;
}
vm->def->maxmem = newmax;
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->uuid, uuidstr);
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
- return -1;
+ goto cleanup;
}
if (virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("cannot set memory of an active domain"));
- return -1;
+ goto cleanup;
}
if (newmem > vm->def->maxmem) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s", _("cannot set memory higher than max memory"));
- return -1;
+ goto cleanup;
}
vm->def->memory = newmem;
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static int qemudDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
info->state = vm->state;
} else {
if (qemudGetProcessInfo(&(info->cpuTime), vm->pid) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, ("cannot read cputime for domain"));
- return -1;
+ goto cleanup;
}
}
info->maxMem = vm->def->maxmem;
info->memory = vm->def->memory;
info->nrVirtCpu = vm->def->vcpus;
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
static int qemudDomainSave(virDomainPtr dom,
const char *path) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
- char *command, *info;
- int fd;
- char *safe_path;
- char *xml;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ char *command = NULL;
+ char *info = NULL;
+ int fd = -1;
+ char *safe_path = NULL;
+ char *xml = NULL;
struct qemud_save_header header;
+ int ret = -1;
memset(&header, 0, sizeof(header));
memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
header.version = QEMUD_SAVE_VERSION;
+ vm = virDomainFindByID(&driver->domains, dom->id);
+
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
/* Pause */
if (qemudDomainSuspend(dom) != 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to pause domain"));
- return -1;
+ goto cleanup;
}
}
if (!xml) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to get domain xml"));
- return -1;
+ goto cleanup;
}
header.xml_len = strlen(xml) + 1;
if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to create '%s'"), path);
- VIR_FREE(xml);
- return -1;
+ goto cleanup;
}
if (safewrite(fd, &header, sizeof(header)) != sizeof(header)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to write save header"));
- close(fd);
- VIR_FREE(xml);
return -1;
}
if (safewrite(fd, xml, header.xml_len) != header.xml_len) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to write xml"));
- close(fd);
- VIR_FREE(xml);
- return -1;
+ goto cleanup;
}
- close(fd);
- VIR_FREE(xml);
+ if (close(fd) < 0) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _("unable to save file %s %s"),
+ path, strerror(errno));
+ goto cleanup;
+ }
+ fd = -1;
/* Migrate to file */
safe_path = qemudEscapeShellArg(path);
if (!safe_path) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("out of memory"));
- return -1;
+ goto cleanup;
}
if (asprintf (&command, "migrate \"exec:"
"dd of='%s' oflag=append conv=notrunc 2>/dev/null"
"\"", safe_path) == -1) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("out of memory"));
- VIR_FREE(safe_path);
- return -1;
+ command = NULL;
+ goto cleanup;
}
- free(safe_path);
if (qemudMonitorCommand(driver, vm, command, &info) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("migrate operation failed"));
- VIR_FREE(command);
- return -1;
+ goto cleanup;
}
DEBUG ("migrate reply: %s", info);
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s",
_("'migrate' not supported by this qemu"));
- VIR_FREE(info);
- VIR_FREE(command);
- return -1;
+ goto cleanup;
}
- VIR_FREE(info);
- VIR_FREE(command);
-
/* Shut it down */
qemudShutdownVMDaemon(dom->conn, driver, vm);
qemudDomainEventDispatch(driver, vm,
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains,
vm);
- return 0;
+ ret = 0;
+
+cleanup:
+ if (fd != -1)
+ close(fd);
+ VIR_FREE(xml);
+ VIR_FREE(safe_path);
+ VIR_FREE(command);
+ VIR_FREE(info);
+ if (ret != 0)
+ unlink(path);
+
+ return ret;
}
static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
int max;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->uuid, uuidstr);
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
- return -1;
+ goto cleanup;
}
if (virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
_("cannot change vcpu count of an active domain"));
- return -1;
+ goto cleanup;
}
if ((max = qemudDomainGetMaxVcpus(dom)) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
_("could not determine max vcpus for the domain"));
- return -1;
+ goto cleanup;
}
if (nvcpus > max) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
_("requested vcpus is greater than max allowable"
" vcpus for the domain: %d > %d"), nvcpus, max);
- return -1;
+ goto cleanup;
}
vm->def->vcpus = nvcpus;
- return 0;
+ ret = 0;
+
+cleanup:
+ return ret;
}
unsigned int vcpu,
unsigned char *cpumap,
int maplen) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
cpu_set_t mask;
int i, maxcpu;
virNodeInfo nodeinfo;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s",_("cannot pin vcpus on an inactive domain"));
- return -1;
+ goto cleanup;
}
if (vcpu > (vm->nvcpupids-1)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
_("vcpu number out of range %d > %d"),
vcpu, vm->nvcpupids);
- return -1;
+ goto cleanup;
}
if (virNodeInfoPopulate(dom->conn, &nodeinfo) < 0)
- return -1;
+ goto cleanup;
maxcpu = maplen * 8;
if (maxcpu > nodeinfo.cpus)
if (sched_setaffinity(vm->vcpupids[vcpu], sizeof(mask), &mask) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
_("cannot set affinity: %s"), strerror(errno));
- return -1;
+ goto cleanup;
}
} else {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("cpu affinity is not supported"));
- return -1;
+ goto cleanup;
}
+ ret = 0;
- return 0;
+cleanup:
+ return ret;
}
static int
int maxinfo,
unsigned char *cpumaps,
int maplen) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
virNodeInfo nodeinfo;
int i, v, maxcpu;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s",_("cannot pin vcpus on an inactive domain"));
- return -1;
+ goto cleanup;
}
if (virNodeInfoPopulate(dom->conn, &nodeinfo) < 0)
- return -1;
+ goto cleanup;
maxcpu = maplen * 8;
if (maxcpu > nodeinfo.cpus)
if (maxinfo > vm->nvcpupids)
maxinfo = vm->nvcpupids;
- if (maxinfo < 1)
- return 0;
-
- if (info != NULL) {
- memset(info, 0, sizeof(*info) * maxinfo);
- for (i = 0 ; i < maxinfo ; i++) {
- info[i].number = i;
- info[i].state = VIR_VCPU_RUNNING;
- /* XXX cpu time, current pCPU mapping */
+ if (maxinfo >= 1) {
+ if (info != NULL) {
+ memset(info, 0, sizeof(*info) * maxinfo);
+ for (i = 0 ; i < maxinfo ; i++) {
+ info[i].number = i;
+ info[i].state = VIR_VCPU_RUNNING;
+ /* XXX cpu time, current pCPU mapping */
+ }
}
- }
- if (cpumaps != NULL) {
- memset(cpumaps, 0, maplen * maxinfo);
- if (vm->vcpupids != NULL) {
- for (v = 0 ; v < maxinfo ; v++) {
- cpu_set_t mask;
- unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);
- CPU_ZERO(&mask);
-
- if (sched_getaffinity(vm->vcpupids[v], sizeof(mask), &mask) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
- _("cannot get affinity: %s"), strerror(errno));
- return -1;
+ if (cpumaps != NULL) {
+ memset(cpumaps, 0, maplen * maxinfo);
+ if (vm->vcpupids != NULL) {
+ for (v = 0 ; v < maxinfo ; v++) {
+ cpu_set_t mask;
+ unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);
+ CPU_ZERO(&mask);
+
+ if (sched_getaffinity(vm->vcpupids[v], sizeof(mask), &mask) < 0) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
+ _("cannot get affinity: %s"), strerror(errno));
+ goto cleanup;
+ }
+
+ for (i = 0 ; i < maxcpu ; i++)
+ if (CPU_ISSET(i, &mask))
+ VIR_USE_CPU(cpumap, i);
}
-
- for (i = 0 ; i < maxcpu ; i++)
- if (CPU_ISSET(i, &mask))
- VIR_USE_CPU(cpumap, i);
+ } else {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ "%s", _("cpu affinity is not available"));
+ goto cleanup;
}
- } else {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
- "%s", _("cpu affinity is not available"));
- return -1;
}
}
+ ret = maxinfo;
- return maxinfo;
+cleanup:
+ return ret;
}
#endif /* HAVE_SCHED_GETAFFINITY */
static int qemudDomainGetMaxVcpus(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
const char *type;
- int ret;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->uuid, uuidstr);
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
- return -1;
+ goto cleanup;
}
if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
_("unknown virt type in domain definition '%d'"),
vm->def->virtType);
- return -1;
+ goto cleanup;
}
- if ((ret = qemudGetMaxVCPUs(dom->conn, type)) < 0) {
- return -1;
- }
+ ret = qemudGetMaxVCPUs(dom->conn, type);
+cleanup:
return ret;
}
static int qemudDomainRestore(virConnectPtr conn,
- const char *path) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
- virDomainDefPtr def;
+ const char *path) {
+ struct qemud_driver *driver = conn->privateData;
+ virDomainDefPtr def = NULL;
virDomainObjPtr vm;
- int fd;
- int ret;
- char *xml;
+ int fd = -1;
+ int ret = -1;
+ char *xml = NULL;
struct qemud_save_header header;
/* Verify the header and read the XML */
if ((fd = open(path, O_RDONLY)) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot read domain image"));
- return -1;
+ goto cleanup;
}
if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to read qemu header"));
- close(fd);
- return -1;
+ goto cleanup;
}
if (memcmp(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic)) != 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("image magic is incorrect"));
- close(fd);
- return -1;
+ goto cleanup;
}
if (header.version > QEMUD_SAVE_VERSION) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("image version is not supported (%d > %d)"),
header.version, QEMUD_SAVE_VERSION);
- close(fd);
- return -1;
+ goto cleanup;
}
if (VIR_ALLOC_N(xml, header.xml_len) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("out of memory"));
- close(fd);
- return -1;
+ goto cleanup;
}
if (saferead(fd, xml, header.xml_len) != header.xml_len) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to read XML"));
- close(fd);
- VIR_FREE(xml);
- return -1;
+ goto cleanup;
}
/* Create a domain from this XML */
if (!(def = virDomainDefParseString(conn, driver->caps, xml))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to parse XML"));
- close(fd);
- VIR_FREE(xml);
- return -1;
+ goto cleanup;
}
- VIR_FREE(xml);
/* Ensure the name and UUID don't already exist in an active VM */
vm = virDomainFindByUUID(&driver->domains, def->uuid);
if (vm && virDomainIsActive(vm)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("domain is already active as '%s'"), vm->def->name);
- close(fd);
- return -1;
+ goto cleanup;
}
if (!(vm = virDomainAssignDef(conn,
def))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to assign new VM"));
- virDomainDefFree(def);
- close(fd);
- return -1;
+ goto cleanup;
}
+ def = NULL;
/* Set the migration source and start it up. */
vm->stdin_fd = fd;
ret = qemudStartVMDaemon(conn, driver, vm, "stdio");
close(fd);
+ fd = -1;
vm->stdin_fd = -1;
if (ret < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains,
vm);
- return -1;
+ goto cleanup;
}
qemudDomainEventDispatch(driver, vm,
if (qemudMonitorCommand(driver, vm, "cont", &info) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to resume domain"));
- return -1;
+ goto cleanup;
}
VIR_FREE(info);
vm->state = VIR_DOMAIN_RUNNING;
}
+ ret = 0;
- return 0;
+cleanup:
+ virDomainDefFree(def);
+ VIR_FREE(xml);
+ if (fd != -1)
+ close(fd);
+
+ return ret;
}
static char *qemudDomainDumpXML(virDomainPtr dom,
int flags ATTRIBUTE_UNUSED) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ char *ret = NULL;
+
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return NULL;
+ goto cleanup;
}
- return virDomainDefFormat(dom->conn,
- (flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef ?
- vm->newDef : vm->def,
- flags);
+ ret = virDomainDefFormat(dom->conn,
+ (flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef ?
+ vm->newDef : vm->def,
+ flags);
+
+cleanup:
+ return ret;
}
static int qemudListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
int got = 0, i;
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) {
}
static int qemudNumDefinedDomains(virConnectPtr conn) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
int n = 0, i;
for (i = 0 ; i < driver->domains.count ; i++)
static int qemudDomainStart(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
- int ret;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
ret = qemudStartVMDaemon(dom->conn, driver, vm, NULL);
- if (ret < 0)
- return ret;
- qemudDomainEventDispatch(driver, vm,
- VIR_DOMAIN_EVENT_STARTED,
- VIR_DOMAIN_EVENT_STARTED_BOOTED);
- return 0;
+ if (ret != -1)
+ qemudDomainEventDispatch(driver, vm,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_BOOTED);
+
+cleanup:
+ return ret;
}
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def;
virDomainObjPtr vm;
- virDomainPtr dom;
+ virDomainPtr dom = NULL;
int newVM = 1;
if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
- return NULL;
+ goto cleanup;
vm = virDomainFindByName(&driver->domains, def->name);
if (vm)
&driver->domains,
def))) {
virDomainDefFree(def);
- return NULL;
+ goto cleanup;
}
vm->persistent = 1;
vm->newDef ? vm->newDef : vm->def) < 0) {
virDomainRemoveInactive(&driver->domains,
vm);
- return NULL;
+ goto cleanup;
}
qemudDomainEventDispatch(driver, vm,
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
+
+cleanup:
return dom;
}
static int qemudDomainUndefine(virDomainPtr dom) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
if (virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot delete active domain"));
- return -1;
+ goto cleanup;
}
if (!vm->persistent) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot undefine transient domain"));
- return -1;
+ goto cleanup;
}
if (virDomainDeleteConfig(dom->conn, driver->configDir, driver->autostartDir, vm) < 0)
- return -1;
+ goto cleanup;
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_UNDEFINED,
virDomainRemoveInactive(&driver->domains,
vm);
+ ret = 0;
- return 0;
+cleanup:
+ return ret;
}
/* Return the disks name for use in monitor commands */
-static char *qemudDiskDeviceName(const virDomainPtr dom,
+static char *qemudDiskDeviceName(const virConnectPtr conn,
const virDomainDiskDefPtr disk) {
int busid, devid;
char *devname;
if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("cannot convert disk '%s' to bus/device index"),
disk->dst);
return NULL;
ret = asprintf(&devname, "virtio%d", devid);
break;
default:
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
_("Unsupported disk name mapping for bus '%s'"),
virDomainDiskBusTypeToString(disk->bus));
return NULL;
}
if (ret == -1) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return NULL;
}
return devname;
}
-static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
+static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
virDomainDiskDefPtr origdisk = NULL, newdisk;
char *cmd, *reply, *safe_path;
char *devname = NULL;
unsigned int qemuCmdFlags;
int i;
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
- return -1;
- }
-
origdisk = NULL;
newdisk = dev->data.disk;
for (i = 0 ; i < vm->def->ndisks ; i++) {
}
if (!origdisk) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
_("No device with bus '%s' and target '%s'"),
virDomainDiskBusTypeToString(newdisk->bus),
newdisk->dst);
if (qemudExtractVersionInfo(vm->def->emulator,
NULL,
&qemuCmdFlags) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
_("Cannot determine QEMU argv syntax %s"),
vm->def->emulator);
return -1;
}
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
- if (!(devname = qemudDiskDeviceName(dom, newdisk)))
+ if (!(devname = qemudDiskDeviceName(conn, newdisk)))
return -1;
} else {
/* Back compat for no -drive option */
STREQ(newdisk->dst, "hdc"))
devname = strdup("cdrom");
else {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
_("Emulator version does not support removable "
"media for device '%s' and target '%s'"),
virDomainDiskDeviceTypeToString(newdisk->device),
}
if (!devname) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return -1;
}
}
if (newdisk->src) {
safe_path = qemudEscapeMonitorArg(newdisk->src);
if (!safe_path) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
VIR_FREE(devname);
return -1;
}
if (asprintf (&cmd, "change %s \"%s\"", devname, safe_path) == -1) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
VIR_FREE(safe_path);
VIR_FREE(devname);
return -1;
VIR_FREE(safe_path);
} else if (asprintf(&cmd, "eject %s", devname) == -1) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_MEMORY, NULL);
VIR_FREE(devname);
return -1;
}
VIR_FREE(devname);
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot change cdrom media"));
VIR_FREE(cmd);
return -1;
* No message is printed on success it seems */
DEBUG ("ejectable media change reply: %s", reply);
if (strstr(reply, "\ndevice ")) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("changing cdrom media failed"));
VIR_FREE(reply);
VIR_FREE(cmd);
return 0;
}
-static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
+static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int ret, i;
char *cmd, *reply, *s;
char *safe_path;
const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
- return -1;
- }
-
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("target %s already exists"), dev->data.disk->dst);
return -1;
}
}
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return -1;
}
safe_path = qemudEscapeMonitorArg(dev->data.disk->src);
if (!safe_path) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("out of memory"));
return -1;
}
safe_path, type);
VIR_FREE(safe_path);
if (ret == -1) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return ret;
}
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("cannot attach %s disk"), type);
VIR_FREE(cmd);
return -1;
if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
qemudLog(QEMUD_WARN, "%s", _("Unable to parse slot number\n"));
} else {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("adding %s disk failed"), type);
VIR_FREE(reply);
VIR_FREE(cmd);
return 0;
}
-static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
+static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int ret, i;
char *safe_path;
char *cmd, *reply;
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
- return -1;
- }
-
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("target %s already exists"), dev->data.disk->dst);
return -1;
}
}
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return -1;
}
safe_path = qemudEscapeMonitorArg(dev->data.disk->src);
if (!safe_path) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("out of memory"));
return -1;
}
ret = asprintf(&cmd, "usb_add disk:%s", safe_path);
VIR_FREE(safe_path);
if (ret == -1) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return ret;
}
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot attach usb disk"));
VIR_FREE(cmd);
return -1;
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s",
_("adding usb disk failed"));
VIR_FREE(reply);
return 0;
}
-static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
+static int qemudDomainAttachHostDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int ret;
char *cmd, *reply;
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
- return -1;
- }
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return -1;
}
dev->data.hostdev->source.subsys.usb.device);
}
if (ret == -1) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return -1;
}
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot attach usb device"));
VIR_FREE(cmd);
return -1;
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s",
_("adding usb device failed"));
VIR_FREE(reply);
static int qemudDomainAttachDevice(virDomainPtr dom,
const char *xml) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
- virDomainDeviceDefPtr dev;
- int ret = 0, supported = 0;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ virDomainDeviceDefPtr dev = NULL;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot attach device on inactive domain"));
- return -1;
+ goto cleanup;
}
dev = virDomainDeviceDefParse(dom->conn,
driver->caps,
vm->def, xml);
- if (dev == NULL) {
- return -1;
- }
+ if (dev == NULL)
+ goto cleanup;
+
if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
switch (dev->data.disk->device) {
- case VIR_DOMAIN_DISK_DEVICE_CDROM:
- case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
- supported = 1;
- ret = qemudDomainChangeEjectableMedia(dom, dev);
- break;
- case VIR_DOMAIN_DISK_DEVICE_DISK:
- if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
- supported = 1;
- ret = qemudDomainAttachUsbMassstorageDevice(dom, dev);
- } else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
- dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
- supported = 1;
- ret = qemudDomainAttachPciDiskDevice(dom, dev);
- }
- break;
+ case VIR_DOMAIN_DISK_DEVICE_CDROM:
+ case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
+ ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev);
+ break;
+ case VIR_DOMAIN_DISK_DEVICE_DISK:
+ if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
+ ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm, dev);
+ } else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
+ dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
+ ret = qemudDomainAttachPciDiskDevice(dom->conn, driver, vm, dev);
+ }
+ break;
+ default:
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ "%s", _("this disk device type cannot be attached"));
+ goto cleanup;
}
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
- dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
- supported = 1;
- ret = qemudDomainAttachHostDevice(dom, dev);
- }
-
- if (!supported) {
+ dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+ ret = qemudDomainAttachHostDevice(dom->conn, driver, vm, dev);
+ } else {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("this device type cannot be attached"));
- ret = -1;
+ goto cleanup;
}
- VIR_FREE(dev);
+cleanup:
+ virDomainDeviceDefFree(dev);
return ret;
}
-static int qemudDomainDetachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
+static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm, virDomainDeviceDefPtr dev)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int i, ret = -1;
- char *cmd, *reply;
+ char *cmd = NULL;
+ char *reply = NULL;
virDomainDiskDefPtr detach = NULL;
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
- return -1;
- }
-
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
detach = vm->def->disks[i];
}
if (!detach) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("disk %s not found"), dev->data.disk->dst);
- return -1;
+ goto cleanup;
}
if (detach->slotnum < 1) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("disk %s cannot be detached - invalid slot number %d"),
detach->dst, detach->slotnum);
- return -1;
+ goto cleanup;
}
- ret = asprintf(&cmd, "pci_del 0 %d", detach->slotnum);
- if (ret == -1) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
- return ret;
+ if (asprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ cmd = NULL;
+ goto cleanup;
}
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to execute detach disk %s command"), detach->dst);
- VIR_FREE(cmd);
- return -1;
+ goto cleanup;
}
DEBUG ("pci_del reply: %s", reply);
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
if (strstr(reply, "invalid slot")) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to detach disk %s: invalid slot %d"),
- detach->dst, detach->slotnum);
- ret = -1;
- goto out;
+ detach->dst, detach->slotnum);
+ goto cleanup;
}
if (vm->def->ndisks > 1) {
vm->def->disks[i] = vm->def->disks[--vm->def->ndisks];
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
- qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
- ret = -1;
- goto out;
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
}
qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
virDomainDiskQSort);
vm->def->ndisks = 0;
}
ret = 0;
-out:
+
+cleanup:
VIR_FREE(reply);
VIR_FREE(cmd);
return ret;
static int qemudDomainDetachDevice(virDomainPtr dom,
const char *xml) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
- virDomainDeviceDefPtr dev;
- int ret = 0;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ virDomainDeviceDefPtr dev = NULL;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot attach device on inactive domain"));
- return -1;
+ goto cleanup;
}
dev = virDomainDeviceDefParse(dom->conn, driver->caps, vm->def, xml);
- if (dev == NULL) {
- return -1;
- }
+ if (dev == NULL)
+ goto cleanup;
+
if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
(dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO))
- ret = qemudDomainDetachPciDiskDevice(dom, dev);
- else {
+ ret = qemudDomainDetachPciDiskDevice(dom->conn, driver, vm, dev);
+ else
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("only SCSI or virtio disk device can be detached dynamically"));
- ret = -1;
- }
- VIR_FREE(dev);
+cleanup:
+ virDomainDeviceDefFree(dev);
return ret;
}
static int qemudDomainGetAutostart(virDomainPtr dom,
int *autostart) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
*autostart = vm->autostart;
+ ret = 0;
- return 0;
+cleanup:
+ return ret;
}
static int qemudDomainSetAutostart(virDomainPtr dom,
int autostart) {
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
char *configFile = NULL, *autostartLink = NULL;
int ret = -1;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
if (!vm->persistent) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot set autostart for transient domain"));
- return -1;
+ goto cleanup;
}
autostart = (autostart != 0);
- if (vm->autostart == autostart)
- return 0;
+ if (vm->autostart != autostart) {
+ if ((configFile = virDomainConfigFile(dom->conn, driver->configDir, vm->def->name)) == NULL)
+ goto cleanup;
+ if ((autostartLink = virDomainConfigFile(dom->conn, driver->autostartDir, vm->def->name)) == NULL)
+ goto cleanup;
- if ((configFile = virDomainConfigFile(dom->conn, driver->configDir, vm->def->name)) == NULL)
- goto cleanup;
- if ((autostartLink = virDomainConfigFile(dom->conn, driver->autostartDir, vm->def->name)) == NULL)
- goto cleanup;
+ if (autostart) {
+ int err;
- if (autostart) {
- int err;
+ if ((err = virFileMakePath(driver->autostartDir))) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot create autostart directory %s: %s"),
+ driver->autostartDir, strerror(err));
+ goto cleanup;
+ }
- if ((err = virFileMakePath(driver->autostartDir))) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("cannot create autostart directory %s: %s"),
- driver->autostartDir, strerror(err));
- goto cleanup;
+ if (symlink(configFile, autostartLink) < 0) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to create symlink '%s to '%s': %s"),
+ autostartLink, configFile, strerror(errno));
+ goto cleanup;
+ }
+ } else {
+ if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to delete symlink '%s': %s"),
+ autostartLink, strerror(errno));
+ goto cleanup;
+ }
}
- if (symlink(configFile, autostartLink) < 0) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Failed to create symlink '%s to '%s': %s"),
- autostartLink, configFile, strerror(errno));
- goto cleanup;
- }
- } else {
- if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Failed to delete symlink '%s': %s"),
- autostartLink, strerror(errno));
- goto cleanup;
- }
+ vm->autostart = autostart;
}
-
- vm->autostart = autostart;
ret = 0;
cleanup:
const char *path,
struct _virDomainBlockStats *stats)
{
- struct qemud_driver *driver =
- (struct qemud_driver *)dom->conn->privateData;
+ struct qemud_driver *driver = dom->conn->privateData;
char *dummy, *info = NULL;
const char *p, *eol;
const char *qemu_dev_name = NULL;
size_t len;
int i, ret = -1;
- const virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ virDomainObjPtr vm;
virDomainDiskDefPtr disk = NULL;
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive (vm)) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (!disk) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
_("invalid path: %s"), path);
- return -1;
+ goto cleanup;
}
- qemu_dev_name = qemudDiskDeviceName(dom, disk);
+ qemu_dev_name = qemudDiskDeviceName(dom->conn, disk);
if (!qemu_dev_name)
- return -1;
+ goto cleanup;
len = strlen (qemu_dev_name);
if (qemudMonitorCommand (driver, vm, "info blockstats", &info) < 0) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("'info blockstats' command failed"));
- goto out;
+ goto cleanup;
}
DEBUG ("info blockstats reply: %s", info);
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s",
_("'info blockstats' not supported by this qemu"));
- goto out;
+ goto cleanup;
}
stats->rd_req = -1;
p++;
}
ret = 0;
- goto out;
+ goto cleanup;
}
/* Skip to next line. */
/* If we reach here then the device was not found. */
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
_("device not found: %s (%s)"), path, qemu_dev_name);
- out:
+ cleanup:
VIR_FREE(qemu_dev_name);
VIR_FREE(info);
return ret;
}
+#ifdef __linux__
static int
qemudDomainInterfaceStats (virDomainPtr dom,
const char *path,
struct _virDomainInterfaceStats *stats)
{
-#ifdef __linux__
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
int i;
+ int ret = -1;
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
if (!path || path[0] == '\0') {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s", _("NULL or empty path"));
- return -1;
+ goto cleanup;
}
/* Check the path is one of the domain's network interfaces. */
for (i = 0 ; i < vm->def->nnets ; i++) {
if (vm->def->nets[i]->ifname &&
- STREQ (vm->def->nets[i]->ifname, path))
- goto ok;
+ STREQ (vm->def->nets[i]->ifname, path)) {
+ ret = 0;
+ break;
+ }
}
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
- _("invalid path, '%s' is not a known interface"), path);
- return -1;
- ok:
+ if (ret == 0)
+ ret = linuxDomainInterfaceStats (dom->conn, path, stats);
+ else
+ qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
+ _("invalid path, '%s' is not a known interface"), path);
- return linuxDomainInterfaceStats (dom->conn, path, stats);
+cleanup:
+ return ret;
+}
#else
+static int
+qemudDomainInterfaceStats (virDomainPtr dom,
+ const char *path ATTRIBUTE_UNUSED,
+ struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", __FUNCTION__);
return -1;
-#endif
}
+#endif
static int
qemudDomainBlockPeek (virDomainPtr dom,
void *buffer,
unsigned int flags ATTRIBUTE_UNUSED)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
- int fd, ret = -1, i;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int fd = -1, ret = -1, i;
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
- return -1;
+ goto cleanup;
}
if (!path || path[0] == '\0') {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
"%s", _("NULL or empty path"));
- return -1;
+ goto cleanup;
}
/* Check the path belongs to this domain. */
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (vm->def->disks[i]->src != NULL &&
- STREQ (vm->def->disks[i]->src, path))
- goto found;
+ STREQ (vm->def->disks[i]->src, path)) {
+ ret = 0;
+ break;
+ }
}
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
- "%s", _("invalid path"));
- return -1;
-found:
- /* The path is correct, now try to open it and get its size. */
- fd = open (path, O_RDONLY);
- if (fd == -1) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
- "%s", strerror (errno));
- goto done;
- }
+ if (ret == 0) {
+ ret = -1;
+ /* The path is correct, now try to open it and get its size. */
+ fd = open (path, O_RDONLY);
+ if (fd == -1) {
+ qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
+ "%s", strerror (errno));
+ goto cleanup;
+ }
- /* Seek and read. */
- /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
- * be 64 bits on all platforms.
- */
- if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
- saferead (fd, buffer, size) == (ssize_t) -1) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
- "%s", strerror (errno));
- goto done;
+ /* Seek and read. */
+ /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
+ * be 64 bits on all platforms.
+ */
+ if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
+ saferead (fd, buffer, size) == (ssize_t) -1) {
+ qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
+ "%s", strerror (errno));
+ goto cleanup;
+ }
+
+ ret = 0;
+ } else {
+ qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
+ "%s", _("invalid path"));
}
- ret = 0;
- done:
- if (fd >= 0) close (fd);
+cleanup:
+ if (fd >= 0)
+ close (fd);
return ret;
}
void *buffer,
unsigned int flags)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
- char cmd[256], *info;
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ char cmd[256], *info = NULL;
char tmp[] = TEMPDIR "/qemu.mem.XXXXXX";
int fd = -1, ret = -1;
- if (flags != VIR_MEMORY_VIRTUAL) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
- "%s", _("QEMU driver only supports virtual memory addrs"));
- return -1;
- }
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
+ }
+
+ if (flags != VIR_MEMORY_VIRTUAL) {
+ qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
+ "%s", _("QEMU driver only supports virtual memory addrs"));
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
/* Create a temporary filename. */
if ((fd = mkstemp (tmp)) == -1) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
"%s", strerror (errno));
- return -1;
+ goto cleanup;
}
/* Issue the memsave command. */
if (qemudMonitorCommand (driver, vm, cmd, &info) < 0) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("'memsave' command failed"));
- goto done;
+ goto cleanup;
}
DEBUG ("memsave reply: %s", info);
- free (info);
/* Read the memory file into buffer. */
if (saferead (fd, buffer, size) == (ssize_t) -1) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
"%s", strerror (errno));
- goto done;
+ goto cleanup;
}
ret = 0;
-done:
+
+cleanup:
+ VIR_FREE(info);
if (fd >= 0) close (fd);
unlink (tmp);
return ret;
void *opaque,
virFreeCallback freecb)
{
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
+ int ret;
+
+ ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
+ callback, opaque, freecb);
- return virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
- callback, opaque, freecb);
+ return ret;
}
static int
qemudDomainEventDeregister (virConnectPtr conn,
void *callback)
{
- struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ struct qemud_driver *driver = conn->privateData;
+ int ret;
+
+ ret = virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
+ callback);
- return virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
- callback);
+ return ret;
}
static void qemudDomainEventDispatch (struct qemud_driver *driver,
const char *dom_xml)
{
static int port = 0;
- struct qemud_driver *driver = (struct qemud_driver *)dconn->privateData;
- virDomainDefPtr def;
+ struct qemud_driver *driver = dconn->privateData;
+ virDomainDefPtr def = NULL;
virDomainObjPtr vm = NULL;
int this_port;
char hostname [HOST_NAME_MAX+1];
char migrateFrom [64];
const char *p;
+ int ret = -1;;
+
+ *uri_out = NULL;
if (!dom_xml) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("no domain XML passed"));
- return -1;
+ goto cleanup;
}
/* The URI passed in may be NULL or a string "tcp://somehostname:port".
if (gethostname (hostname, HOST_NAME_MAX+1) == -1) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_SYSTEM_ERROR,
"%s", strerror (errno));
- return -1;
+ goto cleanup;
}
/* Caller frees */
if (asprintf(uri_out, "tcp:%s:%d", hostname, this_port) < 0) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_NO_MEMORY,
"%s", strerror (errno));
- return -1;
+ *uri_out = NULL;
+ goto cleanup;
}
} else {
/* Check the URI starts with "tcp:". We will escape the
if (!STREQLEN (uri_in, "tcp:", 6)) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_ARG,
"%s", _("only tcp URIs are supported for KVM migrations"));
- return -1;
+ goto cleanup;
}
/* Get the port number. */
if (this_port == -1 || p-uri_in != strlen (uri_in)) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_ARG,
"%s", _("URI did not have ':port' at the end"));
- return -1;
+ goto cleanup;
}
}
if (!(def = virDomainDefParseString(dconn, driver->caps, dom_xml))) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to parse XML"));
- return -1;
+ goto cleanup;
}
/* Target domain name, maybe renamed. */
if (virUUIDGenerate (def->uuid) == -1) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("could not generate random UUID"));
+ goto cleanup;
}
#endif
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("domain with the same name or UUID already exists as '%s'"),
vm->def->name);
- virDomainDefFree(def);
- return -1;
+ goto cleanup;
}
}
def))) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to assign new VM"));
- virDomainDefFree(def);
- return -1;
+ goto cleanup;
}
+ def = NULL;
/* Domain starts inactive, even if the domain XML had an id field. */
vm->def->id = -1;
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains, vm);
- return -1;
+ goto cleanup;
}
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_MIGRATED);
+ ret = 0;
- return 0;
+cleanup:
+ virDomainDefFree(def);
+ if (ret != 0) {
+ VIR_FREE(*uri_out);
+ }
+
+ return ret;
}
/* Perform is the second step, and it runs on the source host. */
const char *dname ATTRIBUTE_UNUSED,
unsigned long resource)
{
- struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
- virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
char *safe_uri;
char cmd[HOST_NAME_MAX+50];
- char *info;
+ char *info = NULL;
+ int ret = -1;
+ vm = virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id %d"), dom->id);
- return -1;
+ goto cleanup;
}
if (!virDomainIsActive(vm)) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("domain is not running"));
- return -1;
+ goto cleanup;
}
if (!(flags & VIR_MIGRATE_LIVE)) {
if (!safe_uri) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
"%s", strerror (errno));
- return -1;
+ goto cleanup;
}
snprintf (cmd, sizeof cmd, "migrate \"%s\"", safe_uri);
VIR_FREE (safe_uri);
if (qemudMonitorCommand (driver, vm, cmd, &info) < 0) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("migrate operation failed"));
- return -1;
+ goto cleanup;
}
DEBUG ("migrate reply: %s", info);
if (strstr(info, "fail") != NULL) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("migrate failed: %s"), info);
- VIR_FREE(info);
- return -1;
+ goto cleanup;
}
- VIR_FREE (info);
-
/* Clean up the source domain. */
qemudShutdownVMDaemon (dom->conn, driver, vm);
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains, vm);
+ ret = 0;
- return 0;
+cleanup:
+ VIR_FREE(info);
+ return ret;
}
/* Finish is the third and final step, and it runs on the destination host. */
unsigned long flags ATTRIBUTE_UNUSED,
int retcode)
{
- struct qemud_driver *driver = (struct qemud_driver *)dconn->privateData;
- virDomainObjPtr vm = virDomainFindByName(&driver->domains, dname);
- virDomainPtr dom;
+ struct qemud_driver *driver = dconn->privateData;
+ virDomainObjPtr vm;
+ virDomainPtr dom = NULL;
char *info = NULL;
+ vm = virDomainFindByName(&driver->domains, dname);
if (!vm) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching name %s"), dname);
- return NULL;
+ goto cleanup;
}
/* Did the migration go as planned? If yes, return the domain
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_RESUMED,
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
- return dom;
} else {
qemudShutdownVMDaemon (dconn, driver, vm);
qemudDomainEventDispatch(driver, vm,
VIR_DOMAIN_EVENT_STOPPED_FAILED);
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains, vm);
- return NULL;
}
+
+cleanup:
+ return dom;
}
static virDriver qemuDriver = {