/** * virAdmConnectOpen: * @name: uri of the daemon to connect to, NULL for default * @flags: extra flags; not used yet, so callers should always pass 0 * * Opens connection to admin interface of the daemon. * * Returns @virAdmConnectPtr object or NULL on error */ virAdmConnectPtr virAdmConnectOpen(const char *name, unsigned int flags) { char *sock_path = NULL; char *alias = NULL; virAdmConnectPtr conn = NULL; virConfPtr conf = NULL; if (virAdmInitialize() < 0) goto error; VIR_DEBUG("flags=%x", flags); virResetLastError(); virCheckFlagsGoto(VIR_CONNECT_NO_ALIASES, error); if (!(conn = virAdmConnectNew())) goto error; if (virConfLoadConfig(&conf, "libvirt-admin.conf") < 0) goto error; if (!name && !(name = virAdmGetDefaultURI(conf))) goto error; if ((!(flags & VIR_CONNECT_NO_ALIASES) && virURIResolveAlias(conf, name, &alias) < 0)) goto error; if (!(conn->uri = virURIParse(alias ? alias : name))) goto error; if (!(sock_path = getSocketPath(conn->uri))) goto error; if (!(conn->privateData = remoteAdminPrivNew(sock_path))) goto error; conn->privateDataFreeFunc = remoteAdminPrivFree; if (remoteAdminConnectOpen(conn, flags) < 0) goto error; cleanup: VIR_FREE(sock_path); VIR_FREE(alias); virConfFree(conf); return conn; error: virDispatchError(NULL); virObjectUnref(conn); conn = NULL; goto cleanup; }
static virDrvOpenStatus bhyveConnectOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) { virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); if (conn->uri == NULL) { if (bhyve_driver == NULL) return VIR_DRV_OPEN_DECLINED; if (!(conn->uri = virURIParse("bhyve:///system"))) return VIR_DRV_OPEN_ERROR; } else { if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "bhyve")) return VIR_DRV_OPEN_DECLINED; if (conn->uri->server) return VIR_DRV_OPEN_DECLINED; if (!STREQ_NULLABLE(conn->uri->path, "/system")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected bhyve URI path '%s', try bhyve:///system"), conn->uri->path); return VIR_DRV_OPEN_ERROR; } if (bhyve_driver == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("bhyve state driver is not active")); return VIR_DRV_OPEN_ERROR; } } if (virConnectOpenEnsureACL(conn) < 0) return VIR_DRV_OPEN_ERROR; conn->privateData = bhyve_driver; return VIR_DRV_OPEN_SUCCESS; }
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; }
const char *dconnuri ATTRIBUTE_UNUSED, const char *uri_str, const char *dname ATTRIBUTE_UNUSED, unsigned int flags) { char *hostname = NULL; unsigned short port = 0; char portstr[100]; virURIPtr uri = NULL; virNetSocketPtr sock; int sockfd = -1; int saved_errno = EINVAL; int ret = -1; /* parse dst host:port from uri */ uri = virURIParse(uri_str); if (uri == NULL || uri->server == NULL || uri->port == 0) goto cleanup; hostname = uri->server; port = uri->port; snprintf(portstr, sizeof(portstr), "%d", port); /* socket connect to dst host:port */ if (virNetSocketNewConnectTCP(hostname, portstr, &sock) < 0) { virReportSystemError(saved_errno, _("unable to connect to '%s:%s'"), hostname, portstr); goto cleanup; }
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; }
static virDrvOpenStatus openvzOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) { struct openvz_driver *driver; virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); if (conn->uri == NULL) { if (!virFileExists("/proc/vz")) return VIR_DRV_OPEN_DECLINED; if (access("/proc/vz", W_OK) < 0) return VIR_DRV_OPEN_DECLINED; if (!(conn->uri = virURIParse("openvz:///system"))) return VIR_DRV_OPEN_ERROR; } else { /* If scheme isn't 'openvz', then its for another driver */ if (conn->uri->scheme == NULL || STRNEQ (conn->uri->scheme, "openvz")) return VIR_DRV_OPEN_DECLINED; /* If server name is given, its for remote driver */ if (conn->uri->server != NULL) return VIR_DRV_OPEN_DECLINED; /* If path isn't /system, then they typoed, so tell them correct path */ if (conn->uri->path == NULL || STRNEQ (conn->uri->path, "/system")) { openvzError(VIR_ERR_INTERNAL_ERROR, _("unexpected OpenVZ URI path '%s', try openvz:///system"), conn->uri->path); return VIR_DRV_OPEN_ERROR; } if (!virFileExists("/proc/vz")) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("OpenVZ control file /proc/vz does not exist")); return VIR_DRV_OPEN_ERROR; } if (access("/proc/vz", W_OK) < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("OpenVZ control file /proc/vz is not accessible")); return VIR_DRV_OPEN_ERROR; } } /* We now know the URI is definitely for this driver, so beyond * here, don't return DECLINED, always use ERROR */ if (VIR_ALLOC(driver) < 0) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; } if (virDomainObjListInit(&driver->domains) < 0) goto cleanup; if (!(driver->caps = openvzCapsInit())) goto cleanup; if (openvzLoadDomains(driver) < 0) goto cleanup; if (openvzExtractVersion(driver) < 0) goto cleanup; conn->privateData = driver; return VIR_DRV_OPEN_SUCCESS; cleanup: openvzFreeDriver(driver); return VIR_DRV_OPEN_ERROR; };