Beispiel #1
0
    def _create(self, share, snap_name, pool_device, request, uvisible,
                snap_type, writable):
        if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
            e_msg = ('Snapshot with name: %s already exists for the '
                     'share: %s' % (snap_name, share.name))
            handle_exception(Exception(e_msg), request)

        try:
            real_name = ('%s_%s' % (share.name, snap_name))
            snap_size = 0
            qgroup_id = '0/na'
            if (snap_type != 'receiver'):
                add_snap(share.pool.name, pool_device, share.subvol_name,
                         real_name, share_prepend=False, readonly=not writable)
                snap_id = share_id(share.pool.name, pool_device, real_name)
                qgroup_id = ('0/%s' % snap_id)
                snap_size = share_usage(share.pool.name, pool_device,
                                        qgroup_id)
            s = Snapshot(share=share, name=snap_name, real_name=real_name,
                         size=snap_size, qgroup=qgroup_id,
                         uvisible=uvisible, snap_type=snap_type,
                         writable=writable)
            s.save()
            return Response(SnapshotSerializer(s).data)
        except Exception, e:
            e_msg = ('Failed to create snapshot due to a system error.')
            logger.error(e_msg)
            logger.exception(e)
            handle_exception(Exception(e_msg), request)
Beispiel #2
0
    def _create(self, share, snap_name, request, uvisible, snap_type,
                writable):
        if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
            e_msg = ('Snapshot(%s) already exists for the Share(%s).' %
                     (snap_name, share.name))
            handle_exception(Exception(e_msg), request)

        snap_size = 0
        qgroup_id = '0/na'
        if (snap_type == 'replication'):
            writable = False
        add_snap(share.pool, share.subvol_name, snap_name, writable)
        snap_id = share_id(share.pool, snap_name)
        qgroup_id = ('0/%s' % snap_id)
        qgroup_assign(qgroup_id, share.pqgroup,
                      ('%s/%s' % (settings.MNT_PT, share.pool.name)))
        snap_size, eusage = share_usage(share.pool, qgroup_id)
        s = Snapshot(share=share,
                     name=snap_name,
                     real_name=snap_name,
                     size=snap_size,
                     qgroup=qgroup_id,
                     uvisible=uvisible,
                     snap_type=snap_type,
                     writable=writable)
        s.save()
        return Response(SnapshotSerializer(s).data)
Beispiel #3
0
    def _create(self, share, snap_name, request, uvisible,
                snap_type, writable):
        if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
            # Note e_msg is consumed by replication/util.py create_snapshot()
            e_msg = ('Snapshot ({}) already exists for '
                     'the share ({}).').format(snap_name, share.name)
            handle_exception(Exception(e_msg), request)

        snap_size = 0
        qgroup_id = '0/na'
        if (snap_type == 'replication'):
            writable = False
        add_snap(share.pool, share.subvol_name, snap_name, writable)
        snap_id = share_id(share.pool, snap_name)
        qgroup_id = ('0/%s' % snap_id)
        if share.pqgroup is not settings.MODEL_DEFS['pqgroup']:
            pool_mnt_pt = '{}{}'.format(settings.MNT_PT, share.pool.name)
            qgroup_assign(qgroup_id, share.pqgroup, pool_mnt_pt)
        snap_size, eusage = volume_usage(share.pool, qgroup_id)
        s = Snapshot(share=share, name=snap_name, real_name=snap_name,
                     size=snap_size, qgroup=qgroup_id,
                     uvisible=uvisible, snap_type=snap_type,
                     writable=writable)
        # The following share.save() was informed by test_snapshot.py
        share.save()
        s.save()
        return Response(SnapshotSerializer(s).data)
