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
Thanks for the comments and explanations,
Florian
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