Commit 664ed1b4 authored by Thibault VINCENT's avatar Thibault VINCENT
Browse files

add: many update to drbd interface

parent 9548f132
Loading
Loading
Loading
Loading
+152 −114
Original line number Diff line number Diff line
@@ -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):
    '''
@@ -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(
@@ -97,6 +96,8 @@ class DRBD(object):
        UP_TO_DATE       = "UpToDate",
        )
    
    _mutex = RWLock()
    
    def __init__(self, manager, minor):
        '''
        '''
@@ -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,
@@ -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
@@ -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',
@@ -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,
@@ -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
@@ -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,
@@ -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,
@@ -232,6 +256,7 @@ class DRBD(object):
    def disconnect(self):
        '''
        '''
        with self._mutex.write:
            # disconnect from remote node
            Exec.silent([self.DRBDSETUP,
                         self._path,
@@ -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')

@@ -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'])
@@ -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',
@@ -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')