with _ ->
raise (Invalid_Mac mac)
+let get_backend_dev ~xs (x: device) =
+ try
+ let path = Hotplug.get_hotplug_path x in
+ xs.Xs.read (path ^ "/vif")
+ with Xb.Noent ->
+ raise (Hotplug_script_expecting_field (x, "vif"))
+
(** Plug in the backend of a guest's VIF in dom0. Note that a guest may disconnect and
then reconnect their network interface: we have to re-run this code every time we
see a hotplug online event. *)
let plug ~xs ~netty ~mac ?(mtu=0) ?rate ?protocol (x: device) =
- let backend_dev = try
- let path = Hotplug.get_hotplug_path x in
- xs.Xs.read (path ^ "/vif")
- with Xb.Noent ->
- raise (Hotplug_script_expecting_field (x, "vif")) in
+ let backend_dev = get_backend_dev xs x in
if mtu > 0 then
Netdev.set_mtu backend_dev mtu;
module Vif :
sig
exception Invalid_Mac of string
-
+ val get_backend_dev : xs:Xs.xsh -> device -> string
val add : xs:Xs.xsh -> devid:int -> netty:Netman.netty
-> mac:string -> ?mtu:int -> ?rate:(int64 * int64) option
-> ?protocol:protocol -> ?backend_domid:Xc.domid -> Xc.domid
| CDEject
| CDInsertFile
| CDInsertReal
+ | NicBridgeSwitch
| ReadConfig
| Help
"physpath", R, ArgString ]);
(CDInsertReal,mk_desc_args "cd-insert-real" [ "virtpath", R, ArgString;
"physpath", R, ArgString ]);
+ (NicBridgeSwitch,mk_desc_args "nic-bridge-switch" [ "id", R, ArgInt;
+ "bridge", R, ArgString ]);
+
(ReadConfig, mk_desc_args_nb "read-config" [ "path", O, ArgString ]);
let (_: Device_common.device) =
Device.Vif.add ~xs ~devid:nic.nic_id ~netty ~mac:nic.nic_mac
~protocol:(devproto_of_state state) state.vm_domid in
+ state.vm_nics <- {ns_id=nic.nic_id; ns_bridge=nic.nic_bridge}::state.vm_nics;
()
let get_nics cfg =
(* then sort the nics by ascending order *)
List.sort (fun nic1 nic2 -> if nic1.nic_id > nic2.nic_id then 1 else -1) cfg.nics
+let device_of_vif domid id =
+ let backend = { Device_common.domid = 0;
+ kind = Device_common.Vif;
+ devid = id } in
+ Device_common.device_of_backend backend domid
+
+let nic_bridge_switch ~xs state id bridge =
+ let id = Int64.to_int id in
+ let ns = List.find (fun ns -> ns.ns_id = id) state.vm_nics in
+ let cur_netty = Netman.Bridge ns.ns_bridge in
+ let new_netty = Netman.Bridge bridge in
+ let device = device_of_vif state.vm_domid id in
+ let backend_dev = Device.Vif.get_backend_dev xs device in
+ Netman.offline backend_dev cur_netty;
+ Netman.online backend_dev new_netty;
+ state.vm_nics <- List.map (fun ns -> if ns.ns_id=id then {ns with ns_bridge=bridge} else ns) state.vm_nics;
+ Xenvmlib.Ok
+
let get_pcis cfg =
let ids = ref [] in
List.iter (fun (id, dev) ->
mutable monitor_dbus_quit: bool;
}
+type nic_state = {
+ ns_id : int;
+ mutable ns_bridge: string;
+}
+
type vm_state = {
vm_uuid: string;
vm_monitors: monitor_state;
mutable vm_vnc_port: int;
mutable vm_lifestate: vmlifestate;
mutable vm_tap2_disks: (Vmconfig.config_disk * string) list;
+ mutable vm_nics: nic_state list;
mutable vm_on_suspend_action: Vmconfig.action;
mutable vm_cfg: Vmconfig.config;
mutable vm_next_cfg: Vmconfig.config option;
vm_lifestate = VmShutdown;
vm_vnc_port = (-1);
vm_tap2_disks = [];
+ vm_nics = [];
vm_on_suspend_action = ActionSuspend;
vm_cfg = cfg;
vm_next_cfg = None;
let virtpath = Tasks.args_get_string args "virtpath" in
let physpath = Tasks.args_get_string args "physpath" in
with_xcs (fun xc xs -> Vmact.cd_insert_file xs state virtpath physpath)
+ | Tasks.NicBridgeSwitch ->
+ let id = Tasks.args_get_int args "id" in
+ let bridge = Tasks.args_get_string args "bridge" in
+ with_xcs (fun xc xs -> Vmact.nic_bridge_switch xs state id bridge)
| Tasks.ReadConfig ->
let path =
try Some (Tasks.args_get_string args "path")