[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 04/14] oxenstored: add support for systemd active sockets
From: "Luis R. Rodriguez" <mcgrof@xxxxxxxx> 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@xxxxxxxxxxxxx> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> Cc: Vincent Hanquez <Vincent.Hanquez@xxxxxxxxxxxxx> Acked-by: Dave Scott <Dave.Scott@xxxxxxxxxx> Acked-by: Anil Madhavapeddy <anil@xxxxxxxxxx> Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxx> --- tools/ocaml/xenstored/Makefile | 11 ++- tools/ocaml/xenstored/systemd.ml | 17 +++++ tools/ocaml/xenstored/systemd.mli | 24 +++++++ tools/ocaml/xenstored/systemd_stubs.c | 132 ++++++++++++++++++++++++++++++++++ tools/ocaml/xenstored/utils.ml | 20 ++++-- tools/ocaml/xenstored/xenstored.ml | 2 + 6 files changed, 198 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..2f55d8b 100644 --- a/tools/ocaml/xenstored/Makefile +++ b/tools/ocaml/xenstored/Makefile @@ -15,6 +15,14 @@ syslog_OBJS = syslog syslog_C_OBJS = syslog_stubs OCAML_LIBRARY = syslog +LDFLAGS += $(LDLIBS_libxenstore) +CFLAGS += $(CFLAGS_libxenstore) + +LIBS += systemd.cma systemd.cmxa +systemd_OBJS = systemd +systemd_C_OBJS = systemd_stubs +OCAML_LIBRARY += systemd + OBJS = define \ stdext \ trie \ @@ -36,11 +44,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..2d3c8e1 --- /dev/null +++ b/tools/ocaml/xenstored/systemd.ml @@ -0,0 +1,17 @@ +(* + * Copyright (C) 2014 Luis R. Rodriguez <mcgrof@xxxxxxxx> + * + * 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_active_socket_required: unit -> bool = "ocaml_sd_active_socket_required" +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..3a42676 --- /dev/null +++ b/tools/ocaml/xenstored/systemd.mli @@ -0,0 +1,24 @@ +(* + * Copyright (C) 2014 Luis R. Rodriguez <mcgrof@xxxxxxxx> + * + * 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_active_socket_required: 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..76250df --- /dev/null +++ b/tools/ocaml/xenstored/systemd_stubs.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2014 Luis R. Rodriguez <mcgrof@xxxxxxxx> + * + * 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 <stdbool.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> +#include "xenstore.h" + +#if defined(HAVE_SYSTEMD) +CAMLprim value ocaml_sd_listen_fds(value connect_to) +{ + CAMLparam1(connect_to); + CAMLlocal1(sock_ret); + int sock; + struct xs_sd_ctx *ctx; + + sock_ret = Val_int(-1); + ctx = xs_get_sd_ctx(); + if (!ctx) + goto out; + + if (!xs_load_sd_required(ctx)) + goto out; + + sock = xs_claim_active_socket(ctx, (const char *) String_val(connect_to)); + if (sock <= 0) + caml_failwith("ocaml_sd_listen_fds_init() mismatch on socket"); + + sock_ret = Val_int(sock); + +out: + xs_free_sd_ctx(ctx); + CAMLreturn(sock_ret); +} + +CAMLprim value ocaml_sd_active_socket_required(value ignore) +{ + CAMLparam1(ignore); + CAMLlocal1(ret); + struct xs_sd_ctx *ctx; + + ret = Val_false; + + /* ctx can be NULL and that's OK */ + ctx = xs_get_sd_ctx(); + if (!ctx) + goto out; + + if (xs_load_sd_required(ctx)) + ret = Val_true; + +out: + xs_free_sd_ctx(ctx); + CAMLreturn(ret); +} + +CAMLprim value ocaml_sd_notify_ready(value ignore) +{ + CAMLparam1(ignore); + CAMLlocal1(ret); + struct xs_sd_ctx *ctx; + + ret = Val_int(-1); + + ctx = xs_get_sd_ctx(); + if (!ctx) { + caml_failwith("ocaml_sd_notify_ready() - failed"); + goto out; + } + + if (!xs_load_sd_required(ctx)) { + caml_failwith("ocaml_sd_notify_ready() - failed"); + goto out; + } + + ret = Val_int(0); + + xs_sd_notify_ready(ctx); +out: + xs_free_sd_ctx(ctx); + 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_active_socket_required(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..50f05c1 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_active_socket_required() 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..b8d18c8 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_active_socket_required() then + Systemd.sd_notify_ready (); main_loop () with exc -> error "caught exception %s" (Printexc.to_string exc); -- 2.0.0.rc3.18.g00a5b79 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |