static virLXCControllerPtr virLXCControllerNew(const char *name) { virLXCControllerPtr ctrl = NULL; virCapsPtr caps = NULL; char *configFile = NULL; if (VIR_ALLOC(ctrl) < 0) goto no_memory; ctrl->timerShutdown = -1; ctrl->firstClient = true; if (!(ctrl->name = strdup(name))) goto no_memory; if ((caps = lxcCapsInit(NULL)) == NULL) goto error; if ((configFile = virDomainConfigFile(LXC_STATE_DIR, ctrl->name)) == NULL) goto error; if ((ctrl->def = virDomainDefParseFile(caps, configFile, 1 << VIR_DOMAIN_VIRT_LXC, 0)) == NULL) goto error; if ((ctrl->timerShutdown = virEventAddTimeout(-1, virLXCControllerQuitTimer, ctrl, NULL)) < 0) goto error; cleanup: VIR_FREE(configFile); virObjectUnref(caps); return ctrl; no_memory: virReportOOMError(); error: virLXCControllerFree(ctrl); ctrl = NULL; goto cleanup; }
static int bhyveDomainSetAutostart(virDomainPtr domain, int autostart) { virDomainObjPtr vm; char *configFile = NULL; char *autostartLink = NULL; int ret = -1; if (!(vm = bhyveDomObjFromDomain(domain))) goto cleanup; if (virDomainSetAutostartEnsureACL(domain->conn, vm->def) < 0) goto cleanup; if (!vm->persistent) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cannot set autostart for transient domain")); goto cleanup; } autostart = (autostart != 0); if (vm->autostart != autostart) { if ((configFile = virDomainConfigFile(BHYVE_CONFIG_DIR, vm->def->name)) == NULL) goto cleanup; if ((autostartLink = virDomainConfigFile(BHYVE_AUTOSTART_DIR, vm->def->name)) == NULL) goto cleanup; if (autostart) { if (virFileMakePath(BHYVE_AUTOSTART_DIR) < 0) { virReportSystemError(errno, _("cannot create autostart directory %s"), BHYVE_AUTOSTART_DIR); goto cleanup; } if (symlink(configFile, autostartLink) < 0) { virReportSystemError(errno, _("Failed to create symlink '%s' to '%s'"), autostartLink, configFile); goto cleanup; } } else { if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) { virReportSystemError(errno, _("Failed to delete symlink '%s'"), autostartLink); goto cleanup; } } vm->autostart = autostart; } ret = 0; cleanup: VIR_FREE(configFile); VIR_FREE(autostartLink); if (vm) virObjectUnlock(vm); return ret; }
int main(int argc, char *argv[]) { pid_t pid; int rc = 1; int client; char *name = NULL; int nveths = 0; char **veths = NULL; int monitor = -1; int appPty = -1; int bg = 0; virCapsPtr caps = NULL; virDomainDefPtr def = NULL; char *configFile = NULL; char *sockpath = NULL; const struct option options[] = { { "background", 0, NULL, 'b' }, { "name", 1, NULL, 'n' }, { "veth", 1, NULL, 'v' }, { "console", 1, NULL, 'c' }, { "help", 0, NULL, 'h' }, { 0, 0, 0, 0 }, }; if (setlocale(LC_ALL, "") == NULL || bindtextdomain(PACKAGE, LOCALEDIR) == NULL || textdomain(PACKAGE) == NULL) { fprintf(stderr, _("%s: initialization failed\n"), argv[0]); exit(EXIT_FAILURE); } while (1) { int c; c = getopt_long(argc, argv, "dn:v:m:c:h", options, NULL); if (c == -1) break; switch (c) { case 'b': bg = 1; break; case 'n': if ((name = strdup(optarg)) == NULL) { virReportOOMError(); goto cleanup; } break; case 'v': if (VIR_REALLOC_N(veths, nveths+1) < 0) { virReportOOMError(); goto cleanup; } if ((veths[nveths++] = strdup(optarg)) == NULL) { virReportOOMError(); goto cleanup; } break; case 'c': if (virStrToLong_i(optarg, NULL, 10, &appPty) < 0) { fprintf(stderr, "malformed --console argument '%s'", optarg); goto cleanup; } break; case 'h': case '?': fprintf(stderr, "\n"); fprintf(stderr, "syntax: %s [OPTIONS]\n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, "Options\n"); fprintf(stderr, "\n"); fprintf(stderr, " -b, --background\n"); fprintf(stderr, " -n NAME, --name NAME\n"); fprintf(stderr, " -c FD, --console FD\n"); fprintf(stderr, " -v VETH, --veth VETH\n"); fprintf(stderr, " -h, --help\n"); fprintf(stderr, "\n"); goto cleanup; } } if (name == NULL) { fprintf(stderr, "%s: missing --name argument for configuration\n", argv[0]); goto cleanup; } if (appPty < 0) { fprintf(stderr, "%s: missing --console argument for container PTY\n", argv[0]); goto cleanup; } if (getuid() != 0) { fprintf(stderr, "%s: must be run as the 'root' user\n", argv[0]); goto cleanup; } if ((caps = lxcCapsInit()) == NULL) goto cleanup; if ((configFile = virDomainConfigFile(LXC_STATE_DIR, name)) == NULL) goto cleanup; if ((def = virDomainDefParseFile(caps, configFile, VIR_DOMAIN_XML_INACTIVE)) == NULL) goto cleanup; if (def->nnets != nveths) { fprintf(stderr, "%s: expecting %d veths, but got %d\n", argv[0], def->nnets, nveths); goto cleanup; } if ((sockpath = lxcMonitorPath(def)) == NULL) goto cleanup; if ((monitor = lxcMonitorServer(sockpath)) < 0) goto cleanup; if (bg) { if ((pid = fork()) < 0) goto cleanup; if (pid > 0) { if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) != 0) { virReportSystemError(rc, _("Unable to write pid file '%s/%s.pid'"), LXC_STATE_DIR, name); _exit(1); } /* First child now exits, allowing original caller * (ie libvirtd's LXC driver to complete their * waitpid & continue */ _exit(0); } /* Don't hold onto any cwd we inherit from libvirtd either */ if (chdir("/") < 0) { virReportSystemError(errno, "%s", _("Unable to change to root dir")); goto cleanup; } if (setsid() < 0) { virReportSystemError(errno, "%s", _("Unable to become session leader")); goto cleanup; } } /* Initialize logging */ virLogSetFromEnv(); /* Accept initial client which is the libvirtd daemon */ if ((client = accept(monitor, NULL, 0)) < 0) { virReportSystemError(errno, "%s", _("Failed to accept a connection from driver")); goto cleanup; } rc = lxcControllerRun(def, nveths, veths, monitor, client, appPty); cleanup: if (def) virFileDeletePid(LXC_STATE_DIR, def->name); lxcControllerCleanupInterfaces(nveths, veths); if (sockpath) unlink(sockpath); VIR_FREE(sockpath); return rc; }