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>