This flag tracks if the disks of an instace are supposed to be active.
That's the case when an instance is running or when its disks got
activated explicitly (and in a couple of other cases).
It will be used by watcher to re-activate disks after a node reboot.
Signed-off-by: Thomas Thrainer <thomasth@google.com>
Reviewed-by: Helga Velroyen <helgav@google.com>
for disk in instance.disks:
self.cfg.SetDiskID(disk, src_node)
- activate_disks = (instance.admin_state != constants.ADMINST_UP)
+ activate_disks = not instance.disks_active
if activate_disks:
# Activate the instance disks if we'exporting a stopped instance
# node here
snode = node_image[nname]
bad_snode = snode.ghost or snode.offline
- _ErrorIf(inst_config.admin_state == constants.ADMINST_UP and
+ _ErrorIf(inst_config.disks_active and
not success and not bad_snode,
constants.CV_EINSTANCEFAULTYDISK, instance,
"couldn't retrieve status for disk/%s on %s: %s",
idx, nname, bdev_status)
- _ErrorIf((inst_config.admin_state == constants.ADMINST_UP and
+ _ErrorIf((inst_config.disks_active and
success and bdev_status.ldisk_status == constants.LDS_FAULTY),
constants.CV_EINSTANCEFAULTYDISK, instance,
"disk/%s on %s is faulty", idx, nname)
node_drbd[minor] = (instance, False)
else:
instance = instanceinfo[instance]
- node_drbd[minor] = (instance.name,
- instance.admin_state == constants.ADMINST_UP)
+ node_drbd[minor] = (instance.name, instance.disks_active)
# and now check them
used_minors = nresult.get(constants.NV_DRBDLIST, [])
res_missing = {}
nv_dict = MapInstanceDisksToNodes(
- [inst for inst in self.instances.values()
- if inst.admin_state == constants.ADMINST_UP])
+ [inst for inst in self.instances.values() if inst.disks_active])
if nv_dict:
nodes = utils.NiceSort(set(self.owned_locks(locking.LEVEL_NODE)) &
primary_node=pnode_name,
nics=self.nics, disks=disks,
disk_template=self.op.disk_template,
+ disks_active=False,
admin_state=constants.ADMINST_DOWN,
network_port=network_port,
beparams=self.op.beparams,
raise errors.OpExecError("There are some degraded disks for"
" this instance")
+ # instance disks are now active
+ iobj.disks_active = True
+
# Release all node resource locks
ReleaseLocks(self, locking.LEVEL_NODE_RES)
source_node = instance.primary_node
target_node = self.target_node
- if instance.admin_state == constants.ADMINST_UP:
+ if instance.disks_active:
self.feedback_fn("* checking disk consistency between source and target")
for (idx, dev) in enumerate(instance.disks):
# for drbd, these are drbd over lvm
ignored.
"""
+ lu.cfg.MarkInstanceDisksInactive(instance.name)
all_result = True
disks = ExpandCheckDisks(instance, disks)
# into any other network-connected state (Connected, SyncTarget,
# SyncSource, etc.)
+ # mark instance disks as active before doing actual work, so watcher does
+ # not try to shut them down erroneously
+ lu.cfg.MarkInstanceDisksActive(iname)
+
# 1st pass, assemble on all nodes in secondary mode
for idx, inst_disk in enumerate(disks):
for node, node_disk in inst_disk.ComputeNodeTree(instance.primary_node):
for disk in disks:
lu.cfg.SetDiskID(disk, instance.primary_node)
+ if not disks_ok:
+ lu.cfg.MarkInstanceDisksInactive(iname)
+
return disks_ok, device_info
if disk_abort:
self.LogWarning("Disk syncing has not returned a good status; check"
" the instance")
- if instance.admin_state != constants.ADMINST_UP:
+ if not instance.disks_active:
_SafeShutdownInstanceDisks(self, instance, disks=[disk])
- elif instance.admin_state != constants.ADMINST_UP:
+ elif not instance.disks_active:
self.LogWarning("Not shutting down the disk even if the instance is"
" not supposed to be running because no wait for"
" sync mode was requested")
if self.op.wait_for_sync:
if not WaitForSync(self, self.instance):
+ self.cfg.MarkInstanceDisksInactive(self.instance.name)
raise errors.OpExecError("Some disks of the instance are degraded!")
return disks_info
feedback_fn("Current seconary node: %s" %
utils.CommaJoin(self.instance.secondary_nodes))
- activate_disks = (self.instance.admin_state != constants.ADMINST_UP)
+ activate_disks = not self.instance.disks_active
# Activate the instance disks if we're replacing them on a down instance
if activate_disks:
"""
# Check whether any instance on this node has faulty disks
for inst in _GetNodeInstances(self.cfg, self.op.node_name):
- if inst.admin_state != constants.ADMINST_UP:
+ if not inst.disks_active:
continue
check_nodes = set(inst.all_nodes)
check_nodes.discard(self.op.node_name)
raise errors.ConfigurationError("Cannot add '%s': UUID %s already"
" in use" % (item.name, item.uuid))
- def _SetInstanceStatus(self, instance_name, status):
+ def _SetInstanceStatus(self, instance_name, status, disks_active):
"""Set the instance's status to a given value.
"""
- assert status in constants.ADMINST_ALL, \
- "Invalid status '%s' passed to SetInstanceStatus" % (status,)
-
if instance_name not in self._config_data.instances:
raise errors.ConfigurationError("Unknown instance '%s'" %
instance_name)
instance = self._config_data.instances[instance_name]
- if instance.admin_state != status:
+
+ if status is None:
+ status = instance.admin_state
+ if disks_active is None:
+ disks_active = instance.disks_active
+
+ assert status in constants.ADMINST_ALL, \
+ "Invalid status '%s' passed to SetInstanceStatus" % (status,)
+
+ if instance.admin_state != status or \
+ instance.disks_active != disks_active:
instance.admin_state = status
+ instance.disks_active = disks_active
instance.serial_no += 1
instance.mtime = time.time()
self._WriteConfig()
def MarkInstanceUp(self, instance_name):
"""Mark the instance status to up in the config.
+ This also sets the instance disks active flag.
+
"""
- self._SetInstanceStatus(instance_name, constants.ADMINST_UP)
+ self._SetInstanceStatus(instance_name, constants.ADMINST_UP, True)
@locking.ssynchronized(_config_lock)
def MarkInstanceOffline(self, instance_name):
"""Mark the instance status to down in the config.
+ This also clears the instance disks active flag.
+
"""
- self._SetInstanceStatus(instance_name, constants.ADMINST_OFFLINE)
+ self._SetInstanceStatus(instance_name, constants.ADMINST_OFFLINE, False)
@locking.ssynchronized(_config_lock)
def RemoveInstance(self, instance_name):
def MarkInstanceDown(self, instance_name):
"""Mark the status of an instance to down in the configuration.
+ This does not touch the instance disks active flag, as shut down instances
+ can still have active disks.
+
+ """
+ self._SetInstanceStatus(instance_name, constants.ADMINST_DOWN, None)
+
+ @locking.ssynchronized(_config_lock)
+ def MarkInstanceDisksActive(self, instance_name):
+ """Mark the status of instance disks active.
+
+ """
+ self._SetInstanceStatus(instance_name, None, True)
+
+ @locking.ssynchronized(_config_lock)
+ def MarkInstanceDisksInactive(self, instance_name):
+ """Mark the status of instance disks inactive.
+
"""
- self._SetInstanceStatus(instance_name, constants.ADMINST_DOWN)
+ self._SetInstanceStatus(instance_name, None, False)
def _UnlockedGetInstanceList(self):
"""Get the list of instances.
constants.IDISK_MODE: dsk.mode}
for dsk in iinfo.disks],
"disk_template": iinfo.disk_template,
+ "disks_active": iinfo.disks_active,
"hypervisor": iinfo.hypervisor,
}
pir["disk_space_total"] = gmi.ComputeDiskSize(iinfo.disk_template,
"nics",
"disks",
"disk_template",
+ "disks_active",
"network_port",
"serial_no",
] + _TIMESTAMPS + _UUID
, simpleField "nics" [t| [PartialNic] |]
, simpleField "disks" [t| [Disk] |]
, simpleField "disk_template" [t| DiskTemplate |]
+ , simpleField "disks_active" [t| Bool |]
, optionalField $ simpleField "network_port" [t| Int |]
]
++ timeStampFields
<*> vectorOf 5 genDisk
-- disk template
<*> arbitrary
+ -- disks active
+ <*> arbitrary
-- network port
<*> arbitrary
-- ts