On Sun, Jan 29, 2006 at 02:27:42PM +0100, Robert Hillen wrote:
> Thanks Jeff. Your patch seems to fix the problem partly, but I still get
> the "device busy" error because the tun device still remains attached to
> one process after eth0 is disabled in the uml.

Can you try the attached patch, which replaces the earlier one?

                                Jeff
Index: linux-2.6.15-mm/arch/um/os-Linux/drivers/tuntap_user.c
===================================================================
--- linux-2.6.15-mm.orig/arch/um/os-Linux/drivers/tuntap_user.c 2006-01-29 
22:33:36.000000000 -0500
+++ linux-2.6.15-mm/arch/um/os-Linux/drivers/tuntap_user.c      2006-01-29 
22:37:49.000000000 -0500
@@ -122,6 +122,7 @@ static int tuntap_open_tramp(char *gate,
                return(-EINVAL);
        }
        *fd_out = ((int *) CMSG_DATA(cmsg))[0];
+       os_set_exec_close(*fd_out, 1);
        return(0);
 }
 
@@ -137,7 +138,8 @@ static int tuntap_open(void *data)
                return(err);
 
        if(pri->fixed_config){
-               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
+               pri->fd = os_open_file("/dev/net/tun",
+                                      of_cloexec(of_rdwr(OPENFLAGS())), 0);
                if(pri->fd < 0){
                        printk("Failed to open /dev/net/tun, err = %d\n",
                               -pri->fd);
Index: linux-2.6.15-mm/arch/um/drivers/chan_user.c
===================================================================
--- linux-2.6.15-mm.orig/arch/um/drivers/chan_user.c    2006-01-03 
17:39:46.000000000 -0500
+++ linux-2.6.15-mm/arch/um/drivers/chan_user.c 2006-01-30 14:14:13.000000000 
-0500
@@ -9,6 +9,7 @@
 #include <termios.h>
 #include <string.h>
 #include <signal.h>
+#include <sched.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -73,7 +74,6 @@ static void winch_handler(int sig)
 struct winch_data {
        int pty_fd;
        int pipe_fd;
-       int close_me;
 };
 
 static int winch_thread(void *arg)
@@ -84,7 +84,6 @@ static int winch_thread(void *arg)
        int count, err;
        char c = 1;
 
-       os_close_file(data->close_me);
        pty_fd = data->pty_fd;
        pipe_fd = data->pipe_fd;
        count = os_write_file(pipe_fd, &c, sizeof(c));
@@ -153,15 +152,16 @@ static int winch_tramp(int fd, struct tt
        }
 
        data = ((struct winch_data) { .pty_fd           = fd,
-                                     .pipe_fd          = fds[1],
-                                     .close_me         = fds[0] } );
-       err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+                                     .pipe_fd          = fds[1] } );
+       /* CLONE_FILES so this thread doesn't hold open files which are open
+        * now, but later closed.  This is a problem with /dev/net/tun.
+        */
+       err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
        if(err < 0){
                printk("fork of winch_thread failed - errno = %d\n", errno);
                goto out_close;
        }
 
-       os_close_file(fds[1]);
        *fd_out = fds[0];
        n = os_read_file(fds[0], &c, sizeof(c));
        if(n != sizeof(c)){
@@ -169,13 +169,12 @@ static int winch_tramp(int fd, struct tt
                printk("read failed, err = %d\n", -n);
                printk("fd %d will not support SIGWINCH\n", fd);
                 err = -EINVAL;
-               goto out_close1;
+               goto out_close;
        }
        return err ;
 
  out_close:
        os_close_file(fds[1]);
- out_close1:
        os_close_file(fds[0]);
  out:
        return err;

Reply via email to