Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Oct 2013 17:10:45 +0000 (UTC)
From:      Will Andrews <will@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r256989 - in projects/vps/sys: kern vps
Message-ID:  <201310231710.r9NHAjgj062554@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: will
Date: Wed Oct 23 17:10:45 2013
New Revision: 256989
URL: http://svnweb.freebsd.org/changeset/base/256989

Log:
  Sync with svn.7he.at/vps/trunk r190.
  
  r190 | klaus | 2013-07-15 09:36:26 -0600 (Mon, 15 Jul 2013) | 5 lines
  Some cleanup and style changes;
  Incremental filedesc restore;
  Changes to dump library.
  
  Submitted by:	Klaus P. Ohrhallinger <k@7he.at>

Modified:
  projects/vps/sys/kern/kern_event.c
  projects/vps/sys/vps/vps_int.h
  projects/vps/sys/vps/vps_libdump.c
  projects/vps/sys/vps/vps_libdump.h
  projects/vps/sys/vps/vps_restore.c
  projects/vps/sys/vps/vps_snapst.c

Modified: projects/vps/sys/kern/kern_event.c
==============================================================================
--- projects/vps/sys/kern/kern_event.c	Wed Oct 23 17:08:50 2013	(r256988)
+++ projects/vps/sys/kern/kern_event.c	Wed Oct 23 17:10:45 2013	(r256989)
@@ -93,8 +93,8 @@ static int	kevent_copyout(void *arg, str
 static int	kevent_copyin(void *arg, struct kevent *kevp, int count);
 /* XXX static*/ int	kqueue_register(struct kqueue *kq, struct kevent *kev,
 		    struct thread *td, int waitok);
-static int	kqueue_acquire(struct file *fp, struct kqueue **kqp);
-static void	kqueue_release(struct kqueue *kq, int locked);
+/* XXX static*/ int	kqueue_acquire(struct file *fp, struct kqueue **kqp);
+/* XXX static*/ void	kqueue_release(struct kqueue *kq, int locked);
 static int	kqueue_expand(struct kqueue *kq, struct filterops *fops,
 		    uintptr_t ident, int waitok);
 static void	kqueue_task(void *arg, int pending);
@@ -1155,7 +1155,7 @@ done:
 	return (error);
 }
 
