~ubuntu-branches/ubuntu/wily/marionnet/wily

« back to all changes in this revision

Viewing changes to user_level.ml

  • Committer: Package Import Robot
  • Author(s): Lucas Nussbaum
  • Date: 2014-04-02 16:59:06 UTC
  • mfrom: (4.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140402165906-w6nrmczff6l0cyc3
Tags: 0.90.6+bzr448-1
New upstream snapshot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
264
264
 
265
265
exception ForbiddenTransition;;
266
266
let raise_forbidden_transition msg =
267
 
 Log.printf "ForbiddenTransition raised in %s\n" msg;
 
267
 Log.printf1 "ForbiddenTransition raised in %s\n" msg;
268
268
 raise ForbiddenTransition
269
269
;;
270
270
 
353
353
          let message =
354
354
            Printf.sprintf "enqueue_task_with_progress_bar: %s %s failed (%s)"
355
355
              verb self#get_name (Printexc.to_string e) in
356
 
          Log.printf "%s\n" message;
 
356
          Log.printf1 "%s\n" message;
357
357
          Simple_dialogs.warning message message ();
358
358
          Log.printf "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
359
359
        end));
366
366
        | None ->
367
367
            assert false)
368
368
 
369
 
(*  method reboot_if_possible =
370
 
    try
371
 
      self#suspend;
372
 
      self#startup;
373
 
    with _ ->
374
 
      () *)
375
 
 
376
369
  method create =
