Beispiel #1
0
 def put(self, request, sid):
     with self._handle_exception(request):
         share = self._validate_share(request, sid)
         if ('size' in request.data):
             new_size = self._validate_share_size(request, share.pool)
             qid = qgroup_id(share.pool, share.subvol_name)
             cur_rusage, cur_eusage = volume_usage(share.pool, qid)
             if (new_size < cur_rusage):
                 e_msg = ('Unable to resize because requested new '
                          'size {} KB is less than current usage {} KB '
                          'of the share.').format(new_size, cur_rusage)
                 handle_exception(Exception(e_msg), request)
             # quota maintenance
             if share.pool.quotas_enabled:
                 # Only try create / update quotas if they are enabled,
                 # pqgroup of PQGROUP_DEFAULT (-1/-1) indicates no pqgroup,
                 # ie quotas were disabled when update was requested.
                 if share.pqgroup == PQGROUP_DEFAULT or \
                         not share.pqgroup_exist:
                     # if quotas were disabled or pqgroup non-existent.
                     share.pqgroup = qgroup_create(share.pool)
                     share.save()
                 if share.pqgroup is not PQGROUP_DEFAULT:
                     # Only update quota and assign if now non default as
                     # default can also indicate Read-only fs at this point.
                     update_quota(share.pool, share.pqgroup,
                                  new_size * 1024)
                     share_pqgroup_assign(share.pqgroup, share)
             else:
                 # Our pool's quotas are disabled so reset pqgroup to -1/-1.
                 if share.pqgroup != PQGROUP_DEFAULT:
                     # Only reset if necessary
                     share.pqgroup = PQGROUP_DEFAULT
                     share.save()
             share.size = new_size
         if ('compression' in request.data):
             new_compression = self._validate_compression(request)
             if (share.compression_algo != new_compression):
                 share.compression_algo = new_compression
                 mnt_pt = '%s%s' % (settings.MNT_PT, share.name)
                 if (new_compression == 'no'):
                     new_compression = ''
                 set_property(mnt_pt, 'compression', new_compression)
         share.save()
         return Response(ShareSerializer(share).data)
Beispiel #2
0
def create_clone(share, new_name, request, logger, snapshot=None):
    # if snapshot is None, create clone of the share.
    # If it's not, then clone it.
    if re.match(settings.SHARE_REGEX + "$", new_name) is None:
        e_msg = ("Clone name is invalid. It must start with a letter and can "
                 "contain letters, digits, _, . and - characters.")
        handle_exception(Exception(e_msg), request)
    if Share.objects.filter(name=new_name).exists():
        e_msg = "Another share with name ({}) already exists.".format(new_name)
        handle_exception(Exception(e_msg), request)
    if Snapshot.objects.filter(share=share, name=new_name).exists():
        e_msg = ("Snapshot with name ({}) already exists for the "
                 "share ({}). Choose a different name.").format(
                     new_name, share.name)
        handle_exception(Exception(e_msg), request)

    try:
        share_name = share.subvol_name
        snap = None
        if snapshot is not None:
            snap = snapshot.real_name
        add_clone(share.pool, share_name, new_name, snapshot=snap)
        snap_id = share_id(share.pool, new_name)
        qgroup_id = "0/{}".format(snap_id)
        pqid = qgroup_create(share.pool)
        new_share = Share(
            pool=share.pool,
            qgroup=qgroup_id,
            pqgroup=pqid,
            name=new_name,
            size=share.size,
            subvol_name=new_name,
        )
        new_share.save()
        if pqid != PQGROUP_DEFAULT:
            update_quota(new_share.pool, pqid, new_share.size * 1024)
            share_pqgroup_assign(pqid, new_share)
        # Mount our new clone share.
        # We independently mount all shares, data pool or system pool, in /mnt2/name
        mnt_pt = "{}{}".format(settings.MNT_PT, new_name)
        mount_share(new_share, mnt_pt)
        return Response(ShareSerializer(new_share).data)
    except Exception as e:
        handle_exception(e, request)
