static char * openvzGenerateContainerVethName(int veid) { char *temp = NULL; char *name = NULL; /* try to get line "^NETIF=..." from config */ if (openvzReadVPSConfigParam(veid, "NETIF", &temp) <= 0) { name = strdup("eth0"); } else { char *saveptr = NULL; char *s; int max = 0; /* get maximum interface number (actually, it is the last one) */ for (s=strtok_r(temp, ";", &saveptr); s; s=strtok_r(NULL, ";", &saveptr)) { int x; if (sscanf(s, "ifname=eth%d", &x) != 1) return NULL; if (x > max) max = x; } /* set new name */ ignore_value(virAsprintf(&name, "eth%d", max + 1)); } VIR_FREE(temp); if (name == NULL) { virReportOOMError(); } return name; }
static int openvzDomainGetAutostart(virDomainPtr dom, int *autostart) { struct openvz_driver *driver = dom->conn->privateData; virDomainObjPtr vm; char *value = NULL; int ret = -1; openvzDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); openvzDriverUnlock(driver); if (!vm) { openvzError(VIR_ERR_NO_DOMAIN, "%s", _("no domain with matching uuid")); goto cleanup; } if (openvzReadVPSConfigParam(strtoI(vm->def->name), "ONBOOT", &value) < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not read container config")); goto cleanup; } *autostart = 0; if (STREQ(value,"yes")) *autostart = 1; ret = 0; cleanup: VIR_FREE(value); if (vm) virDomainObjUnlock(vm); return ret; }
int openvzLoadDomains(struct openvz_driver *driver) { int veid, ret; char *status; char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainObjPtr dom = NULL; virDomainDefPtr def = NULL; char *temp = NULL; char *outbuf = NULL; char *line; virCommandPtr cmd = NULL; unsigned int vcpus = 0; if (openvzAssignUUIDs() < 0) return -1; cmd = virCommandNewArgList(VZLIST, "-a", "-ovpsid,status", "-H", NULL); virCommandSetOutputBuffer(cmd, &outbuf); if (virCommandRun(cmd, NULL) < 0) goto cleanup; line = outbuf; while (line[0] != '\0') { unsigned int flags = 0; if (virStrToLong_i(line, &status, 10, &veid) < 0 || *status++ != ' ' || (line = strchr(status, '\n')) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to parse vzlist output")); goto cleanup; } *line++ = '\0'; if (!(def = virDomainDefNew())) goto cleanup; def->virtType = VIR_DOMAIN_VIRT_OPENVZ; if (STREQ(status, "stopped")) def->id = -1; else def->id = veid; if (virAsprintf(&def->name, "%i", veid) < 0) goto cleanup; openvzGetVPSUUID(veid, uuidstr, sizeof(uuidstr)); ret = virUUIDParse(uuidstr, def->uuid); if (ret == -1) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("UUID in config file malformed")); goto cleanup; } def->os.type = VIR_DOMAIN_OSTYPE_EXE; if (VIR_STRDUP(def->os.init, "/sbin/init") < 0) goto cleanup; ret = openvzReadVPSConfigParam(veid, "CPUS", &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read config for container %d"), veid); goto cleanup; } else if (ret > 0) { vcpus = strtoI(temp); } if (ret == 0 || vcpus == 0) vcpus = openvzGetNodeCPUs(); def->maxvcpus = vcpus; def->vcpus = vcpus; /* XXX load rest of VM config data .... */ openvzReadNetworkConf(def, veid); openvzReadFSConf(def, veid); openvzReadMemConf(def, veid); virUUIDFormat(def->uuid, uuidstr); flags = VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE; if (STRNEQ(status, "stopped")) flags |= VIR_DOMAIN_OBJ_LIST_ADD_LIVE; if (!(dom = virDomainObjListAdd(driver->domains, def, driver->xmlopt, flags, NULL))) goto cleanup; if (STREQ(status, "stopped")) { virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_UNKNOWN); dom->pid = -1; } else { virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN); dom->pid = veid; } /* XXX OpenVZ doesn't appear to have concept of a transient domain */ dom->persistent = 1; virObjectUnlock(dom); dom = NULL; def = NULL; } virCommandFree(cmd); VIR_FREE(temp); VIR_FREE(outbuf); return 0; cleanup: virCommandFree(cmd); VIR_FREE(temp); VIR_FREE(outbuf); virObjectUnref(dom); virDomainDefFree(def); return -1; }
static int openvzReadMemConf(virDomainDefPtr def, int veid) { int ret = -1; char *temp = NULL; unsigned long long barrier, limit; const char *param; long kb_per_pages; kb_per_pages = openvzKBPerPages(); if (kb_per_pages < 0) goto error; /* Memory allocation guarantee */ param = "VMGUARPAGES"; ret = openvzReadVPSConfigParam(veid, param, &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read '%s' from config for container %d"), param, veid); goto error; } else if (ret > 0) { ret = openvzParseBarrierLimit(temp, &barrier, NULL); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not parse barrier of '%s' " "from config for container %d"), param, veid); goto error; } if (barrier == LONG_MAX) def->mem.min_guarantee = 0ull; else def->mem.min_guarantee = barrier * kb_per_pages; } /* Memory hard and soft limits */ param = "PRIVVMPAGES"; ret = openvzReadVPSConfigParam(veid, param, &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read '%s' from config for container %d"), param, veid); goto error; } else if (ret > 0) { ret = openvzParseBarrierLimit(temp, &barrier, &limit); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not parse barrier and limit of '%s' " "from config for container %d"), param, veid); goto error; } if (barrier == LONG_MAX) def->mem.soft_limit = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; else def->mem.soft_limit = barrier * kb_per_pages; if (limit == LONG_MAX) def->mem.hard_limit = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; else def->mem.hard_limit = limit * kb_per_pages; } ret = 0; error: VIR_FREE(temp); return ret; }
static int openvzReadFSConf(virDomainDefPtr def, int veid) { int ret; virDomainFSDefPtr fs = NULL; char *veid_str = NULL; char *temp = NULL; const char *param; unsigned long long barrier, limit; ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'OSTEMPLATE' from config for container %d"), veid); goto error; } else if (ret > 0) { if (VIR_ALLOC(fs) < 0) goto error; fs->type = VIR_DOMAIN_FS_TYPE_TEMPLATE; if (VIR_STRDUP(fs->src, temp) < 0) goto error; } else { /* OSTEMPLATE was not found, VE was booted from a private dir directly */ ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", &temp); if (ret <= 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'VE_PRIVATE' from config for container %d"), veid); goto error; } if (VIR_ALLOC(fs) < 0) goto error; if (virAsprintf(&veid_str, "%d", veid) < 0) goto error; fs->type = VIR_DOMAIN_FS_TYPE_MOUNT; if (!(fs->src = virStringReplace(temp, "$VEID", veid_str))) goto error; VIR_FREE(veid_str); } if (VIR_STRDUP(fs->dst, "/") < 0) goto error; param = "DISKSPACE"; ret = openvzReadVPSConfigParam(veid, param, &temp); if (ret > 0) { if (openvzParseBarrierLimit(temp, &barrier, &limit)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read '%s' from config for container %d"), param, veid); goto error; } else { /* Ensure that we can multiply by 1024 without overflowing. */ if (barrier > ULLONG_MAX / 1024 || limit > ULLONG_MAX / 1024) { virReportError(VIR_ERR_OVERFLOW, "%s", _("Unable to parse quota")); goto error; } fs->space_soft_limit = barrier * 1024; /* unit is bytes */ fs->space_hard_limit = limit * 1024; /* unit is bytes */ } } if (VIR_APPEND_ELEMENT(def->fss, def->nfss, fs) < 0) goto error; VIR_FREE(temp); return 0; error: VIR_FREE(temp); virDomainFSDefFree(fs); return -1; }
int openvzReadNetworkConf(virDomainDefPtr def, int veid) { int ret; virDomainNetDefPtr net = NULL; char *temp = NULL; char *token, *saveptr = NULL; /*parse routing network configuration* * Sample from config: * IP_ADDRESS="1.1.1.1 1.1.1.2" * IPs split by space */ ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'IP_ADDRESS' from config for container %d"), veid); goto error; } else if (ret > 0) { token = strtok_r(temp, " ", &saveptr); while (token != NULL) { if (VIR_ALLOC(net) < 0) goto error; net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; if (virDomainNetAppendIpAddress(net, token, AF_UNSPEC, 0) < 0) goto error; if (VIR_APPEND_ELEMENT_COPY(def->nets, def->nnets, net) < 0) goto error; token = strtok_r(NULL, " ", &saveptr); } } /*parse bridge devices*/ /*Sample from config: * NETIF="ifname=eth10,mac=00:18:51:C1:05:EE,host_ifname=veth105.10,host_mac=00:18:51:8F:D9:F3" *devices split by ';' */ ret = openvzReadVPSConfigParam(veid, "NETIF", &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'NETIF' from config for container %d"), veid); goto error; } else if (ret > 0) { token = strtok_r(temp, ";", &saveptr); while (token != NULL) { /*add new device to list*/ if (VIR_ALLOC(net) < 0) goto error; net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; char *p = token; char cpy_temp[32]; int len; /*parse string*/ do { char *next = strchrnul(p, ','); if (STRPREFIX(p, "ifname=")) { /* skip in libvirt */ } else if (STRPREFIX(p, "host_ifname=")) { p += 12; len = next - p; if (len > 16) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Too long network device name")); goto error; } if (VIR_ALLOC_N(net->ifname, len+1) < 0) goto error; if (virStrncpy(net->ifname, p, len, len+1) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Network ifname %s too long for destination"), p); goto error; } } else if (STRPREFIX(p, "bridge=")) { p += 7; len = next - p; if (len > 16) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Too long bridge device name")); goto error; } if (VIR_ALLOC_N(net->data.bridge.brname, len+1) < 0) goto error; if (virStrncpy(net->data.bridge.brname, p, len, len+1) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Bridge name %s too long for destination"), p); goto error; } } else if (STRPREFIX(p, "mac=")) { p += 4; len = next - p; if (len != 17) { /* should be 17 */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Wrong length MAC address")); goto error; } if (virStrncpy(cpy_temp, p, len, sizeof(cpy_temp)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("MAC address %s too long for destination"), p); goto error; } if (virMacAddrParse(cpy_temp, &net->mac) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Wrong MAC address")); goto error; } } p = ++next; } while (p < token + strlen(token)); if (VIR_APPEND_ELEMENT_COPY(def->nets, def->nnets, net) < 0) goto error; token = strtok_r(NULL, ";", &saveptr); } } VIR_FREE(temp); return 0; error: VIR_FREE(temp); virDomainNetDefFree(net); return -1; }