1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
open Lwt
open Sexplib.Std
module Make(Xs: Xs_client_lwt.S) = struct
type t = {
ring_ref: string;
event_channel: string;
} [@@deriving sexp]
let write ~client_domid ~port t =
Xs.make ()
>>= fun c ->
Xs.(immediate c (fun h -> read h "domid")) >>= fun server_domid ->
Xs.(immediate c (fun h -> getdomainpath h (int_of_string server_domid))) >>= fun domainpath ->
let xs_path = Printf.sprintf "%s/data/vchan/%d/%s" domainpath client_domid (Port.to_string port) in
let acl =
Xs_protocol.ACL.({owner = int_of_string server_domid; other = NONE; acl = [ client_domid, READ ]}) in
let info = [
xs_path ^ "/ring-ref", t.ring_ref;
xs_path ^ "/event-channel", t.event_channel;
] in
Xs.(transaction c
(fun h ->
Lwt_list.iter_s (fun (k, v) ->
write h k v >>= fun () ->
setperms h k acl
) info
)
)
let read ~server_domid ~port =
Xs.make ()
>>= fun c ->
Xs.(immediate c (fun h -> read h "domid")) >>= fun client_domid ->
Xs.(immediate c (fun h -> getdomainpath h server_domid)) >>= fun domainpath ->
let xs_path = Printf.sprintf "%s/data/vchan/%s/%s" domainpath client_domid (Port.to_string port) in
Xs.(wait c
(fun xsh ->
Lwt.catch
(fun () ->
read xsh (xs_path ^ "/ring-ref") >>= fun rref ->
read xsh (xs_path ^ "/event-channel") >>= fun evtchn ->
return (rref, evtchn)
)(fun _ -> fail Xs_protocol.Eagain)))
>>= fun (ring_ref, event_channel) ->
return { ring_ref; event_channel }
let delete ~client_domid ~port =
Xs.make ()
>>= fun c ->
Xs.(immediate c (fun h -> read h "domid")) >>= fun server_domid ->
Xs.(immediate c (fun h -> getdomainpath h (int_of_string server_domid))) >>= fun domainpath ->
let xs_path = Printf.sprintf "%s/data/vchan/%d/%s" domainpath client_domid (Port.to_string port) in
Xs.(transaction c
(fun h ->
rm h xs_path
>>= fun () ->
let dir = Filename.dirname xs_path in
directory h dir
>>= function
| [] -> rm h dir
| _ -> return ()
)
)
end