-
Notifications
You must be signed in to change notification settings - Fork 292
[From REQ-477] Cherry-pick addition of iSCSI IQN and multipathing changes #3470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
eb684d8
b9330d0
1c1db16
6fa4c1a
eebcc10
dc39113
437e263
0d2a4df
3bd02c0
f7ebddb
2734c37
41708bd
d6aee58
8e40260
a4a94b3
d194a39
2629e6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
(* | ||
* Copyright (C) Citrix Systems Inc. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published | ||
* by the Free Software Foundation; version 2.1 only. with the special | ||
* exception on linking described in file LICENSE. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
*) | ||
|
||
open OUnit | ||
|
||
let setup_test_oc_watcher () = | ||
let __context, _ = Test_event_common.event_setup_common () in | ||
let calls = ref [] in | ||
let test_rpc call = | ||
match call.Rpc.name, call.Rpc.params with | ||
| "host.set_iscsi_iqn", [_session_id_rpc;host_rpc;value_rpc] -> | ||
let host = API.ref_host_of_rpc host_rpc in | ||
let v = API.string_of_rpc value_rpc in | ||
Db.Host.set_iscsi_iqn ~__context ~self:host ~value:v; | ||
calls := (host,`set_iscsi_iqn v) :: !calls; | ||
Rpc.{success=true; contents=Rpc.String ""} | ||
| "host.set_multipathing", [_session_id_rpc;host_rpc;value_rpc] -> | ||
let host = API.ref_host_of_rpc host_rpc in | ||
let v = API.bool_of_rpc value_rpc in | ||
Db.Host.set_multipathing ~__context ~self:host ~value:v; | ||
calls := (host,`set_multipathing v) :: !calls; | ||
Rpc.{success=true; contents=Rpc.String ""} | ||
| _ -> Mock_rpc.rpc __context call | ||
in | ||
Context.set_test_rpc __context test_rpc; | ||
let host1 = !Xapi_globs.localhost_ref in | ||
let host2 = Test_common.make_host ~__context () in | ||
let watcher = Xapi_host_helpers.Configuration.watch_other_configs ~__context 0.0 in | ||
let token = watcher "" in | ||
(__context, calls, host1, host2, watcher, token) | ||
|
||
let test_host1 () = | ||
(* Test1: update other_config:iscsi_iqn,multipathing on host1, check they appear in the calls list *) | ||
let (__context, calls, host1, host2, watcher, token) = setup_test_oc_watcher () in | ||
Db.Host.set_multipathing ~__context ~self:host1 ~value:false; | ||
|
||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"iscsi_iqn" ~value:"test1"; | ||
let token = watcher token in | ||
assert_equal !calls [host1, `set_iscsi_iqn "test1"]; | ||
|
||
calls := []; | ||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"multipathing" ~value:"true"; | ||
let _token = watcher token in | ||
assert_equal !calls [host1, `set_multipathing true] | ||
|
||
let test_host2 () = | ||
(* Test2: update other_config:iscsi_iqn,multipathing on host2, check they appear in the calls list *) | ||
let (__context, calls, host1, host2, watcher, token) = setup_test_oc_watcher () in | ||
Db.Host.set_multipathing ~__context ~self:host2 ~value:true; | ||
|
||
Db.Host.add_to_other_config ~__context ~self:host2 ~key:"iscsi_iqn" ~value:"test2"; | ||
let token = watcher token in | ||
assert_equal !calls [host2, `set_iscsi_iqn "test2"]; | ||
|
||
calls := []; | ||
Db.Host.add_to_other_config ~__context ~self:host2 ~key:"multipathing" ~value:"false"; | ||
let _token = watcher token in | ||
assert_equal !calls [host2, `set_multipathing false] | ||
|
||
let test_different_keys () = | ||
(* Test3: verify that setting other other-config keys causes no set *) | ||
let (__context, calls, host1, host2, watcher, token) = setup_test_oc_watcher () in | ||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"other_key" ~value:"test1"; | ||
let _token = watcher token in | ||
assert_equal !calls [] | ||
|
||
let test_host_set_iscsi_iqn () = | ||
(* Test3: verify that sequence of DB calls in Host.set_iscsi_iqn don't cause the | ||
watcher to invoke further calls *) | ||
let (__context, calls, host1, host2, watcher, token) = setup_test_oc_watcher () in | ||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"iscsi_iqn" ~value:"test1"; | ||
let token = watcher token in | ||
assert_equal !calls [host1, `set_iscsi_iqn "test1"]; | ||
calls := []; | ||
Db.Host.remove_from_other_config ~__context ~self:host1 ~key:"iscsi_iqn"; | ||
let token = watcher token in | ||
assert_equal !calls []; | ||
Db.Host.set_iscsi_iqn ~__context ~self:host1 ~value:"test2"; | ||
let token = watcher token in | ||
assert_equal !calls []; | ||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"iscsi_iqn" ~value:"test2"; | ||
let _token = watcher token in | ||
assert_equal !calls [] | ||
|
||
let test_host_set_multipathing () = | ||
(* Test3: verify that sequence of DB calls in Host.set_multipathing don't cause the | ||
watcher to invoke further calls *) | ||
let (__context, calls, host1, host2, watcher, token) = setup_test_oc_watcher () in | ||
Db.Host.set_multipathing ~__context ~self:host2 ~value:false; | ||
|
||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"multipathing" ~value:"true"; | ||
let token = watcher token in | ||
assert_equal !calls [host1, `set_multipathing true]; | ||
calls := []; | ||
|
||
Db.Host.remove_from_other_config ~__context ~self:host1 ~key:"multipathing"; | ||
let token = watcher token in | ||
assert_equal !calls []; | ||
Db.Host.set_multipathing ~__context ~self:host1 ~value:false; | ||
let token = watcher token in | ||
assert_equal !calls []; | ||
Db.Host.add_to_other_config ~__context ~self:host1 ~key:"multipathing" ~value:"false"; | ||
let _token = watcher token in | ||
assert_equal !calls [] | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are testing "success" cases, do we have understood failure cases that also would make sense to check? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that setting multipathing should fail (unless the DB itself fails) |
||
|
||
let test = | ||
"other_config_watcher" >::: | ||
[ | ||
"test_host1" >:: test_host1; | ||
"test_host2" >:: test_host2; | ||
"test_different_keys" >:: test_different_keys; | ||
"test_host_set_iscsi_iqn" >:: test_host_set_iscsi_iqn; | ||
"test_host_set_multipathing" >:: test_host_set_multipathing; | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -645,6 +645,8 @@ let create ~__context ~uuid ~name_label ~name_description ~hostname ~address ~ex | |
~virtual_hardware_platform_versions:(if host_is_us then Xapi_globs.host_virtual_hardware_platform_versions else [0L]) | ||
~control_domain:Ref.null | ||
~updates_requiring_reboot:[] | ||
~iscsi_iqn:"" | ||
~multipathing:false | ||
; | ||
(* If the host we're creating is us, make sure its set to live *) | ||
Db.Host_metrics.set_last_updated ~__context ~self:metrics ~value:(Date.of_float (Unix.gettimeofday ())); | ||
|
@@ -1766,3 +1768,31 @@ let mxgpu_vf_setup ~__context ~host = | |
let allocate_resources_for_vm ~__context ~self ~vm ~live = | ||
(* Implemented entirely in Message_forwarding *) | ||
() | ||
|
||
let set_iscsi_iqn ~__context ~host ~value = | ||
if value = "" then raise Api_errors.(Server_error (invalid_value, ["value"; value])); | ||
(* Note, the following sequence is carefully written - see the | ||
other-config watcher thread in xapi_host_helpers.ml *) | ||
Db.Host.remove_from_other_config ~__context ~self:host ~key:"iscsi_iqn"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is out of scope for this PR, and I suggest not to touch it. But, as a remark for the future, we really need a |
||
(* we need to first set the iscsi_iqn field and then the other-config field: | ||
* setting the other-config field triggers and update on the iscsi_iqn | ||
* field if they are different | ||
* | ||
* we want to keep the legacy `other_config:iscsi_iqn` and the new `iscsi_iqn` | ||
* fields in sync: | ||
* when you update the `iscsi_iqn` field we want to update `other_config`, | ||
* but when updating `other_config` we want to update `iscsi_iqn` too. | ||
* we have to be careful not to introduce an infinite loop of updates. | ||
* *) | ||
Db.Host.set_iscsi_iqn ~__context ~self:host ~value; | ||
Db.Host.add_to_other_config ~__context ~self:host ~key:"iscsi_iqn" ~value; | ||
Xapi_host_helpers.Configuration.set_initiator_name value | ||
|
||
let set_multipathing ~__context ~host ~value = | ||
(* Note, the following sequence is carefully written - see the | ||
other-config watcher thread in xapi_host_helpers.ml *) | ||
Db.Host.remove_from_other_config ~__context ~self:host ~key:"multipathing"; | ||
Db.Host.set_multipathing ~__context ~self:host ~value; | ||
Db.Host.add_to_other_config ~__context ~self:host ~key:"multipathing" ~value:(string_of_bool value); | ||
Xapi_host_helpers.Configuration.set_multipathing value | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From now on, when we introduce new tests we should probably use
Alcotest
from the start. No change needed, this can be ported later with the other tests