
From: Jeff Dike <jdike@addtoit.com>

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 <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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;
_
