@@ -436,6 +436,11 @@ static const char *lu_dump_state(const void *ctx, struct connection *conn)
return ret;
}
+void lu_read_state(void)
+{
+ xprintf("live-update: read state\n");
+}
+
static const char *lu_activate_binary(const void *ctx)
{
return "Not yet implemented.";
@@ -17,3 +17,4 @@
*/
int do_control(struct connection *conn, struct buffered_data *in);
+void lu_read_state(void);
@@ -1637,9 +1637,10 @@ static void tdb_logger(TDB_CONTEXT *tdb, int level, const char * fmt, ...)
}
}
-static void setup_structure(void)
+static void setup_structure(bool live_update)
{
char *tdbname;
+
tdbname = talloc_strdup(talloc_autofree_context(), xs_daemon_tdb());
if (!tdbname)
barf_perror("Could not create tdbname");
@@ -1653,14 +1654,16 @@ static void setup_structure(void)
if (!tdb_ctx)
barf_perror("Could not create tdb file %s", tdbname);
- manual_node("/", "tool");
- manual_node("/tool", "xenstored");
- manual_node("/tool/xenstored", NULL);
+ if (live_update)
+ manual_node("/", NULL);
+ else {
+ manual_node("/", "tool");
+ manual_node("/tool", "xenstored");
+ }
check_store();
}
-
static unsigned int hash_from_key_fn(void *k)
{
char *str = k;
@@ -2066,7 +2069,8 @@ int main(int argc, char *argv[])
if (dofork) {
openlog("xenstored", 0, LOG_DAEMON);
- daemonize();
+ if (!live_update)
+ daemonize();
}
if (pidfile)
write_pidfile(pidfile);
@@ -2081,17 +2085,20 @@ int main(int argc, char *argv[])
talloc_enable_null_tracking();
#ifndef NO_SOCKETS
- init_sockets();
+ if (!live_update)
+ init_sockets();
#endif
init_pipe(reopen_log_pipe);
/* Setup the database */
- setup_structure();
+ setup_structure(live_update);
/* Listen to hypervisor. */
- if (!no_domain_init)
- domain_init();
+ if (!no_domain_init && !live_update) {
+ domain_init(-1);
+ dom0_init();
+ }
if (outputpid) {
printf("%ld\n", (long)getpid());
@@ -2099,13 +2106,21 @@ int main(int argc, char *argv[])
}
/* redirect to /dev/null now we're ready to accept connections */
- if (dofork)
+ if (dofork && !live_update)
finish_daemonize();
+#ifndef __MINIOS__
+ if (dofork)
+ xprintf = trace;
+#endif
signal(SIGHUP, trigger_reopen_log);
if (tracefile)
tracefile = talloc_strdup(NULL, tracefile);
+ /* Read state in case of live update. */
+ if (live_update)
+ lu_read_state();
+
/* Get ready to listen to the tools. */
initialize_fds(&sock_pollfd_idx, &timeout);
@@ -2113,8 +2128,10 @@ int main(int argc, char *argv[])
xenbus_notify_running();
#if defined(XEN_SYSTEMD_ENABLED)
- sd_notify(1, "READY=1");
- fprintf(stderr, SD_NOTICE "xenstored is ready\n");
+ if (!live_update) {
+ sd_notify(1, "READY=1");
+ fprintf(stderr, SD_NOTICE "xenstored is ready\n");
+ }
#endif
/* Main loop. */
@@ -706,29 +706,23 @@ bool check_perms_special(const char *name, struct connection *conn)
return perm_for_conn(conn, p) & XS_PERM_READ;
}
-static int dom0_init(void)
-{
+void dom0_init(void)
+{
evtchn_port_t port;
struct domain *dom0;
port = xenbus_evtchn();
if (port == -1)
- return -1;
+ barf_perror("Failed to initialize dom0 port");
dom0 = introduce_domain(NULL, xenbus_master_domid(), port);
if (!dom0)
- return -1;
+ barf_perror("Failed to initialize dom0");
xenevtchn_notify(xce_handle, dom0->port);
-
- if (set_dom_perms_default(&dom_release_perms) ||
- set_dom_perms_default(&dom_introduce_perms))
- return -1;
-
- return 0;
}
-void domain_init(void)
+void domain_init(int evtfd)
{
int rc;
@@ -758,13 +752,17 @@ void domain_init(void)
talloc_set_destructor(xgt_handle, close_xgt_handle);
- xce_handle = xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
+ if (evtfd < 0)
+ xce_handle = xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
+ else
+ xce_handle = xenevtchn_open_fd(NULL, evtfd, 0);
if (xce_handle == NULL)
barf_perror("Failed to open evtchn device");
- if (dom0_init() != 0)
- barf_perror("Failed to initialize dom0 state");
+ if (set_dom_perms_default(&dom_release_perms) ||
+ set_dom_perms_default(&dom_introduce_perms))
+ barf_perror("Failed to set special permissions");
if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1)
barf_perror("Failed to bind to domain exception virq port");
@@ -42,7 +42,8 @@ int do_get_domain_path(struct connection *conn, struct buffered_data *in);
/* Allow guest to reset all watches */
int do_reset_watches(struct connection *conn, struct buffered_data *in);
-void domain_init(void);
+void domain_init(int evtfd);
+void dom0_init(void);
/* Returns the implicit path of a connection (only domains have this) */
const char *get_implicit_path(const struct connection *conn);
@@ -85,7 +85,6 @@ void finish_daemonize(void)
dup2(devnull, STDOUT_FILENO);
dup2(devnull, STDERR_FILENO);
close(devnull);
- xprintf = trace;
}
void init_pipe(int reopen_log_pipe[2])