]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virDomainGetDiskErrors public API
authorJiri Denemark <jdenemar@redhat.com>
Tue, 31 Jan 2012 06:41:53 +0000 (07:41 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 1 Feb 2012 09:42:16 +0000 (10:42 +0100)
We already provide ways to detect when a domain has been paused as a
result of I/O error, but there was no way of getting the exact error or
even the device that experienced it.  This new API may be used for both.

include/libvirt/libvirt.h.in
python/generator.py
src/driver.h
src/libvirt.c
src/libvirt_public.syms

index d9b9b95f161f4c193f939c4c6daece11f01fb41e..cf53cf260d3d8b6b843724f63b002fdbd9e21ff1 100644 (file)
@@ -1967,6 +1967,38 @@ virDomainGetBlockIoTune(virDomainPtr dom,
                         int *nparams,
                         unsigned int flags);
 
+/**
+ * virDomainDiskErrorCode:
+ *
+ * Disk I/O error.
+ */
+typedef enum {
+    VIR_DOMAIN_DISK_ERROR_NONE      = 0, /* no error */
+    VIR_DOMAIN_DISK_ERROR_UNSPEC    = 1, /* unspecified I/O error */
+    VIR_DOMAIN_DISK_ERROR_NO_SPACE  = 2, /* no space left on the device */
+
+#ifdef VIR_ENUM_SENTINELS
+    VIR_DOMAIN_DISK_ERROR_LAST
+#endif
+} virDomainDiskErrorCode;
+
+/**
+ * virDomainDiskError:
+ *
+ */
+typedef struct _virDomainDiskError virDomainDiskError;
+typedef virDomainDiskError *virDomainDiskErrorPtr;
+
+struct _virDomainDiskError {
+    char *disk; /* disk target */
+    int error;  /* virDomainDiskErrorCode */
+};
+
+int virDomainGetDiskErrors(virDomainPtr dom,
+                           virDomainDiskErrorPtr errors,
+                           unsigned int maxerrors,
+                           unsigned int flags);
+
 
 /*
  * NUMA support
index 6f813ae0dba740f79fe9b05330e26df70e7c6a88..b514af5bc2ec7333f475fd3b47782b6613975145 100755 (executable)
@@ -423,7 +423,8 @@ skip_impl = (
     'virDomainGetBlockIoTune',
     'virDomainSetInterfaceParameters',
     'virDomainGetInterfaceParameters',
-    'virDomainGetCPUStats'  # not implemented now.
+    'virDomainGetCPUStats',  # not implemented now.
+    'virDomainGetDiskErrors',
 )
 
 qemu_skip_impl = (
index 2e2042e3b7218f3509eebeeb14fa1571c11f1ea1..9ff5edf18fc076b962bec61fb94d5e9118f1df4f 100644 (file)
@@ -810,6 +810,12 @@ typedef int
                                unsigned int ncpus,
                                unsigned int flags);
 
+typedef int
+    (*virDrvDomainGetDiskErrors)(virDomainPtr dom,
+                                 virDomainDiskErrorPtr errors,
+                                 unsigned int maxerrors,
+                                 unsigned int flags);
+
 /**
  * _virDriver:
  *
@@ -981,6 +987,7 @@ struct _virDriver {
     virDrvDomainSetBlockIoTune domainSetBlockIoTune;
     virDrvDomainGetBlockIoTune domainGetBlockIoTune;
     virDrvDomainGetCPUStats domainGetCPUStats;
+    virDrvDomainGetDiskErrors domainGetDiskErrors;
 };
 
 typedef int
index f412a823cd5a2255c99450c5fa04c73a8e355299..fc41a3fad2ac103acfbae9066d54db0ef09b6f29 100644 (file)
@@ -18282,3 +18282,68 @@ error:
     virDispatchError(domain->conn);
     return -1;
 }
+
+/**
+ * virDomainGetDiskErrors:
+ * @dom: a domain object
+ * @errors: array to populate on output
+ * @maxerrors: size of @errors array
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * The function populates @errors array with all disks that encountered an
+ * I/O error.  Disks with no error will not be returned in the @errors array.
+ * Each disk is identified by its target (the dev attribute of target
+ * subelement in domain XML), such as "vda", and accompanied with the error
+ * that was seen on it.  The caller is also responsible for calling free()
+ * on each disk name returned.
+ *
+ * In a special case when @errors is NULL and @maxerrors is 0, the function
+ * returns preferred size of @errors that the caller should use to get all
+ * disk errors.
+ *
+ * Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size
+ * of @errors array and getting the errors are two separate operations, new
+ * disks may be hotplugged to the domain and new errors may be encountered
+ * between the two calls.  Thus, this function may not return all disk errors
+ * because the supplied array is not large enough.  Such errors may, however,
+ * be detected by listening to domain events.
+ *
+ * Returns number of disks with errors filled in the @errors array or -1 on
+ * error.
+ */
+int
+virDomainGetDiskErrors(virDomainPtr dom,
+                       virDomainDiskErrorPtr errors,
+                       unsigned int maxerrors,
+                       unsigned int flags)
+{
+    VIR_DOMAIN_DEBUG(dom, "errors=%p, maxerrors=%u, flags=%x",
+                     errors, maxerrors, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_DOMAIN(dom)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    if ((!errors && maxerrors) || (errors && !maxerrors)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        goto error;
+    }
+
+    if (dom->conn->driver->domainGetDiskErrors) {
+        int ret = dom->conn->driver->domainGetDiskErrors(dom, errors,
+                                                         maxerrors, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(dom->conn);
+    return -1;
+}
index 1c4e0a3aa7812bb9b04957f17c2a1b7ec1dcbc43..ced9fb3969ffac7e302522e39a94a3fd3b70c361 100644 (file)
@@ -519,6 +519,7 @@ LIBVIRT_0.9.9 {
 LIBVIRT_0.9.10 {
     global:
         virDomainGetCPUStats;
+        virDomainGetDiskErrors;
         virDomainPMSuspendForDuration;
         virDomainShutdownFlags;
         virStorageVolResize;