From: Vincent Hanquez Date: Fri, 17 Jul 2009 09:47:20 +0000 (+0100) Subject: xenvm: move generation out of config. use dynamic accessor for extensibility later. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f15e8d81a477314240a099668e42928023e35f8a;p=xenclient%2Ftoolstack.git xenvm: move generation out of config. use dynamic accessor for extensibility later. lots of small others change. --- diff --git a/xenvm/vmact.ml b/xenvm/vmact.ml index a43b6a2..51a2552 100644 --- a/xenvm/vmact.ml +++ b/xenvm/vmact.ml @@ -67,22 +67,6 @@ let notify state code l = 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 @@ -107,14 +91,87 @@ let add_disk_to_vm ~xs state disk = () 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 @@ -139,12 +196,35 @@ let dm_info_of_cfg cfg = 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; @@ -175,7 +255,7 @@ let add_devices xc xs domid state restore = | 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 ( @@ -497,13 +577,14 @@ let device_cmd xc xs state ty subcmd args = (* 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 = @@ -518,7 +599,7 @@ let device_cmd xc xs state ty subcmd 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 @@ -535,7 +616,7 @@ let device_cmd xc xs state ty subcmd args = 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 diff --git a/xenvm/vmconfig.ml b/xenvm/vmconfig.ml index 142c304..1ab6eb9 100644 --- a/xenvm/vmconfig.ml +++ b/xenvm/vmconfig.ml @@ -26,6 +26,13 @@ type notify_ty = | 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 @@ -59,8 +66,10 @@ type config_disk = { 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; } @@ -99,7 +108,7 @@ type config = { (* 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; @@ -136,7 +145,7 @@ let config_pci_of_string s = | _ -> 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 @@ -154,48 +163,25 @@ let config_pci_of_string s = 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 @@ -204,24 +190,19 @@ let config_nic_of_string vm_uuid s = 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 } @@ -245,6 +226,38 @@ let config_disk_of_string s = 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 :: [] -> ( @@ -272,7 +285,6 @@ exception Unknown_field of string 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 @@ -290,6 +302,7 @@ let get cfg field = | "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 @@ -299,12 +312,13 @@ let get cfg field = | "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 } @@ -319,29 +333,66 @@ let set cfg field 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 = ""; @@ -358,89 +409,49 @@ let empty = 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 @@ -449,64 +460,6 @@ let of_file uuid error_report file = | "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 @@ -516,186 +469,33 @@ let of_file uuid error_report file = | "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 diff --git a/xenvm/xenvm.ml b/xenvm/xenvm.ml index ff56df0..d1ed4b9 100644 --- a/xenvm/xenvm.ml +++ b/xenvm/xenvm.ml @@ -283,8 +283,8 @@ let monitor_vm state = let online = Hotplug.device_is_online ~xs device in let connected = Hotplug.device_is_connected ~xs device in if online && not connected then ( - let netty = Vmact.params_of_nic nic in - let mac = nic.nic_mac in + let netty = Netman.Bridge nic.nic_bridge_gen in + let mac = nic.nic_mac_gen in let protocol = Vmact.devproto_of_state state in let (_: Device_common.device) = Device.Vif.plug ~xs ~netty ~mac ~protocol device in ()