From: mcm@gorgon.unx.sas.com (Mike Mitchell)
Subject: AMD mods
Date: Fri, 6 Nov 1992 23:15:37 GMT
Organization: SAS Institute Inc.

We've been running AMD 5.3 beta for some time, and have patched some bugs
and made other changes to better support our environment of HP 700 machines
running 8.07.  

We had problems with NFS RPC timeout values being set incorrectly, mounts
failing while an unmount was in progress, and most recently, a mount failing
within 5 minutes of an unmount.  I'm including here some patches we received
to convert AMD to HPUX 8.07.

We've been using AMD for some time now, and a situation came up where I needed
a selector equivalent to '${.key}'.  The key in our case contains a fully
qualified hostname, i.e. 'qa.pc.sas.com' or 'warlock.dev.sas.com'.
I needed to strip the hostname off and select on the domain of the key.

I added two new selectors, named '.key' and 'key.', and initialized them
to the same as ${.key} and ${key.}, respectivly.  I then ran into some
trouble, because sometimes ${.key} was a null string.  To correct for
those cases, I set the selector .key to be "<NULL>", so I can check
for it.  These changes let me use different NFS rsize and wsize parameters
depending on what domain the destination machine is in.
Here is an example from one of our map files:

#----------------------------------------------------------------
# Wildcard match - Can't have more than 2000 bytes in this file!
#
*   -opts:=rw,soft,grpid,suid,rsize=1024,wsize=1024,retrans=20,timeo=10 \
    hostd==${key};type:=link;fs:=.. \
    host==${key};type:=link;fs:=.. \
    .key==<NULL>;host!=${key};type:=host;rhost:=${key};fs:=/remote/${key.};\
	opts:=rw,soft,grpid,suid,rsize=4096,wsize=4096,retrans=20,timeo=10 \
    .key!=<NULL>;domain==${.key};hostd!=${key};host!=${key};type:=host;\
	rhost:=${key};fs:=/remote/${key.};\
	opts:=rw,soft,grpid,suid,rsize=4096,wsize=4096,retrans=20,timeo=10 \
    .key!=<NULL>;.key==unx;hostd!=${key};type:=host;\
	rhost:=${key};fs:=/remote/${key.};\
	opts:=rw,soft,grpid,suid,rsize=4096,wsize=4096,retrans=20,timeo=10 \
    .key!=<NULL>;.key==dev.sas.com;hostd!=${key};type:=host;\
	rhost:=${key};fs:=/remote/${key};\
	opts:=rw,soft,grpid,suid,rsize=8192,wsize=8192,retrans=20,timeo=10 \
    .key!=<NULL>;.key==dev;hostd!=${key};type:=host;\
	rhost:=${key};fs:=/remote/${key};\
	opts:=rw,soft,grpid,suid,rsize=8192,wsize=8192,retrans=20,timeo=10 \
    .key!=<NULL>;domain!=${.key};hostd!=${key};host!=${key};type:=host;\
	rhost:=${key};fs:=/remote/${key};delay:=3
#--------------------------------------------------------------

I don't need the 'key.' selector, but I added it for completeness.
Someone might like the same approach for the 'path' selector, adding
'/path' and 'path/'.

We also have many Apollos here, and need two slashes ('//') left on the
end of strings.  I'm including a patch Kevin Bond added.

I've tried to send these patches off, but the mail bounces back.  Can
anyone suggest the appropriate news group?  Anyway, since we deal
primarily with HP's, I thought this would be a good place to start.

We are running amd.5.2.2.1 1992/02/09 15:11:18 5.3 beta #7, and here
are the context diffs:

*** amd/afs_ops.c	Tue Oct  6 15:46:03 1992
--- amd/afs_ops.c.orig	Sun Feb  9 10:07:53 1992
***************
*** 185,196 ****
  	if (strlen(fs_hostname) >= HOSTNAMESZ)
  		strcpy(fs_hostname + HOSTNAMESZ - 3, "..");
  #endif /* HOSTNAMESZ */
