autofs-5.1.7 - dont use realloc in host exports list processing From: Ian Kent If a server exports list is very large calling realloc(3) for each export is slow. It's better to traverse the exports list twice, once to calculate the length of the mapent then allocate the memory and traverse the exports list again to construct the mapent. Signed-off-by: Ian Kent --- CHANGELOG | 1 + modules/lookup_hosts.c | 59 +++++++++++++++++++++--------------------------- 2 files changed, 27 insertions(+), 33 deletions(-) --- autofs-5.1.4.orig/CHANGELOG +++ autofs-5.1.4/CHANGELOG @@ -1,6 +1,7 @@ - add xdr_exports(). - remove mount.x and rpcgen dependencies. +- dont use realloc in host exports list processing. xx/xx/2018 autofs-5.1.5 - fix flag file permission. --- autofs-5.1.4.orig/modules/lookup_hosts.c +++ autofs-5.1.4/modules/lookup_hosts.c @@ -89,44 +89,40 @@ static char *get_exports(struct autofs_p char buf[MAX_ERR_BUF]; char *mapent; struct exportinfo *exp, *this; + size_t hostlen = strlen(host); + size_t mapent_len; debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER); - mapent = NULL; this = exp; + mapent_len = 0; while (this) { - if (mapent) { - int len = strlen(mapent) + 1; + mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; + this = this->next; + } - len += strlen(host) + 2*(strlen(this->dir) + 2) + 3; - mapent = realloc(mapent, len); - if (!mapent) { - char *estr; - estr = strerror_r(errno, buf, MAX_ERR_BUF); - error(ap->logopt, MODPREFIX "malloc: %s", estr); - rpc_exports_free(exp); - return NULL; - } - strcat(mapent, " \""); - strcat(mapent, this->dir); - strcat(mapent, "\""); - } else { - int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3; - - mapent = malloc(len); - if (!mapent) { - char *estr; - estr = strerror_r(errno, buf, MAX_ERR_BUF); - error(ap->logopt, MODPREFIX "malloc: %s", estr); - rpc_exports_free(exp); - return NULL; - } + mapent = malloc(mapent_len + 1); + if (!mapent) { + char *estr; + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, MODPREFIX "malloc: %s", estr); + error(ap->logopt, MODPREFIX "exports lookup failed for %s", host); + rpc_exports_free(exp); + return NULL; + } + *mapent = 0; + + this = exp; + while (this) { + if (!*mapent) strcpy(mapent, "\""); - strcat(mapent, this->dir); - strcat(mapent, "\""); - } + else + strcat(mapent, " \""); + strcat(mapent, this->dir); + strcat(mapent, "\""); + strcat(mapent, " \""); strcat(mapent, host); strcat(mapent, ":"); @@ -137,9 +133,6 @@ static char *get_exports(struct autofs_p } rpc_exports_free(exp); - if (!mapent) - error(ap->logopt, MODPREFIX "exports lookup failed for %s", host); - return mapent; }