[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 6/7] [xen-ocaml-tools.hg] support being run in stubdomain



When run inside a stubdomain xenstored is passed some extra args.  Use these
arguments to determine whether we are running in a stubdomain or in dom0 and act
accordingly.

Make xenstored also work when built as minios stubdomain.

When started as a stubdomain, xenstored is passed the following extra
arguments:

 * local-domid:         the domain id of the stubdom
 * dom0-grant-ref:      the grant ref needed to map dom0's store page
 * dom0-port:           the port used by dom0 to notify xenstored of changes

local-domid defaults to 0.  If it is non-zero then we're in a stub
domain.  In this case, use the grant mechanism to map store pages into
xenstore rather than map_foreign_range (as that requires the domain to 
be priviledged).

If local-domid = 0 then we cannot use the grant mechanism to map
dom0's store page (as dom0-grant-ref isn't passed in) so we use
map_foreign_range as before.  In fact we use map_foreign_range for 
mapping all domains' store pages when local-domid = 0 as well, just
to keep things consistent.

When running in a stubdom we disable a few things that minios cannot support:

 * listening for clients on unix domain sockets
 * saveto/restorefrom on disk DB 
 * signal handling (for updating on disk DB and exiting cleanly)

Signed-off-by: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx>

diff -r efd7fd89d8c6 libs/xc/xc.ml
--- a/libs/xc/xc.ml     Thu Apr 16 14:20:37 2009 +0100
+++ b/libs/xc/xc.ml     Fri Apr 17 15:07:01 2009 +0100
@@ -42,6 +42,8 @@
 
 external interface_open: unit -> handle = "stub_xc_interface_open"
 external interface_close: handle -> unit = "stub_xc_interface_close"
+external gnttab_open : unit -> handle  = "stub_gnttab_open"
+external gnttab_close : handle -> unit = "stub_gnttab_close"
 
 external using_injection: unit -> bool = "stub_xc_using_injection"
 
@@ -57,4 +59,12 @@
                          -> nativeint -> Mmap.mmap_interface
        = "stub_map_foreign_range"
 
+external gnttab_map_grant_ref :
+  handle -> domid -> int -> nativeint -> Mmap.mmap_interface
+  = "stub_gnttab_map_grant_ref"
+external gnttab_munmap :
+  handle -> Mmap.mmap_interface -> unit
+  = "stub_gnttab_munmap"
+
+
 let _ = Callback.register_exception "xc.error" (Error "register_callback")
diff -r efd7fd89d8c6 libs/xc/xc.mli
--- a/libs/xc/xc.mli    Thu Apr 16 14:20:37 2009 +0100
+++ b/libs/xc/xc.mli    Fri Apr 17 15:07:01 2009 +0100
@@ -48,3 +48,16 @@
 external map_foreign_range :
   handle -> domid -> int -> nativeint -> Mmap.mmap_interface
   = "stub_map_foreign_range"
+external gnttab_open :
+  unit -> handle
+  = "stub_gnttab_open"
+external gnttab_close :
+  handle -> unit
+  = "stub_gnttab_close"
+external gnttab_map_grant_ref :
+  handle -> domid -> int -> nativeint -> Mmap.mmap_interface
+  = "stub_gnttab_map_grant_ref"
+external gnttab_munmap :
+  handle -> Mmap.mmap_interface -> unit
+  = "stub_gnttab_munmap"
+
diff -r efd7fd89d8c6 libs/xc/xc_stubs.c
--- a/libs/xc/xc_stubs.c        Thu Apr 16 14:20:37 2009 +0100
+++ b/libs/xc/xc_stubs.c        Fri Apr 17 15:07:01 2009 +0100
@@ -15,6 +15,7 @@
  */
 
 #define _XOPEN_SOURCE 600
+#include <unistd.h>
 #include <stdlib.h>
 
 #define CAML_NAME_SPACE
@@ -147,6 +148,77 @@
        CAMLreturn(result);
 }
 