Beispiel #3
0
def create_clone(share, new_name, request, logger, snapshot=None):
    # if snapshot is None, create clone of the share.
    # If it's not, then clone it.
    if (re.match(settings.SHARE_REGEX + '$', new_name) is None):
        e_msg = ('Clone name is invalid. It must start with a letter and can'
                 ' contain letters, digits, _, . and - characters')
        handle_exception(Exception(e_msg), request)
    if (Share.objects.filter(name=new_name).exists()):
        e_msg = ('Another Share with name: %s already exists.' % new_name)
        handle_exception(Exception(e_msg), request)
    if (Snapshot.objects.filter(share=share, name=new_name).exists()):
        e_msg = ('Snapshot with name: %s already exists for the '
                 'share: %s. Choose a different name' % (new_name, share.name))
        handle_exception(Exception(e_msg), request)

    try:
        share_name = share.subvol_name
        snap = None
        if (snapshot is not None):
            snap = snapshot.real_name
        add_clone(share.pool, share_name, new_name, snapshot=snap)
        snap_id = share_id(share.pool, new_name)
        qgroup_id = ('0/%s' % snap_id)
        pqid = qgroup_create(share.pool)
        new_share = Share(pool=share.pool,
                          qgroup=qgroup_id,
                          pqgroup=pqid,
                          name=new_name,
                          size=share.size,
                          subvol_name=new_name)
        new_share.save()
        if pqid is not settings.MODEL_DEFS['pqgroup']:
            update_quota(new_share.pool, pqid, new_share.size * 1024)
            share_pqgroup_assign(pqid, new_share)
        # Mount our new clone share.
        mnt_pt = '{}{}'.format(settings.MNT_PT, new_name)
        mount_share(new_share, mnt_pt)
        return Response(ShareSerializer(new_share).data)
    except Exception as e:
        handle_exception(e, request)
Beispiel #4
0
def create_clone(share, new_name, request, logger, snapshot=None):
    # if snapshot is None, create clone of the share.
    # If it's not, then clone it.
    if (re.match(settings.SHARE_REGEX + '$', new_name) is None):
        e_msg = ('Clone name is invalid. It must start with a letter and can '
                 'contain letters, digits, _, . and - characters.')
        handle_exception(Exception(e_msg), request)
    if (Share.objects.filter(name=new_name).exists()):
        e_msg = 'Another share with name ({}) already exists.'.format(new_name)
        handle_exception(Exception(e_msg), request)
    if (Snapshot.objects.filter(share=share, name=new_name).exists()):
        e_msg = ('Snapshot with name ({}) already exists for the '
                 'share ({}). Choose a different name.').format(new_name,
                                                                share.name)
        handle_exception(Exception(e_msg), request)

    try:
        share_name = share.subvol_name
        snap = None
        if (snapshot is not None):
            snap = snapshot.real_name
        add_clone(share.pool, share_name, new_name, snapshot=snap)
        snap_id = share_id(share.pool, new_name)
        qgroup_id = ('0/%s' % snap_id)
        pqid = qgroup_create(share.pool)
        new_share = Share(pool=share.pool, qgroup=qgroup_id, pqgroup=pqid,
                          name=new_name, size=share.size, subvol_name=new_name)
        new_share.save()
        if pqid is not PQGROUP_DEFAULT:
            update_quota(new_share.pool, pqid, new_share.size * 1024)
            share_pqgroup_assign(pqid, new_share)
        # Mount our new clone share.
        mnt_pt = '{}{}'.format(settings.MNT_PT, new_name)
        mount_share(new_share, mnt_pt)
        return Response(ShareSerializer(new_share).data)
    except Exception as e:
        handle_exception(e, request)
Beispiel #5
0
    def post(self, request):
        # qgroup notes for shares. we need to create a qgroup prior to share
        # creation. qgroup ids 0/<subvol_id> automatically get created when a
        # subvolume(i.e., a Share or a Snapshot) is created. So let's create a
        # new qgroup: 2015/<some_number> whenever a Share is
        # created. <some_number> starts from 1 and is incremented as more
        # Shares are created. So, for the very first Share in a pool, it's
        # qgroup will be 1/1. 2015 is arbitrarily chose.

        # Before creating a new Share, we create the qgroup for it. And during
        # it's creation, we assign this qgroup to it. During it's creation a
        # 0/x qgroup will automatically be created, but it will become the
        # child of our explicitly-created qgroup(2015/x).

        # We will set the qgroup limit on our qgroup and it will enforce the
        # quota on every subvolume(i.e., Share and Snapshot) in that qgroup.

        # When a Share is deleted, we need to destroy two qgroups. One is it's
        # auto 0/x qgroup and the other is our explicitly-created 2015/y
        # qgroup.

        with self._handle_exception(request):
            pool_name = request.data.get('pool', None)
            try:
                pool = Pool.objects.get(name=pool_name)
            except:
                e_msg = 'Pool ({}) does not exist.'.format(pool_name)
                handle_exception(Exception(e_msg), request)
            compression = self._validate_compression(request)
            size = self._validate_share_size(request, pool)
            sname = request.data.get('sname', None)
            if ((sname is None or
                 re.match('%s$' % settings.SHARE_REGEX, sname) is None)):
                e_msg = ('Invalid characters in share name. Following are '
                         'allowed: letter(a-z or A-Z), digit(0-9), '
                         'hyphen(-), underscore(_) or a period(.).')
                handle_exception(Exception(e_msg), request)

            if (len(sname) > 254):
                # btrfs subvolume names cannot exceed 254 characters.
                e_msg = ('Share name length cannot exceed 254 characters.')
                handle_exception(Exception(e_msg), request)

            if (Share.objects.filter(name=sname).exists()):
                # Note e_msg is consumed by replication/util.py create_share()
                e_msg = ('Share ({}) already exists. Choose a '
                         'different name.').format(sname)
                handle_exception(Exception(e_msg), request)

            if (Pool.objects.filter(name=sname).exists()):
                e_msg = ('A pool with this name ({}) exists. Share '
                         'and pool names must be distinct. Choose '
                         'a different name.').format(sname)
                handle_exception(Exception(e_msg), request)
            replica = False
            if ('replica' in request.data):
                replica = request.data['replica']
                if (type(replica) != bool):
                    # TODO: confirm this 'type' call works as format parameter.
                    e_msg = ('Replica must be a boolean, '
                             'not ({}).').format(type(replica))
                    handle_exception(Exception(e_msg), request)
            pqid = qgroup_create(pool)
            add_share(pool, sname, pqid)
            qid = qgroup_id(pool, sname)
            s = Share(pool=pool, qgroup=qid, pqgroup=pqid, name=sname,
                      size=size, subvol_name=sname, replica=replica,
                      compression_algo=compression)
            # The following pool.save() was informed by test_share.py
            pool.save()
            s.save()
            if pqid is not PQGROUP_DEFAULT:
                update_quota(pool, pqid, size * 1024)
                share_pqgroup_assign(pqid, s)
            mnt_pt = '%s%s' % (settings.MNT_PT, sname)
            if not s.is_mounted:
                mount_share(s, mnt_pt)
            if (compression != 'no'):
                set_property(mnt_pt, 'compression', compression)
            return Response(ShareSerializer(s).data)
