let vhd_snap_path path = path ^ ".snap" in
let vhd_tmp_path path = path ^ ".snap.tmp" in
List.iter (fun disk ->
- match disk.disk_physty with
- | Device.Vbd.Vhd ->
- let snappath = vhd_snap_path disk.disk_physpath in
- let tmppath = vhd_tmp_path disk.disk_physpath in
- if Sys.file_exists snappath then
- debug "removing snapshot file %s" snappath;
- Unixext.unlink_safe snappath;
- if Sys.file_exists tmppath then
- debug "removing snapshot file %s" tmppath;
- Unixext.unlink_safe tmppath
- | _ -> ()
+ (* snapshots managed with scripts are not removed here *)
+ if disk.disk_snapshot_mode <> Snapshot_scripted then (
+ match disk.disk_physty with
+ | Device.Vbd.Vhd ->
+ let snappath = vhd_snap_path disk.disk_physpath in
+ let tmppath = vhd_tmp_path disk.disk_physpath in
+ if Sys.file_exists snappath then
+ debug "removing snapshot file %s" snappath;
+ Unixext.unlink_safe snappath;
+ if Sys.file_exists tmppath then
+ debug "removing snapshot file %s" tmppath;
+ Unixext.unlink_safe tmppath
+ | _ -> ()
+ )
) disks
-let make_snapshots disks =
+exception Snapshot_failure of string * string
+
+let make_snapshots uuid disks =
let vhd_snap_path path = path ^ ".snap" in
let vhd_tmp_path path = path ^ ".snap.tmp" in
List.map (fun disk ->
match disk.disk_snapshot_mode with
| NoSnapshot -> disk
+ | Snapshot_scripted ->
+ (* snapshots managed by external script *)
+ let physpath = disk.disk_physpath in
+ let tmppath = vhd_tmp_path physpath in
+ let opts = [
+ "-i"; physpath;
+ "-s"; tmppath;
+ "-u"; uuid
+ ] in
+ (try
+ let _ = Forkhelpers.execute_command_get_output
+ ~withpath:true
+ "/usr/sbin/prepare-system-snapshot"
+ opts
+ in
+ { disk with disk_physpath = tmppath }
+ with
+ Forkhelpers.Spawn_internal_error (log, output, status) ->
+ let s = sprintf "output=%S status=%s" output (string_of_unix_process status) in
+ raise (Snapshot_failure (uuid, s)))
| Snapshot_temporary ->
(match disk.disk_physty with
| Device.Vbd.Vhd ->
let nics = get_nics cfg in
(* create disk snapshots *)
- let snap_disks = make_snapshots cfg.disks in
+ let snap_disks = make_snapshots state.vm_uuid cfg.disks in
(* add disks and nics *)
finally (fun () ->
debug "add_devices: adding disks";