@@ -171,31 +171,21 @@ let rec monitor dbg () =
171171 let vendor_id, device_id = if List. length devs = 1 then Sysfs. get_pci_ids dev else " " , " " in
172172 let carriers = List. map Sysfs. get_carrier devs in
173173 let speed, duplex =
174- let int_of_duplex = function
175- | Duplex_half -> 1
176- | Duplex_full -> 2
177- | Duplex_unknown -> 0
174+ let combine_duplex = function
175+ | Duplex_full , Duplex_full -> Duplex_full
176+ | Duplex_unknown , a | a , Duplex_unknown -> a
177+ | _ -> Duplex_half
178178 in
179- let duplex_of_int = function
180- | 1 -> Duplex_half
181- | 2 -> Duplex_full
182- | _ -> Duplex_unknown
183- in
184- let statuses = List. map2 (fun dev carrier ->
185- let speed, duplex =
186- try
187- if not carrier then failwith " no carrier" ;
188- Bindings. get_status dev
189- with _ ->
190- 0 ,
191- Duplex_unknown
192- in
193- speed, int_of_duplex duplex
194- ) devs carriers in
195- let speed, duplex =
196- List. fold_left (fun (speed , duplex ) (speed' , duplex' ) -> (speed + speed'), (min duplex duplex')) (0 , 2 ) statuses
197- in
198- speed, duplex_of_int duplex
179+ List. fold_left2 (fun (speed , duplex ) dev carrier ->
180+ try
181+ if not carrier then
182+ speed, duplex
183+ else
184+ let speed', duplex' = Bindings. get_status dev in
185+ speed + speed', combine_duplex (duplex, duplex')
186+ with _ ->
187+ speed, duplex
188+ ) (0 , Duplex_unknown ) devs carriers
199189 in
200190 let nb_links = List. length devs in
201191 let carrier = List. mem true carriers in
@@ -247,6 +237,19 @@ let signal_networking_change () =
247237 (fun () -> XenAPI.Host. signal_networking_change xapi_rpc session)
248238 (fun () -> XenAPI.Session. local_logout xapi_rpc session)
249239
240+ (* Remove all outstanding reads on a file descriptor *)
241+ let clear_input fd =
242+ let buf = String. make 255 ' ' in
243+ let rec loop () =
244+ try
245+ ignore (Unix. read fd buf 0 255 );
246+ loop ()
247+ with _ -> ()
248+ in
249+ Unix. set_nonblock fd;
250+ loop () ;
251+ Unix. clear_nonblock fd
252+
250253let ip_watcher () =
251254 let cmd = Network_utils. iproute2 in
252255 let args = [" monitor" ; " address" ] in
@@ -256,16 +259,25 @@ let ip_watcher () =
256259 );
257260 Unix. close writeme;
258261 let in_channel = Unix. in_channel_of_descr readme in
259- debug " Started IP watcher thread" ;
260262 let rec loop () =
261263 let line = input_line in_channel in
262- (* Do not send events for link-local IPv6 addresses *)
264+ (* Do not send events for link-local IPv6 addresses, and removed IPs *)
263265 if String. has_substr line " inet" && not (String. has_substr line " inet6 fe80" ) then begin
266+ (* Ignore changes for the next second, since they usually come in bursts,
267+ * and signal only once. *)
268+ Thread. delay 1. ;
269+ clear_input readme;
264270 signal_networking_change ()
265271 end ;
266272 loop ()
267273 in
268- loop ()
274+ while true do
275+ try
276+ info " (Re)started IP watcher thread" ;
277+ loop ()
278+ with e ->
279+ warn " Error in IP watcher: %s\n %s" (Printexc. to_string e) (Printexc. get_backtrace () )
280+ done
269281
270282let start () =
271283 let dbg = " monitor_thread" in
0 commit comments