| VNC of bool * int * string (* auto-allocate, port if previous false, keymap *)
| SDL of string (* X11 display *)
+type info = {
+ memory: int64;
+ boot: string;
+ serial: string;
+ vcpus: int;
+ usb: string list;
+ nics: (string * string * string option) list;
+ acpi: bool;
+ disp: disp_opt;
+ pci_emulations: string list;
+ power_mgmt: int;
+ oem_features: int;
+ extras: (string * string option) list;
+}
+
(* Path to redirect qemu's stdout and stderr *)
let logfile domid = Printf.sprintf "/tmp/qemu.%d" domid
()
(* Returns the allocated vnc port number *)
-let __start ~xs ~dmpath ~memory ~boot ~serial ~vcpus ?(usb=[]) ?(nics=[])
- ~acpi ~disp ?(pci_emulations=[]) ?(power_mgmt=0) ?(oem_features=0)
- ~extras ~restore ?(timeout=qemu_dm_ready_timeout) domid =
+let __start ~xs ~dmpath ~restore ?(timeout=qemu_dm_ready_timeout) info domid =
let usb' =
- if usb = [] then
+ if info.usb = [] then
[]
else
("-usb" :: (List.concat (List.map (fun device ->
- [ "-usbdevice"; device ]) usb))) in
+ [ "-usbdevice"; device ]) info.usb))) in
(* qemu need a different id for every vlan, or things get very bad *)
let vlan_id = ref 0 in
let if_number = ref 0 in
incr if_number;
incr vlan_id;
r
- ) nics in
+ ) info.nics in
let qemu_pid_path = xs.Xs.getdomainpath domid ^ "/qemu-pid" in
- if power_mgmt <> 0 then begin
+ if info.power_mgmt <> 0 then begin
try if (Unix.stat "/proc/acpi/battery").Unix.st_kind == Unix.S_DIR then
- xs.Xs.write (power_mgmt_path domid) (string_of_int power_mgmt);
+ xs.Xs.write (power_mgmt_path domid) (string_of_int info.power_mgmt);
with _ -> () ;
end;
- if oem_features <> 0 then
- xs.Xs.write (oem_features_path domid) (string_of_int oem_features);
+ if info.oem_features <> 0 then
+ xs.Xs.write (oem_features_path domid) (string_of_int info.oem_features);
let log = logfile domid in
let restorefile = sprintf "/tmp/xen.qemu-dm.%d" domid in
let disp_options, wait_for_port =
- match disp with
+ match info.disp with
| NONE -> [], false
| SDL (x11name) -> [], false
| VNC (auto, port, keymap) ->
log; (* absorbed by qemu-dm-wrapper *)
(* everything else goes straight through to qemu-dm: *)
"-d"; string_of_int domid;
- "-m"; Int64.to_string (Int64.div memory 1024L);
- "-boot"; boot;
- "-serial"; serial;
- "-vcpus"; string_of_int vcpus; ]
+ "-m"; Int64.to_string (Int64.div info.memory 1024L);
+ "-boot"; info.boot;
+ "-serial"; info.serial;
+ "-vcpus"; string_of_int info.vcpus; ]
@ disp_options @ usb' @ (List.concat nics')
- @ (if acpi then [ "-acpi" ] else [])
+ @ (if info.acpi then [ "-acpi" ] else [])
@ (if restore then [ "-loadvm"; restorefile ] else [])
- @ (List.fold_left (fun l pci -> "-pciemulation" :: pci :: l) [] (List.rev pci_emulations))
- @ (List.fold_left (fun l (k, v) -> ("-" ^ k) :: (match v with None -> l | Some v -> v :: l)) [] extras)
+ @ (List.fold_left (fun l pci -> "-pciemulation" :: pci :: l) [] (List.rev info.pci_emulations))
+ @ (List.fold_left (fun l (k, v) -> ("-" ^ k) :: (match v with None -> l | Some v -> v :: l)) [] info.extras)
in
(* Now add the close fds wrapper *)
let cmdline = Forkhelpers.close_and_exec_cmdline [] dmpath l in
) else
(-1)
-
-let start ~xs ~dmpath ~memory ~boot ~serial ~vcpus ?(usb=[]) ?(nics=[])
- ?(acpi=false) ~disp ?(pci_emulations=[]) ?(extras=[]) ?power_mgmt ?oem_features ?timeout domid =
- __start ~xs ~dmpath ~memory ~boot ~serial ~vcpus ~usb
- ~nics ~acpi ~disp ~pci_emulations ~restore:false ~extras ?power_mgmt ?oem_features ?timeout domid
-
-let restore ~xs ~dmpath ~memory ~boot ~serial ~vcpus ?(usb=[]) ?(nics=[])
- ?(acpi=false) ~disp ?(pci_emulations=[]) ?(extras=[]) ?power_mgmt ?oem_features ?timeout domid =
- __start ~xs ~dmpath ~memory ~boot ~serial ~vcpus ~usb
- ~nics ~acpi ~disp ~pci_emulations ~restore:true ~extras ?power_mgmt ?oem_features ?timeout domid
+let start ~xs ~dmpath ?timeout info domid = __start ~xs ~restore:false ~dmpath ?timeout info domid
+let restore ~xs ~dmpath ?timeout info domid = __start ~xs ~restore:true ~dmpath ?timeout info domid
(* Called by every domain destroy, even non-HVM *)
let stop ~xs domid signal =
| VNC of bool * int * string (* auto-allocate, port if previous false, keymap *)
| SDL of string (* X11 display *)
+ type info = {
+ memory: int64;
+ boot: string;
+ serial: string;
+ vcpus: int;
+ usb: string list;
+ nics: (string * string * string option) list;
+ acpi: bool;
+ disp: disp_opt;
+ pci_emulations: string list;
+ power_mgmt: int;
+ oem_features: int;
+ extras: (string * string option) list;
+ }
+
val write_logfile_to_log : int -> unit
val unlink_logfile : int -> unit
val signal : xs:Xs.xsh -> domid:Xc.domid
-> string -> string option -> string -> unit
- val start : xs:Xs.xsh -> dmpath:string -> memory:int64
- -> boot:string -> serial:string -> vcpus:int
- -> ?usb:string list -> ?nics:(string * string * string option) list
- -> ?acpi:bool -> disp:disp_opt -> ?pci_emulations:string list
- -> ?extras:(string * string option) list
- -> ?power_mgmt:int -> ?oem_features:int -> ?timeout:float -> Xc.domid
- -> int
- val restore : xs:Xs.xsh -> dmpath:string -> memory:int64
- -> boot:string -> serial:string -> vcpus:int
- -> ?usb:string list -> ?nics:(string * string * string option) list
- -> ?acpi:bool -> disp:disp_opt -> ?pci_emulations:string list
- -> ?extras:(string * string option) list
- -> ?power_mgmt:int -> ?oem_features:int -> ?timeout:float -> Xc.domid
- -> int
+ val start : xs:Xs.xsh -> dmpath:string -> ?timeout:float -> info -> Xc.domid -> int
+ val restore : xs:Xs.xsh -> dmpath:string -> ?timeout:float -> info -> Xc.domid -> int
val stop : xs:Xs.xsh -> Xc.domid -> int -> unit
end
~protocol:(devproto_of_state state) state.vm_domid in
()
+let dm_info_of_cfg cfg =
+ let nics = List.map (fun nic -> nic.nic_mac, nic.nic_bridge, nic.nic_model) cfg.nics in
+ let disp =
+ match cfg.vnc with
+ | (-1) -> Device.Dm.NONE
+ | 0 -> Device.Dm.VNC (true, 0, cfg.vnc_keymap)
+ | _ -> Device.Dm.VNC (false, cfg.vnc, cfg.vnc_keymap)
+ in
+ {
+ Device.Dm.memory = cfg.memory;
+ Device.Dm.boot = cfg.boot;
+ Device.Dm.serial = cfg.serial;
+ Device.Dm.vcpus = cfg.vcpus;
+ Device.Dm.nics = nics;
+ Device.Dm.pci_emulations = [];
+ Device.Dm.usb = [];
+ Device.Dm.acpi = cfg.acpi;
+ Device.Dm.disp = disp;
+ Device.Dm.power_mgmt = cfg.power_management;
+ Device.Dm.oem_features = cfg.oem_features;
+ Device.Dm.extras = cfg.extrahvm;
+ }
+
let add_devices xc xs domid state restore =
let cfg = state.vm_cfg in
if cfg.hvm then (
let dmpath = "/opt/xensource/libexec/qemu-dm-wrapper" in
let dmstart = if restore then Device.Dm.restore else Device.Dm.start in
- let nics = List.map (fun nic -> nic.nic_mac, nic.nic_bridge, nic.nic_model) cfg.nics in
- let disp =
- match cfg.vnc with
- | (-1) -> Device.Dm.NONE
- | 0 -> Device.Dm.VNC (true, 0, cfg.vnc_keymap)
- | _ -> Device.Dm.VNC (false, cfg.vnc, cfg.vnc_keymap)
- in
-
- let vnc_port = try dmstart ~xs ~dmpath ~memory:cfg.memory
- ~boot:cfg.boot ~serial:cfg.serial
- ~vcpus:cfg.vcpus ~nics ~acpi:cfg.acpi
- ~disp domid ~timeout:(15.)
- ~power_mgmt:cfg.power_management ~oem_features:cfg.oem_features ~extras:cfg.extrahvm
+ let info = dm_info_of_cfg cfg in
+ let vnc_port = try dmstart ~xs ~dmpath ~timeout:(15.) info domid
with Device.Ioemu_failed s as exn ->
if String.startswith "Timeout waiting for " s then (
warn "you are using xen-unstable without the dm-ready patch apply the patch for not waiting 15s at boot";
let add_dm ~xs ~domid ~mem_max_kib ~vcpus ~boot =
let dmpath = "/opt/xensource/libexec/qemu-dm-wrapper" in
- Device.Dm.start ~xs ~dmpath ~memory:mem_max_kib ~boot ~serial:"pty"
- ~vcpus ~disp:Device.Dm.NONE domid
+ let info = {
+ Device.Dm.memory = mem_max_kib;
+ Device.Dm.boot = boot;
+ Device.Dm.serial = "pty";
+ Device.Dm.vcpus = vcpus;
+ Device.Dm.nics = [];
+ Device.Dm.pci_emulations = [];
+ Device.Dm.usb = [];
+ Device.Dm.acpi = true;
+ Device.Dm.disp = Device.Dm.NONE;
+ Device.Dm.power_mgmt = 0;
+ Device.Dm.oem_features = 0;
+ Device.Dm.extras = []
+ } in
+ Device.Dm.start ~xs ~dmpath info domid
let add_ioport ~xc ~domid ~ioport_start ~ioport_end =
Domain.add_ioport ~xc domid ioport_start ioport_end