[libvirt] [PATCH 13/20] openvz: Remove several larger stack allocations

Matthias Bolte matthias.bolte at googlemail.com
Sun Apr 3 09:21:26 UTC 2011


Replace openvz_readline with getline in several places to get rid of stack
allocated buffers to hold lines.

openvzReadConfigParam allocates memory for return values instead of
expecting a preexisting buffer.
---
 src/openvz/openvz_conf.c   |  141 +++++++++++++++++++++++++++-----------------
 src/openvz/openvz_conf.h   |    2 +-
 src/openvz/openvz_driver.c |   45 +++++++++-----
 3 files changed, 117 insertions(+), 71 deletions(-)

diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 2fcca68..88cd4c8 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -187,7 +187,7 @@ openvzReadNetworkConf(virDomainDefPtr def,
                       int veid) {
     int ret;
     virDomainNetDefPtr net = NULL;
-    char temp[4096];
+    char *temp = NULL;
     char *token, *saveptr = NULL;
 
     /*parse routing network configuration*
@@ -195,7 +195,7 @@ openvzReadNetworkConf(virDomainDefPtr def,
      *   IP_ADDRESS="1.1.1.1 1.1.1.2"
      *   splited IPs by space
      */
-    ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", temp, sizeof(temp));
+    ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", &temp);
     if (ret < 0) {
         openvzError(VIR_ERR_INTERNAL_ERROR,
                     _("Could not read 'IP_ADDRESS' from config for container %d"),
@@ -227,7 +227,7 @@ openvzReadNetworkConf(virDomainDefPtr def,
      *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 = openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp));
+    ret = openvzReadVPSConfigParam(veid, "NETIF", &temp);
     if (ret < 0) {
         openvzError(VIR_ERR_INTERNAL_ERROR,
                     _("Could not read 'NETIF' from config for container %d"),
@@ -316,10 +316,13 @@ openvzReadNetworkConf(virDomainDefPtr def,
         }
     }
 
+    VIR_FREE(temp);
+
     return 0;
 no_memory:
     virReportOOMError();
 error:
+    VIR_FREE(temp);
     virDomainNetDefFree(net);
     return -1;
 }
@@ -364,10 +367,10 @@ openvzReadFSConf(virDomainDefPtr def,
                  int veid) {
     int ret;
     virDomainFSDefPtr fs = NULL;
-    char* veid_str = NULL;
-    char temp[100];
+    char *veid_str = NULL;
+    char *temp = NULL;
 
-    ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", temp, sizeof(temp));
+    ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp);
     if (ret < 0) {
         openvzError(VIR_ERR_INTERNAL_ERROR,
                     _("Could not read 'OSTEMPLATE' from config for container %d"),
@@ -381,7 +384,7 @@ openvzReadFSConf(virDomainDefPtr def,
         fs->src = strdup(temp);
     } else {
         /* OSTEMPLATE was not found, VE was booted from a private dir directly */
-        ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", temp, sizeof(temp));
+        ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", &temp);
         if (ret <= 0) {
             openvzError(VIR_ERR_INTERNAL_ERROR,
                         _("Could not read 'VE_PRIVATE' from config for container %d"),
@@ -411,10 +414,13 @@ openvzReadFSConf(virDomainDefPtr def,
     def->fss[def->nfss++] = fs;
     fs = NULL;
 
+    VIR_FREE(temp);
+
     return 0;
 no_memory:
     virReportOOMError();
 error:
+    VIR_FREE(temp);
     virDomainFSDefFree(fs);
     return -1;
 }
@@ -439,7 +445,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
     char *status;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     virDomainObjPtr dom = NULL;
-    char temp[50];
+    char *temp = NULL;
     char *outbuf = NULL;
     char *line;
     virCommandPtr cmd = NULL;
@@ -506,7 +512,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
         if (!(dom->def->os.init = strdup("/sbin/init")))
             goto no_memory;
 
-        ret = openvzReadVPSConfigParam(veid, "CPUS", temp, sizeof(temp));
+        ret = openvzReadVPSConfigParam(veid, "CPUS", &temp);
         if (ret < 0) {
             openvzError(VIR_ERR_INTERNAL_ERROR,
                         _("Could not read config for container %d"),
@@ -534,6 +540,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
     }
 
     virCommandFree(cmd);
+    VIR_FREE(temp);
     VIR_FREE(outbuf);
 
     return 0;
@@ -543,6 +550,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
 
  cleanup:
     virCommandFree(cmd);
+    VIR_FREE(temp);
     VIR_FREE(outbuf);
     /* dom hasn't been shared yet, so unref should return 0 */
     if (dom)
@@ -565,25 +573,26 @@ static int
 openvzWriteConfigParam(const char * conf_file, const char *param, const char *value)
 {
     char * temp_file = NULL;
-    int fd = -1, temp_fd = -1;
-    char line[PATH_MAX];
+    int temp_fd = -1;
+    FILE *fp;
+    char *line = NULL;
+    size_t line_size = 0;
 
     if (virAsprintf(&temp_file, "%s.tmp", conf_file)<0) {
         virReportOOMError();
         return -1;
     }
 
-    fd = open(conf_file, O_RDONLY);
-    if (fd == -1)
+    fp = fopen(conf_file, "r");
+    if (fp == NULL)
         goto error;
     temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
     if (temp_fd == -1) {
-        VIR_FORCE_CLOSE(fd);
         goto error;
     }
 
     while (1) {
-        if (openvz_readline(fd, line, sizeof(line)) <= 0)
+        if (getline(&line, &line_size, fp) <= 0)
             break;
 
         if (!(STRPREFIX(line, param) && line[strlen(param)] == '=')) {
@@ -599,7 +608,7 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va
         safewrite(temp_fd, "\"\n", 2) < 0)
         goto error;
 
-    if (VIR_CLOSE(fd) < 0)
+    if (VIR_FCLOSE(fp) < 0)
         goto error;
     if (VIR_CLOSE(temp_fd) < 0)
         goto error;
@@ -607,10 +616,13 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va
     if (rename(temp_file, conf_file) < 0)
         goto error;
 
+    VIR_FREE(line);
+
     return 0;
 
 error:
-    VIR_FORCE_CLOSE(fd);
+    VIR_FREE(line);
+    VIR_FORCE_FCLOSE(fp);
     VIR_FORCE_CLOSE(temp_fd);
     if (temp_file)
         unlink(temp_file);
@@ -632,23 +644,29 @@ openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value)
     return ret;
 }
 
+/*
+ * value will be freed before a new value is assigned to it, the caller is
+ * responsible for freeing it afterwards.
+ */
 static int
-openvzReadConfigParam(const char * conf_file ,const char * param, char *value, int maxlen)
+openvzReadConfigParam(const char *conf_file, const char *param, char **value)
 {
-    char line[PATH_MAX];
-    int ret, found = 0;
-    int fd;
-    char * sf, * token;
+    char *line = NULL;
+    size_t line_size = 0;
+    ssize_t ret;
+    FILE *fp;
+    int found = 0;
+    char *sf, *token;
     char *saveptr = NULL;
 
     value[0] = 0;
 
-    fd = open(conf_file, O_RDONLY);
-    if (fd == -1)
+    fp = fopen(conf_file, "r");
+    if (fp == NULL)
         return -1;
 
     while (1) {
-        ret = openvz_readline(fd, line, sizeof(line));
+        ret = getline(&line, &line_size, fp);
         if (ret <= 0)
             break;
         saveptr = NULL;
@@ -658,7 +676,9 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i
             if (sf[0] == '=' && sf[1] != '\0' ) {
                 sf++;
                 if ((token = strtok_r(sf,"\"\t\n", &saveptr)) != NULL) {
-                    if (virStrcpy(value, token, maxlen) == NULL) {
+                    VIR_FREE(*value);
+                    *value = strdup(token);
+                    if (value == NULL) {
                         ret = -1;
                         break;
                     }
@@ -667,7 +687,8 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i
             }
        }
     }
-    VIR_FORCE_CLOSE(fd);
+    VIR_FREE(line);
+    VIR_FORCE_FCLOSE(fp);
 
     if (ret == 0 && found)
         ret = 1;
@@ -676,14 +697,18 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i
 }
 
 /*
-* Read parameter from container config
-* sample: 133, "OSTEMPLATE", value, 1024
-* return: -1 - error
-*	   0 - don't found
-*          1 - OK
-*/
+ * Read parameter from container config
+ *
+ * value will be freed before a new value is assined to it, the caller is
+ * responsible for freeing it afterwards.
+ *
+ * sample: 133, "OSTEMPLATE", &value
+ * return: -1 - error
+ *          0 - don't found
+ *          1 - OK
+ */
 int
-openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen)
+openvzReadVPSConfigParam(int vpsid, const char *param, char **value)
 {
     char *conf_file;
     int ret;
@@ -691,7 +716,7 @@ openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen)
     if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
         return -1;
 
-    ret = openvzReadConfigParam(conf_file, param, value, maxlen);
+    ret = openvzReadConfigParam(conf_file, param, value);
     VIR_FREE(conf_file);
     return ret;
 }
@@ -699,21 +724,23 @@ openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen)
 static int
 openvz_copyfile(char* from_path, char* to_path)
 {
-    char line[PATH_MAX];
-    int fd, copy_fd;
+    char *line = NULL;
+    size_t line_size = 0;
+    FILE *fp;
+    int copy_fd;
     int bytes_read;
 
-    fd = open(from_path, O_RDONLY);
-    if (fd == -1)
+    fp = fopen(from_path, "r");
+    if (fp == NULL)
         return -1;
     copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
     if (copy_fd == -1) {
-        VIR_FORCE_CLOSE(fd);
+        VIR_FORCE_FCLOSE(fp);
         return -1;
     }
 
     while (1) {
-        if (openvz_readline(fd, line, sizeof(line)) <= 0)
+        if (getline(&line, &line_size, fp) <= 0)
             break;
 
         bytes_read = strlen(line);
@@ -721,15 +748,18 @@ openvz_copyfile(char* from_path, char* to_path)
             goto error;
     }
 
-    if (VIR_CLOSE(fd) < 0)
+    if (VIR_FCLOSE(fp) < 0)
         goto error;
     if (VIR_CLOSE(copy_fd) < 0)
         goto error;
 
+    VIR_FREE(line);
+
     return 0;
 
 error:
-    VIR_FORCE_CLOSE(fd);
+    VIR_FREE(line);
+    VIR_FORCE_FCLOSE(fp);
     VIR_FORCE_CLOSE(copy_fd);
     return -1;
 }
@@ -742,14 +772,13 @@ error:
 int
 openvzCopyDefaultConfig(int vpsid)
 {
-    char * confdir = NULL;
-    char * default_conf_file = NULL;
-    char configfile_value[PATH_MAX];
+    char *confdir = NULL;
+    char *default_conf_file = NULL;
+    char *configfile_value = NULL;
     char *conf_file = NULL;
     int ret = -1;
 
-    if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", configfile_value,
-                              PATH_MAX) < 0)
+    if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", &configfile_value) < 0)
         goto cleanup;
 
     confdir = openvzLocateConfDir();
@@ -772,6 +801,7 @@ openvzCopyDefaultConfig(int vpsid)
 cleanup:
     VIR_FREE(confdir);
     VIR_FREE(default_conf_file);
+    VIR_FREE(configfile_value);
     VIR_FREE(conf_file);
     return ret;
 }
@@ -844,22 +874,24 @@ static int
 openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len)
 {
     char *conf_file;
-    char line[1024];
+    char *line = NULL;
+    size_t line_size = 0;
+    ssize_t ret;
     char *saveptr = NULL;
     char *uuidbuf;
     char *iden;
-    int fd, ret;
+    FILE *fp;
     int retval = -1;
 
     if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
         return -1;
 
-    fd = open(conf_file, O_RDONLY);
-    if (fd == -1)
+    fp = fopen(conf_file, "r");
+    if (fp == NULL)
         goto cleanup;
 
     while (1) {
-        ret = openvz_readline(fd, line, sizeof(line));
+        ret = getline(&line, &line_size, fp);
         if (ret == -1)
             goto cleanup;
 
@@ -882,7 +914,8 @@ openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len)
     }
     retval = 0;
 cleanup:
-    VIR_FORCE_CLOSE(fd);
+    VIR_FREE(line);
+    VIR_FORCE_FCLOSE(fp);
     VIR_FREE(conf_file);
 
     return retval;
diff --git a/src/openvz/openvz_conf.h b/src/openvz/openvz_conf.h
index 50bcb5e..4673fa6 100644
--- a/src/openvz/openvz_conf.h
+++ b/src/openvz/openvz_conf.h
@@ -55,7 +55,7 @@ struct openvz_driver {
 
 int openvz_readline(int fd, char *ptr, int maxlen);
 int openvzExtractVersion(struct openvz_driver *driver);
-int openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen);
+int openvzReadVPSConfigParam(int vpsid, const char *param, char **value);
 int openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value);
 int openvzCopyDefaultConfig(int vpsid);
 virCapsPtr openvzCapsInit(void);
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index fb30c37..c6fee3b 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -631,15 +631,16 @@ openvzGenerateVethName(int veid, char *dev_name_ve)
 static char *
 openvzGenerateContainerVethName(int veid)
 {
-    char    temp[1024];
+    char *temp = NULL;
+    char *name = NULL;
 
     /* try to get line "^NETIF=..." from config */
-    if (openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp)) <= 0) {
-        snprintf(temp, sizeof(temp), "eth0");
+    if (openvzReadVPSConfigParam(veid, "NETIF", &temp) <= 0) {
+        name = strdup("eth0");
     } else {
         char *saveptr;
-        char   *s;
-        int     max = 0;
+        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)) {
@@ -650,9 +651,16 @@ openvzGenerateContainerVethName(int veid)
         }
 
         /* set new name */
-        snprintf(temp, sizeof(temp), "eth%d", max+1);
+        virAsprintf(&name, "eth%d", max + 1);
     }
