diff options
| author | Marko Zec <zec@FreeBSD.org> | 2009-04-30 13:36:26 +0000 |
|---|---|---|
| committer | Marko Zec <zec@FreeBSD.org> | 2009-04-30 13:36:26 +0000 |
| commit | f6dfe47a145263dc5eb67fa4789925ab708709bc (patch) | |
| tree | 47044959fbe0bb326af1b89e4cd6b6798fc96fa1 /sys/kern | |
| parent | 65710fd2d2fd8f687713b46bd8eb37042ec8e2f5 (diff) | |
Notes
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/kern_mib.c | 6 | ||||
| -rw-r--r-- | sys/kern/kern_sysctl.c | 100 | ||||
| -rw-r--r-- | sys/kern/kern_vimage.c | 30 | ||||
| -rw-r--r-- | sys/kern/uipc_socket.c | 4 |
4 files changed, 133 insertions, 7 deletions
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c index 80c1789ad8e9..05f90310ea09 100644 --- a/sys/kern/kern_mib.c +++ b/sys/kern/kern_mib.c @@ -208,9 +208,8 @@ static char machine_arch[] = MACHINE_ARCH; SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD, machine_arch, 0, "System architecture"); -#ifndef VIMAGE +/* should become #ifndef VIMAGE */ char hostname[MAXHOSTNAMELEN]; -#endif /* * This mutex is used to protect the hostname and domainname variables, and @@ -349,9 +348,8 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RW, 0, 0, sysctl_kern_config, "", "Kernel configuration file"); #endif -#ifndef VIMAGE +/* should become #ifndef VIMAGE */ char domainname[MAXHOSTNAMELEN]; /* Protected by hostname_mtx. */ -#endif static int sysctl_domainname(SYSCTL_HANDLER_ARGS) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index d39db26ea124..b69ac8f95ed5 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -934,6 +934,30 @@ sysctl_handle_int(SYSCTL_HANDLER_ARGS) return (error); } +#ifdef VIMAGE +int +sysctl_handle_v_int(SYSCTL_HANDLER_ARGS) +{ + int tmpout, error = 0; + + SYSCTL_RESOLVE_V_ARG1(); + + /* + * Attempt to get a coherent snapshot by making a copy of the data. + */ + tmpout = *(int *)arg1; + error = SYSCTL_OUT(req, &tmpout, sizeof(int)); + + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else + error = SYSCTL_IN(req, arg1, sizeof(int)); + return (error); +} +#endif /* * Based on on sysctl_handle_int() convert milliseconds into ticks. @@ -944,7 +968,9 @@ sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS) { int error, s, tt; - tt = *(int *)oidp->oid_arg1; + SYSCTL_RESOLVE_V_ARG1(); + + tt = *(int *)arg1; s = (int)((int64_t)tt * 1000 / hz); error = sysctl_handle_int(oidp, &s, 0, req); @@ -955,7 +981,7 @@ sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS) if (tt < 1) return (EINVAL); - *(int *)oidp->oid_arg1 = tt; + *(int *)arg1 = tt; return (0); } @@ -1069,6 +1095,47 @@ retry: return (error); } +#ifdef VIMAGE +int +sysctl_handle_v_string(SYSCTL_HANDLER_ARGS) +{ + int error=0; + char *tmparg; + size_t outlen; + + SYSCTL_RESOLVE_V_ARG1(); + + /* + * Attempt to get a coherent snapshot by copying to a + * temporary kernel buffer. + */ +retry: + outlen = strlen((char *)arg1)+1; + tmparg = malloc(outlen, M_SYSCTLTMP, M_WAITOK); + + if (strlcpy(tmparg, (char *)arg1, outlen) >= outlen) { + free(tmparg, M_SYSCTLTMP); + goto retry; + } + + error = SYSCTL_OUT(req, tmparg, outlen); + free(tmparg, M_SYSCTLTMP); + + if (error || !req->newptr) + return (error); + + if ((req->newlen - req->newidx) >= arg2) { + error = EINVAL; + } else { + arg2 = (req->newlen - req->newidx); + error = SYSCTL_IN(req, arg1, arg2); + ((char *)arg1)[arg2] = '\0'; + } + + return (error); +} +#endif + /* * Handle any kind of opaque data. * arg1 points to it, arg2 is the size. @@ -1106,6 +1173,35 @@ retry: return (error); } +#ifdef VIMAGE +int +sysctl_handle_v_opaque(SYSCTL_HANDLER_ARGS) +{ + int error, tries; + u_int generation; + struct sysctl_req req2; + + SYSCTL_RESOLVE_V_ARG1(); + + tries = 0; + req2 = *req; +retry: + generation = curthread->td_generation; + error = SYSCTL_OUT(req, arg1, arg2); + if (error) + return (error); + tries++; + if (generation != curthread->td_generation && tries < 3) { + *req = req2; + goto retry; + } + + error = SYSCTL_IN(req, arg1, arg2); + + return (error); +} +#endif + /* * Transfer functions to/from kernel space. * XXX: rather untested at this point diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index 156efec06182..310e328f7fea 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #ifndef VIMAGE_GLOBALS MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container"); +MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head; static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; @@ -49,6 +50,12 @@ static void vnet_mod_complete_registration(struct vnet_modlink *); static int vnet_mod_constructor(struct vnet_modlink *); static int vnet_mod_destructor(struct vnet_modlink *); +#ifdef VIMAGE +/* curvnet should be thread-local - this is only a temporary step. */ +struct vnet *curvnet; +struct vnet_list_head vnet_head; +#endif + void vnet_mod_register(const struct vnet_modinfo *vmi) { @@ -263,7 +270,14 @@ vi_symlookup(struct kld_sym_lookup *lookup, char *symstr) for (mapentry = vml->vml_modinfo->vmi_symmap; mapentry->name != NULL; mapentry++) { if (strcmp(symstr, mapentry->name) == 0) { - lookup->symvalue = (u_long) mapentry->base; +#ifdef VIMAGE + lookup->symvalue = + (u_long) curvnet->mod_data[ + vml->vml_modinfo->vmi_id]; + lookup->symvalue += mapentry->offset; +#else + lookup->symvalue = (u_long) mapentry->offset; +#endif lookup->symsize = mapentry->size; return (0); } @@ -275,9 +289,23 @@ vi_symlookup(struct kld_sym_lookup *lookup, char *symstr) static void vi_init(void *unused) { +#ifdef VIMAGE + struct vnet *vnet; +#endif TAILQ_INIT(&vnet_modlink_head); TAILQ_INIT(&vnet_modpending_head); + +#ifdef VIMAGE + LIST_INIT(&vnet_head); + + vnet = malloc(sizeof(struct vnet), M_VNET, M_NOWAIT | M_ZERO); + if (vnet == NULL) + panic("vi_alloc: malloc failed"); + LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); + + curvnet = LIST_FIRST(&vnet_head); +#endif } static void diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 9d9a73187c0d..a2f7c056e384 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -130,6 +130,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/uio.h> #include <sys/jail.h> +#include <sys/vimage.h> #include <security/mac/mac_framework.h> @@ -284,6 +285,9 @@ soalloc(void) mtx_lock(&so_global_mtx); so->so_gencnt = ++so_gencnt; ++numopensockets; +#ifdef VIMAGE + so->so_vnet = curvnet; +#endif mtx_unlock(&so_global_mtx); return (so); } |
