113 lines
3.0 KiB
Diff
113 lines
3.0 KiB
Diff
|
autofs-5.1.7 - dont use realloc in host exports list processing
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
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 <raven@themaw.net>
|
||
|
---
|
||
|
CHANGELOG | 1 +
|
||
|
modules/lookup_hosts.c | 59 +++++++++++++++++++++---------------------------
|
||
|
2 files changed, 27 insertions(+), 33 deletions(-)
|
||
|
|
||
|
diff --git a/CHANGELOG b/CHANGELOG
|
||
|
index 19af245e..1bd6ac7f 100644
|
||
|
--- a/CHANGELOG
|
||
|
+++ b/CHANGELOG
|
||
|
@@ -1,6 +1,7 @@
|
||
|
|
||
|
- add xdr_exports().
|
||
|
- remove mount.x and rpcgen dependencies.
|
||
|
+- dont use realloc in host exports list processing.
|
||
|
|
||
|
25/01/2021 autofs-5.1.7
|
||
|
- make bind mounts propagation slave by default.
|
||
|
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
||
|
index 81a4eb18..e3ee0ab8 100644
|
||
|
--- a/modules/lookup_hosts.c
|
||
|
+++ b/modules/lookup_hosts.c
|
||
|
@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
||
|
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;
|
||
|
-
|
||
|
- 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_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
|
||
|
+ this = this->next;
|
||
|
+ }
|
||
|
+
|
||
|
+ 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_point *ap, const char *host)
|
||
|
}
|
||
|
rpc_exports_free(exp);
|
||
|
|
||
|
- if (!mapent)
|
||
|
- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
|
||
|
-
|
||
|
return mapent;
|
||
|
}
|
||
|
|