int libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb) { unsigned short port; const char *listenAddr; libxl_device_vfb_init(x_vfb); switch (l_vfb->type) { case VIR_DOMAIN_GRAPHICS_TYPE_SDL: libxl_defbool_set(&x_vfb->sdl.enable, 1); if (VIR_STRDUP(x_vfb->sdl.display, l_vfb->data.sdl.display) < 0) return -1; if (VIR_STRDUP(x_vfb->sdl.xauthority, l_vfb->data.sdl.xauth) < 0) return -1; break; case VIR_DOMAIN_GRAPHICS_TYPE_VNC: libxl_defbool_set(&x_vfb->vnc.enable, 1); /* driver handles selection of free port */ libxl_defbool_set(&x_vfb->vnc.findunused, 0); if (l_vfb->data.vnc.autoport) { if (virPortAllocatorAcquire(driver->reservedVNCPorts, &port) < 0) return -1; l_vfb->data.vnc.port = port; } x_vfb->vnc.display = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN; listenAddr = virDomainGraphicsListenGetAddress(l_vfb, 0); if (listenAddr) { /* libxl_device_vfb_init() does VIR_STRDUP("127.0.0.1") */ VIR_FREE(x_vfb->vnc.listen); if (VIR_STRDUP(x_vfb->vnc.listen, listenAddr) < 0) return -1; } if (VIR_STRDUP(x_vfb->keymap, l_vfb->data.vnc.keymap) < 0) return -1; break; } return 0; }
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; }