PERFORCE change 126462 for review
Marko Zec
zec at FreeBSD.org
Sun Sep 16 03:15:09 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=126462
Change 126462 by zec at zec_tpx32 on 2007/09/16 10:14:47
Get rid of vimage_0, vnet_0, vprocg_0 and vcpu_0. Checking
whether running in a default context should from now on
be done exclusively using IS_DEFAULT_VIMAGE() or
IS_DEFAULT_VNET() macros. All the structures are allocated
now via vi_alloc() even for the "default" vimage at boot time.
Each vimage / vnet / vprocg / vcpu structure now has an unique
ID number, which is always 0 for "default" instances.
Attempt to fix races in counting the number of processes per
vprocg.
Stop exposing the parent name of the vimage to the userland.
A few cosmetic / style cleanups.
Affected files ...
.. //depot/projects/vimage/src/sys/dev/firewire/firewire.c#8 edit
.. //depot/projects/vimage/src/sys/i386/i386/dump_machdep.c#3 edit
.. //depot/projects/vimage/src/sys/i386/i386/minidump_machdep.c#4 edit
.. //depot/projects/vimage/src/sys/kern/init_main.c#11 edit
.. //depot/projects/vimage/src/sys/kern/kern_exit.c#6 edit
.. //depot/projects/vimage/src/sys/kern/kern_linker.c#9 edit
.. //depot/projects/vimage/src/sys/kern/kern_vimage.c#37 edit
.. //depot/projects/vimage/src/sys/netinet/in_proto.c#8 edit
.. //depot/projects/vimage/src/sys/netinet/tcp_hostcache.c#16 edit
.. //depot/projects/vimage/src/sys/netinet/tcp_subr.c#32 edit
.. //depot/projects/vimage/src/sys/netinet/tcp_var.h#16 edit
.. //depot/projects/vimage/src/sys/netinet/vinet.h#19 edit
.. //depot/projects/vimage/src/sys/sys/vimage.h#37 edit
Differences ...
==== //depot/projects/vimage/src/sys/dev/firewire/firewire.c#8 (text+ko) ====
@@ -677,7 +677,7 @@
static void
fw_reset_crom(struct firewire_comm *fc)
{
- INIT_VPROCG(&vprocg_0);
+ INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg); /* XXX */
struct crom_src_buf *buf;
struct crom_src *src;
struct crom_chunk *root;
==== //depot/projects/vimage/src/sys/i386/i386/dump_machdep.c#3 (text+ko) ====
@@ -112,7 +112,7 @@
mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen,
uint32_t blksz)
{
- INIT_VPROCG(vimage_0.v_procg);
+ INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg); /* XXX */
bzero(kdh, sizeof(*kdh));
strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
==== //depot/projects/vimage/src/sys/i386/i386/minidump_machdep.c#4 (text) ====
@@ -86,7 +86,7 @@
mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen,
uint32_t blksz)
{
- INIT_VPROCG(vimage_0.v_procg);
+ INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg);
bzero(kdh, sizeof(*kdh));
strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
==== //depot/projects/vimage/src/sys/kern/init_main.c#11 (text+ko) ====
@@ -447,8 +447,9 @@
p->p_ucred->cr_ruidinfo = uifind(0);
p->p_ucred->cr_prison = NULL; /* Don't jail it. */
#ifdef VIMAGE
- p->p_ucred->cr_vimage = p->p_ucred->cr_rvimage = &vimage_0;
- vprocg_0.nprocs = 1;
+ p->p_ucred->cr_vimage = LIST_FIRST(&vimage_head);
+ p->p_ucred->cr_rvimage = p->p_ucred->cr_vimage;
+ LIST_FIRST(&vprocg_head)->nprocs = 1;
#endif
#ifdef AUDIT
audit_cred_kproc0(p->p_ucred);
==== //depot/projects/vimage/src/sys/kern/kern_exit.c#6 (text+ko) ====
@@ -173,21 +173,28 @@
}
KASSERT(p->p_numthreads == 1,
("exit1: proc %p exiting with %d threads", p, p->p_numthreads));
+
#ifdef VIMAGE
/*
* Switch back to vprocg of our parent so we can deliver
* signals, otherwise we won't die - why?!? XXX
*
- * XXX real or effective vimage?
- * XXX nprocs counting in vprocg?
+ * XXX is PROC_UNLOCK()/PROC_LOCK() sequence safe here?
*/
if (p->p_pptr && p->p_ucred->cr_vimage->v_procg !=
p->p_pptr->p_ucred->cr_vimage->v_procg) {
- struct ucred *oldcred = p->p_ucred;
+ struct ucred *oldcred;
setsugid(p);
+ crhold(p->p_pptr->p_ucred);
+ oldcred = p->p_ucred;
p->p_ucred = p->p_pptr->p_ucred;
- crhold(p->p_ucred);
+ PROC_UNLOCK(p);
+ sx_xlock(&allproc_lock);
+ oldcred->cr_vimage->v_procg->nprocs--;
+ p->p_ucred->cr_vimage->v_procg->nprocs++;
+ sx_xunlock(&allproc_lock);
+ PROC_LOCK(p);
crfree(oldcred);
}
#endif
==== //depot/projects/vimage/src/sys/kern/kern_linker.c#9 (text+ko) ====
@@ -857,7 +857,7 @@
return (error);
#ifdef VIMAGE
- if (td->td_ucred->cr_vimage != &vimage_0)
+ if (!IS_DEFAULT_VIMAGE(td->td_ucred->cr_vimage))
return (EPERM);
#endif
@@ -929,9 +929,8 @@
return (error);
/* XXX should suser catch this for us? */
- VNET_ASSERT(td->td_ucred->cr_vimage == &vimage_0);
- /* XXX is this necessary at all? */
- VNET_ASSERT(td == curthread);
+ VNET_ASSERT(IS_DEFAULT_VIMAGE(td->td_ucred->cr_vimage));
+
CURVNET_SET(td->td_ucred->cr_vimage->v_vnet);
KLD_LOCK();
==== //depot/projects/vimage/src/sys/kern/kern_vimage.c#37 (text+ko) ====
@@ -36,9 +36,11 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/linker.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/sockio.h>
-#include <sys/priv.h>
+#include <sys/sx.h>
#include <sys/vimage.h>
#ifdef DDB
@@ -58,10 +60,12 @@
MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block");
MALLOC_DEFINE(M_VCPU, "vcpu", "cpu resource control block");
+static struct vimage *vi_alloc(char *, int);
static int vi_destroy(struct vimage *);
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 *);
+static int vi_child_of(struct vimage *, struct vimage *);
#ifdef VI_PREALLOC_SIZE
/*
@@ -100,12 +104,6 @@
#define vi_free(addr, type) free((addr), (type))
#endif /* VI_PREALLOC_SIZE */
-/* XXX those must vanish */
-struct vimage vimage_0;
-struct vprocg vprocg_0;
-struct vcpu vcpu_0;
-struct vnet vnet_0;
-
struct vimage_list_head vimage_head;
struct vnet_list_head vnet_head;
struct vprocg_list_head vprocg_head;
@@ -123,7 +121,12 @@
#define VNET_LIST_UNLOCK() \
mtx_unlock(&vnet_list_refc_mtx);
-static int last_vi_id = 0;
+static u_int last_vi_id = 0;
+static u_int last_vnet_id = 0;
+#if 0
+static u_int last_vprocg_id = 0;
+static u_int last_vcpu_id = 0;
+#endif
static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head;
static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head;
@@ -169,7 +172,9 @@
break; /* Depencency found, we are done */
if (vml_iter == NULL) {
#ifdef DEBUG_ORDERING
- printf("dependency %d missing for vnet mod %s, postponing registration\n", vmi->vmi_dependson, vmi->vmi_name);
+ printf("dependency %d missing for vnet mod %s,"
+ "postponing registration\n",
+ vmi->vmi_dependson, vmi->vmi_name);
#endif /* DEBUG_ORDERING */
TAILQ_INSERT_TAIL(&vnet_modpending_head, vml,
vml_mod_le);
@@ -199,7 +204,10 @@
break;
if (vml_iter != NULL) {
#ifdef DEBUG_ORDERING
- printf("vnet mod %s now registering, dependency %d loaded\n", vml_iter->vml_modinfo->vmi_name, vml->vml_modinfo->vmi_id);
+ printf("vnet mod %s now registering,"
+ "dependency %d loaded\n",
+ vml_iter->vml_modinfo->vmi_name,
+ vml->vml_modinfo->vmi_id);
#endif /* DEBUG_ORDERING */
TAILQ_REMOVE(&vnet_modpending_head, vml_iter,
vml_mod_le);
@@ -288,7 +296,7 @@
u_char eaddr[6];
if (vi_req == NULL || strcmp(vi_req->vi_name, "-") == 0) {
- if (vip == &vimage_0)
+ if (IS_DEFAULT_VIMAGE(vip))
return (ENXIO);
new_vnet = vip->vi_parent->v_vnet;
} else
@@ -313,7 +321,7 @@
struct ifnet *t_ifp;
CURVNET_SET_QUIET(new_vnet);
- t_ifp = ifunit(vi_req->vi_parent_name);
+ t_ifp = ifunit(vi_req->vi_if_xname);
CURVNET_RESTORE();
if (t_ifp != NULL)
return (EEXIST);
@@ -372,9 +380,9 @@
snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", ifp->if_dname,
ifp->if_dunit);
} else {
- if (vi_req && strlen(vi_req->vi_parent_name) > 0) {
+ if (vi_req && strlen(vi_req->vi_if_xname) > 0) {
snprintf(ifp->if_xname, IFNAMSIZ, "%s",
- vi_req->vi_parent_name);
+ vi_req->vi_if_xname);
} else {
int unit = 0;
struct ifnet *iter;
@@ -480,12 +488,6 @@
vi_req->vi_id = vip_r->vi_id;
bcopy(&vip_r->vi_name, &vi_req->vi_name,
sizeof (vi_req->vi_name));
- if (vip_r->vi_parent)
- bcopy(&vip_r->vi_parent->vi_name,
- &vi_req->vi_parent_name,
- sizeof (vi_req->vi_parent_name));
- else
- vi_req->vi_parent_name[0] = 0;
vi_req->vi_proc_count = vip_r->v_procg->nprocs;
vi_req->vi_if_count = vip_r->v_vnet->ifccnt;
vi_req->vi_sock_count = vip_r->v_vnet->sockcnt;
@@ -515,21 +517,24 @@
newcred->cr_rvimage = vip_r; /* XXX */
p->p_ucred = newcred;
PROC_UNLOCK(p);
+ sx_xlock(&allproc_lock);
+ oldcred->cr_vimage->v_procg->nprocs--;
+ p->p_ucred->cr_vimage->v_procg->nprocs++;
+ sx_xunlock(&allproc_lock);
crfree(oldcred);
break;
}
if (vi_req->req_action & VI_CREATE) {
- vip_r = vi_alloc(vi_req->vi_name, vi_req->vi_maxsockets,
- vi_req->vi_tsc_hashs,
- vi_req->vi_tsc_buckl);
+ vip_r = vi_alloc(vi_req->vi_name,
+ vi_req->vi_maxsockets);
if (vip_r == NULL)
return (ENOMEM);
vip_r->vi_parent = vip;
}
- if (vip == vip_r && vip != &vimage_0)
+ if (vip == vip_r && !IS_DEFAULT_VIMAGE(vip))
return (EPERM);
}
@@ -567,9 +572,7 @@
struct vimage *
-vi_alloc(name, maxsock, tsc_hashs, tsc_buckl)
- char *name;
- int maxsock, tsc_hashs, tsc_buckl;
+vi_alloc(char *name, int maxsock)
{
struct vimage *vip;
struct vnet *vnet;
@@ -596,6 +599,7 @@
if (vnet == NULL)
panic("vi_alloc: malloc failed for vnet \"%s\"\n", name);
vip->v_vnet = vnet;
+ vnet->vnet_id = last_vnet_id++;
vnet->vnet_magic_n = VNET_MAGIC_N;
vprocg = vi_malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO);
@@ -646,6 +650,9 @@
struct vnet_modlink *vml;
/* XXX Beware of races -> more locking to be done... */
+ if (vprocg->nprocs != 0)
+ return (EBUSY);
+
if (vnet->sockcnt != 0)
return (EBUSY);
@@ -783,23 +790,13 @@
LIST_INIT(&vprocg_head);
LIST_INIT(&vcpu_head);
- LIST_INSERT_HEAD(&vimage_head, &vimage_0, vi_le);
- LIST_INSERT_HEAD(&vnet_head, &vnet_0, vnet_le);
- LIST_INSERT_HEAD(&vprocg_head, &vprocg_0, vprocg_le);
- LIST_INSERT_HEAD(&vcpu_head, &vcpu_0, vcpu_le);
-
- sprintf(vimage_0.vi_name, "default");
- vimage_0.v_vnet = &vnet_0;
- vimage_0.v_procg = &vprocg_0;
- vimage_0.v_cpu = &vcpu_0;
-
- vnet_0.vnet_magic_n = VNET_MAGIC_N;
-
mtx_init(&vnet_list_refc_mtx, "vnet_list_refc_mtx", NULL, MTX_DEF);
cv_init(&vnet_list_condvar, "vnet_list_condvar");
+ vi_alloc("default", 0);
+
/* We MUST clear curvnet in vi_init_done before going SMP. */
- curvnet = &vnet_0;
+ curvnet = LIST_FIRST(&vnet_head);
}
static void
@@ -824,7 +821,6 @@
SYSINIT(vimage_done, SI_SUB_VIMAGE_DONE, SI_ORDER_FIRST, vi_init_done, NULL)
#ifdef VI_PREALLOC_SIZE
-
void *
vi_malloc(unsigned long size, struct malloc_type *type, int flags)
{
@@ -845,7 +841,8 @@
/* Not (enough) free space in our pool, resort to malloc() */
if (vmt == NULL) {
if (vi_mpool_fail_cnt == 0)
- printf("vi_mpool exhausted, consider increasing VI_PREALLOC_SIZE\n");
+ printf("vi_mpool exhausted,"
+ "consider increasing VI_PREALLOC_SIZE\n");
vi_mpool_fail_cnt++;
addr = malloc(size, type, flags);
return addr;
==== //depot/projects/vimage/src/sys/netinet/in_proto.c#8 (text+ko) ====
@@ -130,6 +130,7 @@
.pr_ctlinput = tcp_ctlinput,
.pr_ctloutput = tcp_ctloutput,
.pr_init = tcp_init,
+ .pr_destroy = tcp_destroy,
.pr_slowtimo = tcp_slowtimo,
.pr_drain = tcp_drain,
.pr_usrreqs = &tcp_usrreqs
==== //depot/projects/vimage/src/sys/netinet/tcp_hostcache.c#16 (text+ko) ====
@@ -105,10 +105,9 @@
#ifndef VIMAGE
static struct tcp_hostcache tcp_hostcache;
+static struct callout tcp_hc_callout;
#endif
-static struct callout tcp_hc_callout;
-
static struct hc_metrics *tcp_hc_lookup(struct in_conninfo *);
static struct hc_metrics *tcp_hc_insert(struct in_conninfo *);
static int sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS);
@@ -222,16 +221,22 @@
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
uma_zone_set_max(V_tcp_hostcache.zone, V_tcp_hostcache.cache_limit);
-#ifdef VIMAGE
- if (!IS_DEFAULT_VNET(curvnet))
- return;
-#endif
-
/*
* Set up periodic cache cleanup.
*/
- callout_init(&tcp_hc_callout, CALLOUT_MPSAFE);
- callout_reset(&tcp_hc_callout, V_tcp_hostcache.prune * hz, tcp_hc_purge, 0);
+ callout_init(&V_tcp_hc_callout, CALLOUT_MPSAFE);
+ callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,
+ tcp_hc_purge, curvnet);
+}
+
+void
+tcp_hc_destroy(void)
+{
+ INIT_VNET_INET(curvnet);
+
+ /* XXX TODO walk the hashtable and free all entries */
+
+ callout_drain(&V_tcp_hc_callout);
}
/*
@@ -638,12 +643,12 @@
static void
tcp_hc_purge(void *arg)
{
+ CURVNET_SET((struct vnet *) arg);
+ INIT_VNET_INET(curvnet);
struct hc_metrics *hc_entry, *hc_next;
int all = 0;
int i;
- VNET_ITERLOOP_BEGIN()
- INIT_VNET_INET(vnet_iter);
if (V_tcp_hostcache.purgeall) {
all = 1;
V_tcp_hostcache.purgeall = 0;
@@ -665,11 +670,9 @@
}
THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
}
- VNET_ITERLOOP_END();
+
+ callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,
+ tcp_hc_purge, arg);
- /* XXX Marko - FIXME! */
- CURVNET_SET(&vnet_0);
- INIT_VNET_INET(&vnet_0);
- callout_reset(&tcp_hc_callout, V_tcp_hostcache.prune * hz, tcp_hc_purge, 0);
CURVNET_RESTORE();
}
==== //depot/projects/vimage/src/sys/netinet/tcp_subr.c#32 (text+ko) ====
@@ -387,6 +387,12 @@
}
void
+tcp_destroy(void)
+{
+ tcp_hc_destroy();
+}
+
+void
tcp_fini(void *xtp)
{
==== //depot/projects/vimage/src/sys/netinet/tcp_var.h#16 (text+ko) ====
@@ -547,6 +547,7 @@
void tcp_drain(void);
void tcp_fasttimo(void);
void tcp_init(void);
+void tcp_destroy(void);
void tcp_fini(void *);
char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *,
const void *);
@@ -587,6 +588,7 @@
* All tcp_hc_* functions are IPv4 and IPv6 (via in_conninfo)
*/
void tcp_hc_init(void);
+void tcp_hc_destroy(void);
void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
u_long tcp_hc_getmtu(struct in_conninfo *);
void tcp_hc_updatemtu(struct in_conninfo *, u_long);
==== //depot/projects/vimage/src/sys/netinet/vinet.h#19 (text+ko) ====
@@ -87,6 +87,7 @@
struct inpcbinfo _tcbinfo;
struct tcpstat _tcpstat; /* tcp statistics */
struct tcp_hostcache _tcp_hostcache;
+ struct callout _tcp_hc_callout;
struct tcp_syncache _tcp_syncache;
TAILQ_HEAD(, tcptw) _twq_2msl;
@@ -220,6 +221,7 @@
#define V_tcpstat VNET_INET(tcpstat)
#define V_twq_2msl VNET_INET(twq_2msl)
#define V_tcp_hostcache VNET_INET(tcp_hostcache)
+#define V_tcp_hc_callout VNET_INET(tcp_hc_callout)
#define V_tcp_syncache VNET_INET(tcp_syncache)
#define V_tcp_sc_rst_sock_fail VNET_INET(tcp_sc_rst_sock_fail)
==== //depot/projects/vimage/src/sys/sys/vimage.h#37 (text+ko) ====
@@ -108,23 +108,25 @@
struct vnet {
void *mod_data[VNET_MOD_MAX];
- LIST_ENTRY(vnet) vnet_le;
+ u_int vnet_ref; /* reference count */
+ LIST_ENTRY(vnet) vnet_le; /* all vnets list */
+ u_int vnet_id; /* ID num */
- int ifccnt;
- int sockcnt;
+ u_int ifccnt;
+ u_int sockcnt;
- int vnet_magic_n;
+ u_int vnet_magic_n;
};
struct vnet_symmap {
char *name;
- int offset;
- int size;
+ size_t offset;
+ size_t size;
};
struct vnet_modinfo {
- int vmi_id;
- int vmi_dependson;
+ u_int vmi_id;
+ u_int vmi_dependson;
char *vmi_name;
vnet_attach_fn *vmi_iattach;
vnet_detach_fn *vmi_idetach;
@@ -298,28 +300,22 @@
const char *);
void printcpuinfo(struct vprocg *);
-struct vimage *vi_alloc(char *, int, int, int);
void vi_cpu_acct(void *);
int vi_td_ioctl(u_long, struct vi_req *, struct thread *);
int vi_if_move(struct vi_req *, struct ifnet *, struct vimage *);
-int vi_child_of(struct vimage *, struct vimage *);
int vi_symlookup(struct kld_sym_lookup *, char *);
struct vimage *vnet2vimage(struct vnet *);
char *vnet_name(struct vnet *);
-extern struct vimage vimage_0;
LIST_HEAD(vimage_list_head, vimage);
extern struct vimage_list_head vimage_head;
-extern struct vprocg vprocg_0;
LIST_HEAD(vprocg_list_head, vprocg);
extern struct vprocg_list_head vprocg_head;
-extern struct vcpu vcpu_0;
LIST_HEAD(vcpu_list_head, vcpu);
extern struct vcpu_list_head vcpu_head;
-extern struct vnet vnet_0;
LIST_HEAD(vnet_list_head, vnet);
extern struct vnet_list_head vnet_head;
extern int vnet_list_refc;
@@ -337,14 +333,13 @@
mtx_unlock(&vnet_list_refc_mtx); \
cv_signal(&vnet_list_condvar);
-#define IS_DEFAULT_VNET(arg) ((arg) == &vnet_0 ? 1 : 0)
+#define IS_DEFAULT_VIMAGE(arg) ((arg)->vi_id == 0)
+#define IS_DEFAULT_VNET(arg) ((arg)->vnet_id == 0)
-/*
- * XXX The stuff bellow needs a major cleanup / rewrite from scratch.
- */
-
struct vimage {
- LIST_ENTRY(vimage) vi_le;
+ LIST_ENTRY(vimage) vi_le; /* all vimage list */
+ LIST_ENTRY(vimage) vi_sibilings; /* vimages with same parent */
+ LIST_HEAD(, vimage) vi_child_head; /* direct offspring list */
struct vimage *vi_parent; /* ptr to parent vimage */
u_int vi_id; /* ID num */
@@ -357,6 +352,8 @@
struct vprocg {
LIST_ENTRY(vprocg) vprocg_le;
+ u_int vprocg_ref; /* reference count */
+ u_int vprocg_id; /* ID num */
u_int nprocs;
@@ -394,6 +391,8 @@
struct vcpu {
LIST_ENTRY(vcpu) vcpu_le;
+ u_int vcpu_ref; /* reference count */
+ u_int vcpu_id; /* ID num */
#if 0
u_int cp_time_avg[CPUSTATES];
@@ -418,8 +417,6 @@
u_int vi_cpu_weight; /* Prop. share scheduling priority */
int vi_intr_limit; /* Limit on CPU usage in intr ctx */
int vi_maxsockets;
- int vi_tsc_hashs;
- int vi_tsc_buckl;
u_short vi_id; /* IDnum - but do we need it at all? */
u_short vi_proc_limit; /* max. number of processes */
u_short vi_proc_count; /* current number of processes */
@@ -427,9 +424,9 @@
u_short vi_child_count; /* current number of child vnets */
int vi_if_count; /* current number network interfaces */
int vi_sock_count;
- char vi_name[MAXHOSTNAMELEN];
- char vi_parent_name[MAXHOSTNAMELEN];
+ char vi_name[MAXPATHLEN];
char vi_chroot[MAXPATHLEN];
+ char vi_if_xname[MAXPATHLEN]; /* XXX should be IFNAMSIZ */
int cp_time_avg[CPUSTATES];
struct loadavg averunnable;
};
More information about the p4-projects
mailing list