Beispiel #6
0
def import_shares(pool, request):
    # Establish known shares/subvols within our db for the given pool:
    shares_in_pool_db = [s.name for s in Share.objects.filter(pool=pool)]
    # Find the actual/current shares/subvols within the given pool:
    # Limited to Rockstor relevant subvols ie shares and clones.
    shares_in_pool = shares_info(pool)
    # List of pool's share.pqgroups so we can remove inadvertent duplication.
    # All pqgroups are removed when quotas are disabled, combined with a part
    # refresh we could have duplicates within the db.
    share_pqgroups_used = []
    # Delete db Share object if it is no longer found on disk.
    for s_in_pool_db in shares_in_pool_db:
        if s_in_pool_db not in shares_in_pool:
            logger.debug("Removing, missing on disk, share db entry ({}) from "
                         "pool ({}).".format(s_in_pool_db, pool.name))
            Share.objects.get(pool=pool, name=s_in_pool_db).delete()
    # Check if each share in pool also has a db counterpart.
    for s_in_pool in shares_in_pool:
        logger.debug("---- Share name = {}.".format(s_in_pool))
        if s_in_pool in shares_in_pool_db:
            logger.debug("Updating pre-existing same pool db share entry.")
            # We have a pool db share counterpart so retrieve and update it.
            share = Share.objects.get(name=s_in_pool, pool=pool)
            # Initially default our pqgroup value to db default of '-1/-1'
            # This way, unless quotas are enabled, all pqgroups will be
            # returned to db default.
            pqgroup = PQGROUP_DEFAULT
            if share.pool.quotas_enabled:
                # Quotas are enabled on our pool so we can validate pqgroup.
                if (share.pqgroup == pqgroup or not share.pqgroup_exist
                        or share.pqgroup in share_pqgroups_used):
                    # we have a void '-1/-1' or non existent pqgroup or
                    # this pqgroup has already been seen / used in this pool.
                    logger.debug(
                        "#### replacing void, non-existent, or duplicate pqgroup."
                    )
                    pqgroup = qgroup_create(pool)
                    if pqgroup != PQGROUP_DEFAULT:
                        update_quota(pool, pqgroup, share.size * 1024)
                        share_pqgroup_assign(pqgroup, share)
                else:
                    # Our share's pqgroup looks OK so use it.
                    pqgroup = share.pqgroup
                # Record our use of this pqgroup to spot duplicates later.
                share_pqgroups_used.append(deepcopy(share.pqgroup))
            if share.pqgroup != pqgroup:
                # we need to update our share.pqgroup
                share.pqgroup = pqgroup
                share.save()
            share.qgroup = shares_in_pool[s_in_pool]
            rusage, eusage, pqgroup_rusage, pqgroup_eusage = volume_usage(
                pool, share.qgroup, pqgroup)
            if (rusage != share.rusage or eusage != share.eusage
                    or pqgroup_rusage != share.pqgroup_rusage
                    or pqgroup_eusage != share.pqgroup_eusage):
                share.rusage = rusage
                share.eusage = eusage
                share.pqgroup_rusage = pqgroup_rusage
                share.pqgroup_eusage = pqgroup_eusage
                update_shareusage_db(s_in_pool, rusage, eusage)
            else:
                update_shareusage_db(s_in_pool, rusage, eusage, UPDATE_TS)
            share.save()
            continue
        try:
            logger.debug("No prior entries in scanned pool trying all pools.")
            # Test (Try) for an existing system wide Share db entry.
            cshare = Share.objects.get(name=s_in_pool)
            # Get a list of Rockstor relevant subvols (ie shares and clones)
            # for the prior existing db share entry's pool.
            cshares_d = shares_info(cshare.pool)
            if s_in_pool in cshares_d:
                e_msg = ("Another pool ({}) has a share with this same "
                         "name ({}) as this pool ({}). This configuration "
                         "is not supported. You can delete one of them "
                         "manually with the following command: "
                         '"btrfs subvol delete {}[pool name]/{}" WARNING this '
                         "will remove the entire contents of that "
                         "subvolume.").format(cshare.pool.name, s_in_pool,
                                              pool.name, settings.MNT_PT,
                                              s_in_pool)
                handle_exception(Exception(e_msg), request)
            else:
                # Update the prior existing db share entry previously
                # associated with another pool.
                logger.debug("Updating prior db entry from another pool.")
                cshare.pool = pool
                cshare.qgroup = shares_in_pool[s_in_pool]
                cshare.size = pool.size
                cshare.subvol_name = s_in_pool
                (
                    cshare.rusage,
                    cshare.eusage,
                    cshare.pqgroup_rusage,
                    cshare.pqgroup_eusage,
                ) = volume_usage(pool, cshare.qgroup, cshare.pqgroup)
                cshare.save()
                update_shareusage_db(s_in_pool, cshare.rusage, cshare.eusage)
        except Share.DoesNotExist:
            logger.debug("Db share entry does not exist - creating.")
            # We have a share on disk that has no db counterpart so create one.
            # Retrieve new pool quota id for use in db Share object creation.
            # As the replication receive share is 'special' we tag it as such.
            replica = False
            share_name = s_in_pool
            if re.match(".snapshot", s_in_pool) is not None:
                # We have an initial replication share, non snap in .snapshots.
                # We could change it's name here but still a little mixing
                # of name and subvol throughout project.
                replica = True
                logger.debug("Initial receive quirk-subvol found: Importing "
                             "as share and setting replica flag.")
            qid = shares_in_pool[s_in_pool]
            pqid = qgroup_create(pool)
            if pqid != PQGROUP_DEFAULT:
                update_quota(pool, pqid, pool.size * 1024)
                qgroup_assign(qid, pqid, pool.mnt_pt)
            rusage, eusage, pqgroup_rusage, pqgroup_eusage = volume_usage(
                pool, qid, pqid)
            nso = Share(
                pool=pool,
                qgroup=qid,
                pqgroup=pqid,
                name=share_name,
                size=pool.size,
                subvol_name=s_in_pool,
                rusage=rusage,
                eusage=eusage,
                pqgroup_rusage=pqgroup_rusage,
                pqgroup_eusage=pqgroup_eusage,
                replica=replica,
            )
            nso.save()
            update_shareusage_db(s_in_pool, rusage, eusage)
            mount_share(nso, "{}{}".format(settings.MNT_PT, s_in_pool))
