Skip to content

Commit dbd1a3e

Browse files
committed
CP-53718: Update device name in xapi pif refresh
Pif device name maybe change. Look up device_to_position table to get the new device name in pif refresh. Then update to db. This function is called by pif.scan and resynchronise_pif_params. Signed-off-by: Changlei Li <[email protected]>
1 parent d45bded commit dbd1a3e

File tree

1 file changed

+112
-65
lines changed

1 file changed

+112
-65
lines changed

ocaml/xapi/xapi_pif.ml

Lines changed: 112 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,62 @@ let get_device_pci ~__context ~host ~device =
3838
| _ ->
3939
Ref.null
4040

41-
let refresh_internal ~__context ~self =
41+
let bridge_naming_convention (device : string) (pos_opt : int option) =
42+
match pos_opt with
43+
| Some index ->
44+
"xenbr" ^ string_of_int index
45+
| None ->
46+
"br" ^ device
47+
48+
let n_of_xenbrn_opt bridge =
49+
try Scanf.sscanf bridge "xenbr%d%!" Option.some with _ -> None
50+
51+
type tables = {
52+
device_to_position_table: (string * int) list
53+
; device_to_mac_table: (string * string) list
54+
; pif_to_device_table: (API.ref_PIF * string) list
55+
}
56+
57+
let make_tables ~__context ~host =
58+
let dbg = Context.string_of_task __context in
59+
let device_to_position_table = Net.Interface.get_interface_positions dbg () in
60+
let device_to_mac_table =
61+
List.filter_map
62+
(fun name ->
63+
if Net.Interface.is_physical dbg name then
64+
Some (name, Net.Interface.get_mac dbg name)
65+
else
66+
None
67+
)
68+
(Net.Interface.get_all dbg ())
69+
in
70+
(* Get all PIFs on this host *)
71+
let pif_to_device_table =
72+
Db.PIF.get_records_where ~__context
73+
~expr:
74+
(And
75+
( Eq (Field "host", Literal (Ref.string_of host))
76+
, Eq (Field "physical", Literal "true")
77+
)
78+
)
79+
|> List.map (fun (pref, prec) -> (pref, prec.API.pIF_device))
80+
in
81+
debug "tables: device_to_position_table = %s"
82+
(String.concat "; "
83+
(List.map
84+
(fun (d, p) -> d ^ ":" ^ string_of_int p)
85+
device_to_position_table
86+
)
87+
) ;
88+
debug "tables: device_to_mac_table = %s"
89+
(String.concat "; "
90+
(List.map (fun (d, m) -> d ^ ":" ^ m) device_to_mac_table)
91+
) ;
92+
debug "tables: pif_to_device_table = %s"
93+
(String.concat "; " (List.map snd pif_to_device_table)) ;
94+
{device_to_position_table; device_to_mac_table; pif_to_device_table}
95+
96+
let refresh_internal ~__context ~interface_tables ~self =
4297
let dbg = Context.string_of_task __context in
4398
let pif = Db.PIF.get_record ~__context ~self in
4499
let network =
@@ -50,12 +105,49 @@ let refresh_internal ~__context ~self =
50105
else
51106
pif.API.pIF_network
52107
in
108+
let find_name_by_position position original_name =
109+
match
110+
List.find_map
111+
(fun (name, pos) -> if pos = position then Some name else None)
112+
interface_tables.device_to_position_table
113+
with
114+
| Some name ->
115+
if name <> original_name then
116+
info "PIF: device name changed from %s to %s" original_name name ;
117+
name
118+
| None -> (
119+
(* This clause should be unlike to happen, if enter this, check the if
120+
we can get mac from networkd. If yes there may be a bug *)
121+
warn "PIF %s: no device found for position %d" original_name position ;
122+
try
123+
let mac = Net.Interface.get_mac dbg original_name in
124+
error
125+
"PIF %s: no device found for position %d, but get MAC address %s , \
126+
there may be a bug in networkd sorting."
127+
original_name position mac ;
128+
original_name
129+
with _ -> original_name
130+
)
131+
in
53132
let bridge = Db.Network.get_bridge ~__context ~self:network in
133+
(* Pif device name maybe change. Look up device_to_position table to get the
134+
new device name. *)
135+
let pif_device_name =
136+
if pif.API.pIF_physical then (
137+
match n_of_xenbrn_opt bridge with
138+
| Some position ->
139+
find_name_by_position position pif.API.pIF_device
140+
| None ->
141+
info "PIF %s: no position found for this device" pif.API.pIF_device ;
142+
pif.API.pIF_device
143+
) else
144+
pif.API.pIF_device
145+
in
54146
(* Update the specified PIF field in the database, if
55-
* and only if a corresponding value can be read from
56-
* the underlying network device and if that value is
57-
* different from the current field value.
58-
*)
147+
* and only if a corresponding value can be read from
148+
* the underlying network device and if that value is
149+
* different from the current field value.
150+
*)
59151
let maybe_update_database field_name db_value set_field get_value print_value
60152
=
61153
Option.iter
@@ -68,14 +160,17 @@ let refresh_internal ~__context ~self =
68160
)
69161
(try Some (get_value ()) with _ -> None)
70162
in
71-
if pif.API.pIF_physical then
163+
if pif.API.pIF_physical then (
164+
maybe_update_database "device" pif.API.pIF_device Db.PIF.set_device
165+
(fun () -> pif_device_name)
166+
Fun.id ;
72167
maybe_update_database "MAC" pif.API.pIF_MAC Db.PIF.set_MAC
73-
(fun () -> Net.Interface.get_mac dbg pif.API.pIF_device)
74-
(fun x -> x) ;
168+
(fun () -> Net.Interface.get_mac dbg pif_device_name)
169+
Fun.id
170+
) ;
75171
maybe_update_database "PCI" pif.API.pIF_PCI Db.PIF.set_PCI
76172
(fun () ->
77-
get_device_pci ~__context ~host:pif.API.pIF_host
78-
~device:pif.API.pIF_device
173+
get_device_pci ~__context ~host:pif.API.pIF_host ~device:pif_device_name
79174
)
80175
Ref.string_of ;
81176
maybe_update_database "MTU" pif.API.pIF_MTU Db.PIF.set_MTU
@@ -84,15 +179,16 @@ let refresh_internal ~__context ~self =
84179
if pif.API.pIF_physical then
85180
maybe_update_database "capabilities" pif.API.pIF_capabilities
86181
Db.PIF.set_capabilities
87-
(fun () -> Net.Interface.get_capabilities dbg pif.API.pIF_device)
182+
(fun () -> Net.Interface.get_capabilities dbg pif_device_name)
88183
(String.concat "; ")
89184

