Skip to content

Commit 1f1c9aa

Browse files
committed
Merge pull request #88 from xapi-project/more-tunnelling
Fix a race with lvchange -an
2 parents b9b5141 + 51d45ad commit 1f1c9aa

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

test/test.ml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,40 @@ let lvcreate_l =
6969
assert_lv_exists ~expected_size_in_extents:1L "test";
7070
xenvm [ "lvremove"; vg ^ "/test" ] |> ignore_string
7171

72+
let file_exists filename =
73+
try
74+
Unix.LargeFile.stat filename |> ignore;
75+
true
76+
with Unix.Unix_error(Unix.ENOENT, _, _) -> false
77+
78+
let dm_exists name = match Devmapper.stat name with
79+
| None -> false
80+
| Some _ -> true
81+
82+
let dev_path_of name = "/dev/" ^ vg ^ "/" ^ name
83+
let mapper_path_of name = "/dev/mapper/" ^ vg ^ "-" ^ name
84+
85+
let lvchange_n =
86+
"lvchange -an <device>: check that we can deactivate a volume" >::
87+
fun () ->
88+
xenvm [ "lvcreate"; "-n"; "test"; "-L"; "3"; vg ] |> ignore_string;
89+
assert_lv_exists ~expected_size_in_extents:1L "test";
90+
let vg_metadata, lv_metadata = Lwt_main.run (Client.get_lv "test") in
91+
let name = Mapper.name_of vg_metadata lv_metadata in
92+
xenvm [ "lvchange"; "-ay"; "/dev/" ^ vg ^ "/test" ] |> ignore_string;
93+
assert_equal ~printer:string_of_bool true (file_exists (dev_path_of "test"));
94+
assert_equal ~printer:string_of_bool true (file_exists (mapper_path_of "test"));
95+
assert_equal ~printer:string_of_bool true (dm_exists name);
96+
xenvm [ "lvchange"; "-an"; "/dev/" ^ vg ^ "/test" ] |> ignore_string;
97+
assert_equal ~printer:string_of_bool false (file_exists (dev_path_of"test"));
98+
assert_equal ~printer:string_of_bool false (file_exists (mapper_path_of"test"));
99+
assert_equal ~printer:string_of_bool false (dm_exists name);
100+
xenvm [ "lvremove"; vg ^ "/test" ] |> ignore_string
101+
72102
let xenvmd_suite = "Commands which require xenvmd" >::: [
73103
lvcreate_L;
74104
lvcreate_l;
105+
lvchange_n;
75106
]
76107

77108
let _ =

xenvm/lvchange.ml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,23 @@ let lvchange_activate copts vg_name lv_name physical_device =
4343
let deactivate vg lv =
4444
let open Xenvm_common in
4545
let name = Mapper.name_of vg lv in
46-
let all = Devmapper.ls () in
47-
if List.mem name all
48-
then Devmapper.remove name;
46+
(* This can fail with an EBUSY *)
47+
let rec retry n =
48+
let all = Devmapper.ls () in
49+
let result =
50+
try
51+
if List.mem name all then Devmapper.remove name;
52+
`Ok ()
53+
with e ->
54+
Printf.fprintf stderr "Caught %s while removing dm device %s\n%!" (Printexc.to_string e) name;
55+
if n = 0 then raise e;
56+
`Retry in
57+
match result with
58+
| `Ok () -> ()
59+
| `Retry ->
60+
Unix.sleep 1;
61+
retry (n - 1) in
62+
retry 30;
4963
(* Delete the device node *)
5064
let path = dev_path_of vg.Lvm.Vg.name lv.Lvm.Lv.name in
5165
Lwt.catch (fun () -> Lwt_unix.unlink path) (fun _ -> Lwt.return ()) >>= fun () ->

0 commit comments

Comments
 (0)