All of the socket handling is needed only when running as daemon.
Move it into posix.c, allowing to remove the NO_SOCKETS macro.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
CFLAGS += $(CFLAGS_libxenguest)
CFLAGS += $(CFLAGS_libxentoolcore)
-ifdef CONFIG_STUBDOM
-CFLAGS += -DNO_SOCKETS=1
-endif
-
$(XENSTORED_OBJS-y): CFLAGS += $(CFLAGS_libxengnttab)
xenstored.a: $(XENSTORED_OBJS-y)
#include <sys/types.h>
#include <sys/stat.h>
#include <poll.h>
-#ifndef NO_SOCKETS
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
static unsigned int nr_fds;
static unsigned int delayed_requests;
-static int sock = -1;
-
int orig_argc;
char **orig_argv;
return -1;
}
-static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
+static void initialize_fds(int *ptimeout)
{
struct connection *conn;
uint64_t msecs;
*ptimeout = delayed_requests ? 1000 : -1;
set_special_fds();
- if (sock != -1)
- *p_sock_pollfd_idx = set_fd(sock, POLLIN|POLLPRI);
if (xce_handle != NULL)
xce_pollfd_idx = set_fd(xenevtchn_fd(xce_handle),
return NULL;
}
-#ifdef NO_SOCKETS
-static void accept_connection(int sock)
-{
-}
-#else
-static int writefd(struct connection *conn, const void *data, unsigned int len)
-{
- int rc;
-
- while ((rc = write(conn->fd, data, len)) < 0) {
- if (errno == EAGAIN) {
- rc = 0;
- break;
- }
- if (errno != EINTR)
- break;
- }
-
- return rc;
-}
-
-static int readfd(struct connection *conn, void *data, unsigned int len)
-{
- int rc;
-
- while ((rc = read(conn->fd, data, len)) < 0) {
- if (errno == EAGAIN) {
- rc = 0;
- break;
- }
- if (errno != EINTR)
- break;
- }
-
- /* Reading zero length means we're done with this connection. */
- if ((rc == 0) && (len != 0)) {
- errno = EBADF;
- rc = -1;
- }
-
- return rc;
-}
-
-static bool socket_can_process(struct connection *conn, int mask)
-{
- if (conn->pollfd_idx == -1)
- return false;
-
- if (poll_fds[conn->pollfd_idx].revents & ~(POLLIN | POLLOUT)) {
- talloc_free(conn);
- return false;
- }
-
- return (poll_fds[conn->pollfd_idx].revents & mask);
-}
-
-static bool socket_can_write(struct connection *conn)
-{
- return socket_can_process(conn, POLLOUT);
-}
-
-static bool socket_can_read(struct connection *conn)
-{
- return socket_can_process(conn, POLLIN);
-}
-
-const struct interface_funcs socket_funcs = {
- .write = writefd,
- .read = readfd,
- .can_write = socket_can_write,
- .can_read = socket_can_read,
-};
-
-static void accept_connection(int sock)
-{
- int fd;
- struct connection *conn;
-
- fd = accept(sock, NULL, NULL);
- if (fd < 0)
- return;
-
- conn = new_connection(&socket_funcs);
- if (conn) {
- conn->fd = fd;
- conn->id = dom0_domid;
- } else
- close(fd);
-}
-#endif
-
/* We create initial nodes manually. */
static void manual_node(const char *name, const char *child)
{
errno = saved_errno;
}
-#ifndef NO_SOCKETS
-static void destroy_fds(void)
-{
- if (sock >= 0)
- close(sock);
-}
-
-void init_sockets(void)
-{
- struct sockaddr_un addr;
- const char *soc_str = xenstore_daemon_path();
-
- if (!soc_str)
- barf_perror("Failed to obtain xs domain socket");
-
- /* Create sockets for them to listen to. */
- atexit(destroy_fds);
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock < 0)
- barf_perror("Could not create socket");
-
- /* FIXME: Be more sophisticated, don't mug running daemon. */
- unlink(soc_str);
-
- addr.sun_family = AF_UNIX;
-
- if(strlen(soc_str) >= sizeof(addr.sun_path))
- barf_perror("socket string '%s' too long", soc_str);
- strcpy(addr.sun_path, soc_str);
- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
- barf_perror("Could not bind socket to %s", soc_str);
-
- if (chmod(soc_str, 0600) != 0)
- barf_perror("Could not chmod sockets");
-
- if (listen(sock, 1) != 0)
- barf_perror("Could not listen on sockets");
-}
-#endif
-
static void usage(void)
{
fprintf(stderr,
int main(int argc, char *argv[])
{
int opt;
- int sock_pollfd_idx = -1;
bool dofork = true;
bool live_update = false;
const char *pidfile = NULL;
check_store();
/* Get ready to listen to the tools. */
- initialize_fds(&sock_pollfd_idx, &timeout);
+ initialize_fds(&timeout);
late_init(live_update);
handle_special_fds();
- if (sock_pollfd_idx != -1) {
- if (poll_fds[sock_pollfd_idx].revents & ~POLLIN) {
- barf_perror("sock poll failed");
- break;
- } else if (poll_fds[sock_pollfd_idx].revents & POLLIN) {
- accept_connection(sock);
- sock_pollfd_idx = -1;
- }
- }
-
if (xce_pollfd_idx != -1) {
if (poll_fds[xce_pollfd_idx].revents & ~POLLIN) {
barf_perror("xce_handle poll failed");
}
}
- initialize_fds(&sock_pollfd_idx, &timeout);
+ initialize_fds(&timeout);
}
}
head.length = sizeof(glb);
if (fwrite(&head, sizeof(head), 1, fp) != 1)
return "Dump global state error";
- glb.socket_fd = sock;
+ glb.socket_fd = get_socket_fd();
glb.evtchn_fd = xenevtchn_fd(xce_handle);
if (fwrite(&glb, sizeof(glb), 1, fp) != 1)
return "Dump global state error";
{
const struct xs_state_global *glb = state;
- sock = glb->socket_fd;
+ set_socket_fd(glb->socket_fd);
domain_init(glb->evtchn_fd);
}
void setup_structure(bool live_update);
struct connection *new_connection(const struct interface_funcs *funcs);
+struct connection *add_socket_connection(int fd);
struct connection *get_connection_by_id(unsigned int conn_id);
void check_store(void);
void corrupt(struct connection *conn, const char *fmt, ...);
void set_special_fds(void);
void handle_special_fds(void);
-void init_sockets(void);
+int get_socket_fd(void);
+void set_socket_fd(int fd);
/* Close stdin/stdout/stderr to complete daemonize */
void finish_daemonize(void);
-#ifndef NO_SOCKETS
-extern const struct interface_funcs socket_funcs;
-#endif
extern xengnttab_handle **xgt_handle;
int remember_string(struct hashtable *hash, const char *str);
struct domain *domain, *tdomain;
if (sc->conn_type == XS_STATE_CONN_TYPE_SOCKET) {
-#ifdef NO_SOCKETS
- barf("socket based connection without sockets");
-#else
- conn = new_connection(&socket_funcs);
- if (!conn)
- barf("error restoring connection");
- conn->fd = sc->spec.socket_fd;
-#endif
+ conn = add_socket_connection(sc->spec.socket_fd);
} else {
domain = introduce_domain(ctx, sc->spec.ring.domid,
sc->spec.ring.evtchn, true);
#include <sys/types.h>
#include <sys/mman.h>
#include "core.h"
+#include "utils.h"
#include <xen/grant_table.h>
void finish_daemonize(void)
{
}
+struct connection *add_socket_connection(int fd)
+{
+ barf("socket based connection without sockets");
+}
+
evtchn_port_t get_xenbus_evtchn(void)
{
return dom0_event;
void handle_special_fds(void)
{
}
+
+int get_socket_fd(void)
+{
+ return -1;
+}
+
+void set_socket_fd(int fd)
+{
+}
#include <stdlib.h>
#include <syslog.h>
#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#if defined(HAVE_SYSTEMD)
#include <systemd/sd-daemon.h>
#endif
#include "utils.h"
#include "core.h"
#include "osdep.h"
+#include "talloc.h"
static int reopen_log_pipe0_pollfd_idx = -1;
static int reopen_log_pipe[2];
+static int sock_pollfd_idx = -1;
+static int sock = -1;
+
static void write_pidfile(const char *pidfile)
{
char buf[100];
return addr;
}
+static int writefd(struct connection *conn, const void *data, unsigned int len)
+{
+ int rc;
+
+ while ((rc = write(conn->fd, data, len)) < 0) {
+ if (errno == EAGAIN) {
+ rc = 0;
+ break;
+ }
+ if (errno != EINTR)
+ break;
+ }
+
+ return rc;
+}
+
+static int readfd(struct connection *conn, void *data, unsigned int len)
+{
+ int rc;
+
+ while ((rc = read(conn->fd, data, len)) < 0) {
+ if (errno == EAGAIN) {
+ rc = 0;
+ break;
+ }
+ if (errno != EINTR)
+ break;
+ }
+
+ /* Reading zero length means we're done with this connection. */
+ if ((rc == 0) && (len != 0)) {
+ errno = EBADF;
+ rc = -1;
+ }
+
+ return rc;
+}
+
+static bool socket_can_process(struct connection *conn, int mask)
+{
+ if (conn->pollfd_idx == -1)
+ return false;
+
+ if (poll_fds[conn->pollfd_idx].revents & ~(POLLIN | POLLOUT)) {
+ talloc_free(conn);
+ return false;
+ }
+
+ return (poll_fds[conn->pollfd_idx].revents & mask);
+}
+
+static bool socket_can_write(struct connection *conn)
+{
+ return socket_can_process(conn, POLLOUT);
+}
+
+static bool socket_can_read(struct connection *conn)
+{
+ return socket_can_process(conn, POLLIN);
+}
+
+static const struct interface_funcs socket_funcs = {
+ .write = writefd,
+ .read = readfd,
+ .can_write = socket_can_write,
+ .can_read = socket_can_read,
+};
+
+static void accept_connection(int sock)
+{
+ int fd;
+ struct connection *conn;
+
+ fd = accept(sock, NULL, NULL);
+ if (fd < 0)
+ return;
+
+ conn = new_connection(&socket_funcs);
+ if (conn) {
+ conn->fd = fd;
+ conn->id = dom0_domid;
+ } else
+ close(fd);
+}
+
+static void destroy_fds(void)
+{
+ if (sock >= 0)
+ close(sock);
+}
+
+static void init_sockets(void)
+{
+ struct sockaddr_un addr;
+ const char *soc_str = xenstore_daemon_path();
+
+ if (!soc_str)
+ barf_perror("Failed to obtain xs domain socket");
+
+ /* Create sockets for them to listen to. */
+ atexit(destroy_fds);
+ sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0)
+ barf_perror("Could not create socket");
+
+ /* FIXME: Be more sophisticated, don't mug running daemon. */
+ unlink(soc_str);
+
+ addr.sun_family = AF_UNIX;
+
+ if (strlen(soc_str) >= sizeof(addr.sun_path))
+ barf_perror("socket string '%s' too long", soc_str);
+ strcpy(addr.sun_path, soc_str);
+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
+ barf_perror("Could not bind socket to %s", soc_str);
+
+ if (chmod(soc_str, 0600) != 0)
+ barf_perror("Could not chmod sockets");
+
+ if (listen(sock, 1) != 0)
+ barf_perror("Could not listen on sockets");
+}
+
+
+struct connection *add_socket_connection(int fd)
+{
+ struct connection *conn;
+
+ conn = new_connection(&socket_funcs);
+ if (!conn)
+ barf("error restoring connection");
+ conn->fd = fd;
+
+ return conn;
+}
+
void early_init(bool live_update, bool dofork, const char *pidfile)
{
reopen_log();
if (reopen_log_pipe[0] != -1)
reopen_log_pipe0_pollfd_idx =
set_fd(reopen_log_pipe[0], POLLIN|POLLPRI);
+
+ if (sock != -1)
+ sock_pollfd_idx = set_fd(sock, POLLIN|POLLPRI);
}
void handle_special_fds(void)
}
reopen_log_pipe0_pollfd_idx = -1;
}
+
+ if (sock_pollfd_idx != -1) {
+ if (poll_fds[sock_pollfd_idx].revents & ~POLLIN) {
+ barf_perror("sock poll failed");
+ } else if (poll_fds[sock_pollfd_idx].revents & POLLIN) {
+ accept_connection(sock);
+ sock_pollfd_idx = -1;
+ }
+ }
}
void late_init(bool live_update)
}
#endif
}
+
+int get_socket_fd(void)
+{
+ return sock;
+}
+
+void set_socket_fd(int fd)
+{
+ sock = fd;
+}