@@ -107,23 +107,43 @@ let fork_exec_rpc root_dir script_name args response_of_rpc =
107
107
end
108
108
109
109
module Attached_SRs = struct
110
- let sr_table = String.Table. create ()
110
+ let sr_table : string String.Table.t ref = ref (String.Table. create () )
111
+ let state_path = ref None
111
112
112
113
let add smapiv2 plugin =
113
- Hashtbl. replace sr_table smapiv2 plugin;
114
+ Hashtbl. replace ! sr_table smapiv2 plugin;
115
+ ( match ! state_path with
116
+ | None ->
117
+ return ()
118
+ | Some path ->
119
+ let contents = String.Table. sexp_of_t (fun x -> Sexplib.Sexp. Atom x) ! sr_table |> Sexplib.Sexp. to_string in
120
+ Writer. save path ~contents
121
+ ) >> = fun () ->
114
122
return (Ok () )
115
123
116
124
let find smapiv2 =
117
- match Hashtbl. find sr_table smapiv2 with
125
+ match Hashtbl. find ! sr_table smapiv2 with
118
126
| None ->
119
127
let open Storage_interface in
120
128
let exnty = Exception. Sr_not_attached smapiv2 in
121
129
return (Error (Exception. rpc_of_exnty exnty))
122
130
| Some sr -> return (Ok sr)
123
131
124
132
let remove smapiv2 =
125
- Hashtbl. remove sr_table smapiv2;
133
+ Hashtbl. remove ! sr_table smapiv2;
126
134
return (Ok () )
135
+
136
+ let reload path =
137
+ state_path := Some path;
138
+ Sys. is_file ~follow_symlinks: true path
139
+ >> = function
140
+ | `No | `Unknown ->
141
+ return ()
142
+ | `Yes ->
143
+ Reader. file_contents path
144
+ >> = fun contents ->
145
+ sr_table := contents |> Sexplib.Sexp. of_string |> String.Table. t_of_sexp (function Sexplib.Sexp. Atom x -> x | _ -> assert false );
146
+ return ()
127
147
end
128
148
129
149
let vdi_of_volume x =
@@ -581,7 +601,9 @@ let sync ~root_dir ~switch_path =
581
601
>> = fun () ->
582
602
Deferred. all_ignore (List. map ~f: (destroy switch_path) (diff got_already needed))
583
603
584
- let main ~root_dir ~switch_path =
604
+ let main ~root_dir ~state_path ~switch_path =
605
+ Attached_SRs. reload state_path
606
+ >> = fun () ->
585
607
(* We watch and create queues for the Volume plugins only *)
586
608
let root_dir = Filename. concat root_dir " volume" in
587
609
Async_inotify. create ~recursive: false ~watch_new_dirs: false root_dir
@@ -614,8 +636,8 @@ let main ~root_dir ~switch_path =
614
636
loop () in
615
637
loop ()
616
638
617
- let main ~root_dir ~switch_path =
618
- let (_: unit Deferred.t ) = main ~root_dir ~switch_path in
639
+ let main ~root_dir ~state_path ~ switch_path =
640
+ let (_: unit Deferred.t ) = main ~root_dir ~state_path ~ switch_path in
619
641
never_returns (Scheduler. go () )
620
642
621
643
open Xcp_service
@@ -629,13 +651,19 @@ let description = String.concat ~sep:" " [
629
651
630
652
let _ =
631
653
let root_dir = ref " /var/lib/xapi/storage-scripts" in
654
+ let state_path = ref " /var/run/nonpersistent/xapi-storage-script/state.db" in
632
655
633
656
let resources = [
634
657
{ Xcp_service. name = " root" ;
635
658
description = " directory whose sub-directories contain sets of per-operation scripts, one sub-directory per queue name" ;
636
659
essential = true ;
637
660
path = root_dir;
638
661
perms = [ U. X_OK ];
662
+ }; { Xcp_service. name = " state" ;
663
+ description = " file containing attached SR information, should be deleted on host boot" ;
664
+ essential = false ;
665
+ path = state_path;
666
+ perms = [ ] ;
639
667
}
640
668
] in
641
669
@@ -655,5 +683,5 @@ let _ =
655
683
use_syslog := true ;
656
684
Core.Syslog. openlog ~id: " xapi-storage-script" ~facility: Core.Syslog.Facility. DAEMON () ;
657
685
end ;
658
- main ~root_dir: ! root_dir ~switch_path: ! Xcp_client. switch_path
686
+ main ~root_dir: ! root_dir ~state_path: ! state_path ~ switch_path:! Xcp_client. switch_path
659
687
0 commit comments