Beispiel #4
0
def import_snapshots(share):
    snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name),
                         share.name)
    snaps = [s.name for s in Snapshot.objects.filter(share=share)]
    for s in snaps:
        if (s not in snaps_d):
            logger.debug('Removing, missing on disk, snapshot db entry ({}) '
                         'from share ({}).'.format(s, share.name))
            Snapshot.objects.get(share=share, name=s).delete()
    for s in snaps_d:
        if (s in snaps):
            so = Snapshot.objects.get(share=share, name=s)
        else:
            logger.debug('Adding, missing in db, on disk snapshot ({}) '
                         'against share ({}).'.format(s, share.name))
            so = Snapshot(share=share, name=s, real_name=s,
                          writable=snaps_d[s][1], qgroup=snaps_d[s][0])
        rusage, eusage = volume_usage(share.pool, snaps_d[s][0])
        if (rusage != so.rusage or eusage != so.eusage):
            so.rusage = rusage
            so.eusage = eusage
            update_shareusage_db(s, rusage, eusage)
        else:
            update_shareusage_db(s, rusage, eusage, UPDATE_TS)
        so.save()
Beispiel #5
0
    def _create(self, share, snap_name, pool_device, request, uvisible,
                snap_type, writable):
        if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
            e_msg = ('Snapshot(%s) already exists for the Share(%s).' %
                     (snap_name, share.name))
            handle_exception(Exception(e_msg), request)

        real_name = snap_name
        snap_size = 0
        qgroup_id = '0/na'
        if (snap_type != 'receiver'):
            if (snap_type == 'replication'):
                writable = False
            add_snap(share.pool, pool_device, share.subvol_name,
                     real_name, readonly=not writable)
            snap_id = share_id(share.pool, pool_device, real_name)
            qgroup_id = ('0/%s' % snap_id)
            snap_size = share_usage(share.pool, pool_device,
                                    qgroup_id)
        s = Snapshot(share=share, name=snap_name, real_name=real_name,
                     size=snap_size, qgroup=qgroup_id,
                     uvisible=uvisible, snap_type=snap_type,
                     writable=writable)
        s.save()
        return Response(SnapshotSerializer(s).data)
def import_snapshots(share):
    snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name),
                         share.name)
    snaps = [s.name for s in Snapshot.objects.filter(share=share)]
    for s in snaps:
        if (s not in snaps_d):
            Snapshot.objects.get(share=share, name=s).delete()
    for s in snaps_d:
        if (s in snaps):
            so = Snapshot.objects.get(share=share, name=s)
        else:
            so = Snapshot(share=share, name=s, real_name=s,
                          writable=snaps_d[s][1], qgroup=snaps_d[s][0])
        rusage, eusage = volume_usage(share.pool, snaps_d[s][0])
        ts = datetime.utcnow().replace(tzinfo=utc)
        if (rusage != so.rusage or eusage != so.eusage):
            so.rusage = rusage
            so.eusage = eusage
            su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts)
            su.save()
        else:
            try:
                su = ShareUsage.objects.filter(name=s).latest('id')
                su.ts = ts
                su.count += 1
            except ShareUsage.DoesNotExist:
                su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage,
                                ts=ts)
            finally:
                su.save()
        so.save()
Beispiel #7
0
    def _create(self, share, snap_name, request, uvisible, snap_type, writable):
        if Snapshot.objects.filter(share=share, name=snap_name).exists():
            # Note e_msg is consumed by replication/util.py create_snapshot()
            e_msg = ("Snapshot ({}) already exists for the share ({}).").format(
                snap_name, share.name
            )
            handle_exception(Exception(e_msg), request)

        snap_size = 0
        qgroup_id = "0/na"
        if snap_type == "replication":
            writable = False
        add_snap(share, snap_name, writable)
        snap_id = share_id(share.pool, snap_name)
        qgroup_id = "0/{}".format(snap_id)
        if share.pqgroup != settings.MODEL_DEFS["pqgroup"]:
            qgroup_assign(qgroup_id, share.pqgroup, share.pool.mnt_pt)
        snap_size, eusage = volume_usage(share.pool, qgroup_id)
        s = Snapshot(
            share=share,
            name=snap_name,
            real_name=snap_name,
            size=snap_size,
            qgroup=qgroup_id,
            uvisible=uvisible,
            snap_type=snap_type,
            writable=writable,
        )
        # The following share.save() was informed by test_snapshot.py
        share.save()
        s.save()
        return Response(SnapshotSerializer(s).data)
