# vm-bhyve snapshot



## al mello (Aug 30, 2017)

Folks,

Snapshots of running vms are not recommended. Can be done with forcing (-f flag).

In order to mechanize regular vm snapshots I'm thinking to use a cron taks to call a script.

As This is not my fortè, any help will be appreciated. Here what I've started:

```
[noparse]#!/bin/bash
#
declare -a vm_name vm_pid

vm list > all.vms
vm_name=( $(awk '{print $1}' all.vms) )
vm_pid=( $(awk '{print $NF}' all.vms) )
#vm stopall
# <---------- Wait for all VMs to stop before continue ------------>
for  i in "${!vm_name[@]}";
do
  echo ${vm_name[$i]} " - " ${vm_pid[$i]}
  if [ "${vm_pid[i]}" != "Stopped" ] &&  [ "${vm_pid[i]}" != "STATE" ]
     then
        vm snapshot ${vm_name[$i]}
        vm start ${vm_name[$i]}
  fi
done[/noparse]
```

I'd like to have the script checking if all VMs have been stopped before continue. I could pause for a minute or so, but is there a way to check if the 
	
	



```
vm stopall
```
 finished? Or maybe check each captured pid?

Any suggestion on improving it will also be welcome.

[]'s,
Al


----------



## SirDice (Aug 30, 2017)

On FreeBSD there is no /bin/bash. It's /usr/local/bin/bash and requires shells/bash to be installed. Not a big deal but it's better to use plain (Bourne) shell syntax and use /bin/sh.


----------



## al mello (Aug 30, 2017)

SirDice said:


> On FreeBSD there is no /bin/bash. It's /usr/local/bin/bash and requires shells/bash to be installed. Not a big deal but it's better to use plain (Bourne) shell syntax and use /bin/sh.



Will keep digging. Thanks!


----------



## al mello (Aug 30, 2017)

Maybe unrelated to issue on hand, but not that unrelated ...

Move to FreeBSD is not an easy task. Will I give up on it? No! Among others ZFS is a must have. The real problem is, although the documentation exists, learn from it takes awhile and researches on how/what are not as available as for linux.

Once a die hard FreeBSD dev from ix said: "The reason is that the number of linux users are 1000 x bigger", but I'd add that the main reason is that FreeBSD is maintained by the community without any monetary incentive, for free, etc. 

Getting a Bourne shell book and trying again


----------



## SirDice (Aug 30, 2017)

al mello said:


> Getting a Bourne shell book and trying again


I use this site a lot for reference: http://www.grymoire.com/Unix/Sh.html


----------



## al mello (Aug 30, 2017)

SirDice said:


> I use this site a lot for reference: http://www.grymoire.com/Unix/Sh.html



Thanks. Was also reading: https://en.wikibooks.org/wiki/Bourne_Shell_Scripting


----------



## al mello (Sep 8, 2017)

```
#!/bin/sh
#

# vmsnapshot.sh
#
# This is a simple script to create a snapshot of each running bhyve VM.
#
# It will creates a list of all hosts' VMs; process one-by-one by stoppping, creating the
# snapshot with the current date and time, and restarting the VM.
#
# It won't snapshot VMs that are not running.
#
# cron tasks can be created to run this script on a regular schedule. No parameters are needed.
# crontab tasks entries will control when the script is to be executed.
#
# A log will be created with the main steps, but you can add anything to the log by executing
# the function log() with the string to be logged.
#
# ----------------------------------------------------------------------------
# License
#
# Copyright (c) 2017 by Al Mello
#
# Feedbacks welcome to: al_mello @ hotmail(dot)com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ------------------------------------------------------------------------------

#######################
# Variables
#######################

now=$(date +"%Y-%m-%d_%H:%M:%S")                # Run date
maindir=/raid/vm/                               # bhyve VM's directory
log_file=$maindir"/vmsnapshot.log"              # Log file
vmbhyve=/usr/local/sbin/vm                      # Path for vm-bhyve

#######################
# Process log entries
#######################

log()
{
timestamp=$(date +"[%Y-%m-%d %H:%M:%S]")
parm="$1"
  if [ -e $log_file ];
     then
     echo "$timestamp bhyve vmsnapshot: $parm" >> $log_file
  else
    echo "$timestamp copy bhyve vmsnapshot: Log file created" > $log_file
    echo "$timestamp copy bhyve vmsnapshot: $parm" >> $log_file
  fi
}


#######################
# Main
#######################

log "*** vmsnapshot Script started ***"

#
# List existing VMs
#

$vmbhyve list > vms.asc

#
# Determine number of existing VMs
#

nr_lines=$(wc -l < vms.asc)
nr_vms=$(($nr_lines - 1))

#
# Exit if no VMs on this host
#

if [ "$nr_vms" -lt "1" ]; then
    log "No VMs defined on this host"
    log "***    End of script    ***"
    exit
fi

#
# Process each VM
#

cur_line=2           
while [ "$cur_line" -le "$nr_lines" ]; do
    line=$(sed -n "$cur_line{p;q;}" 'vms.asc')
    vm_name=$(echo $line | awk '{print $1}')
    flag=$(echo $line | awk '{print $NF}')
    if [ "$flag" = "Stopped" ]; then
        log "VM $vm_name is stopped"
        cur_line=$((cur_line+1))
    else
           log "Creating snapshot of $vm_name"  
           vm_pid=$(echo $line | awk '{print $NF}' | tr -d '()')
           $vmbhyve stop $vm_name
           while kill -0 $vm_pid 2> /dev/null; do
            sleep 1
            vm_pid=$(echo $line | awk '{print $NF}' | tr -d '()')
        done
        $vmbhyve snapshot $vm_name@$now
        $vmbhyve start $vm_name
           cur_line=$((cur_line+1))
    fi
done      

log "***    End of script    ***"
```


----------



## IPTRACE (Sep 9, 2017)

What is the size of the snapshot using vm-bhyve?
I just compress the image files online (without stopping run guests) and copy to another location.
I was restoring compressed image files many times with succeesful.


----------



## al mello (Sep 10, 2017)

I'd think it depends on each situation. My pf is, for instance: raid/vm/pf@2017-09-09_03:30:00                                                 25.8M      -   122G



IPTRACE said:


> I just compress the image files online (without stopping run guests) and copy to another location.



I may be too old school to thrust backing-up a running machine and it takes:

```
[2017-09-07 03:30:00] bhyve vmsnapshot: *** vmsnapshot Script started ***
[2017-09-07 03:30:00] bhyve vmsnapshot: VM dockers is stopped
[2017-09-07 03:30:00] bhyve vmsnapshot: VM freebsd is stopped
[2017-09-07 03:30:00] bhyve vmsnapshot: VM guacamole is stopped
[2017-09-07 03:30:00] bhyve vmsnapshot: Creating snapshot of mediaserver
[2017-09-07 03:30:05] bhyve vmsnapshot: Creating snapshot of mx-server
[2017-09-07 03:30:14] bhyve vmsnapshot: Creating snapshot of nextcloud
[2017-09-07 03:32:04] bhyve vmsnapshot: Creating snapshot of pf
[2017-09-07 03:32:25] bhyve vmsnapshot: Creating snapshot of zm
[2017-09-07 03:33:31] bhyve vmsnapshot: ***    End of script    ***
```

Less than a minutes of down time per VM... Above you see: Plex took 5 seconds, mail server took 9 seconds, NC 60 seconds, pf 21 secs, zm 66 secs; so why not be safer? 

Edit:


----------

