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))
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))
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))
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