mirror of
https://github.com/kneutron/ansitest.git
synced 2025-01-16 04:42:55 +08:00
358 lines
13 KiB
Bash
358 lines
13 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
# TODO - sep datasets for users
|
||
|
|
||
|
# DONE new disk needs to be at least = size of /home du -s -h
|
||
|
# DONE free snapshot
|
||
|
|
||
|
# GOAL: move existing /home to zfs
|
||
|
# $1 = disk name (long or short) OR existing zfs poolname
|
||
|
|
||
|
# =LLC= © (C)opyright 2016 Boojum Consulting LLC / Dave Bechtel, All rights reserved.
|
||
|
## NOTICE: Only Boojum Consulting LLC personnel may use or redistribute this code,
|
||
|
## Unless given explicit permission by the author - see http://www.boojumconsultingsa.com
|
||
|
#
|
||
|
|
||
|
logfile=~/boojum-mvhome2zfs.log
|
||
|
source ~/bin/logecho.mrg
|
||
|
> $logfile
|
||
|
|
||
|
# If set to 1, will interactively kill user processes
|
||
|
# EITHER of these options (if set) will destroy existing ZFS datasets!
|
||
|
debugg=0
|
||
|
RESETALL=0
|
||
|
# DANGEROUS - ONLY SET IF U KNOW WHAT U DOING AFTER RESTORING A SNAPSHOT!
|
||
|
# WILL DESTROY $zp
|
||
|
|
||
|
# TODO edit this to be the name of the ZFS home pool you want to be created, if needed
|
||
|
zp=zhome
|
||
|
[ $RESETALL -gt 0 ] && (set -x;zpool destroy $zp)
|
||
|
|
||
|
tmpfile1=/tmp/mvh2zTMP1.txt
|
||
|
|
||
|
source ~/bin/failexit.mrg
|
||
|
|
||
|
modprobe zfs # shouldnt hurt even if its already loaded
|
||
|
|
||
|
# is zfs installed?
|
||
|
#zfsps=`zpool status |head -n 1`
|
||
|
zfsps=$(zfs list |head -n 1)
|
||
|
|
||
|
if [ `echo "$zfsps" |grep -c 'MOUNTPOINT'` -ge 1 ]; then
|
||
|
logecho 'Existing zfs pool(s) detected:'
|
||
|
zpool status |awk 'NF>0'
|
||
|
echo 'FYI: Pass a ZFS pool name to this script to move /home there, or pass a disk name to create a new pool'
|
||
|
elif [ `echo "$zfsps" |grep -c 'no datasets available'` ]; then
|
||
|
logecho "NOTE: ZFS is installed and appears to be working - will create a pool ( $zp ) to hold /home"
|
||
|
else
|
||
|
logecho '! ZFS does not appear to be installed or is not working correctly'
|
||
|
failexit 99 '! zpool status is not returning a valid result:'
|
||
|
(set -x
|
||
|
zpool status )
|
||
|
fi
|
||
|
|
||
|
# TODO fix/re-enable
|
||
|
#[ `mount |grep /home |grep -c 'type zfs'` -ge 1 ] && failexit 109 "! Home already appears to be ON zfs!"
|
||
|
# bigvaiterazfsNB/home on /home type zfs (rw,noatime,xattr,noacl)
|
||
|
|
||
|
# Is /home a dir hanging off root or sep partn?
|
||
|
#sephome=`df /home |grep /home |awk '{ print $1 }'`
|
||
|
hmnt=$(mount |grep /home |awk '{ print $1 }' |head -n 1) # 1st line only
|
||
|
# bigvaiterazfsNB/home OR /dev/sdX9
|
||
|
|
||
|
roothome=0
|
||
|
homespc=0
|
||
|
if [ `echo $hmnt |grep -c '/dev'` -gt 0 ]; then
|
||
|
echo '';logecho "o Your /home appears to be on $hmnt"
|
||
|
df -h /home
|
||
|
elif [ -d /home ]; then
|
||
|
logecho "o Your /home does not appear to be on a separate partition, is a directory on the root filesystem"
|
||
|
echo "...Please wait while I determine how much space it is using..."
|
||
|
homespc=$(du -s -k /home |awk '{print $1}') # 431484266 /home
|
||
|
logecho $homespc
|
||
|
roothome=1
|
||
|
else
|
||
|
failexit 201 "! This fallthru should not happen, cannot determine /home!"
|
||
|
fi
|
||
|
|
||
|
# skip header line and grab 3rd field (Used)
|
||
|
#[ $debugg -gt 0 ] && homespc=16011904 # 16GB # TODO testing - only set this if there is nothing in /home
|
||
|
[ $homespc = 0 ] && homespc=$(df -k /home |tail -n +2 |awk '{ print $3 }')
|
||
|
|
||
|
let hsbytes=$homespc*1024
|
||
|
|
||
|
# REF: https://unix.stackexchange.com/questions/222121/how-to-remove-a-column-or-multiple-columns-from-file-using-shell-command
|
||
|
# get a list of long drive names with short; strip out blank lines and unnec fields
|
||
|
/bin/ls -go /dev/disk/by-id /dev/disk/by-path \
|
||
|
|egrep -v 'part|wwn|total |dev/' \
|
||
|
|awk 'NF>0' \
|
||
|
|awk '{$1=$2=$3=$4=$5=$6=""; print $0}' \
|
||
|
|column -t \
|
||
|
> $tmpfile1
|
||
|
|
||
|
echo '';echo "o These are the hard drives found on your system:"
|
||
|
# NOT an unnec use of cat - REF: https://unix.stackexchange.com/questions/16279/should-i-care-about-unnecessary-cats
|
||
|
cat $tmpfile1
|
||
|
echo ''
|
||
|
|
||
|
# did we get passed a disk or existing ZFS pool?
|
||
|
argg=$1
|
||
|
[ "$argg" = "" ] && failexit 199 "! Cannot proceed - pass at least a disk device name (long or short form) OR zfs pool to move /home to!"
|
||
|
|
||
|
usepool=""; usedisk=""
|
||
|
if [ `grep -c $argg $tmpfile1` -gt 0 ]; then
|
||
|
logecho "o You apparently want me to use this disk:"
|
||
|
bothforms=`grep $argg $tmpfile1`
|
||
|
echo "$bothforms"
|
||
|
|
||
|
getlongdisk=`grep $argg $tmpfile1 |awk '{ print $1 }' |head -n 1`
|
||
|
shortdisk=${bothforms##*/} # strip off all leading "/"
|
||
|
shortdev=/dev/$shortdisk
|
||
|
usedisk=$getlongdisk
|
||
|
|
||
|
echo ''; logecho "o Using long-form diskname: $usedisk - Short form: $shortdev"
|
||
|
echo "^^ If this is incorrect, then rerun this script and use a more specific device name!"
|
||
|
|
||
|
# test for cd = add all results (tmpusingcd)
|
||
|
ttlusecd=0 # TOTAL
|
||
|
|
||
|
#TMPusecd
|
||
|
tucd=`echo $argg |egrep -c 'sr0|sr1|scd0|scd1|cdrom|cdrw|dvdrw'`
|
||
|
let ttlusecd=$ttlusecd+$tucd
|
||
|
|
||
|
tucd=`echo $shortdisk |egrep -c 'sr0|sr1|scd0|scd1|cdrom|cdrw|dvdrw'`
|
||
|
let ttlusecd=$ttlusecd+$tucd
|
||
|
|
||
|
# [ `echo $argg |grep -c sr1` -gt 0 ] && failexit 401 "! I cant use a CDROM device, wiseguy!!"
|
||
|
[ $ttlusecd -gt 0 ] && failexit 401 "! I cant put /home on a CDROM device, wiseguy!! Try again with a hard drive!"
|
||
|
|
||
|
|
||
|
# test for existing filesystem on destination disk - especially if sda!
|
||
|
echo "...Checking blkid and zpools to see if the disk you specified is OK to use..."
|
||
|
|
||
|
[ `echo $hmnt |grep -c $shortdev` -gt 0 ] && failexit 32768 "! You CRAZY MANIAC - you cant re-use your existing home disk in-place for ZFS!!"
|
||
|
|
||
|
alreadyf=`blkid |grep -c $argg`
|
||
|
alreadyf2=`blkid |grep -c $shortdev`
|
||
|
let alreadyf=$alreadyf+$alreadyf2
|
||
|
#/dev/sde1: LABEL="zredpool2" UUID="17065421584496359800" UUID_SUB="1595728817173195411" TYPE="zfs_member" PARTLABEL="zfs"
|
||
|
#/dev/sda2: LABEL="xubuntu1404" UUID="103f019e-1275-4c27-a972-5b5d3874b863" TYPE="ext4" PARTUUID="b680669e-02"
|
||
|
|
||
|
# ISSUE - blkid is not always up to date, not detecting newly created test pools!
|
||
|
alreadyf2=`zpool status |grep -c $usedisk`
|
||
|
let alreadyf=$alreadyf+$alreadyf2
|
||
|
alreadyf2=`zpool status |grep -c $shortdisk`
|
||
|
let alreadyf=$alreadyf+$alreadyf2
|
||
|
alreadyf2=`zpool status |grep -c $argg`
|
||
|
let alreadyf=$alreadyf+$alreadyf2
|
||
|
|
||
|
|
||
|
# NOTE empty GPT label will not show on blkid!
|
||
|
[ $alreadyf -gt 0 ] && failexit 502 "! Disk is already formatted/IN USE and needs to either be blank or have an empty GPT label: $shortdev / $usedisk"
|
||
|
|
||
|
# Check disk capacity against existing
|
||
|
# fdisk -l /dev/sdb |grep Disk |grep -v 'identifier'
|
||
|
# 1 2 3 4 5
|
||
|
#Disk /dev/sdb: 1000 GB, 1000202273280 bytes
|
||
|
dcap=`fdisk -l $shortdev |grep Disk |grep -v 'identifier' |awk '{print $5}'`
|
||
|
[ $debugg -gt 0 ] && logecho "dcap: $dcap ^^ homespc: $hsbytes"
|
||
|
|
||
|
# comma-sep nums - REF: https://unix.stackexchange.com/questions/113795/add-thousands-separator-in-a-number
|
||
|
if [ $dcap -lt $hsbytes ]; then
|
||
|
dcapcma=`printf "%'d" $dcap`
|
||
|
hsbcma=`printf "%'d" $hsbytes`
|
||
|
|
||
|
logecho "! Disk capacity of $usedisk is less than home data usage!"
|
||
|
logecho "Home: $hsbcma"
|
||
|
logecho "Disk: $dcapcma"
|
||
|
failexit 999 "! Selected Disk capacity of $usedisk is less than home data usage - choose a larger disk or use a larger zpool!"
|
||
|
fi
|
||
|
|
||
|
################################# POINT OF NO RETURN - POSSIBLE DATA DESTRUCTION AFTER THIS!
|
||
|
fdisk -l $shortdev |tee -a $logfile 2>>$logfile
|
||
|
echo '';logecho "YOU ARE ABOUT TO DESTRUCTIVELY GPT LABEL DISK: $usedisk"
|
||
|
echo "ENTER ADMIN PASSWORD TO PROCEED OR ^C: "
|
||
|
read
|
||
|
|
||
|
( set -x
|
||
|
zpool labelclear $shortdev
|
||
|
parted -s $shortdev mklabel gpt
|
||
|
fdisk -l $shortdev |tee -a $logfile)
|
||
|
|
||
|
elif [ `zfs list -d0 |grep -c $argg` -gt 0 ]; then
|
||
|
logecho "o You apparently want me to use this pre-existing ZFS pool for /home:"
|
||
|
zfs list -d0 |grep $argg |head -n 1
|
||
|
usepool=$argg
|
||
|
zp=$argg # using pre-existing pool
|
||
|
else
|
||
|
failexit 404 "! Cannot proceed - $argg was not found on the system!"
|
||
|
fi # did we get passed a disk or existing ZFS pool?
|
||
|
|
||
|
|
||
|
# create the pool if needed
|
||
|
if [ "$usedisk" != "" ] && [ "$usepool" = "" ]; then
|
||
|
[ "$zp" = "" ] && zp=zhome
|
||
|
# set a default name
|
||
|
(set -x
|
||
|
zpool create -o ashift=12 -o autoexpand=on -o autoreplace=on \
|
||
|
-O atime=off -O compression=lz4 \
|
||
|
$zp \
|
||
|
$usedisk
|
||
|
zpool status |awk 'NF>0'
|
||
|
)
|
||
|
fi
|
||
|
|
||
|
# from now on, we are using pool!
|
||
|
(set -x
|
||
|
[ $debugg -gt 0 ] && zfs destroy $zp/home
|
||
|
zfs create -o sharesmb=off $zp/home )
|
||
|
|
||
|
zfs list -p $zp
|
||
|
|
||
|
# TODO check for zfs pool free space vs home use
|
||
|
zpcap=`zfs list -p $zp |awk '{ print $3 }' |tail -n +2` # skip header and get bytes
|
||
|
[ $debugg -gt 0 ] && logecho "zpcap: $zpcap ^^ homespc: $hsbytes"
|
||
|
|
||
|
if [ $zpcap -lt $hsbytes ]; then
|
||
|
zpcapcma=`printf "%'d" $zpcap`
|
||
|
hsbcma=`printf "%'d" $hsbytes`
|
||
|
|
||
|
logecho "! Usable ZFS pool capacity of $zp is less than home data usage!"
|
||
|
logecho "Home: $hsbcma"
|
||
|
logecho "Pool: $zpcapcma"
|
||
|
failexit 919 "! Selected ZFS pool $zp is smaller than home data usage - choose a larger disk or use a larger zpool!"
|
||
|
fi
|
||
|
|
||
|
|
||
|
# Permission was already given, but make sure it's OK to logoff all users
|
||
|
logecho "! NOTE: by proceeding from here, you will be shutting down the X window manager (GUI) and LOGGING OFF all non-root users!"
|
||
|
logecho ' /^^ MAKE SURE ALL YOUR DATA IS BACKED UP / SAVED BEFORE PROCEEDING ^^\'
|
||
|
logecho "You need to be DIRECTLY logged into tty1 or similar as the root userid!"
|
||
|
logecho "ENTER ADMIN PASSWORD TO PROCEED, OR ^C - you need to be running this script directly as root without using sudo!"
|
||
|
read
|
||
|
|
||
|
# Determine WM
|
||
|
xwm=`pstree -psu -A|grep Xorg`
|
||
|
# |-lightdm(1325)-+-Xorg(1388)
|
||
|
xwmedit=`echo $xwm |awk -F\( '{ print $1 }'`
|
||
|
#|-lightdm
|
||
|
xwmedit2=${xwmedit##*-} # strip off to "-" ${tmp2##*-}
|
||
|
#lightdm
|
||
|
|
||
|
[ "$xwmedit2" = "" ] || service $xwmedit2 stop
|
||
|
sleep 2
|
||
|
|
||
|
# OK so far, check if anything in /home is locked
|
||
|
function checkhomelock () {
|
||
|
flocks=`lsof |grep -c /home`
|
||
|
}
|
||
|
|
||
|
logecho "`date` ! Force-logging off anyone who is locking /home files..."
|
||
|
# xxxxx workaround, root getting fragged off
|
||
|
flocks=0
|
||
|
while [ $flocks -gt 0 ]; do
|
||
|
[ $debugg -gt 0 ] && fopts="-i "
|
||
|
# for myuser in `w -h |grep -v root |awk '{print $1}' |sort |uniq`; do
|
||
|
# fuser $fopts -u -v $myuser
|
||
|
fuser $fopts -k -u -v -m /home
|
||
|
# done
|
||
|
checkhomelock
|
||
|
sleep 5;date
|
||
|
done
|
||
|
|
||
|
lsof |grep /home
|
||
|
logecho "o All /home files should be free!"
|
||
|
du -s -h /home
|
||
|
logecho "`date` - Copying /home data over to /$zp/home"
|
||
|
cd /$zp/home || failexit 405 "! FARK - I cant cd to /$zp/home !"
|
||
|
cd /home; df -hT /home /$zp
|
||
|
|
||
|
# had problems with ownership permissions
|
||
|
#time tar cpf - * |pv |(cd /$zp/home; tar xpf - ) || failexit 1000 "! Copying home data failed - check free space!"
|
||
|
# xxxxx 2024.0404 EXPERIMENTAL but appears to work
|
||
|
time rsync -r -t -p -o -g -v --delete -l -s \
|
||
|
--exclude=.thumbnails/* \
|
||
|
/home/ \
|
||
|
/$zp/home \
|
||
|
2>~/rsync-error.log \
|
||
|
|| failexit 1000 "! Copying home data failed - check free space!"
|
||
|
|
||
|
date
|
||
|
|
||
|
df -hT |grep /home
|
||
|
|
||
|
if [ $debugg -gt 0 ]; then
|
||
|
logecho "PK to unmount old /home or move it out of the way:"
|
||
|
read
|
||
|
else
|
||
|
logecho "Unmounting old /home / moving it out of the way:"
|
||
|
fi
|
||
|
|
||
|
if [ $roothome -gt 0 ]; then
|
||
|
mv -v /home /home--old
|
||
|
ls -l / |grep home
|
||
|
else
|
||
|
cd
|
||
|
umount /home
|
||
|
fi
|
||
|
|
||
|
# SKIP edit fstab for noauto - NO, too dangerous to risk
|
||
|
|
||
|
zfs set mountpoint=/home $zp/home
|
||
|
df -h
|
||
|
|
||
|
[ "$xwmedit2" = "" ] || service $xwmedit2 start
|
||
|
logecho "`date` - Finished migrating /home"
|
||
|
|
||
|
zfs snapshot -r $zp@snapshot1
|
||
|
zfs list -r -t snapshot
|
||
|
|
||
|
logecho " -- Dont forget to restart the window manager if needed, and edit /etc/fstab - put /home as noauto!"
|
||
|
logecho "Example: # service lightdm restart"
|
||
|
logecho "EXAMPLE /etc/fstab:"
|
||
|
logecho "LABEL=home /home ext4 defaults,noauto,noatime,errors=remount-ro 0 1"
|
||
|
|
||
|
exit;
|
||
|
|
||
|
|
||
|
REQUIRES:
|
||
|
o Working 'zpool status' and 'zfs list'
|
||
|
o grep, awk, column
|
||
|
o parted, fdisk, blkid
|
||
|
o pstree, lsof, fuser
|
||
|
o tar, pv
|
||
|
|
||
|
lrwxrwxrwx 1 9 Apr 26 13:20 usb-VBOX_HARDDISK-0:0 -> ../../sde
|
||
|
lrwxrwxrwx 1 9 Apr 26 13:20 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sde
|
||
|
lrwxrwxrwx 1 9 Apr 26 13:20 pci-0000:00:14.0-scsi-0:0:0:0 -> ../../sdb
|
||
|
lrwxrwxrwx 1 9 Apr 26 13:20 pci-0000:00:16.0-sas-0x00060504030201a0-lun-0 -> ../../sdc
|
||
|
|
||
|
# column omits leading spaces :)
|
||
|
$ ls -go /dev/disk/by-id /dev/disk/by-path |egrep -v 'part|wwn|total |dev/' |awk 'NF>0' |awk '{$1=$2=$3=$4=$5=$6=""; print $0}'|column -t
|
||
|
ata-VBOX_CD-ROM_VB2-01700376 -> ../../sr0
|
||
|
ata-VBOX_HARDDISK_VB2cf5f3dc-6b93417b -> ../../sdg
|
||
|
ata-VBOX_HARDDISK_VB3c729abf-3f210fcb -> ../../sdd
|
||
|
ata-VBOX_HARDDISK_VB409c8b16-836d593c -> ../../sdf
|
||
|
ata-VBOX_HARDDISK_VBb85ec192-1f9a60c7 -> ../../sda
|
||
|
usb-VBOX_HARDDISK-0:0 -> ../../sde
|
||
|
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sde
|
||
|
pci-0000:00:14.0-scsi-0:0:0:0 -> ../../sdb
|
||
|
pci-0000:00:16.0-sas-0x00060504030201a0-lun-0 -> ../../sdc
|
||
|
|
||
|
alreadyf=`blkid |grep -c $argg`
|
||
|
#/dev/sde1: LABEL="zredpool2" UUID="17065421584496359800" UUID_SUB="1595728817173195411" TYPE="zfs_member" PARTLABEL="zfs" PARTUUID="05762e8f-a4e7-fe42-9b1b-3b2431b1f967"
|
||
|
#/dev/sde9: PARTUUID="9a508052-75aa-3047-a9ef-38d8c2d14649"
|
||
|
|
||
|
#/dev/sda2: LABEL="xubuntu1404" UUID="103f019e-1275-4c27-a972-5b5d3874b863" TYPE="ext4" PARTUUID="b680669e-02"
|
||
|
#/dev/sda3: LABEL="rootantiX-16" UUID="264d2bdc-d4df-4d76-a1dc-3096a5e68bb1" TYPE="ext4" PARTUUID="b680669e-03"
|
||
|
#/dev/sda1: PARTUUID="b680669e-01"
|
||
|
|
||
|
alreadyf2=`blkid |grep -c $shortdev`
|
||
|
let alreadyf=$alreadyf+$alreadyf2
|
||
|
#/dev/sde1: LABEL="zredpool2" UUID="17065421584496359800" UUID_SUB="1595728817173195411" TYPE="zfs_member" PARTLABEL="zfs"
|
||
|
#/dev/sda2: LABEL="xubuntu1404" UUID="103f019e-1275-4c27-a972-5b5d3874b863" TYPE="ext4" PARTUUID="b680669e-02"
|
||
|
#/dev/sda1: PARTUUID="b680669e-01"
|
||
|
|
||
|
|
||
|
|