def volume_usage(pool, volume_id, pvolume_id=None): """ New function to collect volumes rusage and eusage instead of share_usage plus parent rusage and eusage (2015/* qgroup) """ # Obtain path to share in pool, this preserved because # granting pool exists root_pool_mnt = mount_root(pool) cmd = [BTRFS, 'subvolume', 'list', root_pool_mnt] out, err, rc = run_command(cmd, log=True) short_id = volume_id.split('/')[1] volume_dir = '' for line in out: fields = line.split() if (len(fields) > 0 and short_id in fields[1]): volume_dir = root_pool_mnt + '/' + fields[8] break """ Rockstor volume/subvolume hierarchy is not standard and Snapshots actually not always under Share but on Pool, so btrf sub list -o deprecated because won't always return expected data; volumes (shares & snapshots) sizes got via qgroups. Rockstor structure has default share qgroup 0/* becoming child of 2015/* new qgroup and share snapshots 0/*+1 qgroups assigned to new Rockstor 2015/*. Original 0/* qgroup returns current share content size, 2015/* qgroup returns 'real' share size considering snapshots sizes too Note: 2015/* rfer and excl sizes are always equal so to compute current real size we can indistinctly use one of them. """ cmd = [BTRFS, 'qgroup', 'show', volume_dir] out, err, rc = run_command(cmd, log=True) rusage = eusage = 0 pqgroup_rusage = pqgroup_eusage = 0 share_sizes = [] for line in out: fields = line.split() if (len(fields) > 0 and '/' in fields[0]): qgroup = fields[0] if (qgroup == volume_id): rusage = convert_to_kib(fields[1]) eusage = convert_to_kib(fields[2]) share_sizes.extend((rusage, eusage)) if (pvolume_id is not None and qgroup == pvolume_id): pqgroup_rusage = convert_to_kib(fields[1]) pqgroup_eusage = convert_to_kib(fields[2]) share_sizes.extend((pqgroup_rusage, pqgroup_eusage)) return share_sizes
def share_usage(pool, share_id): """ for now, exclusive byte count """ root_pool_mnt = mount_root(pool) cmd = [BTRFS, 'qgroup', 'show', root_pool_mnt] out, err, rc = run_command(cmd, log=True) rusage = eusage = -1 for line in out: fields = line.split() if (len(fields) > 0 and fields[0] == share_id): rusage = convert_to_kib(fields[-2]) eusage = convert_to_kib(fields[-2]) break return (rusage, eusage)
def shares_usage(pool, share_map, snap_map): # don't mount the pool if at least one share in the map is mounted. usage_map = {} mnt_pt = None for s in share_map.keys(): if (is_share_mounted(share_map[s])): mnt_pt = ('%s%s' % (DEFAULT_MNT_DIR, share_map[s])) break if (mnt_pt is None): mnt_pt = mount_root(pool) cmd = [BTRFS, 'qgroup', 'show', mnt_pt] out, err, rc = run_command(cmd, log=True) combined_map = dict(share_map, **snap_map) for line in out: fields = line.split() if (len(fields) > 0 and fields[0] in combined_map): r_usage = convert_to_kib(fields[-2]) e_usage = convert_to_kib(fields[-1]) usage_map[combined_map[fields[0]]] = (r_usage, e_usage) return usage_map
def shares_usage(pool, share_map, snap_map): # TODO: currently unused, is this to be deprecated # don't mount the pool if at least one share in the map is mounted. usage_map = {} mnt_pt = None for s in share_map.keys(): if (is_share_mounted(share_map[s])): mnt_pt = ('%s%s' % (DEFAULT_MNT_DIR, share_map[s])) break if (mnt_pt is None): mnt_pt = mount_root(pool) cmd = [BTRFS, 'qgroup', 'show', mnt_pt] out, err, rc = run_command(cmd, log=True) combined_map = dict(share_map, **snap_map) for line in out: fields = line.split() if (len(fields) > 0 and fields[0] in combined_map): r_usage = convert_to_kib(fields[-2]) e_usage = convert_to_kib(fields[-1]) usage_map[combined_map[fields[0]]] = (r_usage, e_usage) return usage_map
def share_usage(pool, share_id): """ Return the sum of the qgroup sizes of this share and any child subvolumes N.B. qgroupid defaults to a unique identifier of the form 0/<subvolume id> """ # Obtain path to share in pool root_pool_mnt = mount_root(pool) cmd = [BTRFS, 'subvolume', 'list', root_pool_mnt] out, err, rc = run_command(cmd, log=True) short_id = share_id.split('/')[1] share_dir = '' for line in out: fields = line.split() if (len(fields) > 0 and short_id in fields[1]): share_dir = root_pool_mnt + '/' + fields[8] break # Obtain list of child subvolume qgroups cmd = [BTRFS, 'subvolume', 'list', '-o', share_dir] out, err, rc = run_command(cmd, log=True) qgroups = [short_id] for line in out: fields = line.split() if (len(fields) > 0): qgroups.append(fields[1]) # Sum qgroup sizes cmd = [BTRFS, 'qgroup', 'show', share_dir] out, err, rc = run_command(cmd, log=True) rusage = eusage = 0 for line in out: fields = line.split() qgroup = [] if (len(fields) > 0 and '/' in fields[0]): qgroup = fields[0].split('/') if (len(qgroup) > 0 and qgroup[1] in qgroups): rusage += convert_to_kib(fields[1]) eusage += convert_to_kib(fields[2]) return (rusage, eusage)
def volume_usage(pool, volume_id, pvolume_id=None): """ New function to collect volumes rusage and eusage instead of share_usage plus parent rusage and eusage (2015/* qgroup) N.B. this function has 2 personalities. When called with 2 parameters (pool, volume_id) it returns 2 values. But with 3 parameters (pool, volume_id, pvolume_id) it returns 4 values if the last parameter is != None. :param pool: Pool object :param volume_id: qgroupid eg '0/261' :param pvolume_id: qgroupid eg '2015/4' :return: list of len 2 (when pvolul_id=None) or 4 elements. The first 2 pertain to the qgroupid=volume_id the second 2, if present, are for the qgroupid=pvolume_id. I.e [rfer, excl, rfer, excl] """ # Obtain path to share in pool, this preserved because # granting pool exists root_pool_mnt = mount_root(pool) cmd = [BTRFS, 'subvolume', 'list', root_pool_mnt] out, err, rc = run_command(cmd, log=True) short_id = volume_id.split('/')[1] volume_dir = '' for line in out: fields = line.split() if (len(fields) > 0 and short_id in fields[1]): volume_dir = root_pool_mnt + '/' + fields[8] break """ Rockstor volume/subvolume hierarchy is not standard and Snapshots actually not always under Share but on Pool, so btrf sub list -o deprecated because won't always return expected data; volumes (shares & snapshots) sizes got via qgroups. Rockstor structure has default share qgroup 0/* becoming child of 2015/* new qgroup and share snapshots 0/*+1 qgroups assigned to new Rockstor 2015/*. Original 0/* qgroup returns current share content size, 2015/* qgroup returns 'real' share size considering snapshots sizes too Note: 2015/* rfer and excl sizes are always equal so to compute current real size we can indistinctly use one of them. """ cmd = [BTRFS, 'qgroup', 'show', volume_dir] out, err, rc = run_command(cmd, log=True) volume_id_sizes = [0, 0] pvolume_id_sizes = [0, 0] for line in out: fields = line.split() # We may index up to [2] fields (3 values) so ensure they exist. if (len(fields) > 2 and '/' in fields[0]): qgroup = fields[0] if (qgroup == volume_id): rusage = convert_to_kib(fields[1]) eusage = convert_to_kib(fields[2]) volume_id_sizes = [rusage, eusage] if (pvolume_id is not None and qgroup == pvolume_id): pqgroup_rusage = convert_to_kib(fields[1]) pqgroup_eusage = convert_to_kib(fields[2]) pvolume_id_sizes = [pqgroup_rusage, pqgroup_eusage] if pvolume_id is None: return volume_id_sizes return volume_id_sizes + pvolume_id_sizes