Commit 7f75a9fb authored by Jose A. Lopes's avatar Jose A. Lopes

Modify how the KVM daemon is started/stopped

This patch modifies how the KVM daemon is started/stopped.  After this
patch, the KVM daemon is always started by default, as it will
terminate itself if necessary, and it is restarted by the watcher.

Also, changes to user shutdown and vm capable attributes will cause
the KVM daemon instances on the corresponding nodes to be
started/stopped accordingly.  This is achieved through the helper
function 'EnsureKvmdOnNodes'.
Signed-off-by: default avatarJose A. Lopes <>
Reviewed-by: default avatarHrvoje Ribicic <>
parent 173e4632
......@@ -32,6 +32,7 @@ DAEMONS=(
_confd_enabled() {
......@@ -557,6 +557,7 @@ def LeaveCluster(modify_ssh_setup):
logging.exception("Error while removing cluster secrets")
# Raise a custom exception (handled in ganeti-noded)
raise errors.QuitGanetiException(True, "Shutdown scheduled")
......@@ -56,7 +56,7 @@ from ganeti.cmdlib.common import ShareAll, RunPostHook, \
CheckOSParams, CheckHVParams, AdjustCandidatePool, CheckNodePVs, \
ComputeIPolicyInstanceViolation, AnnotateDiskParams, SupportsOob, \
CheckIpolicyVsDiskTemplates, CheckDiskAccessModeValidity, \
CheckDiskAccessModeConsistency, CreateNewClientCert
CheckDiskAccessModeConsistency, CreateNewClientCert, EnsureKvmdOnNodes
import ganeti.masterd.instance
......@@ -1332,6 +1332,8 @@ class LUClusterSetParams(LogicalUnit):
ensure_kvmd = False
if self.op.hvparams:
self.cluster.hvparams = self.new_hvparams
if self.op.os_hvp:
......@@ -1339,6 +1341,7 @@ class LUClusterSetParams(LogicalUnit):
if self.op.enabled_hypervisors is not None:
self.cluster.hvparams = self.new_hvparams
self.cluster.enabled_hypervisors = self.op.enabled_hypervisors
ensure_kvmd = True
if self.op.beparams:
self.cluster.beparams[constants.PP_DEFAULT] = self.new_beparams
if self.op.nicparams:
......@@ -1397,8 +1400,10 @@ class LUClusterSetParams(LogicalUnit):
if self.op.use_external_mip_script is not None:
self.cluster.use_external_mip_script = self.op.use_external_mip_script
if self.op.enabled_user_shutdown is not None:
if self.op.enabled_user_shutdown is not None and \
self.cluster.enabled_user_shutdown != self.op.enabled_user_shutdown:
self.cluster.enabled_user_shutdown = self.op.enabled_user_shutdown
ensure_kvmd = True
def helper_os(aname, mods, desc):
desc += " OS list"
......@@ -1463,6 +1468,13 @@ class LUClusterSetParams(LogicalUnit):
result.Warn("Could not re-enable the master ip on the master,"
" please restart manually", self.LogWarning)
# Even though 'self.op.enabled_user_shutdown' is being tested
# above, the RPCs can only be done after 'self.cfg.Update' because
# this will update the cluster object and sync 'Ssconf', and kvmd
# uses 'Ssconf'.
if ensure_kvmd:
EnsureKvmdOnNodes(self, feedback_fn)
class LUClusterVerify(NoHooksLU):
"""Submits all jobs necessary to verify the cluster.
......@@ -1279,3 +1279,65 @@ def CreateNewClientCert(lu, node_uuid, filename=None):
((crypto_type, new_digest), ) = result.payload
assert crypto_type == constants.CRYPTO_TYPE_SSL_DIGEST
return new_digest
def EnsureKvmdOnNodes(lu, feedback_fn, nodes=None):
"""Ensure KVM daemon is running on nodes with KVM instances.
If user shutdown is enabled in the cluster:
- The KVM daemon will be started on VM capable nodes containing
KVM instances.
- The KVM daemon will be stopped on non VM capable nodes.
If user shutdown is disabled in the cluster:
- The KVM daemon will be stopped on all nodes
Issues a warning for each failed RPC call.
@type lu: L{LogicalUnit}
@param lu: logical unit on whose behalf we execute
@type feedback_fn: callable
@param feedback_fn: feedback function
@type nodes: list of string
@param nodes: if supplied, it overrides the node uuids to start/stop;
this is used mainly for optimization
cluster = lu.cfg.GetClusterInfo()
# Either use the passed nodes or consider all cluster nodes
if nodes is not None:
node_uuids = set(nodes)
node_uuids = lu.cfg.GetNodeList()
# Determine in which nodes should the KVM daemon be started/stopped
if constants.HT_KVM in cluster.enabled_hypervisors and \
start_nodes = []
stop_nodes = []
for node_uuid in node_uuids:
if lu.cfg.GetNodeInfo(node_uuid).vm_capable:
start_nodes = []
stop_nodes = node_uuids
# Start KVM where necessary
if start_nodes:
results = lu.rpc.call_node_ensure_daemon(start_nodes, constants.KVMD, True)
for node_uuid in start_nodes:
results[node_uuid].Warn("Failed to start KVM daemon in node '%s'" %
node_uuid, feedback_fn)
# Stop KVM where necessary
if stop_nodes:
results = lu.rpc.call_node_ensure_daemon(stop_nodes, constants.KVMD, False)
for node_uuid in stop_nodes:
results[node_uuid].Warn("Failed to stop KVM daemon in node '%s'" %
node_uuid, feedback_fn)
......@@ -43,7 +43,8 @@ from ganeti.cmdlib.common import CheckParamsNotGlobal, \
AdjustCandidatePool, CheckIAllocatorOrNode, LoadNodeEvacResult, \
GetWantedNodes, MapInstanceLvsToNodes, RunPostHook, \
FindFaultyInstanceDisks, CheckStorageTypeEnabled, CreateNewClientCert, \
AddNodeCertToCandidateCerts, RemoveNodeCertFromCandidateCerts
AddNodeCertToCandidateCerts, RemoveNodeCertFromCandidateCerts, \
def _DecideSelfPromotion(lu, exceptions=None):
......@@ -432,6 +433,8 @@ class LUNodeAdd(LogicalUnit):
self.cfg.Update(cluster, feedback_fn)
EnsureKvmdOnNodes(self, feedback_fn, nodes=[self.new_node.uuid])
class LUNodeSetParams(LogicalUnit):
"""Modifies the parameters of a node.
......@@ -808,6 +811,8 @@ class LUNodeSetParams(LogicalUnit):
if [self.old_role, self.new_role].count(self._ROLE_CANDIDATE) == 1:
EnsureKvmdOnNodes(self, feedback_fn, nodes=[node.uuid])
return result
......@@ -100,6 +100,8 @@ def StartNodeDaemons():
# start mond as well: all nodes need monitoring
if constants.ENABLE_MOND:
# start kvmd, which will quit if not needed to run
def RunWatcherHooks():
......@@ -36,8 +36,8 @@ if ! grep -q '^ENABLE_MOND = ' lib/; then
err "Please update $0, mond enable feature is missing"
DAEMONS_LIST="noded masterd rapi luxid"
STOPDAEMONS_LIST="luxid rapi masterd noded"
DAEMONS_LIST="noded masterd rapi luxid kvmd"
STOPDAEMONS_LIST="kvmd luxid rapi masterd noded"
if grep -q '^ENABLE_CONFD = True' lib/; then
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment