Example #1
0
def _lvremove(lv):
    lvremove_proc = subprocess.Popen(
        '{0} -f {1}'.format(utils.find_executable('lvremove'), lv),
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, shell=True,
        executable=utils.find_executable('bash'))
    output, error = lvremove_proc.communicate()
    if lvremove_proc.returncode:
        raise Exception(
            'unable to remove snapshot {0}. {1}'.format(lv, error))
Example #2
0
def _umount(path):
    # TODO: check if cwd==path and change working directory to unmount ?
    umount_proc = subprocess.Popen('{0} -l -f {1}'.format(
        utils.find_executable('umount'), path),
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        shell=True, executable=utils.find_executable('bash'))
    (umount_out, mount_err) = umount_proc.communicate()

    if umount_proc.returncode:
        raise Exception('impossible to umount {0}. {1}'
                        .format(path, mount_err))

    logging.info('[*] Volume {0} unmounted'.format(path))
Example #3
0
 def set_max_process_priority():
     """ Set freezer in max priority on the os """
     # children processes inherit niceness from father
     try:
         logging.warning(
             '[*] Setting freezer execution with high CPU and I/O priority')
         PID = os.getpid()
         # Set cpu priority
         os.nice(-19)
         # Set I/O Priority to Real Time class with level 0
         subprocess.call([
             u'{0}'.format(utils.find_executable("ionice")), u'-c', u'1',
             u'-n', u'0', u'-t', u'-p', u'{0}'.format(PID)
         ])
     except Exception as priority_error:
         logging.warning('[*] Priority: {0}'.format(priority_error))
Example #4
0
def lvm_snap(backup_opt_dict):
    """
    Checks the provided parameters and create the lvm snapshot if requested

    The path_to_backup might be adjusted in case the user requested
    a lvm snapshot without specifying an exact path for the snapshot
    (lvm_auto_snap).
    The assumption in this case is that the user wants to use the lvm snapshot
    capability to backup the specified filesystem path, leaving out all
    the rest of the parameters which will guessed and set by freezer.

    if a snapshot is requested using the --snapshot flag, but lvm_auto_snap
    is not provided, then path_to_backup is supposed to be the path to backup
    *before* any information about the snapshot is added and will be
    adjusted.

    :param backup_opt_dict: the configuration dict
    :return: True if the snapshot has been taken, False otherwise
    """
    if backup_opt_dict.snapshot:
        if not backup_opt_dict.lvm_auto_snap:
            # 1) the provided path_to_backup has the meaning of
            #    the lvm_auto_snap and is therefore copied into it
            # 2) the correct value of path_to_backup, which takes into
            #    consideration the snapshot mount-point, is cleared
            #    and will be calculated by freezer
            backup_opt_dict.lvm_auto_snap =\
                backup_opt_dict.path_to_backup
            backup_opt_dict.path_to_backup = ''

    if not backup_opt_dict.lvm_snapname:
        backup_opt_dict.lvm_snapname = \
            "{0}_{1}".format(freezer_config.DEFAULT_LVM_SNAP_BASENAME,
                             uuid.uuid4().hex)

    if backup_opt_dict.lvm_auto_snap:
        # adjust/check lvm parameters according to provided lvm_auto_snap
        lvm_info = get_lvm_info(backup_opt_dict.lvm_auto_snap)

        if not backup_opt_dict.lvm_volgroup:
            backup_opt_dict.lvm_volgroup = lvm_info['volgroup']

        if not backup_opt_dict.lvm_srcvol:
            backup_opt_dict.lvm_srcvol = lvm_info['srcvol']

        if not backup_opt_dict.lvm_dirmount:
            backup_opt_dict.lvm_dirmount = \
                "{0}_{1}".format(freezer_config.DEFAULT_LVM_MOUNT_BASENAME,
                                 uuid.uuid4().hex)

        path_to_backup = os.path.join(backup_opt_dict.lvm_dirmount,
                                      lvm_info['snap_path'])
        if backup_opt_dict.path_to_backup:
            # path_to_backup is user-provided, check if consistent
            if backup_opt_dict.path_to_backup != path_to_backup:
                raise Exception('Path to backup mismatch. '
                                'provided: {0}, should be LVM-mounted: {1}'.
                                format(backup_opt_dict.path_to_backup,
                                       path_to_backup))
        else:
            # path_to_backup not provided: use the one calculated above
            backup_opt_dict.path_to_backup = path_to_backup

    if not validate_lvm_params(backup_opt_dict):
        logging.info('[*] No LVM requested/configured')
        return False

    utils.create_dir(backup_opt_dict.lvm_dirmount)

    lvm_create_command = (
        '{0} --size {1} --snapshot --permission {2} '
        '--name {3} {4}'.format(
            utils.find_executable('lvcreate'),
            backup_opt_dict.lvm_snapsize,
            ('r' if backup_opt_dict.lvm_snapperm == 'ro'
             else backup_opt_dict.lvm_snapperm),
            backup_opt_dict.lvm_snapname,
            backup_opt_dict.lvm_srcvol))

    lvm_process = subprocess.Popen(
        lvm_create_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, shell=True,
        executable=utils.find_executable('bash'))
    (lvm_out, lvm_err) = lvm_process.communicate()

    if lvm_process.returncode:
        raise Exception('lvm snapshot creation error: {0}'.format(lvm_err))

    logging.debug('[*] {0}'.format(lvm_out))
    logging.warning('[*] Logical volume "{0}" created'.
                    format(backup_opt_dict.lvm_snapname))

    # Guess the file system of the provided source volume and st mount
    # options accordingly
    filesys_type = utils.get_vol_fs_type(backup_opt_dict.lvm_srcvol)
    mount_options = '-o {}'.format(backup_opt_dict.lvm_snapperm)
    if 'xfs' == filesys_type:
        mount_options = ' -onouuid '
    # Mount the newly created snapshot to dir_mount
    abs_snap_name = '/dev/{0}/{1}'.format(
        backup_opt_dict.lvm_volgroup,
        backup_opt_dict.lvm_snapname)
    mount_command = '{0} {1} {2} {3}'.format(
        utils.find_executable('mount'),
        mount_options,
        abs_snap_name,
        backup_opt_dict.lvm_dirmount)
    mount_process = subprocess.Popen(
        mount_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, shell=True,
        executable=utils.find_executable('bash'))
    mount_err = mount_process.communicate()[1]
    if 'already mounted' in mount_err:
        logging.warning('[*] Volume {0} already mounted on {1}\
        '.format(abs_snap_name, backup_opt_dict.lvm_dirmount))
        return True
    if mount_err:
        logging.error("[*] Snapshot mount error. Removing snapshot")
        lvm_snap_remove(backup_opt_dict)
        raise Exception('lvm snapshot mounting error: {0}'.format(mount_err))
    else:
        logging.warning(
            '[*] Volume {0} succesfully mounted on {1}'.format(
                abs_snap_name, backup_opt_dict.lvm_dirmount))

    return True