~ken-vandine/ubuntu/natty/nfs-utils/1.2.2-4ubuntu1

« back to all changes in this revision

Viewing changes to support/nfs/svc_create.c

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar, Anibal Monsalve Salazar, Ben Hutchings
  • Date: 2010-04-06 16:11:22 UTC
  • mfrom: (1.2.18 upstream)
  • Revision ID: james.westby@ubuntu.com-20100406161122-x7erw0q8xiitoyp6
Tags: 1:1.2.2-1
[ Anibal Monsalve Salazar ]
* New upstream release 
  Build depend on libcap-dev
  Set configure option --enable-nfsv41
* X-ref nfsd({7,8})
  02-524255-manpages.patch by Cyril Brulebois
  Closes: 524255

[ Ben Hutchings ]
* Change maintainer to Debian kernel team; move Aníbal to uploaders and
  add myself to uploaders
* Check for nfsd in /proc/filesystems rather than looking for signs of it in
  /proc/kallsyms (Closes: #563104, #572736)
* Document the -n option to svcgssd, thanks to Alberto Gonzalez Iniesta
  (Closes: #451402, #550270)
* Replace upstream reference in package descriptions with Homepage fields,
  and do not refer to the obsolete CVS repository
* Update policy version to 3.8.4; no changes required
* Override lintian error 'init.d-script-missing-dependency-on-remote_fs';
  the init script does work without /usr mounted

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2009 Oracle.  All rights reserved.
 
3
 *
 
4
 * This file is part of nfs-utils.
 
5
 *
 
6
 * nfs-utils is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * nfs-utils is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with nfs-utils.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
#include <memory.h>
 
28
#include <signal.h>
 
29
#include <unistd.h>
 
30
#include <netdb.h>
 
31
 
 
32
#include <netinet/in.h>
 
33
 
 
34
#include <sys/socket.h>
 
35
#include <sys/resource.h>
 
36
 
 
37
#include <rpc/rpc.h>
 
38
#include <rpc/svc.h>
 
39
 
 
40
#ifdef HAVE_TCP_WRAPPER
 
41
#include "tcpwrapper.h"
 
42
#endif
 
43
 
 
44
#include "rpcmisc.h"
 
45
#include "xlog.h"
 
46
 
 
47
#ifdef HAVE_LIBTIRPC
 
48
 
 
49
/*
 
50
 * Set up an appropriate bind address, given @port and @nconf.
 
51
 *
 
52
 * Returns getaddrinfo(3) results if successful.  Caller must
 
53
 * invoke freeaddrinfo(3) on these results.
 
54
 *
 
55
 * Otherwise NULL is returned if an error occurs.
 
56
 */
 
57
__attribute_malloc__
 
58
static struct addrinfo *
 
59
svc_create_bindaddr(struct netconfig *nconf, const uint16_t port)
 
60
{
 
61
        struct addrinfo *ai = NULL;
 
62
        struct addrinfo hint = {
 
63
                .ai_flags       = AI_PASSIVE | AI_NUMERICSERV,
 
64
        };
 
65
        char buf[8];
 
66
        int error;
 
67
 
 
68
        if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
 
69
                hint.ai_family = AF_INET;
 
70
#ifdef IPV6_SUPPORTED
 
71
        else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
 
72
                hint.ai_family = AF_INET6;
 
73
#endif  /* IPV6_SUPPORTED */
 
74
        else {
 
75
                xlog(D_GENERAL, "Unrecognized bind address family: %s",
 
76
                        nconf->nc_protofmly);
 
77
                return NULL;
 
78
        }
 
79
 
 
80
        if (strcmp(nconf->nc_proto, NC_UDP) == 0)
 
81
                hint.ai_protocol = (int)IPPROTO_UDP;
 
82
        else if (strcmp(nconf->nc_proto, NC_TCP) == 0)
 
83
                hint.ai_protocol = (int)IPPROTO_TCP;
 
84
        else {
 
85
                xlog(D_GENERAL, "Unrecognized bind address protocol: %s",
 
86
                        nconf->nc_proto);
 
87
                return NULL;
 
88
        }
 
89
 
 
90
        (void)snprintf(buf, sizeof(buf), "%u", port);
 
91
        error = getaddrinfo(NULL, buf, &hint, &ai);
 
92
        if (error != 0) {
 
93
                xlog(L_ERROR, "Failed to construct bind address: %s",
 
94
                        gai_strerror(error));
 
95
                return NULL;
 
96
        }
 
97
 
 
98
        return ai;
 
99
}
 
100
 
 
101
static unsigned int
 
102
svc_create_nconf(const char *name, const rpcprog_t program,
 
103
                const rpcvers_t version,
 
104
                void (*dispatch)(struct svc_req *, SVCXPRT *),
 
105
                const uint16_t port, struct netconfig *nconf)
 
106
{
 
107
        struct t_bind bindaddr;
 
108
        struct addrinfo *ai;
 
109
        SVCXPRT *xprt;
 
110
 
 
111
        ai = svc_create_bindaddr(nconf, port);
 
112
        if (ai == NULL)
 
113
                return 0;
 
114
 
 
115
        bindaddr.addr.buf = ai->ai_addr;
 
116
        bindaddr.qlen = SOMAXCONN;
 
117
 
 
118
        xprt = svc_tli_create(RPC_ANYFD, nconf, &bindaddr, 0, 0);
 
119
        freeaddrinfo(ai);
 
120
        if (xprt == NULL) {
 
121
                xlog(D_GENERAL, "Failed to create listener xprt "
 
122
                                "(%s, %u, %s)", name, version, nconf->nc_netid);
 
123
                return 0;
 
124
        }
 
125
 
 
126
        if (!svc_reg(xprt, program, version, dispatch, nconf)) {
 
127
                /* svc_reg(3) destroys @xprt in this case */
 
128
                xlog(D_GENERAL, "Failed to register (%s, %u, %s)",
 
129
                                name, version, nconf->nc_netid);
 
130
                return 0;
 
131
        }
 
132
 
 
133
        return 1;
 
134
}
 
135
 
 
136
/**
 
137
 * nfs_svc_create - start up RPC svc listeners
 
138
 * @name: C string containing name of new service
 
139
 * @program: RPC program number to register
 
140
 * @version: RPC version number to register
 
141
 * @dispatch: address of function that handles incoming RPC requests
 
142
 * @port: if not zero, transport listens on this port
 
143
 *
 
144
 * Sets up network transports for receiving RPC requests, and starts
 
145
 * the RPC dispatcher.  Returns the number of started network transports.
 
146
 */
 
147
unsigned int
 
148
nfs_svc_create(__attribute__((unused)) char *name,
 
149
                const rpcprog_t program, const rpcvers_t version,
 
150
                void (*dispatch)(struct svc_req *, SVCXPRT *),
 
151
                const uint16_t port)
 
152
{
 
153
        const struct sigaction create_sigaction = {
 
154
                .sa_handler     = SIG_IGN,
 
155
        };
 
156
        unsigned int visible, up;
 
157
        struct netconfig *nconf;
 
158
        void *handlep;
 
159
 
 
160
        /*
 
161
         * Ignore SIGPIPE to avoid exiting sideways when peers
 
162
         * close their TCP connection while we're trying to reply
 
163
         * to them.
 
164
         */
 
165
        (void)sigaction(SIGPIPE, &create_sigaction, NULL);
 
166
 
 
167
        handlep = setnetconfig();
 
168
        if (handlep == NULL) {
 
169
                xlog(L_ERROR, "Failed to access local netconfig database: %s",
 
170
                        nc_sperror());
 
171
                return 0;
 
172
        }
 
173
 
 
174
        visible = 0;
 
175
        up = 0;
 
176
        while ((nconf = getnetconfig(handlep)) != NULL) {
 
177
                if (!(nconf->nc_flag & NC_VISIBLE))
 
178
                        continue;
 
179
                visible++;
 
180
                up += svc_create_nconf(name, program, version, dispatch,
 
181
                                                port, nconf);
 
182
        }
 
183
 
 
184
        if (visible == 0)
 
185
                xlog(L_ERROR, "Failed to find any visible netconfig entries");
 
186
 
 
187
        if (endnetconfig(handlep) == -1)
 
188
                xlog(L_ERROR, "Failed to close local netconfig database: %s",
 
189
                        nc_sperror());
 
190
 
 
191
        return up;
 
192
}
 
193
 
 
194
/**
 
195
 * nfs_svc_unregister - remove service registrations from local rpcbind database
 
196
 * @program: RPC program number to unregister
 
197
 * @version: RPC version number to unregister
 
198
 *
 
199
 * Removes all registrations for [ @program, @version ] .
 
200
 */
 
201
void
 
202
nfs_svc_unregister(const rpcprog_t program, const rpcvers_t version)
 
203
{
 
204
        if (rpcb_unset(program, version, NULL) == FALSE)
 
205
                xlog(D_GENERAL, "Failed to unregister program %lu, version %lu",
 
206
                        (unsigned long)program, (unsigned long)version);
 
207
}
 
208
 
 
209
#else   /* !HAVE_LIBTIRPC */
 
210
 
 
211
/**
 
212
 * nfs_svc_create - start up RPC svc listeners
 
213
 * @name: C string containing name of new service
 
214
 * @program: RPC program number to register
 
215
 * @version: RPC version number to register
 
216
 * @dispatch: address of function that handles incoming RPC requests
 
217
 * @port: if not zero, transport listens on this port
 
218
 *
 
219
 * Sets up network transports for receiving RPC requests, and starts
 
220
 * the RPC dispatcher.  Returns the number of started network transports.
 
221
 */
 
222
unsigned int
 
223
nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
 
224
                void (*dispatch)(struct svc_req *, SVCXPRT *),
 
225
                const uint16_t port)
 
226
{
 
227
        rpc_init(name, (int)program, (int)version, dispatch, (int)port);
 
228
        return 1;
 
229
}
 
230
 
 
231
/**
 
232
 * nfs_svc_unregister - remove service registrations from local rpcbind database
 
233
 * @program: RPC program number to unregister
 
234
 * @version: RPC version number to unregister
 
235
 *
 
236
 * Removes all registrations for [ @program, @version ] .
 
237
 */
 
238
void
 
239
nfs_svc_unregister(const rpcprog_t program, const rpcvers_t version)
 
240
{
 
241
        if (pmap_unset((unsigned long)program, (unsigned long)version) == FALSE)
 
242
                xlog(D_GENERAL, "Failed to unregister program %lu, version %lu",
 
243
                        (unsigned long)program, (unsigned long)version);
 
244
}
 
245
 
 
246
#endif  /* !HAVE_LIBTIRPC */