Beispiel #8
0
    def _create(self, share, snap_name, pool_device, request, uvisible,
                snap_type):
        if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
            e_msg = ('Snapshot with name: %s already exists for the '
                     'share: %s' % (snap_name, share.name))
            handle_exception(Exception(e_msg), request)

        try:
            real_name = ('%s_%s' % (share.name, snap_name))
            snap_size = 0
            qgroup_id = '0/na'
            if (snap_type != 'receiver'):
                add_snap(share.pool.name,
                         pool_device,
                         share.subvol_name,
                         real_name,
                         share_prepend=False)
                snap_id = share_id(share.pool.name, pool_device, real_name)
                qgroup_id = ('0/%s' % snap_id)
                snap_size = share_usage(share.pool.name, pool_device,
                                        qgroup_id)
            s = Snapshot(share=share,
                         name=snap_name,
                         real_name=real_name,
                         size=snap_size,
                         qgroup=qgroup_id,
                         uvisible=uvisible,
                         snap_type=snap_type)
            s.save()
            return Response(SnapshotSerializer(s).data)
        except Exception, e:
            e_msg = ('Failed to create snapshot due to a system error.')
            logger.error(e_msg)
            logger.exception(e)
            handle_exception(Exception(e_msg), request)
Beispiel #9
0
 def post(self, request, sname):
     snap_name = request.DATA['name']
     share = Share.objects.get(name=sname)
     pool_device = Disk.objects.filter(pool=share.pool)[0].name
     s = Snapshot(share=share, name=snap_name)
     add_snap(share.pool.name, pool_device, sname, snap_name)
     s.save()
     return Response(SnapshotSerializer(s).data)
Beispiel #10
0
def import_snapshots(share):
    snaps_d = snaps_info(share.pool.mnt_pt, share.name)
    snaps = [s.name for s in Snapshot.objects.filter(share=share)]
    for s in snaps:
        if s not in snaps_d:
            logger.debug("Removing, missing on disk, snapshot db entry ({}) "
                         "from share ({}).".format(s, share.name))
            Snapshot.objects.get(share=share, name=s).delete()
    for s in snaps_d:
        if s in snaps:
            so = Snapshot.objects.get(share=share, name=s)
        else:
            logger.debug("Adding, missing in db, on disk snapshot ({}) "
                         "against share ({}).".format(s, share.name))
            so = Snapshot(
                share=share,
                name=s,
                real_name=s,
                writable=snaps_d[s][1],
                qgroup=snaps_d[s][0],
            )
        rusage, eusage = volume_usage(share.pool, snaps_d[s][0])
        if rusage != so.rusage or eusage != so.eusage:
            so.rusage = rusage
            so.eusage = eusage
            update_shareusage_db(s, rusage, eusage)
        else:
            update_shareusage_db(s, rusage, eusage, UPDATE_TS)
        so.save()
Beispiel #11
0
def import_snapshots(share):
    snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name),
                         share.name)
    snaps = [s.name for s in Snapshot.objects.filter(share=share)]
    for s in snaps:
        if (s not in snaps_d):
            logger.debug('Removing, missing on disk, snapshot db entry ({}) '
                         'from share ({}).'.format(s, share.name))
            Snapshot.objects.get(share=share, name=s).delete()
    for s in snaps_d:
        if (s in snaps):
            so = Snapshot.objects.get(share=share, name=s)
        else:
            logger.debug('Adding, missing in db, on disk snapshot ({}) '
                         'against share ({}).'.format(s, share.name))
            so = Snapshot(share=share,
                          name=s,
                          real_name=s,
                          writable=snaps_d[s][1],
                          qgroup=snaps_d[s][0])
        rusage, eusage = volume_usage(share.pool, snaps_d[s][0])
        if (rusage != so.rusage or eusage != so.eusage):
            so.rusage = rusage
            so.eusage = eusage
            update_shareusage_db(s, rusage, eusage)
        else:
            update_shareusage_db(s, rusage, eusage, UPDATE_TS)
        so.save()
