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>