Re: [Libguestfs] [PATCH v4 3/9] mllib: ocaml wrapper for lib/osinfo

Pino Toscano
Wed, 08 Mar 2017 17:59:57 -0000

On Tuesday, 7 March 2017 15:26:59 CET Cédric Bosdonnat
wrote:
> Provide osinfo database parsing API in OCAML.
> ---
>  lib/osinfo.c      |  13 +++++++
>  mllib/Makefile.am |  11 ++++--
>  mllib/osinfo-c.c  | 100
++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  mllib/osinfo.ml   |  26 ++++++++++++++
>  mllib/osinfo.mli  |  31 +++++++++++++++++
>  5 files changed, 179 insertions(+), 2 deletions(-)
>  create mode 100644 mllib/osinfo-c.c
>  create mode 100644 mllib/osinfo.ml
>  create mode 100644 mllib/osinfo.mli
>
> diff --git a/lib/osinfo.c b/lib/osinfo.c
> index 11b50d903..126a645c0 100644
> --- a/lib/osinfo.c
> +++ b/lib/osinfo.c
> @@ -52,6 +52,19 @@
>
>  #include "osinfo.h"
>
> +#ifndef GUESTFS_PRIVATE
> +#undef perrorf
> +#define perrorf(g,...)                          \
> +{                                               \
> +  CLEANUP_FREE char *msg = NULL;                \
> +  ignore_value (asprintf (&msg, __VA_ARGS__));  \
> +  perror (msg);                                 \

I'd add a short note here that ignorning the asprintf result is fine,
as perror accepts null pointers (so in case of refactoring, eventual
changes are done).

> +}
> +
> +#undef debug
> +#define debug(g,...) fprintf (stderr, __VA_ARGS__)
> +#endif /* GUESTFS_PRIVATE */
> +
>
>  /* Read the libosinfo XML database files.  The lock is held while
>   * this is called.
> diff --git a/mllib/Makefile.am b/mllib/Makefile.am
> index ee2f1a7a8..ee16fe7ef 100644
> --- a/mllib/Makefile.am
> +++ b/mllib/Makefile.am
> @@ -36,6 +36,7 @@ SOURCES_MLI = \
>  	curl.mli \
>  	getopt.mli \
>  	JSON.mli \
> +	osinfo.mli \
>  	planner.mli \
>  	progress.mli \
>  	regedit.mli \
> @@ -63,7 +64,8 @@ SOURCES_ML = \
>  	curl.ml \
>  	checksums.ml \
>  	xml.ml \
> -	xpath_helpers.ml
> +	xpath_helpers.ml \
> +	osinfo.ml
>
>  SOURCES_C = \
>  	../common/visit/visit.c \
> @@ -71,8 +73,12 @@ SOURCES_C = \
>  	../common/options/keys.c \
>  	../common/options/uri.c \
>  	../common/progress/progress.c \
> +	../lib/alloc.c \
> +	../lib/osinfo.c \
> +	../lib/osinfo.h \
>  	common_utils-c.c \
>  	getopt-c.c \
> +	osinfo-c.c \
>  	progress-c.c \
>  	unix_utils-c.c \
>  	uri-c.c \
> @@ -106,7 +112,8 @@ libmllib_a_CPPFLAGS = \
>  	-I$(top_srcdir)/lib \
>  	-I$(top_srcdir)/common/visit \
>  	-I$(top_srcdir)/common/options \
> -	-I$(top_srcdir)/common/progress
> +	-I$(top_srcdir)/common/progress \
> +	-DLIBOSINFO_DB_PATH='"$(datadir)/libosinfo/db"'
>  libmllib_a_CFLAGS = \
>  	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
>  	$(LIBVIRT_CFLAGS) $(LIBXML2_CFLAGS) \
> diff --git a/mllib/osinfo-c.c b/mllib/osinfo-c.c
> new file mode 100644
> index 000000000..9546c5984
> --- /dev/null
> +++ b/mllib/osinfo-c.c
> @@ -0,0 +1,100 @@
> +/* Bindings for osinfo db reading function.
> + * Copyright (C) 2017 SUSE Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
> + */
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <assert.h>
> +
> +#include <caml/alloc.h>
> +#include <caml/callback.h>
> +#include <caml/fail.h>
> +#include <caml/memory.h>
> +#include <caml/mlvalues.h>
> +
> +#include "guestfs.h"
> +#include "guestfs-internal.h"
> +#include "osinfo.h"
> +
> +#pragma GCC diagnostic ignored "-Wmissing-prototypes"
> +
> +struct callback_wrapper_args {
> +  /* In both case we are pointing to local roots, hence why these are
> +   * value* not value.
> +   */
> +  value *exnp;                  /* Safe place to store any exception
> +                                   raised by callback */
> +  value *fvp;                   /* callback. */
> +};
> +
> +static int read_osinfo_db_callback_wrapper (guestfs_h *g, const char
*path, void *opaque);
> +
> +value
> +guestfs_int_mllib_read_osinfo_db (value gv, value fv)
> +{
> +  CAMLparam2 (gv, fv);
> +  guestfs_h *g = (guestfs_h *) Int64_val (gv);
> +  struct callback_wrapper_args args;
> +
> +  /* This stack address is used to point to the exception, if one is
> +   * raised in the visitor_function.  Note that the macro initializes
> +   * this to Val_unit, which is how we know if an exception was set.
> +   */
> +  CAMLlocal1 (exn);
> +
> +  args.exnp = &exn;
> +  args.fvp = &fv;
> +

This needs the same fix as recently done by Rich with commit
57d17ca301095d761163f966222d42b38880a543.

> +  if (read_osinfo_db (g, read_osinfo_db_callback_wrapper, &args) ==
-1) {
> +    if (exn != Val_unit) {
> +      /* The failure was caused by the callback raising an
> +       * exception.  Re-raise it here.
> +       */
> +      caml_raise (exn);
> +    }
> +
> +    caml_failwith ("read_osinfo_db");
> +}
> +
> +  CAMLreturn (Val_unit);
> +}
> +
> +static int
> +read_osinfo_db_callback_wrapper (guestfs_h *g, const char *path, void
*opaque)
> +{
> +  CAMLparam0 ();
> +  CAMLlocal2 (pathv, v);
> +  struct callback_wrapper_args *args = opaque;
> +
> +  assert (path != NULL);
> +  assert (args != NULL);
> +
> +  pathv = caml_copy_string (path);
> +
> +  v = caml_callback_exn (*args->fvp, pathv);
> +
> +  if (Is_exception_result (v)) {
> +    *args->exnp = Extract_exception (v);
> +    CAMLreturnT (int, -1);
> +  }
> +
> +  /* No error, return normally. */
> +  CAMLreturnT (int, 0);
> +}
> diff --git a/mllib/osinfo.ml b/mllib/osinfo.ml
> new file mode 100644
> index 000000000..f5afbd889
> --- /dev/null
> +++ b/mllib/osinfo.ml
> @@ -0,0 +1,26 @@
> +(* virt-builder
> + * Copyright (C) 2016 - SUSE Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *)
> +open Common_utils
> +
> +type osinfo_db_callback = string -> unit
> +
> +external c_read_osinfo_db : int64 -> osinfo_db_callback -> unit >
+  "guestfs_int_mllib_read_osinfo_db"
> +
> +let read_osinfo_db g f > +  c_read_osinfo_db (Guestfs.c_pointer g) f
> diff --git a/mllib/osinfo.mli b/mllib/osinfo.mli
> new file mode 100644
> index 000000000..306cbce0f
> --- /dev/null
> +++ b/mllib/osinfo.mli
> @@ -0,0 +1,31 @@
> +(* virt-builder
> + * Copyright (C) 2016 - SUSE Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *)
> +
> +(** Bindings for the src/osinfo.h libosinfo database reading API. *)

src -> lib, and libosinfo -> os-info (it's become an independent
database)

Thanks,
--
Pino Toscano