+CAMLprim value stub_gnttab_open(void)
+{
+#ifndef HAVE_LIBXC
+       caml_failwith("xc_gnttab_open not implemented");
+#else
+       int handle;
+       handle = xc_gnttab_open();
+       if (handle < 0)
+               caml_failwith("xc_gnttab_open error");
+       return Val_int(handle);
+#endif
+}
+
+CAMLprim value stub_gnttab_close(value xcg_handle)
+{
+#ifndef HAVE_LIBXC
+       caml_failwith("xc_gnttab_close not implemented");
+#else
+       CAMLparam1(xcg_handle);
+       int c_xcg_handle = _H(xcg_handle);
+       xc_gnttab_close(c_xcg_handle);
+       CAMLreturn(Val_unit);
+#endif
+}
+
+CAMLprim value stub_gnttab_map_grant_ref(value xcg_handle, value dom, value 
size,
+                                        value ref)
+{
+#ifndef HAVE_LIBXC
+       caml_failwith("xc_gnttab_map_grant_ref not implemented");
+#else
+       CAMLparam4(xcg_handle, dom, size, ref);
+       CAMLlocal1(result);
+       struct mmap_interface *intf;
+       int c_xcg_handle = _H(xcg_handle);
+       uint32_t c_dom = _D(dom);
+       unsigned long c_ref = Nativeint_val(ref);
+
+       result = caml_alloc(sizeof(struct mmap_interface), Abstract_tag);
+       intf = (struct mmap_interface *) result;
+
+       intf->len = Int_val(size);
+       intf->addr = xc_gnttab_map_grant_ref(c_xcg_handle,
+                                            c_dom,
+                                            c_ref,
+                                            PROT_READ|PROT_WRITE);
+       if (!intf->addr)
+               caml_failwith("xc_gnttab_map_grant_ref error");
+       CAMLreturn(result);
+#endif
+}
+
+CAMLprim value stub_gnttab_munmap(value xcg_handle, value interface)
+{
+#ifndef HAVE_LIBXC
+       caml_failwith("xc_gnttab_munmap not implemented");
+#else
+       CAMLparam2(xcg_handle, interface);
+       struct mmap_interface *intf;
+       int c_xcg_handle = _H(xcg_handle);
+
+       intf = ((struct mmap_interface *) interface);
+
+       if (intf->addr != NULL)
+               xc_gnttab_munmap(c_xcg_handle, intf->addr, 1);
+       intf->addr = NULL;
+       CAMLreturn(Val_unit);
+#endif
+}
+
+
 /*
  * Local variables:
  *  indent-tabs-mode: t
diff -r efd7fd89d8c6 xenstored/Makefile
--- a/xenstored/Makefile        Thu Apr 16 14:20:37 2009 +0100
+++ b/xenstored/Makefile        Fri Apr 17 15:07:01 2009 +0100
@@ -5,9 +5,9 @@
        -I ../libs/mmap -I ../libs/xc -I ../libs/eventchn \
        -I ../libs/stdext -I ../common
 
-OBJS = define ../common/config logging quota perms symbol utils store disk 
transaction \
+OBJS = define parse_arg ../common/config logging quota perms symbol utils 
store disk transaction \
        event domain domains connection connections \
-       parse_arg process xenstored
+       process xenstored
 INTF = symbol.cmi
 XENSTOREDLIBS = unix.cmxa \
        ../libs/uuid/uuid.cmxa \
diff -r efd7fd89d8c6 xenstored/domain.ml
--- a/xenstored/domain.ml       Thu Apr 16 14:20:37 2009 +0100
+++ b/xenstored/domain.ml       Fri Apr 17 15:07:01 2009 +0100
@@ -15,6 +15,7 @@
  *)
 
 open Printf
+open Parse_arg
 
 let debug fmt = Logs.debug "general" fmt
 
@@ -24,6 +25,7 @@
        mfn: nativeint;
        remote_port: int;
        interface: Mmap.mmap_interface;
+       interface_destroy: unit -> unit;
        eventchn: Event.t;
        mutable port: int;
 }
@@ -47,14 +49,15 @@
 let close dom =
        debug "domain %d unbound port %d" dom.id dom.port;
        Event.unbind dom.eventchn dom.port;
-       Mmap.unmap dom.interface;
+       dom.interface_destroy ();
        ()
 
-let make id mfn remote_port interface eventchn = {
+let make id mfn remote_port interface interface_destroy eventchn = {
        id = id;
        mfn = mfn;
        remote_port = remote_port;
        interface = interface;
+       interface_destroy = interface_destroy;
        eventchn = eventchn;
        port = -1
 }
diff -r efd7fd89d8c6 xenstored/domains.ml
--- a/xenstored/domains.ml      Thu Apr 16 14:20:37 2009 +0100
+++ b/xenstored/domains.ml      Fri Apr 17 15:07:01 2009 +0100
@@ -13,6 +13,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Lesser General Public License for more details.
  *)
+
+open Parse_arg
 
 type domains = {
        eventchn: Event.t;
@@ -57,27 +59,51 @@
        ()
 
 let create xc doms domid mfn port =
-       let interface = Xc.map_foreign_range xc domid (Mmap.getpagesize()) mfn 
in
-       let dom = Domain.make domid mfn port interface doms.eventchn in
+       let interface, interface_destroy = 
+               if do_argv.local_domid = 0 then (
+                       (* In dom0 we don't need to use grant refs as we're 
priviledged *)
+                       let interface = Xc.map_foreign_range xc domid 
(Mmap.getpagesize()) mfn in
+                       let interface_destroy = (fun () -> Mmap.unmap 
interface) in
+                       interface, interface_destroy
+               ) else (
+                       let store_gntref = 1n in
+                           let xcg = Xc.gnttab_open () in 
+                           let interface = Xc.gnttab_map_grant_ref xcg domid 
(Mmap.getpagesize()) store_gntref in
+                           let interface_destroy = (fun () -> 
(Xc.gnttab_munmap xcg interface; Xc.gnttab_close xcg)) in
+                       interface, interface_destroy
+               )
+               in
+       let dom = Domain.make domid mfn port interface interface_destroy 
doms.eventchn in
        Hashtbl.add doms.table domid dom;
        Domain.bind_interdomain dom;
        dom
 
 let create0 fake doms =
-       let port, interface =
+       let port, interface, interface_destroy =
                if fake then (
-                       0, Xc.with_intf (fun xc -> Xc.map_foreign_range xc 0 
(Mmap.getpagesize()) 0n)
+                       let interface = Xc.with_intf (fun xc -> 
Xc.map_foreign_range xc 0 (Mmap.getpagesize()) 0n) in 
+                       let interface_destroy = (fun () -> Mmap.unmap 
interface) in
+                       0, interface, interface_destroy
                ) else (
-                       let port = Utils.read_file_single_integer 
Define.xenstored_proc_port
-                       and fd = Unix.openfile Define.xenstored_proc_kva
-                                              [ Unix.O_RDWR ] 0o600 in
-                       let interface = Mmap.mmap fd Mmap.RDWR Mmap.SHARED
-                                                 (Mmap.getpagesize()) 0 in
-                       Unix.close fd;
-                       port, interface
+                       if do_argv.local_domid = 0 then (
+                               let port = Utils.read_file_single_integer 
Define.xenstored_proc_port
+                               and fd = Unix.openfile Define.xenstored_proc_kva
+                                                      [ Unix.O_RDWR ] 0o600 in
+                               let interface = Mmap.mmap fd Mmap.RDWR 
Mmap.SHARED
+                                                         (Mmap.getpagesize()) 
0 in
+                               let interface_destroy = (fun () -> Mmap.unmap 
interface) in
+                               Unix.close fd;
+                               port, interface, interface_destroy
+                       ) else (
+                               let xcg = Xc.gnttab_open () in 
+                               let interface = Xc.gnttab_map_grant_ref xcg 0 
(Mmap.getpagesize()) do_argv.dom0_grant_ref in
+                               let interface_destroy = (fun () -> 
(Xc.gnttab_munmap xcg interface; Xc.gnttab_close xcg)) in
+
+                               do_argv.dom0_port, interface, interface_destroy
+                       )
                )
                in
-       let dom = Domain.make 0 Nativeint.zero port interface doms.eventchn in
+       let dom = Domain.make 0 Nativeint.zero port interface interface_destroy 
doms.eventchn in
        Hashtbl.add doms.table 0 dom;
        Domain.bind_interdomain dom;
        Domain.notify dom;
diff -r efd7fd89d8c6 xenstored/parse_arg.ml
--- a/xenstored/parse_arg.ml    Thu Apr 16 14:20:37 2009 +0100
+++ b/xenstored/parse_arg.ml    Fri Apr 17 15:07:01 2009 +0100
@@ -24,6 +24,9 @@
        pidfile: string option; (* old xenstored compatibility *)
        tracefile: string option; (* old xenstored compatibility *)
        restart: bool;
+       local_domid: int;
+       dom0_grant_ref: nativeint;
+       dom0_port: int;
 }
 
 let do_argv =
@@ -33,7 +36,10 @@
        and daemonize = ref true
        and reraise_top_level = ref false
        and config_file = ref ""
-       and restart = ref false in
+       and restart = ref false 
+       and local_domid = ref 0 
+       and dom0_grant_ref = ref (-1)
+       and dom0_port = ref (-1) in
 
        let speclist =
                [ ("--no-domain-init", Arg.Unit (fun () -> domain_init := 
false),
@@ -49,8 +55,11 @@
                  ("--pid-file", Arg.Set_string pidfile, ""); (* for 
compatibility *)
                  ("-T", Arg.Set_string tracefile, ""); (* for compatibility *)
                  ("--restart", Arg.Set restart, "Read database on starting");
-                  ] in
-       let usage_msg = "usage : xenstored [--config-file <filename>] 
[--no-domain-init] [--help] [--no-fork] [--reraise-top-level] [--restart]" in
+                 ("--local-domid", Arg.Set_int local_domid, ""); 
+                 ("--dom0-grant-ref", Arg.Set_int dom0_grant_ref, ""); 
+                 ("--dom0-port", Arg.Set_int dom0_port, ""); 
+               ] in
+       let usage_msg = "usage : xenstored [--config-file <filename>] 
[--no-domain-init] [--help] [--no-fork] [--reraise-top-level] [--restart] 
--local-domid=<num> --dom0-grant-ref=<num> --dom0-port=<num>" in
        Arg.parse speclist (fun s -> ()) usage_msg;
        {
                domain_init = !domain_init;
@@ -60,5 +69,8 @@
                config_file = if !config_file <> "" then Some !config_file else 
None;
                pidfile = if !pidfile <> "" then Some !pidfile else None;
                tracefile = if !tracefile <> "" then Some !tracefile else None;
-               restart = !restart
+               restart = !restart;
+               local_domid = !local_domid;
+               dom0_grant_ref = Nativeint.of_int !dom0_grant_ref;
+               dom0_port = !dom0_port;
        }
diff -r efd7fd89d8c6 xenstored/xenstored.ml
--- a/xenstored/xenstored.ml    Thu Apr 16 14:20:37 2009 +0100
+++ b/xenstored/xenstored.ml    Fri Apr 17 15:07:01 2009 +0100
@@ -225,24 +225,27 @@
               Define.xenstored_major Define.xenstored_minor;
 
        let cf = do_argv in
-       let pidfile = parse_config (config_filename cf) in
-       Unixext.mkdir_rec (Filename.dirname pidfile) 0o755;
 
-       let rw_sock = Unix.handle_unix_error Utils.create_unix_socket 
Define.xs_daemon_socket in
-       let ro_sock = Unix.handle_unix_error Utils.create_unix_socket 
Define.xs_daemon_socket_ro in
-       
-       if cf.daemonize then
-               Unixext.daemonize ();
+       (* We can only daemonize & write pidfile in dom0, not in minios stubdom 
*)
+       if cf.local_domid = 0 then (
+               let pidfile = parse_config (config_filename cf) in
+               Unixext.mkdir_rec (Filename.dirname pidfile) 0o755;
+               if cf.daemonize then
+                       Unixext.daemonize ();
+               Unixext.pidfile_write pidfile;
+       );
 
-       Unixext.pidfile_write pidfile;
+       (* We can only support clients connecting via unix domain sockets in 
dom0, not in minios stubdom *)
+       let rw_sock, ro_sock = 
+               if cf.local_domid = 0 then (
+                       Unix.handle_unix_error Utils.create_unix_socket 
Define.xs_daemon_socket, 
+                       Unix.handle_unix_error Utils.create_unix_socket 
Define.xs_daemon_socket_ro
+               ) else (
+                       Unix.stdin, Unix.stdin
+               ) in
 
        info "Xen Storage Daemon, version %d.%d"
             Define.xenstored_major Define.xenstored_minor;
-
-       (* for compatilibity with old xenstored *)
-       begin match cf.pidfile with
-       | Some pidfile -> Unixext.pidfile_write pidfile
-       | None         -> () end;
 
        let store = Store.create () in
        let eventchn = Event.init () in
@@ -271,14 +274,17 @@
                );
        );
 
-       Sys.set_signal Sys.sighup (Sys.Signal_handle sighup_handler);
-       Sys.set_signal Sys.sigterm (Sys.Signal_handle (fun i -> quit := true));
-       Sys.set_signal Sys.sigusr1 (Sys.Signal_handle (fun i -> sigusr1_handler 
store));
-       Sys.set_signal Sys.sigpipe Sys.Signal_ignore;
+       (* We only support signals and logging in dom0, not in minios stubdom *)
+       if cf.local_domid = 0 then (
+               Sys.set_signal Sys.sighup (Sys.Signal_handle sighup_handler);
+               Sys.set_signal Sys.sigterm (Sys.Signal_handle (fun i -> quit := 
true));
+               Sys.set_signal Sys.sigusr1 (Sys.Signal_handle (fun i -> 
sigusr1_handler store));
+               Sys.set_signal Sys.sigpipe Sys.Signal_ignore;
 
-       Logging.init cf.activate_access_log (fun () -> DB.to_file store cons 
"/var/run/xenstored/db");
+               Logging.init cf.activate_access_log (fun () -> DB.to_file store 
cons "/var/run/xenstored/db");
+       );
 
-       let spec_fds = [ rw_sock; ro_sock ] @
+       let spec_fds = (if cf.local_domid = 0 then [ rw_sock; ro_sock ] else 
[]) @
                       (if cf.domain_init then [ eventchn.Event.fd ] else []) in
 
        let xc = Xc.interface_open () in
@@ -302,8 +308,11 @@
                        if List.mem fd set then
                                fct fd in
 
-               do_if_set rw_sock rset (accept_connection true);
-               do_if_set ro_sock rset (accept_connection false);
+               (* We cannot accept socket connections from clients when 
running in a stubdom *)
+               if cf.local_domid = 0 then (
+                       do_if_set rw_sock rset (accept_connection true);
+                       do_if_set ro_sock rset (accept_connection false);
+               );
                do_if_set eventchn.Event.fd rset (handle_eventchn)
                in
 
@@ -380,7 +389,8 @@
                                raise exc
        done;
        info "stopping xenstored";
-       DB.to_file store cons "/var/run/xenstored/db";
+       (* At the moment we can only save the state to a file in dom0, not when 
running in a minios stubdom *)
+       if cf.local_domid = 0 then (DB.to_file store cons 
"/var/run/xenstored/db");
        ()
 
 let _ = main ()

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.