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(a)av-test.de>
---
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#virConnectDom...
+ * 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#virConnectDom...
+ * >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#virConnectDom...
+ * 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