PERFORCE change 163194 for review

Marko Zec zec at FreeBSD.org
Sun May 31 19:28:59 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163194

Change 163194 by zec at zec_tpx32 on 2009/05/31 19:28:20

	Fix misintegrations and hopefully unbreak kernel build.

Affected files ...

.. //depot/projects/vimage/src/sys/kern/kern_vimage.c#92 edit

Differences ...

==== //depot/projects/vimage/src/sys/kern/kern_vimage.c#92 (text+ko) ====

@@ -38,14 +38,12 @@
 #include <sys/linker.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
-#include <sys/priv.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/sx.h>
 #include <sys/priv.h>
 #include <sys/refcount.h>
 #include <sys/vimage.h>
-
 #ifdef DDB
 #include <ddb/ddb.h>
 #endif
@@ -54,34 +52,19 @@
 #include <net/route.h>
 #include <net/vnet.h>
 
-#include <net/if_clone.h>
-#include <net/route.h>
-#include <net/vnet.h>
+#ifndef VIMAGE_GLOBALS
 
-struct vnet_modlink;
-
 MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container");
 MALLOC_DEFINE(M_VNET, "vnet", "network stack control block");
 MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block");
 
-#ifdef VIMAGE
-static struct vimage *vi_alloc(struct vimage *, char *);
-static int vi_destroy(struct vimage *);
-#endif
-
-#ifndef VIMAGE
-#ifndef VIMAGE_GLOBALS
-struct vprocg vprocg_0;
-#endif
-#endif
-
-#ifndef VIMAGE_GLOBALS
 static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head;
 static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head;
 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
 static struct vimage *vimage_by_name(struct vimage *, char *);
 static struct vimage *vi_alloc(struct vimage *, char *);
 static struct vimage *vimage_get_next(struct vimage *, struct vimage *, int);
@@ -625,400 +608,16 @@
 	}
 	return (ENOENT);
 }
-#endif /* !VIMAGE_GLOBALS */
 
 #ifdef VIMAGE
