def mount_root(pool_name, device): root_pool_mnt = DEFAULT_MNT_DIR + pool_name if (is_share_mounted(pool_name)): return root_pool_mnt create_tmp_dir(root_pool_mnt) mnt_cmd = [MOUNT, '-t', 'btrfs', device, root_pool_mnt] run_command(mnt_cmd) return root_pool_mnt
def mount_share(share, mnt_pt): if (is_mounted(mnt_pt)): return mount_root(share.pool) pool_device = ('/dev/%s' % share.pool.disk_set.first().name) subvol_str = 'subvol=%s' % share.subvol_name create_tmp_dir(mnt_pt) mnt_cmd = [MOUNT, '-t', 'btrfs', '-o', subvol_str, pool_device, mnt_pt] return run_command(mnt_cmd)
def mount_share(share, pool_device, mnt_pt): if is_mounted(mnt_pt): return pool_device = "/dev/%s" % pool_device mount_root(share.pool, pool_device) subvol_str = "subvol=%s" % share.subvol_name create_tmp_dir(mnt_pt) mnt_cmd = [MOUNT, "-t", "btrfs", "-o", subvol_str, pool_device, mnt_pt] return run_command(mnt_cmd)
def mount_share(share, mnt_pt): if (is_mounted(mnt_pt)): return mount_root(share["pool"]) pool_device = ('/dev/%s' % share["pool"]["disks"][0]["name"]) subvol_str = 'subvol=%s' % share["subvol_name"] create_tmp_dir(mnt_pt) mnt_cmd = [MOUNT, '-t', 'btrfs', '-o', subvol_str, pool_device, mnt_pt] return run_command(mnt_cmd)
def add_snap(pool, share_name, snap_name, readonly=False): """ create a snapshot """ root_pool_mnt = mount_root(pool) share_full_path = ('%s/%s' % (root_pool_mnt, share_name)) snap_dir = ('%s/.snapshots/%s' % (root_pool_mnt, share_name)) create_tmp_dir(snap_dir) snap_full_path = ('%s/%s' % (snap_dir, snap_name)) return add_snap_helper(share_full_path, snap_full_path, readonly)
def mount_root(pool): """ Mounts a given pool at the default mount root (usually /mnt2/) using the pool.name as the final path entry. Ie pool.name = test-pool will be mounted at /mnt2/test-pool. Any mount options held in pool.mnt_options will be added to the mount command via the -o option as will a compress=pool.compression entry. N.B. Initially the mount target is defined by /dev/disk/by-label/pool.name, if this fails then an attempt to mount by each member of /dev/disk/by-id/pool.disk_set.all() but only if there are any members. If this second method also fails then an exception is raised, currently all but the last failed mount by device name is logged. If no disk members were reported by pool.disk_set.count() a separate Exception is raised. :param pool: pool object :return: either the relevant mount point or an Exception which either indicates 'no disks in pool' or 'Unknown Reason' """ root_pool_mnt = DEFAULT_MNT_DIR + pool.name if (is_share_mounted(pool.name)): return root_pool_mnt # Creates a directory to act as the mount point. create_tmp_dir(root_pool_mnt) mnt_device = '/dev/disk/by-label/%s' % pool.name mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] mnt_options = '' if (pool.mnt_options is not None): mnt_options = pool.mnt_options if (pool.compression is not None): if (re.search('compress', mnt_options) is None): mnt_options = ('%s,compress=%s' % (mnt_options, pool.compression)) if (os.path.exists(mnt_device)): if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) run_command(mnt_cmd) return root_pool_mnt # If we cannot mount by-label, let's try mounting by device; one by one # until we get our first success. if (pool.disk_set.count() < 1): raise Exception('Cannot mount Pool(%s) as it has no disks in it.' % pool.name) last_device = pool.disk_set.last() for device in pool.disk_set.all(): mnt_device = ('/dev/disk/by-id/%s' % device.name) if (os.path.exists(mnt_device)): mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) try: run_command(mnt_cmd) return root_pool_mnt except Exception, e: if (device.name == last_device.name): # exhausted mounting using all devices in the pool raise e logger.error('Error mounting: %s. Will try using another device.' % mnt_cmd) logger.exception(e)
def add_snap(pool, pool_device, share_name, snap_name, readonly=False): """ create a snapshot """ pool_device = "/dev/" + pool_device root_pool_mnt = mount_root(pool, pool_device) share_full_path = "%s/%s" % (root_pool_mnt, share_name) snap_dir = "%s/.snapshots/%s" % (root_pool_mnt, share_name) create_tmp_dir(snap_dir) snap_full_path = "%s/%s" % (snap_dir, snap_name) return add_snap_helper(share_full_path, snap_full_path, readonly)
def mount_snap(share, snap_name, pool_device, snap_mnt=None): pool_device = "/dev/%s" % pool_device share_path = "%s%s" % (DEFAULT_MNT_DIR, share.name) rel_snap_path = ".snapshots/%s/%s" % (share.name, snap_name) snap_path = "%s%s/%s" % (DEFAULT_MNT_DIR, share.pool.name, rel_snap_path) if snap_mnt is None: snap_mnt = "%s/.%s" % (share_path, snap_name) mount_share(share, pool_device[5:], share_path) if is_subvol(snap_path): create_tmp_dir(snap_mnt) return run_command([MOUNT, "-o", "subvol=%s" % rel_snap_path, pool_device, snap_mnt])
def mount_snap(share, snap_name, pool_device, snap_mnt=None): pool_device = ('/dev/%s' % pool_device) share_path = ('%s%s' % (DEFAULT_MNT_DIR, share.name)) rel_snap_path = ('.snapshots/%s/%s' % (share.name, snap_name)) snap_path = ('%s%s/%s' % (DEFAULT_MNT_DIR, share.pool.name, rel_snap_path)) if (snap_mnt is None): snap_mnt = ('%s/.%s' % (share_path, snap_name)) mount_share(share, pool_device[5:], share_path) if (is_subvol(snap_path)): create_tmp_dir(snap_mnt) return run_command([MOUNT, '-o', 'subvol=%s' % rel_snap_path, pool_device, snap_mnt])
def mount_root(pool, device): root_pool_mnt = DEFAULT_MNT_DIR + pool.name if is_share_mounted(pool.name): return root_pool_mnt create_tmp_dir(root_pool_mnt) mnt_device = "/dev/disk/by-label/%s" % pool.name if not os.path.exists(mnt_device): mnt_device = device mnt_cmd = [MOUNT, mnt_device, root_pool_mnt] mnt_options = "" if pool.mnt_options is not None: mnt_options = pool.mnt_options if pool.compression is not None: if re.search("compress", mnt_options) is None: mnt_options = "%s,compress=%s" % (mnt_options, pool.compression) if len(mnt_options) > 0: mnt_cmd.extend(["-o", mnt_options]) run_command(mnt_cmd) return root_pool_mnt
def rollback_snap(snap_name, sname, subvol_name, pool, pool_device): """ 1. validate destination snapshot and umount the share 2. remove the share 3. move the snapshot to share location and mount it. """ mnt_pt = "%s%s" % (DEFAULT_MNT_DIR, sname) snap_fp = "%s/%s/.snapshots/%s/%s" % (DEFAULT_MNT_DIR, pool.name, sname, snap_name) if not is_subvol(snap_fp): raise Exception("Snapshot(%s) does not exist. Rollback is not " "possible" % snap_fp) dpath = "/dev/%s" % pool_device mount_root(pool, dpath) if is_share_mounted(sname): umount_root(mnt_pt) remove_share(pool, pool_device, subvol_name) shutil.move(snap_fp, "%s/%s/%s" % (DEFAULT_MNT_DIR, pool.name, sname)) create_tmp_dir(mnt_pt) subvol_str = "subvol=%s" % sname mnt_cmd = [MOUNT, "-t", "btrfs", "-o", subvol_str, dpath, mnt_pt] run_command(mnt_cmd)
def mount_root(pool, device): root_pool_mnt = DEFAULT_MNT_DIR + pool.name if (is_share_mounted(pool.name)): return root_pool_mnt create_tmp_dir(root_pool_mnt) mnt_device = '/dev/disk/by-label/%s' % pool.name if (not os.path.exists(mnt_device)): mnt_device = device if (re.match('/dev/', device) is None): mnt_device = ('/dev/%s' % mnt_device) mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] mnt_options = '' if (pool.mnt_options is not None): mnt_options = pool.mnt_options if (pool.compression is not None): if (re.search('compress', mnt_options) is None): mnt_options = ('%s,compress=%s' % (mnt_options, pool.compression)) if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) run_command(mnt_cmd) return root_pool_mnt
def mount_root(pool): root_pool_mnt = DEFAULT_MNT_DIR + pool["name"] if (is_share_mounted(pool["name"])): return root_pool_mnt create_tmp_dir(root_pool_mnt) mnt_device = '/dev/disk/by-label/%s' % pool["name"] mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] mnt_options = '' if (pool["mnt_options"] is not None): mnt_options = pool["mnt_options"] if (pool["compression"] is not None): if (re.search('compress', mnt_options) is None): mnt_options = ('%s,compress=%s' % (mnt_options, pool["compression"])) if (os.path.exists(mnt_device)): if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) run_command(mnt_cmd) return root_pool_mnt # If we cannot mount by-label, let's try mounting by device one by one # until we get our first success. # ==============================================================================# if (len(pool["disks"]) < 1): raise Exception('Cannot mount Pool(%s) as it has no disks in it.' % pool["name"]) last_device = pool["disks"][-1] for device in pool["disks"]: mnt_device = ('/dev/%s' % device["name"]) if (os.path.exists(mnt_device)): mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) try: run_command(mnt_cmd) return root_pool_mnt except Exception, e: if (device["name"] == last_device["name"]): # exhausted mounting using all devices in the pool raise e logger.error('Error mouting: %s. Will try using another device.' % mnt_cmd) logger.exception(e)
def rollback_snap(snap_name, sname, subvol_name, pool): """ 1. validate destination snapshot and umount the share 2. remove the share 3. move the snapshot to share location and mount it. """ mnt_pt = ('%s%s' % (DEFAULT_MNT_DIR, sname)) snap_fp = ('%s/%s/.snapshots/%s/%s' % (DEFAULT_MNT_DIR, pool.name, sname, snap_name)) if (not is_subvol(snap_fp)): raise Exception('Snapshot(%s) does not exist. Rollback is not ' 'possible' % snap_fp) mount_root(pool) if (is_share_mounted(sname)): umount_root(mnt_pt) remove_share(pool, subvol_name, '-1/-1') shutil.move(snap_fp, '%s/%s/%s' % (DEFAULT_MNT_DIR, pool.name, sname)) create_tmp_dir(mnt_pt) subvol_str = 'subvol=%s' % sname dpath = '/dev/%s' % pool.disk_set.first().name mnt_cmd = [MOUNT, '-t', 'btrfs', '-o', subvol_str, dpath, mnt_pt] run_command(mnt_cmd)
def mount_root(pool): """ Mounts a given pool at the default mount root (usually /mnt2/) using the pool.name as the final path entry. Ie pool.name = test-pool will be mounted at /mnt2/test-pool. Any mount options held in pool.mnt_options will be added to the mount command via the -o option as will a compress = pool.compression entry. N.B. Initially the mount target is defined by /dev/disk/by-label/pool.name, if this fails then an attempt to mount by each member of /dev/disk/by-id/pool.disk_set.all() but only if there are any members. If this second method also fails then an exception is raised, currently all but the last failed mount by device name is logged. If no disk members were reported by pool.disk_set.count() a separate Exception is raised. :param pool: pool object :return: either the relevant mount point or an Exception which either indicates 'no disks in pool' or 'Unknown Reason' """ root_pool_mnt = DEFAULT_MNT_DIR + pool.name if pool.is_mounted: return root_pool_mnt # Creates a directory to act as the mount point. create_tmp_dir(root_pool_mnt) toggle_path_rw(root_pool_mnt, rw=False) mnt_device = '/dev/disk/by-label/%s' % pool.name mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] mnt_options = '' if (pool.mnt_options is not None): mnt_options = pool.mnt_options if (pool.compression is not None): if (re.search('compress', mnt_options) is None): mnt_options = ('%s,compress=%s' % (mnt_options, pool.compression)) # Prior to a mount by label attempt we call btrfs device scan on all # members of our pool. This call ensures btrfs has up-to-date info on # the relevant devices and avoids the potential overkill of a system wide # call such as is performed in the rockstor-bootstrap service on boot. # Disk.target_name ensures we observe any redirect roles. device_scan([dev.target_name for dev in pool.disk_set.attached()]) if (os.path.exists(mnt_device)): if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) run_command(mnt_cmd) return root_pool_mnt # If we cannot mount by-label, let's try mounting by device; one by one # until we get our first success. All devices known to our pool object # have already been scanned prior to our mount by label attempt above. if (pool.disk_set.count() < 1): raise Exception('Cannot mount Pool(%s) as it has no disks in it.' % pool.name) last_device = pool.disk_set.attached().last() logger.info('Mount by label (%s) failed.' % mnt_device) for device in pool.disk_set.attached(): mnt_device = get_device_path(device.target_name) logger.info('Attempting mount by device (%s).' % mnt_device) if (os.path.exists(mnt_device)): mnt_cmd = [MOUNT, mnt_device, root_pool_mnt, ] if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) try: run_command(mnt_cmd) return root_pool_mnt except Exception as e: if (device.name == last_device.name): # exhausted mounting using all devices in the pool raise e logger.error('Error mounting: %s. ' 'Will try using another device.' % mnt_cmd) logger.exception(e) else: logger.error('Device (%s) was not found' % mnt_device) raise Exception('Failed to mount Pool(%s) due to an unknown reason. ' 'Command used %s' % (pool.name, mnt_cmd))
def mount_root(pool): """ Mounts a given pool at the default mount root (usually /mnt2/) using the pool.name as the final path entry. Ie pool.name = test-pool will be mounted at /mnt2/test-pool. Any mount options held in pool.mnt_options will be added to the mount command via the -o option as will a compress = pool.compression entry. N.B. Initially the mount target is defined by /dev/disk/by-label/pool.name, if this fails then an attempt to mount by each member of /dev/disk/by-id/pool.disk_set.all() but only if there are any members. If this second method also fails then an exception is raised, currently all but the last failed mount by device name is logged. If no disk members were reported by pool.disk_set.count() a separate Exception is raised. :param pool: pool object :return: either the relevant mount point or an Exception which either indicates 'no disks in pool' or 'Unknown Reason' """ root_pool_mnt = DEFAULT_MNT_DIR + pool.name if (is_share_mounted(pool.name)): return root_pool_mnt # Creates a directory to act as the mount point. create_tmp_dir(root_pool_mnt) toggle_path_rw(root_pool_mnt, rw=False) mnt_device = '/dev/disk/by-label/%s' % pool.name mnt_cmd = [ MOUNT, mnt_device, root_pool_mnt, ] mnt_options = '' if (pool.mnt_options is not None): mnt_options = pool.mnt_options if (pool.compression is not None): if (re.search('compress', mnt_options) is None): mnt_options = ('%s,compress=%s' % (mnt_options, pool.compression)) if (os.path.exists(mnt_device)): if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) run_command(mnt_cmd) return root_pool_mnt # If we cannot mount by-label, let's try mounting by device; one by one # until we get our first success. if (pool.disk_set.count() < 1): raise Exception('Cannot mount Pool(%s) as it has no disks in it.' % pool.name) last_device = pool.disk_set.last() for device in pool.disk_set.all(): mnt_device = ('/dev/disk/by-id/%s' % device.name) if (os.path.exists(mnt_device)): mnt_cmd = [ MOUNT, mnt_device, root_pool_mnt, ] if (len(mnt_options) > 0): mnt_cmd.extend(['-o', mnt_options]) try: run_command(mnt_cmd) return root_pool_mnt except Exception as e: if (device.name == last_device.name): # exhausted mounting using all devices in the pool raise e logger.error('Error mouting: %s. ' 'Will try using another device.' % mnt_cmd) logger.exception(e) raise Exception('Failed to mount Pool(%s) due to an unknown reason.' % pool.name)
def mount_share(share_name, pool_device, mnt_pt): pool_device = '/dev/' + pool_device subvol_str = 'subvol=%s' % share_name create_tmp_dir(mnt_pt) mnt_cmd = [MOUNT, '-t', 'btrfs', '-o', subvol_str, pool_device, mnt_pt] return run_command(mnt_cmd)