-    return strdup(temp);
+
+    VIR_FREE(temp);
+
+    if (name == NULL) {
+        virReportOOMError();
+    }
+
+    return name;
 }
 
 static int
@@ -1125,7 +1133,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
 {
     struct openvz_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    char value[1024];
+    char *value = NULL;
     int ret = -1;
 
     openvzDriverLock(driver);
@@ -1138,7 +1146,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
         goto cleanup;
     }
 
-    if (openvzReadVPSConfigParam(strtoI(vm->def->name), "ONBOOT", value, sizeof(value)) < 0) {
+    if (openvzReadVPSConfigParam(strtoI(vm->def->name), "ONBOOT", &value) < 0) {
         openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("Could not read container config"));
         goto cleanup;
@@ -1150,6 +1158,8 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
     ret = 0;
 
 cleanup:
+    VIR_FREE(value);
+
     if (vm)
         virDomainObjUnlock(vm);
     return ret;
@@ -1464,12 +1474,14 @@ out:
     return -1;
 }
 
-static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid) {
-    int fd;
-    char line[1024] ;
+static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid)
+{
+    FILE *fp;
+    char *line = NULL;
+    size_t line_size = 0;
     unsigned long long usertime, systime, nicetime;
     int readvps = vpsid + 1;  /* ensure readvps is initially different */
-    int ret;
+    ssize_t ret;
 
 /* read statistic from /proc/vz/vestat.
 sample:
@@ -1479,12 +1491,12 @@ Version: 2.2
      55      178         0       5340   59424597      542650441835148   other..
 */
 
-    if ((fd = open("/proc/vz/vestat", O_RDONLY)) == -1)
+    if ((fp = fopen("/proc/vz/vestat", "r")) == NULL)
         return -1;
 
     /*search line with VEID=vpsid*/
     while (1) {
-        ret = openvz_readline(fd, line, sizeof(line));
+        ret = getline(&line, &line_size, fp);
         if (ret <= 0)
             break;
 
@@ -1499,7 +1511,8 @@ Version: 2.2
         }
     }
 
-    VIR_FORCE_CLOSE(fd);
+    VIR_FREE(line);
+    VIR_FORCE_FCLOSE(fp);
     if (ret < 0)
         return -1;
 
-- 
1.7.0.4




More information about the libvir-list mailing list