Merge "Allow aggregating disk rescan requests"

This commit is contained in:
Jenkins 2017-08-08 07:44:57 +00:00 committed by Gerrit Code Review
commit 742c6d1bbb
2 changed files with 42 additions and 1 deletions

View File

@ -179,6 +179,21 @@ class DiskUtilsTestCase(test_base.OsWinBaseTestCase):
mock_rescan.assert_called_once_with()
@mock.patch.object(diskutils, '_RESCAN_LOCK')
@mock.patch.object(diskutils.DiskUtils, '_rescan_disks')
def test_rescan_merge_requests(self, mock_rescan_helper, mock_rescan_lock):
mock_rescan_lock.locked.side_effect = [False, True, True]
self._diskutils.rescan_disks(merge_requests=True)
self._diskutils.rescan_disks(merge_requests=True)
self._diskutils.rescan_disks(merge_requests=False)
exp_rescan_count = 2
mock_rescan_helper.assert_has_calls(
[mock.call()] * exp_rescan_count)
mock_rescan_lock.__enter__.assert_has_calls(
[mock.call()] * exp_rescan_count)
@mock.patch('time.sleep')
def test_rescan_disks_error(self, mock_sleep):
mock_rescan = self._get_mocked_wmi_rescan(return_value=1)

View File

@ -17,6 +17,7 @@ import collections
import ctypes
import os
import re
import threading
from oslo_log import log as logging
@ -62,6 +63,8 @@ SCSI_ID_ASSOC_TYPE_DEVICE = 0
SCSI_ID_CODE_SET_BINARY = 1
SCSI_ID_CODE_SET_ASCII = 2
_RESCAN_LOCK = threading.Lock()
class DiskUtils(baseutils.BaseUtils):
@ -132,9 +135,30 @@ class DiskUtils(baseutils.BaseUtils):
err_msg = _("Could not find device number for device: %s")
raise exceptions.DiskNotFound(err_msg % device_name)
def rescan_disks(self, merge_requests=False):
"""Perform a disk rescan.
:param merge_requests: If this flag is set and a disk rescan is
already pending, we'll just wait for it to
finish without issuing a new rescan request.
"""
if merge_requests:
rescan_pending = _RESCAN_LOCK.locked()
if rescan_pending:
LOG.debug("A disk rescan is already pending. "
"Waiting for it to complete.")
with _RESCAN_LOCK:
if not rescan_pending:
self._rescan_disks()
else:
self._rescan_disks()
@_utils.retry_decorator(exceptions=(exceptions.x_wmi,
exceptions.OSWinException))
def rescan_disks(self):
def _rescan_disks(self):
LOG.debug("Rescanning disks.")
ret = self._conn_storage.Msft_StorageSetting.UpdateHostStorageCache()
if isinstance(ret, collections.Iterable):
@ -144,6 +168,8 @@ class DiskUtils(baseutils.BaseUtils):
err_msg = _("Rescanning disks failed. Error code: %s.")
raise exceptions.OSWinException(err_msg % ret)
LOG.debug("Finished rescanning disks.")
def get_disk_capacity(self, path, ignore_errors=False):
norm_path = os.path.abspath(path)