- #ifdef NFSMNT_FSNAME
- 	nfs_args.fsname = pid_fsname;
- 	nfs_args.flags |= NFSMNT_FSNAME;
- #endif /* NFSMNT_FSNAME */
  
- 
  	/*
  	 * Parse a subset of the standard nfs options.  The
  	 * others are probably irrelevant for this application
--- 185,191 ----
***************
*** 905,913 ****
  		 * Note whether this is a real mount attempt
  		 */
  		if (p == &efs_ops) {
- #ifdef DEBUG
  			plog(XLOG_MAP, "Map entry %s for %s failed to match", *cp->ivec, mp->am_path);
- #endif
  			if (this_error <= 0)
  				this_error = ENOENT;
  			continue;
--- 900,906 ----
***************
*** 1271,1277 ****
  				continue;
  			}
  
! 			if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) {
  in_progrss:
  				/*
  				 * If the fs is not mounted or it is unmounting then there
--- 1264,1270 ----
  				continue;
  			}
  
! 			if (!(mf->mf_flags & MFF_MOUNTED) /*|| (mf->mf_flags & MFF_UNMOUNTING)*/) {
  in_progrss:
  				/*
  				 * If the fs is not mounted or it is unmounting then there
***************
*** 1284,1292 ****
  				dlog("ignoring mount of %s in %s -- in progress",
  					fname, mf->mf_mount);
  #endif /* DEBUG */
- if (mf->mf_flags & MFF_UNMOUNTING){
- plog(XLOG_WARNING, "ignoring mount of %s in %s -- unmount in progress", fname,
- mf->mf_mount);}
  				in_progress++;
  				continue;
  			}
--- 1277,1282 ----
*** amd/host_ops.c	Mon Sep 28 11:41:27 1992
--- amd/host_ops.c.orig	Sun Feb  9 10:08:05 1992
***************
*** 247,262 ****
  	char fs_name[MAXPATHLEN], *rfs_dir;
  	char mntpt[MAXPATHLEN];
  	struct timeval tv;
! /*
!  * The original 10 second per try timeout is WAY too large, especially
!  * if we're only waiting 10 or 20 seconds max for the response.
!  * That would mean we'd try only once in 10 seconds, and we could
!  * lose the transmitt or receive packet, and never try again.
!  * A 2-second per try timeout here is much more reasonable.
!  * 09/28/92 Mike Mitchell, mcm@unx.sas.com
!  *	tv.tv_sec = 10; tv.tv_usec = 0;
!  */
!  	tv.tv_sec = 2; tv.tv_usec = 0;
  
  	/*
  	 * Read the mount list
--- 247,253 ----
  	char fs_name[MAXPATHLEN], *rfs_dir;
  	char mntpt[MAXPATHLEN];
  	struct timeval tv;
! 	tv.tv_sec = 10; tv.tv_usec = 0;
  
  	/*
  	 * Read the mount list
***************
*** 306,314 ****
  	tv2.tv_sec = 10; tv2.tv_usec = 0;
  	clnt_stat = clnt_call(client, MOUNTPROC_EXPORT, xdr_void, 0, xdr_exports, &exlist, tv2);
  	if (clnt_stat != RPC_SUCCESS) {
- 		extern char *clnt_sperrno();
- 		char *msg = clnt_sperrno(clnt_stat);
- 		plog(XLOG_ERROR, "host_fmount rpc failed: %s", msg);
  		/*clnt_perror(client, "rpc");*/
  		error = EIO;
  		goto out;
