def callable(*args, **kwargs): try: device = args[0] logger.debug("Sending SCSI command {!r} for device {!r}".format(func, _safe_repr(device))) response = func(*args, **kwargs) logger.debug("Got response {!r}".format(response)) return response except AsiCheckConditionError as e: if not e.sense_obj: msg = "got no sense from device {!r} during {!r}".format(_safe_repr(device), func) logger.error(msg, exc_info=exc_info()) raise chain(DeviceError(msg)) (key, code) = (e.sense_obj.sense_key, e.sense_obj.additional_sense_code.code_name) if (key, code) in CHECK_CONDITIONS_TO_CHECK: msg = "device {!r} got {} {}".format(device, key, code) logger.debug(msg) raise chain(RescanIsNeeded(msg)) raise except AsiRequestQueueFullError as e: msg = "got queue full from device {!r} during {!r}".format(_safe_repr(device), func) logger.debug(msg) raise chain(RescanIsNeeded(msg)) except AsiSCSIError as error: msg = "error with device {!r} during {!r}: {}".format(_safe_repr(device), func, error) logger.error(msg) raise chain(DeviceError(msg)) except (IOError, OSError, AsiOSError) as error: msg = "error with device {!r} during {!r}".format(_safe_repr(device), func) logger.error(msg, exc_info=exc_info()) raise chain(DeviceError(msg))
def receive(self, expected_length=MAX_SIZE): try: return self._receive(expected_length) except socket.timeout: logger.debug("Caught socket timeout: {!r}".format(self._socket.gettimeout())) raise chain(TimeoutExpired("multipathd is not responding")) except socket.error as error: raise chain(ConnectionError("multipathd connection error: {}".format(error.strerror)))
def receive(self, expected_length=MAX_SIZE): from socket import timeout, error try: return self._receive(expected_length) except timeout: logger.debug("Caught socket timeout: {!r}".format(self._socket.gettimeout())) raise chain(TimeoutExpired("multipathd is not responding")) except error: raise chain(ConnectionError("multipathd connection refused"))
def _get_setupapi_property(self, key): from .setupapi import WindowsException with self._open_handle() as handle: dis, devinfo = handle try: return functions.SetupDiGetDeviceProperty(dis, devinfo, key).python_object except WindowsException as exception: if exception.winerror == constants.ERROR_NOT_FOUND: raise KeyError(key) chain(exception)
def connect(self): try: socket_object = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) socket_object.connect(self._address) socket_object.settimeout(self._timeout) except socket.error as error: raise chain(ConnectionError("failed to connect to multipathd socket: {}".format(error.strerror))) except Exception as error: raise chain(ConnectionError("failed to connect to multipathd socket: {}".format(error))) self._socket = socket_object
def _get_list_of_active_devices(self, client): from infi.multipathtools.errors import ConnectionError, TimeoutExpired from infi.exceptools import chain try: devices = [device for device in client.get_list_of_multipath_devices() if self._is_device_active(device)] except TimeoutExpired: raise chain(MultipathDaemonTimeoutError()) except ConnectionError: raise chain(StorageModelFindError()) return devices
def send(self, message): try: bytes_sent = self._socket.send(message) except socket.timeout: logger.debug("Caught socket timeout: {!r}".format(self._socket.gettimeout())) raise chain(TimeoutExpired("multipathd is not responding")) except socket.error as error: raise chain(ConnectionError("multipathd socket error: {}".format(error.strerror))) if bytes_sent < len(message): self.send(message[bytes_sent:])
def callee(*args, **kwargs): from . import WindowsException index = 0 while True: try: kwargs["index"] = index yield decorated_func(*args, **kwargs) index += 1 except WindowsException, exception: if exception.winerror in [ERROR_NO_MORE_ITEMS, ERROR_BAD_COMMAND]: # TODO why ERROR_BAD_COMMAND? raise StopIteration chain(exception)
def _get_list_of_active_devices(self, client): from infi.multipathtools.errors import ConnectionError, TimeoutExpired from infi.exceptools import chain try: all_devices = client.get_list_of_multipath_devices() logger.debug("all multipath devices = {}".format(all_devices)) active_devices = [device for device in all_devices if self._is_device_active(device)] except TimeoutExpired: raise chain(MultipathDaemonTimeoutError()) except ConnectionError: raise chain(StorageModelFindError()) return active_devices
def callee(*args, **kwargs): from . import WindowsException index = 0 while True: try: kwargs["index"] = index yield decorated_func(*args, **kwargs) index += 1 except WindowsException as exception: if exception.winerror in [ERROR_NO_MORE_ITEMS, ERROR_BAD_COMMAND]: # TODO why ERROR_BAD_COMMAND? return chain(exception)
def send(self, message): from socket import timeout, error try: bytes_sent = self._socket.send(message) except timeout: logger.debug("Caught socket timeout: {!r}".format(self._socket.gettimeout())) raise chain(TimeoutExpired("multipathd is not responding")) except error: raise chain(ConnectionError("multipathd connection refused")) if bytes_sent < len(message): self.send(message[bytes_sent:])
def _get_string_inquiry_page(self, page): from infi.asi import AsiCheckConditionError from infi.storagemodel.vendor.infinidat.infinibox.string_page import StringInquiryPageBuffer try: unknown_page = self.device.get_scsi_inquiry_pages()[page] string_page = StringInquiryPageBuffer() string_page.unpack(unknown_page.pack()) return string_page except KeyError: raise chain(InquiryException("Inquiry command error")) except AsiCheckConditionError as error: if _is_exception_of_unsupported_inquiry_page(error): raise chain(InquiryException("Inquiry command error")) raise
def get_json_data(self, page=0xc5): """ Returns the json inquiry data from the system as a `dict` """ try: return self._get_json_inquiry_data(page) except ValueError: logger.exception("Inquiry response is invalid JSON format") raise chain(InquiryException("ValueError"))
def pack(self): """Packs the object and returns a buffer representing the packed object.""" fields = self._all_fields() ctx = PackContext(self, fields) for field in fields: if field.pack_if.deref(ctx): try: ctx.output_buffer.set(field.pack_ref.deref(ctx), field.pack_absolute_position_ref.deref(ctx)) except: raise exceptools.chain(InstructBufferError("Pack error occured", ctx, type(self), field.attr_name())) result = bytearray(ctx.output_buffer.get()) # We want to support the user defining the buffer's fixed byte size but not using it all: static_byte_size = type(self).byte_size if static_byte_size: static_byte_size = int(math.ceil(static_byte_size)) assert len(result) <= static_byte_size, \ ("in type {0} computed pack size is {1} but declared byte size is {2} - perhaps you manually defined " + "the byte size in the type but the actual size is bigger?").format(type(self), len(result), static_byte_size) if len(result) < static_byte_size: result += bytearray(static_byte_size - len(result)) return result
def check_for_scsi_errors(func): """ A decorator for catching SCSI errors from the `infi.asi` layer and converting them to storagemodel errors. """ from infi.asi.errors import AsiOSError, AsiSCSIError, AsiCheckConditionError, AsiRequestQueueFullError from sys import exc_info @wraps(func) def callable(*args, **kwargs): try: device = args[0] logger.debug("Sending SCSI command {!r} for device {!r}".format(func, _safe_repr(device))) response = func(*args, **kwargs) logger.debug("Got response {!r}".format(response)) return response except AsiCheckConditionError, e: if not e.sense_obj: msg = "got no sense from device {!r} during {!r}".format(_safe_repr(device), func) logger.error(msg, exc_info=exc_info()) raise chain(DeviceDisappeared(msg)) (key, code) = (e.sense_obj.sense_key, e.sense_obj.additional_sense_code.code_name) if (key, code) in CHECK_CONDITIONS_TO_CHECK: msg = "device {!r} got {} {}".format(device, key, code) logger.debug(msg) raise chain(RescanIsNeeded(msg)) raise except AsiRequestQueueFullError, e: msg = "got queue full from device {!r} during {!r}".format(_safe_repr(device), func) logger.debug(msg) raise chain(RescanIsNeeded(msg))
def decorator(*args, **kwargs): counter = 10 while counter > 0: try: sg_device, cdb = args msg = "{} attempting to send {} to sg device {}, {} more retries" logger.debug(msg.format(getpid(), func.__name__, sg_device, counter)) response = func(*args, **kwargs) return response except AsiCheckConditionError as e: (key, code) = (e.sense_obj.sense_key, e.sense_obj.additional_sense_code.code_name) msg = "{} sg device {} got {} {}".format(getpid(), sg_device, key, code) logger.warn(msg) counter -= 1 if (key, code) in CHECK_CONDITIONS_NOT_WORTH_RETRY or counter == 0: raise ScsiCheckConditionError(key, code) except AsiReservationConflictError as error: msg = "{} sg device {} has unsupported luns report: {}" logger.error(msg.format(getpid(), sg_device, error)) raise ScsiReservationConflictError() except (IOError, OSError, AsiOSError, AsiSCSIError) as error: msg = "{} sg device {} got unrecoverable error {} during {}" logger.error(msg.format(getpid(), sg_device, error, cdb)) counter = 0 except UnsupportedReportLuns as error: msg = "{} sg device {} has unsupported luns report: {}" logger.error(msg.format(getpid(), sg_device, error)) raise ScsiCommandFailed() raise chain(ScsiCommandFailed())
def create_from_stream(self, stream, context=EMPTY_CONTEXT): packed_value = stream.read(self.size) if len(packed_value) < self.size: raise NotEnoughDataError(expected=self.size, actually_read=len(packed_value)) try: return struct.unpack(self.format_string, packed_value)[0] except struct.error, e: raise chain(InstructError("Unpacking error occurred"))
def get_all_linux_scsi_generic_disk_devices(self): """Linux specific: returns a list of ScsiDisk objects that do not rely on SD""" from .sysfs import SysfsSDDisk try: return [LinuxSCSIBlockDevice(disk) if isinstance(disk, SysfsSDDisk) else LinuxSCSIGenericDevice(disk) for disk in self.sysfs.get_all_sg_disks()] except (IOError, OSError), error: raise chain(DeviceDisappeared())
def parse_configfile(configfile_path): from ConfigParser import ConfigParser try: parser = ConfigParser() parser.read(configfile_path) except: raise chain(InfiException()) return parser
def _get_json_inquiry_page(self): from infi.asi import AsiCheckConditionError try: from ...json_page import JSONInquiryPageData page = self.device.get_scsi_inquiry_pages()[0xc5] return JSONInquiryPageData.create_from_string(page.write_to_string(page)) except AsiCheckConditionError, error: if _is_exception_of_unsupported_inquiry_page(error): raise chain(JSONInquiryException("JSON Inquiry command error"))
def connect(self): import socket try: socket_object = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) socket_object.connect(self._address) socket_object.settimeout(self._timeout) except: raise chain(ConnectionError) self._socket = socket_object
def ioctl_scsi_get_address(handle): size = _sizeof(structures.SCSI_ADDRESS) instance = structures.SCSI_ADDRESS.create_from_string('\x00' * size) instance.Length = size string = ctypes.c_buffer(structures.SCSI_ADDRESS.write_to_string(instance), size) try: _ = infi.wioctl.ioctl(handle, infi.wioctl.constants.IOCTL_SCSI_GET_ADDRESS, 0, 0, string, size) except infi.wioctl.errors.WindowsException, exception: if exception.winerror == infi.wioctl.constants.ERROR_ACCESS_DENIED: raise chain(infi.wioctl.errors.InvalidHandle(exception.winerror))
def get_json_data(self): """:returns: the json inquiry data from the system :rtype: dict""" from json import loads raw_data = self._get_json_inquiry_data() try: logger.debug("Got JSON Inquiry data: {}".format(raw_data)) return loads(raw_data) except ValueError: logger.debug("Inquiry response is invalid JSON format") raise chain(JSONInquiryException("ValueError"))
def has_partition_table(self): try: self.read_partition_table() return True except PartedRuntimeError, error: if "unrecognised disk label" in error.get_error_message(): pass elif "exceeds the loop-partition-table-impose" in error.get_error_message(): pass else: raise chain(InvalidPartitionTable())
def _get_json_inquiry_page(self, page=0xc5): from infi.asi import AsiCheckConditionError from infi.storagemodel.vendor.infinidat.infinibox.json_page import JSONInquiryPageBuffer try: unknown_page = self.device.get_scsi_inquiry_pages()[page] json_page = JSONInquiryPageBuffer() json_page.unpack(unknown_page.pack()) return json_page except AsiCheckConditionError as error: if _is_exception_of_unsupported_inquiry_page(error): raise chain(InquiryException("JSON Inquiry command error")) raise
def has_partition_table(self): try: self.read_partition_table() return True except PartedRuntimeError, error: if "unrecognised disk label" in error.get_error_message(): pass elif "exceeds the loop-partition-table-impose" in error.get_error_message( ): pass else: raise chain(InvalidPartitionTable())
def calc_byte_size(cls, class_name, fields): ctx = PackContext(None, fields) positions = SequentialRangeList() for field in fields: # we avoid list comprehension here so we'll know which field raised an error try: if not (field.pack_absolute_position_ref.is_static() and field.unpack_absolute_position_ref.is_static()): return None positions.extend(field.pack_absolute_position_ref.deref(ctx)) except: raise exceptools.chain(InstructBufferError("Error while calculating static byte size", ctx, class_name, field.attr_name())) return positions.max_stop()
def callable(*args, **kwargs): try: device = args[0] logger.debug("Sending SCSI command {!r} for device {!r}".format(func, safe_repr(device))) response = func(*args, **kwargs) logger.debug("Got response {!r}".format(response)) return func(*args, **kwargs) except AsiCheckConditionError, e: (key, code) = (e.sense_obj.sense_key, e.sense_obj.additional_sense_code.code_name) if (key, code) in CHECK_CONDITIONS_TO_CHECK: msg = "device {!r} got {} {}".format(device, key, code) logger.debug(msg) raise chain(RescanIsNeeded(msg)) raise
def _get_platform_specific_storagemodel_class(): # do platform-specific magic here. from .base import StorageModel as PlatformStorageModel # helps IDEs from importlib import import_module plat = get_platform_name() platform_module_string = "{}.{}".format(__name__, plat) platform_module = import_module(platform_module_string) try: PlatformStorageModel = getattr(platform_module, "{}StorageModel".format(plat.capitalize())) except AttributeError: msg = "Failed to import platform-specific storage model" logger.exception(msg) raise chain(ImportError(msg)) return PlatformStorageModel
def _get_platform_specific_mountmanager_class(): from .base import MountManager as PlatformMountManager from brownie.importing import import_string plat = get_platform_string().split('-')[0] platform_module_string = "{}.{}".format(__name__, plat) platform_module = import_string(platform_module_string) try: PlatformMountManager = getattr( platform_module, "{}MountManager".format(plat.capitalize())) except AttributeError: msg = "Failed to import platform-specific mount manager" logger.exception(msg) raise chain(ImportError(msg)) return PlatformMountManager
def _get_platform_specific_storagemodel_class(): # do platform-specific magic here. from .base import StorageModel as PlatformStorageModel # helps IDEs from importlib import import_module plat = get_platform_name() platform_module_string = "{}.{}".format(__name__, plat) platform_module = import_module(platform_module_string) try: PlatformStorageModel = getattr( platform_module, "{}StorageModel".format(plat.capitalize())) except AttributeError: msg = "Failed to import platform-specific storage model" logger.exception(msg) raise chain(ImportError(msg)) return PlatformStorageModel
def execute(commandname, args): from logging import getLogger log = getLogger() debug = log.debug from infi.execute import execute as _execute debug(u'executing {} {}'.format(commandname, ' '.join(args))) subprocess = _execute([commandname] + args) debug('waiting for it') subprocess.wait() debug('returncode = %s', subprocess.get_returncode()) debug('stdout = %s', subprocess.get_stdout()) debug('stderr = %s', subprocess.get_stderr()) if subprocess.get_returncode() != 0: raise chain(translate_mount_error(subprocess.get_returncode())())
def ioctl_scsi_get_address(handle): size = _sizeof(structures.SCSI_ADDRESS) instance = structures.SCSI_ADDRESS.create_from_string(b'\x00' * size) instance.Length = size string = ctypes.c_buffer(structures.SCSI_ADDRESS.write_to_string(instance), size).raw try: _ = infi.wioctl.ioctl(handle, infi.wioctl.constants.IOCTL_SCSI_GET_ADDRESS, 0, 0, string, size) except infi.wioctl.errors.WindowsException as exception: if exception.winerror == infi.wioctl.constants.ERROR_ACCESS_DENIED: raise chain(infi.wioctl.errors.InvalidHandle(exception.winerror)) instance = structures.SCSI_ADDRESS.create_from_string(string) return (instance.PortNumber, instance.PathId, instance.TargetId, instance.Lun)
def execute(commandname, args): from logging import getLogger log = getLogger() debug = log.debug from infi.execute import execute as _execute debug("executing {} {}".format(commandname, " ".join(args))) subprocess = _execute([commandname] + args) debug("waiting for it") subprocess.wait() debug("returncode = %s", subprocess.get_returncode()) debug("stdout = %s", subprocess.get_stdout()) debug("stderr = %s", subprocess.get_stderr()) if subprocess.get_returncode() != 0: raise chain(MountException(subprocess.get_returncode()))
def unpack(self, buffer): """Unpacks the object's fields from buffer.""" fields = self._all_fields() ctx = UnpackContext(self, fields, buffer) for field in fields: try: for prev_field in field.unpack_after: prev_field.unpack_value_ref(ctx) field.unpack_value_ref(ctx) except: raise exceptools.chain(InstructBufferError("Unpack error occurred", ctx, type(self), field.attr_name())) # Short-circuit: if we already have a static byte size, use that. if type(self).byte_size is not None: return type(self).byte_size return self.calc_byte_size()
def execute(command): from logging import getLogger log = getLogger(__name__) debug = log.debug from infi.execute import execute as _execute debug('executing %s', command) try: subprocess = _execute(command.split()) except: from infi.exceptools import chain raise chain(ServiceException) debug('waiting for it') subprocess.wait() debug('returncode = %s', subprocess.get_returncode()) debug('stdout = %s', subprocess.get_stdout()) debug('stderr = %s', subprocess.get_stderr()) if subprocess.get_returncode() != 0: raise ServiceException(subprocess.get_stderr())
def decorator(*args, **kwargs): counter = 10 while counter > 0: try: msg = "attempting to call {}, {} more retries" logger.debug(msg.format(func.__name__, counter)) return func(*args, **kwargs) except AsiCheckConditionError as e: (key, code) = (e.sense_obj.sense_key, e.sense_obj.additional_sense_code.code_name) msg = "got {} {}".format(key, code) if (key, code) != ('ILLEGAL_REQUEST', 'INSUFFICIENT RESOURCES'): logger.error(msg, exc_info=exc_info()) raise counter -= 1 if counter == 0: logger.error(msg, exc_info=exc_info()) raise chain(InsufficientResourcesError()) sleep(1)
def callable(*args, **kwargs): try: device = args[0] logger.debug("Sending SCSI command {!r} for device {!r}".format( func, _safe_repr(device))) response = func(*args, **kwargs) logger.debug("Got response {!r}".format(response)) return response except AsiCheckConditionError as e: if not e.sense_obj: msg = "got no sense from device {!r} during {!r}".format( _safe_repr(device), func) logger.error(msg, exc_info=exc_info()) raise chain(DeviceError(msg)) (key, code) = (e.sense_obj.sense_key, e.sense_obj.additional_sense_code.code_name) if (key, code) in CHECK_CONDITIONS_TO_CHECK: msg = "device {!r} got {} {}".format(device, key, code) logger.debug(msg) raise chain(RescanIsNeeded(msg)) raise except AsiRequestQueueFullError as e: msg = "got queue full from device {!r} during {!r}".format( _safe_repr(device), func) logger.debug(msg) raise chain(RescanIsNeeded(msg)) except AsiReservationConflictError as e: msg = "got reservation conflict from device {!r} during {!r}".format( _safe_repr(device), func) logger.debug(msg) raise chain(DeviceError(msg)) except AsiSCSIError as error: msg = "error with device {!r} during {!r}: {}".format( _safe_repr(device), func, error) logger.error(msg) raise chain(DeviceError(msg)) except (IOError, OSError, AsiOSError) as error: msg = "error with device {!r} during {!r}".format( _safe_repr(device), func) logger.error(msg, exc_info=exc_info()) raise chain(DeviceError(msg))
def catcher(*args, **kwargs): try: return func(*args, **kwargs) except InvalidHandle: raise chain(DeviceError())
def _get_key_from_json_page(self, key, page=0xc5): try: return self.get_json_data(page)[key] except KeyError: logger.debug("key {} does not exists in JSON response".format(key)) raise chain(InquiryException("KeyError: {}".format(key)))