377
370
    (* This is invisible for the user: don't set the next state *)
378
371
    Task_runner.the_task_runner#schedule ~name:("create "^self#get_name) (fun () -> self#create_right_now)
379
372
 
380
373
  method (*private*) destroy_my_simulated_device =
381
 
    Log.printf "component \"%s\": destroying my simulated device.\n" self#get_name;
 
374
    Log.printf1 "component \"%s\": destroying my simulated device.\n" self#get_name;
382
375
    (* This is invisible for the user: don't set the next state *)
383
376
    Task_runner.the_task_runner#schedule ~name:("destroy "^self#get_name)(fun () -> self#destroy_right_now)
384
377
 
398
391
    self#set_next_simulated_device_state (Some DeviceOff);
399
392
    self#enqueue_task_with_progress_bar (s_ "Stopping") (fun () -> if self#can_gracefully_shutdown then self#gracefully_shutdown_right_now)
400
393
 
 
394
  method gracefully_restart =
 
395
    if not self#can_gracefully_shutdown then () else (* continue *)
 
396
    self#gracefully_shutdown;
 
397
    self#set_next_simulated_device_state (Some DeviceOn);
 
398
    self#enqueue_task_with_progress_bar
 
399
      (s_ "Restarting")
 
400
      (fun () ->
 
401
         Thread.delay 7.; (* Ugly: to prevent a killer signal (all this part must be rewritten with Cortex_lib as soon as possible!!) *)
 
402
         if self#can_startup then self#startup_right_now)
 
403
 
401
404
  method poweroff =
402
405
    self#set_next_simulated_device_state (Some DeviceOff);
403
406
    self#enqueue_task_with_progress_bar (s_ "Shutting down") (fun () -> if self#can_poweroff then self#poweroff_right_now)
405
408
  method (*private*) create_right_now =
406
409
    Recursive_mutex.with_mutex mutex
407
410
      (fun () ->
408
 
        Log.printf "About to create the simulated device %s: it's connected to %d cables.\n"
 
411
        Log.printf2 "About to create the simulated device %s: it's connected to %d cables.\n"
409
412
          self#get_name
410
413
          (List.length (self#get_involved_cables));
411
414
 
417
420
              (* An endpoint for cables linked to self was just added; we need to start some cables. *)
418
421
              ignore (List.map
419
422
                        (fun cable ->
420
 
                           Log.printf "Working on cable %s\n" (cable#show "");
 
423
                           Log.printf1 "Working on cable %s\n" (cable#show "");
421
424
                           cable#increment_alive_endpoint_no)
422
425
                        (self#get_involved_cables)))
423
426
 
425
428
 
426
429
  (** The unit parameter is needed: see how it's used in simulated_network: *)
427
430
  method private destroy_because_of_unexpected_death () =
428
 
    Log.printf "You don't deadlock here %s, do you? -1\n" self#get_name;
 
431
    Log.printf1 "You don't deadlock here %s, do you? -1\n" self#get_name;
429
432
    Recursive_mutex.with_mutex mutex
430
433
      (fun () ->
431
 
        Log.printf "You don't deadlock here %s, do you? 0\n" self#get_name;
 
434
        Log.printf1 "You don't deadlock here %s, do you? 0\n" self#get_name;
432
435
        (try
433
436
          self#destroy_right_now
434
437
        with e -> begin
435
 
          Log.printf "WARNING: destroy_because_of_unexpected_death: failed (%s)\n"
 
438
          Log.printf1 "WARNING: destroy_because_of_unexpected_death: failed (%s)\n"
436
439
            (Printexc.to_string e);
437
440
        end;
438
441
          self#set_next_simulated_device_state None)); (* don't show next-state icons for this *)
440
443
  method (*private*) destroy_right_now =
441
444
    Recursive_mutex.with_mutex mutex
442
445
      (fun () ->
443
 
        Log.printf "About to destroy the simulated device %s \n" self#get_name;
 
446
        Log.printf1 "About to destroy the simulated device %s \n" self#get_name;
444
447
        match !automaton_state, !simulated_device with
445
448
        | (DeviceOn | DeviceSleeping), Some(d) ->
446
 
             Log.printf
 
449
             Log.printf1
447
450
               "  (destroying the on/sleeping device %s. Powering it off first...)\n"
448
451
               self#get_name;
449
452
             self#poweroff_right_now; (* non-gracefully *)
450
453
             self#destroy_right_now
451
454
        | NoDevice, None ->
452
 
            Log.printf
 
455
            Log.printf1
453
456
             "  (destroying the already 'no-device' device %s. Doing nothing...)\n"
454
457
             self#get_name;
455
458
            () (* Do nothing, but don't fail. *)
456
459
        | DeviceOff, Some(d) ->
457
460
            ((* An endpoint for cables linked to self was just added; we
458
461
                may need to start some cables. *)
459
 
             Log.printf
 
462
             Log.printf1
460
463
               "  (destroying the off device %s: decrementing its cables rc...)\n"
461
464
               self#get_name;
462
465
             List.iter
463
466
               (fun cable ->
464
 
                 Log.printf "Unpinning the cable %s " (cable#show "");
 
467
                 Log.printf1 "Unpinning the cable %s " (cable#show "");
465
468
                 cable#decrement_alive_endpoint_no;
466
 
                 Log.printf ("The cable %s was unpinned with success\n") (cable#show "");
 
469
                 Log.printf1 ("The cable %s was unpinned with success\n") (cable#show "");
467
470
                 )
468
471
               self#get_involved_cables;
469
 
             Log.printf "  (destroying the simulated device implementing %s...)\n" self#get_name;
 
472
             Log.printf1 "  (destroying the simulated device implementing %s...)\n" self#get_name;
470
473
             d#destroy; (* This is the a method from some object in Simulation_level *)
471
474
             simulated_device := None;
472
475
             automaton_state := NoDevice;
473
476
             self#set_next_simulated_device_state None;
474
 
             Log.printf "We're not deadlocked yet (%s). Great.\n" self#get_name);
 
477
             Log.printf1 "We're not deadlocked yet (%s). Great.\n" self#get_name);
475
478
        | _ ->
476
479
            raise_forbidden_transition "destroy_right_now"
477
480
        );
478
 
    Log.printf "The simulated device %s was destroyed with success\n" self#get_name
 
481
    Log.printf1 "The simulated device %s was destroyed with success\n" self#get_name
479
482
 
480
483
 
481
484
  method (*private*) startup_right_now =
484
487
        (* Don't startup ``incorrect'' devices. This is currently limited to cables of the
485
488
           wrong crossoverness which the user has defined by mistake: *)
486
489
        if self#is_correct then begin
487
 
          Log.printf "Starting up the device %s...\n" self#get_name;
 
490
          Log.printf1 "Starting up the device %s...\n" self#get_name;
488
491
          match !automaton_state, !simulated_device with
489
492
          | NoDevice, None ->
490
 
             (Log.printf "Creating processes for %s first...\n" self#get_name;
 
493
             (Log.printf1 "Creating processes for %s first...\n" self#get_name;
491
494
              self#create_right_now;
492
 
              Log.printf "Processes for %s were created...\n" self#get_name;
 
495
              Log.printf1 "Processes for %s were created...\n" self#get_name;
493
496
              self#startup_right_now
494
497
              )
495
498
 
497
500
             (d#startup;  (* This is the a method from some object in Simulation_level *)
498
501
              automaton_state := DeviceOn;
499
502
              self#set_next_simulated_device_state None;
500
 
              Log.printf "The device %s was started up\n" self#get_name
 
503
              Log.printf1 "The device %s was started up\n" self#get_name
501
504
              )
502
505
 
503
506
          | DeviceOn,  _ ->
504
 
              Log.printf "startup_right_now: called in state %s: nothing to do.\n" (self#automaton_state_as_string)
 
507
              Log.printf1 "startup_right_now: called in state %s: nothing to do.\n" (self#automaton_state_as_string)
505
508
 
506
509
          | _ -> raise_forbidden_transition "startup_right_now"
507
510
        end else begin
508
 
          Log.printf "REFUSING TO START UP the ``incorrect'' device %s!!!\n" self#get_name
 
511
          Log.printf1 "REFUSING TO START UP the ``incorrect'' device %s!!!\n" self#get_name
509
512
        end)
510
513
 
511
514
  method (*private*) suspend_right_now =
512
515
    Recursive_mutex.with_mutex mutex
513
516
      (fun () ->
514
 
        Log.printf "Suspending up the device %s...\n" self#get_name;
 
517
        Log.printf1 "Suspending up the device %s...\n" self#get_name;
515
518
        match !automaton_state, !simulated_device with
516
519
          DeviceOn, Some(d) ->
517
520
           (d#suspend; (* This is the a method from some object in Simulation_level *)
522
525
  method (*private*) resume_right_now =
523
526
    Recursive_mutex.with_mutex mutex
524
527
      (fun () ->
525
 
        Log.printf "Resuming the device %s...\n" self#get_name;
 
528
        Log.printf1 "Resuming the device %s...\n" self#get_name;
526
529
        match !automaton_state, !simulated_device with
527
530
        | DeviceSleeping, Some(d) ->
528
531
           (d#resume; (* This is the a method from some object in Simulation_level *)
535
538
    Recursive_mutex.with_mutex mutex
536
539
      (fun () ->
537
540
        let current_state = self#automaton_state_as_string in
538
 
        (Log.printf "* Gracefully shutting down the device %s (from state: %s)...\n"
 
541
        (Log.printf2 "* Gracefully shutting down the device %s (from state: %s)...\n"
539
542
          self#get_name
540
543
          current_state);
541
544
        match !automaton_state, !simulated_device with
549
552
            self#gracefully_shutdown_right_now)
550
553
 
551
554
        | NoDevice,  _ | DeviceOff, _ ->
552
 
            Log.printf "gracefully_shutdown_right_now: called in state %s: nothing to do.\n" (self#automaton_state_as_string)
 
555
            Log.printf1 "gracefully_shutdown_right_now: called in state %s: nothing to do.\n" (self#automaton_state_as_string)
553
556
 
554
557
        | _ -> raise_forbidden_transition "gracefully_shutdown_right_now")
555
558
 
556
559
  method (*private*) poweroff_right_now =
557
560
    Recursive_mutex.with_mutex mutex
558
561
      (fun () ->
559
 
        Log.printf "Powering off the device %s...\n" self#get_name;
 
562
        Log.printf1 "Powering off the device %s...\n" self#get_name;
560
563
        match !automaton_state, !simulated_device with
561
564
        | DeviceOn, Some(d) ->
562
565
           (d#shutdown; (* non-gracefully *)
568
571
             self#poweroff_right_now)
569
572
 
570
573
        | NoDevice,  _ | DeviceOff, _ ->
571
 
            Log.printf "poweroff_right_now: called in state %s: nothing to do.\n" (self#automaton_state_as_string)
 
574
            Log.printf1 "poweroff_right_now: called in state %s: nothing to do.\n" (self#automaton_state_as_string)
572
575
 
573
576
        | _ -> raise_forbidden_transition "poweroff_right_now")
574
577
 
678
681
  (** The global network. It's a pain to have to access this via a global variable
679
682
      define in Marionnet *)
680
683
  val network = network
681
 
  
 
684
 
682
685
  method virtual can_suspend : bool
683
686
  method virtual can_resume  : bool
684
 
  
 
687
 
685
688
  method virtual suspend : unit
686
689
  method virtual resume  : unit
687
690
end;;
904
907
        self#get_name
905
908
   with
906
909
   | true ->
907
 
       Log.printf "The %s %s has already defects defined...\n"
 
910
       Log.printf2 "The %s %s has already defects defined...\n"
908
911
         self#defects_device_type
909
912
         self#get_name
910
913
   | false ->
917
920
         ()
918
921
 
919
922
  method private destroy_my_defects =
920
 
    Log.printf "component \"%s\": destroying my defects.\n" self#get_name;
 
923
    Log.printf1 "component \"%s\": destroying my defects.\n" self#get_name;
921
924
    network#defects#remove_subtree_by_name self#get_name;
922
925
 
923
926
  method private defects_update_port_no new_port_no =
1122
1125
               busy_ports_indexes)
1123
1126
 
1124
1127
  method destroy_my_ledgrid : unit =
1125
 
    Log.printf "component \"%s\": destroying my ledgrid.\n" self#get_name;
 
1128
    Log.printf1 "component \"%s\": destroying my ledgrid.\n" self#get_name;
1126
1129
    (network#ledgrid_manager:Ledgrid_manager.ledgrid_manager)#destroy_device_ledgrid
1127
1130
      ~id:(self#id)
1128
1131
      ()
1216
1219
    Obj.magic
1217
1220
      (Printf.ksprintf
1218
1221
        (fun x-> let msg = self#banner^x in
1219
 
                 let () = Log.printf "%s\n" msg in
 
1222
                 let () = Log.printf1 "%s\n" msg in
1220
1223
                 failwith msg))
1221
1224
 
1222
1225
  (** A machine has a Linux filesystem *)
1286
1289
   let icon = self#history_icon in
1287
1290
   let name = self#get_name in
1288
1291
   match ((network#history:Treeview_history.t)#number_of_states_with_name name) > 0 with
1289
 
   | true -> Log.printf "The virtual machine %s has already history defined...\n" name
 
1292
   | true -> Log.printf1 "The virtual machine %s has already history defined...\n" name
1290
1293
   | false ->
1291
1294
      network#history#add_device
1292
1295
          ~name
1304
1307
        "Name"
1305
1308
        self#get_name
1306
1309
   with
1307
 
   | true  -> Log.printf "The %s %s has already ifconfig defined...\n" self#ifconfig_device_type self#get_name
 
1310
   | true  -> Log.printf2 "The %s %s has already ifconfig defined...\n" self#ifconfig_device_type self#get_name
1308
1311
   | false ->
1309
1312
      begin
1310
1313
      network#ifconfig#add_device
1315
1318
      end
1316
1319
 
1317
1320
  method destroy_my_ifconfig =
1318
 
    Log.printf "component \"%s\": destroying my ifconfig.\n" self#get_name;
 
1321
    Log.printf1 "component \"%s\": destroying my ifconfig.\n" self#get_name;
1319
1322
    network#ifconfig#remove_subtree_by_name self#get_name;
1320
1323
 
1321
1324
  method destroy_my_history =
1322
 
    Log.printf "component \"%s\": destroying my history.\n" self#get_name;
 
1325
    Log.printf1 "component \"%s\": destroying my history.\n" self#get_name;
1323
1326
    network#history#remove_device_tree self#get_name;
1324
1327
 
1325
1328
  method update_virtual_machine_with ~name ~port_no kernel =
1436
1439
 method  set_dotoptions x = dotoptions <- Some x
1437
1440
 
1438
1441
 method components : (component list) =
1439
 
   List.append 
1440
 
     (nodes#get  :> component list) 
 
1442
   List.append
 
1443
     (nodes#get  :> component list)
1441
1444
     (cables#get :> component list) (* CABLES MUST BE AT THE FINAL POSITION for marshaling !!!! *)
1442
1445
 
1443
 
 method components_of_kind ?(kind:[`Node | `Cable] option) () = 
 
1446
 method components_of_kind ?(kind:[`Node | `Cable] option) () =
1444
1447
   match kind with
1445
1448
   | None        -> self#components
1446
 
   | Some `Node  -> (nodes#get  :> (component list)) 
1447
 
   | Some `Cable -> (cables#get :> (component list)) 
1448
 
     
 
1449
   | Some `Node  -> (nodes#get  :> (component list))
 
1450
   | Some `Cable -> (cables#get :> (component list))
 
1451
 
1449
1452
 method disjoint_union_of_nodes_and_cables : ((component * [`Node | `Cable]) list) =
1450
1453
   let xs = List.map (fun x -> x,`Node ) (nodes#get  :> component list)  in
1451
1454
   let ys = List.map (fun x -> x,`Cable) (cables#get :> component list)  in
1458
1461
    the task runner method [wait_for_all_currently_scheduled_tasks]. *)
1459
1462
 method reset ?(scheduled=false) () =
1460
1463
  begin
1461
 
   Log.print_string "---\n";
1462
 
   Log.printf "network#reset: begin\n";
1463
 
   Log.printf "\tDestroying all cables...\n";
 
1464
   Log.printf "---\n";
 
1465
   Log.printf "network#reset: begin\n\tDestroying all cables...\n";
1464
1466
   (List.iter
1465
1467
      (fun cable -> try cable#destroy with _ -> ())
1466
1468
      cables#get);
1476
1478
   Log.printf "\tWait for all devices to terminate...\n";
1477
1479
   (** Make sure that all devices have actually been terminated before going
1478
1480
       on: we don't want them to lose filesystem access: *)
1479
 
   Log.printf "\tAll devices did terminate.\n";
1480
 
   Log.printf "network#reset: end (success)\n";
1481
 
   Log.print_string "---\n";
 
1481
   Log.printf "\tAll devices did terminate.\nnetwork#reset: end (success)\n---\n";
1482
1482
  end
1483
1483
 
1484
1484
 method destroy_process_before_quitting () =
1525
1525
  | false ->
1526
1526
      let ((nodename, attrs), _) = f in
1527
1527
        let name  = List.assoc "name" attrs in
1528
 
        (Log.printf "network#eval_forest_child: I can't interpret this \"%s\" name \"%s\".\n" nodename name)
 
1528
        (Log.printf2 "network#eval_forest_child: I can't interpret this \"%s\" name \"%s\".\n" nodename name)
1529
1529
        (* Forward-compatibility *)
1530
1530
 
1531
1531
 method names = (List.map (fun x->x#get_name) self#components)
1546
1546
 method get_component_by_name ?kind n =
1547
1547
   let components = self#components_of_kind ?kind () in
1548
1548
   try List.find (fun x->x#get_name=n) components with _ -> failwith ("get_component_by_name "^n)
1549
 
   
 
1549
 
1550
1550
 method involved_node_and_port_index_list =
1551
1551
   List.flatten (List.map (fun c->c#involved_node_and_port_index_list) cables#get)
1552
1552
 
1669
1669
 method get_node_names  =
1670
1670
   List.map (fun x->x#get_name) (nodes#get)
1671
1671
 
1672
 
 method get_nodes_that_can_startup ~devkind () =
1673
 
  ListExtra.filter_map
1674
 
    (fun x -> if (x#devkind = devkind) && x#can_startup then Some x#get_name else None)
1675
 
    nodes#get
1676
 
 
1677
 
 method get_nodes_that_can_gracefully_shutdown ~devkind () =
1678
 
  ListExtra.filter_map
1679
 
    (fun x -> if (x#devkind = devkind) && x#can_gracefully_shutdown then Some x#get_name else None)
1680
 
    nodes#get
1681
 
 
1682
 
 method get_nodes_that_can_suspend ~devkind () =
1683
 
  ListExtra.filter_map
1684
 
    (fun x -> if (x#devkind = devkind) && x#can_suspend then Some x#get_name else None)
1685
 
    nodes#get
1686
 
 
1687
 
 (* Including cables (suspend=disconnect, resume=reconnect). The boolean in the result 
1688
 
    indicates if the component is suspended (sleeping): *)   
 
1672
 method private predicate_of_optional_devkind ?devkind () =
 
1673
  match devkind with
 
1674
  | Some devkind -> (fun x -> x#devkind = devkind)
 
1675
  | None         -> (fun x -> true)
 
1676
 
 
1677
 method get_nodes_such_that ?devkind (predicate) =
 
1678
  let devkindp = self#predicate_of_optional_devkind ?devkind () in
 
1679
  List.filter (fun x -> (devkindp x) && (predicate x)) (nodes#get)
 
1680
 
 
1681
 (* --- can_startup --- *)
 
1682
 
 
1683
 method get_nodes_that_can_startup ?devkind () =
 
1684
  self#get_nodes_such_that ?devkind (fun x -> x#can_startup)
 
1685
 
 
1686
 method get_node_names_that_can_startup ?devkind () =
 
1687
  List.map (fun x -> x#get_name) (self#get_nodes_that_can_startup ?devkind ())
 
1688
 
 
1689
 (* --- can_gracefully_shutdown --- *)
 
1690
 
 
1691
 method get_nodes_that_can_gracefully_shutdown ?devkind () =
 
1692
  self#get_nodes_such_that ?devkind (fun x -> x#can_gracefully_shutdown)
 
1693
 
 
1694
 method get_node_names_that_can_gracefully_shutdown ?devkind () =
 
1695
  List.map (fun x -> x#get_name) (self#get_nodes_that_can_gracefully_shutdown ?devkind ())
 
1696
 
 
1697
 (* --- can_suspend --- *)
 
1698
 
 
1699
 method get_nodes_that_can_suspend ?devkind () =
 
1700
  self#get_nodes_such_that ?devkind (fun x -> x#can_suspend)
 
1701
 
 
1702
 method get_node_names_that_can_suspend ?devkind () =
 
1703
  List.map (fun x -> x#get_name) (self#get_nodes_that_can_suspend ?devkind ())
 
1704
 
 
1705
 (* --- can_resume --- *)
 
1706
 
 
1707
 method get_nodes_that_can_resume ?devkind () =
 
1708
  self#get_nodes_such_that ?devkind (fun x -> x#can_resume)
 
1709
 
 
1710
 method get_node_names_that_can_resume ?devkind () =
 
1711
  List.map (fun x -> x#get_name) (self#get_nodes_that_can_resume ?devkind ())
 
1712
 
 
1713
 (* Including cables (suspend=disconnect, resume=reconnect). The boolean in the result
 
1714
    indicates if the component is suspended (sleeping): *)
1689
1715
 method get_component_names_that_can_suspend_or_resume () : (string * [`Node|`Cable] * bool) list =
1690
1716
  ListExtra.filter_map
1691
 
    (fun (x, node_or_cable) -> 
 
1717
    (fun (x, node_or_cable) ->
1692
1718
       let can_suspend = x#can_suspend in
1693
1719
       let can_resume  = lazy x#can_resume in
1694
 
       if  can_suspend || (Lazy.force can_resume) 
1695
 
         then Some (x#get_name, node_or_cable, (Lazy.force can_resume)) 
 
1720
       if  can_suspend || (Lazy.force can_resume)
 
1721
         then Some (x#get_name, node_or_cable, (Lazy.force can_resume))
1696
1722
         else None)
1697
1723
    self#disjoint_union_of_nodes_and_cables
1698
 
    
1699
 
 method get_nodes_that_can_resume ~devkind () =
1700
 
  ListExtra.filter_map
1701
 
    (fun x -> if (x#devkind = devkind) && x#can_resume then Some x#get_name else None)
1702
 
    nodes#get
1703
1724
 
1704
1725
 (** List of direct cable names in the network *)
1705
1726
 method get_direct_cable_names  =
1736
1757
        (String.concat " , "
1737
1758
        (List.map (fun d->d#get_name^" ("^(d#string_of_devkind)^")") nodes#get))
1738
1759
        with _ -> ""
1739
 
   in Log.printf "Nodes \r\t\t: %s\n" msg;
 
1760
   in Log.printf1 "Nodes \r\t\t: %s\n" msg;
1740
1761
  (* show links *)
1741
1762
   let msg=try
1742
1763
        (String.concat "\n" (List.map (fun c->(c#show "\r\t\t  ")) cables#get))
1743
1764
        with _ -> ""
1744
 
   in Log.printf "Cables \r\t\t: %s\n" msg
 
1765
   in Log.printf1 "Cables \r\t\t: %s\n" msg
1745
1766
 
1746
1767
 
1747
1768
 (** {b Consider cable as Edge.edges} *)