def resize_from_voldrv(volumename, volumesize, volumepath, storagedriver_id): """ Resize a disk Triggered by volumedriver messages on the queue @param volumepath: path on hypervisor to the volume @param volumename: volume id of the disk @param volumesize: size of the volume """ pmachine = PMachineList.get_by_storagedriver_id(storagedriver_id) storagedriver = StorageDriverList.get_by_storagedriver_id(storagedriver_id) hypervisor = Factory.get(pmachine) volumepath = hypervisor.clean_backing_disk_filename(volumepath) mutex = VolatileMutex('{}_{}'.format(volumename, volumepath)) try: mutex.acquire(wait=30) disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is None: disk = VDiskList.get_by_devicename_and_vpool(volumepath, storagedriver.vpool) if disk is None: disk = VDisk() finally: mutex.release() disk.devicename = volumepath disk.volume_id = volumename disk.size = volumesize disk.vpool = storagedriver.vpool disk.save() VDiskController.sync_with_mgmtcenter(disk, pmachine, storagedriver) MDSServiceController.ensure_safety(disk)
def resize_from_voldrv(volumename, volumesize, volumepath, storagedriver_id): """ Resize a disk Triggered by volumedriver messages on the queue @param volumepath: path on hypervisor to the volume @param volumename: volume id of the disk @param volumesize: size of the volume """ pmachine = PMachineList.get_by_storagedriver_id(storagedriver_id) storagedriver = StorageDriverList.get_by_storagedriver_id( storagedriver_id) hypervisor = Factory.get(pmachine) volumepath = hypervisor.clean_backing_disk_filename(volumepath) mutex = VolatileMutex('{}_{}'.format(volumename, volumepath)) try: mutex.acquire(wait=30) disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is None: disk = VDiskList.get_by_devicename_and_vpool( volumepath, storagedriver.vpool) if disk is None: disk = VDisk() finally: mutex.release() disk.devicename = volumepath disk.volume_id = volumename disk.size = volumesize disk.vpool = storagedriver.vpool disk.save()
def delete_from_voldrv(volumename, storagedriver_id): """ Delete a disk Triggered by volumedriver messages on the queue @param volumename: volume id of the disk """ _ = storagedriver_id # For logging purposes disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is not None: mutex = VolatileMutex('{}_{}'.format(volumename, disk.devicename)) try: mutex.acquire(wait=20) pmachine = None try: pmachine = PMachineList.get_by_storagedriver_id(disk.storagedriver_id) except RuntimeError as ex: if 'could not be found' not in str(ex): raise # else: pmachine can't be loaded, because the volumedriver doesn't know about it anymore if pmachine is not None: limit = 5 hypervisor = Factory.get(pmachine) exists = hypervisor.file_exists(disk.vpool, disk.devicename) while limit > 0 and exists is True: time.sleep(1) exists = hypervisor.file_exists(disk.vpool, disk.devicename) limit -= 1 if exists is True: logger.info('Disk {0} still exists, ignoring delete'.format(disk.devicename)) return logger.info('Delete disk {}'.format(disk.name)) disk.delete() finally: mutex.release()
def volumedriver_error(code, volumename): """ Handles error messages/events from the volumedriver """ if code == VolumeDriverEvents.MDSFailover: disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is not None: MDSServiceController.ensure_safety(disk)
def volumedriver_error(code, volumename, storagedriver_id): """ Handles error messages/events from the volumedriver """ _ = storagedriver_id # Required for the @log decorator if code == VolumeDriverEvents.MDSFailover: disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is not None: MDSServiceController.ensure_safety(disk)
def volumedriver_error(code, volumename): """ Handles error messages/events from the volumedriver :param code: Volumedriver error code :param volumename: Name of the volume throwing the error """ if code == VolumeDriverEvents.MDSFailover: disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is not None: MDSServiceController.ensure_safety(disk)
def volumedriver_error(code, volumename, storagedriver_id): """ Handles error messages/events from the volumedriver :param code: Volumedriver error code :param volumename: Name of the volume throwing the error :param storagedriver_id: ID of the storagedriver hosting the volume """ _ = storagedriver_id # Required for the @log decorator if code == VolumeDriverEvents.MDSFailover: disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is not None: MDSServiceController.ensure_safety(disk)
def volumedriver_error(code, volume_id): """ Handles error messages/events from the volumedriver :param code: Volumedriver error code :type code: int :param volume_id: Name of the volume throwing the error :type volume_id: str :return: None """ if code == VolumeDriverEvents.MDSFailover: disk = VDiskList.get_vdisk_by_volume_id(volume_id) if disk is not None: MDSServiceController.ensure_safety(disk)
def volumedriver_error(code, volume_id): """ Handles error messages/events from the volumedriver :param code: Volumedriver error code :type code: int :param volume_id: Name of the volume throwing the error :type volume_id: str :return: None """ if code == VolumeDriverEvents_pb2.MDSFailover: disk = VDiskList.get_vdisk_by_volume_id(volume_id) if disk is not None: MDSServiceController.ensure_safety(disk)
def dtl_state_transition(volume_name, old_state, new_state, storagedriver_id): """ Triggered by volumedriver when DTL state changes :param volume_name: ID of the volume :param old_state: Previous DTL status :param new_state: New DTL status :param storagedriver_id: ID of the storagedriver hosting the volume :return: None """ if new_state == VolumeDriverEvents_pb2.Degraded and old_state != VolumeDriverEvents_pb2.Standalone: vdisk = VDiskList.get_vdisk_by_volume_id(volume_name) if vdisk: logger.info('Degraded DTL detected for volume {0} with guid {1}'.format(vdisk.name, vdisk.guid)) storagedriver = StorageDriverList.get_by_storagedriver_id(storagedriver_id) VDiskController.dtl_checkup(vdisk_guid=vdisk.guid, storagerouters_to_exclude=[storagedriver.storagerouter.guid], chain_timeout=600)
def rename_from_voldrv(volumename, volume_old_path, volume_new_path, storagedriver_id): """ Rename a disk Triggered by volumedriver messages @param volumename: volume id of the disk @param volume_old_path: old path on hypervisor to the volume @param volume_new_path: new path on hypervisor to the volume """ pmachine = PMachineList.get_by_storagedriver_id(storagedriver_id) hypervisor = Factory.get(pmachine) volume_old_path = hypervisor.clean_backing_disk_filename(volume_old_path) volume_new_path = hypervisor.clean_backing_disk_filename(volume_new_path) disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk: logger.info("Move disk {} from {} to {}".format(disk.name, volume_old_path, volume_new_path)) disk.devicename = volume_new_path disk.save()
def delete_from_voldrv(volumename, storagedriver_id): """ Delete a disk Triggered by volumedriver messages on the queue @param volumename: volume id of the disk """ _ = storagedriver_id # For logging purposes disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk is not None: mutex = VolatileMutex('{}_{}'.format(volumename, disk.devicename)) try: mutex.acquire(wait=20) pmachine = None try: pmachine = PMachineList.get_by_storagedriver_id( disk.storagedriver_id) except RuntimeError as ex: if 'could not be found' not in str(ex): raise # else: pmachine can't be loaded, because the volumedriver doesn't know about it anymore if pmachine is not None: limit = 5 storagedriver = StorageDriverList.get_by_storagedriver_id( storagedriver_id) hypervisor = Factory.get(pmachine) exists = hypervisor.file_exists(storagedriver, disk.devicename) while limit > 0 and exists is True: time.sleep(1) exists = hypervisor.file_exists( storagedriver, disk.devicename) limit -= 1 if exists is True: logger.info( 'Disk {0} still exists, ignoring delete'.format( disk.devicename)) return logger.info('Delete disk {}'.format(disk.name)) for mds_service in disk.mds_services: mds_service.delete() disk.delete() finally: mutex.release()
def migrate_from_voldrv(volume_id, new_owner_id): """ Triggered when volume has changed owner (Clean migration or stolen due to other reason) Triggered by volumedriver messages :param volume_id: Volume ID of the disk :type volume_id: unicode :param new_owner_id: ID of the storage driver the volume migrated to :type new_owner_id: unicode :returns: None """ sd = StorageDriverList.get_by_storagedriver_id(storagedriver_id=new_owner_id) vdisk = VDiskList.get_vdisk_by_volume_id(volume_id=volume_id) if vdisk is not None: logger.info('Migration - Guid {0} - ID {1} - Detected migration for virtual disk {2}'.format(vdisk.guid, vdisk.volume_id, vdisk.name)) if sd is not None: logger.info('Migration - Guid {0} - ID {1} - Storage Router {2} is the new owner of virtual disk {3}'.format(vdisk.guid, vdisk.volume_id, sd.storagerouter.name, vdisk.name)) MDSServiceController.mds_checkup() VDiskController.dtl_checkup(vdisk_guid=vdisk.guid)
def rename_from_voldrv(volumename, volume_old_path, volume_new_path, storagedriver_id): """ Rename a disk Triggered by volumedriver messages @param volumename: volume id of the disk @param volume_old_path: old path on hypervisor to the volume @param volume_new_path: new path on hypervisor to the volume """ pmachine = PMachineList.get_by_storagedriver_id(storagedriver_id) hypervisor = Factory.get(pmachine) volume_old_path = hypervisor.clean_backing_disk_filename( volume_old_path) volume_new_path = hypervisor.clean_backing_disk_filename( volume_new_path) disk = VDiskList.get_vdisk_by_volume_id(volumename) if disk: logger.info('Move disk {} from {} to {}'.format( disk.name, volume_old_path, volume_new_path)) disk.devicename = volume_new_path disk.save()
def test_sync(self): """ Validates whether the sync works as expected """ structure = DalHelper.build_dal_structure({ 'vpools': [1], 'storagerouters': [1], 'storagedrivers': [(1, 1, 1)], # (<id>, <vpool_id>, <storagerouter_id>) 'mds_services': [(1, 1)] } # (<id>, <storagedriver_id>) ) vpool = structure['vpools'][1] storagedriver = structure['storagedrivers'][1] mds_service = structure['mds_services'][1] # noinspection PyArgumentList backend_config = MDSMetaDataBackendConfig([ MDSNodeConfig(address=str(mds_service.service.storagerouter.ip), port=mds_service.service.ports[0]) ]) srclient = StorageRouterClient(vpool.guid, None) VDiskController.create_new('one', 1024**3, storagedriver.guid) VDiskController.create_new('two', 1024**3, storagedriver.guid) vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 2) self.assertEqual(len(srclient.list_volumes()), 2) VDiskController.sync_with_reality() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 2) self.assertEqual(len(srclient.list_volumes()), 2) volume_id = srclient.create_volume('/three.raw', backend_config, 1024**3, storagedriver.storagedriver_id) vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 2) self.assertEqual(len(srclient.list_volumes()), 3) VDiskController.sync_with_reality() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 3) self.assertEqual(len(srclient.list_volumes()), 3) vdisk = VDiskList.get_vdisk_by_volume_id(volume_id) self.assertEqual(vdisk.devicename, '/three.raw') vdisk = VDisk() vdisk.volume_id = 'foo' vdisk.name = 'foo' vdisk.devicename = 'foo.raw' vdisk.size = 1024**3 vdisk.vpool = vpool vdisk.save() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 4) self.assertEqual(len(srclient.list_volumes()), 3) VDiskController.sync_with_reality() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 3) self.assertEqual(len(srclient.list_volumes()), 3) with self.assertRaises(ObjectNotFoundException): vdisk.save()