+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
+{
+ vxdprintk(VXD_CBIT(xid, 6),
+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
+
+ vxi->exit_code = code;
+ vxi->vx_initpid = 0;
+}
+
+
+void vx_set_persistent(struct vx_info *vxi)
+{
+ vxdprintk(VXD_CBIT(xid, 6),
+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
+
+ get_vx_info(vxi);
+ claim_vx_info(vxi, NULL);
+}
+
+void vx_clear_persistent(struct vx_info *vxi)
+{
+ vxdprintk(VXD_CBIT(xid, 6),
+ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
+
+ release_vx_info(vxi, NULL);
+ put_vx_info(vxi);
+}
+
+void vx_update_persistent(struct vx_info *vxi)
+{
+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
+ vx_set_persistent(vxi);
+ else
+ vx_clear_persistent(vxi);
+}
+
+
+/* task must be current or locked */
+
+void exit_vx_info(struct task_struct *p, int code)
+{
+ struct vx_info *vxi = p->vx_info;
+
+ if (vxi) {
+ atomic_dec(&vxi->cvirt.nr_threads);
+ vx_nproc_dec(p);
+
+ vxi->exit_code = code;
+ release_vx_info(vxi, p);
+ }
+}
+
+void exit_vx_info_early(struct task_struct *p, int code)
+{
+ struct vx_info *vxi = p->vx_info;
+
+ if (vxi) {
+ if (vxi->vx_initpid == p->tgid)
+ vx_exit_init(vxi, p, code);
+ if (vxi->vx_reaper == p)
+ vx_set_reaper(vxi, init_pid_ns.child_reaper);
+ }
+}
+