-static int
+/* XXX static*/ int
 kqueue_acquire(struct file *fp, struct kqueue **kqp)
 {
 	int error;
@@ -1178,7 +1178,7 @@ kqueue_acquire(struct file *fp, struct k
 	return error;
 }
 
-static void
+/* XXX static*/ void
 kqueue_release(struct kqueue *kq, int locked)
 {
 	if (locked)

Modified: projects/vps/sys/vps/vps_int.h
==============================================================================
--- projects/vps/sys/vps/vps_int.h	Wed Oct 23 17:08:50 2013	(r256988)
+++ projects/vps/sys/vps/vps_int.h	Wed Oct 23 17:10:45 2013	(r256989)
@@ -59,8 +59,12 @@ void			(*vps_dumpobj_discard)(struct vps
 				struct vps_dumpobj *o);
 int			(*vps_dumpobj_checkobj)(struct vps_snapst_ctx *ctx,
 				struct vps_dumpobj *o);
+void			(*vps_dumpobj_setcur)(struct vps_snapst_ctx *ctx,
+				struct vps_dumpobj *o);
 struct vps_dumpobj *	(*vps_dumpobj_next)(struct vps_snapst_ctx *ctx);
 struct vps_dumpobj *	(*vps_dumpobj_prev)(struct vps_snapst_ctx *ctx);
+struct vps_dumpobj *	(*vps_dumpobj_peek)(struct vps_snapst_ctx *ctx);
+struct vps_dumpobj *	(*vps_dumpobj_getcur)(struct vps_snapst_ctx *ctx);
 int			(*vps_dumpobj_typeofnext)(struct vps_snapst_ctx
 				*ctx);
 int			(*vps_dumpobj_nextischild)(struct vps_snapst_ctx
@@ -168,8 +172,11 @@ extern struct vps_functions *vps_func;
 #define vdo_close		vps_func->vps_dumpobj_close
 #define vdo_discard		vps_func->vps_dumpobj_discard
 #define vdo_checkobj		vps_func->vps_dumpobj_checkobj
+#define vdo_setcur		vps_func->vps_dumpobj_setcur
 #define vdo_next		vps_func->vps_dumpobj_next
 #define vdo_prev		vps_func->vps_dumpobj_prev
+#define vdo_peek		vps_func->vps_dumpobj_peek
+#define vdo_getcur		vps_func->vps_dumpobj_getcur
 #define vdo_typeofnext		vps_func->vps_dumpobj_typeofnext
 #define vdo_nextischild		vps_func->vps_dumpobj_nextischild
 #define vdo_recurse		vps_func->vps_dumpobj_recurse

Modified: projects/vps/sys/vps/vps_libdump.c
==============================================================================
--- projects/vps/sys/vps/vps_libdump.c	Wed Oct 23 17:08:50 2013	(r256988)
+++ projects/vps/sys/vps/vps_libdump.c	Wed Oct 23 17:10:45 2013	(r256989)
@@ -161,8 +161,11 @@ int vps_dumpobj_append(struct vps_snapst
 void vps_dumpobj_close(struct vps_snapst_ctx *ctx);
 void vps_dumpobj_discard(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o);
 int vps_dumpobj_checkobj(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o);
+void vps_dumpobj_setcur(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o);
 struct vps_dumpobj *vps_dumpobj_next(struct vps_snapst_ctx *ctx);
 struct vps_dumpobj *vps_dumpobj_prev(struct vps_snapst_ctx *ctx);
+struct vps_dumpobj *vps_dumpobj_peek(struct vps_snapst_ctx *ctx);
+struct vps_dumpobj *vps_dumpobj_getcur(struct vps_snapst_ctx *ctx);
 int vps_dumpobj_typeofnext(struct vps_snapst_ctx *ctx);
 int vps_dumpobj_nextischild(struct vps_snapst_ctx *ctx,
     struct vps_dumpobj *op);
@@ -487,6 +490,7 @@ vps_dumpobj_create(struct vps_snapst_ctx
 	o->type = type;
 	o->level = ++ctx->level;
 	o->size = sizeof(*o);
+	o->prio = 0;
 	o->next = ctx->cpos;
 	o->parent = ctx->curobj;
 	if (ctx->elements == 0) {
@@ -701,6 +705,35 @@ vps_dumpobj_typeofnext(struct vps_snapst
 	return (o->type);
 }
 
+struct vps_dumpobj *
+vps_dumpobj_peek(struct vps_snapst_ctx *ctx)
+{
+	struct vps_dumpobj *o;
+
+	if (ctx->relative)
+		return (0);
+
+	/* Assumes that the current object has been validated. */
+	o = ctx->curobj->next;
+	if (o == ctx->rootobj)
+		return (0);
+
+	if (vps_dumpobj_checkobj(ctx, o))
+		return (0);
+
+	return (o);
+}
+
+struct vps_dumpobj *
+vps_dumpobj_getcur(struct vps_snapst_ctx *ctx)
+{
+
+	if (ctx->relative)
+		return (NULL);
+
+	return (ctx->curobj);
+}
+
 int
 vps_dumpobj_nextischild(struct vps_snapst_ctx *ctx, struct vps_dumpobj *op)
 {
@@ -733,6 +766,7 @@ vps_dumpobj_nextischild(struct vps_snaps
 struct vps_dumpobj *
 vps_dumpobj_prev(struct vps_snapst_ctx *ctx)
 {
+
 	if (ctx->relative)
 		return (NULL);
 
@@ -745,6 +779,22 @@ vps_dumpobj_prev(struct vps_snapst_ctx *
 	return (ctx->curobj);
 }
 
+void
+vps_dumpobj_setcur(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o)
+{
+
+	if (ctx->relative)
+		return;
+
+	/* XXX
+	if (vps_dumpobj_checkobj(ctx, o))
+	*/
+
+	ctx->curobj = o;
+
+	/* NOTE: ctx->lastobj is invalid now */
+}
+
 /* Check a single object for sanity. */
 int
 vps_dumpobj_checkobj(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o)
@@ -1217,10 +1267,16 @@ vps_libdump_modevent(module_t mod, int t
 		    vps_dumpobj_discard;
 		vps_func->vps_dumpobj_checkobj =
 		    vps_dumpobj_checkobj;
+		vps_func->vps_dumpobj_setcur =
+		    vps_dumpobj_setcur;
 		vps_func->vps_dumpobj_next =
 		    vps_dumpobj_next;
 		vps_func->vps_dumpobj_prev =
 		    vps_dumpobj_prev;
+		vps_func->vps_dumpobj_peek =
+		    vps_dumpobj_peek;
+		vps_func->vps_dumpobj_getcur =
+		    vps_dumpobj_getcur;
 		vps_func->vps_dumpobj_typeofnext =
 		    vps_dumpobj_typeofnext;
 		vps_func->vps_dumpobj_nextischild =
@@ -1251,8 +1307,11 @@ vps_libdump_modevent(module_t mod, int t
 		vps_func->vps_dumpobj_close = NULL;
 		vps_func->vps_dumpobj_discard = NULL;
 		vps_func->vps_dumpobj_checkobj = NULL;
+		vps_func->vps_dumpobj_setcur = NULL;
 		vps_func->vps_dumpobj_next = NULL;
 		vps_func->vps_dumpobj_prev = NULL;
+		vps_func->vps_dumpobj_peek = NULL;
+		vps_func->vps_dumpobj_getcur = NULL;
 		vps_func->vps_dumpobj_typeofnext = NULL;
 		vps_func->vps_dumpobj_nextischild = NULL;
 		vps_func->vps_dumpobj_recurse = NULL;

Modified: projects/vps/sys/vps/vps_libdump.h
==============================================================================
--- projects/vps/sys/vps/vps_libdump.h	Wed Oct 23 17:08:50 2013	(r256988)
+++ projects/vps/sys/vps/vps_libdump.h	Wed Oct 23 17:10:45 2013	(r256989)
@@ -60,8 +60,11 @@ int vps_dumpobj_append(struct vps_snapst
 void vps_dumpobj_close(struct vps_snapst_ctx *ctx);
 void vps_dumpobj_discard(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o);
 int vps_dumpobj_checkobj(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o);
+void vps_dumpobj_setcur(struct vps_snapst_ctx *ctx, struct vps_dumpobj *o);
 struct vps_dumpobj *vps_dumpobj_next(struct vps_snapst_ctx *ctx);
 struct vps_dumpobj *vps_dumpobj_prev(struct vps_snapst_ctx *ctx);
+struct vps_dumpobj *vps_dumpobj_peek(struct vps_snapst_ctx *ctx);
+struct vps_dumpobj *vps_dumpobj_getcur(struct vps_snapst_ctx *ctx);
 int vps_dumpobj_typeofnext(struct vps_snapst_ctx *ctx);
 int vps_dumpobj_nextischild(struct vps_snapst_ctx *ctx,
     struct vps_dumpobj *op);
@@ -128,7 +131,7 @@ void vps_libdump_printheader(struct vps_
 #define VPS_DUMPOBJT_UCRED              120
 
 #define VPS_DUMPH_MAGIC			0xc0debabe
-#define VPS_DUMPH_VERSION		0x20130709
+#define VPS_DUMPH_VERSION		0x20130715
 #define VPS_DUMPH_MSB			12
 #define VPS_DUMPH_LSB			21
 #define VPS_DUMPH_32BIT			32
@@ -233,7 +236,8 @@ struct vps_dumpobj {
 	uint16 type;
 	uint16 level;	/* level this object is in */
 	uint32 size;	/* size of this object including it's header */
-	uint32 pad0;
+	sint16 prio;	/* priority; 0 == any */
+	uint16 pad0;
 	PTR(parent);	/* offset to parent object (from start of
 			   snapshot) */
 	PTR(next);	/* offset to next object (from start of

Modified: projects/vps/sys/vps/vps_restore.c
==============================================================================
--- projects/vps/sys/vps/vps_restore.c	Wed Oct 23 17:08:50 2013	(r256988)
+++ projects/vps/sys/vps/vps_restore.c	Wed Oct 23 17:10:45 2013	(r256989)
@@ -179,7 +179,7 @@ static int vps_restore_mod_refcnt;
  * * * * * Restore functions. * * * *
  */
 
-static struct ucred * vps_restore_ucred_lookup(struct vps_snapst_ctx *ctx,
+static struct ucred *vps_restore_ucred_lookup(struct vps_snapst_ctx *ctx,
     struct vps *vps, void *orig_ptr);
 
 VPSFUNC
@@ -206,9 +206,12 @@ vps_restore_ucred(struct vps_snapst_ctx 
 
 	if ((ncr = vps_restore_ucred_lookup(ctx, vps, vdcr->cr_origptr)) !=
 	    NULL) {
-		/* XXX debugging */
+		/* debugging
 		panic("%s: double restore, orig_ptr=%p !\n",
 		    __func__, vdcr->cr_origptr);
+		*/
+		DBGR("%s: double restore, orig_ptr=%p !\n",
+		    __func__, vdcr->cr_origptr);
 		/* Already restored. */
 		crfree(ncr);
 		return (0);
@@ -232,8 +235,13 @@ vps_restore_ucred(struct vps_snapst_ctx 
 	ncr->cr_uidinfo = uifind(vdcr->cr_uid);
 	ncr->cr_ruidinfo = uifind(vdcr->cr_ruid);
 
-	/* XXX check that vdcr->cr_groups is big enough
-	   (start of next object) */
+	if ((caddr_t)vdcr->cr_groups +
+	     (sizeof(vdcr->cr_groups[0]) * vdcr->cr_ngroups) >
+	     (caddr_t)o1 + o1->size) {
+		ERRMSG(ctx, "%s: vdcr->cr_groups smaller than specified by "
+		    "vdcr->cr_ngroups=%d\n", __func__, vdcr->cr_ngroups);
+		return (EINVAL);
+	}
 	tmp_groups = malloc(sizeof(tmp_groups[0]) * vdcr->cr_ngroups,
 	    M_TEMP, M_WAITOK);
 	for (i = 0; i < vdcr->cr_ngroups; i++)
@@ -354,7 +362,7 @@ vps_restore_ucred_lookup(struct vps_snap
 
 	if (ncr != NULL) {
 		DBGR("%s: found ucred %p for %p, ncr->ref=%d\n",
-			__func__, ncr, orig_ptr, ncr->cr_ref+1);
+		    __func__, ncr, orig_ptr, ncr->cr_ref+1);
 		crhold(ncr);
 		return (ncr);
 	} else {
@@ -462,7 +470,7 @@ vps_restore_vnet_route_one(struct vps_sn
 	    flags, &rt_entry, vdr->rt_fibnum);
 	if (error)
 		ERRMSG(ctx, "%s: rtrequest_fib: error=%d\n",
-			__func__, error);
+		    __func__, error);
 
 	CURVNET_RESTORE();
 
@@ -512,8 +520,6 @@ vps_restore_vnet_route(struct vps_snapst
 			    vnet, o2, rnh, fibnum, af)))
 				goto out;
 		}
-
-		/* Next. */
 	}
 
   out:
@@ -607,7 +613,8 @@ vps_restore_iface_ifaddr(struct vps_snap
 			vdsaddr += 1;
 		}
 
-		DBGR("%s: AF_INET: [%s] [%08x] [%08x] [%08x]\n",
+		DBGR("%s: AF_INET: if_name=[%s] addr=[%08x] "
+		    "dst=[%08x] mask=[%08x]\n",
 		    __func__, in_alreq->ifra_name,
 		    in_alreq->ifra_addr.sin_addr.s_addr,
 		    in_alreq->ifra_dstaddr.sin_addr.s_addr,
@@ -633,7 +640,6 @@ vps_restore_iface_ifaddr(struct vps_snap
 		break;
 
 	case AF_INET6:
-		DBGR("%s: AF_INET6\n", __func__);
 
 		saddr_offset = offsetof(struct sockaddr_in6, sin6_port);
 
@@ -642,7 +648,7 @@ vps_restore_iface_ifaddr(struct vps_snap
 		memcpy(in6_alreq->ifra_name, ifp->if_xname,
 		    sizeof(in6_alreq->ifra_name));
 
-		DBGR("%s: in6_aliasreq @ %p\n\tifra_name=[%s]\n",
+		DBGR("%s: AF_INET6 in6_aliasreq @ %p\n\tifra_name=[%s]\n",
 		    __func__, in6_alreq, in6_alreq->ifra_name);
 
 		if (vdifaddr->have_addr && vdsaddr->sa_len ==
@@ -733,8 +739,8 @@ vps_restore_iface_ifaddr(struct vps_snap
 		break;
 
 	default:
-		DBGR("%s: unhandled address family %d\n",
-			__func__, vdsaddr->sa_family);
+		ERRMSG(ctx, "%s: unhandled address family %d\n",
+		    __func__, vdsaddr->sa_family);
 		error = EINVAL;
 		goto out;
 	}
@@ -816,15 +822,16 @@ vps_restore_vnet_iface(struct vps_snapst
 					ERRMSG(ctx, "%s: if_clone_create "
 						"returned error = %d\n",
 						__func__, error);
-					goto next_iface;
+					goto out;
 				}
 				nifnetp = ifunit(ifname);
 			}
 
 			if (nifnetp == NULL) {
-				DBGR("%s: ifunit ([%s]) == NULL !\n",
-						__func__, ifname);
-				goto next_iface;
+				ERRMSG(ctx, "%s: ifunit ([%s]) == NULL !\n",
+				    __func__, ifname);
+				error = EINVAL;
+				goto out;
 			}
 
 			if (last_was_epair == 0) {
@@ -835,7 +842,6 @@ vps_restore_vnet_iface(struct vps_snapst
 					ERRMSG(ctx, "%s: if_vps_vmove() "
 					    "error = %d\n",
 					    __func__, error);
-					//goto next_iface;
 					goto out;
 				}
 				if (strcmp(vdifnet->if_dname, "epair") == 0)
@@ -860,10 +866,6 @@ vps_restore_vnet_iface(struct vps_snapst
 
 			/* Next ifaddr. */
 		}
-
-		next_iface:
-		/* Next iface. */
-		;
 	}
 
   out:
@@ -883,7 +885,7 @@ vps_restore_vnet(struct vps_snapst_ctx *
 	o1 = vdo_next(ctx);
 	if (o1->type != VPS_DUMPOBJT_VNET) {
 		DBGR("%s: o1=%p o1->type=%d\n",
-			__func__, o1, o1->type);
+		    __func__, o1, o1->type);
 		error = EINVAL;
 		goto out;
 	}
@@ -905,7 +907,7 @@ vps_restore_vnet(struct vps_snapst_ctx *
 	if ((error = vps_restore_vnet_route(ctx, vps, nvnet)))
 		goto out;
 
- out:
+  out:
 	if (error)
 		*vnetp = NULL;
 	return (error);
@@ -930,7 +932,7 @@ vps_restore_sysentvec(struct vps_snapst_
 
 	if (vps_md_restore_sysentvec(vds->sv_type, &sv) != 0) {
 		ERRMSG(ctx, "%s: unknown sysentvec type: %d\n",
-			__func__, vds->sv_type);
+		    __func__, vds->sv_type);
 		return (EINVAL);
 	}
 
@@ -939,17 +941,11 @@ vps_restore_sysentvec(struct vps_snapst_
 	return (0);
 }
 
-#define KQ_LOCK(kq) do {                                                \
-        mtx_lock(&(kq)->kq_lock);                                       \
-} while (0)
-
-#define KQ_UNLOCK(kq) do {                                                \
-        mtx_unlock(&(kq)->kq_lock);                                       \
-} while (0)
-
-int
-kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td,
-    int waitok);
+/* XXX */
+int kqueue_register(struct kqueue *kq, struct kevent *kev,
+    struct thread *td, int waitok);
+int kqueue_acquire(struct file *fp, struct kqueue **kqp);
+void kqueue_release(struct kqueue *kq, int locked);
 
 VPSFUNC
 static int
@@ -958,11 +954,13 @@ vps_restore_kqueue(struct vps_snapst_ctx
 {
 	struct vps_dumpobj *o1, *o2;
 	struct vps_dump_knote *vdkn;
+	//struct filedesc *cfd;
 	struct kevent *nkev;
 	struct kqueue *kq;
 	struct thread *td;
 	struct file *fp;
 	int error;
+	//int kq_fd;
 	int dfl;
 
 	o1 = vdo_next(ctx);
@@ -976,15 +974,52 @@ vps_restore_kqueue(struct vps_snapst_ctx
 
 	if ((error = sys_kqueue(td, NULL))) {
 		ERRMSG(ctx, "%s: sys_kqueue(): %d\n",
-			__func__, error);
+		    __func__, error);
 		return (error);
 	}
 	fget(td, td->td_retval[0], 0, &fp);
-	kq = fp->f_data;
+	DBGR("%s: kqueue installed at fd %ld\n",
+	    __func__, td->td_retval[0]);
+#if 0
+// rubbish ... delete
+	DBGR("%s: fp=%p fp->f_data=%p fp->f_type=%d\n",
+		__func__, fp, fp->f_data, fp->f_type);
 
-	KQ_LOCK(kq);
-	kq->kq_refcnt++;
-	KQ_UNLOCK(kq);
+	KASSERT(td->td_retval[0] == 0, ("%s: fd != 0\n", __func__));
+
+	if (vdo_typeofnext(ctx) != VPS_DUMPOBJT_KNOTE)
+		return (0);
+
+	o2 = vdo_next(ctx);
+	vdkn = (struct vps_dump_knote *)o2->data;
+	kq_fd = vdkn->ke_ident;
+	vdo_prev(ctx);
+
+	/* Temporarily move kqueue fd to match vdkn->ke_ident. */
+	cfd = td->td_proc->p_fd;
+	FILEDESC_XLOCK(cfd);
+	/* fdisused() is static
+	KASSERT(fdisused(cfd, kq_fd) == 0,
+	    ("%s: fdisused(cfd, kq_fd) != 0\n", __func__));
+	*/
+	fdused(cfd, kq_fd);
+	cfd->fd_ofiles[kq_fd].fde_file = cfd->fd_ofiles[0].fde_file;
+	cfd->fd_ofiles[kq_fd].fde_flags = cfd->fd_ofiles[0].fde_flags;
+	cfd->fd_ofiles[kq_fd].fde_rights = cfd->fd_ofiles[0].fde_rights;
+	cfd->fd_ofiles[0].fde_file = NULL;
+	cfd->fd_ofiles[0].fde_flags = 0;
+	cfd->fd_ofiles[0].fde_rights = 0;
+	fdunused(cfd, 0);
+	FILEDESC_XUNLOCK(cfd);
+	td->td_retval[0] = kq_fd;
+#endif
+
+	kq = NULL;
+	if ((error = kqueue_acquire(fp, &kq)) != 0) {
+		ERRMSG(ctx, "%s: kqueue_acquire(): error=%d\n",
+		    __func__, error);
+		goto out;
+	}
 
 	while (vdo_typeofnext(ctx) == VPS_DUMPOBJT_KNOTE) {
 
@@ -1014,7 +1049,7 @@ vps_restore_kqueue(struct vps_snapst_ctx
 		if (dfl & KN_DISABLED)
 			nkev->flags |= EV_DISABLE;
 
-		// XXX ?! kevp->flags &= ~EV_SYSFLAGS;
+		/* XXX ?! kevp->flags &= ~EV_SYSFLAGS; */
 
 		DBGR("kevent: ident  = 0x%016zx\n", (size_t)nkev->ident);
 		DBGR("kevent: filter = 0x%04hx\n", nkev->filter);
@@ -1025,9 +1060,12 @@ vps_restore_kqueue(struct vps_snapst_ctx
 		    (long unsigned int)nkev->udata);
 
 		error = kqueue_register(kq, nkev, td, 1);
-		if (error)
-			ERRMSG(ctx, "%s: kqueue_register: %d\n",
-				__func__, error);
+		if (error) {
+			ERRMSG(ctx, "%s: kqueue_register(): error=%d\n",
+			    __func__, error);
+			free(nkev, M_TEMP);
+			goto out;
+		}
 
 		free(nkev, M_TEMP);
 
@@ -1038,21 +1076,14 @@ vps_restore_kqueue(struct vps_snapst_ctx
 			//knote_enqueue()
 		*/
 
-		/* Next */
-		//vdo2 = (struct vps_dumpobj *)ctx->cpos;
-		;
 	}
 
-// out2:
-	KQ_LOCK(kq);
-	kq->kq_refcnt--;
-	if (kq->kq_refcnt == 1)
-		wakeup(&kq->kq_refcnt);
-	KQ_UNLOCK(kq);
-// out1:
+  out:
+	if (kq != NULL)
+		kqueue_release(kq, 0);
 	fdrop(fp, td);
 
-	return (0);
+	return (error);
 }
 
 /*
@@ -1104,7 +1135,6 @@ vps_restore_pipe(struct vps_snapst_ctx *
 		 * in another run.
 		 */
 
-		/* XXX CAP_ */
 		fget(curthread, filedes[0], 0, &fp);
 		npp = (struct pipepair *)
 		    ((struct pipe *)fp->f_data)->pipe_pair;
@@ -1116,10 +1146,8 @@ vps_restore_pipe(struct vps_snapst_ctx *
 		ro->orig_ptr = vdp->pi_pair;
 		ro->new_ptr = npp;
 		/* These references have to be released later. */
-		/* XXX CAP_ */
 		fget(curthread, filedes[0], 0, &fp);
 		ro->spare[0] = fp;
-		/* XXX CAP_ */
 		fget(curthread, filedes[1], 0, &fp);
 		ro->spare[1] = fp;
 		SLIST_INSERT_HEAD(&ctx->obj_list, ro, list);
@@ -1127,13 +1155,11 @@ vps_restore_pipe(struct vps_snapst_ctx *
 		if (vdp->pi_localend == vdp->pi_rpipe) {
 
 			/* We want the read endpoint. */
-			/* XXX CAP_ */
 			fget(curthread, filedes[0], 0, &fp);
 			fp->f_data = &npp->pp_rpipe;
 			fdrop(fp, curthread);
 
 			/* Close the write endpoint. */
-			/* XXX CAP_ */
 			fget(curthread, filedes[1], 0, &fp);
 			fdclose(curthread->td_proc->p_fd, fp,
 			    filedes[1], curthread);
@@ -1144,13 +1170,11 @@ vps_restore_pipe(struct vps_snapst_ctx *
 		} else if (vdp->pi_localend == vdp->pi_wpipe) {
 
 			/* We want the write endpoint. */
-			/* XXX CAP_ */
 			fget(curthread, filedes[1], 0, &fp);
 			fp->f_data = &npp->pp_wpipe;
 			fdrop(fp, curthread);
 
 			/* Close the read endpoint. */
-			/* XXX CAP_ */
 			fget(curthread, filedes[0], 0, &fp);
 			fdclose(curthread->td_proc->p_fd, fp,
 			    filedes[0], curthread);
@@ -1159,9 +1183,9 @@ vps_restore_pipe(struct vps_snapst_ctx *
 			curthread->td_retval[0] = filedes[1];
 
 		} else {
-			DBGR("%s: vdp->pi_localend != vdp->pi_rpipe && "
-				"vdp->pi_localend != vdp->pi_wpipe\n",
-				__func__);
+			ERRMSG(ctx, "%s: vdp->pi_localend != vdp->pi_rpipe "
+			    "&& vdp->pi_localend != vdp->pi_wpipe\n",
+			    __func__);
 			/* XXX Clean up. */
 			error = EINVAL;
 			goto out;
@@ -1221,7 +1245,7 @@ vps_restore_pipe(struct vps_snapst_ctx *
 		curthread->td_retval[0] = filedes[0];
 	}
 
- out:
+  out:
 	return (error);
 }
 
@@ -1232,8 +1256,6 @@ vps_restore_cleanup_pipe(struct vps_snap
 {
 	struct vps_restore_obj *obj, *obj2;
 
-	/* XXX Is it safe to fdrop() in different vps context ? */
-
 	SLIST_FOREACH_SAFE(obj, obj_list, list, obj2) {
 		if (obj->type != VPS_DUMPOBJT_PIPE)
 			continue;
@@ -1294,6 +1316,7 @@ vps_sbcheck(struct sockbuf *sb)
                     mbcnt, sb->sb_mbcnt);
                 panic("sbcheck");
 		*/
+		/* debugging */
 		printf("cc %ld != %u || mbcnt %ld != %u\n",
 			len, sb->sb_cc, mbcnt, sb->sb_mbcnt);
 		kdb_enter(KDB_WHY_BREAK, "VPS break to debugger");
@@ -1350,7 +1373,9 @@ vps_restore_mbufchain(struct vps_snapst_
 			if (vdmb->mb_have_data==1)
 				nm->m_data = nm->m_dat + vdmb->mb_data_off;
 
-			//vps_print_ascii(nm->m_dat, nm->m_len);
+			/*
+			vps_print_ascii(nm->m_dat, nm->m_len);
+			*/
 
 		} else if (vdmb->mb_have_ext==1) {
 
@@ -1372,7 +1397,7 @@ vps_restore_mbufchain(struct vps_snapst_
 			*/
 
 			/* checksum */
-			{
+			if (1) {
 				int sum = 0, i;
 
 				for (i = 0; i < nm->m_ext.ext_size; i++)
@@ -1381,14 +1406,14 @@ vps_restore_mbufchain(struct vps_snapst_
 				    "original checksum=%08x\n",
 				    __func__, sum, vdmb->mb_checksum);
 				if (sum != vdmb->mb_checksum) {
-					DBGR("%s: checksum failure !\n",
-					    __func__);
+					ERRMSG(ctx, "%s: checksum "
+					    "failure !\n", __func__);
 					return (-1);
 				}
 			}
 
 		} else {
-			DBGR("%s: DON'T KNOW HOW TO HANDLE MBUF\n",
+			ERRMSG(ctx, "%s: DON'T KNOW HOW TO HANDLE MBUF\n",
 			    __func__);
 			DBGR("%s: vdmb->mb_have_dat=%d "
 			    "vdmb->mb_have_ext=%d\n",
@@ -1480,7 +1505,7 @@ vps_restore_sockbuf(struct vps_snapst_ct
 	mptrs[4] = NULL;
 
 	DBGR("%s: mptrs[]: 0=%p 1=%p 2=%p 3=%p\n",
-			__func__, mptrs[0], mptrs[1], mptrs[2], mptrs[3]);
+	    __func__, mptrs[0], mptrs[1], mptrs[2], mptrs[3]);
 
 	if (vdo_typeofnext(ctx) == VPS_DUMPOBJT_MBUFCHAIN)
 		rc = vps_restore_mbufchain(ctx, vps, mptrs);
@@ -1494,7 +1519,7 @@ vps_restore_sockbuf(struct vps_snapst_ct
 	}
 
 	DBGR("%s: mptrs[]: 0=%p 1=%p 2=%p 3=%p\n",
-			__func__, mptrs[0], mptrs[1], mptrs[2], mptrs[3]);
+	    __func__, mptrs[0], mptrs[1], mptrs[2], mptrs[3]);
 
 	nsb->sb_mb =			mptrs[0];
 	nsb->sb_mbtail =		mptrs[1];
@@ -1513,7 +1538,7 @@ vps_restore_sockbuf(struct vps_snapst_ct
 	nsb->sb_hiwat = 		vdsb->sb_hiwat;
 	nsb->sb_timeo = 		vdsb->sb_timeo;
 	nsb->sb_flags = 		vdsb->sb_flags;
-	/*
+	/* XXX
 	nsb->sb_upcall = 		vdsb->sb_upcall;
 	nsb->sb_upcallarg = 		vdsb->sb_upcallarg;
 	*/
@@ -1560,13 +1585,10 @@ vps_restore_fixup_unixsockets(struct vps
 		}
 
 		if (srvso_new == NULL) {
-			DBGR("%s: srvso_new == NULL for srvso_old=%p\n",
-				__func__, srvso_old);
-			/*
+			ERRMSG(ctx, "%s: srvso_new == NULL for "
+			    "srvso_old=%p\n", __func__, srvso_old);
 			error = EINVAL;
 			break;
-			*/
-			continue;
 		}
 
 		cltunp = sotounpcb((struct socket *)obj1->new_ptr);
@@ -1640,7 +1662,7 @@ vps_restore_socket(struct vps_snapst_ctx
 	cpos += sizeof(*vds);
 
 	if (vdo_typeofnext(ctx) == VPS_DUMPOBJT_UCRED) {
-		vdo_next(ctx);//vps_restore_ucred(ctx, vps);
+		vdo_next(ctx);
 		/* XXX don't put child objects in the middle of data ! */
 		cpos = ctx->cpos;
 	}
@@ -1648,7 +1670,7 @@ vps_restore_socket(struct vps_snapst_ctx
 	curthread->td_ucred = ncr;
 
 	DBGR("%s: family=%d protocol=%d type=%d\n",
-		__func__, vds->so_family, vds->so_protocol, vds->so_type);
+	    __func__, vds->so_family, vds->so_protocol, vds->so_type);
 
 	sockargs.domain = vds->so_family;
 	sockargs.type = vds->so_type;
@@ -1955,12 +1977,6 @@ vps_restore_socket(struct vps_snapst_ctx
 
 		if (vdinpcb->inp_have_ppcb != 0) {
 
-			/*
-			 * XXX For now panic, otherwise we never know
-			 *     if this case can happen.
-			 *     Later just return EINVAL, user might
-			 *     made up rubbish.
-			 */
 			KASSERT(ninpcb->inp_ppcb != NULL,
 				("%s: ninpcb->inp_ppcb == NULL", __func__));
 			if (ninpcb->inp_ppcb == NULL) {
@@ -2040,7 +2056,7 @@ vps_restore_socket(struct vps_snapst_ctx
 
 	default:
 		ERRMSG(ctx, "%s: unhandled protocol family %d\n",
-			__func__, vds->so_family);
+		    __func__, vds->so_family);
 		error = EINVAL;
 		goto out_unlock;
 		break;
@@ -2058,7 +2074,7 @@ vps_restore_socket(struct vps_snapst_ctx
 	 * in curthread->td_retval[0].
 	 */
 
- out_unlock:
+  out_unlock:
 
 	SOCKBUF_UNLOCK(&nso->so_snd);
 	SOCKBUF_UNLOCK(&nso->so_rcv);
@@ -2067,7 +2083,7 @@ vps_restore_socket(struct vps_snapst_ctx
 
 	fdrop(fp, curthread);
 
- out:
+  out:
 
 	if (error) {
 		/* XXX destroy socket. */
@@ -2080,8 +2096,6 @@ vps_restore_socket(struct vps_snapst_ctx
 		crfree(ncr);
 	CURVNET_RESTORE();
 
-	//ctx->cpos = (caddr_t)o1->data + o1->size;
-
 	/* Sockets that were on the accept queue of this socket. */
 	if (vds->so_qlen > 0 || vds->so_incqlen > 0) {
 		DBGR("%s: so_qlen=%d so_incqlen=%d\n",
@@ -2091,7 +2105,7 @@ vps_restore_socket(struct vps_snapst_ctx
 		cfd = curthread->td_proc->p_fd;
 
 		for (i = 0; i < (vds->so_qlen + vds->so_incqlen); i++) {
-			//o2 = (struct vps_dumpobj *)ctx->cpos;
+
 			if ((error = vps_restore_socket(ctx, vps, p)))
 				return (error);
 			/*
@@ -2225,7 +2239,7 @@ vps_restore_file_vnode(struct vps_snapst
 
 	/* Returning new fd index in curthread->td_retval[0]. */
 
- out:
+  out:
 	return (error);
 }
 
@@ -2260,7 +2274,7 @@ vps_restore_file_pts(struct vps_snapst_c
 	vdp = (struct vps_dump_pts *)o1->data;
 
 	if (vdo_typeofnext(ctx) == VPS_DUMPOBJT_UCRED)
-		vdo_next(ctx);//vps_restore_ucred(ctx, vps);
+		vdo_next(ctx);
 
 	o2 = vdo_next(ctx);
 	if (o2->type != VPS_DUMPOBJT_FILE_PATH) {
@@ -2295,7 +2309,7 @@ vps_restore_file_pts(struct vps_snapst_c
 
 	if (found == 0) {
 		ERRMSG(ctx, "%s: pts [%s] not found !\n",
-			__func__, vdfp->fp_path);
+		    __func__, vdfp->fp_path);
 		error = EINVAL;
 		goto out;
 	}
@@ -2315,7 +2329,7 @@ vps_restore_file_pts(struct vps_snapst_c
 	free(termiosp, M_TEMP);
 	if (error)
 		ERRMSG(ctx, "%s: ttydev_ioctl() error=%d\n",
-			__func__, error);
+		    __func__, error);
 	ttyp->t_pgrp = (void*)(size_t)vdp->pt_pgrp_id; /* ID */
 	psc = tty_softc(ttyp);
 	psc->pts_flags = vdp->pt_flags;
@@ -2333,7 +2347,7 @@ vps_restore_file_pts(struct vps_snapst_c
 	ro->new_ptr = ttyp;
 	SLIST_INSERT_HEAD(&ctx->obj_list, ro, list);
 
- out:
+  out:
 	return (error);
 }
 
@@ -2371,20 +2385,29 @@ vps_restore_file_kqueue(struct vps_snaps
 	FILEDESC_XUNLOCK(nfd);
 
 	FILEDESC_XLOCK(cfd);
+#if 0
+//delete
 	/* XXX
 	idx = fd_first_free(cfd, 0, 100);
 	XXX
 	*/
 	idx = 10;
 	fdgrowtable(cfd, idx);
+#endif
+	/* fdalloc() calls fdused() for the new descriptor. */
+	if ((error = fdalloc(curtd, 0, &idx))) {
+		ERRMSG(ctx, "%s: fdalloc(): %d\n", __func__, error);
+		fdrop(nfp, curtd);
+		FILEDESC_XUNLOCK(cfd);
+		goto out;
+	}
 	cfd->fd_ofiles[idx].fde_file = nfp;
 	cfd->fd_ofiles[idx].fde_flags = tmpflags;
 	fdrop(nfp, curtd);
-	fdused(cfd, idx);
 	FILEDESC_XUNLOCK(cfd);
 	curtd->td_retval[0] = idx;
 
- out:
+  out:
 	return (error);
 }
 
@@ -2429,8 +2452,8 @@ vps_restore_file(struct vps_snapst_ctx *
 	ncr = NULL;
 
 	DBGR("%s: index= origidx= origptr=%p type=%d flag=%08x offset=%d\n",
-		__func__, /*vdf->index, vdf->orig_index, */vdf->orig_ptr,
-		vdf->f_type, vdf->f_flag, (int)vdf->f_offset);
+	    __func__, vdf->orig_ptr, vdf->f_type, vdf->f_flag,
+	    (int)vdf->f_offset);
 
 	/* Lookup in list of restored file objects. */
 	SLIST_FOREACH(ro, &ctx->obj_list, list)
@@ -2452,7 +2475,7 @@ vps_restore_file(struct vps_snapst_ctx *
 	}
 
 	if (vdo_typeofnext(ctx) == VPS_DUMPOBJT_UCRED) {
-		vdo_next(ctx);//vps_restore_ucred(ctx, vps);
+		vdo_next(ctx);
 	}
 	ncr = vps_restore_ucred_lookup(ctx, vps, vdf->f_cred);
 	save_ucred = curtd->td_ucred;
@@ -2531,10 +2554,7 @@ vps_restore_file(struct vps_snapst_ctx *
 	FILEDESC_XUNLOCK(cfd);
 
 	fhold(nfp);
-	/* Skip for pseudo ttys for now.
-	if (strncmp((char *)o2->data, "/dev/pts/", strlen("/dev/pts/")))
-	*/
-		nfp->f_offset = vdf->f_offset;
+	nfp->f_offset = vdf->f_offset;
 	fdrop(nfp, curtd);
 
 	/* Restore f_flag XXX */
@@ -2550,7 +2570,7 @@ vps_restore_file(struct vps_snapst_ctx *
 	SLIST_INSERT_HEAD(&ctx->obj_list, ro, list);
 	fdrop(nfp, curtd);
 
- out:
+  out:
 	curtd->td_vps = save_vps;
 	curtd->td_proc->p_fd->fd_rdir = save_rdir;
 	curtd->td_proc->p_fd->fd_cdir = save_cdir;
@@ -2565,20 +2585,81 @@ vps_restore_file(struct vps_snapst_ctx *
 
 VPSFUNC
 static int
+vps_restore_fdset_linkup(struct vps_snapst_ctx *ctx, struct vps *vps,
+    struct vps_dump_filedesc *vdfd, struct proc *p, char is_final)
+{
+	struct vps_restore_obj *ro;
+	struct filedesc *nfd;
+	struct file *nfp;
+	int i;
+	int error = 0;
+
+	nfd = p->p_fd;
+
+	/* Now all files should exist, so link them into fdset. */
+	for (i = 0; i < vdfd->fd_nfiles; i++) {
+
+		DBGR("%s: vdfd->fd_entries[%d].fp = %p\n",
+			__func__, i, vdfd->fd_entries[i].fp);
+		if (vdfd->fd_entries[i].fp == NULL)
+			continue;
+
+		/* Look if already restored in a previous run. */
+		if (i <= nfd->fd_nfiles &&
+		    nfd->fd_ofiles[i].fde_file != NULL)
+			continue;
+
+                /* Lookup in list of restored file objects. */
+		SLIST_FOREACH(ro, &ctx->obj_list, list)
+			if (ro->type == VPS_DUMPOBJT_FILE &&
+			    ro->orig_ptr == vdfd->fd_entries[i].fp)
+				break;
+
+		/* Only return error if this is the final run. */
+		if (is_final != 0 && ro == NULL) {
+			ERRMSG(ctx, "%s: can't find file fp=%p\n",
+			    __func__, vdfd->fd_entries[i].fp);
+			error = EINVAL;
+			goto out;
+		} else if (ro == NULL) {
+			continue;
+		}
+		nfp = (struct file *)ro->new_ptr;
+		fhold(nfp);
+
+		FILEDESC_XLOCK(nfd);
+		if (i >= nfd->fd_nfiles)
+			fdgrowtable(nfd, i);
+		nfd->fd_ofiles[i].fde_file = nfp;
+		nfd->fd_ofiles[i].fde_flags = vdfd->fd_entries[i].flags;
+		nfd->fd_ofiles[i].fde_rights = vdfd->fd_entries[i].rights;
+		fdused(nfd, i);
+		FILEDESC_XUNLOCK(nfd);
+
+		DBGR("%s: linked up fp: idx=%d new=%p orig=%p\n",
+		    __func__, i, ro->new_ptr, ro->orig_ptr);
+	}
+
+  out:
+	return (error);
+}
+
+VPSFUNC
+static int
 vps_restore_fdset(struct vps_snapst_ctx *ctx, struct vps *vps,
     struct proc *p, struct filedesc *orig_fdp)
 {
 	struct vps_dumpobj *o1;
+	struct vps_dumpobj *o2;
+	struct vps_dumpobj *o3;
 	struct vps_dump_filedesc *vdfd;
 	struct vps_restore_obj *ro;
 	struct filedesc *nfd, *cfd;
-	struct file *nfp;
 	struct vps *save_vps;
 	struct ucred *save_ucred;
 	struct vnode *save_rdir;
 	struct vnode *save_cdir;
 	int error = 0;
-	int i;
 
 	if (vdo_typeofnext(ctx) != VPS_DUMPOBJT_FDSET) {
 		/* Lookup in list of restored file objects. */
@@ -2587,13 +2668,13 @@ vps_restore_fdset(struct vps_snapst_ctx 
 			    ro->orig_ptr == orig_fdp)
 				break;
 		if (ro == NULL) {
-			DBGR("%s: fdset orig_ptr=%p not found !\n",
+			ERRMSG(ctx, "%s: fdset orig_ptr=%p not found !\n",
 				__func__, orig_fdp);
 			return (EINVAL);
 		}
 		p->p_fd = fdshare(ro->new_ptr);
 		DBGR("%s: linked shared fdset %p (orig %p) to proc %p/%d\n",
-			__func__, p->p_fd, orig_fdp, p, p->p_pid);
+		    __func__, p->p_fd, orig_fdp, p, p->p_pid);
 
 		return (0);
 	}
@@ -2637,47 +2718,45 @@ vps_restore_fdset(struct vps_snapst_ctx 
 	curthread->td_proc->p_fd->fd_rdir = p->p_fd->fd_rdir;
 	curthread->td_proc->p_fd->fd_cdir = p->p_fd->fd_cdir;
 
+	/* 
+	 * First only restore file objects with priority >= 0,
+	 * then the ones with priority < 0.
+	 */
+
+	o2 = vdo_getcur(ctx);
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310231710.r9NHAjgj062554>