def import_snapshots(share):
    snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name),
                         share.name)
    snaps = [s.name for s in Snapshot.objects.filter(share=share)]
    for s in snaps:
        if (s not in snaps_d):
            Snapshot.objects.get(share=share, name=s).delete()
    for s in snaps_d:
        if (s in snaps):
            so = Snapshot.objects.get(share=share, name=s)
        else:
            so = Snapshot(share=share,
                          name=s,
                          real_name=s,
                          writable=snaps_d[s][1],
                          qgroup=snaps_d[s][0])
        rusage, eusage = volume_usage(share.pool, snaps_d[s][0])
        ts = datetime.utcnow().replace(tzinfo=utc)
        if (rusage != so.rusage or eusage != so.eusage):
            so.rusage = rusage
            so.eusage = eusage
            su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts)
            su.save()
        else:
            try:
                su = ShareUsage.objects.filter(name=s).latest('id')
                su.ts = ts
                su.count += 1
            except ShareUsage.DoesNotExist:
                su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts)
            finally:
                su.save()
        so.save()
Beispiel #13
0
    def _create(self, share, snap_name, request, uvisible,
                snap_type, writable):
        if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
            e_msg = ('Snapshot(%s) already exists for the Share(%s).' %
                     (snap_name, share.name))
            handle_exception(Exception(e_msg), request)

        snap_size = 0
        qgroup_id = '0/na'
        if (snap_type == 'replication'):
            writable = False
        add_snap(share.pool, share.subvol_name, snap_name, writable)
        snap_id = share_id(share.pool, snap_name)
        qgroup_id = ('0/%s' % snap_id)
        qgroup_assign(qgroup_id, share.pqgroup, ('%s/%s' % (settings.MNT_PT,
                                                            share.pool.name)))
        snap_size, eusage = volume_usage(share.pool, qgroup_id)
        s = Snapshot(share=share, name=snap_name, real_name=snap_name,
                     size=snap_size, qgroup=qgroup_id,
                     uvisible=uvisible, snap_type=snap_type,
                     writable=writable)
        s.save()
        return Response(SnapshotSerializer(s).data)
Beispiel #14
0
    def post(self, request, sname, snap_name, command=None):
        share = self._validate_share(sname, request)
        pool_device = Disk.objects.filter(pool=share.pool)[0].name
        if (command is None):
            if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
                e_msg = ('Snapshot with name: %s already exists for the '
                         'share: %s' % (snap_name, sname))
                handle_exception(Exception(e_msg), request)

            add_snap(share.pool.name, pool_device, share.subvol_name,
                     snap_name)
            snap_id = share_id(share.pool.name, pool_device, snap_name)
            qgroup_id = ('0/%s' % snap_id)
            s = Snapshot(share=share, name=snap_name, qgroup=qgroup_id)
            s.save()
            return Response(SnapshotSerializer(s).data)

        if (command == 'rollback'):
            try:
                snap = Snapshot.objects.get(share=share, name=snap_name)
            except:
                e_msg = ('Snapshot with name: %s does not exist for the '
                         'share: %s' % (snap_name, sname))
                handle_exception(Exception(e_msg), request)
            try:
                rollback_snap(snap_name, sname, share.subvol_name,
                              share.pool.name, pool_device)
                share.subvol_name = snap_name
                update_quota(share.pool.name, pool_device, snap.qgroup,
                             share.size * 1024)
                share.qgroup = snap.qgroup
                share.save()
                snap.delete()
                return Response()
            except Exception, e:
                logger.exception(e)
                handle_exception(e, request)
