#!/bin/sh
exit 1  #Not actually a script.

VG=xenvg
DISK=/dev/mapper/36090a028407d6e2b2589a45cdb971489
HALFSIZETiB=5.23
TMPDM=tmpfoo
TMPDEV=/dev/mapper/$TMPDM
TMPDM2=tmpbar
TMPDEV2=/dev/mapper/$TMPDM2
METADATASIZE=8128k

#  - pvresize the old PV to half the space
pvresize --setphysicalvolumesize=${HALFSIZETiB}t $DISK

#  - dmsetup create a device in the latter half
dmstart=$(python -c "print int(($HALFSIZETiB + 0.01) * 1024 * 1024 * 1024 * 2)")
dmlen=$(python -c "print int(($HALFSIZETiB - 0.03) * 1024 * 1024 * 1024 * 2)")
#Foreach host:
dmsetup create $TMPDM --table "0 $dmlen linear $DISK $dmstart"
#done

#  - pvcreate a temporary PV on the new device
pvcreate $TMPDEV

#  - vgextend with the temporary PV
vgextend $VG $TMPDEV

#  - pvmove all the LVs to the temporary PV

yamlkeys () {
  python -c 'if 1:
    import yaml, sys
    mm = yaml.load(sys.stdin.read())
    for m in sorted(mm.iterkeys()): print m'
}

vmstolvs () {
  perl -pe 's/^/d_/;s/$/_hda/'
}

totalsize () {
  # handy for estimating time; output in GiB; pipe in a list of LVs
  perl -pe 's.^.xenvg/.' \
   | xargs lvs -o size --units=g \
   | perl -lne '$total += $_; END { print $total; }'
}

lvsleft () {
  lvs -o name,devices $VG \
    | perl -lane "print \$F[0] if (\$F[1] =~ m|$DISK|)"
}

movelv () {
  echo pvmoving $VG/$1...
  pvmove -i 10 -n $VG/$1 $2
}

ssh root@xvm remctl remote web listvms \
 | yamlkeys \
 > runningvms
LVM_SYSTEM_DIR=/root/lvm lvsleft \
 | grep '^d_.*_hda$' \
 | grep -v -xf <(vmstolvs <runningvms) \
 > offvmlvs
for lv in $(offvmlvs); do
  LVM_SYSTEM_DIR=/root/lvm movelv $lv $DISK
done
#FOREACH host:
for lv in $(invirt-listvms | yamlkeys | vmstolvs \
             | grep -xf <(LVM_SYSTEM_DIR=/root/lvm lvsleft)); do
  LVM_SYSTEM_DIR=/root/lvm movelv $lv $DISK
done
#done

ssh root@xvm remctl remote web listvms \
 | perl -lne 'print if (s/^  cdrom: //)' \
 > usedcdroms
LVM_SYSTEM_DIR=/root/lvm lvsleft \
 | grep ^image_ \
 | grep -v -xf <(perl -pe "s|/dev/$VG/||" usedcdroms) \
 > offcdlvs
for lv in $(offcdlvs); do
  LVM_SYSTEM_DIR=/root/lvm movelv $lv $DISK
done

# deal with $(cat usedcdroms)
# deal with s_* LVs
# deal with any remaining $(lvsleft)

[ -z $(lvsleft) ]


#  - pvremove the old PV
LVM_SYSTEM_DIR=lvm vgreduce $VG $DISK
dmsetup create $TMPDM2 --table "0 $((2 * 1024 * 20)) linear $DISK 0"
pvremove $TMPDEV2

#  - pvcreate a new PV in the old space,
#     with --setphysicalvolumesize <half size>
#     and with --metadatasize <huge>    (the point of this exercise)
shortsize=$(python -c "print $HALFSIZETiB - 0.01")t
pvcreate $TMPDEV2 --setphysicalvolumesize $shortsize --metadatasize $METADATASIZE
dmsetup remove $TMPDM2
pvscan
LVM_SYSTEM_DIR=lvm vgextend $VG $DISK

#  - pvmove all the LVs back

# Doing this part with CLVM again.

lvsleft () {
  lvs -o name,devices $VG \
    | perl -lane "print \$F[0] if (\$F[1] =~ m|$TMPDEV|)"
}

movelv () {
  echo pvmoving $VG/$1...
  lvchange -an $VG/$1
  pvmove -i 10 -n $VG/$1 $2
  lvchange -ay $VG/$1
}

movestuff () {
  date
  while read lv; do
    echo MOVING: $lv >>/var/log/lvm2.log
    movelv $lv $TMPDEV
    date
  done
}

moveall () {
  date
  for lv in $(lvsleft); do
    echo MOVING: $lv >>/var/log/lvm2.log
    movelv $lv $TMPDEV
    date
  done
}

#FOREACH host:
#set logging in /etc/lvm/lvm.conf
while sleep 1; do
  echo MARK: $(date) >>/var/log/lvm2.log
done &
lvsleft | grep -xf <(invirt-listvms | yamlkeys | vmstolvs) \
 | movestuff >>/root/lvm/movelv.log 2>&1
moveall >>/root/lvm/movelv.log 2>&1
while true; do
  kinit -k -45
  sh -x status.sh 2>&1 | zwrite -c xvm-auto -i pvmove -O auto
  sleep 1800
done &
#done

#suffix=.return-1; mv /var/log/lvm2.log lvm/lvm2.$suffix.log; mv lvm/movelv{,.$suffix}.log

# hopefully empty:
lvs $VG -o lv_name,devices | grep $TMPDEV
# if not, do some more movelv

#  - pvremove the temporary PV
vgreduce $VG $TMPDEV
pvremove $TMPDEV
#FOREACH host:
dmsetup remove $TMPDM
#done

#  - pvresize the new PV to use the whole space
pvresize $DISK