ia64/xen-unstable

view tools/xenstore/xenstored_core.c @ 9094:cff782f65c4d

Fix printf.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Thu Mar 02 02:35:23 2006 +0100 (2006-03-02)
parents 689da5e0a970
children 2274f293af41
line source
1 /*
2 Simple prototype Xen Store Daemon providing simple tree-like database.
3 Copyright (C) 2005 Rusty Russell IBM Corporation
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/socket.h>
23 #include <sys/select.h>
24 #include <sys/un.h>
25 #include <sys/time.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <stdbool.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <syslog.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <dirent.h>
37 #include <getopt.h>
38 #include <signal.h>
39 #include <assert.h>
40 #include <setjmp.h>
42 //#define DEBUG
43 #include "utils.h"
44 #include "list.h"
45 #include "talloc.h"
46 #include "xs_lib.h"
47 #include "xenstored_core.h"
48 #include "xenstored_watch.h"
49 #include "xenstored_transaction.h"
50 #include "xenstored_domain.h"
51 #include "xenctrl.h"
52 #include "tdb.h"
54 extern int eventchn_fd; /* in xenstored_domain.c */
56 static bool verbose;
57 LIST_HEAD(connections);
58 static int tracefd = -1;
59 static int reopen_log_pipe[2];
60 static char *tracefile = NULL;
61 static TDB_CONTEXT *tdb_ctx;
63 static void corrupt(struct connection *conn, const char *fmt, ...);
64 static void check_store();
66 #define log(...) \
67 do { \
68 char *s = talloc_asprintf(NULL, __VA_ARGS__); \
69 trace("%s\n", s); \
70 syslog(LOG_ERR, "%s", s); \
71 talloc_free(s); \
72 } while (0)
75 #ifdef TESTING
76 static bool failtest = false;
78 /* We override talloc's malloc. */
79 void *test_malloc(size_t size)
80 {
81 /* 1 in 20 means only about 50% of connections establish. */
82 if (failtest && (random() % 32) == 0)
83 return NULL;
84 return malloc(size);
85 }
87 static void stop_failtest(int signum __attribute__((unused)))
88 {
89 failtest = false;
90 }
92 /* Need these before we #define away write_all/mkdir in testing.h */
93 bool test_write_all(int fd, void *contents, unsigned int len);
94 bool test_write_all(int fd, void *contents, unsigned int len)
95 {
96 if (failtest && (random() % 8) == 0) {
97 if (len)
98 len = random() % len;
99 write(fd, contents, len);
100 errno = ENOSPC;
101 return false;
102 }
103 return xs_write_all(fd, contents, len);
104 }
106 int test_mkdir(const char *dir, int perms);
107 int test_mkdir(const char *dir, int perms)
108 {
109 if (failtest && (random() % 8) == 0) {
110 errno = ENOSPC;
111 return -1;
112 }
113 return mkdir(dir, perms);
114 }
115 #endif /* TESTING */
117 #include "xenstored_test.h"
119 TDB_CONTEXT *tdb_context(struct connection *conn)
120 {
121 /* conn = NULL used in manual_node at setup. */
122 if (!conn || !conn->transaction)
123 return tdb_ctx;
124 return tdb_transaction_context(conn->transaction);
125 }
127 bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb)
128 {
129 if (rename(newname, xs_daemon_tdb()) != 0)
130 return false;
131 tdb_close(tdb_ctx);
132 tdb_ctx = talloc_steal(talloc_autofree_context(), newtdb);
133 return true;
134 }
136 static char *sockmsg_string(enum xsd_sockmsg_type type)
137 {
138 switch (type) {
139 case XS_DEBUG: return "DEBUG";
140 case XS_DIRECTORY: return "DIRECTORY";
141 case XS_READ: return "READ";
142 case XS_GET_PERMS: return "GET_PERMS";
143 case XS_WATCH: return "WATCH";
144 case XS_UNWATCH: return "UNWATCH";
145 case XS_TRANSACTION_START: return "TRANSACTION_START";
146 case XS_TRANSACTION_END: return "TRANSACTION_END";
147 case XS_INTRODUCE: return "INTRODUCE";
148 case XS_RELEASE: return "RELEASE";
149 case XS_GET_DOMAIN_PATH: return "GET_DOMAIN_PATH";
150 case XS_WRITE: return "WRITE";
151 case XS_MKDIR: return "MKDIR";
152 case XS_RM: return "RM";
153 case XS_SET_PERMS: return "SET_PERMS";
154 case XS_WATCH_EVENT: return "WATCH_EVENT";
155 case XS_ERROR: return "ERROR";
156 case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED";
157 default:
158 return "**UNKNOWN**";
159 }
160 }
162 void trace(const char *fmt, ...)
163 {
164 va_list arglist;
165 char *str;
166 char sbuf[1024];
167 int ret;
169 if (tracefd < 0)
170 return;
172 /* try to use a static buffer */
173 va_start(arglist, fmt);
174 ret = vsnprintf(sbuf, 1024, fmt, arglist);
175 va_end(arglist);
177 if (ret <= 1024) {
178 write(tracefd, sbuf, ret);
179 return;
180 }
182 /* fail back to dynamic allocation */
183 va_start(arglist, fmt);
184 str = talloc_vasprintf(NULL, fmt, arglist);
185 va_end(arglist);
186 write(tracefd, str, strlen(str));
187 talloc_free(str);
188 }
190 static void trace_io(const struct connection *conn,
191 const char *prefix,
192 const struct buffered_data *data)
193 {
194 unsigned int i;
195 time_t now;
196 struct tm *tm;
198 if (tracefd < 0)
199 return;
201 now = time(NULL);
202 tm = localtime(&now);
204 trace("%s %p %p %04d%02d%02d %02d:%02d:%02d %s (", prefix, conn,
205 conn->transaction, tm->tm_year + 1900, tm->tm_mon + 1,
206 tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
207 sockmsg_string(data->hdr.msg.type));
209 for (i = 0; i < data->hdr.msg.len; i++)
210 trace("%c", (data->buffer[i] != '\0') ? data->buffer[i] : ' ');
211 trace(")\n");
212 }
214 void trace_create(const void *data, const char *type)
215 {
216 trace("CREATE %s %p\n", type, data);
217 }
219 void trace_destroy(const void *data, const char *type)
220 {
221 trace("DESTROY %s %p\n", type, data);
222 }
224 /**
225 * Signal handler for SIGHUP, which requests that the trace log is reopened
226 * (in the main loop). A single byte is written to reopen_log_pipe, to awaken
227 * the select() in the main loop.
228 */
229 static void trigger_reopen_log(int signal __attribute__((unused)))
230 {
231 char c = 'A';
232 write(reopen_log_pipe[1], &c, 1);
233 }
236 static void reopen_log()
237 {
238 if (tracefile) {
239 if (tracefd > 0)
240 close(tracefd);
242 tracefd = open(tracefile, O_WRONLY|O_CREAT|O_APPEND, 0600);
244 if (tracefd < 0)
245 perror("Could not open tracefile");
246 else
247 trace("\n***\n");
248 }
249 }
252 static bool write_messages(struct connection *conn)
253 {
254 int ret;
255 struct buffered_data *out;
257 out = list_top(&conn->out_list, struct buffered_data, list);
258 if (out == NULL)
259 return true;
261 if (out->inhdr) {
262 if (verbose)
263 xprintf("Writing msg %s (%.*s) out to %p\n",
264 sockmsg_string(out->hdr.msg.type),
265 out->hdr.msg.len,
266 out->buffer, conn);
267 ret = conn->write(conn, out->hdr.raw + out->used,
268 sizeof(out->hdr) - out->used);
269 if (ret < 0)
270 return false;
272 out->used += ret;
273 if (out->used < sizeof(out->hdr))
274 return true;
276 out->inhdr = false;
277 out->used = 0;
279 /* Second write might block if non-zero. */
280 if (out->hdr.msg.len && !conn->domain)
281 return true;
282 }
284 ret = conn->write(conn, out->buffer + out->used,
285 out->hdr.msg.len - out->used);
286 if (ret < 0)
287 return false;
289 out->used += ret;
290 if (out->used != out->hdr.msg.len)
291 return true;
293 trace_io(conn, "OUT", out);
295 list_del(&out->list);
296 talloc_free(out);
298 return true;
299 }
301 static int destroy_conn(void *_conn)
302 {
303 struct connection *conn = _conn;
305 /* Flush outgoing if possible, but don't block. */
306 if (!conn->domain) {
307 fd_set set;
308 struct timeval none;
310 FD_ZERO(&set);
311 FD_SET(conn->fd, &set);
312 none.tv_sec = none.tv_usec = 0;
314 while (!list_empty(&conn->out_list)
315 && select(conn->fd+1, NULL, &set, NULL, &none) == 1)
316 if (!write_messages(conn))
317 break;
318 close(conn->fd);
319 }
320 list_del(&conn->list);
321 trace_destroy(conn, "connection");
322 return 0;
323 }
326 static void set_fd(int fd, fd_set *set, int *max)
327 {
328 if (fd < 0)
329 return;
330 FD_SET(fd, set);
331 if (fd > *max)
332 *max = fd;
333 }
336 static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock)
337 {
338 struct connection *i;
339 int max = -1;
341 FD_ZERO(inset);
342 FD_ZERO(outset);
344 set_fd(sock, inset, &max);
345 set_fd(ro_sock, inset, &max);
346 set_fd(eventchn_fd, inset, &max);
347 set_fd(reopen_log_pipe[0], inset, &max);
348 list_for_each_entry(i, &connections, list) {
349 if (i->domain)
350 continue;
351 set_fd(i->fd, inset, &max);
352 if (!list_empty(&i->out_list))
353 FD_SET(i->fd, outset);
354 }
355 return max;
356 }
358 static int destroy_fd(void *_fd)
359 {
360 int *fd = _fd;
361 close(*fd);
362 return 0;
363 }
365 /* Return a pointer to an fd, self-closing and attached to this pathname. */
366 int *talloc_open(const char *pathname, int flags, int mode)
367 {
368 int *fd;
370 fd = talloc(pathname, int);
371 *fd = open(pathname, flags, mode);
372 if (*fd < 0) {
373 int saved_errno = errno;
374 talloc_free(fd);
375 errno = saved_errno;
376 return NULL;
377 }
378 talloc_set_destructor(fd, destroy_fd);
379 return fd;
380 }
382 /* Is child a subnode of parent, or equal? */
383 bool is_child(const char *child, const char *parent)
384 {
385 unsigned int len = strlen(parent);
387 /* / should really be "" for this algorithm to work, but that's a
388 * usability nightmare. */
389 if (streq(parent, "/"))
390 return true;
392 if (strncmp(child, parent, len) != 0)
393 return false;
395 return child[len] == '/' || child[len] == '\0';
396 }
398 /* If it fails, returns NULL and sets errno. */
399 static struct node *read_node(struct connection *conn, const char *name)
400 {
401 TDB_DATA key, data;
402 uint32_t *p;
403 struct node *node;
405 key.dptr = (void *)name;
406 key.dsize = strlen(name);
407 data = tdb_fetch(tdb_context(conn), key);
409 if (data.dptr == NULL) {
410 if (tdb_error(tdb_context(conn)) == TDB_ERR_NOEXIST)
411 errno = ENOENT;
412 else
413 errno = EIO;
414 return NULL;
415 }
417 node = talloc(name, struct node);
418 node->name = talloc_strdup(node, name);
419 node->parent = NULL;
420 node->tdb = tdb_context(conn);
421 talloc_steal(node, data.dptr);
423 /* Datalen, childlen, number of permissions */
424 p = (uint32_t *)data.dptr;
425 node->num_perms = p[0];
426 node->datalen = p[1];
427 node->childlen = p[2];
429 /* Permissions are struct xs_permissions. */
430 node->perms = (void *)&p[3];
431 /* Data is binary blob (usually ascii, no nul). */
432 node->data = node->perms + node->num_perms;
433 /* Children is strings, nul separated. */
434 node->children = node->data + node->datalen;
436 return node;
437 }
439 static bool write_node(struct connection *conn, const struct node *node)
440 {
441 TDB_DATA key, data;
442 void *p;
444 key.dptr = (void *)node->name;
445 key.dsize = strlen(node->name);
447 data.dsize = 3*sizeof(uint32_t)
448 + node->num_perms*sizeof(node->perms[0])
449 + node->datalen + node->childlen;
450 data.dptr = talloc_size(node, data.dsize);
451 ((uint32_t *)data.dptr)[0] = node->num_perms;
452 ((uint32_t *)data.dptr)[1] = node->datalen;
453 ((uint32_t *)data.dptr)[2] = node->childlen;
454 p = data.dptr + 3 * sizeof(uint32_t);
456 memcpy(p, node->perms, node->num_perms*sizeof(node->perms[0]));
457 p += node->num_perms*sizeof(node->perms[0]);
458 memcpy(p, node->data, node->datalen);
459 p += node->datalen;
460 memcpy(p, node->children, node->childlen);
462 /* TDB should set errno, but doesn't even set ecode AFAICT. */
463 if (tdb_store(tdb_context(conn), key, data, TDB_REPLACE) != 0) {
464 errno = ENOSPC;
465 return false;
466 }
467 return true;
468 }
470 static enum xs_perm_type perm_for_conn(struct connection *conn,
471 struct xs_permissions *perms,
472 unsigned int num)
473 {
474 unsigned int i;
475 enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
477 if (!conn->can_write)
478 mask &= ~XS_PERM_WRITE;
480 /* Owners and tools get it all... */
481 if (!conn->id || perms[0].id == conn->id)
482 return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
484 for (i = 1; i < num; i++)
485 if (perms[i].id == conn->id)
486 return perms[i].perms & mask;
488 return perms[0].perms & mask;
489 }
491 static char *get_parent(const char *node)
492 {
493 char *slash = strrchr(node + 1, '/');
494 if (!slash)
495 return talloc_strdup(node, "/");
496 return talloc_asprintf(node, "%.*s", (int)(slash - node), node);
497 }
499 /* What do parents say? */
500 static enum xs_perm_type ask_parents(struct connection *conn, const char *name)
501 {
502 struct node *node;
504 do {
505 name = get_parent(name);
506 node = read_node(conn, name);
507 if (node)
508 break;
509 } while (!streq(name, "/"));
511 /* No permission at root? We're in trouble. */
512 if (!node)
513 corrupt(conn, "No permissions file at root");
515 return perm_for_conn(conn, node->perms, node->num_perms);
516 }
518 /* We have a weird permissions system. You can allow someone into a
519 * specific node without allowing it in the parents. If it's going to
520 * fail, however, we don't want the errno to indicate any information
521 * about the node. */
522 static int errno_from_parents(struct connection *conn, const char *node,
523 int errnum, enum xs_perm_type perm)
524 {
525 /* We always tell them about memory failures. */
526 if (errnum == ENOMEM)
527 return errnum;
529 if (ask_parents(conn, node) & perm)
530 return errnum;
531 return EACCES;
532 }
534 /* If it fails, returns NULL and sets errno. */
535 struct node *get_node(struct connection *conn,
536 const char *name,
537 enum xs_perm_type perm)
538 {
539 struct node *node;
541 if (!name || !is_valid_nodename(name)) {
542 errno = EINVAL;
543 return NULL;
544 }
545 node = read_node(conn, name);
546 /* If we don't have permission, we don't have node. */
547 if (node) {
548 if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
549 != perm)
550 node = NULL;
551 }
552 /* Clean up errno if they weren't supposed to know. */
553 if (!node)
554 errno = errno_from_parents(conn, name, errno, perm);
555 return node;
556 }
558 static struct buffered_data *new_buffer(void *ctx)
559 {
560 struct buffered_data *data;
562 data = talloc_zero(ctx, struct buffered_data);
563 if (data == NULL)
564 return NULL;
566 data->inhdr = true;
567 return data;
568 }
570 /* Return length of string (including nul) at this offset. */
571 static unsigned int get_string(const struct buffered_data *data,
572 unsigned int offset)
573 {
574 const char *nul;
576 if (offset >= data->used)
577 return 0;
579 nul = memchr(data->buffer + offset, 0, data->used - offset);
580 if (!nul)
581 return 0;
583 return nul - (data->buffer + offset) + 1;
584 }
586 /* Break input into vectors, return the number, fill in up to num of them. */
587 unsigned int get_strings(struct buffered_data *data,
588 char *vec[], unsigned int num)
589 {
590 unsigned int off, i, len;
592 off = i = 0;
593 while ((len = get_string(data, off)) != 0) {
594 if (i < num)
595 vec[i] = data->buffer + off;
596 i++;
597 off += len;
598 }
599 return i;
600 }
602 void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
603 const void *data, unsigned int len)
604 {
605 struct buffered_data *bdata;
607 /* Message is a child of the connection context for auto-cleanup. */
608 bdata = new_buffer(conn);
609 bdata->buffer = talloc_array(bdata, char, len);
611 /* Echo request header in reply unless this is an async watch event. */
612 if (type != XS_WATCH_EVENT) {
613 memcpy(&bdata->hdr.msg, &conn->in->hdr.msg,
614 sizeof(struct xsd_sockmsg));
615 } else {
616 memset(&bdata->hdr.msg, 0, sizeof(struct xsd_sockmsg));
617 }
619 /* Update relevant header fields and fill in the message body. */
620 bdata->hdr.msg.type = type;
621 bdata->hdr.msg.len = len;
622 memcpy(bdata->buffer, data, len);
624 /* Queue for later transmission. */
625 list_add_tail(&bdata->list, &conn->out_list);
626 }
628 /* Some routines (write, mkdir, etc) just need a non-error return */
629 void send_ack(struct connection *conn, enum xsd_sockmsg_type type)
630 {
631 send_reply(conn, type, "OK", sizeof("OK"));
632 }
634 void send_error(struct connection *conn, int error)
635 {
636 unsigned int i;
638 for (i = 0; error != xsd_errors[i].errnum; i++) {
639 if (i == ARRAY_SIZE(xsd_errors) - 1) {
640 eprintf("xenstored: error %i untranslatable", error);
641 i = 0; /* EINVAL */
642 break;
643 }
644 }
645 send_reply(conn, XS_ERROR, xsd_errors[i].errstring,
646 strlen(xsd_errors[i].errstring) + 1);
647 }
649 static bool valid_chars(const char *node)
650 {
651 /* Nodes can have lots of crap. */
652 return (strspn(node,
653 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
654 "abcdefghijklmnopqrstuvwxyz"
655 "0123456789-/_@") == strlen(node));
656 }
658 bool is_valid_nodename(const char *node)
659 {
660 /* Must start in /. */
661 if (!strstarts(node, "/"))
662 return false;
664 /* Cannot end in / (unless it's just "/"). */
665 if (strends(node, "/") && !streq(node, "/"))
666 return false;
668 /* No double //. */
669 if (strstr(node, "//"))
670 return false;
672 return valid_chars(node);
673 }
675 /* We expect one arg in the input: return NULL otherwise. */
676 static const char *onearg(struct buffered_data *in)
677 {
678 if (!in->used || get_string(in, 0) != in->used)
679 return NULL;
680 return in->buffer;
681 }
683 static char *perms_to_strings(const void *ctx,
684 struct xs_permissions *perms, unsigned int num,
685 unsigned int *len)
686 {
687 unsigned int i;
688 char *strings = NULL;
689 char buffer[MAX_STRLEN(unsigned int) + 1];
691 for (*len = 0, i = 0; i < num; i++) {
692 if (!xs_perm_to_string(&perms[i], buffer))
693 return NULL;
695 strings = talloc_realloc(ctx, strings, char,
696 *len + strlen(buffer) + 1);
697 strcpy(strings + *len, buffer);
698 *len += strlen(buffer) + 1;
699 }
700 return strings;
701 }
703 char *canonicalize(struct connection *conn, const char *node)
704 {
705 const char *prefix;
707 if (!node || strstarts(node, "/"))
708 return (char *)node;
709 prefix = get_implicit_path(conn);
710 if (prefix)
711 return talloc_asprintf(node, "%s/%s", prefix, node);
712 return (char *)node;
713 }
715 bool check_event_node(const char *node)
716 {
717 if (!node || !strstarts(node, "@")) {
718 errno = EINVAL;
719 return false;
720 }
721 return true;
722 }
724 static void send_directory(struct connection *conn, const char *name)
725 {
726 struct node *node;
728 name = canonicalize(conn, name);
729 node = get_node(conn, name, XS_PERM_READ);
730 if (!node) {
731 send_error(conn, errno);
732 return;
733 }
735 send_reply(conn, XS_DIRECTORY, node->children, node->childlen);
736 }
738 static void do_read(struct connection *conn, const char *name)
739 {
740 struct node *node;
742 name = canonicalize(conn, name);
743 node = get_node(conn, name, XS_PERM_READ);
744 if (!node) {
745 send_error(conn, errno);
746 return;
747 }
749 send_reply(conn, XS_READ, node->data, node->datalen);
750 }
752 static void delete_node_single(struct connection *conn, struct node *node)
753 {
754 TDB_DATA key;
756 key.dptr = (void *)node->name;
757 key.dsize = strlen(node->name);
759 if (tdb_delete(tdb_context(conn), key) != 0)
760 corrupt(conn, "Could not delete '%s'", node->name);
761 }
763 /* Must not be / */
764 static char *basename(const char *name)
765 {
766 return strrchr(name, '/') + 1;
767 }
769 static struct node *construct_node(struct connection *conn, const char *name)
770 {
771 const char *base;
772 unsigned int baselen;
773 struct node *parent, *node;
774 char *children, *parentname = get_parent(name);
776 /* If parent doesn't exist, create it. */
777 parent = read_node(conn, parentname);
778 if (!parent)
779 parent = construct_node(conn, parentname);
780 if (!parent)
781 return NULL;
783 /* Add child to parent. */
784 base = basename(name);
785 baselen = strlen(base) + 1;
786 children = talloc_array(name, char, parent->childlen + baselen);
787 memcpy(children, parent->children, parent->childlen);
788 memcpy(children + parent->childlen, base, baselen);
789 parent->children = children;
790 parent->childlen += baselen;
792 /* Allocate node */
793 node = talloc(name, struct node);
794 node->tdb = tdb_context(conn);
795 node->name = talloc_strdup(node, name);
797 /* Inherit permissions, except domains own what they create */
798 node->num_perms = parent->num_perms;
799 node->perms = talloc_memdup(node, parent->perms,
800 node->num_perms * sizeof(node->perms[0]));
801 if (conn && conn->id)
802 node->perms[0].id = conn->id;
804 /* No children, no data */
805 node->children = node->data = NULL;
806 node->childlen = node->datalen = 0;
807 node->parent = parent;
808 return node;
809 }
811 static int destroy_node(void *_node)
812 {
813 struct node *node = _node;
814 TDB_DATA key;
816 if (streq(node->name, "/"))
817 corrupt(NULL, "Destroying root node!");
819 key.dptr = (void *)node->name;
820 key.dsize = strlen(node->name);
822 tdb_delete(node->tdb, key);
823 return 0;
824 }
826 static struct node *create_node(struct connection *conn,
827 const char *name,
828 void *data, unsigned int datalen)
829 {
830 struct node *node, *i;
832 node = construct_node(conn, name);
833 if (!node)
834 return NULL;
836 node->data = data;
837 node->datalen = datalen;
839 /* We write out the nodes down, setting destructor in case
840 * something goes wrong. */
841 for (i = node; i; i = i->parent) {
842 if (!write_node(conn, i))
843 return NULL;
844 talloc_set_destructor(i, destroy_node);
845 }
847 /* OK, now remove destructors so they stay around */
848 for (i = node; i; i = i->parent)
849 talloc_set_destructor(i, NULL);
850 return node;
851 }
853 /* path, data... */
854 static void do_write(struct connection *conn, struct buffered_data *in)
855 {
856 unsigned int offset, datalen;
857 struct node *node;
858 char *vec[1] = { NULL }; /* gcc4 + -W + -Werror fucks code. */
859 char *name;
861 /* Extra "strings" can be created by binary data. */
862 if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
863 send_error(conn, EINVAL);
864 return;
865 }
867 offset = strlen(vec[0]) + 1;
868 datalen = in->used - offset;
870 name = canonicalize(conn, vec[0]);
871 node = get_node(conn, name, XS_PERM_WRITE);
872 if (!node) {
873 /* No permissions, invalid input? */
874 if (errno != ENOENT) {
875 send_error(conn, errno);
876 return;
877 }
878 node = create_node(conn, name, in->buffer + offset, datalen);
879 if (!node) {
880 send_error(conn, errno);
881 return;
882 }
883 } else {
884 node->data = in->buffer + offset;
885 node->datalen = datalen;
886 if (!write_node(conn, node)){
887 send_error(conn, errno);
888 return;
889 }
890 }
892 add_change_node(conn->transaction, name, false);
893 fire_watches(conn, name, false);
894 send_ack(conn, XS_WRITE);
895 }
897 static void do_mkdir(struct connection *conn, const char *name)
898 {
899 struct node *node;
901 name = canonicalize(conn, name);
902 node = get_node(conn, name, XS_PERM_WRITE);
904 /* If it already exists, fine. */
905 if (!node) {
906 /* No permissions? */
907 if (errno != ENOENT) {
908 send_error(conn, errno);
909 return;
910 }
911 node = create_node(conn, name, NULL, 0);
912 if (!node) {
913 send_error(conn, errno);
914 return;
915 }
916 add_change_node(conn->transaction, name, false);
917 fire_watches(conn, name, false);
918 }
919 send_ack(conn, XS_MKDIR);
920 }
922 static void delete_node(struct connection *conn, struct node *node)
923 {
924 unsigned int i;
926 /* Delete self, then delete children. If we crash, then the worst
927 that can happen is the children will continue to take up space, but
928 will otherwise be unreachable. */
929 delete_node_single(conn, node);
931 /* Delete children, too. */
932 for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
933 struct node *child;
935 child = read_node(conn,
936 talloc_asprintf(node, "%s/%s", node->name,
937 node->children + i));
938 if (child) {
939 delete_node(conn, child);
940 }
941 else {
942 trace("delete_node: No child '%s/%s' found!\n",
943 node->name, node->children + i);
944 /* Skip it, we've already deleted the parent. */
945 }
946 }
947 }
949 /* Delete memory using memmove. */
950 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
951 {
952 memmove(mem + off, mem + off + len, total - off - len);
953 }
955 static bool delete_child(struct connection *conn,
956 struct node *node, const char *childname)
957 {
958 unsigned int i;
960 for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
961 if (streq(node->children+i, childname)) {
962 memdel(node->children, i, strlen(childname) + 1,
963 node->childlen);
964 node->childlen -= strlen(childname) + 1;
965 return write_node(conn, node);
966 }
967 }
968 corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
969 return false;
970 }
973 static int _rm(struct connection *conn, struct node *node, const char *name)
974 {
975 /* Delete from parent first, then if we crash, the worst that can
976 happen is the child will continue to take up space, but will
977 otherwise be unreachable. */
978 struct node *parent = read_node(conn, get_parent(name));
979 if (!parent) {
980 send_error(conn, EINVAL);
981 return 0;
982 }
984 if (!delete_child(conn, parent, basename(name))) {
985 send_error(conn, EINVAL);
986 return 0;
987 }
989 delete_node(conn, node);
990 return 1;
991 }
994 static void internal_rm(const char *name)
995 {
996 char *tname = talloc_strdup(NULL, name);
997 struct node *node = read_node(NULL, tname);
998 if (node)
999 _rm(NULL, node, tname);
1000 talloc_free(tname);
1004 static void do_rm(struct connection *conn, const char *name)
1006 struct node *node;
1008 name = canonicalize(conn, name);
1009 node = get_node(conn, name, XS_PERM_WRITE);
1010 if (!node) {
1011 /* Didn't exist already? Fine, if parent exists. */
1012 if (errno == ENOENT) {
1013 node = read_node(conn, get_parent(name));
1014 if (node) {
1015 send_ack(conn, XS_RM);
1016 return;
1018 /* Restore errno, just in case. */
1019 errno = ENOENT;
1021 send_error(conn, errno);
1022 return;
1025 if (streq(name, "/")) {
1026 send_error(conn, EINVAL);
1027 return;
1030 if (_rm(conn, node, name)) {
1031 add_change_node(conn->transaction, name, true);
1032 fire_watches(conn, name, true);
1033 send_ack(conn, XS_RM);
1038 static void do_get_perms(struct connection *conn, const char *name)
1040 struct node *node;
1041 char *strings;
1042 unsigned int len;
1044 name = canonicalize(conn, name);
1045 node = get_node(conn, name, XS_PERM_READ);
1046 if (!node) {
1047 send_error(conn, errno);
1048 return;
1051 strings = perms_to_strings(node, node->perms, node->num_perms, &len);
1052 if (!strings)
1053 send_error(conn, errno);
1054 else
1055 send_reply(conn, XS_GET_PERMS, strings, len);
1058 static void do_set_perms(struct connection *conn, struct buffered_data *in)
1060 unsigned int num;
1061 char *name, *permstr;
1062 struct node *node;
1064 num = xs_count_strings(in->buffer, in->used);
1065 if (num < 2) {
1066 send_error(conn, EINVAL);
1067 return;
1070 /* First arg is node name. */
1071 name = canonicalize(conn, in->buffer);
1072 permstr = in->buffer + strlen(in->buffer) + 1;
1073 num--;
1075 /* We must own node to do this (tools can do this too). */
1076 node = get_node(conn, name, XS_PERM_WRITE|XS_PERM_OWNER);
1077 if (!node) {
1078 send_error(conn, errno);
1079 return;
1082 node->perms = talloc_array(node, struct xs_permissions, num);
1083 node->num_perms = num;
1084 if (!xs_strings_to_perms(node->perms, num, permstr)) {
1085 send_error(conn, errno);
1086 return;
1088 if (!write_node(conn, node)) {
1089 send_error(conn, errno);
1090 return;
1093 add_change_node(conn->transaction, name, false);
1094 fire_watches(conn, name, false);
1095 send_ack(conn, XS_SET_PERMS);
1098 /* Process "in" for conn: "in" will vanish after this conversation, so
1099 * we can talloc off it for temporary variables. May free "conn".
1100 */
1101 static void process_message(struct connection *conn, struct buffered_data *in)
1103 struct transaction *trans;
1105 trans = transaction_lookup(conn, in->hdr.msg.tx_id);
1106 if (IS_ERR(trans)) {
1107 send_error(conn, -PTR_ERR(trans));
1108 return;
1111 assert(conn->transaction == NULL);
1112 conn->transaction = trans;
1114 switch (in->hdr.msg.type) {
1115 case XS_DIRECTORY:
1116 send_directory(conn, onearg(in));
1117 break;
1119 case XS_READ:
1120 do_read(conn, onearg(in));
1121 break;
1123 case XS_WRITE:
1124 do_write(conn, in);
1125 break;
1127 case XS_MKDIR:
1128 do_mkdir(conn, onearg(in));
1129 break;
1131 case XS_RM:
1132 do_rm(conn, onearg(in));
1133 break;
1135 case XS_GET_PERMS:
1136 do_get_perms(conn, onearg(in));
1137 break;
1139 case XS_SET_PERMS:
1140 do_set_perms(conn, in);
1141 break;
1143 case XS_DEBUG:
1144 if (streq(in->buffer, "print"))
1145 xprintf("debug: %s", in->buffer + get_string(in, 0));
1146 if (streq(in->buffer, "check"))
1147 check_store();
1148 #ifdef TESTING
1149 /* For testing, we allow them to set id. */
1150 if (streq(in->buffer, "setid")) {
1151 conn->id = atoi(in->buffer + get_string(in, 0));
1152 } else if (streq(in->buffer, "failtest")) {
1153 if (get_string(in, 0) < in->used)
1154 srandom(atoi(in->buffer + get_string(in, 0)));
1155 failtest = true;
1157 #endif /* TESTING */
1158 send_ack(conn, XS_DEBUG);
1159 break;
1161 case XS_WATCH:
1162 do_watch(conn, in);
1163 break;
1165 case XS_UNWATCH:
1166 do_unwatch(conn, in);
1167 break;
1169 case XS_TRANSACTION_START:
1170 do_transaction_start(conn, in);
1171 break;
1173 case XS_TRANSACTION_END:
1174 do_transaction_end(conn, onearg(in));
1175 break;
1177 case XS_INTRODUCE:
1178 do_introduce(conn, in);
1179 break;
1181 case XS_IS_DOMAIN_INTRODUCED:
1182 do_is_domain_introduced(conn, onearg(in));
1183 break;
1185 case XS_RELEASE:
1186 do_release(conn, onearg(in));
1187 break;
1189 case XS_GET_DOMAIN_PATH:
1190 do_get_domain_path(conn, onearg(in));
1191 break;
1193 default:
1194 eprintf("Client unknown operation %i", in->hdr.msg.type);
1195 send_error(conn, ENOSYS);
1196 break;
1199 conn->transaction = NULL;
1202 static int out_of_mem(void *data)
1204 longjmp(*(jmp_buf *)data, 1);
1207 static void consider_message(struct connection *conn)
1209 jmp_buf talloc_fail;
1211 if (verbose)
1212 xprintf("Got message %s len %i from %p\n",
1213 sockmsg_string(conn->in->hdr.msg.type),
1214 conn->in->hdr.msg.len, conn);
1216 /* For simplicity, we kill the connection on OOM. */
1217 talloc_set_fail_handler(out_of_mem, &talloc_fail);
1218 if (setjmp(talloc_fail)) {
1219 talloc_free(conn);
1220 goto end;
1223 process_message(conn, conn->in);
1225 talloc_free(conn->in);
1226 conn->in = new_buffer(conn);
1228 end:
1229 talloc_set_fail_handler(NULL, NULL);
1230 if (talloc_total_blocks(NULL)
1231 != talloc_total_blocks(talloc_autofree_context()) + 1) {
1232 talloc_report_full(NULL, stderr);
1233 abort();
1237 /* Errors in reading or allocating here mean we get out of sync, so we
1238 * drop the whole client connection. */
1239 static void handle_input(struct connection *conn)
1241 int bytes;
1242 struct buffered_data *in = conn->in;
1244 /* Not finished header yet? */
1245 if (in->inhdr) {
1246 bytes = conn->read(conn, in->hdr.raw + in->used,
1247 sizeof(in->hdr) - in->used);
1248 if (bytes <= 0)
1249 goto bad_client;
1250 in->used += bytes;
1251 if (in->used != sizeof(in->hdr))
1252 return;
1254 if (in->hdr.msg.len > PATH_MAX) {
1255 #ifndef TESTING
1256 syslog(LOG_ERR, "Client tried to feed us %i",
1257 in->hdr.msg.len);
1258 #endif
1259 goto bad_client;
1262 in->buffer = talloc_array(in, char, in->hdr.msg.len);
1263 if (!in->buffer)
1264 goto bad_client;
1265 in->used = 0;
1266 in->inhdr = false;
1267 return;
1270 bytes = conn->read(conn, in->buffer + in->used,
1271 in->hdr.msg.len - in->used);
1272 if (bytes < 0)
1273 goto bad_client;
1275 in->used += bytes;
1276 if (in->used != in->hdr.msg.len)
1277 return;
1279 trace_io(conn, "IN ", in);
1280 consider_message(conn);
1281 return;
1283 bad_client:
1284 /* Kill it. */
1285 talloc_free(conn);
1288 static void handle_output(struct connection *conn)
1290 if (!write_messages(conn))
1291 talloc_free(conn);
1294 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
1296 struct connection *new;
1298 new = talloc_zero(talloc_autofree_context(), struct connection);
1299 if (!new)
1300 return NULL;
1302 new->fd = -1;
1303 new->write = write;
1304 new->read = read;
1305 new->can_write = true;
1306 INIT_LIST_HEAD(&new->out_list);
1307 INIT_LIST_HEAD(&new->watches);
1308 INIT_LIST_HEAD(&new->transaction_list);
1310 new->in = new_buffer(new);
1311 if (new->in == NULL) {
1312 talloc_free(new);
1313 return NULL;
1316 list_add_tail(&new->list, &connections);
1317 talloc_set_destructor(new, destroy_conn);
1318 trace_create(new, "connection");
1319 return new;
1322 static int writefd(struct connection *conn, const void *data, unsigned int len)
1324 return write(conn->fd, data, len);
1327 static int readfd(struct connection *conn, void *data, unsigned int len)
1329 return read(conn->fd, data, len);
1332 static void accept_connection(int sock, bool canwrite)
1334 int fd;
1335 struct connection *conn;
1337 fd = accept(sock, NULL, NULL);
1338 if (fd < 0)
1339 return;
1341 conn = new_connection(writefd, readfd);
1342 if (conn) {
1343 conn->fd = fd;
1344 conn->can_write = canwrite;
1345 } else
1346 close(fd);
1349 #ifdef TESTING
1350 /* Valgrind can check our writes better if we don't use mmap */
1351 #define TDB_FLAGS TDB_NOMMAP
1352 /* Useful for running under debugger. */
1353 void dump_connection(void)
1355 struct connection *i;
1357 list_for_each_entry(i, &connections, list) {
1358 printf("Connection %p:\n", i);
1359 printf(" state = %s\n",
1360 list_empty(&i->out_list) ? "OK" : "BUSY");
1361 if (i->id)
1362 printf(" id = %i\n", i->id);
1363 if (!i->in->inhdr || i->in->used)
1364 printf(" got %i bytes of %s\n",
1365 i->in->used, i->in->inhdr ? "header" : "data");
1366 #if 0
1367 if (i->out)
1368 printf(" sending message %s (%s) out\n",
1369 sockmsg_string(i->out->hdr.msg.type),
1370 i->out->buffer);
1371 if (i->transaction)
1372 dump_transaction(i);
1373 if (i->domain)
1374 dump_domain(i);
1375 #endif
1376 dump_watches(i);
1379 #else
1380 #define TDB_FLAGS 0
1381 #endif
1383 /* We create initial nodes manually. */
1384 static void manual_node(const char *name, const char *child)
1386 struct node *node;
1387 struct xs_permissions perms = { .id = 0, .perms = XS_PERM_NONE };
1389 node = talloc_zero(NULL, struct node);
1390 node->name = name;
1391 node->perms = &perms;
1392 node->num_perms = 1;
1393 node->children = (char *)child;
1394 if (child)
1395 node->childlen = strlen(child) + 1;
1397 if (!write_node(NULL, node))
1398 barf_perror("Could not create initial node %s", name);
1399 talloc_free(node);
1402 static void setup_structure(void)
1404 char *tdbname;
1405 tdbname = talloc_strdup(talloc_autofree_context(), xs_daemon_tdb());
1406 tdb_ctx = tdb_open(tdbname, 0, TDB_FLAGS, O_RDWR, 0);
1408 if (tdb_ctx) {
1409 /* XXX When we make xenstored able to restart, this will have
1410 to become cleverer, checking for existing domains and not
1411 removing the corresponding entries, but for now xenstored
1412 cannot be restarted without losing all the registered
1413 watches, which breaks all the backend drivers anyway. We
1414 can therefore get away with just clearing /local and
1415 expecting Xend to put the appropriate entries back in.
1417 When this change is made it is important to note that
1418 dom0's entries must be cleaned up on reboot _before_ this
1419 daemon starts, otherwise the backend drivers and dom0's
1420 balloon driver will pick up stale entries. In the case of
1421 the balloon driver, this can be fatal.
1422 */
1423 char *tlocal = talloc_strdup(NULL, "/local");
1425 check_store();
1427 internal_rm("/local");
1428 create_node(NULL, tlocal, NULL, 0);
1430 talloc_free(tlocal);
1432 check_store();
1434 else {
1435 tdb_ctx = tdb_open(tdbname, 7919, TDB_FLAGS, O_RDWR|O_CREAT,
1436 0640);
1437 if (!tdb_ctx)
1438 barf_perror("Could not create tdb file %s", tdbname);
1440 manual_node("/", "tool");
1441 manual_node("/tool", "xenstored");
1442 manual_node("/tool/xenstored", NULL);
1444 check_store();
1448 static char *child_name(const char *s1, const char *s2)
1450 if (strcmp(s1, "/")) {
1451 return talloc_asprintf(NULL, "%s/%s", s1, s2);
1453 else {
1454 return talloc_asprintf(NULL, "/%s", s2);
1458 static void check_store_(const char *name)
1460 struct node *node = read_node(NULL, name);
1462 if (node) {
1463 size_t i = 0;
1465 while (i < node->childlen) {
1466 size_t childlen = strlen(node->children + i);
1467 char * childname = child_name(node->name,
1468 node->children + i);
1469 struct node *childnode = read_node(NULL, childname);
1471 if (childnode) {
1472 check_store_(childname);
1473 i += childlen + 1;
1475 else {
1476 log("check_store: No child '%s' found!\n",
1477 childname);
1479 memdel(node->children, i, childlen + 1,
1480 node->childlen);
1481 node->childlen -= childlen + 1;
1482 write_node(NULL, node);
1485 talloc_free(childname);
1488 else {
1489 /* Impossible, because no database should ever be without the
1490 root, and otherwise, we've just checked in our caller
1491 (which made a recursive call to get here). */
1493 log("check_store: No child '%s' found: impossible!", name);
1498 static void check_store()
1500 char * root = talloc_strdup(NULL, "/");
1501 log("Checking store ...");
1502 check_store_(root);
1503 log("Checking store complete.");
1504 talloc_free(root);
1508 /* Something is horribly wrong: check the store. */
1509 static void corrupt(struct connection *conn, const char *fmt, ...)
1511 va_list arglist;
1512 char *str;
1513 int saved_errno = errno;
1515 va_start(arglist, fmt);
1516 str = talloc_vasprintf(NULL, fmt, arglist);
1517 va_end(arglist);
1519 log("corruption detected by connection %i: err %s: %s",
1520 conn ? (int)conn->id : -1, strerror(saved_errno), str);
1522 #ifdef TESTING
1523 /* Allow them to attach debugger. */
1524 sleep(30);
1525 #endif
1526 check_store();
1530 static void write_pidfile(const char *pidfile)
1532 char buf[100];
1533 int len;
1534 int fd;
1536 fd = open(pidfile, O_RDWR | O_CREAT, 0600);
1537 if (fd == -1)
1538 barf_perror("Opening pid file %s", pidfile);
1540 /* We exit silently if daemon already running. */
1541 if (lockf(fd, F_TLOCK, 0) == -1)
1542 exit(0);
1544 len = sprintf(buf, "%d\n", getpid());
1545 write(fd, buf, len);
1548 /* Stevens. */
1549 static void daemonize(void)
1551 pid_t pid;
1553 /* Separate from our parent via fork, so init inherits us. */
1554 if ((pid = fork()) < 0)
1555 barf_perror("Failed to fork daemon");
1556 if (pid != 0)
1557 exit(0);
1559 /* Session leader so ^C doesn't whack us. */
1560 setsid();
1562 /* Let session leader exit so child cannot regain CTTY */
1563 if ((pid = fork()) < 0)
1564 barf_perror("Failed to fork daemon");
1565 if (pid != 0)
1566 exit(0);
1568 #ifndef TESTING /* Relative paths for socket names */
1569 /* Move off any mount points we might be in. */
1570 chdir("/");
1571 #endif
1572 /* Discard our parent's old-fashioned umask prejudices. */
1573 umask(0);
1577 static void usage(void)
1579 fprintf(stderr,
1580 "Usage:\n"
1581 "\n"
1582 " xenstored <options>\n"
1583 "\n"
1584 "where options may include:\n"
1585 "\n"
1586 " --no-domain-init to state that xenstored should not initialise dom0,\n"
1587 " --pid-file <file> giving a file for the daemon's pid to be written,\n"
1588 " --help to output this message,\n"
1589 " --no-fork to request that the daemon does not fork,\n"
1590 " --output-pid to request that the pid of the daemon is output,\n"
1591 " --trace-file <file> giving the file for logging, and\n"
1592 " --verbose to request verbose execution.\n");
1596 static struct option options[] = {
1597 { "no-domain-init", 0, NULL, 'D' },
1598 { "pid-file", 1, NULL, 'F' },
1599 { "help", 0, NULL, 'H' },
1600 { "no-fork", 0, NULL, 'N' },
1601 { "output-pid", 0, NULL, 'P' },
1602 { "trace-file", 1, NULL, 'T' },
1603 { "verbose", 0, NULL, 'V' },
1604 { NULL, 0, NULL, 0 } };
1606 extern void dump_conn(struct connection *conn);
1608 int main(int argc, char *argv[])
1610 int opt, *sock, *ro_sock, max;
1611 struct sockaddr_un addr;
1612 fd_set inset, outset;
1613 bool dofork = true;
1614 bool outputpid = false;
1615 bool no_domain_init = false;
1616 const char *pidfile = NULL;
1618 while ((opt = getopt_long(argc, argv, "DF:HNPT:V", options,
1619 NULL)) != -1) {
1620 switch (opt) {
1621 case 'D':
1622 no_domain_init = true;
1623 break;
1624 case 'F':
1625 pidfile = optarg;
1626 break;
1627 case 'H':
1628 usage();
1629 return 0;
1630 case 'N':
1631 dofork = false;
1632 break;
1633 case 'P':
1634 outputpid = true;
1635 break;
1636 case 'T':
1637 tracefile = optarg;
1638 break;
1639 case 'V':
1640 verbose = true;
1641 break;
1644 if (optind != argc)
1645 barf("%s: No arguments desired", argv[0]);
1647 reopen_log();
1649 if (dofork) {
1650 openlog("xenstored", 0, LOG_DAEMON);
1651 daemonize();
1653 if (pidfile)
1654 write_pidfile(pidfile);
1656 talloc_enable_leak_report_full();
1658 /* Create sockets for them to listen to. */
1659 sock = talloc(talloc_autofree_context(), int);
1660 *sock = socket(PF_UNIX, SOCK_STREAM, 0);
1661 if (*sock < 0)
1662 barf_perror("Could not create socket");
1663 ro_sock = talloc(talloc_autofree_context(), int);
1664 *ro_sock = socket(PF_UNIX, SOCK_STREAM, 0);
1665 if (*ro_sock < 0)
1666 barf_perror("Could not create socket");
1667 talloc_set_destructor(sock, destroy_fd);
1668 talloc_set_destructor(ro_sock, destroy_fd);
1670 /* Don't kill us with SIGPIPE. */
1671 signal(SIGPIPE, SIG_IGN);
1673 /* FIXME: Be more sophisticated, don't mug running daemon. */
1674 unlink(xs_daemon_socket());
1675 unlink(xs_daemon_socket_ro());
1677 addr.sun_family = AF_UNIX;
1678 strcpy(addr.sun_path, xs_daemon_socket());
1679 if (bind(*sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1680 barf_perror("Could not bind socket to %s", xs_daemon_socket());
1681 strcpy(addr.sun_path, xs_daemon_socket_ro());
1682 if (bind(*ro_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1683 barf_perror("Could not bind socket to %s",
1684 xs_daemon_socket_ro());
1685 if (chmod(xs_daemon_socket(), 0600) != 0
1686 || chmod(xs_daemon_socket_ro(), 0660) != 0)
1687 barf_perror("Could not chmod sockets");
1689 if (listen(*sock, 1) != 0
1690 || listen(*ro_sock, 1) != 0)
1691 barf_perror("Could not listen on sockets");
1693 if (pipe(reopen_log_pipe)) {
1694 barf_perror("pipe");
1697 /* Setup the database */
1698 setup_structure();
1700 /* Listen to hypervisor. */
1701 if (!no_domain_init)
1702 domain_init();
1704 /* Restore existing connections. */
1705 restore_existing_connections();
1707 if (outputpid) {
1708 printf("%i\n", getpid());
1709 fflush(stdout);
1712 /* close stdin/stdout now we're ready to accept connections */
1713 if (dofork) {
1714 close(STDIN_FILENO);
1715 close(STDOUT_FILENO);
1716 close(STDERR_FILENO);
1719 signal(SIGHUP, trigger_reopen_log);
1721 #ifdef TESTING
1722 signal(SIGUSR1, stop_failtest);
1723 #endif
1725 /* Get ready to listen to the tools. */
1726 max = initialize_set(&inset, &outset, *sock, *ro_sock);
1728 /* Main loop. */
1729 /* FIXME: Rewrite so noone can starve. */
1730 for (;;) {
1731 struct connection *i;
1733 if (select(max+1, &inset, &outset, NULL, NULL) < 0) {
1734 if (errno == EINTR)
1735 continue;
1736 barf_perror("Select failed");
1739 if (FD_ISSET(reopen_log_pipe[0], &inset)) {
1740 char c;
1741 read(reopen_log_pipe[0], &c, 1);
1742 reopen_log();
1745 if (FD_ISSET(*sock, &inset))
1746 accept_connection(*sock, true);
1748 if (FD_ISSET(*ro_sock, &inset))
1749 accept_connection(*ro_sock, false);
1751 if (eventchn_fd > 0 && FD_ISSET(eventchn_fd, &inset))
1752 handle_event();
1754 list_for_each_entry(i, &connections, list) {
1755 if (i->domain)
1756 continue;
1758 /* Operations can delete themselves or others
1759 * (xs_release): list is not safe after input,
1760 * so break. */
1761 if (FD_ISSET(i->fd, &inset)) {
1762 handle_input(i);
1763 break;
1765 if (FD_ISSET(i->fd, &outset)) {
1766 handle_output(i);
1767 break;
1771 /* Handle all possible I/O for domain connections. */
1772 more:
1773 list_for_each_entry(i, &connections, list) {
1774 if (!i->domain)
1775 continue;
1777 if (domain_can_read(i)) {
1778 handle_input(i);
1779 goto more;
1782 if (domain_can_write(i) && !list_empty(&i->out_list)) {
1783 handle_output(i);
1784 goto more;
1788 max = initialize_set(&inset, &outset, *sock, *ro_sock);
1792 /*
1793 * Local variables:
1794 * c-file-style: "linux"
1795 * indent-tabs-mode: t
1796 * c-indent-level: 8
1797 * c-basic-offset: 8
1798 * tab-width: 8
1799 * End:
1800 */