diff mbox series

[v3,25/33] tools/xenstored: move all socket handling into posix.c

Message ID 20240104090055.27323-26-jgross@suse.com (mailing list archive)
State Superseded
Headers show
Series tools: enable xenstore-stubdom to use 9pfs | expand

Commit Message

Jürgen Groß Jan. 4, 2024, 9 a.m. UTC
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>
---
V3:
- new patch
---
 tools/xenstored/Makefile.common |   4 -
 tools/xenstored/core.c          | 156 +-------------------------------
 tools/xenstored/core.h          |   8 +-
 tools/xenstored/domain.c        |   9 +-
 tools/xenstored/minios.c        |   6 ++
 tools/xenstored/posix.c         | 153 +++++++++++++++++++++++++++++++
 6 files changed, 167 insertions(+), 169 deletions(-)

Comments

Jason Andryuk Jan. 10, 2024, 8:47 p.m. UTC | #1
On Thu, Jan 4, 2024 at 4:10 AM Juergen Gross <jgross@suse.com> wrote:
>
> 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: Jason Andryuk <jandryuk@gmail.com>
Julien Grall Jan. 26, 2024, 4:22 p.m. UTC | #2
Hi Juergen,

On 04/01/2024 09:00, Juergen Gross wrote:
> 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>
> ---
> V3:
> - new patch
> ---
>   tools/xenstored/Makefile.common |   4 -
>   tools/xenstored/core.c          | 156 +-------------------------------
>   tools/xenstored/core.h          |   8 +-
>   tools/xenstored/domain.c        |   9 +-
>   tools/xenstored/minios.c        |   6 ++
>   tools/xenstored/posix.c         | 153 +++++++++++++++++++++++++++++++
>   6 files changed, 167 insertions(+), 169 deletions(-)
> 
> diff --git a/tools/xenstored/Makefile.common b/tools/xenstored/Makefile.common
> index 189ab81b8d..ef63ef650c 100644
> --- a/tools/xenstored/Makefile.common
> +++ b/tools/xenstored/Makefile.common
> @@ -16,10 +16,6 @@ CFLAGS += $(CFLAGS_libxenctrl)
>   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)
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index 650c1d1574..8ff1faccef 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -20,10 +20,6 @@
>   #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>
> @@ -61,7 +57,7 @@ static unsigned int current_array_size;
>   static unsigned int nr_fds;
>   static unsigned int delayed_requests;
>   
> -static int sock = -1;
> +int sock = -1;

Similar comment to 'fds' on the previous patch. This name is quite 
generic. Can we either pass it as an argument (or return) or rename it?

Cheers,
Jürgen Groß Feb. 5, 2024, 8:07 a.m. UTC | #3
On 26.01.24 17:22, Julien Grall wrote:
> Hi Juergen,
> 
> On 04/01/2024 09:00, Juergen Gross wrote:
>> 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>
>> ---
>> V3:
>> - new patch
>> ---
>>   tools/xenstored/Makefile.common |   4 -
>>   tools/xenstored/core.c          | 156 +-------------------------------
>>   tools/xenstored/core.h          |   8 +-
>>   tools/xenstored/domain.c        |   9 +-
>>   tools/xenstored/minios.c        |   6 ++
>>   tools/xenstored/posix.c         | 153 +++++++++++++++++++++++++++++++
>>   6 files changed, 167 insertions(+), 169 deletions(-)
>>
>> diff --git a/tools/xenstored/Makefile.common b/tools/xenstored/Makefile.common
>> index 189ab81b8d..ef63ef650c 100644
>> --- a/tools/xenstored/Makefile.common
>> +++ b/tools/xenstored/Makefile.common
>> @@ -16,10 +16,6 @@ CFLAGS += $(CFLAGS_libxenctrl)
>>   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)
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index 650c1d1574..8ff1faccef 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -20,10 +20,6 @@
>>   #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>
>> @@ -61,7 +57,7 @@ static unsigned int current_array_size;
>>   static unsigned int nr_fds;
>>   static unsigned int delayed_requests;
>> -static int sock = -1;
>> +int sock = -1;
> 
> Similar comment to 'fds' on the previous patch. This name is quite generic. Can 
> we either pass it as an argument (or return) or rename it?

What about to make it local to posix.c and adding a get_socket_fd() function
for its only usage in core.c (with a related stub in minios.c, of course)?


