/*
Simple prototype Xen Store Daemon providing simple tree-like database.
Copyright (C) 2005 Rusty Russell IBM Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/un.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <getopt.h>
#include <signal.h>
#include <assert.h>
#include <setjmp.h>
#include "utils.h"
#include "list.h"
#include "talloc.h"
#include "xs_lib.h"
#include "xenstored_core.h"
#include "xenstored_watch.h"
#include "xenstored_transaction.h"
#include "xenstored_domain.h"
#include "xenctrl.h"
#include "tdb.h"
#include "hashtable.h"
extern int xce_handle; /* in xenstored_domain.c */
static bool verbose = false;
LIST_HEAD(connections);
static int tracefd = -1;
static bool recovery = true;
static bool remove_local = true;
static int reopen_log_pipe[2];
static char *tracefile = NULL;
static TDB_CONTEXT *tdb_ctx;
static void corrupt(struct connection *conn, const char *fmt, ...);
static void check_store(void);
#define log(...) \
do { \
char *s = talloc_asprintf(NULL, __VA_ARGS__); \
trace("%s\n", s); \
syslog(LOG_ERR, "%s", s); \
talloc_free(s); \
} while (0)
int quota_nb_entry_per_domain = 1000;
int quota_nb_watch_per_domain = 128;
int quota_max_entry_size = 2048; /* 2K */
int quota_max_transaction = 10;
TDB_CONTEXT *tdb_context(struct connection *conn)
{
/* conn = NULL used in manual_node at setup. */
if (!conn || !conn->transaction)
return tdb_ctx;
return tdb_transaction_context(conn->transaction);
}
bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb)
{
if (rename(newname, xs_daemon_tdb()) != 0)
return false;
tdb_close(tdb_ctx);
tdb_ctx = talloc_steal(talloc_autofree_context(), newtdb);
return true;
}
static char *sockmsg_string(enum xsd_sockmsg_type type)
{
switch (type) {
case XS_DEBUG: