Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Jul 2006 18:35:02 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 102013 for review
Message-ID:  <200607201835.k6KIZ22r034916@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102013

Change 102013 by jhb@jhb_mutex on 2006/07/20 18:34:19

	- Add functions to init and destroy the svr4 socket cache and call
	  them from the svr4 module eventhandler.  Setup the TAILQ and mutex
	  in these routines.
	- Rename the mutex to a better name.
	- Add an eventhandler for process exit and exec that removes any
	  entries for the given process from the cache.
	- Sort prototypes in svr4_socket.h.

Affected files ...

.. //depot/projects/smpng/sys/compat/svr4/svr4_socket.c#15 edit
.. //depot/projects/smpng/sys/compat/svr4/svr4_socket.h#9 edit
.. //depot/projects/smpng/sys/compat/svr4/svr4_sysvec.c#21 edit
.. //depot/projects/smpng/sys/notes#85 edit

Differences ...

==== //depot/projects/smpng/sys/compat/svr4/svr4_socket.c#15 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/queue.h>
+#include <sys/eventhandler.h>
 #include <sys/file.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
@@ -75,10 +76,11 @@
 	TAILQ_ENTRY(svr4_sockcache_entry) entries;
 };
 
-static TAILQ_HEAD(, svr4_sockcache_entry) svr4_head =
-    TAILQ_HEAD_INITIALIZER(svr4_head);
-static struct mtx svr4_head_lock;
-MTX_SYSINIT(svr4_head_lock, &svr4_head_lock, "svr4_head", MTX_DEF);
+static TAILQ_HEAD(, svr4_sockcache_entry) svr4_head;
+static struct mtx svr4_sockcache_lock;
+static eventhandler_tag svr4_sockcache_exit_tag, svr4_sockcache_exec_tag;
+
+static void	svr4_purge_sockcache(void *arg, struct proc *p);
 
 int
 svr4_find_socket(td, fp, dev, ino, saun)
@@ -92,7 +94,7 @@
 	void *cookie = ((struct socket *)fp->f_data)->so_emuldata;
 
 	DPRINTF(("svr4_find_socket: [%p,%d,%d]: ", td, dev, ino));
-	mtx_lock(&svr4_head_lock);
+	mtx_lock(&svr4_sockcache_lock);
 	TAILQ_FOREACH(e, &svr4_head, entries)
 		if (e->p == td->td_proc && e->dev == dev && e->ino == ino) {
 #ifdef DIAGNOSTIC
@@ -102,11 +104,11 @@
 			e->cookie = cookie;
 			DPRINTF(("%s\n", e->sock.sun_path));
 			*saun = e->sock;
-			mtx_unlock(&svr4_head_lock);
+			mtx_unlock(&svr4_sockcache_lock);
 			return (0);
 		}
 
-	mtx_unlock(&svr4_head_lock);
+	mtx_unlock(&svr4_sockcache_lock);
 	DPRINTF(("not found\n"));
 	return (ENOENT);
 }
@@ -136,9 +138,9 @@
 	e->sock.sun_family = AF_LOCAL;
 	e->sock.sun_len = len;
 
-	mtx_lock(&svr4_head_lock);
+	mtx_lock(&svr4_sockcache_lock);
 	TAILQ_INSERT_HEAD(&svr4_head, e, entries);
-	mtx_unlock(&svr4_head_lock);
+	mtx_unlock(&svr4_sockcache_lock);
 	DPRINTF(("svr4_add_socket: %s [%p,%d,%d]\n", e->sock.sun_path,
 		 td->td_proc, e->dev, e->ino));
 	return 0;
@@ -152,17 +154,59 @@
 	struct svr4_sockcache_entry *e;
 	void *cookie = ((struct socket *)fp->f_data)->so_emuldata;
 
-	mtx_lock(&svr4_head_lock);
+	mtx_lock(&svr4_sockcache_lock);
 	TAILQ_FOREACH(e, &svr4_head, entries)
 		if (e->p == p && e->cookie == cookie) {
 			TAILQ_REMOVE(&svr4_head, e, entries);
-			mtx_unlock(&svr4_head_lock);
+			mtx_unlock(&svr4_sockcache_lock);
 			DPRINTF(("svr4_delete_socket: %s [%p,%d,%d]\n",
 				 e->sock.sun_path, p, (int)e->dev, e->ino));
 			free(e, M_TEMP);
 			return;
 		}
