From 6263189c05b8692cf5944fea8af3b0e66305c56f Mon Sep 17 00:00:00 2001 From: Guido Trotter <ultrotter@google.com> Date: Fri, 9 Oct 2009 11:52:38 +0100 Subject: [PATCH] Accept shutdown timeout from the user Using the new --timeout option: - gnt-instance shutdown is changed to accept a timeout - the opcode is changed to hold one - the LU is changed to optionally get one - the rpc is changed to carry one - the backend is changed to take it as a parameter rather than hardcoding it in the function Signed-off-by: Guido Trotter <ultrotter@google.com> Reviewed-by: Michael Hanselmann <hansmi@google.com> --- daemons/ganeti-noded | 3 ++- lib/backend.py | 5 +++-- lib/cmdlib.py | 11 ++++++++++- lib/opcodes.py | 2 +- lib/rpc.py | 4 ++-- scripts/gnt-instance | 5 +++-- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded index c75281776..7582597b3 100755 --- a/daemons/ganeti-noded +++ b/daemons/ganeti-noded @@ -449,7 +449,8 @@ class NodeHttpServer(http.server.HttpServer): """ instance = objects.Instance.FromDict(params[0]) - return backend.InstanceShutdown(instance) + timeout = params[1] + return backend.InstanceShutdown(instance, timeout) @staticmethod def perspective_instance_start(params): diff --git a/lib/backend.py b/lib/backend.py index f35e40ff1..ec87aae30 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -960,13 +960,15 @@ def StartInstance(instance): _Fail("Hypervisor error: %s", err, exc=True) -def InstanceShutdown(instance): +def InstanceShutdown(instance, timeout): """Shut an instance down. @note: this functions uses polling with a hardcoded timeout. @type instance: L{objects.Instance} @param instance: the instance object + @type timeout: integer + @param timeout: maximum timeout for soft shutdown @rtype: None """ @@ -974,7 +976,6 @@ def InstanceShutdown(instance): hyper = hypervisor.GetHypervisor(hv_name) running_instances = hyper.ListInstances() iname = instance.name - timeout = constants.DEFAULT_SHUTDOWN_TIMEOUT if iname not in running_instances: logging.info("Instance %s not running, doing nothing", iname) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 0023cac61..a5e25316b 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -3679,6 +3679,13 @@ class LUShutdownInstance(LogicalUnit): _OP_REQP = ["instance_name"] REQ_BGL = False + def CheckArguments(self): + """Check the arguments. + + """ + self.timeout = getattr(self.op, "timeout", + constants.DEFAULT_SHUTDOWN_TIMEOUT) + def ExpandNames(self): self._ExpandAndLockInstance() @@ -3689,6 +3696,7 @@ class LUShutdownInstance(LogicalUnit): """ env = _BuildInstanceHookEnvByObject(self, self.instance) + env["TIMEOUT"] = self.timeout nl = [self.cfg.GetMasterNode()] + list(self.instance.all_nodes) return env, nl, nl @@ -3709,8 +3717,9 @@ class LUShutdownInstance(LogicalUnit): """ instance = self.instance node_current = instance.primary_node + timeout = self.timeout self.cfg.MarkInstanceDown(instance.name) - result = self.rpc.call_instance_shutdown(node_current, instance) + result = self.rpc.call_instance_shutdown(node_current, instance, timeout) msg = result.fail_msg if msg: self.proc.LogWarning("Could not shutdown instance: %s" % msg) diff --git a/lib/opcodes.py b/lib/opcodes.py index 929c62fee..5ff1eb1ff 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -489,7 +489,7 @@ class OpShutdownInstance(OpCode): """Shutdown an instance.""" OP_ID = "OP_INSTANCE_SHUTDOWN" OP_DSC_FIELD = "instance_name" - __slots__ = OpCode.__slots__ + ["instance_name"] + __slots__ = OpCode.__slots__ + ["instance_name", "timeout"] class OpRebootInstance(OpCode): diff --git a/lib/rpc.py b/lib/rpc.py index ea132a9b3..227e355cf 100644 --- a/lib/rpc.py +++ b/lib/rpc.py @@ -467,14 +467,14 @@ class RpcRunner(object): idict = self._InstDict(instance, hvp=hvp, bep=bep) return self._SingleNodeCall(node, "instance_start", [idict]) - def call_instance_shutdown(self, node, instance): + def call_instance_shutdown(self, node, instance, timeout): """Stops an instance. This is a single-node call. """ return self._SingleNodeCall(node, "instance_shutdown", - [self._InstDict(instance)]) + [self._InstDict(instance), timeout]) def call_migration_info(self, node, instance): """Gather the information necessary to prepare an instance migration. diff --git a/scripts/gnt-instance b/scripts/gnt-instance index 194e69771..8d5351384 100755 --- a/scripts/gnt-instance +++ b/scripts/gnt-instance @@ -727,7 +727,8 @@ def _ShutdownInstance(name, opts): @return: the opcode needed for the operation """ - return opcodes.OpShutdownInstance(instance_name=name) + return opcodes.OpShutdownInstance(instance_name=name, + timeout=opts.timeout) def ReplaceDisks(opts, args): @@ -1346,7 +1347,7 @@ commands = { 'shutdown': ( GenericManyOps("shutdown", _ShutdownInstance), [ArgInstance()], [m_node_opt, m_pri_node_opt, m_sec_node_opt, m_clust_opt, - m_inst_opt, m_force_multi, SUBMIT_OPT], + m_inst_opt, m_force_multi, TIMEOUT_OPT, SUBMIT_OPT], "<instance>", "Stops an instance"), 'startup': ( GenericManyOps("startup", _StartupInstance), [ArgInstance()], -- GitLab