4 * The kernel statd client.
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
9 #include <linux/types.h>
10 #include <linux/utsname.h>
11 #include <linux/kernel.h>
12 #include <linux/sunrpc/clnt.h>
13 #include <linux/sunrpc/svc.h>
14 #include <linux/lockd/lockd.h>
15 #include <linux/lockd/sm_inter.h>
18 #define NLMDBG_FACILITY NLMDBG_MONITOR
20 static struct rpc_clnt
* nsm_create(void);
22 extern struct rpc_program nsm_program
;
30 * Common procedure for SM_MON/SM_UNMON calls
33 nsm_mon_unmon(struct nlm_host
*host
, u32 proc
, struct nsm_res
*res
)
35 struct rpc_clnt
*clnt
;
44 args
.addr
= host
->h_addr
.sin_addr
.s_addr
;
45 args
.prog
= NLM_PROGRAM
;
47 args
.proc
= NLMPROC_NSM_NOTIFY
;
48 memset(res
, 0, sizeof(*res
));
50 status
= rpc_call(clnt
, proc
, &args
, res
, 0);
52 printk(KERN_DEBUG
"nsm_mon_unmon: rpc failed, status=%d\n",
61 * Set up monitoring of a remote host
64 nsm_monitor(struct nlm_host
*host
)
69 dprintk("lockd: nsm_monitor(%s)\n", host
->h_name
);
71 status
= nsm_mon_unmon(host
, SM_MON
, &res
);
73 if (status
< 0 || res
.status
!= 0)
74 printk(KERN_NOTICE
"lockd: cannot monitor %s\n", host
->h_name
);
76 host
->h_monitored
= 1;
81 * Cease to monitor remote host
84 nsm_unmonitor(struct nlm_host
*host
)
89 dprintk("lockd: nsm_unmonitor(%s)\n", host
->h_name
);
91 status
= nsm_mon_unmon(host
, SM_UNMON
, &res
);
93 printk(KERN_NOTICE
"lockd: cannot unmonitor %s\n", host
->h_name
);
95 host
->h_monitored
= 0;
100 * Create NSM client for the local host
102 static struct rpc_clnt
*
105 struct rpc_xprt
*xprt
;
106 struct rpc_clnt
*clnt
= NULL
;
107 struct sockaddr_in sin
;
109 sin
.sin_family
= AF_INET
;
110 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
113 xprt
= xprt_create_proto(IPPROTO_UDP
, &sin
, NULL
);
117 clnt
= rpc_create_client(xprt
, "localhost",
118 &nsm_program
, SM_VERSION
,
122 clnt
->cl_softrtry
= 1;
124 clnt
->cl_oneshot
= 1;
134 * XDR functions for NSM.
137 xdr_error(struct rpc_rqst
*rqstp
, u32
*p
, void *dummy
)
143 xdr_encode_mon(struct rpc_rqst
*rqstp
, u32
*p
, struct nsm_args
*argp
)
146 u32 addr
= ntohl(argp
->addr
);
148 dprintk("nsm: xdr_encode_mon(%08x, %d, %d, %d)\n",
149 htonl(argp
->addr
), htonl(argp
->proc
),
150 htonl(argp
->vers
), htonl(argp
->proc
));
153 * Use the dotted-quad IP address of the remote host as
154 * identifier. Linux statd always looks up the canonical
155 * hostname first for whatever remote hostname it receives,
156 * so this works alright.
158 sprintf(buffer
, "%d.%d.%d.%d", (addr
>>24) & 0xff, (addr
>>16) & 0xff,
159 (addr
>>8) & 0xff, (addr
) & 0xff);
160 if (!(p
= xdr_encode_string(p
, buffer
))
161 || !(p
= xdr_encode_string(p
, system_utsname
.nodename
)))
163 *p
++ = htonl(argp
->prog
);
164 *p
++ = htonl(argp
->vers
);
165 *p
++ = htonl(argp
->proc
);
167 /* This is the private part. Needed only for SM_MON call */
168 if (rqstp
->rq_task
->tk_msg
.rpc_proc
== SM_MON
) {
175 rqstp
->rq_slen
= xdr_adjust_iovec(rqstp
->rq_svec
, p
);
180 xdr_decode_stat_res(struct rpc_rqst
*rqstp
, u32
*p
, struct nsm_res
*resp
)
182 resp
->status
= ntohl(*p
++);
183 resp
->state
= ntohl(*p
++);
184 dprintk("nsm: xdr_decode_stat_res status %d state %d\n",
185 resp
->status
, resp
->state
);
190 xdr_decode_stat(struct rpc_rqst
*rqstp
, u32
*p
, struct nsm_res
*resp
)
192 resp
->state
= ntohl(*p
++);
196 #define SM_my_name_sz (1+XDR_QUADLEN(SM_MAXSTRLEN))
197 #define SM_my_id_sz (3+1+SM_my_name_sz)
198 #define SM_mon_id_sz (1+XDR_QUADLEN(20)+SM_my_id_sz)
199 #define SM_mon_sz (SM_mon_id_sz+4)
200 #define SM_monres_sz 2
201 #define SM_unmonres_sz 1
204 # define MAX(a, b) (((a) > (b))? (a) : (b))
207 static struct rpc_procinfo nsm_procedures
[] = {
209 (kxdrproc_t
) xdr_error
,
210 (kxdrproc_t
) xdr_error
, 0, 0 },
212 (kxdrproc_t
) xdr_error
,
213 (kxdrproc_t
) xdr_error
, 0, 0 },
215 (kxdrproc_t
) xdr_encode_mon
,
216 (kxdrproc_t
) xdr_decode_stat_res
, MAX(SM_mon_sz
, SM_monres_sz
) << 2, 0 },
218 (kxdrproc_t
) xdr_encode_mon
,
219 (kxdrproc_t
) xdr_decode_stat
, MAX(SM_mon_id_sz
, SM_unmonres_sz
) << 2, 0 },
221 (kxdrproc_t
) xdr_error
,
222 (kxdrproc_t
) xdr_error
, 0, 0 },
224 (kxdrproc_t
) xdr_error
,
225 (kxdrproc_t
) xdr_error
, 0, 0 },
227 (kxdrproc_t
) xdr_error
,
228 (kxdrproc_t
) xdr_error
, 0, 0 },
231 static struct rpc_version nsm_version1
= {
233 sizeof(nsm_procedures
)/sizeof(nsm_procedures
[0]),
237 static struct rpc_version
* nsm_version
[] = {
242 static struct rpc_stat nsm_stats
;
244 struct rpc_program nsm_program
= {
247 sizeof(nsm_version
)/sizeof(nsm_version
[0]),