Beispiel #7
0
def import_shares(pool, request):
    # Establish known shares/subvols within our db for the given pool:
    shares_in_pool_db = [s.name for s in Share.objects.filter(pool=pool)]
    # Find the actual/current shares/subvols within the given pool:
    # Limited to Rockstor relevant subvols ie shares and clones.
    shares_in_pool = shares_info(pool)
    # List of pool's share.pqgroups so we can remove inadvertent duplication.
    # All pqgroups are removed when quotas are disabled, combined with a part
    # refresh we could have duplicates within the db.
    share_pqgroups_used = []
    # Delete db Share object if it is no longer found on disk.
    for s_in_pool_db in shares_in_pool_db:
        if s_in_pool_db not in shares_in_pool:
            logger.debug('Removing, missing on disk, share db entry ({}) from '
                         'pool ({}).'.format(s_in_pool_db, pool.name))
            Share.objects.get(pool=pool, name=s_in_pool_db).delete()
    # Check if each share in pool also has a db counterpart.
    for s_in_pool in shares_in_pool:
        logger.debug('---- Share name = {}.'.format(s_in_pool))
        if s_in_pool in shares_in_pool_db:
            logger.debug('Updating pre-existing same pool db share entry.')
            # We have a pool db share counterpart so retrieve and update it.
            share = Share.objects.get(name=s_in_pool, pool=pool)
            # Initially default our pqgroup value to db default of '-1/-1'
            # This way, unless quotas are enabled, all pqgroups will be
            # returned to db default.
            pqgroup = PQGROUP_DEFAULT
            if share.pool.quotas_enabled:
                # Quotas are enabled on our pool so we can validate pqgroup.
                if share.pqgroup == pqgroup or not share.pqgroup_exist \
                        or share.pqgroup in share_pqgroups_used:
                    # we have a void '-1/-1' or non existent pqgroup or
                    # this pqgroup has already been seen / used in this pool.
                    logger.debug('#### replacing void, non-existent, or '
                                 'duplicate pqgroup.')
                    pqgroup = qgroup_create(pool)
                    if pqgroup is not PQGROUP_DEFAULT:
                        update_quota(pool, pqgroup, share.size * 1024)
                        share_pqgroup_assign(pqgroup, share)
                else:
                    # Our share's pqgroup looks OK so use it.
                    pqgroup = share.pqgroup
                # Record our use of this pqgroup to spot duplicates later.
                share_pqgroups_used.append(deepcopy(share.pqgroup))
            if share.pqgroup != pqgroup:
                # we need to update our share.pqgroup
                share.pqgroup = pqgroup
                share.save()
            share.qgroup = shares_in_pool[s_in_pool]
            rusage, eusage, pqgroup_rusage, pqgroup_eusage = \
                volume_usage(pool, share.qgroup, pqgroup)
            if (rusage != share.rusage or eusage != share.eusage or
               pqgroup_rusage != share.pqgroup_rusage or
               pqgroup_eusage != share.pqgroup_eusage):
                share.rusage = rusage
                share.eusage = eusage
                share.pqgroup_rusage = pqgroup_rusage
                share.pqgroup_eusage = pqgroup_eusage
                update_shareusage_db(s_in_pool, rusage, eusage)
            else:
                update_shareusage_db(s_in_pool, rusage, eusage, UPDATE_TS)
            share.save()
            continue
        try:
            logger.debug('No prior entries in scanned pool trying all pools.')
            # Test (Try) for an existing system wide Share db entry.
            cshare = Share.objects.get(name=s_in_pool)
            # Get a list of Rockstor relevant subvols (ie shares and clones)
            # for the prior existing db share entry's pool.
            cshares_d = shares_info(cshare.pool)
            if s_in_pool in cshares_d:
                e_msg = ('Another pool ({}) has a share with this same '
                         'name ({}) as this pool ({}). This configuration '
                         'is not supported. You can delete one of them '
                         'manually with the following command: '
                         '"btrfs subvol delete {}[pool name]/{}" WARNING this '
                         'will remove the entire contents of that '
                         'subvolume.').format(cshare.pool.name, s_in_pool,
                                              pool.name, settings.MNT_PT,
                                              s_in_pool)
                handle_exception(Exception(e_msg), request)
            else:
                # Update the prior existing db share entry previously
                # associated with another pool.
                logger.debug('Updating prior db entry from another pool.')
                cshare.pool = pool
                cshare.qgroup = shares_in_pool[s_in_pool]
                cshare.size = pool.size
                cshare.subvol_name = s_in_pool
                (cshare.rusage, cshare.eusage, cshare.pqgroup_rusage,
                 cshare.pqgroup_eusage) = volume_usage(pool, cshare.qgroup,
                                                       cshare.pqgroup)
                cshare.save()
                update_shareusage_db(s_in_pool, cshare.rusage, cshare.eusage)
        except Share.DoesNotExist:
            logger.debug('Db share entry does not exist - creating.')
            # We have a share on disk that has no db counterpart so create one.
            # Retrieve new pool quota id for use in db Share object creation.
            # As the replication receive share is 'special' we tag it as such.
            replica = False
            share_name = s_in_pool
            if re.match('.snapshot', s_in_pool) is not None:
                # We have an initial replication share, non snap in .snapshots.
                # We could change it's name here but still a little mixing
                # of name and subvol throughout project.
                replica = True
                logger.debug('Initial receive quirk-subvol found: Importing '
                             'as share and setting replica flag.')
            qid = shares_in_pool[s_in_pool]
            pqid = qgroup_create(pool)
            if pqid is not PQGROUP_DEFAULT:
                update_quota(pool, pqid, pool.size * 1024)
                pool_mnt_pt = '{}{}'.format(settings.MNT_PT, pool.name)
                qgroup_assign(qid, pqid, pool_mnt_pt)
            rusage, eusage, pqgroup_rusage, pqgroup_eusage = \
                volume_usage(pool, qid, pqid)
            nso = Share(pool=pool, qgroup=qid, pqgroup=pqid, name=share_name,
                        size=pool.size, subvol_name=s_in_pool, rusage=rusage,
                        eusage=eusage, pqgroup_rusage=pqgroup_rusage,
                        pqgroup_eusage=pqgroup_eusage,
                        replica=replica)
            nso.save()
            update_shareusage_db(s_in_pool, rusage, eusage)
            mount_share(nso, '%s%s' % (settings.MNT_PT, s_in_pool))