90185
let refresh ~__context ~host ~self =
91186
let localhost = Helpers.get_localhost ~__context in
187+
let interface_tables = make_tables ~__context ~host in
92188
if not (host = localhost) then
93189
Helpers.internal_error "refresh: Host mismatch, expected %s but got %s"
94190
(Ref.string_of host) (Ref.string_of localhost) ;
95-
refresh_internal ~__context ~self
191+
refresh_internal ~__context ~interface_tables ~self
96192

97193
let refresh_all ~__context ~host =
98194
let localhost = Helpers.get_localhost ~__context in
@@ -112,14 +208,10 @@ let refresh_all ~__context ~host =
112208
)
113209
)
114210
in
115-
List.iter (fun self -> refresh_internal ~__context ~self) pifs
116-
117-
let bridge_naming_convention (device : string) (pos_opt : int option) =
118-
match pos_opt with
119-
| Some index ->
120-
"xenbr" ^ string_of_int index
121-
| None ->
122-
"br" ^ device
211+
let interface_tables = make_tables ~__context ~host in
212+
List.iter
213+
(fun self -> refresh_internal ~__context ~interface_tables ~self)
214+
pifs
123215

124216
let read_bridges_from_inventory () =
125217
try String.split ' ' (Xapi_inventory.lookup Xapi_inventory._current_interfaces)
@@ -360,51 +452,6 @@ let find_or_create_network (bridge : string) (device : string)
360452
in
361453
net_ref
362454

363-
type tables = {
364-
device_to_position_table: (string * int) list
365-
; device_to_mac_table: (string * string) list
366-
; pif_to_device_table: (API.ref_PIF * string) list
367-
}
368-
369-
let make_tables ~__context ~host =
370-
let dbg = Context.string_of_task __context in
371-
let device_to_position_table = Net.Interface.get_interface_positions dbg () in
372-
let device_to_mac_table =
373-
List.filter_map
374-
(fun name ->
375-
if Net.Interface.is_physical dbg name then
376-
Some (name, Net.Interface.get_mac dbg name)
377-
else
378-
None
379-
)
380-
(Net.Interface.get_all dbg ())
381-
in
382-
(* Get all PIFs on this host *)
383-
let pif_to_device_table =
384-
Db.PIF.get_records_where ~__context
385-
~expr:
386-
(And
387-
( Eq (Field "host", Literal (Ref.string_of host))
388-
, Eq (Field "physical", Literal "true")
389-
)
390-
)
391-
|> List.map (fun (pref, prec) -> (pref, prec.API.pIF_device))
392-
in
393-
debug "tables: device_to_position_table = %s"
394-
(String.concat "; "
395-
(List.map
396-
(fun (d, p) -> d ^ ":" ^ string_of_int p)
397-
device_to_position_table
398-
)
399-
) ;
400-
debug "tables: device_to_mac_table = %s"
401-
(String.concat "; "
402-
(List.map (fun (d, m) -> d ^ ":" ^ m) device_to_mac_table)
403-
) ;
404-
debug "tables: pif_to_device_table = %s"
405-
(String.concat "; " (List.map snd pif_to_device_table)) ;
406-
{device_to_position_table; device_to_mac_table; pif_to_device_table}
407-
408455
let is_my_management_pif ~__context ~self =
409456
let net = Db.PIF.get_network ~__context ~self in
410457
let management_if =

0 commit comments

Comments
 (0)