From 74cc60697f825f6f9ade10a2a8d057bc60a89bb5 Mon Sep 17 00:00:00 2001 From: blekot Date: Tue, 17 Jan 2006 17:48:01 +0000 Subject: [PATCH] - from website to cvs Changed files: autofs-4.1.4-misc-fixes.patch -> 1.1 autofs-4.1.4-multi-parse-fix.patch -> 1.1 autofs-4.1.4-no-unlink-upstream.patch -> 1.1 autofs-4.1.4-non-replicated-ping.patch -> 1.1 --- autofs-4.1.4-misc-fixes.patch | 75 +++++++++ autofs-4.1.4-multi-parse-fix.patch | 53 ++++++ autofs-4.1.4-no-unlink-upstream.patch | 47 ++++++ autofs-4.1.4-non-replicated-ping.patch | 221 +++++++++++++++++++++++++ 4 files changed, 396 insertions(+) create mode 100644 autofs-4.1.4-misc-fixes.patch create mode 100644 autofs-4.1.4-multi-parse-fix.patch create mode 100644 autofs-4.1.4-no-unlink-upstream.patch create mode 100644 autofs-4.1.4-non-replicated-ping.patch diff --git a/autofs-4.1.4-misc-fixes.patch b/autofs-4.1.4-misc-fixes.patch new file mode 100644 index 0000000..fa61e2f --- /dev/null +++ b/autofs-4.1.4-misc-fixes.patch @@ -0,0 +1,75 @@ +diff -Nurp autofs-4.1.4.orig/lib/cache.c autofs-4.1.4/lib/cache.c +--- autofs-4.1.4.orig/lib/cache.c 2005-02-06 14:00:53.000000000 +0800 ++++ autofs-4.1.4/lib/cache.c 2005-05-07 17:29:21.000000000 +0800 +@@ -337,8 +337,10 @@ void cache_clean(const char *root, time_ + if (!path) + return; + +- if (is_mounted(_PATH_MOUNTED, path)) ++ if (is_mounted(_PATH_MOUNTED, path)) { ++ free(path); + continue; ++ } + + if (me->age < age) { + mapent_hash[i] = me->next; +diff -Nurp autofs-4.1.4.orig/modules/lookup_file.c autofs-4.1.4/modules/lookup_file.c +--- autofs-4.1.4.orig/modules/lookup_file.c 2005-04-06 23:14:23.000000000 +0800 ++++ autofs-4.1.4/modules/lookup_file.c 2005-05-07 17:27:30.000000000 +0800 +@@ -157,6 +157,10 @@ static int read_one(FILE *f, char *key, + break; + + case st_compare: ++ if (kptr - key > KEY_MAX_LEN) { ++ state = st_badent; ++ break; ++ } + if (ch == '\n') + state = st_begin; + else if (isspace(ch) && !escape) { +diff -Nurp autofs-4.1.4.orig/modules/parse_sun.c autofs-4.1.4/modules/parse_sun.c +--- autofs-4.1.4.orig/modules/parse_sun.c 2005-05-07 17:39:44.000000000 +0800 ++++ autofs-4.1.4/modules/parse_sun.c 2005-05-07 17:35:27.000000000 +0800 +@@ -680,6 +680,10 @@ static int sun_mount(const char *root, c + "mounting root %s, mountpoint %s, what %s, fstype %s, options %s\n", + root, mountpoint, what, fstype, options); + ++ /* A malformed entry of the form key /xyz will trigger this case */ ++ if (!what || *what == '\0') ++ return 1; ++ + if (!strcmp(fstype, "nfs")) { + rv = mount_nfs->mount_mount(root, mountpoint, strlen(mountpoint), + what, fstype, options, mount_nfs->context); +@@ -695,6 +699,18 @@ static int sun_mount(const char *root, c + return rv; + } + ++static int key_exists(struct multi_mnt *list, char *path, int pathlen) ++{ ++ struct multi_mnt *mmptr = list; ++ ++ while (mmptr && pathlen == strlen(mmptr->path)) { ++ if (!strncmp(mmptr->path, path, pathlen)) ++ return 1; ++ mmptr = mmptr->next; ++ } ++ return 0; ++} ++ + /* + * Build list of mounts in shortest -> longest order. + * Pass in list head and return list head. +@@ -725,6 +741,12 @@ struct multi_mnt *multi_add_list(struct + mmptr = mmptr->next; + } + ++ /* if a multimount entry has duplicate keys, it is invalid */ ++ if (key_exists(mmptr, path, plen)) { ++ free(new); ++ return NULL; ++ } ++ + if (old) + old->next = new; + new->next = mmptr; diff --git a/autofs-4.1.4-multi-parse-fix.patch b/autofs-4.1.4-multi-parse-fix.patch new file mode 100644 index 0000000..8faf7c4 --- /dev/null +++ b/autofs-4.1.4-multi-parse-fix.patch @@ -0,0 +1,53 @@ +diff -Nurp autofs-4.1.4.orig/modules/parse_sun.c autofs-4.1.4/modules/parse_sun.c +--- autofs-4.1.4.orig/modules/parse_sun.c 2005-04-05 20:42:42.000000000 +0800 ++++ autofs-4.1.4/modules/parse_sun.c 2005-04-25 10:00:13.000000000 +0800 +@@ -766,7 +766,16 @@ static int check_is_multi(const char *ma + { + const char *p = (char *) mapent; + int multi = 0; +- int first_chunk = 0; ++ int not_first_chunk = 0; ++ ++ if (!p) { ++ crit("check_is_multi: unexpected NULL map entry pointer"); ++ return 0; ++ } ++ ++ /* If first character is "/" it's a multi-mount */ ++ if (*p == '/') ++ return 1; + + while (*p) { + p = skipspace(p); +@@ -779,7 +788,7 @@ static int check_is_multi(const char *ma + * path that begins with '/' indicates a mutil-mount + * entry. + */ +- if (first_chunk) { ++ if (not_first_chunk) { + if (*p == '/' || *p == '-') { + multi = 1; + break; +@@ -796,7 +805,7 @@ static int check_is_multi(const char *ma + * after which it's a multi mount. + */ + p += chunklen(p, check_colon(p)); +- first_chunk++; ++ not_first_chunk++; + } + + return multi; +@@ -883,7 +892,12 @@ int parse_mount(const char *root, const + return 1; + } + +- path = dequote(p, l = chunklen(p, 0)); ++ if (*p != '/') { ++ l = 0; ++ path = dequote("/", 1); ++ } else ++ path = dequote(p, l = chunklen(p, 0)); ++ + if (!path) { + error(MODPREFIX "out of memory"); + free(myoptions); diff --git a/autofs-4.1.4-no-unlink-upstream.patch b/autofs-4.1.4-no-unlink-upstream.patch new file mode 100644 index 0000000..b92b241 --- /dev/null +++ b/autofs-4.1.4-no-unlink-upstream.patch @@ -0,0 +1,47 @@ +--- autofs-4.1.4/daemon/automount.c.no-unlink 2005-07-11 13:28:57.000000000 -0500 ++++ autofs-4.1.4/daemon/automount.c 2005-07-11 13:50:46.000000000 -0500 +@@ -216,16 +216,38 @@ static int walk_tree(const char *base, i + static int rm_unwanted_fn(const char *file, const struct stat *st, int when, void *arg) + { + int rmsymlink = *(int *) arg; ++ struct stat newst; + + if (when == 0) { + if (st->st_dev != ap.dev) + return 0; +- } else { +- info("rm_unwanted: %s\n", file); +- if (S_ISDIR(st->st_mode)) +- rmdir(file); +- else if (!S_ISLNK(st->st_mode) || rmsymlink) +- unlink(file); ++ return 1; ++ } ++ ++ if (lstat(file, &newst)) { ++ crit ("rm_unwanted: unable to stat file, possible race " ++ "condition."); ++ return 0; ++ } ++ ++ if (newst.st_dev != ap.dev) { ++ crit ("rm_unwanted: file %s has the wrong device, possible " ++ "race condition.",file); ++ return 0; ++ } ++ ++ if (S_ISDIR(newst.st_mode)) { ++ if (rmdir(file)) { ++ info ("rm_unwanted: unable to remove directory" ++ " %s", file); ++ return 0; ++ } ++ } else if (S_ISREG(newst.st_mode)) { ++ crit ("rm_unwanted: attempting to remove files from a mounted " ++ "directory."); ++ return 0; ++ } else if (S_ISLNK(newst.st_mode) && rmsymlink) { ++ unlink(file); + } + + return 1; diff --git a/autofs-4.1.4-non-replicated-ping.patch b/autofs-4.1.4-non-replicated-ping.patch new file mode 100644 index 0000000..00b6e23 --- /dev/null +++ b/autofs-4.1.4-non-replicated-ping.patch @@ -0,0 +1,221 @@ +diff -Nurp autofs-4.1.4.orig/modules/mount_nfs.c autofs-4.1.4/modules/mount_nfs.c +--- autofs-4.1.4.orig/modules/mount_nfs.c 2005-04-25 10:55:27.000000000 +0800 ++++ autofs-4.1.4/modules/mount_nfs.c 2005-04-25 10:56:15.000000000 +0800 +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #define MODULE_MOUNT + #include "automount.h" +@@ -105,28 +106,117 @@ int is_local_addr(const char *host, cons + + return 1; + } ++ ++/* ++ * If the entry doesn't contain a ',' or doesn't contain more than ++ * one ':' then @what is not a replicated server entry. ++ */ ++static int inline is_replicated_entry(char *what) ++{ ++ return strchr(what, ',') || ++ (strchr(what, ':') != strrchr(what, ':')); ++} ++ ++/* ++ * Check to see if the 'host:path' or 'host' is on the local machine ++ * Returns < 0 if there is a host lookup problem, otherwise returns 0 ++ * if it's not a local mount, and returns > 0 if it is a local mount. ++ */ ++int is_local_mount(const char *hostpath) ++{ ++ struct hostent *he; ++ char **haddr; ++ char *delim; ++ char *hostname; ++ int hostnamelen; ++ int local = 0; ++ ++ debug(MODPREFIX "is_local_mount: %s", hostpath); ++ delim = strpbrk(hostpath,":"); ++ ++ if (delim) ++ hostnamelen = delim - hostpath; ++ else ++ hostnamelen = strlen(hostpath); ++ ++ hostname = malloc(hostnamelen+1); ++ strncpy(hostname, hostpath, hostnamelen); ++ hostname[hostnamelen] = '\0'; ++ he = gethostbyname(hostname); ++ if (!he) { ++ error(MODPREFIX "host %s: lookup failure", hostname); ++ return -1; ++ } ++ ++ for (haddr = he->h_addr_list; *haddr; haddr++) { ++ local = is_local_addr(hostname, *haddr, he->h_length); ++ if (local < 0) ++ return local; ++ if (local) { ++ debug(MODPREFIX "host %s: is localhost", ++ hostname); ++ return local; ++ } ++ } ++ return 0; ++} ++ + /* + * Given a mount string, return (in the same string) the +- * best mount to use based on weight/locality/rpctime ++ * best mount to use based on locality/weight/rpctime. ++ * ++ * If longtimeout is set to 0 then we only do 100 ms pings to hosts. In ++ * the event that this fails, we call ourself recursively with the ++ * longtimeout option set to 1. In this case we ping for up to 10s and ++ * skip logic for detecting if a localhost has been passed. (if a local ++ * host had been passed, we would have returned that mount as the best ++ * mount. The skipping of local maps in this case is an optimization). ++ * + * - return -1 and what = '\0' on error, + * 1 and what = local mount path if local bind, + * else 0 and what = remote mount path + */ +-int get_best_mount(char *what, const char *original, int longtimeout, int skiplocal) ++int get_best_mount(char *what, const char *original, int longtimeout) + { + char *p = what; + char *winner = NULL; + int winner_weight = INT_MAX, local = 0; + double winner_time = 0; +- char *delim; ++ char *delim, *pstrip; + int sec = (longtimeout) ? 10 : 0; + int micros = (longtimeout) ? 0 : 100000; ++ int skiplocal = longtimeout; /* clearly local is not available */ + + if (!p) { + *what = '\0'; + return -1; + } + ++ /* ++ * If only one mountpoint has been passed in, we don't need to ++ * do anything except strip whitespace from the end of the string. ++ */ ++ if (!is_replicated_entry(p)) { ++ for (pstrip = p+strlen(p) - 1; pstrip >= p; pstrip--) ++ if (isspace(*pstrip)) ++ *pstrip = '\0'; ++ ++ /* Check if the host is the localhost */ ++ if (is_local_mount(p) > 0) { ++ debug(MODPREFIX "host %s: is localhost", p); ++ ++ /* Strip off hostname and ':' */ ++ delim = strchr(p,':'); ++ while (delim && *delim != '\0') { ++ delim++; ++ *what = *delim; ++ what++; ++ } ++ return 1; ++ } ++ return 0; ++ } ++ + while (p && *p) { + char *next; + unsigned int ping_stat = 0; +@@ -171,37 +261,17 @@ int get_best_mount(char *what, const cha + /* p points to a server, "next is our next parse point */ + if (!skiplocal) { + /* Check if it's localhost */ +- struct hostent *he; +- char **haddr; +- +- he = gethostbyname(p); +- if (!he) { +- error(MODPREFIX "host %s: lookup failure", p); +- p = next; +- continue; +- } +- +- /* Check each host in round robin list */ +- for (haddr = he->h_addr_list; *haddr; haddr++) { +- local = is_local_addr(p, *haddr, he->h_length); +- +- if (local < 0) +- continue; +- +- if (local) { +- winner = p; +- break; +- } +- } +- ++ local = is_local_mount(p); + if (local < 0) { + local = 0; + p = next; + continue; + } + +- if (local) ++ if (local) { ++ winner = p; + break; ++ } + } + + /* ping each (or the) entry to see if it's alive. */ +@@ -214,6 +284,7 @@ int get_best_mount(char *what, const cha + /* First unweighted or only host is alive so set winner */ + if (!winner) { + winner = p; ++ winner_time = 1; + /* No more to check, return it */ + if (!next || !*next) + break; +@@ -256,7 +327,7 @@ int get_best_mount(char *what, const cha + */ + if (!local && winner_weight == INT_MAX) { + /* We had more than one contender and none responded in time */ +- if (winner_time != 0 && winner_time > 500) { ++ if (winner_time == 0 || winner_time > 500) { + /* We've already tried a longer timeout */ + if (!longtimeout) { + /* Reset string and try again */ +@@ -267,16 +338,14 @@ int get_best_mount(char *what, const cha + "retrying with longer timeout", + original); + +- return get_best_mount(what, original, 1, 1); ++ return get_best_mount(what, original, 1); + } + } + } + +- /* No winner found so bail */ +- if (!winner) { +- *what = '\0'; +- return 0; +- } ++ /* No winner found so return first */ ++ if (!winner) ++ winner = what; + + /* + * We now have our winner, copy it to the front of the string, +@@ -395,7 +464,7 @@ int mount_mount(const char *root, const + /* No colon, take this as a bind (local) entry */ + local = 1; + } else if (!nosymlink) { +- local = get_best_mount(whatstr, what, 0, 0); ++ local = get_best_mount(whatstr, what, 0); + if (!*whatstr) { + warn(MODPREFIX "no host elected"); + return 1; -- 2.44.0