xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
To: xen-devel@lists.xenproject.org
Cc: David Scott <dave.scott@eu.citrix.com>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	"Luis R. Rodriguez" <mcgrof@suse.com>,
	Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>,
	Ian Campbell <ian.campbell@citrix.com>
Subject: [PATCH v7 3/8] oxenstored: add support for systemd active sockets
Date: Thu, 17 Jul 2014 16:28:14 -0700	[thread overview]
Message-ID: <1405639699-13494-4-git-send-email-mcgrof@do-not-panic.com> (raw)
In-Reply-To: <1405639699-13494-1-git-send-email-mcgrof@do-not-panic.com>

From: "Luis R. Rodriguez" <mcgrof@suse.com>

This adds systemd socket activation support for the Ocaml xenstored.
Ocaml lacks systemd library support so we provide our own C helpers
as is done with other functionality lacking on Ocaml.

Active sockets enables oxenstored to be loaded only if required by a system
onto which Xen is installed on. Socket activation is handled by
systemd, once a port for a service which claims a socket is used
systemd will start the required services for it, on demand. For more
details on socket activation refer to Lennart's socket-activation
post regarding this [0].

An important difference with socket activation is that systemd will set
FD_CLOEXEC for us on the socket before giving it to us, we'll sprinkly
the Unix.set_close_on_exec for LSB init next as a separate commit.

Right now this code adds a no-op for this functionality, leaving the
enablement to be done later once systemd is properly hooked into
the build system. The socket activation is ordered in aligment with
the socket activation order passed on to systemd.

[0] http://0pointer.de/blog/projects/socket-activation2.html

Cc: David Scott <dave.scott@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>
Acked-by: Dave Scott <Dave.Scott@citrix.com>
Acked-by: Anil Madhavapeddy <anil@recoil.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 tools/ocaml/xenstored/Makefile        |   8 +-
 tools/ocaml/xenstored/systemd.ml      |  17 ++++
 tools/ocaml/xenstored/systemd.mli     |  24 ++++++
 tools/ocaml/xenstored/systemd_stubs.c | 152 ++++++++++++++++++++++++++++++++++
 tools/ocaml/xenstored/utils.ml        |  20 +++--
 tools/ocaml/xenstored/xenstored.ml    |   2 +
 6 files changed, 215 insertions(+), 8 deletions(-)
 create mode 100644 tools/ocaml/xenstored/systemd.ml
 create mode 100644 tools/ocaml/xenstored/systemd.mli
 create mode 100644 tools/ocaml/xenstored/systemd_stubs.c

diff --git a/tools/ocaml/xenstored/Makefile b/tools/ocaml/xenstored/Makefile
index 7fa8f53..382a813 100644
--- a/tools/ocaml/xenstored/Makefile
+++ b/tools/ocaml/xenstored/Makefile
@@ -15,6 +15,11 @@ syslog_OBJS = syslog
 syslog_C_OBJS = syslog_stubs
 OCAML_LIBRARY = syslog
 
+LIBS += systemd.cma systemd.cmxa
+systemd_OBJS = systemd
+systemd_C_OBJS = systemd_stubs
+OCAML_LIBRARY += systemd
+
 OBJS = define \
 	stdext \
 	trie \
@@ -36,11 +41,12 @@ OBJS = define \
 	process \
 	xenstored
 
-INTF = symbol.cmi trie.cmi syslog.cmi
+INTF = symbol.cmi trie.cmi syslog.cmi systemd.cmi
 
 XENSTOREDLIBS = \
 	unix.cmxa \
 	-ccopt -L -ccopt . syslog.cmxa \
+	-ccopt -L -ccopt . systemd.cmxa \
 	-ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/mmap $(OCAML_TOPLEVEL)/libs/mmap/xenmmap.cmxa \
 	-ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/eventchn $(OCAML_TOPLEVEL)/libs/eventchn/xeneventchn.cmxa \
 	-ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/xc $(OCAML_TOPLEVEL)/libs/xc/xenctrl.cmxa \
