----- Original Message -----
Hi, all
I am very confused with the two ways of disk monitors: passive monitor
(VIR_DOMAIN_EVENT_ID_IO_ERROR Event of libvirt) and active monitor (thread
calls bolockInfo() function).
These ways have the same goal of extending the LV volume in the block storage
domain.
The node who wants to enlarge its actual disk size would send the extend
message to the SPM by the mailbox of the domain.
Why we choose both the ways?
I think either is OK. The reason is that the two ways would suspend the vm in
the process of extending.
What’s the scene of the passive monitor above? I think that once the active
monitor have existed, the passive monitor event would never occur.
Extending the LV is a process that requires going from the host running the VM to the SPM
and have it enlarge the LV and then refresh the LV locally.
This process takes time and since we do not want the VM to pause for the duration of this
process (several seconds) then we want to do this proactively when we detect that disk
space is running low. Since we cannot set a threshold in qemu we actively monitor the
location of the last write and when free space goes below a certain threshold we
automatically extend the volume.
However, this process is race prone since what we're doing is polling, i.e. there can
be a situation in which the guest is writing a lot and we do not catch this in time. In
such a scenario the disk will run out of space and the guest will hit an ENOSPC error and
pause. In this case, qemu throws an event and we'll immediately catch it (and not
wait for next polling interval) and initiate the extend flow to minimize pause time.
Can someone help me? Thank you
Qi
Appendix:
1)VIR_DOMAIN_EVENT_ID_IO_ERROR Event callback --- à passive monitor
if cif != None:
for ev in (libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
libvirt.VIR_DOMAIN_EVENT_ID_REBOOT,
libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB):
conn.domainEventRegisterAny(None, ev,
__eventCallback, (cif, ev))
def _onAbnormalStop(self, blockDevAlias, err):
……
if err.upper() == 'ENOSPC':
for d in self._devices[vm.DISK_DEVICES]:
if d.alias == blockDevAlias:
……
capacity, alloc, physical = self._dom.blockInfo(d.path, 0)
if physical > (alloc + config.getint('irs',
'volume_utilization_chunk_mb')):
……
self._lvExtend(d.name)
2)create a new thread to sample the statistics in the vm with its running.
--- à active monitor
def _initVmStats(self):
self._vmStats = VmStatsThread(self)
self._vmStats.start()
self._guestEventTime = self._startTime
----------------------------------------------------------------------
def _highWrite(self):
if not self._vm._volumesPrepared:
# Avoid queries from storage during recovery process
return
for vmDrive in self._vm._devices[vm.DISK_DEVICES]:
if vmDrive.blockDev and vmDrive.format == 'cow':
capacity, alloc, physical = \
self._vm._dom.blockInfo(vmDrive.path, 0)
if physical - alloc < self._vm._MIN_DISK_REMAIN:
……
self._vm._onHighWrite(vmDrive.name, alloc)
def _onHighWrite(self, block_dev, offset):
self.log.info('_onHighWrite: write above watermark on %s offset %s',
block_dev, offset)
self._lvExtend(block_dev)
def _lvExtend(self, block_dev, newsize=None):
……
self.cif.irs.sendExtendMsg(d.poolID, volDict, newsize * 2**20,
self._afterLvExtend)
……
_______________________________________________
vdsm-devel mailing list
vdsm-devel(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-devel