Beispiel #15
0
    def post(self, request, sname, snap_name, command=None):
        share = self._validate_share(sname, request)
        pool_device = Disk.objects.filter(pool=share.pool)[0].name
        if (command is None):
            if (Snapshot.objects.filter(share=share, name=snap_name).exists()):
                e_msg = ('Snapshot with name: %s already exists for the '
                         'share: %s' % (snap_name, sname))
                handle_exception(Exception(e_msg), request)

            add_snap(share.pool.name, pool_device, share.subvol_name,
                     snap_name)
            snap_id = share_id(share.pool.name, pool_device, snap_name)
            qgroup_id = ('0/%s' % snap_id)
            s = Snapshot(share=share, name=snap_name, qgroup=qgroup_id)
            s.save()
            return Response(SnapshotSerializer(s).data)

        if (command == 'rollback'):
            try:
                snap = Snapshot.objects.get(share=share, name=snap_name)
            except:
                e_msg = ('Snapshot with name: %s does not exist for the '
                         'share: %s' % (snap_name, sname))
                handle_exception(Exception(e_msg), request)
            try:
                rollback_snap(snap_name, sname, share.subvol_name,
                              share.pool.name, pool_device)
                share.subvol_name = snap_name
                update_quota(share.pool.name, pool_device, snap.qgroup,
                             share.size * 1024)
                share.qgroup = snap.qgroup
                share.save()
                snap.delete()
                return Response()
            except Exception, e:
                logger.exception(e)
                handle_exception(e, request)
Beispiel #16
0
def import_snapshots(share):
    snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name),
                         share.name)
    snaps = [s.name for s in Snapshot.objects.filter(share=share)]
    for s in snaps:
        if (s not in snaps_d):
            Snapshot.objects.get(share=share, name=s).delete()
    for s in snaps_d:
        if (s in snaps):
            so = Snapshot.objects.get(share=share, name=s)
        else:
            so = Snapshot(share=share,
                          name=s,
                          real_name=s,
                          writable=snaps_d[s][1],
                          qgroup=snaps_d[s][0])
        rusage, eusage = volume_usage(share.pool, snaps_d[s][0])
        if (rusage != so.rusage or eusage != so.eusage):
            so.rusage = rusage
            so.eusage = eusage
            update_shareusage_db(s, rusage, eusage)
        else:
            update_shareusage_db(s, rusage, eusage, UPDATE_TS)
        so.save()
