/** * virReleaseConnect: * @conn: the hypervisor connection to release * * Unconditionally release all memory associated with a connection. * The conn.lock mutex must be held prior to calling this, and will * be released prior to this returning. The connection obj must not * be used once this method returns. */ static void virReleaseConnect(virConnectPtr conn) { VIR_DEBUG("release connection %p", conn); /* make sure to release the connection lock before we call the * close callbacks, otherwise we will deadlock if an error * is raised by any of the callbacks */ virMutexUnlock(&conn->lock); if (conn->networkDriver) conn->networkDriver->close(conn); if (conn->interfaceDriver) conn->interfaceDriver->close(conn); if (conn->storageDriver) conn->storageDriver->close(conn); if (conn->deviceMonitor) conn->deviceMonitor->close(conn); if (conn->secretDriver) conn->secretDriver->close(conn); if (conn->nwfilterDriver) conn->nwfilterDriver->close(conn); if (conn->driver) conn->driver->close(conn); virMutexLock(&conn->lock); virResetError(&conn->err); virURIFree(conn->uri); virMutexUnlock(&conn->lock); virMutexDestroy(&conn->lock); VIR_FREE(conn); }
static void virAdmConnectDispose(void *obj) { virAdmConnectPtr conn = obj; if (conn->privateDataFreeFunc) conn->privateDataFreeFunc(conn); virURIFree(conn->uri); virObjectUnref(conn->closeCallback); }
/** * virConnectDispose: * @obj: the hypervisor connection to release * * Unconditionally release all memory associated with a connection. * The connection object must not be used once this method returns. */ static void virConnectDispose(void *obj) { virConnectPtr conn = obj; if (conn->driver) conn->driver->connectClose(conn); virResetError(&conn->err); virURIFree(conn->uri); }
/** * virConnectDispose: * @conn: the hypervisor connection to release * * Unconditionally release all memory associated with a connection. * The conn.lock mutex must be held prior to calling this, and will * be released prior to this returning. The connection obj must not * be used once this method returns. */ static void virConnectDispose(void *obj) { virConnectPtr conn = obj; if (conn->networkDriver) conn->networkDriver->networkClose(conn); if (conn->interfaceDriver) conn->interfaceDriver->interfaceClose(conn); if (conn->storageDriver) conn->storageDriver->storageClose(conn); if (conn->nodeDeviceDriver) conn->nodeDeviceDriver->nodeDeviceClose(conn); if (conn->secretDriver) conn->secretDriver->secretClose(conn); if (conn->nwfilterDriver) conn->nwfilterDriver->nwfilterClose(conn); if (conn->driver) conn->driver->connectClose(conn); virMutexLock(&conn->lock); virResetError(&conn->err); virURIFree(conn->uri); if (conn->closeCallback) { virObjectLock(conn->closeCallback); conn->closeCallback->callback = NULL; virObjectUnlock(conn->closeCallback); virObjectUnref(conn->closeCallback); } virMutexUnlock(&conn->lock); virMutexDestroy(&conn->lock); }
static int testURIParse(const void *args) { int ret = -1; virURIPtr uri = NULL; const struct URIParseData *data = args; char *uristr = NULL; size_t i; if (!(uri = virURIParse(data->uri))) goto cleanup; if (!STREQ(uri->scheme, data->scheme)) { VIR_DEBUG("Expected scheme '%s', actual '%s'", data->scheme, uri->scheme); goto cleanup; } if (!STREQ(uri->server, data->server)) { VIR_DEBUG("Expected server '%s', actual '%s'", data->server, uri->server); goto cleanup; } if (uri->port != data->port) { VIR_DEBUG("Expected port '%d', actual '%d'", data->port, uri->port); goto cleanup; } if (!STREQ_NULLABLE(uri->path, data->path)) { VIR_DEBUG("Expected path '%s', actual '%s'", data->path, uri->path); goto cleanup; } if (!STREQ_NULLABLE(uri->query, data->query)) { VIR_DEBUG("Expected query '%s', actual '%s'", data->query, uri->query); goto cleanup; } if (!STREQ_NULLABLE(uri->fragment, data->fragment)) { VIR_DEBUG("Expected fragment '%s', actual '%s'", data->fragment, uri->fragment); goto cleanup; } for (i = 0; data->params && data->params[i].name && i < uri->paramsCount; i++) { if (!STREQ_NULLABLE(data->params[i].name, uri->params[i].name)) { VIR_DEBUG("Expected param name %zu '%s', actual '%s'", i, data->params[i].name, uri->params[i].name); goto cleanup; } if (!STREQ_NULLABLE(data->params[i].value, uri->params[i].value)) { VIR_DEBUG("Expected param value %zu '%s', actual '%s'", i, data->params[i].value, uri->params[i].value); goto cleanup; } } if (data->params && data->params[i].name) { VIR_DEBUG("Missing parameter %zu %s=%s", i, data->params[i].name, data->params[i].value); goto cleanup; } if (i != uri->paramsCount) { VIR_DEBUG("Unexpected parameter %zu %s=%s", i, uri->params[i].name, uri->params[i].value); goto cleanup; } VIR_FREE(uri->query); uri->query = virURIFormatParams(uri); if (!(uristr = virURIFormat(uri))) goto cleanup; if (!STREQ(uristr, data->uri_out)) { VIR_DEBUG("URI did not roundtrip, expect '%s', actual '%s'", data->uri_out, uristr); goto cleanup; } ret = 0; cleanup: VIR_FREE(uristr); virURIFree(uri); return ret; }
int libxlDomainMigrationPrepare(virConnectPtr dconn, virDomainDefPtr def, const char *uri_in, char **uri_out, unsigned int flags) { libxlDriverPrivatePtr driver = dconn->privateData; virDomainObjPtr vm = NULL; char *hostname = NULL; unsigned short port; char portstr[100]; virURIPtr uri = NULL; virNetSocketPtr *socks = NULL; size_t nsocks = 0; int nsocks_listen = 0; libxlMigrationDstArgs *args; size_t i; int ret = -1; if (!(vm = virDomainObjListAdd(driver->domains, def, driver->xmlopt, VIR_DOMAIN_OBJ_LIST_ADD_LIVE | VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL))) goto cleanup; /* Create socket connection to receive migration data */ if (!uri_in) { if ((hostname = virGetHostname()) == NULL) goto cleanup; if (STRPREFIX(hostname, "localhost")) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("hostname on destination resolved to localhost," " but migration requires an FQDN")); goto cleanup; } if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) goto cleanup; if (virAsprintf(uri_out, "tcp://%s:%d", hostname, port) < 0) goto cleanup; } else { if (!(STRPREFIX(uri_in, "tcp://"))) { /* not full URI, add prefix tcp:// */ char *tmp; if (virAsprintf(&tmp, "tcp://%s", uri_in) < 0) goto cleanup; uri = virURIParse(tmp); VIR_FREE(tmp); } else { uri = virURIParse(uri_in); } if (uri == NULL) { virReportError(VIR_ERR_INVALID_ARG, _("unable to parse URI: %s"), uri_in); goto cleanup; } if (uri->server == NULL) { virReportError(VIR_ERR_INVALID_ARG, _("missing host in migration URI: %s"), uri_in); goto cleanup; } else { hostname = uri->server; } if (uri->port == 0) { if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) goto cleanup; } else { port = uri->port; } if (virAsprintf(uri_out, "tcp://%s:%d", hostname, port) < 0) goto cleanup; } snprintf(portstr, sizeof(portstr), "%d", port); if (virNetSocketNewListenTCP(hostname, portstr, &socks, &nsocks) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Fail to create socket for incoming migration")); goto cleanup; } if (libxlMigrationDstArgsInitialize() < 0) goto cleanup; if (!(args = virObjectNew(libxlMigrationDstArgsClass))) goto cleanup; args->conn = dconn; args->vm = vm; args->flags = flags; args->socks = socks; args->nsocks = nsocks; for (i = 0; i < nsocks; i++) { if (virNetSocketSetBlocking(socks[i], true) < 0) continue; if (virNetSocketListen(socks[i], 1) < 0) continue; if (virNetSocketAddIOCallback(socks[i], VIR_EVENT_HANDLE_READABLE, libxlDoMigrateReceive, args, virObjectFreeCallback) < 0) continue; /* * Successfully added sock to event loop. Take a ref on args to * ensure it is not freed until sock is removed from the event loop. * Ref is dropped in virObjectFreeCallback after being removed * from the event loop. */ virObjectRef(args); nsocks_listen++; } /* Done with args in this function, drop reference */ virObjectUnref(args); if (!nsocks_listen) goto cleanup; ret = 0; goto done; cleanup: for (i = 0; i < nsocks; i++) { virNetSocketClose(socks[i]); virObjectUnref(socks[i]); } done: virURIFree(uri); if (vm) virObjectUnlock(vm); return ret; }
static char * getSocketPath(const char *name) { char *rundir = virGetUserRuntimeDirectory(); char *sock_path = NULL; size_t i = 0; virURIPtr uri = NULL; if (name) { if (!(uri = virURIParse(name))) goto error; if (STRNEQ(uri->scheme, "admin") || uri->server || uri->user || uri->fragment) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid connection name '%s'"), name); goto error; } for (i = 0; i < uri->paramsCount; i++) { virURIParamPtr param = &uri->params[i]; if (STREQ(param->name, "socket")) { VIR_FREE(sock_path); if (VIR_STRDUP(sock_path, param->value) < 0) goto error; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown URI parameter '%s'"), param->name); goto error; } } } if (!sock_path) { if (!uri || !uri->path || STREQ(uri->path, "/system")) { if (VIR_STRDUP(sock_path, LIBVIRTD_ADMIN_UNIX_SOCKET) < 0) goto error; } else if (STREQ_NULLABLE(uri->path, "/session")) { if (!rundir) goto error; if (virAsprintf(&sock_path, "%s%s", rundir, LIBVIRTD_ADMIN_SOCK_NAME) < 0) goto error; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid URI path '%s'"), uri->path); goto error; } } cleanup: VIR_FREE(rundir); virURIFree(uri); return sock_path; error: VIR_FREE(sock_path); goto cleanup; }