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
|