-struct vimage_list_head vimage_head;
-struct vnet_list_head vnet_head;
-struct vprocg_list_head vprocg_head;
-
-struct cv vnet_list_condvar;
-struct mtx vnet_list_refc_mtx;
-int vnet_list_refc = 0;
-
-#define VNET_LIST_LOCK()						\
-	mtx_lock(&vnet_list_refc_mtx);					\
-	while (vnet_list_refc != 0)					\
-		cv_wait(&vnet_list_condvar, &vnet_list_refc_mtx);
-
-#define VNET_LIST_UNLOCK()						\
-	mtx_unlock(&vnet_list_refc_mtx);
-
-static u_int last_vi_id = 0;
-static u_int last_vnet_id = 0;
-static u_int last_vprocg_id = 0;
-
-struct vimage *
-vnet2vimage(struct vnet *vnet)
-{
-	struct vimage *vip;
-
-	LIST_FOREACH(vip, &vimage_head, vi_le)
-		if (vip->v_net == vnet)
-			return(vip);
-
-	panic("vnet2vimage");	/* must never happen */
-}
-
-char *
-vnet_name(struct vnet *vnet)
-{
-	return(vnet2vimage(vnet)->vi_name);
-}
-
-
-int
-vi_child_of(struct vimage *parent, struct vimage *child)
-{
-	if (child == parent)
-		return (0);
-	for (; child; child = child->vi_parent)
-		if (child == parent)
-			return (1);
-	return (0);
-}
-
-/*
- * if_reassign_common() should be called by all device specific
- * ifnet reassignment routines after the interface is detached from
- * current vnet and before the interface gets attached to the target
- * vnet.  This routine attempts to shrink if_index in current vnet,
- * find an unused if_index in target vnet and calls if_grow() if
- * necessary, and finally finds an unused if_xname for the target
- * vnet.
- *
- * XXX this routine should hold a lock over if_index and return with
- * such a lock held, and the caller should release that lock
- * after ifattach completes!
- */
-void
-if_reassign_common(struct ifnet *ifp, struct vnet *new_vnet, const char *dname)
-{
-	/* do/while construct needed to confine scope of INIT_VNET_NET() */
-	do {
-		INIT_VNET_NET(curvnet);
-
-		IFNET_WLOCK();
-		ifnet_setbyindex(ifp->if_index, NULL);
-		while (V_if_index > 0 &&
-		    ifnet_byindex_locked(V_if_index) == NULL)
-			V_if_index--;
-		IFNET_WUNLOCK();
-	} while (0);
-
-	CURVNET_SET_QUIET(new_vnet);
-	INIT_VNET_NET(new_vnet);
-	/*
-	 * Try to find an empty slot below if_index.  If we fail, take 
-	 * the next slot.
-	 */
-	IFNET_WLOCK();
-	for (ifp->if_index = 1; ifp->if_index <= V_if_index; ifp->if_index++) {
-		if (ifnet_byindex_locked(ifp->if_index) == NULL)
-			break;
-	}
-	/* Catch if_index overflow. */
-	if (ifp->if_index < 1)
-		panic("vi_if_move: if_index overflow");
-
-	if (ifp->if_index > V_if_index)
-		V_if_index = ifp->if_index;
-	if (V_if_index >= V_if_indexlim)
-		if_grow();
-	ifnet_setbyindex(ifp->if_index, ifp);
-	IFNET_WUNLOCK();
-
-	/* Rename the ifnet */
-	if (new_vnet == ifp->if_home_vnet) {
-		/* always restore the original name on return to home vnet */
-		if_initname(ifp, ifp->if_dname, ifp->if_dunit);
-	} else {
-		int unit = 0;
-		struct ifnet *iter;
-
-		do {
-			snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", dname, unit);
-			TAILQ_FOREACH(iter, &V_ifnet, if_link)
-				if (strcmp(ifp->if_xname, iter->if_xname) == 0)
-					break;
-			unit++;
-		} while (iter);
-	}
-	CURVNET_RESTORE();
-}
-
-/*
- * Move the interface to another vnet. The interface can be specified either
- * by ifp argument, or by name contained in vi_req->vi_chroot if NULL is
- * passed as ifp.  The interface will be renamed to vi_req->vi_parent_name
- * if vi_req->vi_parent_name is not an empty string (uff ugly ugly)...
- * Similary, the target vnet can be specified either by vnet argument or
- * by name. If vnet name equals to ".." or vi_req is set to NULL the
- * interface is moved to the parent vnet.
- */
-int
-vi_if_move(struct vi_req *vi_req, struct ifnet *ifp, struct vimage *vip)
-{
-	struct vimage *new_vip;
-	struct vnet *new_vnet = NULL;
-
-	if (vi_req == NULL || strcmp(vi_req->vi_name, "..") == 0) {
-		if (IS_DEFAULT_VIMAGE(vip))
-			return (ENXIO);
-		new_vnet = vip->vi_parent->v_net;
-	} else {
-		new_vip = vimage_by_name(vip, vi_req->vi_name);
-		if (new_vip == NULL)
-			return (ENXIO);
-		new_vnet = new_vip->v_net;
-	}
-
-	if (ifp == NULL)
-		ifp = ifunit(vi_req->vi_chroot);
-	if (ifp == NULL)
-		return (ENXIO);
-
-	/* Abort if driver did not provide a if_reassign() method */
-	if (ifp->if_reassign == NULL)
-		return (ENODEV);
-
-	if (vi_req != NULL) {
-		struct ifnet *t_ifp;
-
-		CURVNET_SET_QUIET(new_vnet);
-		t_ifp = ifunit(vi_req->vi_if_xname);
-		CURVNET_RESTORE();
-		if (t_ifp != NULL)
-			return (EEXIST);
-	}
-
-	if (vi_req  && strlen(vi_req->vi_if_xname) > 0)
-		ifp->if_reassign(ifp, new_vnet, vi_req->vi_if_xname);
-	else
-		ifp->if_reassign(ifp, new_vnet, NULL);
-	getmicrotime(&ifp->if_lastchange);
-
-	/* Report the new if_xname back to the userland */
-	if (vi_req != NULL)
-		sprintf(vi_req->vi_chroot, "%s", ifp->if_xname);
-
-	return (0);
-}
-
-
-struct vimage *
-vimage_by_name(struct vimage *top, char *name)
-{
-	struct vimage *vip;
-	char *next_name;
-	int namelen;
-
-	next_name = strchr(name, '.');
-	if (next_name != NULL) {
-		namelen = next_name - name;
-		next_name++;
-		if (namelen == 0) {
-			if (strlen(next_name) == 0)
-				return(top);	/* '.' == this vimage */
-			else
-				return(NULL);
-		}
-	} else
-		namelen = strlen(name);
-	if (namelen == 0)
-		return(NULL);
-	LIST_FOREACH(vip, &top->vi_child_head, vi_sibling)
-		if (strlen(vip->vi_name) == namelen &&
-		    strncmp(name, vip->vi_name, namelen) == 0) {
-			if (next_name != NULL)
-				return(vimage_by_name(vip, next_name));
-			else
-				return(vip);
-		}
-	return(NULL);
-}
-
-
-vimage_relative_name(struct vimage *top, struct vimage *where,
-    char *buffer, int bufflen)
-{
-	int used = 1;
-
-	if (where == top) {
-		sprintf(buffer, ".");
-		return;
-	} else
-		*buffer = 0;
-
-	do {
-		int namelen = strlen(where->vi_name);
-
-		if (namelen + used + 1 >= bufflen)
-			panic("buffer overflow");
-
-		if (used > 1) {
-			bcopy(buffer, &buffer[namelen + 1], used);
-			buffer[namelen] = '.';
-			used++;
-		} else
-			bcopy(buffer, &buffer[namelen], used);
-		bcopy(where->vi_name, buffer, namelen);
-		used += namelen;
-		where = where->vi_parent;
-	} while (where != top);
-}
-
-
 static struct vimage *
