Federico Simoncelli has uploaded a new change for review.
Change subject: [wip] sdcache: avoid extra refresh due samplingmethod
......................................................................
[wip] sdcache: avoid extra refresh due samplingmethod
In order to avoid an extra iscsi rescan (symptomatic of samplingmethod)
an additional lock has been introduced to queue the requests when the
storage is flagged as stale.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=870768
Change-Id: If178a8eaeb94f1dfe9e0957036dde88f6a22829c
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/sdc.py
1 file changed, 25 insertions(+), 26 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/74/9274/1
diff --git a/vdsm/storage/sdc.py b/vdsm/storage/sdc.py
index f2f4534..978e3fa 100644
--- a/vdsm/storage/sdc.py
+++ b/vdsm/storage/sdc.py
@@ -62,32 +62,27 @@
STORAGE_UPDATED = 0
STORAGE_STALE = 1
- STORAGE_REFRESHING = 2
def __init__(self, storage_repo):
- self._syncroot = threading.Condition()
+ self._syncDomain = threading.Condition()
+ self._syncRefresh = threading.Lock()
self.__domainCache = {}
self.__inProgress = set()
self.__staleStatus = self.STORAGE_STALE
self.storage_repo = storage_repo
def invalidateStorage(self):
- with self._syncroot:
- self.__staleStatus = self.STORAGE_STALE
+ self.log.debug("The storages have been invalidated")
+ self.__staleStatus = self.STORAGE_STALE
@misc.samplingmethod
def refreshStorage(self):
- self.__staleStatus = self.STORAGE_REFRESHING
-
+ # We need to set the __staleStatus value at the beginning because we
+ # want to keep track of the future invalidateStorage calls that might
+ # arrive during the rescan procedure.
+ self.__staleStatus = self.STORAGE_UPDATED
multipath.rescan()
lvm.invalidateCache()
-
- # If a new invalidateStorage request came in after the refresh
- # started then we cannot flag the storages as updated (force a
- # new rescan later).
- with self._syncroot:
- if self.__staleStatus == self.STORAGE_REFRESHING:
- self.__staleStatus = self.STORAGE_UPDATED
def produce(self, sdUUID):
domain = DomainProxy(self, sdUUID)
@@ -98,7 +93,7 @@
return domain
def _realProduce(self, sdUUID):
- with self._syncroot:
+ with self._syncDomain:
while True:
domain = self.__domainCache.get(sdUUID)
@@ -109,25 +104,29 @@
self.__inProgress.add(sdUUID)
break
- self._syncroot.wait()
+ self._syncDomain.wait()
try:
- # If multiple calls reach this point and the storage is not
- # updated the refreshStorage() sampling method is called
- # serializing (and eventually grouping) the requests.
- if self.__staleStatus != self.STORAGE_UPDATED:
- self.refreshStorage()
+ # Here we cannot take full advantage of the refreshStorage
+ # samplingmethod since we might be scheduling an unneeded
+ # extra rescan. We need an additional lock (_syncRefresh)
+ # to make sure that __staleStatus is taken in account
+ # (without affecting all the other external refreshStorage
+ # calls as it would be if we move this check there).
+ with self._syncRefresh:
+ if self.__staleStatus != self.STORAGE_UPDATED:
+ self.refreshStorage()
domain = self._findDomain(sdUUID)
- with self._syncroot:
+ with self._syncDomain:
self.__domainCache[sdUUID] = domain
return domain
finally:
- with self._syncroot:
+ with self._syncDomain:
self.__inProgress.remove(sdUUID)
- self._syncroot.notifyAll()
+ self._syncDomain.notifyAll()
def _findDomain(self, sdUUID):
import blockSD
@@ -162,16 +161,16 @@
return uuids
def refresh(self):
- with self._syncroot:
+ with self._syncDomain:
lvm.invalidateCache()
self.__domainCache.clear()
def manuallyAddDomain(self, domain):
- with self._syncroot:
+ with self._syncDomain:
self.__domainCache[domain.sdUUID] = domain
def manuallyRemoveDomain(self, sdUUID):
- with self._syncroot:
+ with self._syncDomain:
try:
del self.__domainCache[sdUUID]
except KeyError:
--
To view, visit http://gerrit.ovirt.org/9274
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If178a8eaeb94f1dfe9e0957036dde88f6a22829c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: sp: prevent master demotion on activation
......................................................................
sp: prevent master demotion on activation
Change-Id: I47a0c3ea16bcdefa99899e04c453eaf995344dfb
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/sp.py
1 file changed, 9 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/28332/1
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 3f983b6..3762c10 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1041,7 +1041,15 @@
# Domain conversion requires the links to be present
self._refreshDomainLinks(dom)
- self._backend.setDomainRegularRole(dom)
+
+ # This should never happen because we're not deactivating the
+ # current master in deactivateStorageDomain if a new master is
+ # not provided. It is also impossible to connect to a pool
+ # where the master domain is not active. Anyway to be on the
+ # safe side we must prevent the current master domain from
+ # being demoted to regular.
+ if sdUUID != self.masterDomain.sdUUID:
+ self._backend.setDomainRegularRole(dom)
if dom.getDomainClass() == sd.DATA_DOMAIN:
self._convertDomain(dom)
--
To view, visit http://gerrit.ovirt.org/28332
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I47a0c3ea16bcdefa99899e04c453eaf995344dfb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Nir Soffer has uploaded a new change for review.
Change subject: tests: Add storage mailbox tests
......................................................................
tests: Add storage mailbox tests
Use fake repository for testing the content of the storage mailbox
without using real block devices.
Change-Id: If02ed99b95dfd0d6bc5cc9694e60c3808d0974aa
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M tests/Makefile.am
A tests/mailboxTests.py
2 files changed, 91 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/71/29371/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6507165..a1fd385 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -46,6 +46,7 @@
libvirtconnectionTests.py \
lsblkTests.py \
lvmTests.py \
+ mailboxTests.py \
main.py \
md_utils_tests.py \
miscTests.py \
diff --git a/tests/mailboxTests.py b/tests/mailboxTests.py
new file mode 100644
index 0000000..ec6854c
--- /dev/null
+++ b/tests/mailboxTests.py
@@ -0,0 +1,90 @@
+import ConfigParser
+import errno
+import os
+import time
+
+from storage import sd
+from storage import storage_mailbox
+from vdsm import config
+
+from testrunner import VdsmTestCase as TestCaseBase
+import monkeypatch
+
+# Don't use /tmp, as O_DIRECT does not work with tempfs file system. Keeping
+# the test files in the source is ugly but make it very easy to debug the
+# mailbox content.
+REPO_DIR = 'mailboxTests.tmp'
+
+HOST_ID = 1
+POOL_ID = 'pool'
+MD_DIR = os.path.join(REPO_DIR, POOL_ID, "mastersd", sd.DOMAIN_META_DATA)
+INBOX = os.path.join(MD_DIR, "inbox")
+OUTBOX = os.path.join(MD_DIR, "outbox")
+MAX_HOSTS = 2000
+
+# U (0x55) is a nice initial value
+DIRTY_MAILBOX = 'U' * storage_mailbox.MAILBOX_SIZE
+
+fake_config = ConfigParser.ConfigParser()
+config.set_defaults(fake_config)
+fake_config.set('irs', 'repository', REPO_DIR)
+
+
+class HSMMailboxTests(TestCaseBase):
+
+ def setUp(self):
+ # Note: we don't remove the inbox and outbox when test ends to make it
+ # eaiser to debug by checking inbox and outbox content after a test
+ # fails.
+ create_repository()
+ init_mailbox(INBOX)
+ init_mailbox(OUTBOX)
+
+ @monkeypatch.MonkeyPatch(storage_mailbox, 'config', fake_config)
+ def test_init_inbox(self):
+ mailer = storage_mailbox.HSM_Mailbox(HOST_ID, POOL_ID)
+ try:
+ time.sleep(0.5)
+ with open(INBOX) as f:
+ # First mailbox is not used
+ data = f.read(storage_mailbox.MAILBOX_SIZE)
+ self.assertEquals(data, DIRTY_MAILBOX)
+ # When mailbox is started, it clears the host inbox
+ data = f.read(storage_mailbox.MAILBOX_SIZE)
+ self.assertEquals(data, storage_mailbox.EMPTYMAILBOX)
+ # This mailbox belong to another host, and should not change
+ data = f.read(storage_mailbox.MAILBOX_SIZE)
+ self.assertEquals(data, DIRTY_MAILBOX)
+ finally:
+ mailer.stop()
+
+ @monkeypatch.MonkeyPatch(storage_mailbox, 'config', fake_config)
+ def test_keep_outbox(self):
+ mailer = storage_mailbox.HSM_Mailbox(HOST_ID, POOL_ID)
+ try:
+ time.sleep(0.5)
+ with open(OUTBOX) as f:
+ # First mailbox is not used
+ data = f.read(storage_mailbox.MAILBOX_SIZE)
+ self.assertEquals(data, DIRTY_MAILBOX)
+ # Outbox is not touched
+ data = f.read(storage_mailbox.MAILBOX_SIZE)
+ self.assertEquals(data, DIRTY_MAILBOX)
+ # This mailbox belong to another host, and should not change
+ data = f.read(storage_mailbox.MAILBOX_SIZE)
+ self.assertEquals(data, DIRTY_MAILBOX)
+ finally:
+ mailer.stop()
+
+
+def init_mailbox(path):
+ with open(path, 'w') as f:
+ f.write(DIRTY_MAILBOX * MAX_HOSTS)
+
+
+def create_repository():
+ try:
+ os.makedirs(MD_DIR)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
--
To view, visit http://gerrit.ovirt.org/29371
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If02ed99b95dfd0d6bc5cc9694e60c3808d0974aa
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>