warning of pending commit attempt.
Marko Zec
zec at icir.org
Thu Feb 28 14:31:38 UTC 2008
On Thursday 28 February 2008 14:17:04 Dag-Erling Smørgrav wrote:
> Marko Zec <zec at icir.org> writes:
> > [about vimage]
>
> One thing you haven't mentioned is sysctl. I've always been of the
> opinion that if we virtualize one part of the system, we should also
> virtualize the sysctl tree. This does not mean that each vimage
> should have its own copy of the entire tree, but rather that it
> should be possible to mark some sysctl nodes as virtualized. For
> instance, it would be useful on amd64 to be able to create an i386
> vimage, where hw.machine and hw.machine_arch would be "i386".
>
> For PROC nodes, of course, this is easily done (as you already do)
> with INIT_VPROCG(TD_TO_VPROGC(curthread)), but the basic node types
> (int, long, string etc.) are a little trickier, and don't seem to be
> handled in your patch.
Actually the patch provides certain level of support for virtualizing
leaf sysctl nodes. So far I have only introduced macros for methods /
data types that I've found necessary to virtualize, such as
SYSCTL_V_OID, SYSCTL_V_STRING, SYSCTL_V_INT, and SYSCTL_V_PROC.
Instead of embedding a "pointer" to the variable that a sysctl needs to
control into the linker set that standard SYSCTL macros create, the
SYSCTL_V macros embed an ID of the virtualization container / strucrure
where the data has to be resolved, and an offset inside such a
structure.
Here's a randomly picked example from a recent diff:
+#ifndef VIMAGE
struct icmpstat icmpstat;
-SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RW,
- &icmpstat, icmpstat, "");
+#endif
+SYSCTL_V_STRUCT(V_NET, vnet_inet, _net_inet_icmp, ICMPCTL_STATS, stats,
+ CTLFLAG_RW, icmpstat, icmpstat, "");
So the latter macro will embedd an offsetof(struct vnet_inet, _icmpstat)
somewhere in the resulting linker set structure, with V_NET telling us
that we are resolving a networking symbol, and vnet_inet will also be
translated to an ID determining in which networking submodule to
resolve the address.
The above sysctl will be handled by the sysctl_handle_v_int() function:
#ifdef VIMAGE
int
sysctl_handle_v_int(SYSCTL_HANDLER_V_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
Observe the SYSCTL_RESOLVE_V_ARG1() macro above which does the actual
magic of computing the address of the target variable:
/*
* Resolve void *arg1 in a proper virtualization container.
*/
#ifdef VIMAGE
#define SYSCTL_RESOLVE_V_ARG1() do {
char *cp;
switch (subs) {
case V_NET:
cp = (char *) TD_TO_VNET(curthread)->mod_data[mod];
break;
case V_PROCG:
cp = (char *) TD_TO_VPROCG(curthread);
break;
case V_CPU:
cp = (char *) TD_TO_VCPU(curthread);
break;
default:
panic("unsupported module id %d", subs);
}
arg1 = cp + (size_t) arg1;
} while (0)
#endif
Hmm probably I should make subs and mod the arguments of the above
macro...
Anyhow if the kernel is compiled without "options VIMAGE" the SYSCTL_V
macros fall back to standard SYSCTL macros of course.
Hope this clarifies the picture to some extent...
Marko
More information about the freebsd-current
mailing list