warn "notify failed: %s" (Printexc.to_string exn)
-let params_of_nic nic =
- let bridge =
- if nic.nic_bridge = "" then (
- let l = Netdev.Bridge.list () in
- if List.length l > 0 then
- List.hd l
- else
- ""
- ) else (
- if Netdev.Bridge.exists nic.nic_bridge then
- nic.nic_bridge
- else
- ""
- ) in
- (Netman.Bridge bridge)
-
let devproto_of_state state =
match state.vm_arch with
| Domain.Arch_HVM | Domain.Arch_native -> Device_common.Protocol_Native
()
let add_nic_to_vm ~xs state nic =
- let netty = params_of_nic nic in
+ nic.nic_bridge_gen <- (
+ match nic.nic_bridge with
+ | None ->
+ let l = Netdev.Bridge.list () in
+ if List.length l > 0 then
+ List.hd l
+ else
+ ""
+ | Some bridge ->
+ if Netdev.Bridge.exists bridge then
+ bridge
+ else
+ ""
+ );
+ if nic.nic_mac_gen = "" then (
+ let generate_random_mac () =
+ String.concat ":" (List.map (sprintf "%02x")
+ ([0x00; 0x16; 0x3e] @
+ List.map Random.int [0x80; 0x100; 0x100]))
+ in
+ let generate_vm_mac nic_id nic_model vm_uuid =
+ let s_of_c c1 c2 =
+ let s = String.create 2 in
+ s.[0] <- c1; s.[1] <- c2; s
+ in
+ let unicast_local h =
+ let v = int_of_string ("0x" ^ (List.hd h)) in
+ let n = sprintf "%02x" (0x2 lor (v land 0xfe)) in
+ n :: (List.tl h)
+ in
+ let vector =
+ (if nic_id = -1 then [] else [ string_of_int nic_id ]) @
+ (match nic_model with None -> [] | Some x -> [ x ]) @
+ [ vm_uuid ]
+ in
+ let digest = Digest.to_hex (Digest.string (String.concat " " vector)) in
+ let hexs = List.map (fun i -> s_of_c digest.[i] digest.[i + 12]) [ 0; 2; 1; 7; 6; 4 ] in
+ String.concat ":" (unicast_local hexs)
+ in
+ let is_valid_mac s =
+ let x = String.split ':' s in
+ if List.length x != 6 then
+ false
+ else (
+ try ignore (List.map (fun s -> int_of_string ("0x" ^ s)) x); true
+ with _ -> false
+ )
+ in
+ nic.nic_mac_gen <- (
+ match nic.nic_mac with
+ | Some "random" -> generate_random_mac ();
+ | None | Some "vm" -> generate_vm_mac nic.nic_aid nic.nic_model state.vm_uuid
+ | Some mac ->
+ if is_valid_mac mac then mac else generate_vm_mac nic.nic_aid nic.nic_model state.vm_uuid
+ )
+ );
+ let netty = Netman.Bridge nic.nic_bridge_gen in
let (_: Device_common.device) =
- Device.Vif.add ~xs ~devid:nic.nic_aid ~netty ~mac:nic.nic_mac
+ Device.Vif.add ~xs ~devid:nic.nic_aid ~netty ~mac:nic.nic_mac_gen
~protocol:(devproto_of_state state) state.vm_domid in
()
+let get_nics cfg =
+ (* then sort the nics by ascending order *)
+ List.sort (fun nic1 nic2 -> if nic1.nic_aid > nic2.nic_aid then 1 else -1) cfg.nics
+
+let get_pcis cfg =
+ let ids = ref [] in
+ List.iter (fun (id, dev) ->
+ if not (List.mem id !ids) then
+ ids := id :: !ids
+ ) cfg.pcis;
+ List.map (fun id ->
+ let ds = List.map (fun (_, dev) -> dev)
+ (List.filter (fun (x, dev) -> x = id) cfg.pcis) in
+ id, ds
+ ) !ids
+
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 nics = get_nics cfg in
+ let nics = List.map (fun nic -> nic.nic_mac_gen, nic.nic_bridge_gen, nic.nic_model) nics in
let disp =
match cfg.vnc with
| (-1) -> Device.Dm.NONE
Device.Dm.extras = cfg.extrahvm;
}
+(* set all nics aid *)
+let setup_nics state =
+ List.iter (fun nic ->
+ if nic.nic_id = (-1) then (
+ let first_free_id =
+ let rec s i =
+ if i > 32 then
+ failwith "cannot find a free nic id";
+ let found =
+ try let (_: config_nic) = List.find (fun x -> x.nic_aid = i) state.vm_cfg.nics in true
+ with Not_found -> false
+ in
+ if not found then i else s (i + 1)
+ in
+ s 0
+ in
+ nic.nic_aid <- first_free_id
+ )
+ ) state.vm_cfg.nics;
+ ()
+
let add_devices xc xs domid state restore =
let cfg = state.vm_cfg in
+ let pcis = get_pcis cfg in
+ let nics = get_nics cfg in
(* add disks and nics *)
List.iter (fun x -> add_disk_to_vm ~xs state x) cfg.disks;
- List.iter (fun nic -> add_nic_to_vm ~xs state nic) cfg.nics;
+ List.iter (fun nic -> add_nic_to_vm ~xs state nic) nics;
(* add vcpus *)
for i = 0 to cfg.vcpus - 1 do Device.Vcpu.add ~xs ~devid:i domid done;
| Some i -> i
in
Device.PCI.add ~xc ~xs ~hvm:cfg.hvm ~msitranslate ~pci_power_mgmt devs domid devid
- ) cfg.pcis;
+ ) pcis;
(* add device model *)
if cfg.hvm then (
(* specific handler *)
let unimplemented args = Xenvmlib.Error "unimplemented command" in
let pci_list args =
+ let pcis = get_pcis cfg in
let l = List.map (fun (id, devs) ->
let devstrs = List.map (fun dev ->
sprintf " domain:%d, bus:%d, slot: %d, func: %d\n"
dev.pci_domain dev.pci_bus dev.pci_slot dev.pci_func
) devs in
(sprintf "id:%d\n" id) ^ (String.concat "" devstrs)
- ) cfg.pcis in
+ ) pcis in
Xenvmlib.Msg (String.concat "" l)
in
let disk_list args =
let nic_list args =
let l = List.map (fun nic ->
sprintf "id: %d, bridge:%s, mac:%s\n"
- nic.nic_aid nic.nic_bridge nic.nic_mac
+ nic.nic_aid nic.nic_bridge_gen nic.nic_mac_gen
) cfg.nics in
Xenvmlib.Msg (String.concat "" l)
in
Xenvmlib.Ok
in
let nic_add args =
- let nic = Config.config_nic_of_string state.vm_uuid (List.hd args) in
+ let nic = Config.config_nic_of_string (List.hd args) in
add_nic_to_vm ~xs state nic;
Xenvmlib.Ok
in
| NotifyUnix of string
| NotifyNone
+let string_of_notify ty =
+ match ty with
+ | NotifyTcp6 s -> sprintf "tcp6,%s" s
+ | NotifyTcp (iaddr, port) -> sprintf "tcp,%s:%d" "" port
+ | NotifyUnix path -> sprintf "unix,%s" path
+ | NotifyNone -> ""
+
type snapshot_mode =
| NoSnapshot
| Snapshot_temporary
type config_nic = {
nic_id: int;
mutable nic_aid: int; (* actual id for unallocated devices *)
- nic_bridge: string;
- nic_mac: string;
+ nic_bridge: string option;
+ mutable nic_bridge_gen: string;
+ nic_mac: string option;
+ mutable nic_mac_gen: string;
nic_model: string option;
nic_dynadded: bool;
}
(* devices *)
disks: config_disk list;
nics: config_nic list;
- pcis: (int * config_pci list) list;
+ pcis: (int * config_pci) list;
(* others *)
boot: string;
vnc: int;
| _ ->
failwith "unexpected format for pci config"
in
- let pcidev =
+ let domain, bus, slot, func =
try Scanf.sscanf pcidev_str "%x:%x:%x.%x" (fun a b c d -> (a, b, c, d))
with _ -> failwith "unexpected format for pci descriptor"
in
try Some (int_of_string (snd (List.find (fun p -> fst p = "power_mgmt") params)))
with Not_found -> None
in
- id, bind, pcidev, msitranslate, power_mgmt
+ let pcidev = {
+ pci_bind = bind;
-let config_nic_of_string vm_uuid s =
- let generate_random_mac () =
- String.concat ":" (List.map (sprintf "%02x")
- ([0x00; 0x16; 0x3e] @
- List.map Random.int [0x80; 0x100; 0x100]))
- in
- let generate_vm_mac nic_id nic_model vm_uuid =
- let s_of_c c1 c2 =
- let s = String.create 2 in
- s.[0] <- c1; s.[1] <- c2; s
- in
- let unicast_local h =
- let v = int_of_string ("0x" ^ (List.hd h)) in
- let n = sprintf "%02x" (0x2 lor (v land 0xfe)) in
- n :: (List.tl h)
- in
- let vector =
- (if nic_id = -1 then [] else [ string_of_int nic_id ]) @
- (match nic_model with None -> [] | Some x -> [ x ]) @
- [ vm_uuid ]
- in
- let digest = Digest.to_hex (Digest.string (String.concat " " vector)) in
- let hexs = List.map (fun i -> s_of_c digest.[i] digest.[i + 12]) [ 0; 2; 1; 7; 6; 4 ] in
- String.concat ":" (unicast_local hexs)
- in
- let is_valid_mac s =
- let x = String.split ':' s in
- if List.length x != 6 then
- false
- else (
- try ignore (List.map (fun s -> int_of_string ("0x" ^ s)) x); true
- with _ -> false
- )
- in
+ pci_domain = domain;
+ pci_bus = bus;
+ pci_slot = slot;
+ pci_func = func;
+ pci_msitranslate = msitranslate;
+ pci_power_mgmt = power_mgmt;
+ } in
+ id, pcidev
+
+let config_nic_of_string s =
let ls = if s = "" then [] else String.split ',' s in
let id = ref (-1)
- and bridge = ref ""
+ and bridge = ref None
and model = ref None
- and mac = ref "" in
+ and mac = ref None in
List.iter (fun v ->
let lv = String.split '=' v in
match lvalue with
| "id" -> id := int_of_string value
- | "bridge" -> bridge := value
+ | "bridge" -> bridge := Some value
| "model" -> model := Some value
- | "mac" -> mac := value
- | _ -> ()) ls;
-
- begin match !mac with
- | "random" ->
- mac := generate_random_mac ();
- | _ -> (* otherwise verify and use a vm-specific one if invalid *)
- if not (is_valid_mac !mac) then
- mac := generate_vm_mac !id !model vm_uuid;
- end;
+ | "mac" -> mac := Some value
+ | _ -> ()
+ ) ls;
{
nic_id = !id;
nic_aid = !id;
nic_bridge = !bridge;
+ nic_bridge_gen = "";
nic_mac = !mac;
+ nic_mac_gen = "";
nic_model = !model;
nic_dynadded = false
}
disk_dynadded = false;
}
+let config_cpuid_of_string s =
+ (* that's the same format as xend. i.e. NODE+NODE:REG=[01xks]{32}{,REG=[01xks]{32}}* *)
+ match String.split ':' s with
+ | [ nodes; x ] ->
+ let nodetuple =
+ match String.split '+' nodes with
+ | [ x; y ] -> Int64.of_string x, Some (Int64.of_string y)
+ | [ x ] -> Int64.of_string x, None
+ | _ -> failwith "cannot parse node format"
+ in
+ let l = String.split ',' x in
+ let x = List.map (fun x ->
+ match String.split '=' x with
+ | [ reg_str; mask ] ->
+ let reg = Domain.cpuid_reg_of_string reg_str in
+ if String.startswith "0x" mask then (
+ failwith "FIXME hexadecimal mask not supported yet"
+ ) else if String.length mask <> 32 then (
+ let a = Array.create 32 Domain.Default in
+ for i = 0 to (String.length mask - 1); do
+ a.(i) <- Domain.cpuid_rtype_of_char mask.[i]
+ done;
+ reg, a
+ ) else
+ failwith "mask is not 32 characters long"
+ | _ ->
+ failwith "cannot parse register mask"
+ ) l in
+ nodetuple, x
+ | _ ->
+ failwith "cannot parse format"
+
let config_notify_of_string s =
match (String.split ~limit:2 ',' s) with
| "tcp" :: addr :: [] -> (
let get cfg field =
match field with
| "hvm" -> string_of_bool cfg.hvm
- | "debug" -> string_of_bool cfg.debug
| "kernel" -> cfg.kernel
| "cmdline" -> cfg.cmdline
| "serial" -> cfg.serial
| "diskinfo-pt" -> string_of_bool cfg.diskinfo_pt
| "boot" -> cfg.boot
| "vnc" -> string_of_int cfg.vnc
+ | "vnc-keymap" -> cfg.vnc_keymap
| "timer-mode" -> string_of_int_option cfg.timer_mode
| "time-offset" -> string_of_string_option cfg.timeoffset
| "hpet" -> string_of_int_option cfg.hpet
| "pci-msitranslate" -> string_of_int cfg.global_pci_msitranslate
| "pci-power-management" -> string_of_int cfg.global_pci_power_mgmt
| "inject-sci" -> string_of_int cfg.inject_sci
+ | "sound" -> string_of_string_option cfg.sound
+ | "notify" -> string_of_notify cfg.notify
| _ -> raise (Unknown_field field)
let set cfg field value =
match field with
| "hvm" -> { cfg with hvm = bool_of_string value }
- | "debug" -> { cfg with debug = bool_of_string value }
| "kernel" -> { cfg with kernel = value }
| "cmdline" -> { cfg with cmdline = value }
| "serial" -> { cfg with serial = value }
| "videoram" -> { cfg with videoram = int_option_of_string value }
| "smbios-pt" -> { cfg with smbios_pt = bool_of_string value }
| "acpi-pt" -> { cfg with acpi_pt = bool_of_string value }
- | "diskinfo-pt" -> { cfg with diskinfo_pt = bool_of_string value }
- | "boot" -> { cfg with boot = value }
- | "vnc" -> { cfg with vnc = int_of_string value }
- | "timer-mode" -> { cfg with timer_mode = int_option_of_string value }
- | "time-offset" -> { cfg with timeoffset = string_option_of_string value }
- | "hpet" -> { cfg with hpet = int_option_of_string value }
- | "vpt-align" -> { cfg with vpt_align = int_option_of_string value }
+ | "diskinfo-pt" -> { cfg with diskinfo_pt = bool_of_string value }
+ | "boot" -> { cfg with boot = value }
+ | "vnc" -> { cfg with vnc = int_of_string value }
+ | "vnc-keymap" -> { cfg with vnc_keymap = value }
+ | "timer-mode" -> { cfg with timer_mode = int_option_of_string value }
+ | "time-offset" -> { cfg with timeoffset = string_option_of_string value }
+ | "hpet" -> { cfg with hpet = int_option_of_string value }
+ | "vpt-align" -> { cfg with vpt_align = int_option_of_string value }
| "power-management" -> { cfg with power_management = int_of_string value }
- | "oem-features" -> { cfg with oem_features = int_of_string value }
+ | "oem-features" -> { cfg with oem_features = int_of_string value }
| "pci-msitranslate" -> { cfg with global_pci_msitranslate = int_of_string value }
| "pci-power-management" -> { cfg with global_pci_power_mgmt = int_of_string value }
- | "inject-sci" -> { cfg with inject_sci = int_of_string value }
+ | "inject-sci" -> { cfg with inject_sci = int_of_string value }
+ | "sound" -> { cfg with sound = string_option_of_string value }
+ | "notify" -> { cfg with notify = config_notify_of_string value }
| _ -> raise (Unknown_field field)
+let list_add cfg field value =
+ let config_extrahvm_of_string s =
+ match String.split ~limit:2 '=' s with
+ | k :: v :: [] -> k, Some v
+ | k :: [] -> k, None
+ | _ -> failwith "bad format for extrahvm. expecting k=v"
+ in
+ let config_platform_of_string s =
+ match String.split ~limit:2 '=' s with
+ | k :: v :: [] -> k, v
+ | k :: [] -> k, ""
+ | _ -> failwith "bad format for platform. expecting k=v"
+ in
+ match field with
+ | "disk" -> { cfg with disks = cfg.disks @ [ config_disk_of_string value ] }
+ | "nic" | "vif" -> { cfg with nics = cfg.nics @ [ config_nic_of_string value ] }
+ | "pci" -> { cfg with pcis = cfg.pcis @ [ config_pci_of_string value ] }
+ | "cpuid" -> { cfg with cpuid = cfg.cpuid @ [ config_cpuid_of_string value ] }
+ | "extra-hvm" -> { cfg with extrahvm = cfg.extrahvm @ [ config_extrahvm_of_string value ] }
+ | "platform" -> { cfg with platform = cfg.platform @ [ config_platform_of_string value ] }
+ | "extra-local-watch" -> { cfg with extra_local_watches = cfg.extra_local_watches @ [ value ] }
+ | "extra-vm-watch" -> { cfg with extra_vm_watches = cfg.extra_vm_watches @ [ value ] }
+ | _ -> raise (Unknown_field field)
+
+let list_del cfg field index =
+ match field with
+ | _ -> raise (Unknown_field field)
+
+let list_get cfg field =
+ match field with
+ | _ -> raise (Unknown_field field)
+
let empty =
{
__uuid = None;
name = None;
- debug = false;
verbose = false;
no_mem_check = false;
output = "";
startup = StartupStart;
+
+ (* get/set *)
+ debug = false;
hvm = false;
kernel = "";
cmdline = "";
diskinfo_pt = false;
viridian = false;
videoram = None;
- on_halt = ActionDestroy;
- on_restart = ActionRestart;
- on_crash = ActionDestroy;
- disks = [];
- nics = [];
- pcis = [];
boot = "cd";
vnc = 0;
vnc_keymap = "en-us";
- cpuid = [];
- datadir = "";
- platform = [];
- extrahvm = [];
- notify = NotifyNone;
- daemonize = false;
power_management = 0;
oem_features = 0;
timer_mode = None;
timeoffset = None;
hpet = None;
vpt_align = None;
- snapshot_mode = NoSnapshot;
- extra_local_watches = [];
- extra_vm_watches = [];
global_pci_msitranslate = 0;
global_pci_power_mgmt = 0;
- sound = None;
inject_sci = 0;
+ sound = None;
+
+ (* list_{get/del/add} *)
+ disks = [];
+ nics = [];
+ pcis = [];
+ cpuid = [];
+ platform = [];
+ extrahvm = [];
+ extra_local_watches = [];
+ extra_vm_watches = [];
+
+ (* others *)
+ snapshot_mode = NoSnapshot;
+ datadir = "";
+ notify = NotifyNone;
+ daemonize = false;
+ on_halt = ActionDestroy;
+ on_restart = ActionRestart;
+ on_crash = ActionDestroy;
}
let of_file uuid error_report file =
- let hvm = ref empty.hvm
- and debug = ref empty.debug
- and verbose = ref empty.verbose
- and no_mem_check = ref empty.no_mem_check
- and output = ref ""
- and kernel = ref ""
- and cmdline = ref ""
- and serial = ref ""
- and initrd = ref ""
- and memory = ref (-1)
- and vcpus = ref 1
- and pae = ref false
- and apic = ref false
- and acpi = ref false
- and nx = ref false
- and smbios_pt = ref false
- and acpi_pt = ref false
- and diskinfo_pt = ref false
- and viridian = ref false
- and videoram = ref None
- and disks = ref []
- and nics = ref []
- and pcis = ref []
- and on_restart = ref ActionRestart
- and on_crash = ref ActionDestroy
- and on_halt = ref ActionDestroy
- and boot = ref "cd"
- and vnc = ref 0
- and vnc_keymap = ref "en-us"
- and __uuid = ref None
- and name = ref ""
- and cpuid = ref []
+ let cfg = ref empty in
+
+ let __uuid = ref None
and startup = ref StartupStart
- and notify = ref NotifyNone
- and datadir = ref ""
- and extrahvm = ref []
- and platform = ref []
- and daemonize = ref false
- and power_management = ref 0
- and oem_features = ref 0
- and timer_mode = ref None
- and timeoffset = ref None
- and hpet = ref None
- and vpt_align = ref None
- and snapshot_mode = ref NoSnapshot
- and extra_local_watches = ref []
- and extra_vm_watches = ref []
- and pci_msitranslate = ref 0
- and pci_power_mgmt = ref 0
- and sound = ref None
- and inject_sci = ref 0
- in
+ and debug = ref (!cfg.debug)
+ and output = ref (!cfg.output)
+ and no_mem_check = ref (!cfg.no_mem_check)
+ in
let set_action ref_var s =
match s with
| "preserve" -> ref_var := ActionPreserve
| _ -> failwith "unknown action state"
in
- let set_disk s =
- try disks := (config_disk_of_string s) :: !disks
- with exn ->
- eprintf "error: disk config: %s\n%!"
- (Printexc.to_string exn);
- raise exn
- in
- let set_nic s =
- try
- let nic = config_nic_of_string uuid s in
- nics := nic :: !nics;
- with exn ->
- eprintf "error: vif config: %s\n%!"
- (Printexc.to_string exn);
- raise exn
- in
- let set_pci s =
- try
- let pcistruct = config_pci_of_string s in
- pcis := pcistruct :: !pcis
- with exn ->
- eprintf "error: pci config: %s\n%!" (Printexc.to_string exn); raise exn
- in
- let __set_cpuid s =
- (* that's the same format as xend. i.e. NODE+NODE:REG=[01xks]{32}{,REG=[01xks]{32}}* *)
- match String.split ':' s with
- | [ nodes; x ] ->
- let nodetuple =
- match String.split '+' nodes with
- | [ x; y ] -> Int64.of_string x, Some (Int64.of_string y)
- | [ x ] -> Int64.of_string x, None
- | _ -> failwith "cannot parse node format"
- in
- let l = String.split ',' x in
- let x = List.map (fun x ->
- match String.split '=' x with
- | [ reg_str; mask ] ->
- let reg = Domain.cpuid_reg_of_string reg_str in
- if String.startswith "0x" mask then (
- failwith "FIXME hexadecimal mask not supported yet"
- ) else if String.length mask <> 32 then (
- let a = Array.create 32 Domain.Default in
- for i = 0 to (String.length mask - 1); do
- a.(i) <- Domain.cpuid_rtype_of_char mask.[i]
- done;
- reg, a
- ) else
- failwith "mask is not 32 characters long"
- | _ ->
- failwith "cannot parse register mask"
- ) l in
- cpuid := (nodetuple, x) :: !cpuid
- | _ ->
- failwith "cannot parse format"
- in
- let set_cpuid s =
- try __set_cpuid s with exn -> eprintf "error: cpuid config: %s\n%!" (Printexc.to_string exn); raise exn
- in
let set_startup s =
match String.split ~limit:2 ' ' s with
| "started" :: _ | "start" :: _ -> startup := StartupStart
| "restore-del" :: file :: _ -> startup := StartupRestore (file, true)
| _ -> ()
in
- let set_extra_hvm s =
- match String.split ~limit:2 '=' s with
- | k :: v :: [] -> extrahvm := (k, Some v) :: !extrahvm
- | k :: [] -> extrahvm := (k, None) :: !extrahvm
- | _ -> ()
- in
- let set_platform s =
- match String.split ~limit:2 '=' s with
- | k :: v :: [] -> platform := (k, v) :: !platform
- | k :: [] -> platform := (k, "") :: !platform
- | _ -> ()
- in
- let set_local_watch s =
- extra_local_watches := s :: !extra_local_watches
- in
- let set_vm_watch s =
- extra_vm_watches := s :: !extra_vm_watches
- in
- let set_notify s = notify := config_notify_of_string s in
let cfg_args = [
- ("paused", Config.Bool (fun b -> startup := if b then StartupPause else StartupStart));
("startup", Config.String set_startup);
- ("hvm", Config.Set_bool hvm);
- ("pae", Config.Set_bool pae);
- ("acpi", Config.Set_bool acpi);
- ("apic", Config.Set_bool apic);
- ("nx", Config.Set_bool nx);
- ("smbios-pt", Config.Set_bool smbios_pt);
- ("acpi-pt", Config.Set_bool acpi_pt);
- ("diskinfo-pt", Config.Set_bool diskinfo_pt);
- ("viridian", Config.Set_bool viridian);
- ("videoram", Config.Int (fun i -> videoram := Some i));
- ("debug", Config.Set_bool debug);
- ("no_mem_check", Config.Set_bool no_mem_check);
("output", Config.Set_string output);
- ("verbose", Config.Set_bool verbose);
- ("name", Config.Set_string name);
("uuid", Config.String (fun s -> __uuid := Some s));
- ("kernel", Config.Set_string kernel);
- ("cmdline", Config.Set_string cmdline);
- ("serial", Config.Set_string serial);
- ("initrd", Config.Set_string initrd);
- ("vcpus", Config.Set_int vcpus);
- ("memory", Config.Int (fun i -> memory := i * 1024));
- ("on_halt", Config.String (set_action on_halt));
- ("on_restart", Config.String (set_action on_restart));
- ("on_crash", Config.String (set_action on_crash));
- ("vnc", Config.Set_int vnc);
- ("vnc_keymap", Config.Set_string vnc_keymap);
- ("disk", Config.String (set_disk));
- ("vif", Config.String (set_nic));
- ("nic", Config.String (set_nic));
- ("pci", Config.String (set_pci));
- ("cpuid", Config.String (set_cpuid));
- ("extra-hvm", Config.String set_extra_hvm);
- ("platform", Config.String set_platform);
- ("boot", Config.Set_string boot);
- ("notify", Config.String set_notify);
- ("datadir", Config.Set_string datadir);
- ("daemonize", Config.Set_bool daemonize);
- ("power-management", Config.Set_int power_management);
- ("oem-features", Config.Set_int oem_features);
- ("timer-mode", Config.Int (fun i -> timer_mode := Some i));
- ("time-offset", Config.String (fun s -> timeoffset := Some s));
- ("hpet", Config.Int (fun i -> hpet := Some i));
- ("vpt-align", Config.Int (fun i -> vpt_align := Some i));
- ("snapshot-mode", Config.String (fun s -> snapshot_mode := snapshot_mode_of_string s));
- ("extra-local-watch", Config.String set_local_watch);
- ("extra-vm-watch", Config.String set_vm_watch);
- ("pci-msitranslate", Config.Set_int pci_msitranslate);
- ("pci-power-management", Config.Set_int pci_power_mgmt);
- ("sound", Config.String (fun s -> sound := Some s));
- ("inject-sci", Config.Set_int inject_sci);
+ ("debug", Config.Set_bool debug);
+ ("no_mem_check", Config.Set_bool no_mem_check);
] in
+ let kv k v =
+ match k with
+ | "disk" | "vif" | "nic" | "pci" | "cpuid"
+ | "extra-hvm" | "extra-local-watch" | "extra-vm-watch" ->
+ cfg := list_add !cfg k v
+ | _ ->
+ cfg := set !cfg k v
+ in
begin try
- Config.read file cfg_args (fun _ _ -> raise Not_found);
+ Config.read file cfg_args kv;
with
Config.Error ls -> error_report ls
end;
- let pcis =
- let ids = ref [] in
- List.iter (fun (id, _, _, _, _) ->
- if not (List.mem id !ids) then
- ids := id :: !ids
- ) !pcis;
- List.map (fun id ->
- let ds = List.map (fun (_, bind, (a, b, c, d), msitranslate, power_mgmt) ->
- {
- pci_bind = bind;
- pci_domain = a;
- pci_bus = b;
- pci_slot = c;
- pci_func = d;
- pci_msitranslate = msitranslate;
- pci_power_mgmt = power_mgmt;
- }
- ) (List.filter (fun (x, _, _, _, _) -> x = id) !pcis) in
- id, ds
- ) !ids
- in
-
- (* first allocate unknown nics *)
- nics := List.rev !nics;
- List.iter (fun nic ->
- if nic.nic_id = (-1) then (
- let first_free_id =
- let rec s i =
- if i > 32 then
- failwith "cannot find a free nic id";
- let found =
- try let (_: config_nic) = List.find (fun x -> x.nic_aid = i) !nics in true
- with Not_found -> false
- in
- if not found then i else s (i + 1)
- in
- s 0
- in
- nic.nic_aid <- first_free_id
- )
- ) !nics;
- (* then sort the nics by ascending order *)
- let nics = List.sort (fun nic1 nic2 -> if nic1.nic_aid > nic2.nic_aid then 1 else -1) !nics in
-
- if !memory = -1 then
- failwith "you need to set memory";
- {
+ { !cfg with
__uuid = !__uuid;
- name = string_option_of_string !name;
- debug = !debug;
- verbose = !verbose;
- no_mem_check = !no_mem_check;
- output = !output;
startup = !startup;
- hvm = !hvm;
- kernel = if !hvm && !kernel = "" then "/usr/lib/xen/boot/hvmloader" else !kernel;
- cmdline = !cmdline;
- serial = if !serial = "" then "pty" else !serial;
- initrd = string_option_of_string !initrd;
- memory = Int64.of_int !memory;
- vcpus = !vcpus;
- pae = !pae;
- acpi = !acpi;
- apic = !apic;
- nx = !nx;
- smbios_pt = !smbios_pt;
- acpi_pt = !acpi_pt;
- diskinfo_pt = !diskinfo_pt;
- viridian = !viridian;
- videoram = !videoram;
- on_halt = !on_halt;
- on_restart = !on_restart;
- on_crash = !on_crash;
- disks = !disks;
- nics = nics;
- pcis = pcis;
- boot = !boot;
- vnc = !vnc;
- vnc_keymap = !vnc_keymap;
- cpuid = !cpuid;
- datadir = !datadir;
- platform = List.rev !platform;
- extrahvm = List.rev !extrahvm;
- notify = !notify;
- daemonize = !daemonize;
- power_management = !power_management;
- oem_features = !oem_features;
- timer_mode = !timer_mode;
- timeoffset = !timeoffset;
- hpet = !hpet;
- vpt_align = !vpt_align;
- snapshot_mode = !snapshot_mode;
- extra_local_watches = List.rev !extra_local_watches;
- extra_vm_watches = List.rev !extra_vm_watches;
- global_pci_msitranslate = !pci_msitranslate;
- global_pci_power_mgmt = !pci_power_mgmt;
- sound = !sound;
- inject_sci = !inject_sci;
+ output = !output;
+ no_mem_check = !no_mem_check;
}
-
end