type command =
| Exit_thread
| Connect of string option * domain list callback
+ | Disk_usage of source * string * int64 callback
| Download_dir_find0 of source * string * string * unit callback
| Download_dir_tarball of source * string * download_dir_tarball_format * string * unit callback
| Download_file of source * string * string * unit callback
| Exit_thread -> "Exit_thread"
| Connect (Some name, _) -> sprintf "Connect %s" name
| Connect (None, _) -> "Connect NULL"
+ | Disk_usage (src, remotedir, _) ->
+ sprintf "Disk_usage (%s, %s)" (string_of_source src) remotedir
| Download_dir_find0 (src, remotedir, localfile, _) ->
sprintf "Download_dir_find0 (%s, %s, %s)"
(string_of_source src) remotedir localfile
let failure_hook = ref (fun _ -> ())
let busy_hook = ref (fun _ -> ())
let idle_hook = ref (fun _ -> ())
+let status_hook = ref (fun _ -> ())
let progress_hook = ref (fun _ -> ())
let set_failure_hook cb = failure_hook := cb
let set_busy_hook cb = busy_hook := cb
let set_idle_hook cb = idle_hook := cb
+let set_status_hook cb = status_hook := cb
let set_progress_hook cb = progress_hook := cb
(* Execute a function, while holding a mutex. If the function
)
let connect ?fail uri cb = send_to_slave ?fail (Connect (uri, cb))
+let disk_usage ?fail src remotedir cb =
+ send_to_slave ?fail (Disk_usage (src, remotedir, cb))
let download_dir_find0 ?fail src remotedir localfile cb =
send_to_slave ?fail (Download_dir_find0 (src, remotedir, localfile, cb))
let download_dir_tarball ?fail src remotedir format localfile cb =
f ()
) ()
+(* Update the status bar. *)
+let status fs =
+ let f str = GtkThread.async !status_hook str in
+ ksprintf f fs
+
let rec loop () =
debug "top of slave loop";
close_all ()
| Connect (name, cb) ->
+ let printable_name =
+ match name with None -> "default hypervisor" | Some uri -> uri in
+ status "Connecting to %s ..." printable_name;
+
close_all ();
conn := Some (C.connect_readonly ?name ());
) doms in
let cmp { dom_name = n1 } { dom_name = n2 } = compare n1 n2 in
let doms = List.sort ~cmp doms in
+
+ status "Connected to %s" printable_name;
callback_if_not_discarded cb doms
+ | Disk_usage (src, remotedir, cb) ->
+ status "Calculating disk usage of %s ..." remotedir;
+
+ let g = get_g () in
+ let r =
+ with_mount_ro g src (
+ fun () ->
+ g#du remotedir
+ ) in
+
+ status "Finished calculating disk usage of %s" remotedir;
+ callback_if_not_discarded cb r
+
| Download_dir_find0 (src, remotedir, localfile, cb) ->
+ status "Downloading %s filenames to %s ..." remotedir localfile;
+
let g = get_g () in
with_mount_ro g src (
fun () ->
g#find0 remotedir localfile
);
+
+ status "Finished downloading %s" localfile;
callback_if_not_discarded cb ()
| Download_dir_tarball (src, remotedir, format, localfile, cb) ->
+ status "Downloading %s to %s ..." remotedir localfile;
+
let g = get_g () in
let f = match format with
| Tar -> g#tar_out
fun () ->
f remotedir localfile
);
+
+ status "Finished downloading %s" localfile;
callback_if_not_discarded cb ()
| Download_file (src, remotefile, localfile, cb) ->
+ status "Downloading %s to %s ..." remotefile localfile;
+
let g = get_g () in
with_mount_ro g src (
fun () ->
g#download remotefile localfile
);
+
+ status "Finished downloading %s" localfile;
callback_if_not_discarded cb ()
| Open_domain (name, cb) ->
+ status "Opening %s ..." name;
+
let conn = get_conn () in
let dom = D.lookup_by_name conn name in
let xml = D.get_xml_desc dom in
open_disk_images images cb
| Open_images (images, cb) ->
+ status "Opening disk images ...";
+
open_disk_images images cb
| Read_directory (src, dir, cb) ->
+ status "Reading directory %s ..." dir;
+
let g = get_g () in
let names, stats, links =
with_mount_ro g src (
fun ((name, stat), link) ->
{ dent_name = name; dent_stat = stat; dent_link = link }
) entries in
+
+ status "Finished reading directory %s" dir;
callback_if_not_discarded cb entries
(* Expect to be connected, and return the current libvirt connection. *)
g#launch ();
+ status "Listing filesystems ...";
+
(* Get list of filesystems. *)
let fses = g#list_filesystems () in
+ status "Looking for operating systems ...";
+
(* Perform inspection. This can fail, ignore errors. *)
let roots =
try Array.to_list (g#inspect_os ())
insp_all_filesystems = fses;
insp_oses = oses;
} in
+
+ status "Finished opening disk";
callback_if_not_discarded cb data
(* guestfs_lstatlist has a "hidden" limit of the protocol message size.