diff --git a/autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch b/autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch new file mode 100644 index 0000000..f5015f9 --- /dev/null +++ b/autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch @@ -0,0 +1,50 @@ +autofs-5.0.5 - add lsb force-reload and try-restart + +From: Ian Kent + +LSB specifies two additional init script options, force-reload and +try-restart. The force-reload option is supposed to do what restart +does and does that. The try-restart option is essentially condrestart +and is another option for that action. This change is made only to +RedHat init script. +--- + + redhat/autofs.init.in | 10 +++------- + 1 files changed, 3 insertions(+), 7 deletions(-) + + +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index 05ab145..4a915ec 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -173,7 +173,7 @@ case "$1" in + status) + status -p /var/run/autofs.pid -l autofs $prog + ;; +- restart) ++ restart|force-reload) + restart + ;; + forcerestart) +@@ -183,19 +183,15 @@ case "$1" in + reload) + reload + ;; +- condrestart) ++ condrestart|try-restart) + if [ -f /var/lock/subsys/autofs ]; then + restart + fi + ;; + usage) +- echo $"Usage: $0 {start|forcestart|stop|status|restart|forcerestart|reload|condrestart}" ++ echo $"Usage: $0 {start|forcestart|stop|status|restart|force-reload|forcerestart|reload|condrestart|try-restart}" + exit 0 + ;; +- try-restart|force-reload) +- echo "$1 service action not supported" +- exit 3 +- ;; + *) + echo "unknown, invalid or excess argument(s)" + exit 2 diff --git a/autofs-5.0.5-auto-adjust-ldap-page-size.patch b/autofs-5.0.5-auto-adjust-ldap-page-size.patch new file mode 100644 index 0000000..fd4ee9b --- /dev/null +++ b/autofs-5.0.5-auto-adjust-ldap-page-size.patch @@ -0,0 +1,113 @@ +autofs-5.0.5 - auto adjust ldap page size + +From: Ian Kent + +When doing a paged LDAP request, if an LDAP server is configured with +request size limits less than the size autofs requests the query fails +with an LDAP_ADMINLIMIT_EXCEEDED. To fix this, when the error is returned +halve the request size and try again until we get down to a ridiculously +small size. +--- + + CHANGELOG | 1 + + modules/lookup_ldap.c | 32 ++++++++++++++++++++++++-------- + 2 files changed, 25 insertions(+), 8 deletions(-) + + +--- autofs-5.0.5.orig/CHANGELOG ++++ autofs-5.0.5/CHANGELOG +@@ -56,6 +56,7 @@ + - add option to dump configured automount maps. + - use weight only for server selection. + - fix isspace() wild card substition. ++- auto adjust ldap page size. + + 03/09/2009 autofs-5.0.5 + ----------------------- +--- autofs-5.0.5.orig/modules/lookup_ldap.c ++++ autofs-5.0.5/modules/lookup_ldap.c +@@ -55,6 +55,7 @@ struct ldap_search_params { + LDAP *ldap; + char *query, **attrs; + struct berval *cookie; ++ ber_int_t pageSize; + int morePages; + ber_int_t totalCount; + LDAPMessage *result; +@@ -1946,7 +1947,6 @@ static int do_paged_query(struct ldap_se + struct autofs_point *ap = sp->ap; + LDAPControl *pageControl=NULL, *controls[2] = { NULL, NULL }; + LDAPControl **returnedControls = NULL; +- static ber_int_t pageSize = 1000; + static char pagingCriticality = 'T'; + int rv, scope = LDAP_SCOPE_SUBTREE; + +@@ -1959,7 +1959,8 @@ static int do_paged_query(struct ldap_se + * Check for Size Limit exceeded and force run through loop + * and requery using page control. + */ +- if (rv == LDAP_SIZELIMIT_EXCEEDED) ++ if (rv == LDAP_SIZELIMIT_EXCEEDED || ++ rv == LDAP_ADMINLIMIT_EXCEEDED) + sp->morePages = TRUE; + else { + debug(ap->logopt, +@@ -1974,7 +1975,7 @@ do_paged: + /* we need to use page controls so requery LDAP */ + debug(ap->logopt, MODPREFIX "geting page of results"); + +- rv = ldap_create_page_control(sp->ldap, pageSize, sp->cookie, ++ rv = ldap_create_page_control(sp->ldap, sp->pageSize, sp->cookie, + pagingCriticality, &pageControl); + if (rv != LDAP_SUCCESS) { + warn(ap->logopt, MODPREFIX "failed to create page control"); +@@ -1989,10 +1990,11 @@ do_paged: + ctxt->qdn, scope, sp->query, sp->attrs, + 0, controls, NULL, NULL, 0, &sp->result); + if ((rv != LDAP_SUCCESS) && (rv != LDAP_PARTIAL_RESULTS)) { +- debug(ap->logopt, +- MODPREFIX "query failed for %s: %s", +- sp->query, ldap_err2string(rv)); + ldap_control_free(pageControl); ++ if (rv != LDAP_ADMINLIMIT_EXCEEDED) ++ debug(ap->logopt, ++ MODPREFIX "query failed for %s: %s", ++ sp->query, ldap_err2string(rv)); + return rv; + } + +@@ -2347,18 +2349,32 @@ static int read_one_map(struct autofs_po + MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, ctxt->qdn); + + sp.cookie = NULL; ++ sp.pageSize = 1000; + sp.morePages = FALSE; + sp.totalCount = 0; + sp.result = NULL; + + do { + rv = do_paged_query(&sp, ctxt); +- if (rv == LDAP_SIZELIMIT_EXCEEDED) +- { ++ if (rv == LDAP_SIZELIMIT_EXCEEDED) { + debug(ap->logopt, MODPREFIX "result size exceed"); + if (sp.result) + ldap_msgfree(sp.result); ++ continue; ++ } + ++ if (rv == LDAP_ADMINLIMIT_EXCEEDED) { ++ if (sp.result) ++ ldap_msgfree(sp.result); ++ sp.pageSize = sp.pageSize / 2; ++ if (sp.pageSize < 5) { ++ debug(ap->logopt, MODPREFIX ++ "administrative result size too small"); ++ unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ *result_ldap = rv; ++ free(sp.query); ++ return NSS_STATUS_UNAVAIL; ++ } + continue; + } + diff --git a/autofs-5.0.5-fix-expire-race.patch b/autofs-5.0.5-fix-expire-race.patch new file mode 100644 index 0000000..a6d9f75 --- /dev/null +++ b/autofs-5.0.5-fix-expire-race.patch @@ -0,0 +1,40 @@ +autofs-5.0.3 - fix expire race + +From: Ian Kent + +For multi-mounts, if a mount request comes in and does not complete +before a concurrent expire autofs will not recognize that the tree +has become busy which can lead to a partial expire leaving the +multi-mount non-functional. +--- + + CHANGELOG | 1 + + lib/mounts.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + + +--- autofs-5.0.5.orig/CHANGELOG ++++ autofs-5.0.5/CHANGELOG +@@ -59,6 +59,7 @@ + - auto adjust ldap page size. + - fix prune cache valid check. + - fix mountd vers retry. ++- fix expire race. + + 03/09/2009 autofs-5.0.5 + ----------------------- +--- autofs-5.0.5.orig/lib/mounts.c ++++ autofs-5.0.5/lib/mounts.c +@@ -1525,8 +1525,11 @@ int umount_multi_triggers(struct autofs_ + oe_base = oe->key + strlen(root); + left += umount_multi_triggers(ap, oe, root, oe_base); + +- if (oe->ioctlfd != -1) ++ if (oe->ioctlfd != -1 || ++ is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { + left++; ++ break; ++ } + } + + if (left) diff --git a/autofs-5.0.5-fix-isspace-wild-card-substition.patch b/autofs-5.0.5-fix-isspace-wild-card-substition.patch new file mode 100644 index 0000000..ead44ff --- /dev/null +++ b/autofs-5.0.5-fix-isspace-wild-card-substition.patch @@ -0,0 +1,78 @@ +autofs-5.0.5 - fix isspace() wild card substition + +From: Ian Kent + +If there are characters that match isspace() (such as \t, \n, etc.) in a +passed map entry key and there is no space in the key these characters +won't be properly preserved, leading to failed or incorrect mounts. + +This is caused by an incorrect attempt at optimization, using a check +to see if a space is present in the passed key and only then processing +each character of the key individually, escaping any isspace() characters. +--- + + CHANGELOG | 1 + + modules/parse_sun.c | 40 +++++++++++++++++----------------------- + 2 files changed, 18 insertions(+), 23 deletions(-) + + +--- autofs-5.0.5.orig/CHANGELOG ++++ autofs-5.0.5/CHANGELOG +@@ -55,6 +55,7 @@ + - fix add simple bind auth. + - add option to dump configured automount maps. + - use weight only for server selection. ++- fix isspace() wild card substition. + + 03/09/2009 autofs-5.0.5 + ----------------------- +--- autofs-5.0.5.orig/modules/parse_sun.c ++++ autofs-5.0.5/modules/parse_sun.c +@@ -161,30 +161,24 @@ int expandsunent(const char *src, char * + case '&': + l = strlen(key); + /* +- * In order to ensure that any spaces in the key +- * re preserved, we need to escape them here. ++ * In order to ensure that any isspace() characters ++ * in the key are preserved, we need to escape them ++ * here. + */ +- if (strchr(key, ' ')) { +- const char *keyp = key; +- while (*keyp) { +- if (isspace(*keyp)) { +- if (dst) { +- *dst++ = '\\'; +- *dst++ = *keyp++; +- } else +- keyp++; +- l++; +- } else { +- if (dst) +- *dst++ = *keyp++; +- else +- keyp++; +- } +- } +- } else { +- if (dst) { +- strcpy(dst, key); +- dst += l; ++ const char *keyp = key; ++ while (*keyp) { ++ if (isspace(*keyp)) { ++ if (dst) { ++ *dst++ = '\\'; ++ *dst++ = *keyp++; ++ } else ++ keyp++; ++ l++; ++ } else { ++ if (dst) ++ *dst++ = *keyp++; ++ else ++ keyp++; + } + } + len += l; diff --git a/autofs-5.0.5-fix-mountd-vers-retry.patch b/autofs-5.0.5-fix-mountd-vers-retry.patch new file mode 100644 index 0000000..7e4bf3a --- /dev/null +++ b/autofs-5.0.5-fix-mountd-vers-retry.patch @@ -0,0 +1,81 @@ +autofs-5.0.5 - fix mountd vers retry + +From: Ian Kent + +The autofs RPC function used to get the exports list from a host to +be used by the hosts internal map did not try all potentially available +mountd versions. This leads to a failure to get the export list when +certain mountd protocol versions are disabled. +--- + + CHANGELOG | 1 + + lib/rpc_subs.c | 26 +++++++++++++++++++++----- + 2 files changed, 22 insertions(+), 5 deletions(-) + + +--- autofs-5.0.5.orig/CHANGELOG ++++ autofs-5.0.5/CHANGELOG +@@ -58,6 +58,7 @@ + - fix isspace() wild card substition. + - auto adjust ldap page size. + - fix prune cache valid check. ++- fix mountd vers retry. + + 03/09/2009 autofs-5.0.5 + ----------------------- +--- autofs-5.0.5.orig/lib/rpc_subs.c ++++ autofs-5.0.5/lib/rpc_subs.c +@@ -53,6 +53,12 @@ + /* Get numeric value of the n bits starting at position p */ + #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) + ++static const rpcvers_t mount_vers[] = { ++ MOUNTVERS_NFSV3, ++ MOUNTVERS_POSIX, ++ MOUNTVERS, ++}; ++ + static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *); + inline void dump_core(void); + +@@ -846,6 +852,7 @@ static int rpc_get_exports_proto(struct + enum clnt_stat status; + int proto = info->proto->p_proto; + unsigned int option = info->close_option; ++ int vers_entry; + + if (info->proto->p_proto == IPPROTO_UDP) { + info->send_sz = UDPMSGSIZE; +@@ -862,10 +869,19 @@ static int rpc_get_exports_proto(struct + + client->cl_auth = authunix_create_default(); + +- status = clnt_call(client, MOUNTPROC_EXPORT, +- (xdrproc_t) xdr_void, NULL, +- (xdrproc_t) xdr_exports, (caddr_t) exp, +- info->timeout); ++ vers_entry = 0; ++ while (1) { ++ status = clnt_call(client, MOUNTPROC_EXPORT, ++ (xdrproc_t) xdr_void, NULL, ++ (xdrproc_t) xdr_exports, (caddr_t) exp, ++ info->timeout); ++ if (status != RPC_PROGVERSMISMATCH) ++ break; ++ if (++vers_entry > 2) ++ break; ++ CLNT_CONTROL(client, CLSET_VERS, ++ (void *) &mount_vers[vers_entry]); ++ } + + /* Only play with the close options if we think it completed OK */ + if (proto == IPPROTO_TCP && status == RPC_SUCCESS) { +@@ -934,7 +950,7 @@ exports rpc_get_exports(const char *host + info.addr = NULL; + info.addr_len = 0; + info.program = MOUNTPROG; +- info.version = MOUNTVERS; ++ info.version = mount_vers[0]; + info.send_sz = 0; + info.recv_sz = 0; + info.timeout.tv_sec = seconds; diff --git a/autofs-5.0.5-fix-prune-cache-valid-check.patch b/autofs-5.0.5-fix-prune-cache-valid-check.patch new file mode 100644 index 0000000..f639578 --- /dev/null +++ b/autofs-5.0.5-fix-prune-cache-valid-check.patch @@ -0,0 +1,42 @@ +autofs-5.0.5 - fix prune cache valid check + +From: Ian Kent + +During a map reload, when pruning the cache we look for a valid map entry +in another map. In lookup_prune_one_cache() There is a missing check for +the entry being in the current map which causes the directory cleanup code +from doing its job. +--- + + CHANGELOG | 1 + + daemon/lookup.c | 8 ++++++++ + 2 files changed, 9 insertions(+) + + +--- autofs-5.0.5.orig/CHANGELOG ++++ autofs-5.0.5/CHANGELOG +@@ -57,6 +57,7 @@ + - use weight only for server selection. + - fix isspace() wild card substition. + - auto adjust ldap page size. ++- fix prune cache valid check. + + 03/09/2009 autofs-5.0.5 + ----------------------- +--- autofs-5.0.5.orig/daemon/lookup.c ++++ autofs-5.0.5/daemon/lookup.c +@@ -1060,6 +1060,14 @@ void lookup_prune_one_cache(struct autof + * cache entry. + */ + valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT); ++ if (valid && valid->mc == mc) { ++ /* ++ * We've found a map entry that has been removed from ++ * the current cache so it isn't really valid. ++ */ ++ cache_unlock(valid->mc); ++ valid = NULL; ++ } + if (!valid && + is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { + debug(ap->logopt, diff --git a/autofs-5.0.5-use-weight-only-for-server-selection.patch b/autofs-5.0.5-use-weight-only-for-server-selection.patch new file mode 100644 index 0000000..d56ff90 --- /dev/null +++ b/autofs-5.0.5-use-weight-only-for-server-selection.patch @@ -0,0 +1,568 @@ +autofs-5.0.5 - use weight only for server selection + +From: Ian Kent + +When using weighted server names in map entries the server response +time is also taken into consideration when selecting a server for +the target of the mount. In some cases people need to be able to +rely on selection strictly by weight. We add pseudo option +"--use-weight-only" that can be used in with master map entries +or with individual map entries to provide for this. For individual +map entries the option "no-use-weight-only" can also be used to +override the master map option. +--- + + CHANGELOG | 1 + daemon/automount.c | 8 ++--- + include/automount.h | 3 ++ + include/replicated.h | 3 +- + lib/master_parse.y | 12 ++++++-- + lib/master_tok.l | 1 + man/auto.master.5.in | 6 ++++ + man/autofs.5 | 7 ++++ + modules/mount_nfs.c | 15 ++++++---- + modules/parse_sun.c | 36 +++++++++++++++++++++--- + modules/replicated.c | 76 ++++++++++++++++++++++++++++++--------------------- + 11 files changed, 120 insertions(+), 48 deletions(-) + + +--- autofs-5.0.5.orig/CHANGELOG ++++ autofs-5.0.5/CHANGELOG +@@ -54,6 +54,7 @@ + - add external bind method. + - fix add simple bind auth. + - add option to dump configured automount maps. ++- use weight only for server selection. + + 03/09/2009 autofs-5.0.5 + ----------------------- +--- autofs-5.0.5.orig/daemon/automount.c ++++ autofs-5.0.5/daemon/automount.c +@@ -57,8 +57,8 @@ const char *fifodir = AUTOFS_FIFO_DIR "/ + const char *global_options; /* Global option, from command line */ + + static char *pid_file = NULL; /* File in which to keep pid */ +-unsigned int global_random_selection; /* use random policy when selecting +- * which multi-mount host to mount */ ++unsigned int global_selection_options; ++ + long global_negative_timeout = -1; + int do_force_unlink = 0; /* Forceably unlink mount tree at startup */ + +@@ -1855,7 +1855,7 @@ int main(int argc, char *argv[]) + timeout = defaults_get_timeout(); + ghost = defaults_get_browse_mode(); + logging = defaults_get_logging(); +- global_random_selection = 0; ++ global_selection_options = 0; + global_options = NULL; + have_global_options = 0; + foreground = 0; +@@ -1898,7 +1898,7 @@ int main(int argc, char *argv[]) + exit(0); + + case 'r': +- global_random_selection = 1; ++ global_selection_options |= MOUNT_FLAG_RANDOM_SELECT; + break; + + case 'n': +--- autofs-5.0.5.orig/include/automount.h ++++ autofs-5.0.5/include/automount.h +@@ -443,6 +443,9 @@ struct kernel_mod_version { + /* Mount being re-mounted */ + #define MOUNT_FLAG_REMOUNT 0x0008 + ++/* Use server weight only for selection */ ++#define MOUNT_FLAG_USE_WEIGHT_ONLY 0x0010 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +--- autofs-5.0.5.orig/include/replicated.h ++++ autofs-5.0.5/include/replicated.h +@@ -56,6 +56,7 @@ struct host { + size_t addr_len; + char *path; + unsigned int version; ++ unsigned int options; + unsigned int proximity; + unsigned int weight; + unsigned long cost; +@@ -65,7 +66,7 @@ struct host { + void seed_random(void); + void free_host_list(struct host **); + int parse_location(unsigned, struct host **, const char *, unsigned int); +-int prune_host_list(unsigned, struct host **, unsigned int, const char *, unsigned int); ++int prune_host_list(unsigned, struct host **, unsigned int, const char *); + void dump_host_list(struct host *); + + #endif +--- autofs-5.0.5.orig/lib/master_parse.y ++++ autofs-5.0.5/lib/master_parse.y +@@ -58,8 +58,9 @@ static char *format; + static long timeout; + static long negative_timeout; + static unsigned ghost; +-extern unsigned global_random_selection; ++extern unsigned global_selection_options; + static unsigned random_selection; ++static unsigned use_weight; + static char **tmp_argv; + static int tmp_argc; + static char **local_argv; +@@ -98,7 +99,7 @@ static int master_fprintf(FILE *, char * + %token COMMENT + %token MAP + %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE +-%token OPT_DEBUG OPT_RANDOM ++%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT + %token COLON COMMA NL DDASH + %type map + %type options +@@ -181,6 +182,7 @@ line: + | PATH OPTION { master_notify($2); YYABORT; } + | PATH NILL { master_notify($2); YYABORT; } + | PATH OPT_RANDOM { master_notify($1); YYABORT; } ++ | PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; } + | PATH OPT_DEBUG { master_notify($1); YYABORT; } + | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } + | PATH OPT_GHOST { master_notify($1); YYABORT; } +@@ -558,6 +560,7 @@ daemon_option: OPT_TIMEOUT NUMBER { time + | OPT_VERBOSE { verbose = 1; } + | OPT_DEBUG { debug = 1; } + | OPT_RANDOM { random_selection = 1; } ++ | OPT_USE_WEIGHT { use_weight = 1; } + ; + + mount_option: OPTION +@@ -622,7 +625,8 @@ static void local_init_vars(void) + timeout = -1; + negative_timeout = 0; + ghost = defaults_get_browse_mode(); +- random_selection = global_random_selection; ++ random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; ++ use_weight = 0; + tmp_argv = NULL; + tmp_argc = 0; + local_argv = NULL; +@@ -808,6 +812,8 @@ int master_parse_entry(const char *buffe + } + if (random_selection) + entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; ++ if (use_weight) ++ entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; + +--- autofs-5.0.5.orig/lib/master_tok.l ++++ autofs-5.0.5/lib/master_tok.l +@@ -363,6 +363,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|-- + -g|--ghost|-?browse { return(OPT_GHOST); } + -v|--verbose { return(OPT_VERBOSE); } + -d|--debug { return(OPT_DEBUG); } ++ -w|--use-weight-only { return(OPT_USE_WEIGHT); } + -r|--random-multimount-selection { return(OPT_RANDOM); } + + {OPTWS}","{OPTWS} { return(COMMA); } +--- autofs-5.0.5.orig/man/auto.master.5.in ++++ autofs-5.0.5/man/auto.master.5.in +@@ -153,6 +153,12 @@ list of replicated servers. This option + only, overriding the global setting that may be specified on the + command line. + .TP ++.I "\-w, \-\-use-weight-only" ++Use only specified weights for server selection where more than one ++server is specified in the map entry. If no server weights are given ++then each available server will be tried in the order listed, within ++proximity. ++.TP + .I "\-n, \-\-negative\-timeout " + Set the timeout for caching failed key lookups. This option can be + used to override the global default given either on the command line +--- autofs-5.0.5.orig/man/autofs.5 ++++ autofs-5.0.5/man/autofs.5 +@@ -49,6 +49,13 @@ is used to treat errors when mounting fi + multiple file systems should be mounted (`multi-mounts'). If this option + is given, no file system is mounted at all if at least one file system + can't be mounted. ++.I -use-weight-only ++is used to make the weight the sole factor in selecting a server when multiple ++servers are present in a map entry. ++and ++.I -no-use-weight-only ++can be used to negate the option if it is present in the master map entry ++for the map but is not wanted for the given mount. + + .SS location + The location specifies from where the file system is to be mounted. In the +--- autofs-5.0.5.orig/modules/mount_nfs.c ++++ autofs-5.0.5/modules/mount_nfs.c +@@ -63,7 +63,8 @@ int mount_mount(struct autofs_point *ap, + struct host *this, *hosts = NULL; + unsigned int mount_default_proto, vers; + char *nfsoptions = NULL; +- unsigned int random_selection = ap->flags & MOUNT_FLAG_RANDOM_SELECT; ++ unsigned int flags = ap->flags & ++ (MOUNT_FLAG_RANDOM_SELECT | MOUNT_FLAG_USE_WEIGHT_ONLY); + int len, status, err, existed = 1; + int nosymlink = 0; + int ro = 0; /* Set if mount bind should be read-only */ +@@ -112,9 +113,13 @@ int mount_mount(struct autofs_point *ap, + while (*comma == ' ' || *comma == '\t') + end--; + +- if (strncmp("nosymlink", cp, end - cp + 1) == 0) ++ if (strncmp("nosymlink", cp, end - cp + 1) == 0) { + nosymlink = 1; +- else { ++ } else if (strncmp("no-use-weight-only", cp, end - cp + 1) == 0) { ++ flags &= ~MOUNT_FLAG_USE_WEIGHT_ONLY; ++ } else if (strncmp("use-weight-only", cp, end - cp + 1) == 0) { ++ flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; ++ } else { + /* Check for options that also make sense + with bind mounts */ + if (strncmp("ro", cp, end - cp + 1) == 0) +@@ -137,11 +142,11 @@ int mount_mount(struct autofs_point *ap, + else if (mount_default_proto == 4) + vers = vers | NFS4_VERS_MASK; + +- if (!parse_location(ap->logopt, &hosts, what, random_selection)) { ++ if (!parse_location(ap->logopt, &hosts, what, flags)) { + info(ap->logopt, MODPREFIX "no hosts available"); + return 1; + } +- prune_host_list(ap->logopt, &hosts, vers, nfsoptions, random_selection); ++ prune_host_list(ap->logopt, &hosts, vers, nfsoptions); + + if (!hosts) { + info(ap->logopt, MODPREFIX "no hosts available"); +--- autofs-5.0.5.orig/modules/parse_sun.c ++++ autofs-5.0.5/modules/parse_sun.c +@@ -529,6 +529,7 @@ static int sun_mount(struct autofs_point + { + char *fstype = "nfs"; /* Default filesystem type */ + int nonstrict = 1; ++ int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY; + int rv, cur_state; + char *mountpoint; + char *what; +@@ -575,6 +576,10 @@ static int sun_mount(struct autofs_point + memcpy(np, cp, comma - cp + 1); + np += comma - cp + 1; + } ++ } else if (strncmp("no-use-weight-only", cp, 18) == 0) { ++ use_weight_only = -1; ++ } else if (strncmp("use-weight-only", cp, 15) == 0) { ++ use_weight_only = MOUNT_FLAG_USE_WEIGHT_ONLY; + } else if (strncmp("bg", cp, 2) == 0 || + strncmp("nofg", cp, 4) == 0) { + continue; +@@ -593,11 +598,10 @@ static int sun_mount(struct autofs_point + options = noptions; + } + +- + if (!strcmp(fstype, "autofs") && ctxt->macros) { + char *noptions = NULL; + +- if (!options) { ++ if (!options || *options == '\0') { + noptions = alloca(strlen(ctxt->macros) + 1); + *noptions = '\0'; + } else { +@@ -610,7 +614,7 @@ static int sun_mount(struct autofs_point + } + } + +- if (noptions) { ++ if (noptions && *noptions != '\0') { + strcat(noptions, ctxt->macros); + options = noptions; + } else { +@@ -624,7 +628,7 @@ static int sun_mount(struct autofs_point + + type = ap->entry->maps->type; + if (type && !strcmp(type, "hosts")) { +- if (options) { ++ if (options && *options != '\0') { + int len = strlen(options); + int suid = strstr(options, "suid") ? 0 : 7; + int dev = strstr(options, "dev") ? 0 : 6; +@@ -669,6 +673,30 @@ static int sun_mount(struct autofs_point + memcpy(what, loc, loclen); + what[loclen] = '\0'; + ++ /* Add back "[no-]use-weight-only" for NFS mounts only */ ++ if (use_weight_only) { ++ char *tmp; ++ int len; ++ ++ if (options && *options != '\0') { ++ len = strlen(options) + 19; ++ tmp = alloca(len); ++ strcpy(tmp, options); ++ strcat(tmp, ","); ++ if (use_weight_only == MOUNT_FLAG_USE_WEIGHT_ONLY) ++ strcat(tmp, "use-weight-only"); ++ else ++ strcat(tmp, "no-use-weight-only"); ++ } else { ++ tmp = alloca(19); ++ if (use_weight_only == MOUNT_FLAG_USE_WEIGHT_ONLY) ++ strcpy(tmp, "use-weight-only"); ++ else ++ strcpy(tmp, "no-use-weight-only"); ++ } ++ options = tmp; ++ } ++ + debug(ap->logopt, MODPREFIX + "mounting root %s, mountpoint %s, " + "what %s, fstype %s, options %s", +--- autofs-5.0.5.orig/modules/replicated.c ++++ autofs-5.0.5/modules/replicated.c +@@ -351,7 +351,8 @@ static unsigned int get_proximity(struct + + static struct host *new_host(const char *name, + struct sockaddr *addr, size_t addr_len, +- unsigned int proximity, unsigned int weight) ++ unsigned int proximity, unsigned int weight, ++ unsigned int options) + { + struct host *new; + struct sockaddr *tmp2; +@@ -385,6 +386,7 @@ static struct host *new_host(const char + new->addr = tmp2; + new->proximity = proximity; + new->weight = weight; ++ new->options = options; + + return new; + } +@@ -519,9 +521,11 @@ static unsigned short get_port_option(co + static unsigned int get_nfs_info(unsigned logopt, struct host *host, + struct conn_info *pm_info, struct conn_info *rpc_info, + const char *proto, unsigned int version, +- const char *options, unsigned int random_selection) ++ const char *options) + { + char *have_port_opt = options ? strstr(options, "port=") : NULL; ++ unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT; ++ unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY; + struct pmap parms; + struct timeval start, end; + struct timezone tz; +@@ -675,7 +679,10 @@ done_ver: + * Average response time to 7 significant places as + * integral type. + */ +- host->cost = (unsigned long) ((taken * 1000000) / count); ++ if (use_weight_only) ++ host->cost = 1; ++ else ++ host->cost = (unsigned long) ((taken * 1000000) / count); + + /* Allow for user bias */ + if (host->weight) +@@ -689,8 +696,7 @@ done_ver: + } + + static int get_vers_and_cost(unsigned logopt, struct host *host, +- unsigned int version, const char *options, +- unsigned int random_selection) ++ unsigned int version, const char *options) + { + struct conn_info pm_info, rpc_info; + time_t timeout = RPC_TIMEOUT; +@@ -717,8 +723,7 @@ static int get_vers_and_cost(unsigned lo + + if (version & UDP_REQUESTED) { + supported = get_nfs_info(logopt, host, +- &pm_info, &rpc_info, "udp", vers, +- options, random_selection); ++ &pm_info, &rpc_info, "udp", vers, options); + if (supported) { + ret = 1; + host->version |= (supported << 8); +@@ -727,8 +732,7 @@ static int get_vers_and_cost(unsigned lo + + if (version & TCP_REQUESTED) { + supported = get_nfs_info(logopt, host, +- &pm_info, &rpc_info, "tcp", vers, +- options, random_selection); ++ &pm_info, &rpc_info, "tcp", vers, options); + if (supported) { + ret = 1; + host->version |= supported; +@@ -739,10 +743,11 @@ static int get_vers_and_cost(unsigned lo + } + + static int get_supported_ver_and_cost(unsigned logopt, struct host *host, +- unsigned int version, const char *options, +- unsigned int random_selection) ++ unsigned int version, const char *options) + { + char *have_port_opt = options ? strstr(options, "port=") : NULL; ++ unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT; ++ unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY; + struct conn_info pm_info, rpc_info; + struct pmap parms; + const char *proto; +@@ -855,7 +860,10 @@ done: + + if (status) { + /* Response time to 7 significant places as integral type. */ +- host->cost = (unsigned long) (taken * 1000000); ++ if (use_weight_only) ++ host->cost = 1; ++ else ++ host->cost = (unsigned long) (taken * 1000000); + + /* Allow for user bias */ + if (host->weight) +@@ -870,8 +878,7 @@ done: + } + + int prune_host_list(unsigned logopt, struct host **list, +- unsigned int vers, const char *options, +- unsigned int random_selection) ++ unsigned int vers, const char *options) + { + struct host *this, *last, *first; + struct host *new = NULL; +@@ -892,6 +899,7 @@ int prune_host_list(unsigned logopt, str + this = first; + while (this && this->proximity == PROXIMITY_LOCAL) + this = this->next; ++ first = this; + + /* + * Check for either a list containing only proximity local hosts +@@ -903,8 +911,6 @@ int prune_host_list(unsigned logopt, str + return 1; + + proximity = this->proximity; +- first = this; +- this = first; + while (this) { + struct host *next = this->next; + +@@ -912,8 +918,7 @@ int prune_host_list(unsigned logopt, str + break; + + if (this->name) { +- status = get_vers_and_cost(logopt, this, vers, +- options, random_selection); ++ status = get_vers_and_cost(logopt, this, vers, options); + if (!status) { + if (this == first) { + first = next; +@@ -1022,8 +1027,7 @@ int prune_host_list(unsigned logopt, str + add_host(&new, this); + } else { + status = get_supported_ver_and_cost(logopt, this, +- selected_version, options, +- random_selection); ++ selected_version, options); + if (status) { + this->version = selected_version; + remove_host(list, this); +@@ -1041,8 +1045,7 @@ int prune_host_list(unsigned logopt, str + + static int add_new_host(struct host **list, + const char *host, unsigned int weight, +- struct addrinfo *host_addr, +- unsigned int random_selection) ++ struct addrinfo *host_addr, unsigned int options) + { + struct host *new; + unsigned int prx; +@@ -1054,10 +1057,21 @@ static int add_new_host(struct host **li + * We can't use PROXIMITY_LOCAL or we won't perform an RPC ping + * to remove hosts that may be down. + */ +- if (random_selection) ++ if (options & MOUNT_FLAG_RANDOM_SELECT) + prx = PROXIMITY_SUBNET; +- else ++ else { + prx = get_proximity(host_addr->ai_addr); ++ /* ++ * If we want the weight to be the determining factor ++ * when selecting a host then all hosts must have the ++ * same proximity. However, if this is the local machine ++ * it should always be used since it is certainly available. ++ */ ++ if (prx != PROXIMITY_LOCAL && ++ (options & MOUNT_FLAG_USE_WEIGHT_ONLY)) ++ prx = PROXIMITY_SUBNET; ++ } ++ + /* + * If we tried to add an IPv6 address and we don't have IPv6 + * support return success in the hope of getting an IPv4 +@@ -1069,7 +1083,7 @@ static int add_new_host(struct host **li + return 0; + + addr_len = sizeof(struct sockaddr); +- new = new_host(host, host_addr->ai_addr, addr_len, prx, weight); ++ new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options); + if (!new) + return 0; + +@@ -1082,7 +1096,7 @@ static int add_new_host(struct host **li + } + + static int add_host_addrs(struct host **list, const char *host, +- unsigned int weight, unsigned int random_selection) ++ unsigned int weight, unsigned int options) + { + struct addrinfo hints, *ni, *this; + int ret; +@@ -1098,7 +1112,7 @@ static int add_host_addrs(struct host ** + + this = ni; + while (this) { +- ret = add_new_host(list, host, weight, this, random_selection); ++ ret = add_new_host(list, host, weight, this, options); + if (!ret) + break; + this = this->ai_next; +@@ -1121,7 +1135,7 @@ try_name: + + this = ni; + while (this) { +- ret = add_new_host(list, host, weight, this, random_selection); ++ ret = add_new_host(list, host, weight, this, options); + if (!ret) + break; + this = this->ai_next; +@@ -1209,7 +1223,7 @@ static char *seek_delim(const char *s) + } + + int parse_location(unsigned logopt, struct host **hosts, +- const char *list, unsigned int random_selection) ++ const char *list, unsigned int options) + { + char *str, *p, *delim; + unsigned int empty = 1; +@@ -1264,7 +1278,7 @@ int parse_location(unsigned logopt, stru + } + + if (p != delim) { +- if (!add_host_addrs(hosts, p, weight, random_selection)) { ++ if (!add_host_addrs(hosts, p, weight, options)) { + if (empty) { + p = next; + continue; +@@ -1286,7 +1300,7 @@ int parse_location(unsigned logopt, stru + *delim = '\0'; + next = delim + 1; + +- if (!add_host_addrs(hosts, p, weight, random_selection)) { ++ if (!add_host_addrs(hosts, p, weight, options)) { + p = next; + continue; + } diff --git a/autofs.spec b/autofs.spec index 7c8d791..9fc9a65 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.5 -Release: 35%{?dist} +Release: 36%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -68,6 +68,13 @@ Patch56: autofs-5.0.5-add-external-bind-method.patch Patch57: autofs-5.0.5-fix-add-simple-bind-auth.patch Patch58: autofs-5.0.5-add-dump-maps-option.patch Patch59: autofs-5.0.5-fix-submount-shutdown-wait.patch +Patch60: autofs-5.0.5-use-weight-only-for-server-selection.patch +Patch61: autofs-5.0.5-fix-isspace-wild-card-substition.patch +Patch62: autofs-5.0.5-auto-adjust-ldap-page-size.patch +Patch63: autofs-5.0.5-fix-prune-cache-valid-check.patch +Patch64: autofs-5.0.5-fix-mountd-vers-retry.patch +Patch65: autofs-5.0.5-fix-expire-race.patch +Patch66: autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel Conflicts: cyrus-sasl-lib < 2.1.23-9 @@ -169,6 +176,13 @@ echo %{version}-%{release} > .version %patch57 -p1 %patch58 -p1 %patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -221,6 +235,15 @@ fi %{_libdir}/autofs/ %changelog +* Thu Mar 03 2011 Ian Kent - 1:5.0.5-36 +- use weight only for server selection. +- fix isspace() wild card substition. +- auto adjust ldap page size. +- fix prune cache valid check. +- fix mountd vers retry. +- fix expire race. +- add lsb force-reload and try-restart. + * Mon Feb 07 2011 Fedora Release Engineering - 1:5.0.5-35 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild