Unverified Commit 08e40844 authored by Kroese's avatar Kroese Committed by GitHub
Browse files

feat: Daemonize QEMU

* feat: Daemonize QEMU
parent 06f21084
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,8 +3,8 @@ set -Eeuo pipefail

: ${VM_NET_DEV:='eth0'}

[ ! -f "/run/qemu.pid" ] && echo "QEMU not running yet.." && exit 0
[ -f "/run/qemu.count" ] && echo "QEMU is shutting down.." && exit 1
[ ! -f "/run/qemu.pid" ] && echo "QEMU not running yet.." && exit 0

file="/run/dsm.url"
[ ! -f  "$file" ] && echo "DSM has not enabled networking yet.." && exit 1
+8 −9
Original line number Diff line number Diff line
@@ -23,12 +23,11 @@ if [[ "$CONSOLE" == [Yy]* ]]; then
  exit $?
fi

set -m
(
[[ "$DEBUG" == [Yy1]* ]] && info "$VERS" && set -x
  qemu-system-x86_64 ${ARGS:+ $ARGS} & echo $! > "$QEMU_PID"
qemu-system-x86_64 -daemonize -pidfile "$QEMU_PID" ${ARGS:+ $ARGS}

{ set +x; } 2>/dev/null
)
set +m
cat /dev/pts/1 2>/dev/null & wait $! || true

