Server IP : 68.178.168.24 / Your IP : 18.116.10.73 Web Server : Apache System : Linux 24.168.178.68.host.secureserver.net 3.10.0-1160.119.1.el7.tuxcare.els19.x86_64 #1 SMP Mon Mar 31 17:29:00 UTC 2025 x86_64 User : realcarecert ( 1247) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /bin/ |
Upload File : |
#!/bin/bash # # prl_backup - utility for managing attached backups # # Copyright (c) 2014-2017 Parallels International GmbH. # Copyright (c) 2017-2019 Virtuozzo International GmbH, All rights reserved. KPARTX=kpartx DMSETUP="dmsetup -v -v" LSBLK=lsblk BLOCKDEV=blockdev UDEVADM=udevadm GETOPT=getopt BASENAME=basename MOUNT=mount UMOUNT=umount SERIAL_PREFIX="__bckp_" OFFSET=1024 SCRIPTNAME=$("$BASENAME" $0) LOG_FILE="/tmp/prl_backup.log" REDIRECT="/dev/null" msg() { echo "$@" >&2 } die() { code=$1 shift msg "$@" exit $code } usage() { msg "Usage: $SCRIPTNAME list [options]" msg " $SCRIPTNAME enable /path/to/device [-l,--log]" msg " $SCRIPTNAME disable /path/to/device [-l,--log]" msg "Options for the 'list' command" msg " -e|--enabled - Show only enabled attached backups" msg " -d|--disabled - Show only disabled attached backups" msg " -r|--raw - Raw output, useful for scripting" msg "Options for the 'enable'/'disable' commands" msg " -l|--log - Redirect some output to log $LOG_FILE" exit 1 } get_serial() { val="$($UDEVADM info --query=property -n $1 2>/dev/null | grep 'ID_SERIAL_SHORT=')" echo ${val##ID_SERIAL_SHORT=} } match_serial() { [[ "$1" =~ ^${SERIAL_PREFIX}.* ]] && return 1 return 0 } unmangle_serial() { echo ${1/"$SERIAL_PREFIX"/"backup"} } list() { local opt_raw=0 local opt_enabled=0 local opt_disabled=0 local opts=$("$GETOPT" -o edr -l enabled,disabled,raw -n "$SCRIPTNAME" -- "$@") [ $? -ne 0 ] && usage eval set -- "$opts" while true do case $1 in -e|--enabled) opt_enabled=1 shift ;; -d|--disabled) opt_disabled=1 shift ;; -r|--raw) opt_raw=1 shift ;; --) shift; break ;; *) usage ;; esac done if [ $opt_enabled -eq 0 -a $opt_disabled -eq 0 ]; then opt_enabled=1 opt_disabled=1 fi # Emulate associative arrays with indexed arrays (key-value) for Bash v3 compatibility # "disabled" does not need values local -a enabled_k enabled_v disabled_k local enabled_num=0 disabled_num=0 for dev in $("$LSBLK" --nodeps --noheadings --list --output NAME 2>/dev/null); do local serial=$(get_serial "$dev") match_serial "$serial" [ $? -ne 0 ] || continue serial=$(unmangle_serial "$serial") local node="/dev/mapper/$serial" local device="/dev/$dev" # check that dmsetup was properly executed if [ ! -e "$node" ]; then disabled_k[${#disabled_k[@]}]="$device" (( disabled_num = disabled_num + 1 )) continue fi enabled_k[${#enabled_k[@]}]="$device" enabled_v[${#enabled_v[@]}]="$node" (( enabled_num = enabled_num + 1 )) done if [ ${enabled_num} -eq 0 -a ${disabled_num} -eq 0 ]; then msg "Attached backups are not detected" exit 0 fi local lvm=0 local i text if [ ${enabled_num} -ne 0 -a $opt_enabled -eq 1 ]; then [ $opt_raw -eq 1 ] || echo -e "List of enabled attached backups:\n" for (( i=0; i<${enabled_num}; i++ )); do dev=${enabled_k[$i]} node=${enabled_v[$i]} if [ $opt_raw -eq 1 ]; then text="$dev $node" [ $opt_disabled -eq 1 ] && text="enabled $text" echo "$text" else echo "[$((i+1))] $dev (${node})" text="$($LSBLK --output NAME,TYPE,SIZE,FSTYPE,UUID,MOUNTPOINT ${node} 2>/dev/null)" echo "$text" | grep -q LVM2_member [ $? -eq 0 ] && lvm=1 echo -e "$text\n" fi done fi if [ ${disabled_num} -ne 0 -a $opt_disabled -eq 1 ]; then [ $opt_raw -eq 1 ] || echo -e "List of disabled attached backups:\n" for (( i=0; i<${disabled_num}; i++ )); do dev=${disabled_k[$i]} text="$dev" if [ $opt_raw -eq 1 ]; then [ $opt_enabled -eq 1 ] && text="disabled $text" echo "$text" else echo "[$((i+1))] $text" fi done [ $opt_raw -eq 1 ] || echo "" fi if [ $opt_raw -eq 0 ]; then [ $lvm -eq 1 ] && msg "NOTE: before activating a LVM volume from the attached backup, consider changing its VG name using vgimportclone utility" fi } check_block_dev() { [ "$1" ] || die 1 "Device is not specified" [ -b "$1" ] || die 2 "$1 is not a block device" } fake_udev_rule() { $MOUNT --bind /dev/null "$1" || return 1 $UDEVADM control --reload &>/dev/null return 0 } unfake_udev_rule() { $UMOUNT "$1" if [ $? -ne 0 ]; then msg "Unable to $UMOUNT $1. Please try to unmount it manually" return fi $UDEVADM control --reload &>/dev/null } exec_command() { local command="$1" local error_text="$2" local error_code="$3" local not_equal="$4" echo "$command" >>$REDIRECT 2>&1 eval "$command" >>$REDIRECT 2>&1 result=$? if [ -z $not_equal ]; then [ $result -eq 0 ] || die "$error_code" "$error_text" else [ $result -ne 0 ] || die "$error_code" "$error_text" fi } enable_one() { local dev="$1" check_block_dev "$dev" local serial=$(get_serial "$dev") match_serial "$serial" [ $? -ne 0 ] || die 3 "$dev is not an attached backup" serial=$(unmangle_serial "$serial") local name="$serial" local mname="/dev/mapper/$name" exec_command "$DMSETUP status $name" "Attached backup $dev is already enabled" 4 true local size=$("$BLOCKDEV" --getsz "$dev" 2>/dev/null) [ $? -ne 0 -o -z "$size" ] && die 5 "Can not get the size of block device $dev" [ $size -le $(($OFFSET * 2)) ] && die 6 "Wrong disk size '$size' obtained from block device $dev" exec_command "$DMSETUP create $name --table \"0 $(($size - $OFFSET * 2)) linear $dev $OFFSET\"" "dmsetup failed to create a mapping for $dev" 7 # Execution of /lib/udev/rules.d/69-dm-lvm-metad.rules will result in starting pvscan service # via systemd (e.g. in Fedora 23). pvscan will scan available disks for physical volumes and # detect duplicates since the backup LVM PV has the same UUID. After that system may start using backup # LVM instead of the original disks. For more information see #PSBM-42980. local rule="" if [ -e "/lib/udev/rules.d/69-dm-lvm-metad.rules" ]; then rule="/lib/udev/rules.d/69-dm-lvm-metad.rules" elif [ -e "/lib/udev/rules.d/69-lvm-metad.rules" ]; then rule="/lib/udev/rules.d/69-lvm-metad.rules" fi local unfake=0 [ -n "$rule" ] && fake_udev_rule "$rule" && unfake=1 echo "$KPARTX -a -p p -s $mname" >>$REDIRECT 2>&1 "$KPARTX" -a -p p -s "$mname" >>$REDIRECT 2>&1 if [ $? -eq 0 ]; then exec_command "$UDEVADM settle --timeout 10" else msg "Failed to parse the partition table on $mname" fi [ -n "$rule" -a $unfake -eq 1 ] && unfake_udev_rule "$rule" } disable_one() { local dev="$1" check_block_dev "$dev" local serial=$(get_serial "$dev") match_serial "$serial" [ $? -ne 0 ] || die 3 "$dev is not an attached backup" serial=$(unmangle_serial "$serial") local name="$serial" local mname="/dev/mapper/$name" exec_command "$DMSETUP status $name" "Attached backup $dev is not enabled" 4 exec_command "$KPARTX -d -p p -s $mname" "Failed to disable partitions for attached backup $dev" 5 exec_command "$DMSETUP remove $name" "Failed to remove mapping for attached backup $dev" 6 } [ $# -ge 1 ] || usage proceed=1 for exe in "$KPARTX" "${DMSETUP%% *}" "$LSBLK" "$BLOCKDEV" "$UDEVADM"; do path=$(which "$exe" 2>/dev/null) if [ $? -ne 0 -o -z "$path" ]; then msg "$exe utility is not found" proceed=0 fi done [ $proceed -ne 1 ] && die 1 "Could not proceed because of unsatisfied dependencies" mv $LOG_FILE $LOG_FILE.old &>/dev/null case $1 in list) shift list "$@" ;; enable|disable) [[ "$3" == "-l" || "$3" == "--log" ]] && REDIRECT=$LOG_FILE if [ $1 == "enable" ]; then enable_one "$2" else disable_one "$2" fi ;; *) usage ;; esac exit 0Private