[libvirt] [libvirt-java] [PATCH 43/65] events: handle registration for IOError events

Claudio Bley cbley at av-test.de
Thu Feb 13 15:22:51 UTC 2014


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 at 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#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




More information about the libvir-list mailing list