Loading ccnode/drbd.py +152 −114 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ import xml.dom.minidom, os from time import sleep from errors import DRBDPoolError, DRBDError from utils import RWLock, Exec, Enum, Net from utils import RWLock, Exec, Enum class DRBDPool(object): ''' Loading Loading @@ -51,7 +51,6 @@ class DRBD(object): DRBDADM = os.path.join(BIN_PATH, 'drbdadm') DRBDMETA = os.path.join(BIN_PATH, 'drbdmeta') DRBDSETUP = os.path.join(BIN_PATH, 'drbdsetup') DMSETUP = os.path.join(BIN_PATH, 'dmsetup') MODPROBE = os.path.join(BIN_PATH, 'modprobe') # connection states CSTATES = Enum( Loading Loading @@ -97,6 +96,8 @@ class DRBD(object): UP_TO_DATE = "UpToDate", ) _mutex = RWLock() def __init__(self, manager, minor): ''' ''' Loading @@ -115,14 +116,13 @@ class DRBD(object): ' is not available' % cmd) # check that device is not used if self.status()['conn'] is not None: print DRBDError('device minor `%i` is configured, cannot use it' % self._minor) print DRBDError('device minor `%i` is already configured, cannot' ' use it' % self._minor) def destroy(self): ''' ''' # disconnect remote node self.disconnect() with self._mutex.write: # bring down drbd device Exec.silent([self.DRBDSETUP, self._path, Loading @@ -136,16 +136,35 @@ class DRBD(object): self._path = None self._minor = None def get_minor(self): ''' ''' return self._minor def get_port(self): ''' ''' return 7788 + self._minor def status(self): def get_path(self): ''' ''' with self._mutex.read: return self._path def status(self, nolock = False): ''' ''' if not nolock: self._mutex.read.acquire() # fetch xml status try: rc, output = Exec.call([self.DRBDSETUP, self._path, 'status']) except Exception as err: if not nolock: self._mutex.read.release() raise err else: if rc: raise DRBDError('failed to get device status') # parse status Loading @@ -161,11 +180,15 @@ class DRBD(object): return status except Exception as err: return {'conn' : None} finally: if not nolock: self._mutex.read.release() def setup(self, sourcedev, metadev): ''' ''' if self.status()['conn'] is None: with self._mutex.write: if self.status(nolock=True)['conn'] is None: # wipe and init meta device rc = Exec.silent([self.DRBDMETA, '-f', Loading @@ -175,8 +198,8 @@ class DRBD(object): '0', 'wipe-md']) if rc != 0: raise DRBDError('failed to clean meta device, maybe it is in' ' use or does not exist') raise DRBDError('failed to clean meta device, maybe it is' ' in use or does not exist') rc = Exec.silent([self.DRBDMETA, '-f', self._path, Loading @@ -185,8 +208,8 @@ class DRBD(object): '0', 'create-md']) if rc != 0: raise DRBDError('failed to create meta device, maybe it is in' ' use or does not exist') raise DRBDError('failed to create meta device, maybe it is' ' in use or does not exist') else: self._meta = metadev # create the drbd disk Loading @@ -205,6 +228,7 @@ class DRBD(object): def connect(self, remote, remoteport, rate=50000): ''' ''' with self._mutex.write: # connect to remote node rc = Exec.silent([self.DRBDSETUP, self._path, Loading @@ -218,8 +242,8 @@ class DRBD(object): if rc != 0: raise DRBDError('failed to initiate connection to remote node,' ' local port may already be in use') # FIXME is this wait really needed ? sleep(3) # seems to be mandatory sleep(0.5) # force sync rate rc = Exec.silent([self.DRBDSETUP, self._path, Loading @@ -232,6 +256,7 @@ class DRBD(object): def disconnect(self): ''' ''' with self._mutex.write: # disconnect from remote node Exec.silent([self.DRBDSETUP, self._path, Loading @@ -241,10 +266,11 @@ class DRBD(object): ''' Switch the drbd to primary mode ''' with self._mutex.write: rc = Exec.silent([self.DRBDSETUP, self._path, 'primary', '-f']) '-o']) if rc != 0: raise DRBDError('failed to switch to primary node mode') Loading @@ -252,6 +278,7 @@ class DRBD(object): ''' Switch the drbd to secondary mode ''' with self._mutex.write: rc = Exec.silent([self.DRBDSETUP, self._path, 'secondary']) Loading @@ -262,6 +289,8 @@ class DRBD(object): ''' Wait for connection with the remote drbd node ''' with self._mutex.read: sleep(0.5) #FIXME really needed ? rc = Exec.silent([self.DRBDSETUP, self._path, 'wait-connect', Loading @@ -271,17 +300,26 @@ class DRBD(object): str(timeout), '-o', str(timeout)]) # seems to be mandatory sleep(0.5) try: if rc != 0 or self.status()['conn'] != self.CSTATES.CONNECTED: raise DRBDError('no connection after `%i` seconds' %timeout) except Exception as err: print err def wait_sync(self): ''' Wait for synchronization of the drbd device ''' with self._mutex.read: rc = Exec.silent([self.DRBDSETUP, self._path, 'wait-sync']) # seems to be mandatory sleep(0.5) status = self.status() if (rc != 0 or not status or status['disk'] != self.DSTATES.UP_TO_DATE or status['rdisk'] != self.DSTATES.UP_TO_DATE): print status, self.DSTATES.UP_TO_DATE_str if (rc != 0 or not status or status['disk'] != self.DSTATES.UP_TO_DATE): raise DRBDError('synchronization failed') Loading
ccnode/drbd.py +152 −114 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ import xml.dom.minidom, os from time import sleep from errors import DRBDPoolError, DRBDError from utils import RWLock, Exec, Enum, Net from utils import RWLock, Exec, Enum class DRBDPool(object): ''' Loading Loading @@ -51,7 +51,6 @@ class DRBD(object): DRBDADM = os.path.join(BIN_PATH, 'drbdadm') DRBDMETA = os.path.join(BIN_PATH, 'drbdmeta') DRBDSETUP = os.path.join(BIN_PATH, 'drbdsetup') DMSETUP = os.path.join(BIN_PATH, 'dmsetup') MODPROBE = os.path.join(BIN_PATH, 'modprobe') # connection states CSTATES = Enum( Loading Loading @@ -97,6 +96,8 @@ class DRBD(object): UP_TO_DATE = "UpToDate", ) _mutex = RWLock() def __init__(self, manager, minor): ''' ''' Loading @@ -115,14 +116,13 @@ class DRBD(object): ' is not available' % cmd) # check that device is not used if self.status()['conn'] is not None: print DRBDError('device minor `%i` is configured, cannot use it' % self._minor) print DRBDError('device minor `%i` is already configured, cannot' ' use it' % self._minor) def destroy(self): ''' ''' # disconnect remote node self.disconnect() with self._mutex.write: # bring down drbd device Exec.silent([self.DRBDSETUP, self._path, Loading @@ -136,16 +136,35 @@ class DRBD(object): self._path = None self._minor = None def get_minor(self): ''' ''' return self._minor def get_port(self): ''' ''' return 7788 + self._minor def status(self): def get_path(self): ''' ''' with self._mutex.read: return self._path def status(self, nolock = False): ''' ''' if not nolock: self._mutex.read.acquire() # fetch xml status try: rc, output = Exec.call([self.DRBDSETUP, self._path, 'status']) except Exception as err: if not nolock: self._mutex.read.release() raise err else: if rc: raise DRBDError('failed to get device status') # parse status Loading @@ -161,11 +180,15 @@ class DRBD(object): return status except Exception as err: return {'conn' : None} finally: if not nolock: self._mutex.read.release() def setup(self, sourcedev, metadev): ''' ''' if self.status()['conn'] is None: with self._mutex.write: if self.status(nolock=True)['conn'] is None: # wipe and init meta device rc = Exec.silent([self.DRBDMETA, '-f', Loading @@ -175,8 +198,8 @@ class DRBD(object): '0', 'wipe-md']) if rc != 0: raise DRBDError('failed to clean meta device, maybe it is in' ' use or does not exist') raise DRBDError('failed to clean meta device, maybe it is' ' in use or does not exist') rc = Exec.silent([self.DRBDMETA, '-f', self._path, Loading @@ -185,8 +208,8 @@ class DRBD(object): '0', 'create-md']) if rc != 0: raise DRBDError('failed to create meta device, maybe it is in' ' use or does not exist') raise DRBDError('failed to create meta device, maybe it is' ' in use or does not exist') else: self._meta = metadev # create the drbd disk Loading @@ -205,6 +228,7 @@ class DRBD(object): def connect(self, remote, remoteport, rate=50000): ''' ''' with self._mutex.write: # connect to remote node rc = Exec.silent([self.DRBDSETUP, self._path, Loading @@ -218,8 +242,8 @@ class DRBD(object): if rc != 0: raise DRBDError('failed to initiate connection to remote node,' ' local port may already be in use') # FIXME is this wait really needed ? sleep(3) # seems to be mandatory sleep(0.5) # force sync rate rc = Exec.silent([self.DRBDSETUP, self._path, Loading @@ -232,6 +256,7 @@ class DRBD(object): def disconnect(self): ''' ''' with self._mutex.write: # disconnect from remote node Exec.silent([self.DRBDSETUP, self._path, Loading @@ -241,10 +266,11 @@ class DRBD(object): ''' Switch the drbd to primary mode ''' with self._mutex.write: rc = Exec.silent([self.DRBDSETUP, self._path, 'primary', '-f']) '-o']) if rc != 0: raise DRBDError('failed to switch to primary node mode') Loading @@ -252,6 +278,7 @@ class DRBD(object): ''' Switch the drbd to secondary mode ''' with self._mutex.write: rc = Exec.silent([self.DRBDSETUP, self._path, 'secondary']) Loading @@ -262,6 +289,8 @@ class DRBD(object): ''' Wait for connection with the remote drbd node ''' with self._mutex.read: sleep(0.5) #FIXME really needed ? rc = Exec.silent([self.DRBDSETUP, self._path, 'wait-connect', Loading @@ -271,17 +300,26 @@ class DRBD(object): str(timeout), '-o', str(timeout)]) # seems to be mandatory sleep(0.5) try: if rc != 0 or self.status()['conn'] != self.CSTATES.CONNECTED: raise DRBDError('no connection after `%i` seconds' %timeout) except Exception as err: print err def wait_sync(self): ''' Wait for synchronization of the drbd device ''' with self._mutex.read: rc = Exec.silent([self.DRBDSETUP, self._path, 'wait-sync']) # seems to be mandatory sleep(0.5) status = self.status() if (rc != 0 or not status or status['disk'] != self.DSTATES.UP_TO_DATE or status['rdisk'] != self.DSTATES.UP_TO_DATE): print status, self.DSTATES.UP_TO_DATE_str if (rc != 0 or not status or status['disk'] != self.DSTATES.UP_TO_DATE): raise DRBDError('synchronization failed')