Skip to content

Commit ba66bbb

Browse files
authored
Merge pull request #55 from last-genius/directory_part
2 parents f6fb5dd + dd8845d commit ba66bbb

File tree

9 files changed

+81
-69
lines changed

9 files changed

+81
-69
lines changed

client_lwt/xs_client_lwt.ml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ module type S = sig
5454
val mkdir : handle -> string -> unit Lwt.t
5555
val setperms : handle -> string -> Xs_protocol.ACL.t -> unit Lwt.t
5656
val debug : handle -> string list -> string list Lwt.t
57-
val restrict : handle -> int -> unit Lwt.t
5857
val getdomainpath : handle -> int -> string Lwt.t
5958
val watch : handle -> string -> Xs_protocol.Token.t -> unit Lwt.t
6059
val unwatch : handle -> string -> Xs_protocol.Token.t -> unit Lwt.t
@@ -342,9 +341,6 @@ functor
342341

343342
let debug h cmd_args = rpc "debug" h (Request.Debug cmd_args) Unmarshal.list
344343

345-
let restrict h domid =
346-
rpc "restrict" h (Request.Restrict domid) Unmarshal.ok
347-
348344
let getdomainpath h domid =
349345
rpc "getdomainpath" h (Request.Getdomainpath domid) Unmarshal.string
350346

client_lwt/xs_client_lwt.mli

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,6 @@ module type S = sig
8989
val debug : handle -> string list -> string list Lwt.t
9090
(** [debug cmd_args] invokes a debug command. *)
9191

92-
val restrict : handle -> int -> unit Lwt.t
93-
(** [restrict h domid] restricts the current connection to have only
94-
the priviledges associated with domain [domid]. *)
95-
9692
val getdomainpath : handle -> int -> string Lwt.t
9793
(** [getdomainpath domid] returns the local directory of domain
9894
[domid]. *)

client_unix/xs_client_unix.ml

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,40 @@ functor
301301
with_mutex c.m (fun () -> Hashtbl.remove c.rid_to_wakeup rid);
302302
response hint request res unmarshal)
303303

304+
let directory_part h path offset =
305+
rpc "directory_part" h
306+
Request.(PathOp (path, Directory_part offset))
307+
Unmarshal.raw
308+
309+
let rpc_dir hint h path =
310+
try rpc hint h Request.(PathOp (path, Directory)) Unmarshal.list
311+
with Error "E2BIG" ->
312+
let data = Buffer.create 16 in
313+
let rec read_part generation =
314+
let offset = Buffer.length data in
315+
let out = directory_part h path offset in
316+
let i = String.index out '\000' in
317+
let new_generation = String.sub out 0 i in
318+
319+
(* Node's children changed, restart *)
320+
if offset <> 0 && new_generation <> generation then (
321+
Buffer.clear data;
322+
read_part "")
323+
else Buffer.add_substring data out (i + 1) (String.length out - i - 1);
324+
325+
let l = Buffer.length data in
326+
327+
if l < 2 then Buffer.clear data
328+
else if String.ends_with ~suffix:"\000\000" (Buffer.contents data)
329+
then (* last packet *)
330+
Buffer.truncate data (l - 2)
331+
else read_part new_generation
332+
in
333+
read_part "";
334+
String.split_on_char '\000' (Buffer.contents data)
335+
304336
let directory h path =
305-
rpc "directory"
306-
(Xs_handle.accessed_path h path)
307-
Request.(PathOp (path, Directory))
308-
Unmarshal.list
337+
rpc_dir "directory" (Xs_handle.accessed_path h path) path
309338

310339
let read h path =
311340
rpc "read"
@@ -339,9 +368,6 @@ functor
339368

340369
let debug h cmd_args = rpc "debug" h (Request.Debug cmd_args) Unmarshal.list
341370

342-
let restrict h domid =
343-
rpc "restrict" h (Request.Restrict domid) Unmarshal.ok
344-
345371
let getdomainpath h domid =
346372
rpc "getdomainpath" h (Request.Getdomainpath domid) Unmarshal.string
347373

client_unix/xs_client_unix.mli

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,6 @@ module Client : functor (IO : IO) -> sig
110110
val debug : handle -> string list -> string list IO.t
111111
(** [debug cmd_args] invokes a debug command. *)
112112

113-
val restrict : handle -> int -> unit IO.t
114-
(** [restrict h domid] restricts the current connection to have only
115-
the priviledges associated with domain [domid]. *)
116-
117113
val getdomainpath : handle -> int -> string IO.t
118114
(** [getdomainpath domid] returns the local directory of domain
119115
[domid]. *)

core/xs_protocol.ml

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ module Op = struct
3737
| Isintroduced
3838
| Resume
3939
| Set_target
40-
| Restrict
40+
| Invalid
41+
| Reset_watches
42+
| Directory_part
4143

4244
(* The index of the value in the array is the integer representation used
4345
by the wire protocol. Every element of t exists exactly once in the array. *)
@@ -63,7 +65,9 @@ module Op = struct
6365
; Isintroduced
6466
; Resume
6567
; Set_target
66-
; Restrict
68+
; Invalid
69+
; Reset_watches
70+
; Directory_part
6771
|]
6872

6973
let of_int32 i =
@@ -104,7 +108,9 @@ module Op = struct
104108
| Isintroduced -> "isintroduced"
105109
| Resume -> "resume"
106110
| Set_target -> "set_target"
107-
| Restrict -> "restrict"
111+
| Invalid -> "invalid"
112+
| Reset_watches -> "reset_watches"
113+
| Directory_part -> "directory_part"
108114
end
109115

110116
let split_string ~limit c s =
@@ -212,6 +218,7 @@ let get_data pkt =
212218
Buffer.sub pkt.data 0 (pkt.len - 1)
213219
else Buffer.contents pkt.data
214220

221+
let get_raw_data pkt = Buffer.contents pkt.data
215222
let get_rid pkt = pkt.rid
216223

217224
module Parser = struct
@@ -372,10 +379,12 @@ module Response = struct
372379
| Resume
373380
| Release
374381
| Set_target
375-
| Restrict
376382
| Isintroduced of bool
377383
| Error of string
378384
| Watchevent of string * string
385+
| Directory_part of int64 * string
386+
(* Not a string list like Directory because we need to add another null
387+
character at the end of the last packet *)
379388

380389
let prettyprint_payload =
381390
let open Printf in
@@ -397,10 +406,10 @@ module Response = struct
397406
| Resume -> "Resume"
398407
| Release -> "Release"
399408
| Set_target -> "Set_target"
400-
| Restrict -> "Restrict"
401409
| Isintroduced x -> sprintf "Isintroduced %b" x
402410
| Error x -> sprintf "Error %s" x
403411
| Watchevent (x, y) -> sprintf "Watchevent %s %s" x y
412+
| Directory_part (gen, ls) -> sprintf "Directory_part %Ld %s" gen ls
404413

405414
let ty_of_payload = function
406415
| Read _ -> Op.Read
@@ -423,7 +432,7 @@ module Response = struct
423432
| Resume -> Op.Resume
424433
| Release -> Op.Release
425434
| Set_target -> Op.Set_target
426-
| Restrict -> Op.Restrict
435+
| Directory_part _ -> Op.Directory_part
427436

428437
let ok = "OK\000"
429438

@@ -437,6 +446,9 @@ module Response = struct
437446
| Isintroduced b -> data_concat [ (if b then "T" else "F") ]
438447
| Watchevent (path, token) -> data_concat [ path; token ]
439448
| Error x -> data_concat [ x ]
449+
| Directory_part (gen, ls) ->
450+
let gen = Int64.to_string gen in
451+
gen ^ "\000" ^ ls
440452
| _ -> ok
441453

442454
let print x tid rid = create tid rid (ty_of_payload x) (data_of_payload x)
@@ -446,6 +458,7 @@ module Request = struct
446458
type path_op =
447459
| Read
448460
| Directory
461+
| Directory_part of int (* offset *)
449462
| Getperms
450463
| Write of string
451464
| Mkdir
@@ -464,7 +477,6 @@ module Request = struct
464477
| Resume of int
465478
| Release of int
466479
| Set_target of int * int
467-
| Restrict of int
468480
| Isintroduced of int
469481
| Error of string
470482
| Watchevent of string
@@ -474,6 +486,8 @@ module Request = struct
474486
let prettyprint_pathop x = function
475487
| Read -> sprintf "Read %s" x
476488
| Directory -> sprintf "Directory %s" x
489+
| Directory_part offset ->
490+
sprintf "Directory_part %s %s" x (string_of_int offset)
477491
| Getperms -> sprintf "Getperms %s" x
478492
| Write v -> sprintf "Write %s %s" x v
479493
| Mkdir -> sprintf "Mkdir %s" x
@@ -492,12 +506,13 @@ module Request = struct
492506
| Resume x -> sprintf "Resume %d" x
493507
| Release x -> sprintf "Release %d" x
494508
| Set_target (x, y) -> sprintf "Set_target %d %d" x y
495-
| Restrict x -> sprintf "Restrict %d" x
496509
| Isintroduced x -> sprintf "Isintroduced %d" x
497510
| Error x -> sprintf "Error %s" x
498511
| Watchevent x -> sprintf "Watchevent %s" x
499512

500513
exception Parse_failure
514+
exception Deprecated
515+
exception Unimplemented
501516

502517
let strings data = String.split_on_char '\000' data
503518

@@ -515,9 +530,10 @@ module Request = struct
515530
let acl x =
516531
match ACL.of_string x with Some x -> x | None -> raise Parse_failure
517532

533+
let is_digit c = c >= '0' && c <= '9'
534+
518535
let domid s =
519536
let v = ref 0 in
520-
let is_digit c = c >= '0' && c <= '9' in
521537
let len = String.length s in
522538
let i = ref 0 in
523539
while !i < len && not (is_digit s.[!i]) do
@@ -537,6 +553,11 @@ module Request = struct
537553
match get_ty request with
538554
| Op.Read -> PathOp (data |> one_string, Read)
539555
| Op.Directory -> PathOp (data |> one_string, Directory)
556+
| Op.Directory_part ->
557+
let path, off = two_strings data in
558+
let off = int_of_string off in
559+
PathOp (path, Directory_part off)
560+
| Op.Reset_watches -> raise Unimplemented
540561
| Op.Getperms -> PathOp (data |> one_string, Getperms)
541562
| Op.Getdomainpath -> Getdomainpath (data |> one_string |> domid)
542563
| Op.Transaction_start -> Transaction_start
@@ -571,10 +592,10 @@ module Request = struct
571592
let mine, yours = two_strings data in
572593
let mine = domid mine and yours = domid yours in
573594
Set_target (mine, yours)
574-
| Op.Restrict -> Restrict (data |> one_string |> domid)
575595
| Op.Isintroduced -> Isintroduced (data |> one_string |> domid)
576596
| Op.Error -> Error (data |> one_string)
577597
| Op.Watchevent -> Watchevent (data |> one_string)
598+
| Op.Invalid -> raise Deprecated
578599

579600
let parse request = try Some (parse_exn request) with _ -> None
580601

@@ -587,6 +608,7 @@ module Request = struct
587608

588609
let ty_of_payload = function
589610
| PathOp (_, Directory) -> Op.Directory
611+
| PathOp (_, Directory_part _) -> Op.Directory_part
590612
| PathOp (_, Read) -> Op.Read
591613
| PathOp (_, Getperms) -> Op.Getperms
592614
| Debug _ -> Op.Debug
@@ -603,7 +625,6 @@ module Request = struct
603625
| PathOp (_, Rm) -> Op.Rm
604626
| PathOp (_, Setperms _) -> Op.Setperms
605627
| Set_target (_, _) -> Op.Set_target
606-
| Restrict _ -> Op.Restrict
607628
| Isintroduced _ -> Op.Isintroduced
608629
| Error _ -> Op.Error
609630
| Watchevent _ -> Op.Watchevent
@@ -616,6 +637,8 @@ module Request = struct
616637
| PathOp (path, Write value) ->
617638
path ^ "\000" ^ value (* no NUL at the end *)
618639
| PathOp (path, Setperms perms) -> data_concat [ path; ACL.to_string perms ]
640+
| PathOp (path, Directory_part value) ->
641+
data_concat [ path; string_of_int value ]
619642
| PathOp (path, _) -> data_concat [ path ]
620643
| Debug commands -> data_concat commands
621644
| Watch (path, token) | Unwatch (path, token) -> data_concat [ path; token ]
@@ -628,11 +651,7 @@ module Request = struct
628651
; Printf.sprintf "%nu" mfn
629652
; string_of_int port
630653
]
631-
| Release domid
632-
| Resume domid
633-
| Getdomainpath domid
634-
| Restrict domid
635-
| Isintroduced domid ->
654+
| Release domid | Resume domid | Getdomainpath domid | Isintroduced domid ->
636655
data_concat [ Printf.sprintf "%u" domid ]
637656
| Set_target (mine, yours) ->
638657
data_concat [ Printf.sprintf "%u" mine; Printf.sprintf "%u" yours ]
@@ -658,6 +677,7 @@ module Unmarshal = struct
658677
let int32 = int32_of_string_opt ++ get_data
659678
let unit = unit_of_string_opt ++ get_data
660679
let ok = ok ++ get_data
680+
let raw = some ++ get_raw_data (* with trailing NUL *)
661681
end
662682

663683
exception Enoent of string

core/xs_protocol.mli

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ module Op : sig
3939
| Isintroduced
4040
| Resume
4141
| Set_target
42-
| Restrict (** The type of xenstore operation. *)
42+
| Invalid
43+
| Reset_watches
44+
| Directory_part (** The type of xenstore operation. *)
4345

4446
val to_string : t -> string
4547
val of_int32 : int32 -> t option
@@ -159,10 +161,10 @@ module Response : sig
159161
| Resume
160162
| Release
161163
| Set_target
162-
| Restrict
163164
| Isintroduced of bool
164165
| Error of string
165166
| Watchevent of string * string
167+
| Directory_part of int64 * string
166168

167169
val ty_of_payload : payload -> Op.t
168170
val prettyprint_payload : payload -> string
@@ -173,6 +175,7 @@ module Request : sig
173175
type path_op =
174176
| Read
175177
| Directory
178+
| Directory_part of int
176179
| Getperms
177180
| Write of string
178181
| Mkdir
@@ -191,7 +194,6 @@ module Request : sig
191194
| Resume of int
192195
| Release of int
193196
| Set_target of int * int
194-
| Restrict of int
195197
| Isintroduced of int
196198
| Error of string
197199
| Watchevent of string
@@ -211,6 +213,7 @@ module Unmarshal : sig
211213
val int32 : t -> int32 option
212214
val unit : t -> unit option
213215
val ok : t -> unit option
216+
val raw : t -> string option
214217
end
215218

216219
exception Enoent of string (* Raised when a named key does not exist. *)

server/call.ml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ let op_exn _store c t (payload : Request.payload) : Response.payload =
5252
| Introduce (_, _, _)
5353
| Resume _ | Release _
5454
| Set_target (_, _)
55-
| Restrict _ | Isintroduced _ | Error _ | Watchevent _ ->
55+
| Isintroduced _ | Error _ | Watchevent _ ->
5656
assert false
5757
| Getdomainpath domid ->
5858
let v = Store.Path.getdomainpath domid |> Store.Path.to_string in
@@ -80,6 +80,7 @@ let op_exn _store c t (payload : Request.payload) : Response.payload =
8080
| Directory ->
8181
let entries = Impl.list t c.Connection.perm path in
8282
Response.Directory entries
83+
| Directory_part _ -> raise Parse_failure
8384
| Getperms ->
8485
let v = Impl.getperms t c.Connection.perm path in
8586
Response.Getperms v
@@ -203,10 +204,6 @@ let reply_exn store c (request : t) : Response.payload =
203204
c.Connection.perm <- Perms.set_target c.Connection.perm yours)
204205
Connection.by_address;
205206
Response.Set_target
206-
| Request.Restrict domid ->
207-
Perms.has c.Connection.perm Perms.RESTRICT;
208-
c.Connection.perm <- Perms.restrict c.Connection.perm domid;
209-
Response.Restrict
210207
| Request.Isintroduced _ ->
211208
Perms.has c.Connection.perm Perms.ISINTRODUCED;
212209
Response.Isintroduced false

server/store.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,7 @@ let char_is_valid c =
8585
|| (c >= '0' && c <= '9')
8686
|| c = '_' || c = '-' || c = '@'
8787

88-
let name_is_valid name =
89-
name <> ""
90-
&& String.fold_left (fun accu c -> accu && char_is_valid c) true name
91-
88+
let name_is_valid name = name <> "" && String.for_all char_is_valid name
9289
let is_valid = List.for_all name_is_valid
9390

9491
type path = string list

0 commit comments

Comments
 (0)