-	mtx_unlock(&svr4_head_lock);
+	mtx_unlock(&svr4_sockcache_lock);
+}
+
+void
+svr4_purge_sockcache(arg, p)
+	void *arg;
+	struct proc *p;
+{
+	struct svr4_sockcache_entry *e, *ne;
+
+	mtx_lock(&svr4_sockcache_lock);
+	TAILQ_FOREACH_SAFE(e, &svr4_head, entries, ne) {
+		if (e->p == p) {
+			TAILQ_REMOVE(&svr4_head, e, entries);
+			DPRINTF(("svr4_purge_sockcache: %s [%p,%d,%d]\n",
+				 e->sock.sun_path, p, (int)e->dev, e->ino));
+			free(e, M_TEMP);
+		}
+	}
+	mtx_unlock(&svr4_sockcache_lock);
+}
+
+void
+svr4_sockcache_init(void)
+{
+
+	TAILQ_INIT(&svr4_head);
+	mtx_init(&svr4_sockcache_lock, "svr4 socket cache", NULL, MTX_DEF);
+	svr4_sockcache_exit_tag = EVENTHANDLER_REGISTER(process_exit,
+	    svr4_purge_sockcache, NULL, EVENTHANDLER_PRI_ANY);
+	svr4_sockcache_exec_tag = EVENTHANDLER_REGISTER(process_exec,
+	    svr4_purge_sockcache, NULL, EVENTHANDLER_PRI_ANY);
+}
+
+void
+svr4_sockcache_destroy(void)
+{
+
+	KASSERT(TAILQ_EMPTY(&svr4_head),
+	    ("%s: sockcache entries still around", __func__));
+	EVENTHANDLER_DEREGISTER(process_exec, svr4_sockcache_exec_tag);
+	EVENTHANDLER_DEREGISTER(process_exit, svr4_sockcache_exit_tag);
+	mtx_destroy(&svr4_sockcache_lock);
 }
 
 int

==== //depot/projects/smpng/sys/compat/svr4/svr4_socket.h#9 (text+ko) ====

@@ -48,9 +48,11 @@
         u_char         sin_zero[8];
 };
 
+int	svr4_add_socket(struct thread *, const char *, struct stat *);
+void	svr4_delete_socket(struct proc *, struct file *);
 int	svr4_find_socket(struct thread *, struct file *, dev_t, ino_t,
     struct sockaddr_un *);
-void	svr4_delete_socket(struct proc *, struct file *);
-int	svr4_add_socket(struct thread *, const char *, struct stat *);
+void	svr4_sockcache_init(void);
+void	svr4_sockcache_destroy(void);
 
 #endif /* _SVR4_SOCKET_H_ */

==== //depot/projects/smpng/sys/compat/svr4/svr4_sysvec.c#21 (text+ko) ====

@@ -62,6 +62,7 @@
 #include <compat/svr4/svr4_types.h>
 #include <compat/svr4/svr4_syscall.h>
 #include <compat/svr4/svr4_signal.h>
+#include <compat/svr4/svr4_socket.h>
 #include <compat/svr4/svr4_sockio.h>
 #include <compat/svr4/svr4_errno.h>
 #include <compat/svr4/svr4_proto.h>
@@ -269,12 +270,14 @@
 
 	switch(type) {
 	case MOD_LOAD:
-		if (elf32_insert_brand_entry(&svr4_brand) < 0)
+		if (elf32_insert_brand_entry(&svr4_brand) < 0) {
+			printf("cannot insert svr4 elf brand handler\n");
 			error = EINVAL;
-		if (error)
-			printf("cannot insert svr4 elf brand handler\n");
-		else if (bootverbose)
+			break;
+		}
+		if (bootverbose)
 			printf("svr4 ELF exec handler installed\n");
+		svr4_sockcache_init();
 		break;
 	case MOD_UNLOAD:
 		/* Only allow the emulator to be removed if it isn't in use. */
@@ -284,11 +287,14 @@
 			error = EINVAL;
 		}
 
-		if (error)
+		if (error) {
 			printf("Could not deinstall ELF interpreter entry (error %d)\n",
 			       error);
-		else if (bootverbose)
+			break;
+		}
+		if (bootverbose)
 			printf("svr4 ELF exec handler removed\n");
+		svr4_sockcache_destroy();
 		break;
 	default:
 		return (EOPNOTSUPP);

==== //depot/projects/smpng/sys/notes#85 (text+ko) ====

@@ -88,7 +88,8 @@
 	  - need to see where this is called and see if all of the files
 	    should already have f_ops set correctly and if we can just
 	    allocate so_emuldata directly in streamsopen()
-	  - XXX: svr4_add_socket() can add duplicates?
+	  + XXX: svr4_add_socket() can add duplicates?  it's ok, just
+	    purge them all on process exit or exec
 	  + change svr4_find_socket() to copy the sockaddr out to a
 	    passed in sockaddr_un and return bool
 	- svr4_sys_ioctl()



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607201835.k6KIZ22r034916>