if_vmove: return proper error status
if_vmove can fail if it lost a race and the vnet's already been moved. The callers (and their callers) can generally cope with this, but right now success is assumed. Plumb out the ENOENT from if_detach_internal if it happens so that the error's properly reported to userland. Reviewed by: bz, kp MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D22780
This commit is contained in:
parent
4a8b575c6b
commit
c7bab2a7ca
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356536
27
sys/net/if.c
27
sys/net/if.c
@ -274,7 +274,7 @@ static void if_attach_internal(struct ifnet *, int, struct if_clone *);
|
||||
static int if_detach_internal(struct ifnet *, int, struct if_clone **);
|
||||
static void if_siocaddmulti(void *, int);
|
||||
#ifdef VIMAGE
|
||||
static void if_vmove(struct ifnet *, struct vnet *);
|
||||
static int if_vmove(struct ifnet *, struct vnet *);
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
@ -1257,7 +1257,7 @@ if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp)
|
||||
* unused if_index in target vnet and calls if_grow() if necessary,
|
||||
* and finally find an unused if_xname for the target vnet.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
|
||||
{
|
||||
struct if_clone *ifc;
|
||||
@ -1283,7 +1283,7 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
|
||||
*/
|
||||
rc = if_detach_internal(ifp, 1, &ifc);
|
||||
if (rc != 0)
|
||||
return;
|
||||
return (rc);
|
||||
|
||||
/*
|
||||
* Unlink the ifnet from ifindex_table[] in current vnet, and shrink
|
||||
@ -1327,6 +1327,7 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
|
||||
#endif
|
||||
|
||||
CURVNET_RESTORE();
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1337,6 +1338,7 @@ if_vmove_loan(struct thread *td, struct ifnet *ifp, char *ifname, int jid)
|
||||
{
|
||||
struct prison *pr;
|
||||
struct ifnet *difp;
|
||||
int error;
|
||||
|
||||
/* Try to find the prison within our visibility. */
|
||||
sx_slock(&allprison_lock);
|
||||
@ -1372,13 +1374,14 @@ if_vmove_loan(struct thread *td, struct ifnet *ifp, char *ifname, int jid)
|
||||
CURVNET_RESTORE();
|
||||
|
||||
/* Move the interface into the child jail/vnet. */
|
||||
if_vmove(ifp, pr->pr_vnet);
|
||||
error = if_vmove(ifp, pr->pr_vnet);
|
||||
|
||||
/* Report the new if_xname back to the userland. */
|
||||
sprintf(ifname, "%s", ifp->if_xname);
|
||||
/* Report the new if_xname back to the userland on success. */
|
||||
if (error == 0)
|
||||
sprintf(ifname, "%s", ifp->if_xname);
|
||||
|
||||
prison_free(pr);
|
||||
return (0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1387,6 +1390,7 @@ if_vmove_reclaim(struct thread *td, char *ifname, int jid)
|
||||
struct prison *pr;
|
||||
struct vnet *vnet_dst;
|
||||
struct ifnet *ifp;
|
||||
int error;
|
||||
|
||||
/* Try to find the prison within our visibility. */
|
||||
sx_slock(&allprison_lock);
|
||||
@ -1422,14 +1426,15 @@ if_vmove_reclaim(struct thread *td, char *ifname, int jid)
|
||||
}
|
||||
|
||||
/* Get interface back from child jail/vnet. */
|
||||
if_vmove(ifp, vnet_dst);
|
||||
error = if_vmove(ifp, vnet_dst);
|
||||
CURVNET_RESTORE();
|
||||
|
||||
/* Report the new if_xname back to the userland. */
|
||||
sprintf(ifname, "%s", ifp->if_xname);
|
||||
/* Report the new if_xname back to the userland on success. */
|
||||
if (error == 0)
|
||||
sprintf(ifname, "%s", ifp->if_xname);
|
||||
|
||||
prison_free(pr);
|
||||
return (0);
|
||||
return (error);
|
||||
}
|
||||
#endif /* VIMAGE */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user