Beispiel #8
0
def import_shares(pool, request):
    # Establish known shares/subvols within our db for the given pool:
    shares_in_pool_db = [s.name for s in Share.objects.filter(pool=pool)]
    # Find the actual/current shares/subvols within the given pool:
    # Limited to Rockstor relevant subvols ie shares and clones.
    shares_in_pool = shares_info(pool)
    # List of pool's share.pqgroups so we can remove inadvertent duplication.
    # All pqgroups are removed when quotas are disabled, combined with a part
    # refresh we could have duplicates within the db.
    share_pqgroups_used = []
    # Delete db Share object if it is no longer found on disk.
    for s_in_pool_db in shares_in_pool_db:
        if s_in_pool_db not in shares_in_pool:
            Share.objects.get(pool=pool, name=s_in_pool_db).delete()
    # Check if each share in pool also has a db counterpart.
    for s_in_pool in shares_in_pool:
        logger.debug('---- Share name = {}.'.format(s_in_pool))
        if s_in_pool in shares_in_pool_db:
            logger.debug('Updating pre-existing same pool db share entry.')
            # We have a pool db share counterpart so retrieve and update it.
            share = Share.objects.get(name=s_in_pool, pool=pool)
            # Initially default our pqgroup value to db default of '-1/-1'
            # This way, unless quotas are enabled, all pqgroups will be
            # returned to db default.
            pqgroup = settings.MODEL_DEFS['pqgroup']
            if share.pool.quotas_enabled:
                # Quotas are enabled on our pool so we can validate pqgroup.
                if share.pqgroup == pqgroup or not share.pqgroup_exist \
                        or share.pqgroup in share_pqgroups_used:
                    # we have a void '-1/-1' or non existent pqgroup or
                    # this pqgroup has already been seen / used in this pool.
                    logger.debug('#### replacing void, non-existent, or '
                                 'duplicate pqgroup')
                    pqgroup = qgroup_create(pool)
                    update_quota(pool, pqgroup, share.size * 1024)
                    share_pqgroup_assign(pqgroup, share)
                else:
                    # Our share's pqgroup looks OK so use it.
                    pqgroup = share.pqgroup
                # Record our use of this pqgroup to spot duplicates later.
                share_pqgroups_used.append(deepcopy(share.pqgroup))
            if share.pqgroup != pqgroup:
                # we need to update our share.pqgroup
                share.pqgroup = pqgroup
                share.save()
            share.qgroup = shares_in_pool[s_in_pool]
            rusage, eusage, pqgroup_rusage, pqgroup_eusage = \
                volume_usage(pool, share.qgroup, pqgroup)
            if (rusage != share.rusage or eusage != share.eusage
                    or pqgroup_rusage != share.pqgroup_rusage
                    or pqgroup_eusage != share.pqgroup_eusage):
                share.rusage = rusage
                share.eusage = eusage
                share.pqgroup_rusage = pqgroup_rusage
                share.pqgroup_eusage = pqgroup_eusage
                update_shareusage_db(s_in_pool, rusage, eusage)
            else:
                update_shareusage_db(s_in_pool, rusage, eusage, UPDATE_TS)
            share.save()
            continue
        try:
            logger.debug('No prior entries in scanned pool trying all pools.')
            # Test (Try) for an existing system wide Share db entry.
            cshare = Share.objects.get(name=s_in_pool)
            # Get a list of Rockstor relevant subvols (ie shares and clones)
            # for the prior existing db share entry's pool.
            cshares_d = shares_info(cshare.pool)
            if s_in_pool in cshares_d:
                e_msg = ('Another pool ({}) has a Share with this same '
                         'name ({}) as this pool ({}). This configuration '
                         'is not supported. You can delete one of them '
                         'manually with the following command: '
                         '"btrfs subvol delete {}[pool name]/{}" WARNING this '
                         'will remove the entire contents of that subvolume.'.
                         format(cshare.pool.name, s_in_pool, pool.name,
                                settings.MNT_PT, s_in_pool))
                handle_exception(Exception(e_msg), request)
            else:
                # Update the prior existing db share entry previously
                # associated with another pool.
                logger.debug('Updating prior db entry from another pool.')
                cshare.pool = pool
                cshare.qgroup = shares_in_pool[s_in_pool]
                cshare.size = pool.size
                cshare.subvol_name = s_in_pool
                (cshare.rusage, cshare.eusage, cshare.pqgroup_rusage,
                 cshare.pqgroup_eusage) = volume_usage(pool, cshare.qgroup,
                                                       cshare.pqgroup)
                cshare.save()
                update_shareusage_db(s_in_pool, cshare.rusage, cshare.eusage)
        except Share.DoesNotExist:
            logger.debug('Db share entry does not exist - creating.')
            # We have a share on disk that has no db counterpart so create one.
            # Retrieve new pool quota id for use in db Share object creation.
            pqid = qgroup_create(pool)
            update_quota(pool, pqid, pool.size * 1024)
            rusage, eusage, pqgroup_rusage, pqgroup_eusage = \
                volume_usage(pool, shares_in_pool[s_in_pool], pqid)
            nso = Share(pool=pool,
                        qgroup=shares_in_pool[s_in_pool],
                        pqgroup=pqid,
                        name=s_in_pool,
                        size=pool.size,
                        subvol_name=s_in_pool,
                        rusage=rusage,
                        eusage=eusage,
                        pqgroup_rusage=pqgroup_rusage,
                        pqgroup_eusage=pqgroup_eusage)
            nso.save()
            update_shareusage_db(s_in_pool, rusage, eusage)
            mount_share(nso, '%s%s' % (settings.MNT_PT, s_in_pool))