-vimage_get_next(struct vimage *top, struct vimage *where, int recurse)
-{
-	struct vimage *next;
-
-	if (recurse) {
-		/* Try to go deeper in the hierarchy */
-		next = LIST_FIRST(&where->vi_child_head);
-		if (next != NULL)
-			return(next);
-	}
-
-	do {
-		/* Try to find next sibling */
-		next = LIST_NEXT(where, vi_sibling);
-		if (!recurse || next != NULL)
-			return(next);
-
-		/* Nothing left on this level, go one level up */
-		where = where->vi_parent;
-	} while (where != top->vi_parent);
-
-	/* Nothing left to be visited, we are done */
-	return(NULL);
-}
-
-
-int
-vi_td_ioctl(u_long cmd, struct vi_req *vi_req, struct thread *td)
-{
-	int error;
-	struct vimage *vip = TD_TO_VIMAGE(td);
-	struct vimage *vip_r = NULL;
-
-	error = priv_check(td, PRIV_REBOOT); /* XXX fixme MARKO */
-	if (error)
-		return (error);
-
-	vip_r = vimage_by_name(vip, vi_req->vi_name);
-	if (vip_r == NULL && !(vi_req->req_action & VI_CREATE))
-		return (ESRCH);
-	if (vip_r != NULL && vi_req->req_action & VI_CREATE)
-		return (EADDRINUSE);
-	if (vi_req->req_action == VI_GETNEXT) {
-		vip_r = vimage_get_next(vip, vip_r, 0);
-		if (vip_r == NULL)
-			return (ESRCH);
-	}
-	if (vi_req->req_action == VI_GETNEXT_RECURSE) {
-		vip_r = vimage_get_next(vip, vip_r, 1);
-		if (vip_r == NULL)
-			return (ESRCH);
-	}
-
-	if (vip_r && !vi_child_of(vip, vip_r) && /* XXX delete the rest? */
-	    vi_req->req_action != VI_GET && vi_req->req_action != VI_GETNEXT)
-		return (EPERM);
-
-	switch (cmd) {
-
-	case SIOCGPVIMAGE:
-		vimage_relative_name(vip, vip_r, vi_req->vi_name,
-		    sizeof (vi_req->vi_name));
-		vi_req->vi_proc_count = vip_r->v_procg->nprocs;
-		vi_req->vi_if_count = vip_r->v_net->ifccnt;
-		vi_req->vi_sock_count = vip_r->v_net->sockcnt;
-		break;
-
-	case SIOCSPVIMAGE:
-		if (vi_req->req_action == VI_DESTROY) {
-			error = vi_destroy(vip_r);
-			break;
-		}
-
-		if (vi_req->req_action == VI_SWITCHTO) {
-			struct proc *p = td->td_proc;
-			struct ucred *oldcred, *newcred;
-
-			/*
-			 * XXX priv_check()?
-			 * XXX allow only a single td per proc here?
-			 */
-			newcred = crget();
-			PROC_LOCK(p);
-			oldcred = p->p_ucred;
-			setsugid(p);
-			crcopy(newcred, oldcred);
-			refcount_release(&newcred->cr_vimage->vi_ucredrefc);
-			newcred->cr_vimage = vip_r;
-			refcount_acquire(&newcred->cr_vimage->vi_ucredrefc);
-			p->p_ucred = newcred;
-			PROC_UNLOCK(p);
-			sx_xlock(&allproc_lock);
-			oldcred->cr_vimage->v_procg->nprocs--;
-			refcount_release(&oldcred->cr_vimage->vi_ucredrefc);
-			P_TO_VPROCG(p)->nprocs++;
-#if 0
-			sched_load_reassign(oldcred->cr_vimage->v_procg,
-			    newcred->cr_vimage->v_procg);
-#endif
-			sx_xunlock(&allproc_lock);
-			crfree(oldcred);
-			break;
-		}
-
-		if (vi_req->req_action & VI_CREATE) {
-			char *dotpos;
-
-			dotpos = strrchr(vi_req->vi_name, '.');
-			if (dotpos != NULL) {
-				*dotpos = 0;
-				vip = vimage_by_name(vip, vi_req->vi_name);
-				if (vip == NULL)
-					return (ESRCH);
-				dotpos++;
-				vip_r = vi_alloc(vip, dotpos);
-			} else
-				vip_r = vi_alloc(vip, vi_req->vi_name);
-			if (vip_r == NULL)
-				return (ENOMEM);
-		}
-
-		/* XXX What the hell is this doing here? */
-		if (vip == vip_r && !IS_DEFAULT_VIMAGE(vip))
-			return (EPERM);
-	}
-
-	return (error);
-}
-
-
-struct vimage *
 vi_alloc(struct vimage *parent, char *name)
 {
 	struct vimage *vip;
 	struct vprocg *vprocg;
 	struct vnet *vnet;
-	struct vprocg *vprocg;
 	struct vnet_modlink *vml;
 
-	/*
-	 * XXX don't forget the locking
-	 */
-
-	/* A brute force check whether there's enough mem for a new vimage */
-	vip = malloc(512*1024, M_VIMAGE, M_NOWAIT); /* XXX aaaargh... */
-	if (vip == NULL)
-		goto vi_alloc_done;
-	free(vip, M_VIMAGE);
-
 	vip = malloc(sizeof(struct vimage), M_VIMAGE, M_NOWAIT | M_ZERO);
 	if (vip == NULL)
 		panic("vi_alloc: malloc failed for vimage \"%s\"\n", name);
@@ -1061,11 +660,9 @@
 	/* XXX locking */
 	LIST_INSERT_HEAD(&vprocg_head, vprocg, vprocg_le);
 
-vi_alloc_done:
 	return (vip);
 }
 
-
 /*
  * Destroy a vnet - unlink all linked lists, free all the memory, stop all
  * the timers... How can one ever be sure to have done *all* the necessary
@@ -1124,10 +721,6 @@
 			      vnet_modlink_head, vml_mod_le)
 		vnet_mod_destructor(vml);
 
-#if 0
-	free((caddr_t)vnet->ifnet_addrs, M_IFADDR);
-	free((caddr_t)vnet->ifindex2ifnet, M_IFADDR);
-
 	CURVNET_RESTORE();
 
 	/* hopefully, we are finally OK to free the vnet container itself! */
@@ -1140,7 +733,6 @@
 }
 #endif /* VIMAGE */
 
-#ifndef VIMAGE_GLOBALS
 static void
 vi_init(void *unused)
 {


More information about the p4-projects mailing list