summaryrefslogtreecommitdiff
path: root/usr.sbin/rpc.lockd
diff options
context:
space:
mode:
authorNikolay Sturm <sturm@cvs.openbsd.org>2008-06-15 04:48:04 +0000
committerNikolay Sturm <sturm@cvs.openbsd.org>2008-06-15 04:48:04 +0000
commitd0f0e294512e78991d770f3c4557bb8d9e45e005 (patch)
tree1919d80f1bc05093c77e9a46bf911d13f66dee1a /usr.sbin/rpc.lockd
parenteab79369c74387e8fe798e1ddf1c49f0b4fc7551 (diff)
add glue for rpc.lockd to talk to rpc.statd
"just get it in" deraadt
Diffstat (limited to 'usr.sbin/rpc.lockd')
-rw-r--r--usr.sbin/rpc.lockd/lockd.c10
-rw-r--r--usr.sbin/rpc.lockd/lockd_lock.c64
-rw-r--r--usr.sbin/rpc.lockd/procs.c16
3 files changed, 87 insertions, 3 deletions
diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c
index 206651b352d..6849f1be5ae 100644
--- a/usr.sbin/rpc.lockd/lockd.c
+++ b/usr.sbin/rpc.lockd/lockd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lockd.c,v 1.10 2008/06/13 23:56:28 jmc Exp $ */
+/* $OpenBSD: lockd.c,v 1.11 2008/06/15 04:48:03 sturm Exp $ */
/*
* Copyright (c) 1995
@@ -54,6 +54,7 @@ int debug_level = 0; /* 0 = no debugging syslog() calls */
int _rpcsvcdirty = 0;
int grace_expired;
+void nlm_prog_0(struct svc_req *, SVCXPRT *);
void nlm_prog_1(struct svc_req *, SVCXPRT *);
void nlm_prog_3(struct svc_req *, SVCXPRT *);
void nlm_prog_4(struct svc_req *, SVCXPRT *);
@@ -91,6 +92,8 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
}
+
+ (void) pmap_unset(NLM_PROG, NLM_SM);
(void) pmap_unset(NLM_PROG, NLM_VERS);
(void) pmap_unset(NLM_PROG, NLM_VERSX);
(void) pmap_unset(NLM_PROG, NLM_VERS4);
@@ -100,6 +103,11 @@ main(int argc, char *argv[])
fprintf(stderr, "cannot create udp service.\n");
exit(1);
}
+ if (!svc_register(transp, NLM_PROG, NLM_SM,
+ (void (*) (struct svc_req *, SVCXPRT *)) nlm_prog_0, IPPROTO_UDP)) {
+ fprintf(stderr, "unable to register (NLM_PROG, NLM_SM, udp).\n");
+ exit(1);
+ }
if (!svc_register(transp, NLM_PROG, NLM_VERS,
(void (*) (struct svc_req *, SVCXPRT *)) nlm_prog_1, IPPROTO_UDP)) {
fprintf(stderr, "unable to register (NLM_PROG, NLM_VERS, udp).\n");
diff --git a/usr.sbin/rpc.lockd/lockd_lock.c b/usr.sbin/rpc.lockd/lockd_lock.c
index c650fc32cea..9a84aa20e50 100644
--- a/usr.sbin/rpc.lockd/lockd_lock.c
+++ b/usr.sbin/rpc.lockd/lockd_lock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lockd_lock.c,v 1.3 2008/06/15 03:58:38 sturm Exp $ */
+/* $OpenBSD: lockd_lock.c,v 1.4 2008/06/15 04:48:03 sturm Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -125,6 +125,19 @@ void send_granted(struct file_lock *, int);
void siglock(void);
void sigunlock(void);
+/* list of hosts we monitor */
+LIST_HEAD(hostlst_head, host);
+struct hostlst_head hostlst_head = LIST_HEAD_INITIALIZER(hostlst_head);
+
+/* struct describing a lock */
+struct host {
+ LIST_ENTRY(host) hostlst;
+ char name[SM_MAXSTRLEN+1];
+ int refcnt;
+};
+
+void do_mon(const char *);
+
#define LL_FH 0x01
#define LL_NAME 0x02
#define LL_SVID 0x04
@@ -311,6 +324,7 @@ getlock(nlm4_lockargs * lckarg, struct svc_req *rqstp, int flags)
lckarg->alock.svid);
newfl->status = LKST_WAITING;
LIST_INSERT_HEAD(&lcklst_head, newfl, lcklst);
+ do_mon(lckarg->alock.caller_name);
sigunlock();
return (flags & LOCK_V4) ?
nlm4_blocked : nlm_blocked;
@@ -336,6 +350,7 @@ getlock(nlm4_lockargs * lckarg, struct svc_req *rqstp, int flags)
/* case nlm_granted: is the same as nlm4_granted */
case nlm4_blocked:
/* case nlm_blocked: is the same as nlm4_blocked */
+ do_mon(lckarg->alock.caller_name);
break;
default:
lfree(newfl);
@@ -747,6 +762,53 @@ sigunlock(void)
}
}
+/* monitor a host through rpc.statd, and keep a ref count */
+void
+do_mon(const char *hostname)
+{
+ static char localhost[] = "localhost";
+ struct host *hp;
+ struct mon my_mon;
+ struct sm_stat_res result;
+ int retval;
+
+ LIST_FOREACH(hp, &hostlst_head, hostlst) {
+ if (strcmp(hostname, hp->name) == 0) {
+ /* already monitored, just bump refcnt */
+ hp->refcnt++;
+ return;
+ }
+ }
+ /* not found, have to create an entry for it */
+ hp = malloc(sizeof(struct host));
+ if (hp == NULL) {
+ syslog(LOG_WARNING, "can't monitor host %s (%m)", hostname);
+ return;
+ }
+ strlcpy(hp->name, hostname, sizeof(hp->name));
+ hp->refcnt = 1;
+ syslog(LOG_DEBUG, "monitoring host %s", hostname);
+ memset(&my_mon, 0, sizeof(my_mon));
+ my_mon.mon_id.mon_name = hp->name;
+ my_mon.mon_id.my_id.my_name = localhost;
+ my_mon.mon_id.my_id.my_prog = NLM_PROG;
+ my_mon.mon_id.my_id.my_vers = NLM_SM;
+ my_mon.mon_id.my_id.my_proc = NLM_SM_NOTIFY;
+ if ((retval = callrpc(localhost, SM_PROG, SM_VERS, SM_MON, xdr_mon,
+ (void *)&my_mon, xdr_sm_stat_res, (void *)&result)) != 0) {
+ syslog(LOG_WARNING, "rpc to statd failed (%s)",
+ clnt_sperrno((enum clnt_stat)retval));
+ free(hp);
+ return;
+ }
+ if (result.res_stat == stat_fail) {
+ syslog(LOG_WARNING, "statd failed");
+ free(hp);
+ return;
+ }
+ LIST_INSERT_HEAD(&hostlst_head, hp, hostlst);
+}
+
void
notify(const char *hostname, int state)
{
diff --git a/usr.sbin/rpc.lockd/procs.c b/usr.sbin/rpc.lockd/procs.c
index 018b705c71e..7d8acc9a15f 100644
--- a/usr.sbin/rpc.lockd/procs.c
+++ b/usr.sbin/rpc.lockd/procs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procs.c,v 1.12 2008/06/13 21:32:26 sturm Exp $ */
+/* $OpenBSD: procs.c,v 1.13 2008/06/15 04:48:03 sturm Exp $ */
/*
* Copyright (c) 1995
@@ -1134,3 +1134,17 @@ nlm4_free_all_4_svc(nlm_notify *arg, struct svc_req *rqstp)
log_from_addr("nlm4_free_all", rqstp);
return &dummy;
}
+
+/* nlm_sm_notify --------------------------------------------------------- */
+/*
+ * Purpose: called by rpc.statd when a monitored host state changes.
+ * Returns: Nothing
+ */
+void *
+/*ARGSUSED*/
+nlm_sm_notify_0_svc(struct nlm_sm_status *arg, struct svc_req *rqstp)
+{
+ static char dummy;
+ notify(arg->mon_name, arg->state);
+ return &dummy;
+}