def _mount_avfs(self): """Mounts the AVFS filesystem.""" self._paths['avfs'] = tempfile.mkdtemp(prefix='image_mounter_avfs_') # start by calling the mountavfs command to initialize avfs _util.check_call_(['avfsd', self._paths['avfs'], '-o', 'allow_other'], stdout=subprocess.PIPE) # no multifile support for avfs avfspath = self._paths['avfs'] + '/' + os.path.abspath(self.paths[0]) + '#' targetraw = os.path.join(self.mountpoint, 'avfs') os.symlink(avfspath, targetraw) logger.debug("Symlinked {} with {}".format(avfspath, targetraw)) raw_path = self.get_raw_path() logger.debug("Raw path to avfs is {}".format(raw_path)) if raw_path is None: raise MountpointEmptyError()
def mount(self): """Mounts the base image on a temporary location using the mount method stored in :attr:`method`. If mounting was successful, :attr:`mountpoint` is set to the temporary mountpoint. If :attr:`read_write` is enabled, a temporary read-write cache is also created and stored in :attr:`rwpath`. :return: whether the mounting was successful :rtype: bool """ if self.parser.casename: self.mountpoint = tempfile.mkdtemp(prefix='image_mounter_', suffix='_' + self.parser.casename) else: self.mountpoint = tempfile.mkdtemp(prefix='image_mounter_') if self.read_write: self.rwpath = tempfile.mkstemp(prefix="image_mounter_rw_cache_")[1] disk_type = self.get_disk_type() methods = self._get_mount_methods(disk_type) cmds = [] for method in methods: if method == 'avfs': # avfs does not participate in the fallback stuff, unfortunately self._mount_avfs() self.disk_mounter = method self.was_mounted = True self.is_mounted = True return elif method == 'dummy': os.rmdir(self.mountpoint) self.mountpoint = "" logger.debug("Raw path to dummy is {}".format( self.get_raw_path())) self.disk_mounter = method self.was_mounted = True self.is_mounted = True return elif method == 'xmount': cmds.append([ 'xmount', '--in', 'ewf' if disk_type == 'encase' else 'dd' ]) if self.read_write: cmds[-1].extend(['--rw', self.rwpath]) cmds[-1].extend( self.paths) # specify all paths, xmount needs this :( cmds[-1].append(self.mountpoint) elif method == 'affuse': cmds.extend([[ 'affuse', '-o', 'allow_other', self.paths[0], self.mountpoint ], ['affuse', self.paths[0], self.mountpoint]]) elif method == 'ewfmount': cmds.extend([[ 'ewfmount', '-X', 'allow_other', self.paths[0], self.mountpoint ], ['ewfmount', self.paths[0], self.mountpoint]]) elif method == 'vmware-mount': cmds.append([ 'vmware-mount', '-r', '-f', self.paths[0], self.mountpoint ]) elif method == 'nbd': _util.check_output_(['modprobe', 'nbd', 'max_part=63']) # Load nbd driver try: self._paths['nbd'] = _util.get_free_nbd_device( ) # Get free nbd device except NoNetworkBlockAvailableError: logger.warning("No free network block device found.", exc_info=True) raise cmds.extend([[ 'qemu-nbd', '--read-only', '-c', self._paths['nbd'], self.paths[0] ]]) else: raise ArgumentError("Unknown mount method {0}".format( self.disk_mounter)) for cmd in cmds: # noinspection PyBroadException try: _util.check_call_(cmd, stdout=subprocess.PIPE) # mounting does not seem to be instant, add a timer here time.sleep(.1) except Exception: logger.warning( 'Could not mount {0}, trying other method'.format( self.paths[0]), exc_info=True) continue else: raw_path = self.get_raw_path() logger.debug("Raw path to disk is {}".format(raw_path)) self.disk_mounter = cmd[0] if raw_path is None: raise MountpointEmptyError() self.was_mounted = True self.is_mounted = True return logger.error('Unable to mount {0}'.format(self.paths[0])) os.rmdir(self.mountpoint) self.mountpoint = "" raise MountError()