diff --git a/tools/ocaml/xenstored/systemd.ml b/tools/ocaml/xenstored/systemd.ml
new file mode 100644
index 0000000..2aa39ea
--- /dev/null
+++ b/tools/ocaml/xenstored/systemd.ml
@@ -0,0 +1,17 @@
+(*
+ * Copyright (C) 2014 Luis R. Rodriguez <mcgrof@suse.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * 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 Lesser General Public License for more details.
+ *)
+
+external sd_listen_fds: string -> Unix.file_descr = "ocaml_sd_listen_fds"
+external sd_booted: unit -> bool = "ocaml_sd_booted"
+external sd_notify_ready: unit -> unit = "ocaml_sd_notify_ready"
diff --git a/tools/ocaml/xenstored/systemd.mli b/tools/ocaml/xenstored/systemd.mli
new file mode 100644
index 0000000..85c9f2e
--- /dev/null
+++ b/tools/ocaml/xenstored/systemd.mli
@@ -0,0 +1,24 @@
+(*
+ * Copyright (C) 2014 Luis R. Rodriguez <mcgrof@suse.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * 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 Lesser General Public License for more details.
+ *)
+
+(** Calls the C library sd_listen_fds() function for us. Although
+ *  the library doesn't accept argument we send one over to help
+ *  us do sanity checks on the expected sockets *)
+val sd_listen_fds: string -> Unix.file_descr
+
+(** Tells us whether or not systemd support was compiled in *)
+val sd_booted: unit -> bool
+
+(** Tells systemd we're ready *)
+external sd_notify_ready: unit -> unit = "ocaml_sd_notify_ready"
diff --git a/tools/ocaml/xenstored/systemd_stubs.c b/tools/ocaml/xenstored/systemd_stubs.c
new file mode 100644
index 0000000..a368ac1
--- /dev/null
+++ b/tools/ocaml/xenstored/systemd_stubs.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 Luis R. Rodriguez <mcgrof@suse.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * 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 Lesser General Public License for more details.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <caml/mlvalues.h>
+#include <caml/memory.h>
+#include <caml/alloc.h>
+#include <caml/custom.h>
+#include <caml/signals.h>
+#include <caml/fail.h>
+#include <config.h>
+
+#if defined(HAVE_SYSTEMD)
+
+#include <sys/socket.h>
+#include <systemd/sd-daemon.h>
+
+/* Will work regardless of the order systemd gives them to us */
+static int oxen_get_sd_fd(const char *connect_to)
+{
+	int fd = SD_LISTEN_FDS_START;
+	int r;
+
+	while (fd <= SD_LISTEN_FDS_START + 1) {
+		r = sd_is_socket_unix(fd, SOCK_STREAM, 1, connect_to, 0);
+		if (r > 0)
+			return fd;
+		fd++;
+	}
+
+	return -EBADR;
+}
+
+static int oxen_verify_socket_socket(const char *connect_to)
+{
+	if ((strcmp("/var/run/xenstored/socket_ro", connect_to) != 0) &&
+	    (strcmp("/var/run/xenstored/socket", connect_to) != 0)) {
+		sd_notifyf(0, "STATUS=unexpected socket: %s\n"
+			   "ERRNO=%i",
+			   connect_to,
+			   EBADR);
+		return -EBADR;
+	}
+
+	return oxen_get_sd_fd(connect_to);
+}
+
+CAMLprim value ocaml_sd_listen_fds(value connect_to)
+{
+	CAMLparam1(connect_to);
+	CAMLlocal1(sock_ret);
+	int sock = -EBADR, n;
+
+	n = sd_listen_fds(0);
+	if (n <= 0) {
+		sd_notifyf(0, "STATUS=Failed to get any active sockets: %s\n"
+			   "ERRNO=%i",
+			   strerror(errno),
+			   errno);
+		caml_failwith("ocaml_sd_listen_fds() failed to get any sockets");
+	} else if (n > 2) {
+		fprintf(stderr, SD_ERR "Expected 2 fds but given %d\n", n);
+		sd_notifyf(0, "STATUS=Mismatch on number (2): %s\n"
+			   "ERRNO=%d",
+			   strerror(EBADR),
+			   EBADR);
+		caml_failwith("ocaml_sd_listen_fds() mismatch");
+	}
+
+	sock = oxen_verify_socket_socket(String_val(connect_to));
+	if (sock <= 0) {
+		fprintf(stderr, "failed to verify sock %s\n",
+			String_val(connect_to));
+		caml_failwith("ocaml_sd_listen_fds_init() invalid socket");
+	}
+
+	sock_ret = Val_int(sock);
+
+	CAMLreturn(sock_ret);
+}
+
+CAMLprim value ocaml_sd_booted(value ignore)
+{
+	CAMLparam1(ignore);
+	CAMLlocal1(ret);
+
+	ret = Val_false;
+
+	if (sd_booted())
+		ret = Val_true;
+
+	CAMLreturn(ret);
+}
+
+CAMLprim value ocaml_sd_notify_ready(value ignore)
+{
+	CAMLparam1(ignore);
+	CAMLlocal1(ret);
+
+	ret = Val_int(0);
+
+	sd_notify(1, "READY=1");
+
+	CAMLreturn(ret);
+}
+
+#else
+
+CAMLprim value ocaml_sd_listen_fds(value connect_to)
+{
+	CAMLparam1(connect_to);
+	CAMLlocal1(sock_ret);
+
+	sock_ret = Val_int(-1);
+
+	CAMLreturn(sock_ret);
+}
+
+CAMLprim value ocaml_sd_booted(value ignore)
+{
+	CAMLparam1(ignore);
+	CAMLlocal1(ret);
+
+	ret = Val_false;
+
+	CAMLreturn(ret);
+}
+
+CAMLprim value ocaml_sd_notify_ready(value ignore)
+{
+	CAMLparam1(ignore);
+	CAMLlocal1(ret);
+
+	ret = Val_int(-1);
+
+	CAMLreturn(ret);
+}
+#endif
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index 68b70c5..0cfeded 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -73,14 +73,20 @@ let trim_path path =
 let join_by_null ls = String.concat "\000" ls
 
 (* unix utils *)
+let create_regular_unix_socket name =
+        Unixext.unlink_safe name;
+        Unixext.mkdir_rec (Filename.dirname name) 0o700;
+        let sockaddr = Unix.ADDR_UNIX(name) in
+        let sock = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in
+        Unix.bind sock sockaddr;
+        Unix.listen sock 1;
+        sock
+
 let create_unix_socket name =
-	Unixext.unlink_safe name;
-	Unixext.mkdir_rec (Filename.dirname name) 0o700;
-	let sockaddr = Unix.ADDR_UNIX(name) in
-	let sock = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in
-	Unix.bind sock sockaddr;
-	Unix.listen sock 1;
-	sock
+        if Systemd.sd_booted() then
+                Systemd.sd_listen_fds name
+        else
+                create_regular_unix_socket name
 
 let read_file_single_integer filename =
 	let fd = Unix.openfile filename [ Unix.O_RDONLY ] 0o640 in
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 438ecb9..1c02f2f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -383,6 +383,8 @@ let _ =
 	while not !quit
 	do
 		try
+                        if Systemd.sd_booted() then
+                                Systemd.sd_notify_ready ();
 			main_loop ()
 		with exc ->
 			error "caught exception %s" (Printexc.to_string exc);
-- 
2.0.1

  parent reply	other threads:[~2014-07-17 23:28 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-17 23:28 [PATCH v7 0/8] xen: add systemd support Luis R. Rodriguez
2014-07-17 23:28 ` [PATCH v7 1/8] xenstored: enable usage of config.h on both xenstored and oxenstored Luis R. Rodriguez
2014-07-17 23:28 ` [PATCH v7 2/8] cxenstored: add support for systemd active sockets Luis R. Rodriguez
2014-07-24 15:10   ` Ian Campbell
2014-07-24 15:54     ` Ian Campbell
2014-07-25 22:45     ` Luis R. Rodriguez
2014-07-28  9:48       ` Ian Campbell
2014-07-28 15:06         ` Luis R. Rodriguez
2015-08-05 10:06   ` George Dunlap
2015-08-05 10:17     ` Ian Campbell
2015-08-05 10:56       ` George Dunlap
2015-08-05 11:11         ` Ian Campbell
2015-08-05 11:14           ` Ian Campbell
2015-08-05 11:21           ` George Dunlap
2015-08-05 11:27             ` Ian Campbell
2015-08-05 13:17         ` Wei Liu
2015-08-05 16:30           ` George Dunlap
2015-08-05 17:24             ` Wei Liu
2015-08-05 18:19               ` Wei Liu
2015-08-06  9:13                 ` Ian Campbell
2015-08-06  9:20                   ` Wei Liu
2015-08-06  9:29                     ` Ian Campbell
2015-08-06  9:36                       ` Wei Liu
2015-08-06 10:17                   ` Wei Liu
2015-08-06 10:48                     ` Ian Campbell
2015-08-06 10:56                       ` Wei Liu
2015-08-06 11:03                         ` Ian Campbell
2015-08-06 13:56                 ` George Dunlap
2014-07-17 23:28 ` Luis R. Rodriguez [this message]
2014-07-17 23:28 ` [PATCH v7 4/8] oxenstored: force FD_CLOEXEC with Unix.set_close_on_exec on LSB init Luis R. Rodriguez
2014-07-24 15:09   ` Ian Campbell
2014-07-17 23:28 ` [PATCH v7 5/8] autoconf: xen: move standard path variables to config/Paths.mk.in Luis R. Rodriguez
2014-07-24 15:29   ` Ian Campbell
2014-07-17 23:28 ` [PATCH v7 6/8] xencommons: move module list into a generic place Luis R. Rodriguez
2014-07-24 15:35   ` Ian Campbell
2014-07-25 23:16     ` Luis R. Rodriguez
2014-07-17 23:28 ` [PATCH v7 7/8] autoconf: xen: enable explicit preference option for xenstored preference Luis R. Rodriguez
2014-07-24 15:40   ` Ian Campbell
2014-07-25 23:25     ` Luis R. Rodriguez
2014-07-17 23:28 ` [PATCH v7 8/8] systemd: add xen systemd service and module files Luis R. Rodriguez
2014-07-24 15:47   ` Ian Campbell
2014-07-25 23:34     ` Luis R. Rodriguez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1405639699-13494-4-git-send-email-mcgrof@do-not-panic.com \
    --to=mcgrof@do-not-panic.com \
    --cc=Vincent.Hanquez@eu.citrix.com \
    --cc=dave.scott@eu.citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=mcgrof@suse.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).