Add IOErrorActionListener and IOErrorAction enum which is handed to the onIOError callback method when an IO error event occurs. Signed-off-by: Claudio Bley <cbley@xxxxxxxxxx> --- src/main/java/org/libvirt/Connect.java | 59 ++++++++++++++++++++ src/main/java/org/libvirt/Domain.java | 16 ++++++ src/main/java/org/libvirt/Library.java | 20 +++++++ src/main/java/org/libvirt/event/IOErrorAction.java | 39 +++++++++++++ .../java/org/libvirt/event/IOErrorListener.java | 21 +++++++ src/main/java/org/libvirt/jna/Libvirt.java | 8 +++ 6 files changed, 163 insertions(+) create mode 100644 src/main/java/org/libvirt/event/IOErrorAction.java create mode 100644 src/main/java/org/libvirt/event/IOErrorListener.java diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index 14668ef..5637337 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -20,6 +20,7 @@ import org.libvirt.jna.virConnectAuth; import org.libvirt.jna.virNodeInfo; import static org.libvirt.Library.libvirt; +import static org.libvirt.Library.getConstant; import static org.libvirt.ErrorHandler.processError; import static org.libvirt.ErrorHandler.processErrorIfZero; @@ -411,6 +412,64 @@ public class Connect { handlers.put(l, ret); } + void domainEventRegister(Domain domain, final IOErrorListener cb) throws LibvirtException { + if (cb == null) + throw new IllegalArgumentException("IOError callback cannot be null"); + + Libvirt.VirConnectDomainEventIOErrorCallback virCB = new Libvirt.VirConnectDomainEventIOErrorCallback() { + @Override + public void eventCallback(ConnectionPointer virConnectPtr, DomainPointer virDomainPointer, + String srcPath, + String devAlias, + int action, + Pointer opaque) { + assert VCP.equals(virConnectPtr); + + try { + Domain d = Domain.constructIncRef(Connect.this, virDomainPointer); + cb.onIOError(d, + srcPath, + devAlias, + getConstant(IOErrorAction.class, action)); + } catch (LibvirtException e) { + throw new RuntimeException("libvirt error in IOError callback", e); + } + } + }; + + domainEventRegister(domain, DomainEventID.IO_ERROR, virCB, cb); + } + + /** + * Adds the specified I/O error listener to receive I/O error events + * for domains of this connection. + * + * @see <a + * href="http://www.libvirt.org/html/libvirt-libvirt.html#virConnectDomainEventRegisterAny">Libvirt + * Documentation</a> + * @param l + * the I/O error listener + * @throws LibvirtException on failure + */ + public void addIOErrorListener(final IOErrorListener l) throws LibvirtException { + domainEventRegister(null, l); + } + + /** + * Removes the specified I/O error listener so that it no longer + * receives I/O error events. + * + * @param l the I/O error listener + * @throws LibvirtException + * + * @see <a + * href="http://www.libvirt.org/html/libvirt-libvirt.html#virConnectDomainEventDeregisterAny" + * >virConnectDomainEventDeregisterAny</a> + */ + public void removeIOErrorListener(IOErrorListener l) throws LibvirtException { + domainEventDeregister(DomainEventID.IO_ERROR, l); + } + /** * Finds a domain based on the hypervisor ID number. * diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index ec95f5f..f37f299 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -1,5 +1,6 @@ package org.libvirt; +import org.libvirt.event.IOErrorListener; import org.libvirt.jna.DomainPointer; import org.libvirt.jna.DomainSnapshotPointer; import org.libvirt.jna.Libvirt; @@ -1031,6 +1032,21 @@ public class Domain { } /** + * Adds a callback to receive notifications of IOError domain events + * occurring on this domain. + * + * @see <a + * href="http://www.libvirt.org/html/libvirt-libvirt.html#virConnectDomainEventRegisterAny">Libvirt + * Documentation</a> + * @param cb + * the IOErrorCallback instance + * @throws LibvirtException on failure + */ + public void addIOErrorListener(final IOErrorListener cb) throws LibvirtException { + virConnect.domainEventRegister(this, cb); + } + + /** * Revert the domain to a given snapshot. * * @see <a href= diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java index 3cfb8fd..81df223 100644 --- a/src/main/java/org/libvirt/Library.java +++ b/src/main/java/org/libvirt/Library.java @@ -176,4 +176,24 @@ final class Library { null, null); } } + + /** + * Look up a constant of an enum by its ordinal number. + * + * @return the corresponding enum constant when such a constant exists, + * otherwise the element which has the biggest ordinal number + * assigned. + * + * @throws IllegalArgumentException if {@code ordinal} is negative + */ + static <T extends Enum<T>> T getConstant(final Class<T> c, final int ordinal) { + if (ordinal < 0) + throw new IllegalArgumentException("ordinal must be >= 0"); + + T[] a = c.getEnumConstants(); + + assert a.length > 0 : "there must be at least one enum constant"; + + return a[Math.min(ordinal, a.length - 1)]; + } } diff --git a/src/main/java/org/libvirt/event/IOErrorAction.java b/src/main/java/org/libvirt/event/IOErrorAction.java new file mode 100644 index 0000000..bfda1de --- /dev/null +++ b/src/main/java/org/libvirt/event/IOErrorAction.java @@ -0,0 +1,39 @@ +package org.libvirt.event; + +public enum IOErrorAction { + /** + * No action, I/O error ignored. + */ + NONE, + + /** + * Guest CPUs are paused. + */ + PAUSE, + + /** + * I/O error was reported to the guest OS. + */ + REPORT, + + /** + * An unknown action was taken. + */ + UNKNOWN; + + private static final IOErrorAction vals[] = IOErrorAction.values(); + + static { + // make sure that the enum constants have the correct + // ordinal number assigned in correspondence to the + // values of the virDomainEventIOErrorAction enum + // members + + assert NONE.ordinal() == 0; + assert PAUSE.ordinal() == 1; + assert REPORT.ordinal() == 2; + + // must be the last constant + assert UNKNOWN.ordinal() == vals.length - 1; + } +} diff --git a/src/main/java/org/libvirt/event/IOErrorListener.java b/src/main/java/org/libvirt/event/IOErrorListener.java new file mode 100644 index 0000000..efd66c4 --- /dev/null +++ b/src/main/java/org/libvirt/event/IOErrorListener.java @@ -0,0 +1,21 @@ +package org.libvirt.event; + +import org.libvirt.Domain; + +/** + * Interface for receiving domain I/O error events. + */ +public interface IOErrorListener extends EventListener { + /** + * This method gets called upon a domain I/O error event. + * + * @param domain the domain which got an I/O error + * @param srcPath the src of the block device with errors + * @param devAlias the device alias of the block device with errors + * @param action the action that is to be taken due to the I/O error + */ + void onIOError(Domain domain, + String srcPath, + String devAlias, + IOErrorAction action); +} diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index ba8b073..0e36251 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -77,6 +77,14 @@ public interface Libvirt extends Library { */ interface VirDomainEventCallback extends Callback {} + interface VirConnectDomainEventIOErrorCallback extends VirDomainEventCallback { + void eventCallback(ConnectionPointer virConnectPtr, DomainPointer virDomainPointer, + String srcPath, + String devAlias, + int action, + Pointer opaque); + } + /** * Error callback */ -- 1.7.9.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list