Example #1
0
    def _ensure_share_mounted(self, share):
        m = re.search(self.SHARE_FORMAT_REGEX, share)
        if not m:
            msg = (
                _("Invalid Virtuozzo Storage share specification: %r. "
                  "Must be: [MDS1[,MDS2],...:/]<CLUSTER NAME>[:PASSWORD].") %
                share)
            raise exception.VzStorageException(msg)
        cluster_name = m.group(2)

        if share in self.shares:
            mnt_flags = json.loads(self.shares[share])
        else:
            mnt_flags = []

        if '-l' not in mnt_flags:
            # If logging path is not specified in shares config
            # set up logging to non-default path, so that it will
            # be possible to mount the same cluster to another mount
            # point by hand with default options.
            mnt_flags.extend(
                ['-l',
                 '/var/log/vstorage/%s/cinder.log.gz' % cluster_name])

        self._remotefsclient.mount(share, mnt_flags)
Example #2
0
    def do_setup(self, context):
        """Any initialization the volume driver does while starting."""
        super(VZStorageDriver, self).do_setup(context)

        config = self.configuration.vzstorage_shares_config
        if not os.path.exists(config):
            msg = (_("VzStorage config file at %(config)s doesn't exist.") % {
                'config': config
            })
            LOG.error(msg)
            raise exception.VzStorageException(msg)

        if not os.path.isabs(self.base):
            msg = _("Invalid mount point base: %s.") % self.base
            LOG.error(msg)
            raise exception.VzStorageException(msg)

        used_ratio = self.configuration.vzstorage_used_ratio
        if not ((used_ratio > 0) and (used_ratio <= 1)):
            msg = _("VzStorage config 'vzstorage_used_ratio' invalid. "
                    "Must be > 0 and <= 1.0: %s.") % used_ratio
            LOG.error(msg)
            raise exception.VzStorageException(msg)

        self.shares = {}

        # Check if mount.fuse.pstorage is installed on this system;
        # note that we don't need to be root to see if the package
        # is installed.
        package = 'mount.fuse.pstorage'
        try:
            self._execute(package, check_exit_code=False, run_as_root=False)
        except OSError as exc:
            if exc.errno == errno.ENOENT:
                msg = _('%s is not installed.') % package
                raise exception.VzStorageException(msg)
            else:
                raise

        self.configuration.nas_secure_file_operations = 'true'
        self.configuration.nas_secure_file_permissions = 'true'
Example #3
0
    def _delete_snapshot_qcow2(self, snapshot):
        info_path = self._local_path_volume_info(snapshot.volume)
        snap_info = self._read_info_file(info_path, empty_if_missing=True)
        if snapshot.id not in snap_info:
            LOG.warning("Snapshot %s doesn't exist in snap_info",
                        snapshot.id)
            return

        snap_file = os.path.join(self._local_volume_dir(snapshot.volume),
                                 snap_info[snapshot.id])
        active_file = os.path.join(self._local_volume_dir(snapshot.volume),
                                   snap_info['active'])
        higher_file = self._get_higher_image_path(snapshot)
        if higher_file:
            higher_file = os.path.join(self._local_volume_dir(snapshot.volume),
                                       higher_file)
        elif active_file != snap_file:
            msg = (_("Expected higher file exists for snapshot %s") %
                   snapshot.id)
            raise exception.VzStorageException(msg)

        img_info = self._qemu_img_info(snap_file, snapshot.volume.name)
        base_file = os.path.join(self._local_volume_dir(snapshot.volume),
                                 img_info.backing_file)

        super(VZStorageDriver, self)._delete_snapshot(snapshot)

        def _qemu_info_cache(fn):
            return fn + ".qemu_img_info"

        def _update_backing_file(info_src, info_dst):
            with open(info_src, 'r') as fs, open(info_dst, 'r') as fd:
                src = json.load(fs)
                dst = json.load(fd)
            dst['backing_file'] = src['backing_file']
            with open(info_dst, 'w') as fdw:
                json.dump(dst, fdw)

        if snap_file != active_file:
            # mv snap_file.info higher_file.info
            _update_backing_file(
                _qemu_info_cache(snap_file),
                _qemu_info_cache(higher_file))
            self._delete(_qemu_info_cache(snap_file))
        elif snapshot.volume.status == 'in-use':
            # mv base_file.info snap_file.info
            _update_backing_file(
                _qemu_info_cache(base_file),
                _qemu_info_cache(snap_file))
            self._delete(_qemu_info_cache(base_file))
        else:
            # rm snap_file.info
            self._delete(_qemu_info_cache(snap_file))
Example #4
0
    def delete_volume(self, volume):
        """Deletes a logical volume."""
        if not volume['provider_location']:
            msg = (_('Volume %s does not have provider_location '
                     'specified, skipping.') % volume['name'])
            LOG.error(msg)
            raise exception.VzStorageException(msg)

        self._ensure_share_mounted(volume['provider_location'])
        volume_dir = self._local_volume_dir(volume)
        mounted_path = os.path.join(volume_dir,
                                    self.get_active_image_from_info(volume))
        if os.path.exists(mounted_path):
            self._delete(mounted_path)
        else:
            LOG.info(
                _LI("Skipping deletion of volume %s "
                    "as it does not exist."), mounted_path)

        info_path = self._local_path_volume_info(volume)
        self._delete(info_path)