tail --pid "$(cat "$QEMU_PID")" --follow /dev/null & wait $!
sleep 1
finish 0
+3 −3
Original line number Diff line number Diff line
@@ -158,14 +158,14 @@ closeNetwork () {

  if [[ "$DHCP" == [Yy1]* ]]; then

    { pkill -f server.sh || true; } 2>/dev/null
    fKill "server.sh"

    ip link set "$VM_NET_TAP" down || true
    ip link delete "$VM_NET_TAP" || true

  else

    { pkill -f dnsmasq || true; } 2>/dev/null
    fKill "dnsmasq"

    ip link set "$VM_NET_TAP" down promisc off || true
    ip link delete "$VM_NET_TAP" || true
@@ -180,7 +180,7 @@ closeNetwork () {
#  Configure Network
# ######################################

{ pkill -f server.sh || true; } 2>/dev/null
fKill "server.sh"

# Create the necessary file structure for /dev/net/tun
if [ ! -c /dev/net/tun ]; then
+72 −31
Original line number Diff line number Diff line
@@ -3,11 +3,20 @@ set -Eeuo pipefail

# Configure QEMU for graceful shutdown

API_CMD=6
API_TIMEOUT=50
API_HOST="127.0.0.1:2210"

QEMU_PORT=7100
QEMU_TIMEOUT=55
QEMU_TIMEOUT=50
QEMU_PID="/run/qemu.pid"
QEMU_COUNT="/run/qemu.count"

if [[ "$KVM" == [Nn]* ]]; then
  API_TIMEOUT=$(( API_TIMEOUT*2 ))
  QEMU_TIMEOUT=$(( QEMU_TIMEOUT*2 ))
fi

rm -f "$QEMU_PID"
rm -f "$QEMU_COUNT"

@@ -18,23 +27,64 @@ _trap(){
  done
}

finish() {

  local pid
  local reason=$1

  if [ -f "$QEMU_PID" ]; then

    pid="$(cat "$QEMU_PID")"
    echo && error "Forcefully quitting QEMU process, reason: $reason..."
    { kill -15 "$pid" || true; } 2>/dev/null

    while isAlive "$pid"; do
      sleep 1
      # Workaround for zombie pid
      [ ! -f "$QEMU_PID" ] && break
    done
  fi

  fKill "print.sh"
  fKill "host.bin"

  closeNetwork

  sleep 1
  echo && info "Shutdown completed!"

  exit "$reason"
}

_graceful_shutdown() {

  set +e
  local cnt response
  local code=$?
  local pid cnt response

  [ ! -f "$QEMU_PID" ] && exit 130
  [ -f "$QEMU_COUNT" ] && return

  echo 0 > "$QEMU_COUNT"

  set +e
  echo && info "Received $1 signal, sending shutdown command..."

  if [ ! -f "$QEMU_PID" ]; then
    echo && error "QEMU PID file does not exist?"
    finish "$code" && return "$code"
  fi

  pid="$(cat "$QEMU_PID")"

  if ! isAlive "$pid"; then
    echo && error "QEMU process does not exist?"
    finish "$code" && return "$code"
  fi

  # Don't send the powerdown signal because vDSM ignores ACPI signals
  # echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null

  # Send shutdown command to guest agent via serial port
  url="http://127.0.0.1:2210/read?command=6&timeout=50"
  response=$(curl -sk -m 52 -S "$url" 2>&1)
  url="http://$API_HOST/read?command=$API_CMD&timeout=$API_TIMEOUT"
  response=$(curl -sk -m "$(( API_TIMEOUT+2 ))" -S "$url" 2>&1)

  if [[ "$response" =~ "\"success\"" ]]; then

@@ -43,19 +93,17 @@ _graceful_shutdown() {
  else

    response="${response#*message\"\: \"}"
    echo && error "Failed to send shutdown command: ${response%%\"*}"

    kill -15 "$(cat "$QEMU_PID")"
    pkill -f qemu-system-x86_64 || true
    [ -z "$response" ] && response="second signal"
    echo && error "Forcefully quitting because of: ${response%%\"*}"
    { kill -15 "$pid" || true; } 2>/dev/null

  fi

  while [ "$(cat $QEMU_COUNT)" -lt "$QEMU_TIMEOUT" ]; do

    # Try to connect to qemu
    if ! echo 'info version'| nc -q 1 -w 1 localhost "$QEMU_PORT" >/dev/null 2>&1 ; then
      break
    fi
    ! isAlive "$pid" && break

    sleep 1

    # Increase the counter
    cnt=$(($(cat $QEMU_COUNT)+1))
@@ -63,23 +111,16 @@ _graceful_shutdown() {

    [[ "$DEBUG" == [Yy1]* ]] && info "Shutting down, waiting... ($cnt/$QEMU_TIMEOUT)"

    # Workaround for zombie pid
    [ ! -f "$QEMU_PID" ] && break

  done

  if [ "$(cat $QEMU_COUNT)" -ge "$QEMU_TIMEOUT" ]; then
    echo && error "Shutdown timeout reached, forcefully quitting.."
  else
    echo && echo "❯ Quitting..."
    echo && error "Shutdown timeout reached!"
  fi

  echo 'quit' | nc -q 1 -w 1 localhost "$QEMU_PORT" >/dev/null 2>&1 || true

  { pkill -f print.sh || true; } 2>/dev/null
  { pkill -f host.bin || true; } 2>/dev/null

  closeNetwork
  sleep 1

  return
  finish "$code" && return "$code"
}

_trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT
+34 −2
Original line number Diff line number Diff line
@@ -49,8 +49,41 @@ rm -rf "$STORAGE/tmp"

# Helper functions

getCountry () {
isAlive() {
  local pid=$1

  if kill -0 "$pid" 2>/dev/null; then
    return 0
  fi

  return 1
}

pKill() {
  local pid=$1

  { kill -15 "$pid" || true; } 2>/dev/null

  while isAlive "$pid"; do
    sleep 0.1
  done

  return 0
}

fKill () {
  local name=$1

  { pkill -f "$name" || true; } 2>/dev/null

  while pgrep -f -l "$name" >/dev/null; do
    sleep 0.1
  done

  return 0
}

getCountry () {
  local url=$1
  local query=$2
  local rc json result
@@ -87,7 +120,6 @@ setCountry () {
}

addPackage () {

  local pkg=$1
  local desc=$2

Loading