Juergen
Jürgen Groß Feb. 5, 2024, 9:21 a.m. UTC | #4
On 26.01.24 17:22, Julien Grall wrote:
> Hi Juergen,
> 
> On 04/01/2024 09:00, Juergen Gross wrote:
>> 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>
>> ---
>> V3:
>> - new patch
>> ---
>>   tools/xenstored/Makefile.common |   4 -
>>   tools/xenstored/core.c          | 156 +-------------------------------
>>   tools/xenstored/core.h          |   8 +-
>>   tools/xenstored/domain.c        |   9 +-
>>   tools/xenstored/minios.c        |   6 ++
>>   tools/xenstored/posix.c         | 153 +++++++++++++++++++++++++++++++
>>   6 files changed, 167 insertions(+), 169 deletions(-)
>>
>> diff --git a/tools/xenstored/Makefile.common b/tools/xenstored/Makefile.common
>> index 189ab81b8d..ef63ef650c 100644
>> --- a/tools/xenstored/Makefile.common
>> +++ b/tools/xenstored/Makefile.common
>> @@ -16,10 +16,6 @@ CFLAGS += $(CFLAGS_libxenctrl)
>>   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)
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index 650c1d1574..8ff1faccef 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -20,10 +20,6 @@
>>   #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>
>> @@ -61,7 +57,7 @@ static unsigned int current_array_size;
>>   static unsigned int nr_fds;
>>   static unsigned int delayed_requests;
>> -static int sock = -1;
>> +int sock = -1;
> 
> Similar comment to 'fds' on the previous patch. This name is quite generic. Can 
> we either pass it as an argument (or return) or rename it?

Turns out this patch now makes the "fds" solution more complicated: I'd need to
add fds as an additional parameter to the .can_write() and .can_read() callbacks
of struct interface_funcs.

I can do that, but an alternative would be to just rename fds to e.g. poll_fds.

Do you have any preference?

In case we pass fds as a parameter, I'd be inclined to make it even local to the
main() function.


Juergen
Julien Grall Feb. 5, 2024, 9:35 a.m. UTC | #5
Hi Juergen,

On 05/02/2024 08:07, Juergen Gross wrote:
> On 26.01.24 17:22, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 04/01/2024 09:00, Juergen Gross wrote:
>>> 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>
>>> ---
>>> V3:
>>> - new patch
>>> ---
>>>   tools/xenstored/Makefile.common |   4 -
>>>   tools/xenstored/core.c          | 156 +-------------------------------
>>>   tools/xenstored/core.h          |   8 +-
>>>   tools/xenstored/domain.c        |   9 +-
>>>   tools/xenstored/minios.c        |   6 ++
>>>   tools/xenstored/posix.c         | 153 +++++++++++++++++++++++++++++++
>>>   6 files changed, 167 insertions(+), 169 deletions(-)
>>>
>>> diff --git a/tools/xenstored/Makefile.common 
>>> b/tools/xenstored/Makefile.common
>>> index 189ab81b8d..ef63ef650c 100644
>>> --- a/tools/xenstored/Makefile.common
>>> +++ b/tools/xenstored/Makefile.common
>>> @@ -16,10 +16,6 @@ CFLAGS += $(CFLAGS_libxenctrl)
>>>   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)
>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>> index 650c1d1574..8ff1faccef 100644
>>> --- a/tools/xenstored/core.c
>>> +++ b/tools/xenstored/core.c
>>> @@ -20,10 +20,6 @@
>>>   #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>
>>> @@ -61,7 +57,7 @@ static unsigned int current_array_size;
>>>   static unsigned int nr_fds;
>>>   static unsigned int delayed_requests;
>>> -static int sock = -1;
>>> +int sock = -1;
>>
>> Similar comment to 'fds' on the previous patch. This name is quite 
>> generic. Can we either pass it as an argument (or return) or rename it?
> 
> What about to make it local to posix.c and adding a get_socket_fd() 
> function
> for its only usage in core.c (with a related stub in minios.c, of course)?

That looks fine to me in principle.

Cheers,
Julien Grall Feb. 5, 2024, 9:36 a.m. UTC | #6
Hi Juergen,

On 05/02/2024 09:21, Juergen Gross wrote:
> On 26.01.24 17:22, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 04/01/2024 09:00, Juergen Gross wrote:
>>> 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>
>>> ---
>>> V3:
>>> - new patch
>>> ---
>>>   tools/xenstored/Makefile.common |   4 -
>>>   tools/xenstored/core.c          | 156 +-------------------------------
>>>   tools/xenstored/core.h          |   8 +-
>>>   tools/xenstored/domain.c        |   9 +-
>>>   tools/xenstored/minios.c        |   6 ++
>>>   tools/xenstored/posix.c         | 153 +++++++++++++++++++++++++++++++
>>>   6 files changed, 167 insertions(+), 169 deletions(-)
>>>
>>> diff --git a/tools/xenstored/Makefile.common 
>>> b/tools/xenstored/Makefile.common
>>> index 189ab81b8d..ef63ef650c 100644
>>> --- a/tools/xenstored/Makefile.common
>>> +++ b/tools/xenstored/Makefile.common
>>> @@ -16,10 +16,6 @@ CFLAGS += $(CFLAGS_libxenctrl)
>>>   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)
>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>> index 650c1d1574..8ff1faccef 100644
>>> --- a/tools/xenstored/core.c
>>> +++ b/tools/xenstored/core.c
>>> @@ -20,10 +20,6 @@
>>>   #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>
>>> @@ -61,7 +57,7 @@ static unsigned int current_array_size;
>>>   static unsigned int nr_fds;
>>>   static unsigned int delayed_requests;
>>> -static int sock = -1;
>>> +int sock = -1;
>>
>> Similar comment to 'fds' on the previous patch. This name is quite 
>> generic. Can we either pass it as an argument (or return) or rename it?
> 
> Turns out this patch now makes the "fds" solution more complicated: I'd 
> need to
> add fds as an additional parameter to the .can_write() and .can_read() 
> callbacks
> of struct interface_funcs.
> 
> I can do that, but an alternative would be to just rename fds to e.g. 
> poll_fds.
> 
> Do you have any preference?
The last one seems to be the simplest approach. And I am fine with the 
renaming. This can be improved in the future.

