diff --git a/cmd/kill b/cmd/kill index 93ae7c2..b3e5e9c 100644 --- a/cmd/kill +++ b/cmd/kill @@ -9,6 +9,20 @@ USAGE="usage: ${BASENAME} -c CONFIG kill The \`kill\` command shuts down the running virtual machine defined by the given \`CONFIG\` using a \`quit\` QEMU monitor command." +source "${BASEDIR}/common/msgs" +_run_sys_kill() { + local curr_pid="" + if [[ ! -f "${VMRUN}/pidfile" ]]; then + return 1 + fi + curr_pid="$(cat "${VMRUN}/pidfile")" + if kill -0 "${curr_pid}" 2> /dev/null; then + kill -9 "${curr_pid}" + fi + rm -f "${VMRUN}/pidfile" + return 0 +} + _kill() { _require_program socat @@ -42,15 +56,15 @@ _kill() { _fatal 1 "$VMNAME does not appear to be running" fi - if ! _is_daemonized; then - _fatal 1 "$VMNAME is running interactively; attach to monitor from console using 'Ctrl-a c' and kill using 'quit'" + if [[ -S "${VMRUN}/monitor" ]]; then + local args=( "-" "UNIX-CONNECT:${VMRUN}/monitor") + if echo quit | socat "${args[@]}" >> "${VMLOG}/full" 2>&1; then + return 0 + fi fi - local args=( - "-" "UNIX-CONNECT:${VMRUN}/monitor" - ) - - if ! echo quit | socat "${args[@]}" >> "${VMLOG}/full" 2>&1; then - _fatal 1 "could not power off vm; see ${VMLOG}/full" + if ! _run_sys_kill >> "${VMLOG}/full" ; then + _fatal 1 "could not power off vm; see ${VMLOG}/full" fi + } diff --git a/cmd/monitor b/cmd/monitor index b5d71fc..c5ffe95 100644 --- a/cmd/monitor +++ b/cmd/monitor @@ -10,6 +10,7 @@ The \`monitor\` command is used to run commands in the QEMU monitor of a running virtual machine defined by the given \`CONFIG\`. If no \`COMMAND\` is given, attach interactively to the monitor." +source "${BASEDIR}/common/msgs" _monitor() { _require_program socat @@ -43,8 +44,8 @@ _monitor() { _fatal 1 "$VMNAME does not appear to be running" fi - if ! _is_daemonized; then - _fatal 1 "$VMNAME is running interactively; attach to monitor from console using 'Ctrl-a c'" + if [[ ! -S "${VMRUN}/monitor" ]]; then + _fatal 1 "${VMNAME}: ${MSG_CHECK_DAEMONIZED/THE COMMAND/any command}" fi local args=( diff --git a/cmd/poweroff b/cmd/poweroff index 56bafc4..b835d16 100644 --- a/cmd/poweroff +++ b/cmd/poweroff @@ -9,6 +9,7 @@ USAGE="usage: ${BASENAME} -c CONFIG poweroff The \`poweroff\` command gracefully shuts down the running virtual machine defined by the given \`CONFIG\` if supported by the machine." +source "${BASEDIR}/common/msgs" _poweroff() { _require_program socat @@ -42,8 +43,8 @@ _poweroff() { _fatal 1 "$VMNAME does not appear to be running" fi - if ! _is_daemonized; then - _fatal 1 "$VMNAME is running interactively; attach to monitor from console using 'Ctrl-a c' and type 'system_powerdown'" + if [[ ! -S "${VMRUN}/monitor" ]]; then + _fatal 1 "${VMNAME}: ${MSG_CHECK_DAEMONIZED/THE COMMAND/system_powerdown}" fi local args=( @@ -54,4 +55,9 @@ _poweroff() { if ! echo system_powerdown | socat "${args[@]}" >> "${VMLOG}/full" 2>&1; then _fatal 1 "could not power off vm; see ${VMLOG}/full" fi + + if echo "info status" | socat "${args[@]}" >> "${VMLOG}/full" 2>&1; then + _fatal 1 "poweroff returned success but did not execute a power off." \ + "Try the kill command" + fi } diff --git a/cmd/run b/cmd/run index 2951f20..7013a74 100644 --- a/cmd/run +++ b/cmd/run @@ -149,9 +149,10 @@ _run() { QEMU_PARAMS+=("-daemonize") # serial and monitor - QEMU_PARAMS+=("-serial" "unix:${VMROOT}/run/${VMNAME}/console,server,nowait") - QEMU_PARAMS+=("-monitor" "unix:${VMROOT}/run/${VMNAME}/monitor,server,nowait") + QEMU_PARAMS+=("-serial" "unix:${VMRUN}/console,server,nowait") + QEMU_PARAMS+=("-monitor" "unix:${VMRUN}/monitor,server,nowait") else + _add_pre_cmd "rm -f ${VMRUN}/console ${VMRUN}/monitor" QEMU_PARAMS+=("-serial" "mon:stdio") fi @@ -179,6 +180,10 @@ _run() { if [[ -v do_print ]]; then if [[ -v VMPRE ]]; then echo "Before QEMU:" + if command -v _pre > /dev/null; then + declare -f _pre + fi + echo for cmd in "${VMPRE[@]}"; do echo -n " $cmd" echo @@ -203,6 +208,9 @@ _run() { done echo + if command -v _post > /dev/null; then + typeset -f _post + fi exit 0 fi diff --git a/cmd/ssh b/cmd/ssh index f0bc744..9615187 100644 --- a/cmd/ssh +++ b/cmd/ssh @@ -13,14 +13,13 @@ Options: -h, --help display this help message and exit -w, --wait wait until an ssh connection is established -p, --port port to connect to (default: \"$GUEST_SSH_PORT\") - -l, --login the user to log in as (default: \"$GUEST_SSH_USER\") - -c, --command Execute a command and disconnect" + -l, --login the user to log in as (default: \"$GUEST_SSH_USER\")" _ssh() { _require_program ssh - local short="+w,p:,l:,c:,h" - local long="wait,port:,login:,command:,help" + local short="+w,p:,l:,h" + local long="wait,port:,login:,help" if ! tmp=$(getopt -o "$short" --long "$long" -n "$BASENAME" -- "$@"); then exit 1 @@ -43,9 +42,6 @@ _ssh() { '-h' | '--help' ) _usage "$USAGE" 0 ;; - '-c' | '--command' ) - cmd="$2"; shift 2 - ;; '--' ) shift; break ;; @@ -59,7 +55,6 @@ _ssh() { : "${port:="${GUEST_SSH_PORT}"}" : "${user:="${GUEST_SSH_USER}"}" - : "${cmd:=""}" if ! _is_running; then _fatal 1 "$VMNAME does not appear to be running" @@ -82,5 +77,5 @@ _ssh() { fi #shellcheck disable=SC2029 - ssh "${args[@]}" localhost "$@" "${cmd}" + ssh "${args[@]}" localhost "$@" } diff --git a/common/msgs b/common/msgs new file mode 100644 index 0000000..b5e2a20 --- /dev/null +++ b/common/msgs @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0-or-later +# Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved. +# +# Written by Joel Granados + +source "${BASEDIR}/common/shellcheck" + +MSG_CHECK_DAEMONIZED="The vm is most likely running interactively. \ +Try to attach monitor using 'Ctrl-a c' and type THE COMMAND. \ +Or add '-d' to vmctl command to run daemonized" + + diff --git a/common/rc b/common/rc index 5c1c7f7..85d360f 100644 --- a/common/rc +++ b/common/rc @@ -153,14 +153,6 @@ _is_running() { return 1 } -_is_daemonized() { - if [[ -S "${VMRUN}/monitor" ]]; then - return 0 - fi - - return 1 -} - _add_pre_cmd() { VMPRE+=("$1") } diff --git a/common/shellcheck b/common/shellcheck index c585dfb..ebd54c7 100644 --- a/common/shellcheck +++ b/common/shellcheck @@ -10,5 +10,6 @@ _silence_sc2034() { $QEMU_TRACE_EVENTS \ ${GUEST_KERNEL_CMDLINE[*]} \ $RESET \ - $GUEST_KERNEL_CUSTOM_DIR " > /dev/null + $MSG_CHECK_DAEMONIZED \ + $GUEST_KERNEL_CUSTOM_DIR" > /dev/null } diff --git a/examples/vm/nvme-aarch64.conf b/examples/vm/nvme-aarch64.conf index 1a33d93..89df9ee 100644 --- a/examples/vm/nvme-aarch64.conf +++ b/examples/vm/nvme-aarch64.conf @@ -1,6 +1,6 @@ #!/usr/bin/env bash -QEMU_SYSTEM_AARCH64=$(/usr/bin/which qemu-system-aarch64) +QEMU_SYSTEM_AARCH64=$(/usr/bin/env which qemu-system-aarch64) GUEST_BOOT_BASE="img/debian-13-genericcloud-arm64.qcow2" source "aarch64-virt-base.conf" diff --git a/examples/vm/nvme.conf b/examples/vm/nvme.conf index c51db08..9e2a9ae 100644 --- a/examples/vm/nvme.conf +++ b/examples/vm/nvme.conf @@ -1,6 +1,6 @@ #!/usr/bin/env bash -QEMU_SYSTEM_X86_64=$(/usr/bin/which qemu-system-x86_64) +QEMU_SYSTEM_X86_64=$(/usr/bin/env which qemu-system-x86_64) source "x86_64-q35-base.conf" #source "x86_64-q35-noimgnix-base.conf" diff --git a/examples/vm/x86_64-q35-base.conf b/examples/vm/x86_64-q35-base.conf index 16d7c43..c227aa1 100644 --- a/examples/vm/x86_64-q35-base.conf +++ b/examples/vm/x86_64-q35-base.conf @@ -18,8 +18,7 @@ if [[ -f "common.conf" ]]; then source "common.conf" fi -QEMU_SYSTEM_BINARY=${QEMU_SYSTEM_X86_64} - +: "${QEMU_SYSTEM_BINARY:="$(/usr/bin/env which qemu-system-x86_64)"}" : "${GUEST_DISPLAY:="0"}" : "${GUEST_VIOMMU:="1"}" : "${GUEST_VIOMMU_ARGS:="intel-iommu,intremap=on"}" diff --git a/lib/qemu/rc b/lib/qemu/rc index b142028..d25dd6f 100644 --- a/lib/qemu/rc +++ b/lib/qemu/rc @@ -87,7 +87,7 @@ qemu_drive_add() { while true; do case "$1" in '--file' ) - local file="/$2"; shift 2 + local file="$2"; shift 2 ;; '--format' ) @@ -139,11 +139,9 @@ qemu_drive_add() { local id="$1" if [[ ! -v file ]]; then - local file="/state/${VMNAME}/${id}.img" - fi - - if [[ ! -v DOCKER_IMAGE ]]; then - file="${VMROOT}${file}" + local file="${VMROOT}/state/${VMNAME}/${id}.img" + elif [[ "${file}" != /* ]]; then + file="${VMROOT}/${file}" fi if [[ -v do_create ]]; then