Merge "master" branch into "db".
[cascardo/ovs.git] / lib / unixctl.c
1 /*
2  * Copyright (c) 2008, 2009 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "unixctl.h"
19 #include <assert.h>
20 #include <ctype.h>
21 #include <errno.h>
22 #include <poll.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/socket.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include "coverage.h"
29 #include "dirs.h"
30 #include "dynamic-string.h"
31 #include "fatal-signal.h"
32 #include "list.h"
33 #include "ofpbuf.h"
34 #include "poll-loop.h"
35 #include "shash.h"
36 #include "socket-util.h"
37 #include "util.h"
38
39 #ifndef SCM_CREDENTIALS
40 #include <time.h>
41 #endif
42
43 #define THIS_MODULE VLM_unixctl
44 #include "vlog.h"
45 \f
46 struct unixctl_command {
47     unixctl_cb_func *cb;
48     void *aux;
49 };
50
51 struct unixctl_conn {
52     struct list node;
53     int fd;
54
55     enum { S_RECV, S_PROCESS, S_SEND } state;
56     struct ofpbuf in;
57     struct ds out;
58     size_t out_pos;
59 };
60
61 /* Server for control connection. */
62 struct unixctl_server {
63     char *path;
64     int fd;
65     struct list conns;
66 };
67
68 /* Client for control connection. */
69 struct unixctl_client {
70     char *connect_path;
71     char *bind_path;
72     FILE *stream;
73 };
74
75 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
76
77 static struct shash commands = SHASH_INITIALIZER(&commands);
78
79 static void
80 unixctl_help(struct unixctl_conn *conn, const char *args UNUSED,
81              void *aux UNUSED)
82 {
83     struct ds ds = DS_EMPTY_INITIALIZER;
84     struct shash_node *node;
85
86     ds_put_cstr(&ds, "The available commands are:\n");
87     SHASH_FOR_EACH (node, &commands) {
88         ds_put_format(&ds, "\t%s\n", node->name);
89     }
90     unixctl_command_reply(conn, 214, ds_cstr(&ds));
91     ds_destroy(&ds);
92 }
93
94 void
95 unixctl_command_register(const char *name, unixctl_cb_func *cb, void *aux)
96 {
97     struct unixctl_command *command;
98
99     assert(!shash_find_data(&commands, name)
100            || shash_find_data(&commands, name) == cb);
101     command = xmalloc(sizeof *command);
102     command->cb = cb;
103     command->aux = aux;
104     shash_add(&commands, name, command);
105 }
106
107 static const char *
108 translate_reply_code(int code)
109 {
110     switch (code) {
111     case 200: return "OK";
112     case 201: return "Created";
113     case 202: return "Accepted";
114     case 204: return "No Content";
115     case 211: return "System Status";
116     case 214: return "Help";
117     case 400: return "Bad Request";
118     case 401: return "Unauthorized";
119     case 403: return "Forbidden";
120     case 404: return "Not Found";
121     case 500: return "Internal Server Error";
122     case 501: return "Invalid Argument";
123     case 503: return "Service Unavailable";
124     default: return "Unknown";
125     }
126 }
127
128 void
129 unixctl_command_reply(struct unixctl_conn *conn,
130                       int code, const char *body)
131 {
132     struct ds *out = &conn->out;
133
134     COVERAGE_INC(unixctl_replied);
135     assert(conn->state == S_PROCESS);
136     conn->state = S_SEND;
137     conn->out_pos = 0;
138
139     ds_clear(out);
140     ds_put_format(out, "%03d %s\n", code, translate_reply_code(code));
141     if (body) {
142         const char *p;
143         for (p = body; *p != '\0'; ) {
144             size_t n = strcspn(p, "\n");
145
146             if (*p == '.') {
147                 ds_put_char(out, '.');
148             }
149             ds_put_buffer(out, p, n);
150             ds_put_char(out, '\n');
151             p += n;
152             if (*p == '\n') {
153                 p++;
154             }
155         }
156     }
157     ds_put_cstr(out, ".\n");
158 }
159
160 /* Creates a unixctl server listening on 'path', which may be:
161  *
162  *      - NULL, in which case <rundir>/<program>.<pid>.ctl is used.
163  *
164  *      - A name that does not start with '/', in which case it is put in
165  *        <rundir>.
166  *
167  *      - An absolute path (starting with '/') that gives the exact name of
168  *        the Unix domain socket to listen on.
169  *
170  * A program that (optionally) daemonizes itself should call this function
171  * *after* daemonization, so that the socket name contains the pid of the
172  * daemon instead of the pid of the program that exited.  (Otherwise,
173  * "ovs-appctl --target=<program>" will fail.)
174  *
175  * Returns 0 if successful, otherwise a positive errno value.  If successful,
176  * sets '*serverp' to the new unixctl_server, otherwise to NULL. */
177 int
178 unixctl_server_create(const char *path, struct unixctl_server **serverp)
179 {
180     struct unixctl_server *server;
181     int error;
182
183     unixctl_command_register("help", unixctl_help, NULL);
184
185     server = xmalloc(sizeof *server);
186     list_init(&server->conns);
187
188     if (path) {
189         if (path[0] == '/') {
190             server->path = xstrdup(path);
191         } else {
192             server->path = xasprintf("%s/%s", ovs_rundir, path);
193         }
194     } else {
195         server->path = xasprintf("%s/%s.%ld.ctl", ovs_rundir,
196                                  program_name, (long int) getpid());
197     }
198
199     server->fd = make_unix_socket(SOCK_STREAM, true, false, server->path,
200                                   NULL);
201     if (server->fd < 0) {
202         error = -server->fd;
203         fprintf(stderr, "Could not initialize control socket %s (%s)\n",
204                 server->path, strerror(error));
205         goto error;
206     }
207
208     if (chmod(server->path, S_IRUSR | S_IWUSR) < 0) {
209         error = errno;
210         fprintf(stderr, "Failed to chmod control socket %s (%s)\n",
211                 server->path, strerror(error));
212         goto error;
213     }
214
215     if (listen(server->fd, 10) < 0) {
216         error = errno;
217         fprintf(stderr, "Failed to listen on control socket %s (%s)\n",
218                 server->path, strerror(error));
219         goto error;
220     }
221
222     *serverp = server;
223     return 0;
224
225 error:
226     if (server->fd >= 0) {
227         close(server->fd);
228     }
229     free(server->path);
230     free(server);
231     *serverp = NULL;
232     return error;
233 }
234
235 static void
236 new_connection(struct unixctl_server *server, int fd)
237 {
238     struct unixctl_conn *conn;
239
240     set_nonblocking(fd);
241
242     conn = xmalloc(sizeof *conn);
243     list_push_back(&server->conns, &conn->node);
244     conn->fd = fd;
245     conn->state = S_RECV;
246     ofpbuf_init(&conn->in, 128);
247     ds_init(&conn->out);
248     conn->out_pos = 0;
249 }
250
251 static int
252 run_connection_output(struct unixctl_conn *conn)
253 {
254     while (conn->out_pos < conn->out.length) {
255         size_t bytes_written;
256         int error;
257
258         error = write_fully(conn->fd, conn->out.string + conn->out_pos,
259                             conn->out.length - conn->out_pos, &bytes_written);
260         conn->out_pos += bytes_written;
261         if (error) {
262             return error;
263         }
264     }
265     conn->state = S_RECV;
266     return 0;
267 }
268
269 static void
270 process_command(struct unixctl_conn *conn, char *s)
271 {
272     struct unixctl_command *command;
273     size_t name_len;
274     char *name, *args;
275
276     COVERAGE_INC(unixctl_received);
277     conn->state = S_PROCESS;
278
279     name = s;
280     name_len = strcspn(name, " ");
281     args = name + name_len;
282     args += strspn(args, " ");
283     name[name_len] = '\0';
284
285     command = shash_find_data(&commands, name);
286     if (command) {
287         command->cb(conn, args, command->aux);
288     } else {
289         char *msg = xasprintf("\"%s\" is not a valid command", name);
290         unixctl_command_reply(conn, 400, msg);
291         free(msg);
292     }
293 }
294
295 static int
296 run_connection_input(struct unixctl_conn *conn)
297 {
298     for (;;) {
299         size_t bytes_read;
300         char *newline;
301         int error;
302
303         newline = memchr(conn->in.data, '\n', conn->in.size);
304         if (newline) {
305             char *command = conn->in.data;
306             size_t n = newline - command + 1;
307
308             if (n > 0 && newline[-1] == '\r') {
309                 newline--;
310             }
311             *newline = '\0';
312
313             process_command(conn, command);
314
315             ofpbuf_pull(&conn->in, n);
316             if (!conn->in.size) {
317                 ofpbuf_clear(&conn->in);
318             }
319             return 0;
320         }
321
322         ofpbuf_prealloc_tailroom(&conn->in, 128);
323         error = read_fully(conn->fd, ofpbuf_tail(&conn->in),
324                            ofpbuf_tailroom(&conn->in), &bytes_read);
325         conn->in.size += bytes_read;
326         if (conn->in.size > 65536) {
327             VLOG_WARN_RL(&rl, "excess command length, killing connection");
328             return EPROTO;
329         }
330         if (error) {
331             if (error == EAGAIN || error == EWOULDBLOCK) {
332                 if (!bytes_read) {
333                     return EAGAIN;
334                 }
335             } else {
336                 if (error != EOF || conn->in.size != 0) {
337                     VLOG_WARN_RL(&rl, "read failed: %s",
338                                  (error == EOF
339                                   ? "connection dropped mid-command"
340                                   : strerror(error)));
341                 }
342                 return error;
343             }
344         }
345     }
346 }
347
348 static int
349 run_connection(struct unixctl_conn *conn)
350 {
351     int old_state;
352     do {
353         int error;
354
355         old_state = conn->state;
356         switch (conn->state) {
357         case S_RECV:
358             error = run_connection_input(conn);
359             break;
360
361         case S_PROCESS:
362             error = 0;
363             break;
364
365         case S_SEND:
366             error = run_connection_output(conn);
367             break;
368
369         default:
370             NOT_REACHED();
371         }
372         if (error) {
373             return error;
374         }
375     } while (conn->state != old_state);
376     return 0;
377 }
378
379 static void
380 kill_connection(struct unixctl_conn *conn)
381 {
382     list_remove(&conn->node);
383     ofpbuf_uninit(&conn->in);
384     ds_destroy(&conn->out);
385     close(conn->fd);
386     free(conn);
387 }
388
389 void
390 unixctl_server_run(struct unixctl_server *server)
391 {
392     struct unixctl_conn *conn, *next;
393     int i;
394
395     for (i = 0; i < 10; i++) {
396         int fd = accept(server->fd, NULL, NULL);
397         if (fd < 0) {
398             if (errno != EAGAIN && errno != EWOULDBLOCK) {
399                 VLOG_WARN_RL(&rl, "accept failed: %s", strerror(errno));
400             }
401             break;
402         }
403         new_connection(server, fd);
404     }
405
406     LIST_FOR_EACH_SAFE (conn, next,
407                         struct unixctl_conn, node, &server->conns) {
408         int error = run_connection(conn);
409         if (error && error != EAGAIN) {
410             kill_connection(conn);
411         }
412     }
413 }
414
415 void
416 unixctl_server_wait(struct unixctl_server *server)
417 {
418     struct unixctl_conn *conn;
419
420     poll_fd_wait(server->fd, POLLIN);
421     LIST_FOR_EACH (conn, struct unixctl_conn, node, &server->conns) {
422         if (conn->state == S_RECV) {
423             poll_fd_wait(conn->fd, POLLIN);
424         } else if (conn->state == S_SEND) {
425             poll_fd_wait(conn->fd, POLLOUT);
426         }
427     }
428 }
429
430 /* Destroys 'server' and stops listening for connections. */
431 void
432 unixctl_server_destroy(struct unixctl_server *server)
433 {
434     if (server) {
435         struct unixctl_conn *conn, *next;
436
437         LIST_FOR_EACH_SAFE (conn, next,
438                             struct unixctl_conn, node, &server->conns) {
439             kill_connection(conn);
440         }
441
442         close(server->fd);
443         fatal_signal_unlink_file_now(server->path);
444         free(server->path);
445         free(server);
446     }
447 }
448 \f
449 /* Connects to a Vlog server socket.  'path' should be the name of a Vlog
450  * server socket.  If it does not start with '/', it will be prefixed with
451  * ovs_rundir (e.g. /var/run).
452  *
453  * Returns 0 if successful, otherwise a positive errno value.  If successful,
454  * sets '*clientp' to the new unixctl_client, otherwise to NULL. */
455 int
456 unixctl_client_create(const char *path, struct unixctl_client **clientp)
457 {
458     static int counter;
459     struct unixctl_client *client;
460     int error;
461     int fd = -1;
462
463     /* Determine location. */
464     client = xmalloc(sizeof *client);
465     if (path[0] == '/') {
466         client->connect_path = xstrdup(path);
467     } else {
468         client->connect_path = xasprintf("%s/%s", ovs_rundir, path);
469     }
470     client->bind_path = xasprintf("/tmp/vlog.%ld.%d",
471                                   (long int) getpid(), counter++);
472
473     /* Open socket. */
474     fd = make_unix_socket(SOCK_STREAM, false, false,
475                           client->bind_path, client->connect_path);
476     if (fd < 0) {
477         error = -fd;
478         goto error;
479     }
480
481     /* Bind socket to stream. */
482     client->stream = fdopen(fd, "r+");
483     if (!client->stream) {
484         error = errno;
485         VLOG_WARN("%s: fdopen failed (%s)",
486                   client->connect_path, strerror(error));
487         goto error;
488     }
489     *clientp = client;
490     return 0;
491
492 error:
493     if (fd >= 0) {
494         close(fd);
495     }
496     free(client->connect_path);
497     free(client->bind_path);
498     free(client);
499     *clientp = NULL;
500     return error;
501 }
502
503 /* Destroys 'client'. */
504 void
505 unixctl_client_destroy(struct unixctl_client *client)
506 {
507     if (client) {
508         fatal_signal_unlink_file_now(client->bind_path);
509         free(client->bind_path);
510         free(client->connect_path);
511         fclose(client->stream);
512         free(client);
513     }
514 }
515
516 /* Sends 'request' to the server socket and waits for a reply.  Returns 0 if
517  * successful, otherwise to a positive errno value.  If successful, sets
518  * '*reply' to the reply, which the caller must free, otherwise to NULL. */
519 int
520 unixctl_client_transact(struct unixctl_client *client,
521                         const char *request,
522                         int *reply_code, char **reply_body)
523 {
524     struct ds line = DS_EMPTY_INITIALIZER;
525     struct ds reply = DS_EMPTY_INITIALIZER;
526     int error;
527
528     /* Send 'request' to server.  Add a new-line if 'request' didn't end in
529      * one. */
530     fputs(request, client->stream);
531     if (request[0] == '\0' || request[strlen(request) - 1] != '\n') {
532         putc('\n', client->stream);
533     }
534     if (ferror(client->stream)) {
535         VLOG_WARN("error sending request to %s: %s",
536                   client->connect_path, strerror(errno));
537         return errno;
538     }
539
540     /* Wait for response. */
541     *reply_code = -1;
542     for (;;) {
543         const char *s;
544
545         error = ds_get_line(&line, client->stream);
546         if (error) {
547             VLOG_WARN("error reading reply from %s: %s",
548                       client->connect_path,
549                       (error == EOF ? "unexpected end of file"
550                        : strerror(error)));
551             goto error;
552         }
553
554         s = ds_cstr(&line);
555         if (*reply_code == -1) {
556             if (!isdigit((unsigned char)s[0])
557                     || !isdigit((unsigned char)s[1])
558                     || !isdigit((unsigned char)s[2])) {
559                 VLOG_WARN("reply from %s does not start with 3-digit code",
560                           client->connect_path);
561                 error = EPROTO;
562                 goto error;
563             }
564             sscanf(s, "%3d", reply_code);
565         } else {
566             if (s[0] == '.') {
567                 if (s[1] == '\0') {
568                     break;
569                 }
570                 s++;
571             }
572             ds_put_cstr(&reply, s);
573             ds_put_char(&reply, '\n');
574         }
575     }
576     *reply_body = ds_cstr(&reply);
577     ds_destroy(&line);
578     return 0;
579
580 error:
581     ds_destroy(&line);
582     ds_destroy(&reply);
583     *reply_code = 0;
584     *reply_body = NULL;
585     return error == EOF ? EPROTO : error;
586 }
587
588 /* Returns the path of the server socket to which 'client' is connected.  The
589  * caller must not modify or free the returned string. */
590 const char *
591 unixctl_client_target(const struct unixctl_client *client)
592 {
593     return client->connect_path;
594 }