home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1691 < prev    next >
Text File  |  1990-12-28  |  6KB  |  303 lines

  1. Newsgroups: alt.sources
  2. From: richard@aiai.ed.ac.uk (Richard Tobin)
  3. Subject: [comp.sys.hp...] Re: NFS mounts - hard versus soft - info. wanted
  4. Message-ID: <1990Aug21.193114.23120@math.lsa.umich.edu>
  5. Date: Tue, 21 Aug 90 19:31:14 GMT
  6.  
  7. Archive-name: nfslink/21-Aug-90
  8. Original-posting-by: richard@aiai.ed.ac.uk (Richard Tobin)
  9. Original-subject: Re: NFS mounts - hard versus soft - info. wanted
  10. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
  11.  
  12. [Reposted from comp.sys.hp,comp.unix.questions.
  13. Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
  14.  
  15. In article <1990Aug20.204546.15101@anduin.cs.liverpool.ac.uk> dave8@anduin.cs.liverpool.ac.uk writes:
  16. >However, we are frustrated by situations where a cluster server goes down,
  17. >and the workstations on another cluster server hang because the PATH
  18. >environment variable on these includes a directory residing on a
  19. >partition being exported from the machine that has gone down. 
  20.  
  21. One way to deal with this is to mount the filesystems in some
  22. obscure place, and make symbolic links to them.  You can then remove
  23. the links when the server goes down.
  24.  
  25. Of course, this doesn't work if you don't have symbolic links.
  26.  
  27. You should also mount filesystems from different machines in different
  28. directories, so that "pwd" doesn't hang.
  29.  
  30. You can have a program maintain the links automatically - here's one
  31. I use.  It may need changing for HPs.
  32.  
  33. -- Richard
  34.  
  35. /*
  36.  * nfslink [-i interval] [-t timeout] host name mountpt [name mountpt ...]
  37.  *
  38.  * maintain links to mounted file systems, removing them if the
  39.  * remote machine isn't responding.
  40.  *
  41.  * Copyright Richard Tobin / AIAI 1989
  42.  * 
  43.  * May be freely redistributed if this whole notice remains intact.
  44.  */
  45.  
  46. #include <stdio.h>
  47. #include <errno.h>
  48. #include <signal.h>
  49. #include <sys/time.h>
  50. #include <rpc/rpc.h>
  51. #include <rpc/clnt.h>
  52. #include <nfs/nfs.h>
  53. #include <setjmp.h>
  54. #include <sys/stat.h>
  55. #include <netdb.h>
  56. #include <sys/socket.h>
  57.  
  58. main(argc, argv)
  59. int argc;
  60. char **argv;
  61. {
  62.     int c, interval = 20, timeout = 5, firsttime = 1;
  63.     extern char *optarg;
  64.     extern int optind, opterr;
  65.  
  66.     while((c = getopt(argc, argv, "i:t:")) != EOF)
  67.     switch(c)
  68.     {
  69.       case 'i':
  70.         interval = atoi(optarg);
  71.         break;
  72.  
  73.       case 't':
  74.         timeout = atoi(optarg);
  75.         break;
  76.  
  77.       case '?':
  78.         usage();
  79.         break;
  80.     }
  81.  
  82.     if((argc - optind) < 3 || ((argc - optind) & 1) == 0)
  83.     usage();
  84.  
  85.     while(1)
  86.     {
  87.     if(nfscheck(argv[optind], timeout) == 0)
  88.         makelinks(&argv[optind+1], firsttime);
  89.     else
  90.         removelinks(&argv[optind+1], firsttime);
  91.  
  92.     firsttime = 0;
  93.     sleep(interval);
  94.     }
  95. }
  96.  
  97. void dodate()
  98. {
  99.     char *tim;
  100.     long *clk;
  101.  
  102.     time(&clk);
  103.     tim = ctime(&clk);
  104.     tim[24] = '\0';        /* lose the linefeed */
  105.  
  106.     printf("nfslink: %s: ", tim);
  107. }
  108.  
  109. makelinks(links, verbose)
  110. char **links;
  111. int verbose;
  112. {
  113.     struct stat namestat;
  114.     
  115.     while(*links)
  116.     {
  117.     char *name = *links++;
  118.     char *mountpt = *links++;
  119.  
  120.     if(lstat(name, &namestat) == -1)
  121.     {
  122.         if(errno == ENOENT)
  123.         {
  124.         if(symlink(mountpt, name) == -1)
  125.         {
  126.             perror("nfslink: symlink");
  127.             fatal("can't link %s to %s\n", name, mountpt);
  128.         }
  129.         dodate();
  130.         printf("linked %s to %s\n", name, mountpt);
  131.         fflush(stdout);
  132.         continue;
  133.         }
  134.         else
  135.         {
  136.         perror("nfslink: lstat");
  137.         fatal("can't lstat %s\n", name, 0);
  138.         }
  139.     }
  140.  
  141.     if((namestat.st_mode & S_IFMT) == S_IFLNK)
  142.     {
  143.         if(pointsto(name, mountpt))
  144.         {
  145.         if(verbose)
  146.         {
  147.             dodate();
  148.             printf("%s is already linked to %s\n",
  149.                name, mountpt);
  150.             fflush(stdout);
  151.         }
  152.         }
  153.         else
  154.         {
  155.         fatal("%s is a link, but not to %s\n", name, mountpt);
  156.         }
  157.     }
  158.     else
  159.     {
  160.         fatal("%s exists, but is not a symbolic link\n", name, 0);
  161.     }
  162.     }
  163. }
  164.  
  165. removelinks(links, verbose)
  166. char **links;
  167. int verbose;
  168. {
  169.     struct stat namestat;
  170.     
  171.     while(*links)
  172.     {
  173.     char *name = *links++;
  174.     char *mountpt = *links++;
  175.  
  176.     if(lstat(name, &namestat) == -1)
  177.     {
  178.         if(errno == ENOENT)
  179.         {
  180.         if(verbose)
  181.         {
  182.             dodate();
  183.             printf("link from %s to %s is already removed\n",
  184.                name, mountpt);
  185.             fflush(stdout);
  186.         }
  187.         continue;
  188.         }
  189.         else
  190.         {
  191.         perror("nfslink: lstat");
  192.         fatal("can't lstat %s\n", name, 0);
  193.         }
  194.     }
  195.  
  196.     if((namestat.st_mode & S_IFMT) == S_IFLNK)
  197.     {
  198.         if(pointsto(name, mountpt))
  199.         {
  200.         if(unlink(name) == -1)
  201.         {
  202.             perror("nfslink: unlink");
  203.             fatal("can't remove link from %s to %s\n",
  204.               name, mountpt);
  205.         }
  206.         dodate();
  207.         printf("removed link from %s to %s\n",
  208.                name, mountpt);
  209.         fflush(stdout);
  210.         }
  211.         else
  212.         {
  213.         fatal("%s is a link, but not to %s\n", name, mountpt);
  214.         }
  215.     }
  216.     else
  217.     {
  218.         fatal("%s exists, but is not a symbolic link\n", name, 0);
  219.     }
  220.     }
  221. }
  222.  
  223. int pointsto(name, target)
  224. char *name, *target;
  225. {
  226.     /* We don't use stat lest it hang, so it's not quite right */
  227.  
  228.     char buf[200];
  229.     int len;
  230.  
  231.     len = readlink(name, buf, sizeof(buf)-1);
  232.     if(len == -1)
  233.     {
  234.     perror("nfslink: readlink");
  235.     fatal("can't read link %s\n", name, 0);
  236.     }
  237.  
  238.     buf[len] = '\0';
  239.     return strcmp(buf, target) == 0;
  240. }
  241.  
  242. fatal(fmt, arg1, arg2)
  243. char *fmt, *arg1, *arg2;
  244. {
  245.     fprintf(stderr, "nfslink: fatal error: ");
  246.     fprintf(stderr, fmt, arg1, arg2);
  247.     exit(1);
  248. }
  249.  
  250. usage()
  251. {
  252.     fprintf(stderr, "usage: nfslink [-i interval] [-t timeout] host name mountpt [name mountpt ...]\n");
  253.     exit(2);
  254. }
  255.  
  256. int nfscheck(host, timeout)
  257. char *host;
  258. int timeout;
  259. {
  260.     int stat, sock= RPC_ANYSOCK;
  261.     struct hostent *server;
  262.     struct sockaddr_in sin;
  263.     CLIENT *client;
  264.     struct timeval try, total;
  265.  
  266.     server = gethostbyname(host);
  267.     if(!server)
  268.     {
  269.     fprintf(stderr, "nfslink: unknown host %s\n", host);
  270.     return -1;
  271.     }
  272.  
  273.     bcopy(server->h_addr, &sin.sin_addr, server->h_length);
  274.     sin.sin_family = AF_INET;
  275.     sin.sin_port = 2049;    /* avoid calling portmapper */
  276.  
  277.     try.tv_sec = 1;
  278.     try.tv_usec = 0;
  279.  
  280.     client = clntudp_create(&sin, NFS_PROGRAM, NFS_VERSION,
  281.                 try, &sock);
  282.     if(!client)
  283.     return -1;
  284.  
  285.     total.tv_sec = timeout;
  286.     total.tv_usec = 0;
  287.  
  288.     stat = clnt_call(client, RFS_NULL, xdr_void, 0, xdr_void, 0, total);
  289.  
  290.     clnt_destroy(client);
  291.  
  292.     if(stat != RPC_SUCCESS)
  293.     return -1;
  294.  
  295.     return 0;
  296. }
  297.  
  298.  
  299. -- 
  300. Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
  301. AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
  302. Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin
  303.