diff options
Diffstat (limited to 'libvirt')
-rw-r--r-- | libvirt/libvirt.ml | 32 | ||||
-rw-r--r-- | libvirt/libvirt.mli | 25 | ||||
-rw-r--r-- | libvirt/libvirt_c.c | 72 |
3 files changed, 108 insertions, 21 deletions
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml index 586aa7b..69e1c0d 100644 --- a/libvirt/libvirt.ml +++ b/libvirt/libvirt.ml @@ -260,6 +260,8 @@ struct | VIR_WAR_NO_NETWORK | VIR_ERR_NO_DOMAIN | VIR_ERR_NO_NETWORK + | VIR_ERR_INVALID_MAC + | VIR_ERR_UNKNOWN of int let string_of_code = function | VIR_ERR_OK -> "VIR_ERR_OK" @@ -306,16 +308,8 @@ struct | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK" | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN" | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK" - - type level = - | VIR_ERR_NONE - | VIR_ERR_WARNING - | VIR_ERR_ERROR - - let string_of_level = function - | VIR_ERR_NONE -> "VIR_ERR_NONE" - | VIR_ERR_WARNING -> "VIR_ERR_WARNING" - | VIR_ERR_ERROR -> "VIR_ERR_ERROR" + | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC" + | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i type domain = | VIR_FROM_NONE @@ -333,6 +327,9 @@ struct | VIR_FROM_TEST | VIR_FROM_REMOTE | VIR_FROM_OPENVZ + | VIR_FROM_XENXM + | VIR_FROM_STATS_LINUX + | VIR_FROM_UNKNOWN of int let string_of_domain = function | VIR_FROM_NONE -> "VIR_FROM_NONE" @@ -350,6 +347,21 @@ struct | VIR_FROM_TEST -> "VIR_FROM_TEST" | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE" | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ" + | VIR_FROM_XENXM -> "VIR_FROM_XENXM" + | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX" + | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i + + type level = + | VIR_ERR_NONE + | VIR_ERR_WARNING + | VIR_ERR_ERROR + | VIR_ERR_UNKNOWN_LEVEL of int + + let string_of_level = function + | VIR_ERR_NONE -> "VIR_ERR_NONE" + | VIR_ERR_WARNING -> "VIR_ERR_WARNING" + | VIR_ERR_ERROR -> "VIR_ERR_ERROR" + | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i type t = { code : code; diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli index 1d9da1e..aa4b9f4 100644 --- a/libvirt/libvirt.mli +++ b/libvirt/libvirt.mli @@ -463,18 +463,13 @@ sig | VIR_WAR_NO_NETWORK | VIR_ERR_NO_DOMAIN | VIR_ERR_NO_NETWORK + | VIR_ERR_INVALID_MAC + (* ^^ NB: If you add a variant you MUST edit libvirt_c.c:MAX_VIR_* *) + | VIR_ERR_UNKNOWN of int (** See [<libvirt/virterror.h>] for meaning of these codes. *) val string_of_code : code -> string - type level = - | VIR_ERR_NONE - | VIR_ERR_WARNING - | VIR_ERR_ERROR - (** No error, a warning or an error. *) - - val string_of_level : level -> string - type domain = | VIR_FROM_NONE | VIR_FROM_XEN @@ -491,10 +486,24 @@ sig | VIR_FROM_TEST | VIR_FROM_REMOTE | VIR_FROM_OPENVZ + | VIR_FROM_XENXM + | VIR_FROM_STATS_LINUX + (* ^^ NB: If you add a variant you MUST edit libvirt_c.c: MAX_VIR_* *) + | VIR_FROM_UNKNOWN of int (** Subsystem / driver which produced the error. *) val string_of_domain : domain -> string + type level = + | VIR_ERR_NONE + | VIR_ERR_WARNING + | VIR_ERR_ERROR + (* ^^ NB: If you add a variant you MUST edit libvirt_c.c: MAX_VIR_* *) + | VIR_ERR_UNKNOWN_LEVEL of int + (** No error, a warning or an error. *) + + val string_of_level : level -> string + type t = { code : code; (** Error code. *) domain : domain; (** Origin of the error. *) diff --git a/libvirt/libvirt_c.c b/libvirt/libvirt_c.c index 9e2182b..a2bb1ad 100644 --- a/libvirt/libvirt_c.c +++ b/libvirt/libvirt_c.c @@ -1795,6 +1795,72 @@ _raise_virterror (virConnectPtr conn, const char *fn) CAMLreturn (Val_unit); } +/* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums + * into values (longs because they are variants in OCaml). + * + * The enum values are part of the libvirt ABI so they cannot change, + * which means that we can convert these numbers directly into + * OCaml variants (which use the same ordering) very fast. + * + * The tricky part here is when we are linked to a newer version of + * libvirt than the one we were compiled against. If the newer libvirt + * generates an error code which we don't know about then we need + * to convert it into VIR_*_UNKNOWN (code). + */ + +#define MAX_VIR_CODE 44 /* VIR_ERR_INVALID_MAC */ +#define MAX_VIR_DOMAIN 16 /* VIR_FROM_STATS_LINUX */ +#define MAX_VIR_LEVEL VIR_ERR_ERROR + +static inline value +Val_err_number (virErrorNumber code) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + if (0 <= code && code <= MAX_VIR_CODE) + rv = Val_int (code); + else { + rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN (code) */ + Store_field (rv, 0, Val_int (code)); + } + + CAMLreturn (rv); +} + +static inline value +Val_err_domain (virErrorDomain code) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + if (0 <= code && code <= MAX_VIR_DOMAIN) + rv = Val_int (code); + else { + rv = caml_alloc (1, 0); /* VIR_FROM_UNKNOWN (code) */ + Store_field (rv, 0, Val_int (code)); + } + + CAMLreturn (rv); +} + +static inline value +Val_err_level (virErrorLevel code) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + if (0 <= code && code <= MAX_VIR_LEVEL) + rv = Val_int (code); + else { + rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN_LEVEL (code) */ + Store_field (rv, 0, Val_int (code)); + } + + CAMLreturn (rv); +} + +/* Convert a virterror to a value. */ static value Val_virterror (virErrorPtr err) { @@ -1802,11 +1868,11 @@ Val_virterror (virErrorPtr err) CAMLlocal3 (rv, connv, optv); rv = caml_alloc (12, 0); - Store_field (rv, 0, Val_int (err->code)); - Store_field (rv, 1, Val_int (err->domain)); + Store_field (rv, 0, Val_err_number (err->code)); + Store_field (rv, 1, Val_err_domain (err->domain)); Store_field (rv, 2, Val_opt (err->message, (Val_ptr_t) caml_copy_string)); - Store_field (rv, 3, Val_int (err->level)); + Store_field (rv, 3, Val_err_level (err->level)); /* conn, dom and net fields, all optional */ if (err->conn) { |