├── README.md ├── zfs-snapshot.sh ├── hdd-temp.sh └── create-jail.sh /README.md: -------------------------------------------------------------------------------- 1 | # FreeBSD tools collection 2 | 3 | 4 | ## hdd-temp 5 | 6 | FreeBSD tool to trigger the temperature of all attached hdd's 7 | Data is presented in a nice colorized way (green, yellow and red) 8 | 9 | **Requirements:** 10 | 11 | * smartctl (sysutils/smartmontools) 12 | * must be run as root 13 | 14 | 15 | ## create-jail 16 | 17 | FreeBSD tool to create a jail on non-zfs systems easily 18 | 19 | **Requirements:** 20 | 21 | * /usr/src must be compiled 22 | * must be run as root 23 | 24 | 25 | ## zfs-snapshot 26 | 27 | An automated zfs snapshot creation script, Ideally used for cron. 28 | Let's you specify which zfs filesystem to snapshot and also how many old snapshots to keep. 29 | 30 | **Requirements:** 31 | 32 | * ZFS ;-) 33 | -------------------------------------------------------------------------------- /zfs-snapshot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return Pantu 8 | # ---------------------------------------------------------------------------- 9 | # 10 | # To use as previous version in samba: 11 | # follow symlinks = yes 12 | # wide links = yes 13 | # vfs objects = shadow_copy2 14 | # shadow:snapdir = .zfs/snapshot 15 | # shadow:localtime = yes ; use local server timezone rather than GMT 16 | # shadow:sort = desc ; descending sort makes more sense 17 | # shadow:format = %Y-%m-%d_%H.%M.%S ; format (see below for LABEL) - They must match!! 18 | # 19 | 20 | progname=$0 21 | 22 | usage () 23 | { 24 | cat <] [-l ] [-k ] 26 | 27 | Required Options: 28 | -d : Specify the zfs dataset to create the snapshot for 29 | -l : Specify the label of the snapshot 30 | -k : Only keep X snapshots and delete the rest 31 | 32 | Example: 33 | $progname -d tank/files/data -l %Y-%m-%d_%H.%M.%S -k 5 34 | 35 | EOF 36 | exit 0; 37 | } 38 | 39 | while getopts ":h::d:l:k:" opt; 40 | do 41 | case $opt in 42 | h) usage; 43 | ;; 44 | d) d=$OPTARG; 45 | ;; 46 | l) l=$OPTARG; 47 | ;; 48 | k) k=$OPTARG; 49 | ;; 50 | ?) usage; 51 | ;; 52 | esac 53 | done 54 | shift $(($OPTIND - 1)); 55 | 56 | 57 | # If required vars are not set, display usage 58 | if [ -z "${d+xxx}" ]; then usage; fi 59 | if [ -z "${l+xxx}" ]; then usage; fi 60 | if [ -z "${k+xxx}" ]; then usage; fi 61 | 62 | # ------------------- Settings ------------------- 63 | 64 | # How many snapshots to keep? 65 | # All older snapshots will be deleted. 66 | KEEP=$k 67 | 68 | # Which ZFS filesystem to snapshot? 69 | # E.g.: tank/data/files 70 | # Note: Do not append a slash at the end! 71 | FILESYSTEM=$d 72 | 73 | 74 | 75 | # ------------------- Binaries ------------------- 76 | ZFS="/sbin/zfs" 77 | GREP="/usr/bin/grep" 78 | WC="/usr/bin/wc" 79 | DATE="/bin/date" 80 | EXPR="/bin/expr" 81 | 82 | 83 | 84 | # ------------------- Create new snapshot ------------------- 85 | 86 | # Label to use for snapshot 87 | LABEL=`${DATE} +"${l}"` 88 | `${ZFS} snapshot ${FILESYSTEM}@${LABEL}` 89 | 90 | 91 | # ------------------- Delete old snapshots ------------------- 92 | 93 | # Count current available snapshots 94 | # The '@' makes sure we do not count childs of that snapshot. 95 | COUNT=`${ZFS} list -t snapshot | ${GREP} ${FILESYSTEM}@ | ${WC} -l` 96 | 97 | # Get the difference between the number you want to keep and the number that actually exists 98 | DIFF=`$EXPR $COUNT - $KEEP` 99 | 100 | 101 | # Are there more snapshots than you want to keep? 102 | if [ $DIFF -gt 0 ]; then 103 | 104 | # get older snapshots for deletion 105 | for snapshot in `${ZFS} list -t snapshot | ${GREP} ${FILESYSTEM}@ | head -n${DIFF} | awk '{print $1}'` 106 | do 107 | # delete the undesired snapshots 108 | `${ZFS} destroy ${snapshot}` 109 | done 110 | fi 111 | -------------------------------------------------------------------------------- /hdd-temp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return cytopia 8 | # ---------------------------------------------------------------------------- 9 | # 10 | 11 | 12 | # ---------------------------------- Global Variables --------------------------------- # 13 | # Colors 14 | GREEN="\033[32m" 15 | YELLOW="\033[33m" 16 | RED="\033[31m" 17 | OFF="\033[0m" 18 | 19 | 20 | # ---------------------------------- Misc Function ---------------------------------- # 21 | 22 | # 23 | # Prequisites, 24 | # * check if this script is run by root 25 | # * check if smartctl is installed 26 | # 27 | check_requirements() 28 | { 29 | # Check if we are root 30 | if [ "$(id -u)" != "0" ]; then 31 | echo "This script must be run as root" 1>&2 32 | exit 1 33 | fi 34 | 35 | # Check if smartctl exists on the system 36 | command -v smartctl >/dev/null || { echo "smartctl not found. (install sysutils/smartmontools)"; exit 1; } 37 | } 38 | 39 | 40 | # 41 | # Colorize output of temperature (all platforms) 42 | # 43 | colorize_temperature() 44 | { 45 | temp=$1 46 | 47 | case $temp in 48 | # no temperature obtained 49 | ''|*[!0-9]*) 50 | temp="n.a." 51 | ;; 52 | # temperature is obtained 53 | *) 54 | if [ $temp -gt 40 ]; then 55 | temp="${RED}${temp} C${OFF}" 56 | elif [ $temp -gt 30 ]; then 57 | temp="${YELLOW}${temp} C${OFF}" 58 | else 59 | temp="${GREEN}${temp} C${OFF}" 60 | fi 61 | ;; 62 | esac 63 | 64 | echo $temp 65 | } 66 | 67 | 68 | 69 | # ---------------------------------- Generic Disk Function ---------------------------------- # 70 | 71 | # 72 | # Get all devices that are attached to the system 73 | # 74 | get_attached_devices() 75 | { 76 | DEVS=`sysctl kern.disks | awk '{$1=""; ;print $0}' | awk 'gsub(" ", "\n")' | tail -n500 -r | sed '/^cd[0-9]/d'` 77 | echo $DEVS 78 | } 79 | 80 | get_disk_bus() 81 | { 82 | dev=$1 83 | bus=`cat /var/run/dmesg.boot | grep "${dev} at" |grep target | awk '{print $3}'` 84 | echo $bus 85 | } 86 | 87 | get_disk_size() 88 | { 89 | dev=$1 90 | size=`diskinfo -v /dev/${dev} | grep bytes | awk '{printf "%.2f\n",($1/(1024*1024*1024))}'` 91 | echo $size 92 | } 93 | 94 | get_disk_speed() 95 | { 96 | dev=$1 97 | speed=`cat /var/run/dmesg.boot |grep ${dev}: | grep transfers | awk '{print $2};'` 98 | echo $speed 99 | } 100 | 101 | get_disk_number() 102 | { 103 | dev=$1 104 | disk_num=`echo ${dev} | sed 's/[^0-9]*//g'` 105 | echo $disk_num 106 | } 107 | 108 | 109 | # ---------------------------------- ATA-Device Functions ---------------------------------- # 110 | get_ata_disk_name() 111 | { 112 | dev=$1 113 | name=`cat /var/run/dmesg.boot |grep ${dev}: | grep "<"|grep ">" | awk 'gsub(/<|>/, "\n");' | awk 'NR==2'` 114 | echo $name 115 | } 116 | 117 | get_ata_disk_temp() 118 | { 119 | dev=$1 120 | temp=`smartctl -d atacam -A /dev/${dev} | grep Temperature_Celsius | awk '{print $10}'` 121 | echo $temp 122 | } 123 | 124 | 125 | # ---------------------------------- CISS-Device Functions ---------------------------------- # 126 | get_ciss_disk_name() 127 | { 128 | smartctl=$1 129 | name=`echo "${smartctl}" | grep "Device Model" | awk '{$1=$2=""} {sub(/^[ \t]+/, ""); print;}'` 130 | firm=`echo "${smartctl}" | grep "Firmware" | awk ' {$1=$2=""} {sub(/^[ \t]+/, ""); print;}'` 131 | echo "$name $firm" 132 | } 133 | 134 | get_ciss_disk_temp() 135 | { 136 | smartctl=$1 137 | temp=`echo "${smartctl}" | grep Temperature_Celsius | awk '{print $10}'` 138 | echo $temp 139 | } 140 | 141 | 142 | 143 | 144 | 145 | # ---------------------------------- Main Entry Point ---------------------------------- # 146 | 147 | # Check if script can be run 148 | check_requirements 149 | 150 | 151 | # Loop through all attached devices 152 | for dev in `get_attached_devices` 153 | do 154 | size=`get_disk_size ${dev}` 155 | bus=`get_disk_bus ${dev}` 156 | speed=`get_disk_speed ${dev}` 157 | 158 | # check for HP Smart Array controllers 159 | if [ $bus == "ciss*" ]; then 160 | devnum=`get_disk_number ${dev}` 161 | smartctl=`smartctl -a -T permissive -d cciss,${devnum} /dev/${bus} 2> /dev/null` 162 | name=`get_ciss_disk_name "${smartctl}"` # preserve newlines by using " 163 | temp=`get_ciss_disk_temp "${smartctl}"` 164 | echo "smartctl -a -T permissive -d cciss,${devnum} /dev/${bus} 2> /dev/null" # debug 165 | else 166 | name=`get_ata_disk_name ${dev}` 167 | temp=`get_ata_disk_temp ${dev}` 168 | fi 169 | 170 | temp=`colorize_temperature ${temp}` 171 | 172 | echo -e "$temp\t${bus}:${dev}\t${speed}\t${name} (${size}G)" 173 | done 174 | 175 | #eof 176 | 177 | -------------------------------------------------------------------------------- /create-jail.sh: -------------------------------------------------------------------------------- 1 | #/!bin/sh 2 | # 3 | # ---------------------------------------------------------------------------- 4 | # "THE BEER-WARE LICENSE" (Revision 42): 5 | # wrote this file. As long as you retain this notice you 6 | # can do whatever you want with this stuff. If we meet some day, and you think 7 | # this stuff is worth it, you can buy me a beer in return cytopia 8 | # ---------------------------------------------------------------------------- 9 | # 10 | 11 | 12 | 13 | # ---------------------------------- Misc Functions --------------------------------- # 14 | 15 | show_usage() 16 | { 17 | script=$1 18 | echo "Usage:" 19 | echo " ${script} /path/to/new/jail_name" 20 | } 21 | 22 | 23 | # 24 | # Prequisites, 25 | # 26 | check_requirements() 27 | { 28 | jail_path=$1 29 | num_args=$2 30 | 31 | # 01) Check if we are root 32 | if [ "$(id -u)" != "0" ]; then 33 | echo "This script must be run as root" 1>&2 34 | exit 35 | fi 36 | 37 | # 02) check for correct number of parameters 38 | if [ "$num_args" != "1" ]; then 39 | echo "Illegal number of arguments" 40 | show_usage $0 41 | exit 42 | fi 43 | 44 | # 03) Check if directory exists 45 | if [ ! -d "$jail_path" ]; then 46 | echo "$jail_path does not exist" 47 | echo "Please create it first" 48 | exit 49 | fi 50 | 51 | # 04) Check if directory is already used (not empty) 52 | if [ "$(ls -A $jail_path)" ]; then 53 | echo "The directory $jail_path is not empty." 54 | echo "Make sure to specify an empty (unused) directory" 55 | exit 56 | fi 57 | 58 | # 05) ask for requirements 59 | read -r -p "Did you already do a 'make buildworld' in /usr/src ? [Y/n] " response 60 | case $response in 61 | [yY][eE][sS]|[yY]) 62 | echo "good :-)" 63 | ;; 64 | *) 65 | echo "This is required. Good Bye!" 66 | exit 67 | ;; 68 | esac 69 | } 70 | 71 | 72 | 73 | # ---------------------------------- Action Functions --------------------------------- # 74 | 75 | jail_install() 76 | { 77 | jail_path=$1 78 | echo "" 79 | echo "------------------------- INSTALLING SOURCE -------------------------" 80 | echo "" 81 | 82 | cd /usr/src 83 | make installworld DESTDIR=$jail_path 84 | cd /usr/src/etc 85 | make distribution DESTDIR=$jail_path 86 | } 87 | 88 | jail_create_configs() 89 | { 90 | jail_path=$1 91 | echo "" 92 | echo "------------------------- CREATING jail configs -------------------------" 93 | echo "" 94 | 95 | touch $jail_path/etc/fstab 96 | touch $jail_path/etc/resolv.conf 97 | touch $jail_path/etc/rc.conf 98 | 99 | echo "#disable remote logging" >> $jail_path/etc/rc.conf 100 | echo "syslogd_enable=\"YES\"" >> $jail_path/etc/rc.conf 101 | echo "syslogd_flags=\"-ss\"" >> $jail_path/etc/rc.conf 102 | echo "" >> $jail_path/etc/rc.conf 103 | echo "#disable sendmail" >> $jail_path/etc/rc.conf 104 | echo "sendmail_enable=\"NONE\"" >> $jail_path/etc/rc.conf 105 | echo "" >> $jail_path/etc/rc.conf 106 | echo "#disable rpc bind" >> $jail_path/etc/rc.conf 107 | echo "rpcbind_enable=\"NO\"" >> $jail_path/etc/rc.conf 108 | echo "" >> $jail_path/etc/rc.conf 109 | echo "#prevent lots of jails running cron jobs at the same time" >> $jail_path/etc/rc.conf 110 | echo "cron_flags=\"\$cront_flags -J 15\"" >> $jail_path/etc/rc.conf 111 | echo "" >> $jail_path/etc/rc.conf 112 | echo "#clear /tmp " >> $jail_path/etc/rc.conf 113 | echo "clear_tmp_enable=\"YES\"" >> $jail_path/etc/rc.conf 114 | } 115 | 116 | host_create_configs() 117 | { 118 | jail_path=$1 119 | jail_base="$(dirname "$jail_path")" 120 | jail_name="$(basename "$jail_path")" 121 | jail_path="${jail_base}/${jail_name}" # prevent double slashes 122 | 123 | host_fstab="${jail_base}/fstab.${jail_name}" 124 | port_mount="/usr/ports ${jail_path}/usr/ports nullfs noatime,rw 0 0" 125 | portsnap_mount="/var/db/portsnap ${jail_path}/var/db/portsnap nullfs noatime,rw 0 0" 126 | 127 | echo "" 128 | echo "------------------------- CREATING host configs -------------------------" 129 | echo "" 130 | 131 | # create host fstab for jail 132 | touch $host_fstab 133 | 134 | # automount ports and portsnap 135 | echo "${port_mount}" >> $host_fstab 136 | echo "${portsnap_mount}" >> $host_fstab 137 | } 138 | 139 | 140 | 141 | 142 | # ------------------------------------- Vars ------------------------------------- # 143 | 144 | INSTALL_DIR=$1 145 | NUM_ARGS=$# 146 | 147 | 148 | # ------------------------------------- Main Entry Point ------------------------------------- # 149 | 150 | check_requirements $INSTALL_DIR $NUM_ARGS 151 | 152 | 153 | echo "Going to create a new jail in $INSTALL_DIR" 154 | read -r -p "Are you sure? [Y/n] " response 155 | case $response in 156 | [yY][eE][sS]|[yY]) 157 | jail_install $INSTALL_DIR 158 | jail_create_configs $INSTALL_DIR 159 | host_create_configs $INSTALL_DIR 160 | echo "" 161 | echo "done" 162 | ;; 163 | *) 164 | echo "Good Bye!" 165 | exit 166 | ;; 167 | esac 168 | --------------------------------------------------------------------------------