From: Jeff Dike This process closes some file descriptors which were left open incorrectly. These are the initrd descriptor, the temporary test file used for testing /tmp for execution permission, and a descriptor used by the netork to connect to the switch. In the network case, we add network devices to the opened list as soon as they are added to UML, rather than when they are configured. This ensures that close_devices will remove the device properly on shutdown. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton --- 25-akpm/arch/um/drivers/net_kern.c | 17 ++++++++--------- 25-akpm/arch/um/kernel/initrd_user.c | 2 ++ 25-akpm/arch/um/kernel/mem_user.c | 2 ++ 3 files changed, 12 insertions(+), 9 deletions(-) diff -puN arch/um/drivers/net_kern.c~uml-close-host-file-descriptors-properly arch/um/drivers/net_kern.c --- 25/arch/um/drivers/net_kern.c~uml-close-host-file-descriptors-properly 2004-12-12 02:23:12.025338616 -0800 +++ 25-akpm/arch/um/drivers/net_kern.c 2004-12-12 02:23:12.035337096 -0800 @@ -126,10 +126,6 @@ static int uml_net_open(struct net_devic lp->tl.data = (unsigned long) &lp->user; netif_start_queue(dev); - spin_lock(&opened_lock); - list_add(&lp->list, &opened); - spin_unlock(&opened_lock); - /* clear buffer - it can happen that the host side of the interface * is full when we get here. In this case, new data is never queued, * SIGIOs never arrive, and the net never works. @@ -150,11 +146,9 @@ static int uml_net_close(struct net_devi free_irq_by_irq_and_dev(dev->irq, dev); free_irq(dev->irq, dev); - if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); + if(lp->close != NULL) + (*lp->close)(lp->fd, &lp->user); lp->fd = -1; - spin_lock(&opened_lock); - list_del(&lp->list); - spin_unlock(&opened_lock); spin_unlock(&lp->lock); return 0; @@ -397,6 +391,11 @@ static int eth_configure(int n, void *in if (device->have_mac) set_ether_mac(dev, device->mac); + + spin_lock(&opened_lock); + list_add(&lp->list, &opened); + spin_unlock(&opened_lock); + return(0); } @@ -705,7 +704,7 @@ __initcall(uml_net_init); static void close_devices(void) { struct list_head *ele; - struct uml_net_private *lp; + struct uml_net_private *lp; list_for_each(ele, &opened){ lp = list_entry(ele, struct uml_net_private, list); diff -puN arch/um/kernel/initrd_user.c~uml-close-host-file-descriptors-properly arch/um/kernel/initrd_user.c --- 25/arch/um/kernel/initrd_user.c~uml-close-host-file-descriptors-properly 2004-12-12 02:23:12.027338312 -0800 +++ 25-akpm/arch/um/kernel/initrd_user.c 2004-12-12 02:23:12.036336944 -0800 @@ -29,6 +29,8 @@ int load_initrd(char *filename, void *bu filename, -n); return(-1); } + + os_close_file(fd); return(0); } diff -puN arch/um/kernel/mem_user.c~uml-close-host-file-descriptors-properly arch/um/kernel/mem_user.c --- 25/arch/um/kernel/mem_user.c~uml-close-host-file-descriptors-properly 2004-12-12 02:23:12.030337856 -0800 +++ 25-akpm/arch/um/kernel/mem_user.c 2004-12-12 02:23:12.036336944 -0800 @@ -101,6 +101,8 @@ void check_tmpexec(void) } printf("OK\n"); munmap(addr, UM_KERN_PAGE_SIZE); + + os_close_file(fd); } static int have_devanon = 0; _