@@ -1946,6 +1946,226 @@ int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info)
19461946 return err ;
19471947}
19481948
1949+ /**
1950+ * nfsd_nl_listener_set_doit - set the nfs running sockets
1951+ * @skb: reply buffer
1952+ * @info: netlink metadata and command arguments
1953+ *
1954+ * Return 0 on success or a negative errno.
1955+ */
1956+ int nfsd_nl_listener_set_doit (struct sk_buff * skb , struct genl_info * info )
1957+ {
1958+ struct net * net = genl_info_net (info );
1959+ struct svc_xprt * xprt , * tmp ;
1960+ const struct nlattr * attr ;
1961+ struct svc_serv * serv ;
1962+ LIST_HEAD (permsocks );
1963+ struct nfsd_net * nn ;
1964+ int err , rem ;
1965+
1966+ mutex_lock (& nfsd_mutex );
1967+
1968+ err = nfsd_create_serv (net );
1969+ if (err ) {
1970+ mutex_unlock (& nfsd_mutex );
1971+ return err ;
1972+ }
1973+
1974+ nn = net_generic (net , nfsd_net_id );
1975+ serv = nn -> nfsd_serv ;
1976+
1977+ spin_lock_bh (& serv -> sv_lock );
1978+
1979+ /* Move all of the old listener sockets to a temp list */
1980+ list_splice_init (& serv -> sv_permsocks , & permsocks );
1981+
1982+ /*
1983+ * Walk the list of server_socks from userland and move any that match
1984+ * back to sv_permsocks
1985+ */
1986+ nlmsg_for_each_attr (attr , info -> nlhdr , GENL_HDRLEN , rem ) {
1987+ struct nlattr * tb [NFSD_A_SOCK_MAX + 1 ];
1988+ const char * xcl_name ;
1989+ struct sockaddr * sa ;
1990+
1991+ if (nla_type (attr ) != NFSD_A_SERVER_SOCK_ADDR )
1992+ continue ;
1993+
1994+ if (nla_parse_nested (tb , NFSD_A_SOCK_MAX , attr ,
1995+ nfsd_sock_nl_policy , info -> extack ) < 0 )
1996+ continue ;
1997+
1998+ if (!tb [NFSD_A_SOCK_ADDR ] || !tb [NFSD_A_SOCK_TRANSPORT_NAME ])
1999+ continue ;
2000+
2001+ if (nla_len (tb [NFSD_A_SOCK_ADDR ]) < sizeof (* sa ))
2002+ continue ;
2003+
2004+ xcl_name = nla_data (tb [NFSD_A_SOCK_TRANSPORT_NAME ]);
2005+ sa = nla_data (tb [NFSD_A_SOCK_ADDR ]);
2006+
2007+ /* Put back any matching sockets */
2008+ list_for_each_entry_safe (xprt , tmp , & permsocks , xpt_list ) {
2009+ /* This shouldn't be possible */
2010+ if (WARN_ON_ONCE (xprt -> xpt_net != net )) {
2011+ list_move (& xprt -> xpt_list , & serv -> sv_permsocks );
2012+ continue ;
2013+ }
2014+
2015+ /* If everything matches, put it back */
2016+ if (!strcmp (xprt -> xpt_class -> xcl_name , xcl_name ) &&
2017+ rpc_cmp_addr_port (sa , (struct sockaddr * )& xprt -> xpt_local )) {
2018+ list_move (& xprt -> xpt_list , & serv -> sv_permsocks );
2019+ break ;
2020+ }
2021+ }
2022+ }
2023+
2024+ /* For now, no removing old sockets while server is running */
2025+ if (serv -> sv_nrthreads && !list_empty (& permsocks )) {
2026+ list_splice_init (& permsocks , & serv -> sv_permsocks );
2027+ spin_unlock_bh (& serv -> sv_lock );
2028+ err = - EBUSY ;
2029+ goto out_unlock_mtx ;
2030+ }
2031+
2032+ /* Close the remaining sockets on the permsocks list */
2033+ while (!list_empty (& permsocks )) {
2034+ xprt = list_first_entry (& permsocks , struct svc_xprt , xpt_list );
2035+ list_move (& xprt -> xpt_list , & serv -> sv_permsocks );
2036+
2037+ /*
2038+ * Newly-created sockets are born with the BUSY bit set. Clear
2039+ * it if there are no threads, since nothing can pick it up
2040+ * in that case.
2041+ */
2042+ if (!serv -> sv_nrthreads )
2043+ clear_bit (XPT_BUSY , & xprt -> xpt_flags );
2044+
2045+ set_bit (XPT_CLOSE , & xprt -> xpt_flags );
2046+ spin_unlock_bh (& serv -> sv_lock );
2047+ svc_xprt_close (xprt );
2048+ spin_lock_bh (& serv -> sv_lock );
2049+ }
2050+
2051+ spin_unlock_bh (& serv -> sv_lock );
2052+
2053+ /* walk list of addrs again, open any that still don't exist */
2054+ nlmsg_for_each_attr (attr , info -> nlhdr , GENL_HDRLEN , rem ) {
2055+ struct nlattr * tb [NFSD_A_SOCK_MAX + 1 ];
2056+ const char * xcl_name ;
2057+ struct sockaddr * sa ;
2058+ int ret ;
2059+
2060+ if (nla_type (attr ) != NFSD_A_SERVER_SOCK_ADDR )
2061+ continue ;
2062+
2063+ if (nla_parse_nested (tb , NFSD_A_SOCK_MAX , attr ,
2064+ nfsd_sock_nl_policy , info -> extack ) < 0 )
2065+ continue ;
2066+
2067+ if (!tb [NFSD_A_SOCK_ADDR ] || !tb [NFSD_A_SOCK_TRANSPORT_NAME ])
2068+ continue ;
2069+
2070+ if (nla_len (tb [NFSD_A_SOCK_ADDR ]) < sizeof (* sa ))
2071+ continue ;
2072+
2073+ xcl_name = nla_data (tb [NFSD_A_SOCK_TRANSPORT_NAME ]);
2074+ sa = nla_data (tb [NFSD_A_SOCK_ADDR ]);
2075+
2076+ xprt = svc_find_listener (serv , xcl_name , net , sa );
2077+ if (xprt ) {
2078+ svc_xprt_put (xprt );
2079+ continue ;
2080+ }
2081+
2082+ ret = svc_xprt_create_from_sa (serv , xcl_name , net , sa ,
2083+ SVC_SOCK_ANONYMOUS ,
2084+ get_current_cred ());
2085+ /* always save the latest error */
2086+ if (ret < 0 )
2087+ err = ret ;
2088+ }
2089+
2090+ if (!serv -> sv_nrthreads && list_empty (& nn -> nfsd_serv -> sv_permsocks ))
2091+ nfsd_destroy_serv (net );
2092+
2093+ out_unlock_mtx :
2094+ mutex_unlock (& nfsd_mutex );
2095+
2096+ return err ;
2097+ }
2098+
2099+ /**
2100+ * nfsd_nl_listener_get_doit - get the nfs running listeners
2101+ * @skb: reply buffer
2102+ * @info: netlink metadata and command arguments
2103+ *
2104+ * Return 0 on success or a negative errno.
2105+ */
2106+ int nfsd_nl_listener_get_doit (struct sk_buff * skb , struct genl_info * info )
2107+ {
2108+ struct svc_xprt * xprt ;
2109+ struct svc_serv * serv ;
2110+ struct nfsd_net * nn ;
2111+ void * hdr ;
2112+ int err ;
2113+
2114+ skb = genlmsg_new (GENLMSG_DEFAULT_SIZE , GFP_KERNEL );
2115+ if (!skb )
2116+ return - ENOMEM ;
2117+
2118+ hdr = genlmsg_iput (skb , info );
2119+ if (!hdr ) {
2120+ err = - EMSGSIZE ;
2121+ goto err_free_msg ;
2122+ }
2123+
2124+ mutex_lock (& nfsd_mutex );
2125+ nn = net_generic (genl_info_net (info ), nfsd_net_id );
2126+
2127+ /* no nfs server? Just send empty socket list */
2128+ if (!nn -> nfsd_serv )
2129+ goto out_unlock_mtx ;
2130+
2131+ serv = nn -> nfsd_serv ;
2132+ spin_lock_bh (& serv -> sv_lock );
2133+ list_for_each_entry (xprt , & serv -> sv_permsocks , xpt_list ) {
2134+ struct nlattr * attr ;
2135+
2136+ attr = nla_nest_start (skb , NFSD_A_SERVER_SOCK_ADDR );
2137+ if (!attr ) {
2138+ err = - EINVAL ;
2139+ goto err_serv_unlock ;
2140+ }
2141+
2142+ if (nla_put_string (skb , NFSD_A_SOCK_TRANSPORT_NAME ,
2143+ xprt -> xpt_class -> xcl_name ) ||
2144+ nla_put (skb , NFSD_A_SOCK_ADDR ,
2145+ sizeof (struct sockaddr_storage ),
2146+ & xprt -> xpt_local )) {
2147+ err = - EINVAL ;
2148+ goto err_serv_unlock ;
2149+ }
2150+
2151+ nla_nest_end (skb , attr );
2152+ }
2153+ spin_unlock_bh (& serv -> sv_lock );
2154+ out_unlock_mtx :
2155+ mutex_unlock (& nfsd_mutex );
2156+ genlmsg_end (skb , hdr );
2157+
2158+ return genlmsg_reply (skb , info );
2159+
2160+ err_serv_unlock :
2161+ spin_unlock_bh (& serv -> sv_lock );
2162+ mutex_unlock (& nfsd_mutex );
2163+ err_free_msg :
2164+ nlmsg_free (skb );
2165+
2166+ return err ;
2167+ }
2168+
19492169/**
19502170 * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
19512171 * @net: a freshly-created network namespace
0 commit comments