]> git.decadent.org.uk Git - nfs-utils.git/blob - utils/statd/svc_run.c
14ee663eed5560b58d8c5d18d4aa9a6fd1477a78
[nfs-utils.git] / utils / statd / svc_run.c
1 /*
2  * Copyright (C) 1984 Sun Microsystems, Inc.
3  * Modified by Jeffrey A. Uphoff, 1995, 1997-1999.
4  * Modified by Olaf Kirch, 1996.
5  *
6  * NSM for Linux.
7  */
8
9 /* 
10  * Copyright (c) 2009, Sun Microsystems, Inc.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  * - Redistributions of source code must retain the above copyright notice,
16  *   this list of conditions and the following disclaimer.
17  * - Redistributions in binary form must reproduce the above copyright notice,
18  *   this list of conditions and the following disclaimer in the documentation
19  *   and/or other materials provided with the distribution.
20  * - Neither the name of Sun Microsystems, Inc. nor the names of its
21  *   contributors may be used to endorse or promote products derived
22  *   from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 /* 
38  * This has been modified for my own evil purposes to prevent deadlocks
39  * when two hosts start NSM's simultaneously and try to notify each
40  * other (which mainly occurs during testing), or to stop and smell the
41  * roses when I have callbacks due.
42  * --Jeff Uphoff.
43  */
44
45 /* 
46  * This is the RPC server side idle loop.
47  * Wait for input, call server program.
48  */
49
50 #ifdef HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53
54 #include <errno.h>
55 #include <time.h>
56 #include "statd.h"
57 #include "notlist.h"
58
59 static int      svc_stop = 0;
60
61 /*
62  * This is the global notify list onto which all SM_NOTIFY and CALLBACK
63  * requests are put.
64  */
65 notify_list *   notify = NULL;
66
67 /*
68  * Jump-off function.
69  */
70 void
71 my_svc_exit(void)
72 {
73         svc_stop = 1;
74 }
75
76
77 /*
78  * The heart of the server.  A crib from libc for the most part...
79  */
80 void
81 my_svc_run(void)
82 {
83         FD_SET_TYPE     readfds;
84         int             selret;
85         time_t          now;
86
87         svc_stop = 0;
88
89         for (;;) {
90                 if (svc_stop)
91                         return;
92
93                 /* Ah, there are some notifications to be processed */
94                 while (notify && NL_WHEN(notify) <= time(&now)) {
95                         process_notify_list();
96                 }
97
98                 readfds = SVC_FDSET;
99                 if (notify) {
100                         struct timeval  tv;
101
102                         tv.tv_sec  = NL_WHEN(notify) - now;
103                         tv.tv_usec = 0;
104                         dprintf(N_DEBUG, "Waiting for reply... (timeo %d)",
105                                                         tv.tv_sec);
106                         selret = select(FD_SETSIZE, &readfds,
107                                 (void *) 0, (void *) 0, &tv);
108                 } else {
109                         dprintf(N_DEBUG, "Waiting for client connections.");
110                         selret = select(FD_SETSIZE, &readfds,
111                                 (void *) 0, (void *) 0, (struct timeval *) 0);
112                 }
113
114                 switch (selret) {
115                 case -1:
116                         if (errno == EINTR || errno == ECONNREFUSED
117                          || errno == ENETUNREACH || errno == EHOSTUNREACH)
118                                 continue;
119                         note(N_ERROR, "my_svc_run() - select: %s",
120                                 strerror (errno));
121                         return;
122
123                 case 0:
124                         /* A notify/callback timed out. */
125                         continue;
126
127                 default:
128                         selret -= process_reply(&readfds);
129                         if (selret)
130                                 svc_getreqset(&readfds);
131                 }
132         }
133 }