@@ -43,6 +43,11 @@ type virq_t =
external notify: handle -> int -> unit = "stub_eventchn_notify"
external bind_interdomain: handle -> int -> int -> int = "stub_eventchn_bind_interdomain"
+
+let restore_interdomain handle _domid _remote_port local_port =
+ notify handle local_port;
+ local_port
+
external bind_virq: handle -> virq_t -> int = "stub_eventchn_bind_virq"
let bind_dom_exc_virq handle = bind_virq handle Dom_exc
external unbind: handle -> int -> unit = "stub_eventchn_unbind"
@@ -68,6 +68,11 @@ val bind_interdomain : handle -> int -> int -> t
channel connected to domid:remote_port. On error it will
throw a Failure exception. *)
+val restore_interdomain : handle -> int -> int -> int -> t
+(** [restore_interdomain h domid remote_port local_port] returns a local event
+ channel connected to domid:remote_port. On error it will
+ throw a Failure exception. *)
+
val bind_dom_exc_virq : handle -> t
(** Binds a local event channel to the VIRQ_DOM_EXC
(domain exception VIRQ). On error it will throw a Failure
@@ -61,7 +61,7 @@ let string_of_port = function
| Some x -> string_of_int (Xeneventchn.to_int x)
let dump d chan =
- fprintf chan "dom,%d,%nd,%d\n" d.id d.mfn d.remote_port
+ fprintf chan "dom,%d,%nd,%d,%s\n" d.id d.mfn d.remote_port (string_of_port d.port)
let notify dom = match dom.port with
| None ->
@@ -77,6 +77,10 @@ let bind_interdomain dom =
dom.port <- Some (Event.bind_interdomain dom.eventchn dom.id dom.remote_port);
debug "bound domain %d remote port %d to local port %s" dom.id dom.remote_port (string_of_port dom.port)
+let restore_interdomain dom localport =
+ assert (dom.port = None);
+ dom.port <- Some (Event.restore_interdomain dom.eventchn dom.id dom.remote_port localport);
+ debug "restored interdomain %d remote port %d to local port %s" dom.id dom.remote_port (string_of_port dom.port)
let close dom =
debug "domain %d unbound port %s" dom.id (string_of_port dom.port);
@@ -123,17 +123,22 @@ let cleanup doms =
let resume _doms _domid =
()
-let create doms domid mfn port =
+let maybe_bind_interdomain restore_localport dom =
+ match restore_localport with
+ | None -> Domain.bind_interdomain dom
+ | Some p -> Domain.restore_interdomain dom p
+
+let create doms domid mfn ?restore_localport port =
let interface = Xenctrl.map_foreign_range xc domid (Xenmmap.getpagesize()) mfn in
let dom = Domain.make domid mfn port interface doms.eventchn in
Hashtbl.add doms.table domid dom;
- Domain.bind_interdomain dom;
+ maybe_bind_interdomain restore_localport dom;
dom
let xenstored_kva = ref ""
let xenstored_port = ref ""
-let create0 doms =
+let create0 ?restore_localport doms =
let port, interface =
(
let port = Utils.read_file_single_integer !xenstored_port
@@ -147,7 +152,7 @@ let create0 doms =
in
let dom = Domain.make 0 Nativeint.zero port interface doms.eventchn in
Hashtbl.add doms.table 0 dom;
- Domain.bind_interdomain dom;
+ maybe_bind_interdomain restore_localport dom;
Domain.notify dom;
dom
@@ -29,6 +29,7 @@ let init ?fd () =
let fd eventchn = Xeneventchn.fd eventchn.handle
let bind_dom_exc_virq eventchn = eventchn.virq_port <- Some (Xeneventchn.bind_dom_exc_virq eventchn.handle)
let bind_interdomain eventchn domid port = Xeneventchn.bind_interdomain eventchn.handle domid port
+let restore_interdomain eventchn domid port local_port = Xeneventchn.restore_interdomain eventchn.handle domid port local_port
let unbind eventchn port = Xeneventchn.unbind eventchn.handle port
let notify eventchn port = Xeneventchn.notify eventchn.handle port
let pending eventchn = Xeneventchn.pending eventchn.handle
@@ -169,10 +169,13 @@ module DB = struct
event_f ~eventfd
| "socket" :: fd :: [] ->
socket_f ~fd:(int_of_string fd)
- | "dom" :: domid :: mfn :: port :: []->
+ | "dom" :: domid :: mfn :: port :: rest ->
domain_f (int_of_string domid)
(Nativeint.of_string mfn)
(int_of_string port)
+ (match rest with
+ | [] -> None (* backward compat: old version didn't have it *)
+ | localport :: _ -> Some (int_of_string localport))
| "watch" :: domid :: path :: token :: [] ->
watch_f (int_of_string domid)
(unhexify path) (unhexify token)
@@ -232,13 +235,13 @@ module DB = struct
else
warn "Ignoring invalid socket FD %d" fd
in
- let domain_f domid mfn port =
+ let domain_f domid mfn port restore_localport =
let doms = require_doms () in
let ndom =
if domid > 0 then
- Domains.create doms domid mfn port
+ Domains.create doms domid mfn ?restore_localport port
else
- Domains.create0 doms
+ Domains.create0 ?restore_localport doms
in
Connections.add_domain cons ndom;
in
See explanation in previous commit. This introduces a new field into the live update stream to retain both ports, and handles the missing value in a backward compatible way. Signed-off-by: Edwin Török <edvin.torok@citrix.com> --- Reason for inclusion 4.17: - fixes a bug in oxenstored live update, needed to make live updates with future 4.17 security fixes possible/more reliable Changes since v2: - new in v3 --- tools/ocaml/libs/eventchn/xeneventchn.ml | 5 +++++ tools/ocaml/libs/eventchn/xeneventchn.mli | 5 +++++ tools/ocaml/xenstored/domain.ml | 6 +++++- tools/ocaml/xenstored/domains.ml | 13 +++++++++---- tools/ocaml/xenstored/event.ml | 1 + tools/ocaml/xenstored/xenstored.ml | 11 +++++++---- 6 files changed, 32 insertions(+), 9 deletions(-)