Thread: NFS timeout problem

  1. #1
    Registered User
    Join Date
    Aug 2002
    Posts
    351

    NFS timeout problem

    Hi All,

    I have some code that is require to chdir(2) to a directory. If the chdir(2) fails, create it.

    Now this directory is on an NFS mount. These are 'hard' linked!

    If the remote NFS server is not running (for whatever reason), the code will hang on chdir. I've tried to use an alarm timeout around the chdir call, but this seems to be handled.

    Does anyone suggest using select(2)? If so, whats the best way to obtain a file descriptor with which to wait on?

    TIA, rotis23
    Last edited by rotis23; 10-20-2003 at 10:20 AM.

  2. #2
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    some code maybe:
    Code:
    #include        <sys/stat.h>
    #include        <signal.h>
    
    void timed_out(){}
    
    int main()
    {
            int timeout = 5,check_in = 0;
            int *ch_res = NULL;
            struct sigaction action;
    
            bzero(&action, sizeof(action));
            action.sa_handler = timed_out;
            action.sa_flags = 0;
            sigaction(SIGALRM, &action, 0);
    
            char *h = "/tmp/test/dir/";
    
            alarm(timeout);
            ch_res = (int*)malloc(sizeof(int) * 1);
            printf("set timeout; attempting to chdir to %s\n",h);
            //try and chdir to broken nfs directory
            ch_res[0] = chdir(h);
            if(ch_res)printf("got result from chdir - %d\n",ch_res[0]);
            alarm(0);
    
            if(!ch_res)
            {
                    printf("timeout whilst changing to directory %s - NFS problem?\n",h);
                    free(ch_res);
                    exit(1);
            }
    
                    if (ch_res[0] < 0)
                    {
                            printf("Creating directory %s\n",h);
    
                            if(mkdir(h, 0755))
                            {
                                    printf("Error making directory %s\n",h);
                                    exit(1);
                            }
                            else
                            {
                                    printf("Made directory %s\n",h);
                            }
    
                            //try again
                            if (chdir(h) < 0)
                            {
                                    printf("Error changing to directory %s\n",h);
                                    exit(1);
                            }
                    }
            free(ch_res);
    
            exit(0);
    }

  3. #3
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    OK, I've found out some more info.

    According to the man page for mount_nfs I am already passing the intr flag to allow keyboard interrupts; specifically SIGQUIT and SIGINT.

    So, all I need to do is fork, wait and send my process a SIGINT signal.

    Do others agree?

  4. #4
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    This is the answer - it can use a timeout on hard mounted nfs mounted directories.

    It uses fork(2), pipe(2), child(2) and kill(2) to create a child that attempts to use the mount.

    The parent uses select to set a timeout and listen to a pipe for a successful child response.

    Remember to use the intr flag when mounting nfs shares!
    Code:
    #include        <sys/stat.h>
    #include        <signal.h>
    #include <stdio.h>
    #include <time.h>
    
    
    void timed_out(){}
    
    int main()
    {
            int timeout = 5,check_in = 0;
            int ch_res;
            struct sigaction action;
            FILE *temp_file = NULL;
            int fd,rc,error;
            int fds[2];
            fd_set fdset;
            struct timeval t;
            pid_t child;
    
            char *h = "/var/tmp/nfs/mount/somewhere/";
    
            if(pipe(fds) != 0)
            {
                    return NULL;
            }
            child = fork();
            if(child == -1)
            {
                    printf("Error forking child\n");
                    exit(1);
            }
    
            if( child == 0 )
            {
                    char *buf = "ok";
                    printf("Child attempting to chdir\n");
                    chdir(h);
                    printf("Child writing to pipe\n");
                    write(fds[1],buf,3);
                    close(fds[0]);
                    close(fds[1]);
                    printf("Child exiting normally\n");
                    exit(0);
            }
            else
            {
                    t.tv_sec  = timeout;
                    t.tv_usec = 0;
                    FD_ZERO(&fdset);
                    FD_SET(fds[0], &fdset);
    
                    rc = select(fds[0] + 1,&fdset,NULL,NULL,&t);
    
                    if(rc == -1)
                    {
                            printf("Error in select\n");
                            close(fds[0]);
                            close(fds[1]);
                            exit(1);
                    }
                    else if(rc == 0)
                    {
                            printf("Timeout - possible nfs error\n");
                            kill(child,SIGINT);
                            close(fds[0]);
                            close(fds[1]);
                            exit(1);
                    }
                    else if(FD_ISSET(fds[0],&fdset))
                    {
                            printf("Got a response, nfs ok\n");
                            //close all stuff
                            close(fds[0]);
                            close(fds[1]);
                    }
            }
    
            ch_res = chdir(h);
    
            if (ch_res < 0)
            {
                    printf("Creating directory %s\n",h);
    
                    if(mkdir(h, 0755))
                    {
                            printf("Error making directory %s\n",h);
                            exit(1);
                    }
                    else
                    {
                            printf("Made directory %s\n",h);
                    }
    
                    if (chdir(h) < 0)
                    {
                            printf("Error changing to directory %s\n",h);
                            exit(1);
                    }
            }
            else
            {
                    printf("Changed directory successfully %d\n",ch_res);
            }
    
            exit(0);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM