openvz: Remove several larger stack allocations

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.
This commit is contained in:
Matthias Bolte 2011-04-03 11:21:26 +02:00
parent 76f0ae3261
commit f044376530
3 changed files with 117 additions and 71 deletions

View File

@ -187,7 +187,7 @@ openvzReadNetworkConf(virDomainDefPtr def,
int veid) { int veid) {
int ret; int ret;
virDomainNetDefPtr net = NULL; virDomainNetDefPtr net = NULL;
char temp[4096]; char *temp = NULL;
char *token, *saveptr = NULL; char *token, *saveptr = NULL;
/*parse routing network configuration* /*parse routing network configuration*
@ -195,7 +195,7 @@ openvzReadNetworkConf(virDomainDefPtr def,
* IP_ADDRESS="1.1.1.1 1.1.1.2" * IP_ADDRESS="1.1.1.1 1.1.1.2"
* splited IPs by space * splited IPs by space
*/ */
ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", temp, sizeof(temp)); ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", &temp);
if (ret < 0) { if (ret < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, openvzError(VIR_ERR_INTERNAL_ERROR,
_("Could not read 'IP_ADDRESS' from config for container %d"), _("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" *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 ';' *devices splited by ';'
*/ */
ret = openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp)); ret = openvzReadVPSConfigParam(veid, "NETIF", &temp);
if (ret < 0) { if (ret < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, openvzError(VIR_ERR_INTERNAL_ERROR,
_("Could not read 'NETIF' from config for container %d"), _("Could not read 'NETIF' from config for container %d"),
@ -316,10 +316,13 @@ openvzReadNetworkConf(virDomainDefPtr def,
} }
} }
VIR_FREE(temp);
return 0; return 0;
no_memory: no_memory:
virReportOOMError(); virReportOOMError();
error: error:
VIR_FREE(temp);
virDomainNetDefFree(net); virDomainNetDefFree(net);
return -1; return -1;
} }
@ -365,9 +368,9 @@ openvzReadFSConf(virDomainDefPtr def,
int ret; int ret;
virDomainFSDefPtr fs = NULL; virDomainFSDefPtr fs = NULL;
char *veid_str = NULL; char *veid_str = NULL;
char temp[100]; char *temp = NULL;
ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", temp, sizeof(temp)); ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp);
if (ret < 0) { if (ret < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, openvzError(VIR_ERR_INTERNAL_ERROR,
_("Could not read 'OSTEMPLATE' from config for container %d"), _("Could not read 'OSTEMPLATE' from config for container %d"),
@ -381,7 +384,7 @@ openvzReadFSConf(virDomainDefPtr def,
fs->src = strdup(temp); fs->src = strdup(temp);
} else { } else {
/* OSTEMPLATE was not found, VE was booted from a private dir directly */ /* 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) { if (ret <= 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, openvzError(VIR_ERR_INTERNAL_ERROR,
_("Could not read 'VE_PRIVATE' from config for container %d"), _("Could not read 'VE_PRIVATE' from config for container %d"),
@ -411,10 +414,13 @@ openvzReadFSConf(virDomainDefPtr def,
def->fss[def->nfss++] = fs; def->fss[def->nfss++] = fs;
fs = NULL; fs = NULL;
VIR_FREE(temp);
return 0; return 0;
no_memory: no_memory:
virReportOOMError(); virReportOOMError();
error: error:
VIR_FREE(temp);
virDomainFSDefFree(fs); virDomainFSDefFree(fs);
return -1; return -1;
} }
@ -439,7 +445,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
char *status; char *status;
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
virDomainObjPtr dom = NULL; virDomainObjPtr dom = NULL;
char temp[50]; char *temp = NULL;
char *outbuf = NULL; char *outbuf = NULL;
char *line; char *line;
virCommandPtr cmd = NULL; virCommandPtr cmd = NULL;
@ -506,7 +512,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
if (!(dom->def->os.init = strdup("/sbin/init"))) if (!(dom->def->os.init = strdup("/sbin/init")))
goto no_memory; goto no_memory;
ret = openvzReadVPSConfigParam(veid, "CPUS", temp, sizeof(temp)); ret = openvzReadVPSConfigParam(veid, "CPUS", &temp);
if (ret < 0) { if (ret < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, openvzError(VIR_ERR_INTERNAL_ERROR,
_("Could not read config for container %d"), _("Could not read config for container %d"),
@ -534,6 +540,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
} }
virCommandFree(cmd); virCommandFree(cmd);
VIR_FREE(temp);
VIR_FREE(outbuf); VIR_FREE(outbuf);
return 0; return 0;
@ -543,6 +550,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
cleanup: cleanup:
virCommandFree(cmd); virCommandFree(cmd);
VIR_FREE(temp);
VIR_FREE(outbuf); VIR_FREE(outbuf);
/* dom hasn't been shared yet, so unref should return 0 */ /* dom hasn't been shared yet, so unref should return 0 */
if (dom) if (dom)
@ -565,25 +573,26 @@ static int
openvzWriteConfigParam(const char * conf_file, const char *param, const char *value) openvzWriteConfigParam(const char * conf_file, const char *param, const char *value)
{ {
char * temp_file = NULL; char * temp_file = NULL;
int fd = -1, temp_fd = -1; int temp_fd = -1;
char line[PATH_MAX]; FILE *fp;
char *line = NULL;
size_t line_size = 0;
if (virAsprintf(&temp_file, "%s.tmp", conf_file)<0) { if (virAsprintf(&temp_file, "%s.tmp", conf_file)<0) {
virReportOOMError(); virReportOOMError();
return -1; return -1;
} }
fd = open(conf_file, O_RDONLY); fp = fopen(conf_file, "r");
if (fd == -1) if (fp == NULL)
goto error; goto error;
temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (temp_fd == -1) { if (temp_fd == -1) {
VIR_FORCE_CLOSE(fd);
goto error; goto error;
} }
while (1) { while (1) {
if (openvz_readline(fd, line, sizeof(line)) <= 0) if (getline(&line, &line_size, fp) <= 0)
break; break;
if (!(STRPREFIX(line, param) && line[strlen(param)] == '=')) { 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) safewrite(temp_fd, "\"\n", 2) < 0)
goto error; goto error;
if (VIR_CLOSE(fd) < 0) if (VIR_FCLOSE(fp) < 0)
goto error; goto error;
if (VIR_CLOSE(temp_fd) < 0) if (VIR_CLOSE(temp_fd) < 0)
goto error; goto error;
@ -607,10 +616,13 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va
if (rename(temp_file, conf_file) < 0) if (rename(temp_file, conf_file) < 0)
goto error; goto error;
VIR_FREE(line);
return 0; return 0;
error: error:
VIR_FORCE_CLOSE(fd); VIR_FREE(line);
VIR_FORCE_FCLOSE(fp);
VIR_FORCE_CLOSE(temp_fd); VIR_FORCE_CLOSE(temp_fd);
if (temp_file) if (temp_file)
unlink(temp_file); unlink(temp_file);
@ -632,23 +644,29 @@ openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value)
return ret; return ret;
} }
/*
* value will be freed before a new value is assigned to it, the caller is
* responsible for freeing it afterwards.
*/
static int 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]; char *line = NULL;
int ret, found = 0; size_t line_size = 0;
int fd; ssize_t ret;
FILE *fp;
int found = 0;
char *sf, *token; char *sf, *token;
char *saveptr = NULL; char *saveptr = NULL;
value[0] = 0; value[0] = 0;
fd = open(conf_file, O_RDONLY); fp = fopen(conf_file, "r");
if (fd == -1) if (fp == NULL)
return -1; return -1;
while (1) { while (1) {
ret = openvz_readline(fd, line, sizeof(line)); ret = getline(&line, &line_size, fp);
if (ret <= 0) if (ret <= 0)
break; break;
saveptr = NULL; saveptr = NULL;
@ -658,7 +676,9 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i
if (sf[0] == '=' && sf[1] != '\0' ) { if (sf[0] == '=' && sf[1] != '\0' ) {
sf++; sf++;
if ((token = strtok_r(sf,"\"\t\n", &saveptr)) != NULL) { 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; ret = -1;
break; 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) if (ret == 0 && found)
ret = 1; ret = 1;
@ -677,13 +698,17 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i
/* /*
* Read parameter from container config * Read parameter from container config
* sample: 133, "OSTEMPLATE", value, 1024 *
* 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 * return: -1 - error
* 0 - don't found * 0 - don't found
* 1 - OK * 1 - OK
*/ */
int int
openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen) openvzReadVPSConfigParam(int vpsid, const char *param, char **value)
{ {
char *conf_file; char *conf_file;
int ret; int ret;
@ -691,7 +716,7 @@ openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen)
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0) if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
return -1; return -1;
ret = openvzReadConfigParam(conf_file, param, value, maxlen); ret = openvzReadConfigParam(conf_file, param, value);
VIR_FREE(conf_file); VIR_FREE(conf_file);
return ret; return ret;
} }
@ -699,21 +724,23 @@ openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen)
static int static int
openvz_copyfile(char* from_path, char* to_path) openvz_copyfile(char* from_path, char* to_path)
{ {
char line[PATH_MAX]; char *line = NULL;
int fd, copy_fd; size_t line_size = 0;
FILE *fp;
int copy_fd;
int bytes_read; int bytes_read;
fd = open(from_path, O_RDONLY); fp = fopen(from_path, "r");
if (fd == -1) if (fp == NULL)
return -1; return -1;
copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (copy_fd == -1) { if (copy_fd == -1) {
VIR_FORCE_CLOSE(fd); VIR_FORCE_FCLOSE(fp);
return -1; return -1;
} }
while (1) { while (1) {
if (openvz_readline(fd, line, sizeof(line)) <= 0) if (getline(&line, &line_size, fp) <= 0)
break; break;
bytes_read = strlen(line); bytes_read = strlen(line);
@ -721,15 +748,18 @@ openvz_copyfile(char* from_path, char* to_path)
goto error; goto error;
} }
if (VIR_CLOSE(fd) < 0) if (VIR_FCLOSE(fp) < 0)
goto error; goto error;
if (VIR_CLOSE(copy_fd) < 0) if (VIR_CLOSE(copy_fd) < 0)
goto error; goto error;
VIR_FREE(line);
return 0; return 0;
error: error:
VIR_FORCE_CLOSE(fd); VIR_FREE(line);
VIR_FORCE_FCLOSE(fp);
VIR_FORCE_CLOSE(copy_fd); VIR_FORCE_CLOSE(copy_fd);
return -1; return -1;
} }
@ -744,12 +774,11 @@ openvzCopyDefaultConfig(int vpsid)
{ {
char *confdir = NULL; char *confdir = NULL;
char *default_conf_file = NULL; char *default_conf_file = NULL;
char configfile_value[PATH_MAX]; char *configfile_value = NULL;
char *conf_file = NULL; char *conf_file = NULL;
int ret = -1; int ret = -1;
if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", configfile_value, if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", &configfile_value) < 0)
PATH_MAX) < 0)
goto cleanup; goto cleanup;
confdir = openvzLocateConfDir(); confdir = openvzLocateConfDir();
@ -772,6 +801,7 @@ openvzCopyDefaultConfig(int vpsid)
cleanup: cleanup:
VIR_FREE(confdir); VIR_FREE(confdir);
VIR_FREE(default_conf_file); VIR_FREE(default_conf_file);
VIR_FREE(configfile_value);
VIR_FREE(conf_file); VIR_FREE(conf_file);
return ret; return ret;
} }
@ -844,22 +874,24 @@ static int
openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len) openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len)
{ {
char *conf_file; char *conf_file;
char line[1024]; char *line = NULL;
size_t line_size = 0;
ssize_t ret;
char *saveptr = NULL; char *saveptr = NULL;
char *uuidbuf; char *uuidbuf;
char *iden; char *iden;
int fd, ret; FILE *fp;
int retval = -1; int retval = -1;
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0) if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
return -1; return -1;
fd = open(conf_file, O_RDONLY); fp = fopen(conf_file, "r");
if (fd == -1) if (fp == NULL)
goto cleanup; goto cleanup;
while (1) { while (1) {
ret = openvz_readline(fd, line, sizeof(line)); ret = getline(&line, &line_size, fp);
if (ret == -1) if (ret == -1)
goto cleanup; goto cleanup;
@ -882,7 +914,8 @@ openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len)
} }
retval = 0; retval = 0;
cleanup: cleanup:
VIR_FORCE_CLOSE(fd); VIR_FREE(line);
VIR_FORCE_FCLOSE(fp);
VIR_FREE(conf_file); VIR_FREE(conf_file);
return retval; return retval;

View File

@ -55,7 +55,7 @@ struct openvz_driver {
int openvz_readline(int fd, char *ptr, int maxlen); int openvz_readline(int fd, char *ptr, int maxlen);
int openvzExtractVersion(struct openvz_driver *driver); 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 openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value);
int openvzCopyDefaultConfig(int vpsid); int openvzCopyDefaultConfig(int vpsid);
virCapsPtr openvzCapsInit(void); virCapsPtr openvzCapsInit(void);

View File

@ -631,11 +631,12 @@ openvzGenerateVethName(int veid, char *dev_name_ve)
static char * static char *
openvzGenerateContainerVethName(int veid) openvzGenerateContainerVethName(int veid)
{ {
char temp[1024]; char *temp = NULL;
char *name = NULL;
/* try to get line "^NETIF=..." from config */ /* try to get line "^NETIF=..." from config */
if (openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp)) <= 0) { if (openvzReadVPSConfigParam(veid, "NETIF", &temp) <= 0) {
snprintf(temp, sizeof(temp), "eth0"); name = strdup("eth0");
} else { } else {
char *saveptr; char *saveptr;
char *s; char *s;
@ -650,9 +651,16 @@ openvzGenerateContainerVethName(int veid)
} }
/* set new name */ /* 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 static int
@ -1125,7 +1133,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
{ {
struct openvz_driver *driver = dom->conn->privateData; struct openvz_driver *driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
char value[1024]; char *value = NULL;
int ret = -1; int ret = -1;
openvzDriverLock(driver); openvzDriverLock(driver);
@ -1138,7 +1146,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
goto cleanup; 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", openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not read container config")); _("Could not read container config"));
goto cleanup; goto cleanup;
@ -1150,6 +1158,8 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(value);
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
return ret; return ret;
@ -1464,12 +1474,14 @@ out:
return -1; return -1;
} }
static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid) { static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid)
int fd; {
char line[1024] ; FILE *fp;
char *line = NULL;
size_t line_size = 0;
unsigned long long usertime, systime, nicetime; unsigned long long usertime, systime, nicetime;
int readvps = vpsid + 1; /* ensure readvps is initially different */ int readvps = vpsid + 1; /* ensure readvps is initially different */
int ret; ssize_t ret;
/* read statistic from /proc/vz/vestat. /* read statistic from /proc/vz/vestat.
sample: sample:
@ -1479,12 +1491,12 @@ Version: 2.2
55 178 0 5340 59424597 542650441835148 other.. 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; return -1;
/*search line with VEID=vpsid*/ /*search line with VEID=vpsid*/
while (1) { while (1) {
ret = openvz_readline(fd, line, sizeof(line)); ret = getline(&line, &line_size, fp);
if (ret <= 0) if (ret <= 0)
break; break;
@ -1499,7 +1511,8 @@ Version: 2.2
} }
} }
VIR_FORCE_CLOSE(fd); VIR_FREE(line);
VIR_FORCE_FCLOSE(fp);
if (ret < 0) if (ret < 0)
return -1; return -1;