# HG changeset patch # User Magnus Therning # Date 1282906370 -3600 # Node ID 5c7ac6e21b287a403b5295fe09a5ebfe80afd863 # Parent 41abc8ba2593d7d4b09838554bc3b577b55ed97b Changing the emergency mode to be encoded in a single variable (option type) rather than in two. Not for merging just yet, please comment on the interface first. Should this go into a separate module instead maybe? diff -r 41abc8ba2593 -r 5c7ac6e21b28 ocaml/xapi/api_server.ml --- a/ocaml/xapi/api_server.ml +++ b/ocaml/xapi/api_server.ml @@ -112,8 +112,8 @@ (* We now have the body string, the xml and the call name, and can also tell *) (* if we're a master or slave and whether the call came in on the unix domain socket or the tcp socket *) (* If we're a slave, and the call is from the unix domain socket, and the call *isn't* session.login_with_password, then forward *) - if !Xapi_globs.slave_emergency_mode && (not (List.mem call emergency_call_list)) - then raise !Xapi_globs.emergency_mode_error; + if Xapi_globs.in_emergency_mode () && (not (List.mem call emergency_call_list)) + then raise (Xapi_globs.get_emergency_mode ()); if ((not (Pool_role.is_master ())) && (Context.is_unix_socket fd) && (not (List.mem call whitelist))) then forward req body xml diff -r 41abc8ba2593 -r 5c7ac6e21b28 ocaml/xapi/cli_operations.ml --- a/ocaml/xapi/cli_operations.ml +++ b/ocaml/xapi/cli_operations.ml @@ -3552,7 +3552,7 @@ in let doit task_id = let url = Printf.sprintf "%s&task_id=%s" url (Ref.string_of task_id) in - if not (!Xapi_globs.slave_emergency_mode) then + if not (Xapi_globs.in_emergency_mode ()) then begin if n > 1 then raise Not_found diff -r 41abc8ba2593 -r 5c7ac6e21b28 ocaml/xapi/xapi.ml --- a/ocaml/xapi/xapi.ml +++ b/ocaml/xapi/xapi.ml @@ -452,7 +452,7 @@ (* Called if we cannot contact master at init time *) let server_run_in_emergency_mode () = info "Cannot contact master: running in slave emergency mode"; - Xapi_globs.slave_emergency_mode := true; + Xapi_globs.emergency_mode_error := Some (Api_errors.Server_error (Api_errors.host_still_booting, [])); (* signal the init script that it should succeed even though we're bust *) Helpers.touch_file !Xapi_globs.ready_file; @@ -822,7 +822,7 @@ | Pool_role.Slave _ -> info "Running in 'Pool Slave' mode"; (* Set emergency mode until we actually talk to the master *) - Xapi_globs.slave_emergency_mode := true; + Xapi_globs.emergency_mode_error := Some (Api_errors.Server_error (Api_errors.host_still_booting, [])); (* signal the init script that it should succeed even though we're bust *) Helpers.touch_file !Xapi_globs.ready_file; @@ -845,7 +845,7 @@ end; done; debug "Startup successful"; - Xapi_globs.slave_emergency_mode := false; + Xapi_globs.emergency_mode_error := None; Master_connection.connection_timeout := initial_connection_timeout; begin diff -r 41abc8ba2593 -r 5c7ac6e21b28 ocaml/xapi/xapi_globs.ml --- a/ocaml/xapi/xapi_globs.ml +++ b/ocaml/xapi/xapi_globs.ml @@ -76,12 +76,15 @@ (* the time taken to wait before restarting after restoring db backup *) let db_restore_fuse_time = 30 -(* if a slave in emergency "cannot see master mode" then this flag is set *) -let slave_emergency_mode = ref false - -(** Whenever in emergency mode we stash an error here so the user can determine what's wrong - without trawling through logfiles *) -let emergency_mode_error = ref (Api_errors.Server_error(Api_errors.host_still_booting, [])) +(** If a slave is in emergency mode then this is set to an error, so the user can determine what's wrong without trawling through logfiles *) +let emergency_mode_error = ref (Some (Api_errors.Server_error (Api_errors.host_still_booting, []))) +(** Check whether emergency mode is turned on *) +let in_emergency_mode () = match !emergency_mode_error with + | Some _ -> true + | None -> false +(** Get the current emergency mode error. Deliberately partial function!! *) +let get_emergency_mode () = match !emergency_mode_error with + | Some e -> e (* Interval between host heartbeats *) let host_heartbeat_interval = 30.0 diff -r 41abc8ba2593 -r 5c7ac6e21b28 ocaml/xapi/xapi_ha.ml --- a/ocaml/xapi/xapi_ha.ml +++ b/ocaml/xapi/xapi_ha.ml @@ -788,20 +788,17 @@ raise e end; info "Assuming HA is still enabled on the Pool and that our storage system has failed: will retry in 10s"; - Xapi_globs.slave_emergency_mode := true; - Xapi_globs.emergency_mode_error := Api_errors.Server_error(Api_errors.ha_host_cannot_access_statefile, []); + Xapi_globs.emergency_mode_error := Some (Api_errors.Server_error(Api_errors.ha_host_cannot_access_statefile, [])); Helpers.touch_file !Xapi_globs.ready_file; Thread.delay 10.; | Xha_error errno -> error "ha_start_daemon failed with unexpected error %s: will retry in 10s" (Xha_errno.to_string errno); - Xapi_globs.slave_emergency_mode := true; - Xapi_globs.emergency_mode_error := Api_errors.Server_error(Api_errors.ha_heartbeat_daemon_startup_failed, []); + Xapi_globs.emergency_mode_error := Some (Api_errors.Server_error(Api_errors.ha_heartbeat_daemon_startup_failed, [])); Helpers.touch_file !Xapi_globs.ready_file; Thread.delay 10.; | e -> error "ha_start_daemon failed with unexpected exception: %s -- retrying in 10s" (ExnHelper.string_of_exn e); - Xapi_globs.slave_emergency_mode := true; - Xapi_globs.emergency_mode_error := Api_errors.Server_error(Api_errors.ha_heartbeat_daemon_startup_failed, []); + Xapi_globs.emergency_mode_error := Some (Api_errors.Server_error(Api_errors.ha_heartbeat_daemon_startup_failed, [])); Helpers.touch_file !Xapi_globs.ready_file; Thread.delay 10.; done; diff -r 41abc8ba2593 -r 5c7ac6e21b28 ocaml/xapi/xapi_host.ml --- a/ocaml/xapi/xapi_host.ml +++ b/ocaml/xapi/xapi_host.ml @@ -26,12 +26,12 @@ let host_bugreport_upload = "/opt/xensource/libexec/host-bugreport-upload" -let set_emergency_mode_error code params = Xapi_globs.emergency_mode_error := Api_errors.Server_error(code, params) +let set_emergency_mode_error code params = Xapi_globs.emergency_mode_error := Some (Api_errors.Server_error(code, params)) let local_assert_healthy ~__context = match Pool_role.get_role () with | Pool_role.Master -> () - | Pool_role.Broken -> raise !Xapi_globs.emergency_mode_error - | Pool_role.Slave _ -> if !Xapi_globs.slave_emergency_mode then raise !Xapi_globs.emergency_mode_error + | Pool_role.Broken -> raise (Xapi_globs.get_emergency_mode ()) + | Pool_role.Slave _ -> if Xapi_globs.in_emergency_mode () then raise (Xapi_globs.get_emergency_mode ()) let set_license_params ~__context ~self ~value = Db.Host.set_license_params ~__context ~self ~value; @@ -781,7 +781,7 @@ let local_management_reconfigure ~__context ~interface = (* Only let this one through if we are in emergency mode, otherwise use Host.management_reconfigure *) - if not !Xapi_globs.slave_emergency_mode + if not (Xapi_globs.in_emergency_mode ()) then raise (Api_errors.Server_error (Api_errors.pool_not_in_emergency_mode, [])); change_management_interface ~__context interface @@ -875,8 +875,7 @@ Db.Host.set_hostname ~__context ~self:host ~value:hostname ) -let is_in_emergency_mode ~__context = - !Xapi_globs.slave_emergency_mode +let is_in_emergency_mode ~__context = Xapi_globs.in_emergency_mode () let compute_free_memory ~__context ~host = (*** XXX: Use a more appropriate free memory calculation here. *)