[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |