#!/bin/bash #!/usr/bin/env bash start_time="$(date '+%Y-%m-%d_%H.%M.%S')" logdir=/tmp log="$logdir"/log_"$start_time".log log_x="$logdir"/log_x_"$start_time".log exec 3>&1 1>>"$log_x" 2>&1 set -x loginput() { echo "$*" >&3; echo "[INPUT] $(date '+%H:%M:%S') $*" >> "$log"; } logresponse() { echo "[RESPONSE] $(date '+%H:%M:%S') $*" >> "$log"; } loginfo() { echo "$*" >&3; echo "[INFO] $(date '+%H:%M:%S') $*" >> "$log"; } logwarn() { echo "$*" >&3; echo "[WARNING] $(date '+%H:%M:%S') $*" >> "$log"; } logerror() { echo "$*" >&3; echo "[ERROR] $(date '+%H:%M:%S') $*" >> "$log"; } confirm_message () { local typed= while [[ ! $typed = "$2" ]]; do loginput "$1" read -r typed logresponse "$typed" done } # shellcheck disable=SC2329 catch_sigint () { logwarn "Signal Interrupt initiated. Stopping script." cleanup kill -INT "$$" } # shellcheck disable=SC2329 catch_exit () { cleanup kill -INT "$$" } # shellcheck disable=SC2329 cleanup () { loginfo "Cleaning up." pcie_disable loginfo "Unmounting drives." exec 1>/dev/null 2>&1 umount /mnt/"$ticket_number" umount "/mnt/dest" trap - EXIT trap - INT } trap catch_sigint SIGINT trap catch_exit EXIT get_netid () { netid= while [[ $netid =~ ^\s*$ ]]; do loginput "Please enter your r-account netid: " read -r netid logresponse "$netid" if [[ $netid =~ ^\s*$ ]]; then logwarn "Your netid cannot be blank." else local ret_value=$(kinit "$netid"@EGR.MSU.EDU >&3; echo $?) if [[ ! $ret_value = "0" ]] then kdestroy netid= logwarn "Error when authenticating netid $netid." else clear loginfo "Authenticated as user $netid." fi fi done } get_ticket () { ticket_number= loginfo "Please enter the ticket number that corresponds to this backup." loginfo "Allowed characters: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -, _" loginfo "Examples: 12345, 12345-1, 12345_2" loginput "Ticket number: " read -r ticket_number logresponse "$ticket_number" if [[ $ticket_number =~ ^\s*$ ]]; then ticket_number="UNKNWN" logwarn "Starting with no ticket number specified." logwarn "Backup will be stored under $ticket_number." fi } mount_remote () { mkdir -p /mnt/dest if mount -t cifs -o user="$netid",sec=krb5i "//reinstallbackups/reinstallbackups" /mnt/dest then while [ -d /mnt/dest/"$ticket_number" ]; do logwarn "Backup directory /mnt/dest/$ticket_number already exists." loginput "Enter another ticket number: " read -r ticket_number logresponse "$ticket_number" if [[ $ticket_number =~ ^\s*$ ]]; then ticket_number="UNKNWN" logwarn "Starting with no ticket number specified." logwarn "Backup will be stored under $ticket_number." fi done if ! mkdir -p /mnt/dest/"$ticket_number"; then logerror "Insufficient permissions to write in //reinstallbackups/reinstallbackups" exit else logdir=/mnt/dest/"$ticket_number" cp "$log" "$logdir"/log_"$ticket_number"_"$start_time".log cp "$log_x" "$logdir"/log_x_"$ticket_number"_"$start_time".log log="$logdir"/log_"$ticket_number"_"$start_time".log log_x="$logdir"/log_x_"$ticket_number"_"$start_time".log exec 1>>"$log_x" 2>&1 set -x fi else logerror "Failed to mount remote DECS drive. Stopping" exit fi } get_partition () { partition= echo "- - -" | sudo tee /sys/class/scsi_host/host*/scan >/dev/null echo 1 | sudo tee /sys/class/block/sd?/device/rescan >/dev/null pcie_enable echo 1 | sudo tee /sys/class/block/nvme?/device/rescan >/dev/null loginfo "Listing current attached devices and partitions..." loginfo "" loginfo "$(lsblk -o NAME,SIZE,FSTYPE,LABEL,MODEL,VENDOR | grep -E '^NAME|sd[a-z]|nvme[0-9]')" loginfo "" loginput "Which partition would you like to back up? (Type 'help' for help.)" while [[ $partition =~ ^\s*$ ]]; do read -r partition logresponse "$partition" while [[ ! $partition =~ ^sd[a-z][0-9]+$ ]] && [[ ! $partition =~ ^nvme[0-9]n[0-9]p[0-9]+$ ]]; do if [[ $partition = "help" ]]; then loginfo "The UNIX filesystem thinks of storage devices as directories, which are under /dev/" loginfo "Partitions are numbered entries beneath a device." loginfo "If you have a SATA connection, you will be looking for sd{a-z}{1-9}. (i.e. sda1)" loginfo "If you have a NVME connection, you will be looking for nvme0n1p{1-9}. (i.e. nvme0n1p2)" else logwarn "Invalid format, partition should follow naming conventions. (i.e. sd{a-z}{1-9}, nvme0n1p{1-9})" fi read -r partition logresponse "$partition" done if [ -e /dev/"$partition" ]; then loginfo "Picking partition /dev/$partition." else logwarn "/dev/$partition does not exist, please ensure you are typing the partition name correctly." partition= fi done } backup_partition () { loginfo "Mounting /dev/$partition read-only." mkdir -p /mnt/"$ticket_number" if ! mount -o ro /dev/"$partition" /mnt/"$ticket_number" then logerror "Failed to mount /dev/$partition. Stopping" exit fi local destination=/mnt/dest/"$ticket_number"/"$partition" if ! mkdir -p "$destination"; then logerror "Insufficient permissions to write in $destination" umount /mnt/"$ticket_number" exit fi loginfo "Backing up /dev/$partition to $destination." loginfo "This may take a while!" local ret_value=$(rsync -avxzSHPL --progress /mnt/"$ticket_number"/ "$destination"/ >&3; echo $?) if [[ ! $ret_value = "0" ]] then case $ret_value in "23") logwarn "Rsync finished but some files could not be transferred. Check the log for details." ;; "24") logwarn "Rsync finished but some files vanished during transfer. Check the log for details." ;; *) logerror "Rsync failed with exit code $ret_value. Please contact your supervisor." umount /mnt/"$ticket_number" exit ;; esac else loginfo "Finished backing up /dev/$partition to $destination." fi umount /mnt/"$ticket_number" } #Rescan for PCIe devices pcie_enable (){ echo 1 > /sys/bus/pci/rescan loginfo "Enabled PCIe card, sleeping for 5 seconds." sleep 5 } #Remove the PCIe NVMe readrer # shellcheck disable=SC2329 pcie_disable (){ echo 1 > /sys/bus/pci/devices/0000:02:00.0/remove echo 1 > /sys/bus/pci/devices/0000:03:00.0/remove loginfo "Disabled PCIe card." } main (){ get_netid loginfo "" get_ticket loginfo "" mount_remote loginfo "" get_partition #sets $partition to one of the /dev/xyz partitions. loginfo "" loginfo "Starting process for backing up $partition to /mnt/dest/$ticket_number." confirm_message "Please type 'confirm' to begin." "confirm" loginfo "" backup_partition loginfo "" loginfo "Finished backing up $partition to /mnt/dest/$ticket_number." loginfo "" cleanup } main