BLOCKDEV=blockdev
REGLOOKUP=reglookup
CHNTPW=chntpw
+SGDISK=sgdisk
+GROWFS_UFS=growfs.ufs
+DUMPFS_UFS=dumpfs.ufs
DATE="date -u" # Time in UTC
EATMYDATA=eatmydata
+MOUNT="mount -n"
CLEANUP=( )
ERRORS=( )
exec {fd}>&-
}
+send_result_kvm() {
+ echo "$@" > /dev/ttyS1
+}
+
+send_monitor_message_kvm() {
+ echo "$@" > /dev/ttyS2
+}
+
+send_result_xen() {
+ xenstore-write /local/domain/0/snf-image-helper/$DOMID "$*"
+}
+
+send_monitor_message_xen() {
+ #Broadcast the message
+ echo "$@" | socat "STDIO" "UDP-DATAGRAM:${BROADCAST}:${MONITOR_PORT},broadcast"
+}
+
prepare_helper() {
local cmdline item key val hypervisor domid
read -a cmdline < /proc/cmdline
for item in "${cmdline[@]}"; do
- key=$(cut -d= -f1 <<< "$item")
- if [ "$key" = "hypervisor" ]; then
+ key=$(cut -d= -f1 <<< "$item")
val=$(cut -d= -f2 <<< "$item")
- hypervisor="$val"
- fi
+ if [ "$key" = "hypervisor" ]; then
+ hypervisor="$val"
+ fi
+ if [ "$key" = "rules_dev" ]; then
+ export RULES_DEV="$val"
+ fi
+ if [ "$key" = "helper_ip" ]; then
+ export IP="$val"
+ export NETWORK="$IP/24"
+ export BROADCAST="${IP%.*}.255"
+ fi
+ if [ "$key" = "monitor_port" ]; then
+ export MONITOR_PORT="$val"
+ fi
done
case "$hypervisor" in
kvm)
- FLOPPY_DEV=/dev/fd0
- exec {RESULT_FD}> /dev/ttyS1
- add_cleanup close_fd ${RESULT_FD}
- exec {MONITOR_FD}> /dev/ttyS2
- add_cleanup close_fd ${MONITOR_FD}
+ HYPERVISOR=kvm
;;
xen-hvm|xen-pvm)
- mount -t xenfs xenfs /proc/xen
- iptables -P OUTPUT DROP
- ip6tables -P OUTPUT DROP
- ip link set eth0 up
- FLOPPY_DEV=/dev/xvdc
- domid=$(xenstore-read domid)
- exec {RESULT_FD}> >(xargs -l1 xenstore-write /local/domain/0/snf-image-helper/$domid)
- add_cleanup close_fd ${RESULT_FD}
- exec {MONITOR_FD}> >(socat STDIN INTERFACE:eth0)
- add_cleanup close_fd ${MONITOR_FD}
+ if [ -z "$IP" ]; then
+ echo "ERROR: \`helper_ip' not defined or empty" >&2
+ exit 1
+ fi
+ if [ -z "$MONITOR_PORT" ]; then
+ echo "ERROR: \`monitor_port' not defined or empty" >&2
+ exit 1
+ fi
+ $MOUNT -t xenfs xenfs /proc/xen
+ ip addr add "$NETWORK" dev eth0
+ ip link set eth0 up
+ ip route add default dev eth0
+ export DOMID=$(xenstore-read domid)
+ HYPERVISOR=xen
;;
*)
echo "ERROR: Unknown hypervisor: \`$hypervisor'" >&2
;;
esac
- export RESULT_FD MONITOR_FD
+ export HYPERVISOR
}
report_error() {
+ msg=""
if [ ${#ERRORS[*]} -eq 0 ]; then
# No error message. Print stderr
- local lines
- lines=$(tail --lines=${STDERR_LINE_SIZE} "$STDERR_FILE" | wc -l)
- echo -n "STDERR:${lines}:" >&${MONITOR_FD}
- tail --lines=$lines "$STDERR_FILE" >&${MONITOR_FD}
+ local lines stderr
+ stderr="$(tail --lines=${STDERR_LINE_SIZE} "$STDERR_FILE")"
+ lines=$(wc -l <<< "$stderr")
+ msg="STDERR:${lines}:$stderr"
else
for line in "${ERRORS[@]}"; do
- echo "ERROR:$line" >&${MONITOR_FD}
+ msg+="ERROR:$line"$'\n'
done
fi
+
+ send_monitor_message_${HYPERVISOR} "$msg"
}
log_error() {
ERRORS+=("$*")
- echo "ERROR: $@" >&2
- echo "ERROR: $@" >&${MONITOR_FD}
- echo "ERROR" >&${RUSULT_FD}
+ send_result_${HYPERVISOR} "ERROR: $@"
# Use return instead of exit. The set -x options will terminate the script
# but will also trigger ERR traps if defined.
warn() {
echo "Warning: $@" >&2
- echo "WARNING: $@" >&${MONITOR_FD}
+ send_monitor_message_${HYPERVISOR} "WARNING: $@"
}
report_task_start() {
- echo "$MSG_TYPE_TASK_START:${PROGNAME:2}" >&${MONITOR_FD}
+ send_monitor_message_${HYPERVISOR} "$MSG_TYPE_TASK_START:${PROGNAME:2}"
}
report_task_end() {
- echo "$MSG_TYPE_TASK_END:${PROGNAME:2}" >&${MONITOR_FD}
+ send_monitor_message_${HYPERVISOR} "$MSG_TYPE_TASK_END:${PROGNAME:2}"
}
system_poweroff() {
echo "gentoo"
elif [ -e "$root_dir/etc/arch-release" ]; then
echo "arch"
+ elif [ -e "$root_dir/etc/freebsd-update.conf" ]; then
+ echo "freebsd"
else
warn "Unknown base distro."
fi
echo "gentoo"
elif [ -e "$root_dir/etc/arch-release" ]; then
echo "arch"
+ elif [ -e "$root_dir/etc/freebsd-update.conf" ]; then
+ echo "freebsd"
else
warn "Unknown distro."
fi
local dev="$1"
local part_num="$2"
- id=$($SFDISK --print-id "$dev" "$part_num")
+ id=$($SFDISK --force --print-id "$dev" "$part_num")
if [ "$id" = "5" -o "$id" = "f" ]; then
echo "yes"
else
dev="$1"
table=$(get_partition_table "$dev")
+ if [ -z "$table" ]; then
+ return 0
+ fi
if [ $(get_partition_count "$table") -eq 0 ]; then
return 0
local name="${fields[5]}"
local flags="${fields[6]//,/ }"
- $PARTED -s -m -- $device mkpart "$ptype" $fs "$start" "$end"
- for flag in $flags; do
- $PARTED -s -m $device set "$id" "$flag" on
- done
+ if [ "$ptype" = "primary" -o "$ptype" = "logical" -o "$ptype" = "extended" ]; then
+ $PARTED -s -m -- $device mkpart "$ptype" $fs "$start" "$end"
+ for flag in $flags; do
+ $PARTED -s -m $device set "$id" "$flag" on
+ done
+ else
+ # For gpt
+ start=${start:0:${#start}-1} # remove the s at the end
+ end=${end:0:${#end}-1} # remove the s at the end
+ $SGDISK -n "$id":"$start":"$end" -t "$id":"$ptype" "$device"
+ fi
}
enlarge_partition() {
done
}
+get_ufstype() {
+ local device ufs
+
+ device="$1"
+ ufs="$($DUMPFS_UFS "$device" | head -1 | awk '{ match ($3, /\((.+)\)/, ufs); print ufs[1] }')"
+
+ case "$ufs" in
+ UFS1)
+ echo 44bsd
+ ;;
+ UFS2)
+ echo ufs2
+ ;;
+ *)
+ log_error "Unsupported UFS type: \`$ufs' in device $device"
+ echo ""
+ ;;
+ esac
+}
+
cleanup() {
# if something fails here, it shouldn't call cleanup again...
trap - EXIT
return 0
}
-
return_success() {
- echo SUCCESS >&${RESULT_FD}
+ send_result_${HYPERVISOR} "SUCCESS"
}
trap cleanup EXIT