2 * nfsdcld.c -- NFSv4 client name tracking daemon
4 * Copyright (C) 2011 Red Hat, Jeff Layton <jlayton@redhat.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program 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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
24 #endif /* HAVE_CONFIG_H */
32 #include <sys/types.h>
41 #define PIPEFS_DIR NFS_STATEDIR "/rpc_pipefs"
44 #define DEFAULT_CLD_PATH PIPEFS_DIR "/nfsd/cld"
46 #define UPCALL_VERSION 1
48 /* private data structures */
51 struct event cl_event;
52 struct cld_msg cl_msg;
55 /* global variables */
56 static char *pipepath = DEFAULT_CLD_PATH;
58 static struct option longopts[] =
60 { "help", 0, NULL, 'h' },
61 { "foreground", 0, NULL, 'F' },
62 { "debug", 0, NULL, 'd' },
63 { "pipe", 1, NULL, 'p' },
64 { "storagedir", 1, NULL, 's' },
68 /* forward declarations */
69 static void cldcb(int UNUSED(fd), short which, void *data);
74 printf("%s [ -hFd ] [ -p pipe ] [ -s dir ]\n", progname);
78 cld_pipe_open(struct cld_client *clnt)
82 xlog(D_GENERAL, "%s: opening upcall pipe %s", __func__, pipepath);
83 fd = open(pipepath, O_RDWR, 0);
85 xlog(L_ERROR, "%s: open of %s failed: %m", __func__, pipepath);
89 if (clnt->cl_event.ev_flags & EVLIST_INIT)
90 event_del(&clnt->cl_event);
95 event_set(&clnt->cl_event, clnt->cl_fd, EV_READ, cldcb, clnt);
96 /* event_add is done by the caller */
101 cld_pipe_init(struct cld_client *clnt)
106 ret = cld_pipe_open(clnt);
110 event_add(&clnt->cl_event, NULL);
115 cld_not_implemented(struct cld_client *clnt)
118 ssize_t bsize, wsize;
119 struct cld_msg *cmsg = &clnt->cl_msg;
121 xlog(D_GENERAL, "%s: downcalling with not implemented error", __func__);
124 cmsg->cm_status = -EOPNOTSUPP;
126 bsize = sizeof(*cmsg);
128 wsize = atomicio((void *)write, clnt->cl_fd, cmsg, bsize);
130 xlog(L_ERROR, "%s: problem writing to cld pipe (%ld): %m",
133 /* reopen pipe, just to be sure */
134 ret = cld_pipe_open(clnt);
136 xlog(L_FATAL, "%s: unable to reopen pipe: %d", __func__, ret);
142 cld_create(struct cld_client *clnt)
145 ssize_t bsize, wsize;
146 struct cld_msg *cmsg = &clnt->cl_msg;
148 xlog(D_GENERAL, "%s: create client record.", __func__);
150 ret = sqlite_insert_client(cmsg->cm_u.cm_name.cn_id,
151 cmsg->cm_u.cm_name.cn_len);
153 cmsg->cm_status = ret ? -EREMOTEIO : ret;
155 bsize = sizeof(*cmsg);
157 xlog(D_GENERAL, "Doing downcall with status %d", cmsg->cm_status);
158 wsize = atomicio((void *)write, clnt->cl_fd, cmsg, bsize);
159 if (wsize != bsize) {
160 xlog(L_ERROR, "%s: problem writing to cld pipe (%ld): %m",
162 ret = cld_pipe_open(clnt);
164 xlog(L_FATAL, "%s: unable to reopen pipe: %d",
172 cldcb(int UNUSED(fd), short which, void *data)
175 struct cld_client *clnt = data;
176 struct cld_msg *cmsg = &clnt->cl_msg;
178 if (which != EV_READ)
181 len = atomicio(read, clnt->cl_fd, cmsg, sizeof(*cmsg));
183 xlog(L_ERROR, "%s: pipe read failed: %m", __func__);
188 if (cmsg->cm_vers != UPCALL_VERSION) {
189 xlog(L_ERROR, "%s: unsupported upcall version: %hu",
195 switch(cmsg->cm_cmd) {
200 xlog(L_WARNING, "%s: command %u is not yet implemented",
201 __func__, cmsg->cm_cmd);
202 cld_not_implemented(clnt);
205 event_add(&clnt->cl_event, NULL);
209 main(int argc, char **argv)
213 bool foreground = false;
215 char *storagedir = NULL;
216 struct cld_client clnt;
218 memset(&clnt, 0, sizeof(clnt));
220 progname = strdup(basename(argv[0]));
222 fprintf(stderr, "%s: unable to allocate memory.\n", argv[0]);
230 /* process command-line options */
231 while ((arg = getopt_long(argc, argv, "hdFp:s:", longopts,
235 xlog_config(D_ALL, 1);
259 xlog(L_ERROR, "Unable to daemonize: %m");
264 /* set up storage db */
265 rc = sqlite_maindb_init(storagedir);
267 xlog(L_ERROR, "Failed to open main database: %d", rc);
271 /* set up event handler */
272 rc = cld_pipe_init(&clnt);
276 xlog(D_GENERAL, "%s: Starting event dispatch handler.", __func__);
277 rc = event_dispatch();
279 xlog(L_ERROR, "%s: event_dispatch failed: %m", __func__);