On Fri, Mar 13, 2009 at 12:06:12PM +0100, Florian Vichot wrote: > Hi everyone, > > Here is the new patch, with the requested modifications: > - The target tag is now set to '/', and not used to specify the pivot > root location. > - Search and replace uses virBuffer and strstr() > - Use of virAsprintf when possible, instead of stack arrays. > - Default config file name is read from /etc/vz/vz.conf I think this looks good now, so ACK to this patch unless Evgeniy has further suggestions from an OpenVZ point of view. I'll commit this tomorrow if no one objects... Daniel > diff --git a/src/openvz_conf.c b/src/openvz_conf.c > index ff3d607..c5f4a14 100644 > --- a/src/openvz_conf.c > +++ b/src/openvz_conf.c > @@ -192,7 +192,7 @@ openvzReadNetworkConf(virConnectPtr conn, > * IP_ADDRESS="1.1.1.1 1.1.1.2" > * splited IPs by space > */ > - ret = openvzReadConfigParam(veid, "IP_ADDRESS", temp, sizeof(temp)); > + ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", temp, sizeof(temp)); > if (ret < 0) { > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > _("Cound not read 'IP_ADDRESS' from config for container %d"), > @@ -224,7 +224,7 @@ openvzReadNetworkConf(virConnectPtr conn, > *NETIF="ifname=eth10,mac=00:18:51:C1:05:EE,host_ifname=veth105.10,host_mac=00:18:51:8F:D9:F3" > *devices splited by ';' > */ > - ret = openvzReadConfigParam(veid, "NETIF", temp, sizeof(temp)); > + ret = openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp)); > if (ret < 0) { > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > _("Cound not read 'NETIF' from config for container %d"), > @@ -314,15 +314,46 @@ error: > } > > > +/* utility function to replace 'from' by 'to' in 'str' */ > +static char* > +openvz_replace(const char* str, > + const char* from, > + const char* to) { > + const char* offset = NULL; > + const char* str_start = str; > + int to_len = strlen(to); > + int from_len = strlen(from); > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + > + if(!from) > + return NULL; > + > + while((offset = strstr(str_start, from))) > + { > + virBufferAdd(&buf, str_start, offset-str_start); > + virBufferAdd(&buf, to, to_len); > + str_start = offset + from_len; > + } > + > + virBufferAdd(&buf, str_start, strlen(str_start)); > + > + if(virBufferError(&buf)) > + return NULL; > + > + return virBufferContentAndReset(&buf); > +} > + > + > static int > openvzReadFSConf(virConnectPtr conn, > virDomainDefPtr def, > int veid) { > int ret; > virDomainFSDefPtr fs = NULL; > - char temp[4096]; > + char* veid_str = NULL; > + char temp[100]; > > - ret = openvzReadConfigParam(veid, "OSTEMPLATE", temp, sizeof(temp)); > + ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", temp, sizeof(temp)); > if (ret < 0) { > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > _("Cound not read 'OSTEMPLATE' from config for container %d"), > @@ -334,18 +365,38 @@ openvzReadFSConf(virConnectPtr conn, > > fs->type = VIR_DOMAIN_FS_TYPE_TEMPLATE; > fs->src = strdup(temp); > - fs->dst = strdup("/"); > + } else { > + /* OSTEMPLATE was not found, VE was booted from a private dir directly */ > + ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", temp, sizeof(temp)); > + if (ret <= 0) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + _("Cound not read 'VE_PRIVATE' from config for container %d"), > + veid); > + goto error; > + } > > - if (fs->src == NULL || fs->dst == NULL) > + if (VIR_ALLOC(fs) < 0) > goto no_memory; > > - if (VIR_REALLOC_N(def->fss, def->nfss + 1) < 0) > - goto no_memory; > - def->fss[def->nfss++] = fs; > - fs = NULL; > + if(virAsprintf(&veid_str, "%d", veid) < 0) > + goto error; > + > + fs->type = VIR_DOMAIN_FS_TYPE_MOUNT; > + fs->src = openvz_replace(temp, "$VEID", veid_str); > > + VIR_FREE(veid_str); > } > > + fs->dst = strdup("/"); > + > + if (fs->src == NULL || fs->dst == NULL) > + goto no_memory; > + > + if (VIR_REALLOC_N(def->fss, def->nfss + 1) < 0) > + goto no_memory; > + def->fss[def->nfss++] = fs; > + fs = NULL; > + > return 0; > no_memory: > virReportOOMError(conn); > @@ -432,7 +483,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { > if (!(dom->def->os.init = strdup("/sbin/init"))) > goto no_memory; > > - ret = openvzReadConfigParam(veid, "CPUS", temp, sizeof(temp)); > + ret = openvzReadVPSConfigParam(veid, "CPUS", temp, sizeof(temp)); > if (ret < 0) { > openvzError(NULL, VIR_ERR_INTERNAL_ERROR, > _("Cound not read config for container %d"), > @@ -485,26 +536,23 @@ openvzGetNodeCPUs(void) > return nodeinfo.cpus; > } > > -int > -openvzWriteConfigParam(int vpsid, const char *param, const char *value) > +static int > +openvzWriteConfigParam(const char * conf_file, const char *param, const char *value) > { > - char conf_file[PATH_MAX]; > - char temp_file[PATH_MAX]; > + char * temp_file = NULL; > + int fd = -1, temp_fd = -1; > char line[PATH_MAX] ; > - int fd, temp_fd; > > - if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0) > - return -1; > - if (openvzLocateConfFile(vpsid, temp_file, PATH_MAX, "tmp")<0) > + if (virAsprintf(&temp_file, "%s.tmp", conf_file)<0) > return -1; > > fd = open(conf_file, O_RDONLY); > if (fd == -1) > - return -1; > + goto error; > temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); > if (temp_fd == -1) { > close(fd); > - return -1; > + goto error; > } > > while(1) { > @@ -541,30 +589,32 @@ error: > close(fd); > if (temp_fd != -1) > close(temp_fd); > - unlink(temp_file); > + if(temp_file) > + unlink(temp_file); > + VIR_FREE(temp_file); > return -1; > } > > -/* > -* Read parameter from container config > -* sample: 133, "OSTEMPLATE", value, 1024 > -* return: -1 - error > -* 0 - don't found > -* 1 - OK > -*/ > int > -openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen) > +openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value) > +{ > + char conf_file[PATH_MAX]; > + > + if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0) > + return -1; > + > + return openvzWriteConfigParam(conf_file, param, value); > +} > + > +static int > +openvzReadConfigParam(const char * conf_file ,const char * param, char *value, int maxlen) > { > - char conf_file[PATH_MAX] ; > char line[PATH_MAX] ; > int ret, found = 0; > int fd ; > char * sf, * token; > char *saveptr = NULL; > > - if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0) > - return -1; > - > value[0] = 0; > > fd = open(conf_file, O_RDONLY); > @@ -597,6 +647,103 @@ openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen) > return ret ; > } > > +/* > +* Read parameter from container config > +* sample: 133, "OSTEMPLATE", value, 1024 > +* return: -1 - error > +* 0 - don't found > +* 1 - OK > +*/ > +int > +openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen) > +{ > + char conf_file[PATH_MAX] ; > + > + if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0) > + return -1; > + > + return openvzReadConfigParam(conf_file, param, value, maxlen); > +} > + > +static int > +openvz_copyfile(char* from_path, char* to_path) > +{ > + char line[PATH_MAX]; > + int fd, copy_fd; > + int bytes_read; > + > + fd = open(from_path, O_RDONLY); > + if (fd == -1) > + return -1; > + copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); > + if (copy_fd == -1) { > + close(fd); > + return -1; > + } > + > + while(1) { > + if (openvz_readline(fd, line, sizeof(line)) <= 0) > + break; > + > + bytes_read = strlen(line); > + if (safewrite(copy_fd, line, bytes_read) != bytes_read) > + goto error; > + } > + > + if (close(fd) < 0) > + goto error; > + fd = -1; > + if (close(copy_fd) < 0) > + goto error; > + copy_fd = -1; > + > + return 0; > + > +error: > + if (fd != -1) > + close(fd); > + if (copy_fd != -1) > + close(copy_fd); > + return -1; > +} > + > +/* > +* Copy the default config to the VE conf file > +* return: -1 - error > +* 0 - OK > +*/ > +int > +openvzCopyDefaultConfig(int vpsid) > +{ > + char * confdir = NULL; > + char * default_conf_file = NULL; > + char configfile_value[PATH_MAX]; > + char conf_file[PATH_MAX]; > + int ret = -1; > + > + if(openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", configfile_value, PATH_MAX) < 0) > + goto cleanup; > + > + confdir = openvzLocateConfDir(); > + if (confdir == NULL) > + goto cleanup; > + > + if (virAsprintf(&default_conf_file, "%s/ve-%s.conf-sample", confdir, configfile_value) < 0) > + goto cleanup; > + > + if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0) > + goto cleanup; > + > + if (openvz_copyfile(default_conf_file, conf_file)<0) > + goto cleanup; > + > + ret = 0; > +cleanup: > + VIR_FREE(confdir); > + VIR_FREE(default_conf_file); > + return ret; > +} > + > /* Locate config file of container > * return -1 - error > * 0 - OK > diff --git a/src/openvz_conf.h b/src/openvz_conf.h > index 8e02056..00e18b4 100644 > --- a/src/openvz_conf.h > +++ b/src/openvz_conf.h > @@ -42,6 +42,7 @@ enum { OPENVZ_WARN, OPENVZ_ERR }; > /* OpenVZ commands - Replace with wrapper scripts later? */ > #define VZLIST "/usr/sbin/vzlist" > #define VZCTL "/usr/sbin/vzctl" > +#define VZ_CONF_FILE "/etc/vz/vz.conf" > > #define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 + 1) > > @@ -56,8 +57,9 @@ struct openvz_driver { > int openvz_readline(int fd, char *ptr, int maxlen); > int openvzExtractVersion(virConnectPtr conn, > struct openvz_driver *driver); > -int openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen); > -int openvzWriteConfigParam(int vpsid, const char *param, const char *value); > +int openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen); > +int openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value); > +int openvzCopyDefaultConfig(int vpsid); > virCapsPtr openvzCapsInit(void); > int openvzLoadDomains(struct openvz_driver *driver); > void openvzFreeDriver(struct openvz_driver *driver); > diff --git a/src/openvz_driver.c b/src/openvz_driver.c > index d6c4362..ac2c089 100644 > --- a/src/openvz_driver.c > +++ b/src/openvz_driver.c > @@ -132,19 +132,9 @@ static int openvzDomainDefineCmd(virConnectPtr conn, > ADD_ARG_LIT("create"); > ADD_ARG_LIT(vmdef->name); > > - if (vmdef->nfss) { > - if (vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE) { > - openvzError(conn, VIR_ERR_INTERNAL_ERROR, > - "%s", _("only filesystem templates are supported")); > - return -1; > - } > - > - if (vmdef->nfss > 1) { > - openvzError(conn, VIR_ERR_INTERNAL_ERROR, > - "%s", _("only one filesystem supported")); > - return -1; > - } > - > + if (vmdef->nfss == 1 && > + vmdef->fss[0]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) > + { > ADD_ARG_LIT("--ostemplate"); > ADD_ARG_LIT(vmdef->fss[0]->src); > } > @@ -166,6 +156,77 @@ static int openvzDomainDefineCmd(virConnectPtr conn, > } > > > +static int openvzSetInitialConfig(virConnectPtr conn, > + virDomainDefPtr vmdef) > +{ > + int ret = -1; > + int vpsid; > + char * confdir = NULL; > + const char *prog[OPENVZ_MAX_ARG]; > + prog[0] = NULL; > + > + if (vmdef->nfss > 1) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + "%s", _("only one filesystem supported")); > + goto cleanup; > + } > + > + if (vmdef->nfss == 1 && > + vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE && > + vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_MOUNT) > + { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + "%s", _("filesystem is not of type 'template' or 'mount'")); > + goto cleanup; > + } > + > + > + if (vmdef->nfss == 1 && > + vmdef->fss[0]->type == VIR_DOMAIN_FS_TYPE_MOUNT) > + { > + > + if(virStrToLong_i(vmdef->name, NULL, 10, &vpsid) < 0) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + "%s", _("Could not convert domain name to VEID")); > + goto cleanup; > + } > + > + if (openvzCopyDefaultConfig(vpsid) < 0) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + "%s", _("Could not copy default config")); > + goto cleanup; > + } > + > + if (openvzWriteVPSConfigParam(vpsid, "VE_PRIVATE", vmdef->fss[0]->src) < 0) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + "%s", _("Could not set the source dir for the filesystem")); > + goto cleanup; > + } > + } > + else > + { > + if (openvzDomainDefineCmd(conn, prog, OPENVZ_MAX_ARG, vmdef) < 0) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + "%s", _("Error creating command for container")); > + goto cleanup; > + } > + > + if (virRun(conn, prog, NULL) < 0) { > + openvzError(conn, VIR_ERR_INTERNAL_ERROR, > + _("Could not exec %s"), VZCTL); > + goto cleanup; > + } > + } > + > + ret = 0; > + > +cleanup: > + VIR_FREE(confdir); > + cmdExecFree(prog); > + return ret; > +} > + > + > static virDomainPtr openvzDomainLookupByID(virConnectPtr conn, > int id) { > struct openvz_driver *driver = conn->privateData; > @@ -447,7 +508,7 @@ openvzGenerateContainerVethName(int veid) > char temp[1024]; > > /* try to get line "^NETIF=..." from config */ > - if ( (ret = openvzReadConfigParam(veid, "NETIF", temp, sizeof(temp))) <= 0) { > + if ( (ret = openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp))) <= 0) { > snprintf(temp, sizeof(temp), "eth0"); > } else { > char *saveptr; > @@ -630,7 +691,7 @@ openvzDomainSetNetworkConfig(virConnectPtr conn, > if (driver->version < VZCTL_BRIDGE_MIN_VERSION && def->nnets) { > param = virBufferContentAndReset(&buf); > if (param) { > - if (openvzWriteConfigParam(strtoI(def->name), "NETIF", param) < 0) { > + if (openvzWriteVPSConfigParam(strtoI(def->name), "NETIF", param) < 0) { > VIR_FREE(param); > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > "%s", _("cannot replace NETIF config")); > @@ -656,8 +717,6 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) > virDomainDefPtr vmdef = NULL; > virDomainObjPtr vm = NULL; > virDomainPtr dom = NULL; > - const char *prog[OPENVZ_MAX_ARG]; > - prog[0] = NULL; > > openvzDriverLock(driver); > if ((vmdef = virDomainDefParseString(conn, driver->caps, xml, > @@ -680,20 +739,14 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) > goto cleanup; > vmdef = NULL; > > - if (openvzDomainDefineCmd(conn, prog, OPENVZ_MAX_ARG, vm->def) < 0) { > + if (openvzSetInitialConfig(conn, vm->def) < 0) { > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > - "%s", _("Error creating command for container")); > + "%s", _("Error creating intial configuration")); > goto cleanup; > } > > //TODO: set quota > > - if (virRun(conn, prog, NULL) < 0) { > - openvzError(conn, VIR_ERR_INTERNAL_ERROR, > - _("Could not exec %s"), VZCTL); > - goto cleanup; > - } > - > if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) { > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > "%s", _("Could not set UUID")); > @@ -717,7 +770,6 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) > > cleanup: > virDomainDefFree(vmdef); > - cmdExecFree(prog); > if (vm) > virDomainObjUnlock(vm); > openvzDriverUnlock(driver); > @@ -733,8 +785,6 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml, > virDomainObjPtr vm = NULL; > virDomainPtr dom = NULL; > const char *progstart[] = {VZCTL, "--quiet", "start", PROGRAM_SENTINAL, NULL}; > - const char *progcreate[OPENVZ_MAX_ARG]; > - progcreate[0] = NULL; > > openvzDriverLock(driver); > if ((vmdef = virDomainDefParseString(conn, driver->caps, xml, > @@ -756,15 +806,9 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml, > goto cleanup; > vmdef = NULL; > > - if (openvzDomainDefineCmd(conn, progcreate, OPENVZ_MAX_ARG, vm->def) < 0) { > - openvzError(conn, VIR_ERR_INTERNAL_ERROR, > - "%s", _("Error creating command for container")); > - goto cleanup; > - } > - > - if (virRun(conn, progcreate, NULL) < 0) { > + if (openvzSetInitialConfig(conn, vm->def) < 0) { > openvzError(conn, VIR_ERR_INTERNAL_ERROR, > - _("Could not exec %s"), VZCTL); > + "%s", _("Error creating intial configuration")); > goto cleanup; > } > > @@ -803,7 +847,6 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml, > > cleanup: > virDomainDefFree(vmdef); > - cmdExecFree(progcreate); > if (vm) > virDomainObjUnlock(vm); > openvzDriverUnlock(driver); > @@ -940,7 +983,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) > goto cleanup; > } > > - if (openvzReadConfigParam(strtoI(vm->def->name), "ONBOOT", value, sizeof(value)) < 0) { > + if (openvzReadVPSConfigParam(strtoI(vm->def->name), "ONBOOT", value, sizeof(value)) < 0) { > openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR, > "%s", _("Could not read container config")); > goto cleanup; > -- > Libvir-list mailing list > Libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list