--- 297,302 ----
*** amd/info_hes.c	Fri May  8 10:29:52 1992
--- amd/info_hes.c.orig	Sun Feb  9 10:08:09 1992
***************
*** 459,465 ****
  		cp += sizeof(u_short);
  		/* Check to see if key is in our domain */
  		if (type == T_TXT && hs_strip_our_domain(key)) {
! 			value = hs_make_value((unsigned char *)cp, len);
  			if (value == NULL)
  				return(-1);
  			key_cpy = strdup(key);
--- 459,465 ----
  		cp += sizeof(u_short);
  		/* Check to see if key is in our domain */
  		if (type == T_TXT && hs_strip_our_domain(key)) {
! 			value = hs_make_value(cp, len);
  			if (value == NULL)
  				return(-1);
  			key_cpy = strdup(key);
***************
*** 500,510 ****
  
  char *
  hs_make_value(cp, len)
! unsigned char *cp;
  int len;
  {
! 	char *value, *valuep;
! 	unsigned char *cpcpy;
  	int cnt, nextcnt, totalcnt, lencpy;
  #ifdef DEBUG
  	char *dbgname;
--- 500,509 ----
  
  char *
  hs_make_value(cp, len)
! char *cp;
  int len;
  {
! 	char *value, *cpcpy, *valuep;
  	int cnt, nextcnt, totalcnt, lencpy;
  #ifdef DEBUG
  	char *dbgname;
*** amd/mntfs.c	Wed Sep 23 17:46:39 1992
--- amd/mntfs.c.orig	Sun Feb  9 10:08:22 1992
***************
*** 175,187 ****
  				 */
  				if (mf->mf_ops != &efs_ops)
  					continue;
- 			/*
- 			 * following two lines added to prevent AMD
- 			 * from hanging.  Suggested by:
- 			 * cagney@cs.adelaide.edu.au (Andrew Cagney)
- 			 */
- 				else
- 					return dup_mntfs(mf);
  			} else /* ops != &efs_ops */ {
  				/*
  				 * If the existing ops are efs_ops
--- 175,180 ----
*** amd/nfs_ops.c	Fri Mar 27 12:41:00 1992
--- amd/nfs_ops.c.orig	Sun Feb  9 10:08:27 1992
***************
*** 530,540 ****
  	if (strlen(host) >= HOSTNAMESZ)
  		strcpy(host + HOSTNAMESZ - 3, "..");
  #endif /* HOSTNAMESZ */
- #ifdef NFSMNT_FSNAME
- 	nfs_args.fsname = fs_name;
- 	nfs_args.flags |= NFSMNT_FSNAME;
- #endif /* NFSMNT_FSNAME */
- 
  
  	if (nfs_args.rsize = hasmntval(&mnt, "rsize"))
  		nfs_args.flags |= NFSMNT_RSIZE;
--- 530,535 ----
*** amd/opts.c	Wed Jul 15 14:21:50 1992
--- amd/opts.c.orig	Sun Feb  9 10:08:35 1992
***************
*** 43,49 ****
  
  #include "am.h"
  
! extern char *getenv P((Const char *));
  
  /*
   * static copy of the options with
--- 43,49 ----
  
  #include "am.h"
  
! extern char *getenv P((const char *));
  
  /*
   * static copy of the options with
***************
*** 54,63 ****
  static char *opt_host = hostname;
  static char *opt_hostd = hostd;
  static char nullstr[] = "";
- static char NullStr[] = "<NULL>";
  static char *opt_key = nullstr;
- static char *opt_dkey = NullStr;
- static char *opt_keyd = nullstr;
  static char *opt_map = nullstr;
  static char *opt_path = nullstr;
  
--- 54,60 ----
***************
*** 103,110 ****
  	{ S("cache"), &fs_static.opt_cache, 0 },
  	{ S("user"), &fs_static.opt_user, 0 },
  	{ S("group"), &fs_static.opt_group, 0 },
- 	{ S(".key"), 0, &opt_dkey },
- 	{ S("key."), 0, &opt_keyd },
  	{ S("var0"), &vars[0], 0 },
  	{ S("var1"), &vars[1], 0 },
  	{ S("var2"), &vars[2], 0 },
--- 100,105 ----
***************
*** 245,254 ****
  			/*
  			 * No value, just continue
  			 */
! #ifdef DEBUG
! 			plog(XLOG_USER, "key %s: No value component in \"%s\"",
! 					mapkey, f);
! #endif
  			continue;
  		}
  
--- 240,246 ----
  			/*
  			 * No value, just continue
  			 */
! 			plog(XLOG_USER, "key %s: No value component in \"%s\"", mapkey, f);
  			continue;
  		}
  
***************
*** 302,315 ****
  				case SelEQ:
  				case SelNE:
  					if (op->sel_p && (STREQ(*op->sel_p, opt) == (vs_opt == SelNE))) {
- #ifdef DEBUG
  						plog(XLOG_MAP, "key %s: map selector %s (=%s) did not %smatch %s",
  							mapkey,
  							op->name,
  							*op->sel_p,
! 							vs_opt == SelNE ? "(not) " : "",
  							opt);
- #endif
  						return 0;
  					}
  					break;
--- 294,305 ----
  				case SelEQ:
  				case SelNE:
  					if (op->sel_p && (STREQ(*op->sel_p, opt) == (vs_opt == SelNE))) {
  						plog(XLOG_MAP, "key %s: map selector %s (=%s) did not %smatch %s",
  							mapkey,
  							op->name,
  							*op->sel_p,
! 							vs_opt == SelNE ? "not " : "",
  							opt);
  						return 0;
  					}
  					break;
***************
*** 746,752 ****
  /*
   * Remove trailing /'s from a string
   * unless the string is a single / (Steven Glassman)
-  * or unless it is two slashes // (Kevin D. Bond)
   */
  void deslashify P((char *s));
  void deslashify(s)
--- 736,741 ----
***************
*** 754,761 ****
  {
  	if (s && *s) {
  		char *sl = s + strlen(s);
- 		if ( *s == '/' && s[1] == '/' )
- 			s++;
  		while (*--sl == '/' && sl > s)
  			*sl = '\0';
  	}
--- 743,748 ----
***************
*** 783,801 ****
  	opt_map = map;
  	opt_path = path;
  
- 	opt_dkey = strchr(key, '.');
- 	if (!opt_dkey) {
- 	    opt_dkey = NullStr;
- 	    opt_keyd = key;
- 	}
- 	else {
- 	    opt_keyd = strnsave(key, opt_dkey - key);
- 	    opt_dkey++;
- 	    if (*opt_dkey == '\0')	/* check for 'host.' */
- 		opt_dkey = NullStr;
- 	}
- 
- 
  	/*
  	 * Expand global options
  	 */
--- 770,775 ----
***************
*** 853,862 ****
  	/*
  	 * Clear defined options
  	 */
- 	if (opt_keyd != key && opt_keyd != nullstr)
- 	    free(opt_keyd);
- 	opt_keyd = nullstr;
- 	opt_dkey = NullStr;
  	opt_key = opt_map = opt_path = nullstr;
  
  	return ok;
--- 827,832 ----
*** amd/srvr_nfs.c	Tue Nov  3 19:40:00 1992
--- amd/srvr_nfs.c.orig	Sun Feb  9 10:08:47 1992
***************
*** 641,667 ****
  
  	ITER(fs, fserver, &nfs_srvr_list) {
  		if (STREQ(host, fs->fs_host)) {
- 			/*
- 			 * following if statement from Mike Mitchell
- 			 * <mcm@unx.sas.com>
- 			 * Initialize the ping data if we are no longer
- 			 * pinging.  The np_ttl and np_ping fields are
- 			 * especially important.
- 			 */
- 			if (!(fs->fs_flags & FSF_PINGING)) {
- 				np = (nfs_private *) fs->fs_private;
- 				np->np_mountd_inval = TRUE;
- 				np->np_xid = NPXID_ALLOC();
- 				np->np_error = -1;
- 				np->np_ping = 0;
- 				/*
- 				 * Initially the server will be deemed dead
- 				 * after MAX_ALLOWED_PINGS of the fast variety
- 				 * have failed.
- 				 */
- 				np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING +
- 						clocktime() - 1;
- 			}
  			start_nfs_pings(fs, pingval);
  			fs->fs_refc++;
  			return fs;
--- 641,646 ----
*** amq/amq.c	Fri Oct  2 11:53:35 1992
--- amq/amq.c.orig	Sun Feb  9 10:08:57 1992
***************
*** 408,419 ****
  	s = privsock(SOCK_STREAM);
  	clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
  	if (clnt == 0) {
- 		struct timeval tv;
  		close(s);
  		s = privsock(SOCK_DGRAM);
! 		tv.tv_sec  = 2;		/* 2 seconds per retry */
! 		tv.tv_usec = 0;
! 		clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tv, &s);
  	}
  	if (clnt == 0) {
  		fprintf(stderr, "%s: ", progname);
--- 408,416 ----
  	s = privsock(SOCK_STREAM);
  	clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
  	if (clnt == 0) {
  		close(s);
  		s = privsock(SOCK_DGRAM);
! 		clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
  	}
  	if (clnt == 0) {
  		fprintf(stderr, "%s: ", progname);
*** config/Makefile.hpux	Fri Mar 27 12:41:23 1992
--- config/Makefile.hpux.orig	Sun Feb  9 10:10:06 1992
***************
*** 44,50 ****
  
  #CC = gcc ${GCCOPTS}
  # Works only on HP300
! #CC = cc -Wc,-Nd2000
! #SYSCC = $(CC)
  # Works only Hp800
! CC = cc -Aa -D_HPUX_SOURCE -Dhp9000s800 -Dhp9000s700
--- 44,50 ----
  
  #CC = gcc ${GCCOPTS}
  # Works only on HP300
! CC = cc -Wc,-Nd2000
! SYSCC = $(CC)
  # Works only Hp800
! # CC = cc
*** config/misc-hpux.h	Fri Mar 27 12:41:31 1992
--- config/misc-hpux.h.orig	Sun Feb  9 10:10:04 1992
***************
*** 77,81 ****
  #define	NFSMNT_HOSTNAME	0x020	/* set hostname for error printf */
  #define	NFSMNT_INT	0x040	/* set option to have interruptable mounts */
  #define	NFSMNT_NODEVS   0x080   /* turn off device file access (default on) */
- #define NFSMNT_FSNAME   0x100   /* provide name of server's fs to system */
- 
--- 77,79 ----
*** config/os-hpux.h	Fri May  8 09:54:48 1992
--- config/os-hpux.h.orig	Sun Feb  9 10:10:03 1992
***************
*** 133,143 ****
   */
  #define FIXUP_MNTENT(mntp) { \
  	(mntp)->mnt_time = clocktime(); \
- 	(mntp)->mnt_cnode = 0; \
  }
  #define FIXUP_MNTENT_DUP(mntp, mp) { \
  	(mntp)->mnt_time = (mp)->mnt_time; \
- 	(mntp)->mnt_cnode = (mp)->mnt_cnode; \
  }
  
  #define	bzero(ptr, len)	memset(ptr, 0, len)
--- 133,141 ----
*** include/config.h	Fri May  8 10:21:27 1992
--- include/config.h.orig	Sun Feb  9 10:09:36 1992
***************
*** 137,142 ****
  extern void plog ();
  /*extern void plog P((int, char*, ...));*/
  extern void show_opts P((int ch, struct opt_tab*));
! extern char* strchr P((Const char*, int)); /* C */
  extern voidp xmalloc P((int));
  extern voidp xrealloc P((voidp, int));
--- 137,142 ----
  extern void plog ();
  /*extern void plog P((int, char*, ...));*/
  extern void show_opts P((int ch, struct opt_tab*));
! extern char* strchr P((const char*, int)); /* C */
  extern voidp xmalloc P((int));
  extern voidp xrealloc P((voidp, int));
*** rpcx/amq.x	Fri May  8 10:25:23 1992
--- rpcx/amq.x.orig	Sun Feb  9 10:09:00 1992
***************
*** 45,51 ****
   * Protocol description used by the amq program
   */
  
! Const AMQ_STRLEN = 1024;	/* Maximum length of a pathname */
  
  /*
   * The type dirpath is the pathname of a directory
--- 45,51 ----
   * Protocol description used by the amq program
   */
  
! const AMQ_STRLEN = 1024;	/* Maximum length of a pathname */
  
  /*
   * The type dirpath is the pathname of a directory
====================================================================
End of patches.
-- 
------------------------------------------------------------------------------
Mike Mitchell			"There's laughter where I used to see a tear.
mcm@unx.sas.com			 It's all done with mirrors, have no fear."
(919) 677-8000 X6793			-- Blue Oyster Cult