Beispiel #17
0
    def post(self, request, uuid):
        """
        import a pool with given uuid
        """
        disks = Disk.objects.filter(btrfs_uuid=uuid)

        if (not btrfs_importable(disks[0].name)):
            e_msg = ('btrfs check failed on device: %s Cannot automatically '
                     'import the pool with uuid: %s' % (disks[0].name, uuid))
            handle_exception(Exception(e_msg), request)

        #get name of the pool
        pname = btrfs_label(uuid)

        #mount the pool
        mount_root(pname, '/dev/%s' % disks[0].name)
        pool_mnt_pt = '%s/%s' % (settings.MNT_PT, pname)

        #get raid level
        raid_level = btrfs_raid_level(pname)
        if (raid_level is None):
            umount_root(pool_mnt_pt)
            e_msg = ('Problem while probing for the raid level of the pool.'
                     'Cannot automatically import the pool with uuid: %s' %
                     uuid)
            handle_exception(Exception(e_msg), request)

        #check for shares in the pool
        subvols, e, rc = subvol_list_helper(pool_mnt_pt)
        snap_list = snapshot_list(pool_mnt_pt)
        share_map = {}
        for s in subvols:
            s_fields = s.split()
            if (s_fields[-1] not in snap_list):
                share_map[s_fields[-1]] = s_fields[1]

        entries = os.listdir(pool_mnt_pt)
        e_msg_prefix = ('Only btrfs filesystem with nothing but subvolumes in '
                        'it can be imported.')
        for e in entries:
            if (os.path.isfile('%s/%s' % (pool_mnt_pt, e))):
                e_msg = ('%s Unexpected file %s found. Due to this reason, '
                         'pool with uuid: %s cannot be imported' %
                         (e_msg_prefix, e, uuid))
                handle_exception(Exception(e_msg), request)
            elif (e not in share_map):
                e_msg = ('%s Unexpected directory %s found. Due to this '
                         'reason, pool with uuid: %s cannot be imported' %
                         (e_msg_prefix, e, uuid))
                handle_exception(Exception(e_msg), request)

        #add pool model
        pool_size = self._pool_size(disks, raid_level)
        p = Pool(name=pname, raid=raid_level, size=pool_size, uuid=uuid)
        p.save()

        #import shares
        for s in share_map.keys():
            so = Share(pool=p,
                       qgroup='0/%s' % share_map[s],
                       name=s,
                       size=qgroup_size,
                       subvol_name=s,
                       replica=False)
            so.save()

            #import snapshots?
            for snap in snap_list:
                snap_fields = snap.split('_')
                snap_name = snap_fields[-1]
                sname = '_'.join(snap_fields[0:-1])
                if (sname == s):
                    snapo = Snapshot(share=so,
                                     name=snap_name,
                                     real_name=snap,
                                     qgroup=qgroup_id)
                    snapo.save()
    def post(self, request, uuid):
        """
        import a pool with given uuid
        """
        disks = Disk.objects.filter(btrfs_uuid=uuid)

        if (not btrfs_importable(disks[0].name)):
            e_msg = ('btrfs check failed on device: %s Cannot automatically '
                     'import the pool with uuid: %s' % (disks[0].name, uuid))
            handle_exception(Exception(e_msg), request)


        #get name of the pool
        pname = btrfs_label(uuid)

        #mount the pool
        mount_root(pname, '/dev/%s' % disks[0].name)
        pool_mnt_pt = '%s/%s' % (settings.MNT_PT, pname)

        #get raid level
        raid_level = btrfs_raid_level(pname)
        if (raid_level is None):
            umount_root(pool_mnt_pt)
            e_msg = ('Problem while probing for the raid level of the pool.'
                     'Cannot automatically import the pool with uuid: %s' %
                     uuid)
            handle_exception(Exception(e_msg), request)

        #check for shares in the pool
        subvols, e, rc = subvol_list_helper(pool_mnt_pt)
        snap_list = snapshot_list(pool_mnt_pt)
        share_map = {}
        for s in subvols:
            s_fields = s.split()
            if (s_fields[-1] not in snap_list):
                share_map[s_fields[-1]] = s_fields[1]

        entries = os.listdir(pool_mnt_pt)
        e_msg_prefix = ('Only btrfs filesystem with nothing but subvolumes in '
                        'it can be imported.')
        for e in entries:
            if (os.path.isfile('%s/%s' % (pool_mnt_pt, e))):
                e_msg = ('%s Unexpected file %s found. Due to this reason, '
                         'pool with uuid: %s cannot be imported' %
                         (e_msg_prefix, e, uuid))
                handle_exception(Exception(e_msg), request)
            elif (e not in share_map):
                e_msg = ('%s Unexpected directory %s found. Due to this '
                         'reason, pool with uuid: %s cannot be imported' %
                         (e_msg_prefix, e, uuid))
                handle_exception(Exception(e_msg), request)

        #add pool model
        pool_size = self._pool_size(disks, raid_level)
        p = Pool(name=pname, raid=raid_level, size=pool_size, uuid=uuid)
        p.save()

        #import shares
        for s in share_map.keys():
            so = Share(pool=p, qgroup='0/%s' % share_map[s], name=s,
                       size=qgroup_size, subvol_name=s, replica=False)
            so.save()

            #import snapshots?
            for snap in snap_list:
                snap_fields = snap.split('_')
                snap_name = snap_fields[-1]
                sname = '_'.join(snap_fields[0:-1])
                if (sname == s):
                    snapo = Snapshot(share=so, name=snap_name,
                                     real_name=snap, qgroup=qgroup_id)
                    snapo.save()