Skip to content

Commit 2b6bac9

Browse files
Tim SmithTimSmithCtx
authored andcommitted
CP-49720 De-duplicate GC kick optimisation
Both LVHDSR and FileSR in their _kickGC() method would check to see if a GC was already in progress and avoid starting one if so. This code was duplicated and can be moved into the cleanup.start_gc() method. Signed-off-by: Tim Smith <tim.smith@cloud.com>
1 parent 303baa2 commit 2b6bac9

File tree

4 files changed

+28
-49
lines changed

4 files changed

+28
-49
lines changed

drivers/FileSR.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import time
3232
import glob
3333
from uuid import uuid4
34-
from lock import Lock, LOCK_TYPE_GC_RUNNING
34+
from lock import Lock
3535
import xmlrpc.client
3636
import XenAPI # pylint: disable=import-error
3737
from constants import CBTLOG_TAG
@@ -378,31 +378,8 @@ def _process_replay(self, data):
378378
index += 1
379379

380380
def _kickGC(self):
381-
# don't bother if an instance already running (this is just an
382-
# optimization to reduce the overhead of forking a new process if we
383-
# don't have to, but the process will check the lock anyways)
384-
lockRunning = Lock(LOCK_TYPE_GC_RUNNING, self.uuid)
385-
if not lockRunning.acquireNoblock():
386-
if cleanup.should_preempt(self.session, self.uuid):
387-
util.SMlog("Aborting currently-running coalesce of garbage VDI")
388-
try:
389-
if not cleanup.abort(self.uuid, soft=True):
390-
util.SMlog("The GC has already been scheduled to "
391-
"re-start")
392-
except util.CommandException as e:
393-
if e.code != errno.ETIMEDOUT:
394-
raise
395-
util.SMlog('failed to abort the GC')
396-
finally:
397-
return
398-
else:
399-
util.SMlog("A GC instance already running, not kicking")
400-
return
401-
else:
402-
lockRunning.release()
403-
404381
util.SMlog("Kicking GC")
405-
cleanup.start_gc(self.uuid)
382+
cleanup.start_gc(self.session, self.uuid)
406383

407384
def _isbind(self):
408385
# os.path.ismount can't deal with bind mount

drivers/LVHDSR.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import cleanup
3737
import blktap2
3838
from journaler import Journaler
39-
from lock import Lock, LOCK_TYPE_GC_RUNNING
39+
from lock import Lock
4040
from refcounter import RefCounter
4141
from ipc import IPCFlag
4242
from lvmanager import LVActivator
@@ -1289,29 +1289,8 @@ def _prepareTestMode(self):
12891289
util.SMlog("Setting env %s" % self.ENV_VAR_VHD_TEST[self.testMode])
12901290

12911291
def _kickGC(self):
1292-
# don't bother if an instance already running (this is just an
1293-
# optimization to reduce the overhead of forking a new process if we
1294-
# don't have to, but the process will check the lock anyways)
1295-
lockRunning = Lock(LOCK_TYPE_GC_RUNNING, self.uuid)
1296-
if not lockRunning.acquireNoblock():
1297-
if cleanup.should_preempt(self.session, self.uuid):
1298-
util.SMlog("Aborting currently-running coalesce of garbage VDI")
1299-
try:
1300-
if not cleanup.abort(self.uuid, soft=True):
1301-
util.SMlog("The GC has already been scheduled to "
1302-
"re-start")
1303-
except util.CommandException as e:
1304-
if e.code != errno.ETIMEDOUT:
1305-
raise
1306-
util.SMlog('failed to abort the GC')
1307-
else:
1308-
util.SMlog("A GC instance already running, not kicking")
1309-
return
1310-
else:
1311-
lockRunning.release()
1312-
13131292
util.SMlog("Kicking GC")
1314-
cleanup.start_gc(self.uuid)
1293+
cleanup.start_gc(self.session, self.uuid)
13151294

13161295
def ensureCBTSpace(self):
13171296
# Ensure we have space for at least one LV

drivers/cleanup.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3205,7 +3205,27 @@ def gc(session, srUuid, inBackground, dryRun=False):
32053205
_gc(session, srUuid, dryRun, immediate=True)
32063206

32073207

3208-
def start_gc(sr_uuid):
3208+
def start_gc(session, sr_uuid):
3209+
# don't bother if an instance already running (this is just an
3210+
# optimization to reduce the overhead of forking a new process if we
3211+
# don't have to, but the process will check the lock anyways)
3212+
lockRunning = lock.Lock(lock.LOCK_TYPE_GC_RUNNING, sr_uuid)
3213+
if not lockRunning.acquireNoblock():
3214+
if should_preempt(session, sr_uuid):
3215+
util.SMlog("Aborting currently-running coalesce of garbage VDI")
3216+
try:
3217+
if not abort(sr_uuid, soft=True):
3218+
util.SMlog("The GC has already been scheduled to re-start")
3219+
except util.CommandException as e:
3220+
if e.code != errno.ETIMEDOUT:
3221+
raise
3222+
util.SMlog('failed to abort the GC')
3223+
else:
3224+
util.SMlog("A GC instance already running, not kicking")
3225+
return
3226+
else:
3227+
lockRunning.release()
3228+
32093229
util.SMlog(f"Starting GC file is {__file__}")
32103230
subprocess.run([__file__, '-b', '-u', sr_uuid, '-g'],
32113231
stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)

tests/test_FileSR.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ def setUp(self):
450450
lock_patcher = mock.patch('FileSR.Lock')
451451
self.mock_lock = lock_patcher.start()
452452

453+
lock_patcher_cleanup = mock.patch('cleanup.lock.Lock')
454+
self.mock_lock_cleanup = lock_patcher_cleanup.start()
455+
453456
xapi_patcher = mock.patch('SR.XenAPI')
454457
self.mock_xapi = xapi_patcher.start()
455458
self.mock_session = mock.MagicMock()

0 commit comments

Comments
 (0)