correctly close nfs mounts when we shutdown

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey list:

Was doing some work for rhel4 (#208103) in the loader department and was wondering if the idea of putting it into rawhide would be a good one.  The basic idea is to add some function to tell the nfs server that we no longer need the shared directory.  In the case of the rhel4 patch, I used the nfs_umount_rpc_call function from the util-linux rhel4 package.
Haven't gone into detail on rawhide or rhel5 and before I do, I would like some feedback from the community.  specially since we did some mount changes in the installer.  I really doubt that that would affect the init script, but I could be wrong.

So: How relevant do you think closing the nfs mount at shutdown is? patch attached. (the rhel4 one)

--
Joel Andres Granados
Red Hat / Brno, Czech Republic
diff --git a/loader2/undomounts.c b/loader2/undomounts.c
index 07892af..f17532a 100644
--- a/loader2/undomounts.c
+++ b/loader2/undomounts.c
@@ -27,11 +27,13 @@
 #include <sys/stat.h>
 #include <sys/swap.h>
 #include <unistd.h>
-
 #include "devt.h"
+#include "nfsmount.h"
 
 struct unmountInfo {
     char * name;
+    char * fstype;
+    char * device;
     int mounted;
     int loopDevice;
     enum { FS, LOOP } what;
@@ -45,6 +47,89 @@ static void printstr(char * string) {
     write(1, string, strlen(string));
 }
 
+static int xdr_dir(XDR *xdrsp, char *dirp)
+{
+      return (xdr_string(xdrsp, &dirp, MNTPATHLEN));
+}
+
+static int
+nfs_umount_rpc_call(const char *spec, const char *opts)
+{
+      register CLIENT *clp;
+      struct sockaddr_in saddr;
+      struct timeval pertry, try;
+      enum clnt_stat clnt_stat;
+      int port = 0;
+      int so = RPC_ANYSOCK;
+      struct hostent *hostp;
+      char *hostname;
+      char *dirname;
+      char *p;
+      char *tmp;
+
+      if (spec == NULL || (p = strchr(spec,':')) == NULL)
+		return 0;
+      tmp = strdup(spec);
+      hostname = strtok(tmp, ":");
+      dirname = strtok(NULL, ":");
+
+      if (opts && (p = strstr(opts, "addr="))) {
+	   char *q;
+
+	   free(hostname);
+           tmp = strdup(p);
+           strtok(tmp, "= ,");
+           hostname = strtok(NULL, "= ,");
+      }
+
+      if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10)))
+	   port = atoi(p+10);
+
+      sleep(5);
+      if (hostname[0] >= '0' && hostname[0] <= '9'){
+	   saddr.sin_addr.s_addr = inet_addr(hostname);
+      } else {
+	   if (mygethostbyname(hostname, &saddr.sin_addr) < 0) 
+		return 1;
+      }
+
+      saddr.sin_family = AF_INET;
+      saddr.sin_port = htons(port);
+      pertry.tv_sec = 3;
+      pertry.tv_usec = 0;
+      if (opts && (p = strstr(opts, "tcp"))) {
+	   /* possibly: make sure option is not "notcp"
+	      possibly: try udp if tcp fails */
+	   if ((clp = clnttcp_create(&saddr, MOUNTPROG, MOUNTVERS,
+				     &so, 0, 0)) == NULL) {
+		clnt_pcreateerror("Cannot MOUNTPROG RPC (tcp)");
+		return 1;
+	   }
+      } else {
+           if ((clp = clntudp_create(&saddr, MOUNTPROG, MOUNTVERS,
+				     pertry, &so)) == NULL) {
+		clnt_pcreateerror("Cannot MOUNTPROG RPC");
+		return 1;
+	   }
+      }
+      clp->cl_auth = authunix_create_default();
+      try.tv_sec = 20;
+      try.tv_usec = 0;
+      clnt_stat = clnt_call(clp, MOUNTPROC_UMNT,
+			    (xdrproc_t) xdr_dir, dirname,
+			    (xdrproc_t) xdr_void, (caddr_t) 0,
+			    try);
+
+      if (clnt_stat != RPC_SUCCESS) {
+	   clnt_perror(clp, "Bad UMNT RPC");
+	   return 1;
+      }
+      auth_destroy(clp->cl_auth);
+      clnt_destroy(clp);
+
+      return 0;
+}
+
 void undoMount(struct unmountInfo * fs, int numFs, int this) {
     int len = strlen(fs[this].name);
     int i;
@@ -67,11 +152,19 @@ void undoMount(struct unmountInfo * fs, int numFs, int this) {
     printf("\t%s", fs[this].name);
     /* don't need to unmount /tmp.  it is busy anyway. */
     if (!testing) {
-	if (umount2(fs[this].name, 0) < 0) {
-	    printf(" umount failed (%d)", errno);
-	} else {
-	    printf(" done");
-	}
+        sleep(2);
+        if(strcmp(fs[this].fstype, "nfs") == 0){
+            if(nfs_umount_rpc_call(fs[this].device, "") != 0){
+                printf(" umount failed (%d)", errno);
+            }else{
+                printf(" done");
+            }
+        } else{
+            if (umount2(fs[this].name, 0) < 0) 
+                printf(" umount failed (%d)", errno);
+            else
+                printf(" done");
+        }
     }
     printf("\n");
 }
@@ -112,12 +205,11 @@ void undoLoop(struct unmountInfo * fs, int numFs, int this) {
 void unmountFilesystems(void) {
     int fd, size;
     char buf[65535];			/* this should be big enough */
-    char * chptr, * start;
+    char * chptr, * start, * device, * fst;
     struct unmountInfo filesystems[500];
     int numFilesystems = 0;
     int i;
     struct loop_info li;
-    char * device;
     struct stat sb;
 
     fd = open("/proc/mounts", O_RDONLY, 0);
@@ -141,11 +233,16 @@ void unmountFilesystems(void) {
 	start = chptr;
 	while (*chptr != ' ') chptr++;
 	*chptr++ = '\0';
+        fst = chptr;
+        while (*chptr != ' ') chptr++;
+        *chptr++ = '\0';
 
 	if (strcmp(start, "/") && strcmp(start, "/tmp")) {
 	    filesystems[numFilesystems].name = strdup(start);
 	    filesystems[numFilesystems].what = FS;
 	    filesystems[numFilesystems].mounted = 1;
+            filesystems[numFilesystems].fstype = strdup(fst);
+            filesystems[numFilesystems].device = strdup(device);
 
 	    stat(start, &sb);
 	    if ((sb.st_dev >> 8) == 7) {
_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux