let get_acl perms = perms.acl
let get_owner perm = perm.owner
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+ let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+ let owner = if perm.owner = domid then 0 else perm.owner in
+ { perm with acl; owner }
+
let default0 = create 0 NONE []
let perm_of_string s =
let fire_spec_watches = Domains.exist domains domid in
Domains.del domains domid;
Connections.del_domain cons domid;
+ Store.reset_permissions (Transaction.get_store t) domid;
if fire_spec_watches
then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
else raise Invalid_Cmd_Args
let rec recurse fct node = fct node; List.iter (recurse fct) node.children
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+ let rec walk node =
+ f { node with children = List.rev_map walk node.children |> List.rev }
+ in
+ walk
+
let unpack node = (Symbol.to_string node.name, node.perms, node.value)
end
Quota.del_entry store.quota old_owner;
Quota.add_entry store.quota new_owner
+let reset_permissions store domid =
+ Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+ store.root <- Node.recurse_map (fun node ->
+ let perms = Perms.Node.remove_domid ~domid node.perms in
+ if perms <> node.perms then
+ Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+ { node with perms }
+ ) store.root
+
type ops = {
store: t;
write: Path.t -> string -> unit;
finally (fun () ->
if Some port = eventchn.Event.virq_port then (
let (notify, deaddom) = Domains.cleanup domains in
+ List.iter (Store.reset_permissions store) deaddom;
List.iter (Connections.del_domain cons) deaddom;
if deaddom <> [] || notify then
Connections.fire_spec_watches