Cheers,
diff mbox series

Patch

diff --git a/tools/xenstored/Makefile.common b/tools/xenstored/Makefile.common
index 189ab81b8d..ef63ef650c 100644
--- a/tools/xenstored/Makefile.common
+++ b/tools/xenstored/Makefile.common
@@ -16,10 +16,6 @@  CFLAGS += $(CFLAGS_libxenctrl)
 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)
diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 650c1d1574..8ff1faccef 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -20,10 +20,6 @@ 
 #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>
@@ -61,7 +57,7 @@  static unsigned int current_array_size;
 static unsigned int nr_fds;
 static unsigned int delayed_requests;
 
-static int sock = -1;
+int sock = -1;
 
 int orig_argc;
 char **orig_argv;
@@ -486,7 +482,7 @@  fail:
 	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;
@@ -499,8 +495,6 @@  static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
 	*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),
@@ -2260,97 +2254,6 @@  struct connection *get_connection_by_id(unsigned int conn_id)
 	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 (fds[conn->pollfd_idx].revents & ~(POLLIN | POLLOUT)) {
-		talloc_free(conn);
-		return false;
-	}
-
-	return (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)
 {
@@ -2579,46 +2482,6 @@  void corrupt(struct connection *conn, const char *fmt, ...)
 	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,
@@ -2796,7 +2659,6 @@  int set_trace_switch(const char *arg)
 int main(int argc, char *argv[])
 {
 	int opt;
-	int sock_pollfd_idx = -1;
 	bool dofork = true;
 	bool live_update = false;
 	const char *pidfile = NULL;
@@ -2907,7 +2769,7 @@  int main(int argc, char *argv[])
 	check_store();
 
 	/* Get ready to listen to the tools. */
-	initialize_fds(&sock_pollfd_idx, &timeout);
+	initialize_fds(&timeout);
 
 	late_init(live_update);
 
@@ -2923,16 +2785,6 @@  int main(int argc, char *argv[])
 
 		handle_special_fds();
 
-		if (sock_pollfd_idx != -1) {
-			if (fds[sock_pollfd_idx].revents & ~POLLIN) {
-				barf_perror("sock poll failed");
-				break;
-			} else if (fds[sock_pollfd_idx].revents & POLLIN) {
-				accept_connection(sock);
-				sock_pollfd_idx = -1;
-			}
-		}
-
 		if (xce_pollfd_idx != -1) {
 			if (fds[xce_pollfd_idx].revents & ~POLLIN) {
 				barf_perror("xce_handle poll failed");
@@ -2986,7 +2838,7 @@  int main(int argc, char *argv[])
 			}
 		}
 
-		initialize_fds(&sock_pollfd_idx, &timeout);
+		initialize_fds(&timeout);
 	}
 }
 
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index 6944f48719..ddc345050c 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -301,6 +301,7 @@  int rm_node(struct connection *conn, const void *ctx, const char *name);
 
 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, ...);
@@ -335,6 +336,8 @@  void close_log(void);
 		errno = _saved_errno;					\
 	} while (0)
 
+extern int sock;
+
 extern int orig_argc;
 extern char **orig_argv;
 
@@ -394,14 +397,9 @@  int set_fd(int fd, short events);
 void set_special_fds(void);
 void handle_special_fds(void);
 
-void init_sockets(void);
-
 /* 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);
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 6ef136e01f..040df98b8c 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1739,14 +1739,7 @@  void read_state_connection(const void *ctx, const void *state)
 	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);
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index 3208169187..5d59cc90cc 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -18,12 +18,18 @@ 
 #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;
diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
index 2dbbef4a0b..f72c8406d2 100644
--- a/tools/xenstored/posix.c
+++ b/tools/xenstored/posix.c
@@ -24,6 +24,8 @@ 
 #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
@@ -32,10 +34,13 @@ 
 #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 void write_pidfile(const char *pidfile)
 {
 	char buf[100];
@@ -180,6 +185,142 @@  void *xenbus_map(void)
 	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 (fds[conn->pollfd_idx].revents & ~(POLLIN | POLLOUT)) {
+		talloc_free(conn);
+		return false;
+	}
+
+	return (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();
@@ -212,6 +353,9 @@  void set_special_fds(void)
 	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)
@@ -230,6 +374,15 @@  void handle_special_fds(void)
 		}
 		reopen_log_pipe0_pollfd_idx = -1;
 	}
+
+	if (sock_pollfd_idx != -1) {
+		if (fds[sock_pollfd_idx].revents & ~POLLIN) {
+			barf_perror("sock poll failed");
+		} else if (fds[sock_pollfd_idx].revents & POLLIN) {
+			accept_connection(sock);
+			sock_pollfd_idx = -1;
+		}
+	}
 }
 
 void late_init(bool live_update)