@@ -1946,6 +1946,226 @@ int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info)
1946
1946
return err ;
1947
1947
}
1948
1948
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
+
1949
2169
/**
1950
2170
* nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
1951
2171
* @net: a freshly-created network namespace
0 commit comments