diff --git a/dev-example/config.yaml b/dev-example/config.yaml index 2a72bc8..fc1cee7 100644 --- a/dev-example/config.yaml +++ b/dev-example/config.yaml @@ -21,8 +21,8 @@ # Defaults for namespace (VM domain) handlers=java.util.logging.ConsoleHandler - #org.jgrapes.level=FINE - #org.jgrapes.core.handlerTracking.level=FINER + org.jgrapes.level=FINE + org.jgrapes.core.handlerTracking.level=FINER org.jdrupes.vmoperator.runner.qemu.level=FINEST diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuConnector.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuConnector.java index 2e1dbfa..777478e 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuConnector.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuConnector.java @@ -242,7 +242,7 @@ public abstract class QemuConnector extends Component { */ @Handler public void onClosed(Closed event, SocketIOChannel channel) { - channel.associated(this, getClass()).ifPresent(qm -> { + channel.associated(this, getClass()).ifPresent(qc -> { qemuChannel = null; }); } diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuMonitor.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuMonitor.java index 75310f8..3b229b5 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuMonitor.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/QemuMonitor.java @@ -42,6 +42,7 @@ import org.jgrapes.core.Components.Timer; import org.jgrapes.core.annotation.Handler; import org.jgrapes.core.events.Stop; import org.jgrapes.io.events.Closed; +import org.jgrapes.io.events.ProcessExited; import org.jgrapes.net.SocketIOChannel; import org.jgrapes.util.events.ConfigurationUpdate; @@ -136,24 +137,12 @@ public class QemuMonitor extends QemuConnector { * @param event the event */ @Handler - @SuppressWarnings({ "PMD.AvoidSynchronizedStatement", - "PMD.AvoidDuplicateLiterals" }) public void onClosed(Closed event, SocketIOChannel channel) { - super.onClosed(event, channel); - logger.finer(() -> "QMP socket closed."); - monitorReady = false; channel.associated(this, getClass()).ifPresent(qm -> { - synchronized (this) { - if (powerdownTimer != null) { - powerdownTimer.cancel(); - } - if (suspendedStop != null) { - suspendedStop.resumeHandling(); - suspendedStop = null; - } - } + super.onClosed(event, channel); + logger.finer(() -> "QMP socket closed."); + monitorReady = false; }); - logger.finer(() -> "QMP socket closed."); } /** @@ -163,7 +152,8 @@ public class QemuMonitor extends QemuConnector { * @throws IOException */ @Handler - @SuppressWarnings("PMD.AvoidSynchronizedStatement") + @SuppressWarnings({ "PMD.AvoidSynchronizedStatement", + "PMD.AvoidDuplicateLiterals" }) public void onMonitorCommand(MonitorCommand event) throws IOException { // Check prerequisites if (!monitorReady && !(event.command() instanceof QmpCapabilities)) { @@ -228,7 +218,9 @@ public class QemuMonitor extends QemuConnector { } /** - * On powerdown event. + * When the powerdown event is confirmed, wait for termination + * or timeout. Termination is detected by the qemu process exiting + * (see {@link #onProcessExited(ProcessExited)}). * * @param event the event */ @@ -258,6 +250,29 @@ public class QemuMonitor extends QemuConnector { } } + /** + * On process exited. + * + * @param event the event + */ + @Handler + @SuppressWarnings("PMD.AvoidSynchronizedStatement") + public void onProcessExited(ProcessExited event) { + if (!event.startedBy().associated(CommandDefinition.class) + .map(cd -> Runner.QEMU.equals(cd.name())).orElse(false)) { + return; + } + synchronized (this) { + if (powerdownTimer != null) { + powerdownTimer.cancel(); + } + if (suspendedStop != null) { + suspendedStop.resumeHandling(); + suspendedStop = null; + } + } + } + /** * On configure qemu. * diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java index 6c69191..1bbf597 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java @@ -195,9 +195,9 @@ import org.jgrapes.util.events.WatchFile; "PMD.CouplingBetweenObjects", "PMD.TooManyFields" }) public class Runner extends Component { - private static final String QEMU = "qemu"; - private static final String SWTPM = "swtpm"; - private static final String CLOUD_INIT_IMG = "cloudInitImg"; + public static final String QEMU = "qemu"; + public static final String SWTPM = "swtpm"; + public static final String CLOUD_INIT_IMG = "cloudInitImg"; private static final String TEMPLATE_DIR = "/opt/" + APP_NAME.replace("-", "") + "/templates"; private static final String DEFAULT_TEMPLATE