diff -NurpP --minimal linux-2.6.11-rc5-vs1.9.4.8/include/linux/vserver/debug.h linux-2.6.11-rc5-vs1.9.4.9/include/linux/vserver/debug.h --- linux-2.6.11-rc5-vs1.9.4.8/include/linux/vserver/debug.h 2005-02-25 12:24:31 +0100 +++ linux-2.6.11-rc5-vs1.9.4.9/include/linux/vserver/debug.h 2005-02-27 22:36:01 +0100 @@ -115,6 +115,7 @@ enum { VXH_UNHASH_VX_INFO, VXH_LOC_VX_INFO, VXH_LOOKUP_VX_INFO, + VXH_CREATE_VX_INFO, }; struct _vx_hist_entry { @@ -298,6 +299,19 @@ static inline void vxh_lookup_vx_info(un preempt_enable(); } +static inline void vxh_create_vx_info(unsigned arg, struct vx_info *vxi) +{ + struct _vx_hist_entry *entry; + + preempt_disable(); + entry = vxh_advance(VXH_HERE()); + __vxh_copy_vxi(entry, vxi); + entry->ll.arg = arg; + entry->type = VXH_CREATE_VX_INFO; + preempt_enable(); +} + + extern void vxh_dump_history(void); #else /* CONFIG_VSERVER_HISTORY */ diff -NurpP --minimal linux-2.6.11-rc5-vs1.9.4.8/kernel/vserver/context.c linux-2.6.11-rc5-vs1.9.4.9/kernel/vserver/context.c --- linux-2.6.11-rc5-vs1.9.4.8/kernel/vserver/context.c 2005-02-25 12:24:31 +0100 +++ linux-2.6.11-rc5-vs1.9.4.9/kernel/vserver/context.c 2005-02-27 22:39:15 +0100 @@ -33,6 +33,7 @@ #include #include +#include #include #include "cvirt_init.h" @@ -314,6 +315,55 @@ out_unlock: return vxi; } +/* __create_vx_info() + + * create the requested context + * get() it and hash it */ + +static struct vx_info * __create_vx_info(int id) +{ + struct vx_info *new, *vxi = NULL; + + vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id); + + if (!(new = __alloc_vx_info(id))) { + return ERR_PTR(-ENOMEM); + } + + /* required to make dynamic xids unique */ + spin_lock(&vx_info_hash_lock); + + /* dynamic context requested */ + if (id == VX_DYNAMIC_ID) { + id = __vx_dynamic_id(); + if (!id) { + printk(KERN_ERR "no dynamic context available.\n"); + goto out_unlock; + } + new->vx_id = id; + } + /* existing context requested */ + else if ((vxi = __lookup_vx_info(id))) { + /* context in setup is not available */ + vxdprintk(VXD_CBIT(xid, 0), + "create_vx_info(%d) = %p (already there)", id, vxi); + vxi = ERR_PTR(-EINVAL); + goto out_unlock; + } + + /* new context requested */ + vxdprintk(VXD_CBIT(xid, 0), + "create_vx_info(%d) = %p (new)", id, new); + __hash_vx_info(get_vx_info(new)); + vxi = new, new = NULL; + +out_unlock: + spin_unlock(&vx_info_hash_lock); + vxh_create_vx_info(id, vxi); + if (new) + __dealloc_vx_info(new); + return vxi; +} /* exported stuff */ @@ -595,21 +645,22 @@ int vc_ctx_create(uint32_t xid, void __u if ((xid >= MIN_D_CONTEXT) && (xid != VX_DYNAMIC_ID)) return -EINVAL; - if (xid < 1) + if (xid < 2) return -EINVAL; - new_vxi = __loc_vx_info(xid, &ret); - if (!new_vxi) - return ret; + new_vxi = __create_vx_info(xid); + if (IS_ERR(new_vxi)) + return PTR_ERR(new_vxi); +/* if (!(new_vxi->vx_flags & VXF_STATE_SETUP)) { ret = -EEXIST; goto out_put; } +*/ ret = new_vxi->vx_id; vx_migrate_task(current, new_vxi); /* if this fails, we might end up with a hashed vx_info */ -out_put: put_vx_info(new_vxi); return ret; } diff -NurpP --minimal linux-2.6.11-rc5-vs1.9.4.8/kernel/vserver/history.c linux-2.6.11-rc5-vs1.9.4.9/kernel/vserver/history.c --- linux-2.6.11-rc5-vs1.9.4.8/kernel/vserver/history.c 2005-02-25 12:24:31 +0100 +++ linux-2.6.11-rc5-vs1.9.4.9/kernel/vserver/history.c 2005-02-27 22:34:23 +0100 @@ -125,9 +125,11 @@ void vxh_dump_entry(struct _vx_hist_entr case VXH_LOC_VX_INFO: case VXH_LOOKUP_VX_INFO: + case VXH_CREATE_VX_INFO: printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n", VXH_LOC_ARGS(e), - (e->type==VXH_LOC_VX_INFO)?"loc":"lookup", + (e->type==VXH_CREATE_VX_INFO)?"create": + ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"), e->ll.arg, VXH_VXI_ARGS(e)); break; }