X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Fnetwork.c;h=1ceb1fcb806c616c4730e520aa51d698fd98e458;hb=34a75f0025b9cf803b6a88db032e6ad6950c9313;hp=66e09de41bd22486d9422f9a6fde2b9b9486cff9;hpb=43bc926fffd92024b46cafaf7350d669ba9ca884;p=linux-2.6.git diff --git a/kernel/vserver/network.c b/kernel/vserver/network.c index 66e09de41..1ceb1fcb8 100644 --- a/kernel/vserver/network.c +++ b/kernel/vserver/network.c @@ -488,13 +488,25 @@ int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, struct sock *sk) void nx_set_persistent(struct nx_info *nxi) { - if (nx_info_flags(nxi, NXF_PERSISTENT, 0)) { - get_nx_info(nxi); - claim_nx_info(nxi, current); - } else { - release_nx_info(nxi, current); - put_nx_info(nxi); - } + get_nx_info(nxi); + claim_nx_info(nxi, current); +} + +void nx_clear_persistent(struct nx_info *nxi) +{ + vxdprintk(VXD_CBIT(nid, 6), + "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id); + + release_nx_info(nxi, current); + put_nx_info(nxi); +} + +void nx_update_persistent(struct nx_info *nxi) +{ + if (nx_info_flags(nxi, NXF_PERSISTENT, 0)) + nx_set_persistent(nxi); + else + nx_clear_persistent(nxi); } /* vserver syscall commands below here */ @@ -577,10 +589,22 @@ int vc_net_create(uint32_t nid, void __user *data) if ((vc_data.flagword & NXF_PERSISTENT)) nx_set_persistent(new_nxi); - vs_net_change(new_nxi, VSC_NETUP); - ret = new_nxi->nx_id; - nx_migrate_task(current, new_nxi); - /* if this fails, we might end up with a hashed nx_info */ + ret = -ENOEXEC; + if (vs_net_change(new_nxi, VSC_NETUP)) + goto out_unhash; + ret = nx_migrate_task(current, new_nxi); + if (!ret) { + /* return context id on success */ + ret = new_nxi->nx_id; + goto out; + } +out_unhash: + /* prepare for context disposal */ + new_nxi->nx_state |= NXS_SHUTDOWN; + if ((vc_data.flagword & NXF_PERSISTENT)) + nx_clear_persistent(new_nxi); + __unhash_nx_info(new_nxi); +out: put_nx_info(new_nxi); return ret; } @@ -668,7 +692,7 @@ int vc_net_remove(uint32_t nid, void __user *data) if (!nxi) return -ESRCH; - switch ((unsigned)vc_data.type) { + switch (vc_data.type) { case NXA_TYPE_ANY: nxi->nbipv4 = 0; break; @@ -728,7 +752,7 @@ int vc_set_nflags(uint32_t id, void __user *data) nxi->nx_flags = vx_mask_flags(nxi->nx_flags, vc_data.flagword, mask); if (trigger & NXF_PERSISTENT) - nx_set_persistent(nxi); + nx_update_persistent(nxi); put_nx_info(nxi); return 0;