Richard W.M. Jones
2017-Jul-21 21:47 UTC
[Libguestfs] [PATCH v3 REPOST 0/5] threads: Add support for thread-safe handle.
Previously posted in 2015: v1: https://www.redhat.com/archives/libguestfs/2015-June/msg00048.html v2: https://www.redhat.com/archives/libguestfs/2015-June/msg00118.html This series was posted about 4 weeks ago: v3: https://www.redhat.com/archives/libguestfs/2017-June/msg00287.html There is no change in this series except I rebased it against current upstream head and retested. Last time there was some discussion and patch review, but no change appears to be needed. Rich.
Richard W.M. Jones
2017-Jul-21 21:47 UTC
[Libguestfs] [PATCH v3 REPOST 1/5] threads: Add a lock (a recursive mutex) to the handle.
Add a g->lock field. This commit simply initializes and destroys the lock on handle creation/free, and does nothing else. --- lib/guestfs-internal.h | 6 ++++++ lib/handle.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h index 7269fbeba..10080c4b7 100644 --- a/lib/guestfs-internal.h +++ b/lib/guestfs-internal.h @@ -52,6 +52,7 @@ #endif #endif +#include "glthread/lock.h" #include "hash.h" #include "guestfs-utils.h" @@ -388,6 +389,11 @@ struct guestfs_h { struct guestfs_h *next; /* Linked list of open handles. */ enum state state; /* See the state machine diagram in guestfs(3)*/ + /* Lock acquired when entering any public guestfs_* function to + * protect the handle. + */ + gl_recursive_lock_define (, lock); + /**** Configuration of the handle. ****/ bool verbose; /* Debugging. */ bool trace; /* Trace calls. */ diff --git a/lib/handle.c b/lib/handle.c index 91f5f755d..09c29ed84 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -86,6 +86,8 @@ guestfs_create_flags (unsigned flags, ...) g = calloc (1, sizeof (*g)); if (!g) return NULL; + gl_recursive_lock_init (g->lock); + g->state = CONFIG; g->conn = NULL; @@ -169,6 +171,7 @@ guestfs_create_flags (unsigned flags, ...) free (g->path); free (g->hv); free (g->append); + gl_recursive_lock_destroy (g->lock); free (g); return NULL; } @@ -399,6 +402,7 @@ guestfs_close (guestfs_h *g) free (g->backend_data); guestfs_int_free_string_list (g->backend_settings); free (g->append); + gl_recursive_lock_destroy (g->lock); free (g); } -- 2.13.2
Richard W.M. Jones
2017-Jul-21 21:47 UTC
[Libguestfs] [PATCH v3 REPOST 2/5] threads: Acquire and release the lock around each public guestfs_* API.
Acquire the per-handle lock on entering each public API function. The lock is released by a cleanup handler, so we only need to use the ACQUIRE_LOCK_FOR_CURRENT_SCOPE macro at the top of each function. Note this means we require __attribute__((cleanup)). On platforms where this is not supported, the code will probably hang whenever a libguestfs function is called. The only definitive list of public APIs is found indirectly in the generator (in generator/c.ml : globals). --- generator/c.ml | 4 ++++ lib/errors.c | 8 ++++++++ lib/events.c | 8 ++++++++ lib/guestfs-internal.h | 8 ++++++++ lib/handle.c | 17 ++++++++++++++++- lib/private-data.c | 7 +++++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/generator/c.ml b/generator/c.ml index c9fd867de..6396b4159 100644 --- a/generator/c.ml +++ b/generator/c.ml @@ -1690,6 +1690,7 @@ and generate_client_actions actions () ~dll_public:true c_name style; pr "{\n"; + pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; handle_null_optargs optargs c_name; @@ -1776,6 +1777,7 @@ and generate_client_actions actions () c_name style; pr "{\n"; + pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; handle_null_optargs optargs c_name; @@ -2121,6 +2123,7 @@ and generate_client_actions_variants () ~handle:"g" ~prefix:"guestfs_" ~suffix:"_va" ~optarg_proto:VA c_name style; pr "{\n"; + pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; pr " struct guestfs_%s_argv optargs_s;\n" c_name; pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" c_name; pr " int i;\n"; @@ -2178,6 +2181,7 @@ and generate_client_actions_variants () ~handle:"g" ~prefix:"guestfs_" name (ret, args, []); pr "{\n"; + pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; pr " struct guestfs_%s_opts_argv optargs_s = { .bitmask = 0 };\n" name; pr " struct guestfs_%s_opts_argv *optargs = &optargs_s;\n" name; pr "\n"; diff --git a/lib/errors.c b/lib/errors.c index ace6a89cf..def1d3c89 100644 --- a/lib/errors.c +++ b/lib/errors.c @@ -54,12 +54,14 @@ const char * guestfs_last_error (guestfs_h *g) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); return g->last_error; } int guestfs_last_errno (guestfs_h *g) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); return g->last_errnum; } @@ -217,12 +219,14 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...) void guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); g->abort_cb = cb; } guestfs_abort_cb guestfs_get_out_of_memory_handler (guestfs_h *g) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); return g->abort_cb; } @@ -230,6 +234,7 @@ void guestfs_set_error_handler (guestfs_h *g, guestfs_error_handler_cb cb, void *data) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); g->error_cb = cb; g->error_cb_data = data; } @@ -237,6 +242,7 @@ guestfs_set_error_handler (guestfs_h *g, guestfs_error_handler_cb guestfs_get_error_handler (guestfs_h *g, void **data_rtn) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); if (data_rtn) *data_rtn = g->error_cb_data; return g->error_cb; } @@ -245,6 +251,7 @@ void guestfs_push_error_handler (guestfs_h *g, guestfs_error_handler_cb cb, void *data) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); struct error_cb_stack *old_stack; old_stack = g->error_cb_stack; @@ -259,6 +266,7 @@ guestfs_push_error_handler (guestfs_h *g, void guestfs_pop_error_handler (guestfs_h *g) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); struct error_cb_stack *next_stack; if (g->error_cb_stack) { diff --git a/lib/events.c b/lib/events.c index 1bddd7611..8005b1cc8 100644 --- a/lib/events.c +++ b/lib/events.c @@ -35,6 +35,7 @@ guestfs_set_event_callback (guestfs_h *g, int flags, void *opaque) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); int event_handle; if (flags != 0) { @@ -69,6 +70,8 @@ guestfs_set_event_callback (guestfs_h *g, void guestfs_delete_event_callback (guestfs_h *g, int event_handle) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); + if (event_handle < 0 || event_handle >= (int) g->nr_events) return; @@ -296,6 +299,7 @@ void guestfs_set_log_message_callback (guestfs_h *g, guestfs_log_message_cb cb, void *opaque) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); replace_old_style_event_callback (g, log_message_callback_wrapper, GUESTFS_EVENT_APPLIANCE, opaque, cb); @@ -318,6 +322,7 @@ void guestfs_set_subprocess_quit_callback (guestfs_h *g, guestfs_subprocess_quit_cb cb, void *opaque) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); replace_old_style_event_callback (g, subprocess_quit_callback_wrapper, GUESTFS_EVENT_SUBPROCESS_QUIT, opaque, cb); @@ -340,6 +345,7 @@ void guestfs_set_launch_done_callback (guestfs_h *g, guestfs_launch_done_cb cb, void *opaque) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); replace_old_style_event_callback (g, launch_done_callback_wrapper, GUESTFS_EVENT_LAUNCH_DONE, opaque, cb); @@ -362,6 +368,7 @@ void guestfs_set_close_callback (guestfs_h *g, guestfs_close_cb cb, void *opaque) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); replace_old_style_event_callback (g, close_callback_wrapper, GUESTFS_EVENT_CLOSE, opaque, cb); @@ -385,6 +392,7 @@ void guestfs_set_progress_callback (guestfs_h *g, guestfs_progress_cb cb, void *opaque) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); replace_old_style_event_callback (g, progress_callback_wrapper, GUESTFS_EVENT_PROGRESS, opaque, cb); diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h index 10080c4b7..be92befdc 100644 --- a/lib/guestfs-internal.h +++ b/lib/guestfs-internal.h @@ -77,6 +77,14 @@ #define TRACE4(name, arg1, arg2, arg3, arg4) #endif +/* Acquire and release the per-handle lock. Note the release happens + * in an __attribute__((cleanup)) handler, making it simple to write + * bug-free code. + */ +#define ACQUIRE_LOCK_FOR_CURRENT_SCOPE(g) \ + CLEANUP_GL_RECURSIVE_LOCK_UNLOCK gl_recursive_lock_t *_lock = &(g)->lock; \ + gl_recursive_lock_lock (*_lock) + /* Default and minimum appliance memory size. */ /* Needs to be larger on ppc64 because of the larger page size (64K). diff --git a/lib/handle.c b/lib/handle.c index 09c29ed84..183f247fb 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -322,6 +322,7 @@ guestfs_close (guestfs_h *g) { struct hv_param *hp, *hp_next; guestfs_h **gg; + int r; if (g->state == NO_HANDLE) { /* Not safe to call ANY callbacks here, so ... */ @@ -402,7 +403,21 @@ guestfs_close (guestfs_h *g) free (g->backend_data); guestfs_int_free_string_list (g->backend_settings); free (g->append); - gl_recursive_lock_destroy (g->lock); + r = glthread_recursive_lock_destroy (&g->lock); + if (r != 0) { + /* If pthread_mutex_destroy returns 16 (EBUSY), this indicates + * that the lock is held somewhere. That means a programming + * error if the main program is using threads. + */ + errno = r; + perror ("guestfs_close: g->lock"); + /* While we're debugging locks in libguestfs I want this to fail + * noisily. Remove this later since there are valid times when + * this might fail such as if the program exits during a + * libguestfs operation. + */ + abort (); + } free (g); } diff --git a/lib/private-data.c b/lib/private-data.c index f448894b4..65b902260 100644 --- a/lib/private-data.c +++ b/lib/private-data.c @@ -81,6 +81,7 @@ freer (void *x) void guestfs_set_private (guestfs_h *g, const char *key, void *data) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); struct pda_entry *new_entry, *old_entry, *entry; if (g->pda == NULL) { @@ -105,6 +106,8 @@ guestfs_set_private (guestfs_h *g, const char *key, void *data) void * guestfs_get_private (guestfs_h *g, const char *key) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); + if (g->pda == NULL) return NULL; /* no keys have been set */ @@ -120,6 +123,8 @@ guestfs_get_private (guestfs_h *g, const char *key) void * guestfs_first_private (guestfs_h *g, const char **key_rtn) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); + if (g->pda == NULL) return NULL; @@ -139,6 +144,8 @@ guestfs_first_private (guestfs_h *g, const char **key_rtn) void * guestfs_next_private (guestfs_h *g, const char **key_rtn) { + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); + if (g->pda == NULL) return NULL; -- 2.13.2
Richard W.M. Jones
2017-Jul-21 21:47 UTC
[Libguestfs] [PATCH v3 REPOST 3/5] threads: Use thread-local storage for errors.
We permit the following constructs in libguestfs code: if (guestfs_some_call (g) == -1) { fprintf (stderr, "failed: error is %s\n", guestfs_last_error (g)); } and: guestfs_push_error_handler (g, NULL, NULL); guestfs_some_call (g); guestfs_pop_error_handler (g); Neither of these would be safe if we allowed the handle to be used from threads concurrently, since the error string or error handler could be changed by another thread. Solve this in approximately the same way that libvirt does: by making the error, current error handler, and stack of error handlers use thread-local storage (TLS). The implementation is not entirely straightforward, mainly because POSIX doesn't give us useful destructor behaviour, so effectively we end up creating our own destructor using a linked list. Note that you have to set the error handler in each thread separately, which is an API change (eg: if you set the error handler in one thread, then pass the handle 'g' to another thread, the error handler in the second thread appears to have reset itself back to the default error handler). I haven't yet worked out a better way to solve this. --- bootstrap | 1 + lib/errors.c | 196 ++++++++++++++++++++++++++++++++++++++++--------- lib/guestfs-internal.h | 25 +++---- lib/handle.c | 11 +-- m4/.gitignore | 1 + 5 files changed, 180 insertions(+), 54 deletions(-) diff --git a/bootstrap b/bootstrap index 77a95a25b..4e3d4bc51 100755 --- a/bootstrap +++ b/bootstrap @@ -95,6 +95,7 @@ symlinkat sys_select sys_types sys_wait +tls vasprintf vc-list-files warnings diff --git a/lib/errors.c b/lib/errors.c index def1d3c89..b0c678d77 100644 --- a/lib/errors.c +++ b/lib/errors.c @@ -51,26 +51,150 @@ #include "guestfs.h" #include "guestfs-internal.h" +/* How errors and error handlers works in the handle: + * + * The handle has a g->error_data field which is a thread-local + * storage (TLS) key. + * + * We use TLS because we want to support the common idioms of: + * if (guestfs_foo (g) == -1) + * printf ("%s\n", guestfs_last_error (g)); + * and: + * guestfs_push_error_handler (g, ...); + * guestfs_foo (g); + * guestfs_pop_error_handler (g); + * neither of which would ordinarily be safe when using the same + * handle from multiple threads. + * + * In each thread, the TLS data is either NULL or contains a pointer + * to a 'struct error_data'. + * + * When it is NULL, it means the stack is empty (in that thread) and + * the default handler (default_error_cb) is installed. + * + * As soon as the current thread calls guestfs_set_error_handler, + * guestfs_push_error_handler, or an error is set in the handle (calls + * like guestfs_int_perrorf and so on), the key is created and + * initialized with a pointer to a real 'struct error_data'. + * + * All the 'struct error_data' structures associated with one handle + * are linked together in a linked list, so that we are able to free + * them when the handle is closed. (The pthread_key* API doesn't give + * us any other way to do this, in particular pthread_key_delete + * doesn't call the destructor associated with the key). + */ + +static void default_error_cb (guestfs_h *g, void *data, const char *msg); + +/* Stack of old error handlers. */ +struct error_cb_stack { + struct error_cb_stack *next; + guestfs_error_handler_cb error_cb; + void * error_cb_data; +}; + +/* Error data, stored in thread-local storage in g->error_data key. */ +struct error_data { + /* Linked list of error_data structs allocated for this handle. */ + struct error_data *next; + + char *last_error; /* Last error on handle. */ + int last_errnum; /* errno, or 0 if there was no errno */ + + /* Error handler and stack of old error handlers. */ + guestfs_error_handler_cb error_cb; + void * error_cb_data; + struct error_cb_stack *error_cb_stack; +}; + +static void +free_error_data (struct error_data *error_data) +{ + struct error_cb_stack *p, *next_p; + + free (error_data->last_error); + for (p = error_data->error_cb_stack; p != NULL; p = next_p) { + next_p = p->next; + free (p); + } + free (error_data); +} + +/* Free all the error_data structs created for a particular handle. */ +void +guestfs_int_free_error_data_list (guestfs_h *g) +{ + struct error_data *p, *next_p; + + gl_lock_lock (g->error_data_list_lock); + + for (p = g->error_data_list; p != NULL; p = next_p) { + next_p = p->next; + free_error_data (p); + } + + g->error_data_list = NULL; + + gl_lock_unlock (g->error_data_list_lock); +} + +/* Get thread-specific error_data struct. Create it if necessary. */ +static struct error_data * +get_error_data (guestfs_h *g) +{ + struct error_data *ret; + + ret = gl_tls_get (g->error_data); + + /* Not allocated yet for this thread, so allocate one. */ + if (ret == NULL) { + ret = safe_malloc (g, sizeof *ret); + ret->last_error = NULL; + ret->last_errnum = 0; + ret->error_cb = default_error_cb; + ret->error_cb_data = NULL; + ret->error_cb_stack = NULL; + + /* Add it to the linked list of struct error_data that are + * associated with this handle, so we can free them when the + * handle is closed. + */ + gl_lock_lock (g->error_data_list_lock); + ret->next = g->error_data_list; + g->error_data_list = ret; + gl_lock_unlock (g->error_data_list_lock); + + /* Set the TLS to point to the struct. This is safe because we + * should have acquired the handle lock. + */ + gl_tls_set (g->error_data, ret); + } + + return ret; +} + const char * guestfs_last_error (guestfs_h *g) { ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); - return g->last_error; + return get_error_data (g)->last_error; } int guestfs_last_errno (guestfs_h *g) { ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); - return g->last_errnum; + return get_error_data (g)->last_errnum; } static void set_last_error (guestfs_h *g, int errnum, const char *msg) { - free (g->last_error); - g->last_error = strdup (msg); - g->last_errnum = errnum; + struct error_data *error_data = get_error_data (g); + + free (error_data->last_error); + error_data->last_error = strdup (msg); + error_data->last_errnum = errnum; } /** @@ -166,6 +290,7 @@ guestfs_int_error_errno (guestfs_h *g, int errnum, const char *fs, ...) va_list args; CLEANUP_FREE char *msg = NULL; int err; + struct error_data *error_data = get_error_data (g); va_start (args, fs); err = vasprintf (&msg, fs, args); @@ -177,7 +302,8 @@ guestfs_int_error_errno (guestfs_h *g, int errnum, const char *fs, ...) * message and errno through the handle if it wishes. */ set_last_error (g, errnum, msg); - if (g->error_cb) g->error_cb (g, g->error_cb_data, msg); + if (error_data->error_cb) + error_data->error_cb (g, error_data->error_cb_data, msg); } /** @@ -196,6 +322,7 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...) const int errnum = errno; int err; char buf[256]; + struct error_data *error_data = get_error_data (g); va_start (args, fs); err = vasprintf (&msg, fs, args); @@ -213,7 +340,8 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...) * message and errno through the handle if it wishes. */ set_last_error (g, errnum, msg); - if (g->error_cb) g->error_cb (g, g->error_cb_data, msg); + if (error_data->error_cb) + error_data->error_cb (g, error_data->error_cb_data, msg); } void @@ -235,16 +363,21 @@ guestfs_set_error_handler (guestfs_h *g, guestfs_error_handler_cb cb, void *data) { ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); - g->error_cb = cb; - g->error_cb_data = data; + struct error_data *error_data; + + error_data = get_error_data (g); + error_data->error_cb = cb; + error_data->error_cb_data = data; } guestfs_error_handler_cb guestfs_get_error_handler (guestfs_h *g, void **data_rtn) { ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); - if (data_rtn) *data_rtn = g->error_cb_data; - return g->error_cb; + struct error_data *error_data = get_error_data (g); + + if (data_rtn) *data_rtn = error_data->error_cb_data; + return error_data->error_cb; } void @@ -252,13 +385,15 @@ guestfs_push_error_handler (guestfs_h *g, guestfs_error_handler_cb cb, void *data) { ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); + struct error_data *error_data; struct error_cb_stack *old_stack; - old_stack = g->error_cb_stack; - g->error_cb_stack = safe_malloc (g, sizeof (struct error_cb_stack)); - g->error_cb_stack->next = old_stack; - g->error_cb_stack->error_cb = g->error_cb; - g->error_cb_stack->error_cb_data = g->error_cb_data; + error_data = get_error_data (g); + old_stack = error_data->error_cb_stack; + error_data->error_cb_stack = safe_malloc (g, sizeof (struct error_cb_stack)); + error_data->error_cb_stack->next = old_stack; + error_data->error_cb_stack->error_cb = error_data->error_cb; + error_data->error_cb_stack->error_cb_data = error_data->error_cb_data; guestfs_set_error_handler (g, cb, data); } @@ -267,26 +402,21 @@ void guestfs_pop_error_handler (guestfs_h *g) { ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); + struct error_data *error_data; struct error_cb_stack *next_stack; - if (g->error_cb_stack) { - next_stack = g->error_cb_stack->next; - guestfs_set_error_handler (g, g->error_cb_stack->error_cb, - g->error_cb_stack->error_cb_data); - free (g->error_cb_stack); - g->error_cb_stack = next_stack; + error_data = get_error_data (g); + if (error_data->error_cb_stack) { + next_stack = error_data->error_cb_stack->next; + guestfs_set_error_handler (g, error_data->error_cb_stack->error_cb, + error_data->error_cb_stack->error_cb_data); + free (error_data->error_cb_stack); + error_data->error_cb_stack = next_stack; + } + else { + error_data->error_cb = default_error_cb; + error_data->error_cb_data = NULL; } - else - guestfs_int_init_error_handler (g); -} - -static void default_error_cb (guestfs_h *g, void *data, const char *msg); - -void -guestfs_int_init_error_handler (guestfs_h *g) -{ - g->error_cb = default_error_cb; - g->error_cb_data = NULL; } static void diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h index be92befdc..1f31860de 100644 --- a/lib/guestfs-internal.h +++ b/lib/guestfs-internal.h @@ -53,6 +53,7 @@ #endif #include "glthread/lock.h" +#include "glthread/tls.h" #include "hash.h" #include "guestfs-utils.h" @@ -372,15 +373,6 @@ struct connection_ops { }; /** - * Stack of old error handlers. - */ -struct error_cb_stack { - struct error_cb_stack *next; - guestfs_error_handler_cb error_cb; - void * error_cb_data; -}; - -/** * Cache of queried features. * * Used to cache the appliance features (see F<lib/available.c>). @@ -457,9 +449,6 @@ struct guestfs_h { char **backend_settings; /* Backend settings (can be NULL). */ /**** Runtime information. ****/ - char *last_error; /* Last error on handle. */ - int last_errnum; /* errno, or 0 if there was no errno */ - /* Temporary and cache directories. */ /* The actual temporary directory - this is not created with the * handle, you have to call guestfs_int_lazy_make_tmpdir. @@ -473,9 +462,13 @@ struct guestfs_h { char *int_cachedir; /* $LIBGUESTFS_CACHEDIR or guestfs_set_cachedir or NULL */ /* Error handler, plus stack of old error handlers. */ - guestfs_error_handler_cb error_cb; - void * error_cb_data; - struct error_cb_stack *error_cb_stack; + gl_tls_key_t error_data; + + /* Linked list of error_data structures allocated for this handle, + * plus a mutex to protect the linked list. + */ + gl_lock_define (, error_data_list_lock); + struct error_data *error_data_list; /* Out of memory error handler. */ guestfs_abort_cb abort_cb; @@ -705,7 +698,7 @@ extern char *guestfs_int_safe_asprintf (guestfs_h *g, const char *fs, ...) #define safe_asprintf guestfs_int_safe_asprintf /* errors.c */ -extern void guestfs_int_init_error_handler (guestfs_h *g); +extern void guestfs_int_free_error_data_list (guestfs_h *g); extern void guestfs_int_error_errno (guestfs_h *g, int errnum, const char *fs, ...) __attribute__((format (printf,3,4))); diff --git a/lib/handle.c b/lib/handle.c index 183f247fb..7f528c129 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -32,6 +32,7 @@ #include <libxml/xmlversion.h> #include "glthread/lock.h" +#include "glthread/tls.h" #include "ignore-value.h" #include "c-ctype.h" #include "getprogname.h" @@ -92,7 +93,7 @@ guestfs_create_flags (unsigned flags, ...) g->conn = NULL; - guestfs_int_init_error_handler (g); + gl_tls_key_init (g->error_data, NULL); g->abort_cb = abort; g->recovery_proc = 1; @@ -171,6 +172,8 @@ guestfs_create_flags (unsigned flags, ...) free (g->path); free (g->hv); free (g->append); + guestfs_int_free_error_data_list (g); + gl_tls_key_destroy (g->error_data); gl_recursive_lock_destroy (g->lock); free (g); return NULL; @@ -383,9 +386,6 @@ guestfs_close (guestfs_h *g) free (hp); } - while (g->error_cb_stack) - guestfs_pop_error_handler (g); - if (g->pda) hash_free (g->pda); free (g->tmpdir); @@ -394,7 +394,6 @@ guestfs_close (guestfs_h *g) free (g->env_runtimedir); free (g->int_tmpdir); free (g->int_cachedir); - free (g->last_error); free (g->identifier); free (g->program); free (g->path); @@ -403,6 +402,8 @@ guestfs_close (guestfs_h *g) free (g->backend_data); guestfs_int_free_string_list (g->backend_settings); free (g->append); + guestfs_int_free_error_data_list (g); + gl_tls_key_destroy (g->error_data); r = glthread_recursive_lock_destroy (&g->lock); if (r != 0) { /* If pthread_mutex_destroy returns 16 (EBUSY), this indicates diff --git a/m4/.gitignore b/m4/.gitignore index 07960ed7b..a84b22e5c 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -248,6 +248,7 @@ /thread.m4 /time_h.m4 /timespec.m4 +/tls.m4 /ttyname_r.m4 /ulonglong.m4 /ungetc.m4 -- 2.13.2
Richard W.M. Jones
2017-Jul-21 21:47 UTC
[Libguestfs] [PATCH v3 REPOST 4/5] threads: Update documentation in guestfs(3) to describe the new behaviour.
--- lib/guestfs.pod | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/guestfs.pod b/lib/guestfs.pod index b87210e65..8a1773fd7 100644 --- a/lib/guestfs.pod +++ b/lib/guestfs.pod @@ -1340,14 +1340,31 @@ encrypted devices. All high-level libguestfs actions are synchronous. If you want to use libguestfs asynchronously then you must create a thread. -Only use the handle from a single thread. Either use the handle -exclusively from one thread, or provide your own mutex so that two -threads cannot issue calls on the same handle at the same time. Even -apparently innocent functions like L</guestfs_get_trace> are I<not> -safe to be called from multiple threads without a mutex. - -See the graphical program guestfs-browser for one possible -architecture for multithreaded programs using libvirt and libguestfs. +=head3 Threads in libguestfs E<ge> 1.38 + +In libguestfs E<ge> 1.38, each handle (C<guestfs_h>) contains a lock +which is acquired automatically when you call a libguestfs function. +The practical effect of this is you can call libguestfs functions with +the same handle from multiple threads without needing to do any +locking. + +Also in libguestfs E<ge> 1.38, the last error on the handle +(L</guestfs_last_error>, L</guestfs_last_errno>) is stored in +thread-local storage, so it is safe to write code like: + + if (guestfs_add_drive_ro (g, drive) == -1) + fprintf (stderr, "error was: %s\n", guestfs_last_error (g)); + +even when other threads may be concurrently using the same handle C<g>. + +=head3 Threads in libguestfs E<lt> 1.38 + +In libguestfs E<lt> 1.38, you must use the handle only from a single +thread. Either use the handle exclusively from one thread, or provide +your own mutex so that two threads cannot issue calls on the same +handle at the same time. Even apparently innocent functions like +L</guestfs_get_trace> are I<not> safe to be called from multiple +threads without a mutex in libguestfs E<lt> 1.38. Use L</guestfs_set_identifier> to make it simpler to identify threads in trace output. -- 2.13.2
Richard W.M. Jones
2017-Jul-21 21:47 UTC
[Libguestfs] [PATCH v3 REPOST 5/5] threads: Add a test.
--- .gitignore | 1 + tests/c-api/Makefile.am | 21 ++++++- tests/c-api/test-threads.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index bbd9284c6..5b936239c 100644 --- a/.gitignore +++ b/.gitignore @@ -562,6 +562,7 @@ Makefile.in /tests/c-api/test-pwd /tests/c-api/tests /tests/c-api/tests.c +/tests/c-api/test-threads /tests/c-api/test*.tmp /tests/c-api/test-user-cancel /tests/charsets/test-charset-fidelity diff --git a/tests/c-api/Makefile.am b/tests/c-api/Makefile.am index d79b8ed52..e80f88fa0 100644 --- a/tests/c-api/Makefile.am +++ b/tests/c-api/Makefile.am @@ -41,7 +41,8 @@ check_PROGRAMS = \ test-debug-to-file \ test-environment \ test-pwd \ - test-event-string + test-event-string \ + test-threads if HAVE_LIBDL check_PROGRAMS += \ test-dlopen @@ -59,7 +60,8 @@ TESTS = \ test-user-cancel \ test-debug-to-file \ test-environment \ - test-event-string + test-event-string \ + test-threads if HAVE_LIBDL TESTS += \ test-dlopen @@ -265,6 +267,21 @@ test_event_string_LDADD = \ $(LTLIBINTL) \ $(top_builddir)/gnulib/lib/libgnu.la +test_threads_SOURCES = test-threads.c +test_threads_CPPFLAGS = \ + -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ + -I$(top_srcdir)/lib -I$(top_builddir)/lib \ + -I$(top_srcdir)/gnulib/lib \ + -I$(top_builddir)/gnulib/lib +test_threads_CFLAGS = \ + -pthread \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) +test_threads_LDADD = \ + $(top_builddir)/lib/libguestfs.la \ + $(LTLIBTHREAD) \ + $(LTLIBINTL) \ + $(top_builddir)/gnulib/lib/libgnu.la + if HAVE_LIBVIRT test_add_libvirt_dom_SOURCES = test-add-libvirt-dom.c test_add_libvirt_dom_CPPFLAGS = \ diff --git a/tests/c-api/test-threads.c b/tests/c-api/test-threads.c new file mode 100644 index 000000000..673b4bbff --- /dev/null +++ b/tests/c-api/test-threads.c @@ -0,0 +1,133 @@ +/* libguestfs + * Copyright (C) 2015-2017 Red Hat 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. + */ + +/* Test that we can make API calls safely from multiple threads. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include <pthread.h> + +#include "guestfs.h" +#include "guestfs-utils.h" + +static guestfs_h *g; + +#define RUN_TIME 60 /* seconds */ +#define NR_CONCURRENT_THREADS 4 + +static void *start_thread (void *nullv); + +int +main (int argc, char *argv[]) +{ + time_t start_t, t; + pthread_t threads[NR_CONCURRENT_THREADS]; + void *ret; + int i, r; + + /* Because we rely on error message content below, force LC_ALL=C. */ + setenv ("LC_ALL", "C", 1); + + g = guestfs_create (); + if (!g) { + perror ("guestfs_create"); + exit (EXIT_FAILURE); + } + + time (&start_t); + + while (time (&t), t - start_t < RUN_TIME) { + for (i = 0; i < NR_CONCURRENT_THREADS; ++i) { + r = pthread_create (&threads[i], NULL, start_thread, NULL); + if (r != 0) { + fprintf (stderr, "pthread_create: %s\n", strerror (r)); + exit (EXIT_FAILURE); + } + } + + for (i = 0; i < NR_CONCURRENT_THREADS; ++i) { + r = pthread_join (threads[i], &ret); + if (r != 0) { + fprintf (stderr, "pthread_join: %s\n", strerror (r)); + exit (EXIT_FAILURE); + } + if (ret != NULL) { + fprintf (stderr, "thread[%d] failed\n", i); + exit (EXIT_FAILURE); + } + } + } + + guestfs_close (g); + + exit (EXIT_SUCCESS); +} + +static void * +start_thread (void *nullv) +{ + char *p; + const char *err; + int iterations; + + for (iterations = 0; iterations < 1000; ++iterations) { + guestfs_set_hv (g, "test"); + p = guestfs_get_hv (g); + if (!p || STRNEQ (p, "test")) { + fprintf (stderr, "invalid return from guestfs_get_hv\n"); + pthread_exit ((void *)-1); + } + free (p); + + guestfs_push_error_handler (g, NULL, NULL); + guestfs_set_hv (g, "test"); + p = guestfs_get_hv (g); + guestfs_pop_error_handler (g); + if (!p || STRNEQ (p, "test")) { + fprintf (stderr, "invalid return from guestfs_get_hv\n"); + pthread_exit ((void *)-1); + } + free (p); + + guestfs_push_error_handler (g, NULL, NULL); + guestfs_set_program (g, NULL); /* deliberately cause an error */ + guestfs_pop_error_handler (g); + err = guestfs_last_error (g); + if (!err || !STRPREFIX (err, "set_program: program: ")) { + fprintf (stderr, "invalid error message: %s\n", err ? err : "NULL"); + pthread_exit ((void *)-1); + } + + guestfs_push_error_handler (g, NULL, NULL); + guestfs_set_memsize (g, 1); /* deliberately cause an error */ + guestfs_pop_error_handler (g); + err = guestfs_last_error (g); + if (!err || strstr (err, "memsize") == NULL) { + fprintf (stderr, "invalid error message: %s\n", err ? err : "NULL"); + pthread_exit ((void *)-1); + } + } + + pthread_exit (NULL); +} -- 2.13.2
Richard Jones
2017-Jul-21 22:34 UTC
[Libguestfs] check-release success (was: Re: [PATCH v3 REPOST 5/5] threads: Add a test.)
0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/php' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/php' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/php' Making check in erlang make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/erlang' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/erlang' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/erlang' PASS: tests/010-load.erl PASS: tests/030-config.erl PASS: run-bindtests PASS: tests/070-optargs.erl PASS: tests/060-readdir.erl PASS: tests/050-lvcreate.erl ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 6 # PASS: 6 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/erlang' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/erlang' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/erlang' Making check in erlang/examples make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/erlang/examples' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/erlang/examples' Making check in lua make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/lua' ln -sf .libs/libluaguestfs.so guestfs.so make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/lua' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/lua' PASS: tests/025-create-flags.lua PASS: tests/015-globals.lua PASS: run-bindtests PASS: tests/020-create.lua PASS: tests/010-load.lua PASS: tests/030-config.lua PASS: tests/027-create-multiple.lua PASS: tests/400-events.lua PASS: tests/070-optargs.lua PASS: tests/900-errors.lua PASS: tests/060-readdir.lua PASS: tests/050-lvcreate.lua PASS: tests/400-progress.lua ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 13 # PASS: 13 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/lua' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/lua' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/lua' Making check in lua/examples make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/lua/examples' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/lua/examples' Making check in gobject make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/gobject' make check-am make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/gobject' make check-TESTS make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/gobject' make[4]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/gobject' SKIP: run-tests PASS: run-tests-retvalues PASS: run-live-tests ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 3 # PASS: 2 # SKIP: 1 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[4]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/gobject' make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/gobject' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/gobject' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/gobject' Making check in csharp make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/csharp' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/csharp' Making check in common/mlutils make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' make c_utils_unit_tests make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' CC c_utils_unit_tests-dummy.o OCAMLOPT c_utils_unit_tests.cmx GEN c_utils_unit_tests make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' PASS: c_utils_unit_tests ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlutils' Making check in common/mlprogress make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlprogress' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlprogress' Making check in common/mlvisit make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' make visit_tests make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' CC dummy.o OCAMLOPT visit_tests.cmx File "visit_tests.ml", line 111, characters 25-31: Warning 52: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 8.5) File "visit_tests.ml", line 119, characters 16-23: Warning 52: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 8.5) GEN visit_tests make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' PASS: visit_tests ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlvisit' Making check in common/mlxml make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/common/mlxml' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/common/mlxml' Making check in mllib make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/mllib' make getopt_tests common_utils_tests JSON_tests make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/mllib' CC getopt_tests-dummy.o OCAMLOPT getopt_tests.cmx CC common_utils_tests-dummy.o OCAMLOPT common_utils_tests.cmx CC dummy.o OCAMLOPT JSON_tests.cmx GEN getopt_tests GEN JSON_tests GEN common_utils_tests make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/mllib' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/mllib' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/mllib' PASS: JSON_tests PASS: common_utils_tests PASS: test-getopt.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 3 # PASS: 3 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/mllib' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/mllib' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/mllib' Making check in customize make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/customize' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/customize' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/customize' rm -f test-firstboot-rhel-4.9.sh test-firstboot-rhel-4.9.sh-t rm -f test-firstboot-rhel-5.11.sh test-firstboot-rhel-5.11.sh-t rm -f test-firstboot-rhel-6.8.sh test-firstboot-rhel-6.8.sh-t f=`echo "test-firstboot-rhel-4.9.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-4.9.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-4.9.sh-t f=`echo "test-firstboot-rhel-5.11.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-5.11.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-5.11.sh-t f=`echo "test-firstboot-rhel-6.8.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-6.8.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-6.8.sh-t chmod 0755 test-firstboot-rhel-5.11.sh-t chmod 0755 test-firstboot-rhel-4.9.sh-t chmod 0755 test-firstboot-rhel-6.8.sh-t mv test-firstboot-rhel-4.9.sh-t test-firstboot-rhel-4.9.sh mv test-firstboot-rhel-5.11.sh-t test-firstboot-rhel-5.11.sh mv test-firstboot-rhel-6.8.sh-t test-firstboot-rhel-6.8.sh rm -f test-firstboot-rhel-7.2.sh test-firstboot-rhel-7.2.sh-t rm -f test-firstboot-debian-6.sh test-firstboot-debian-6.sh-t f=`echo "test-firstboot-rhel-7.2.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-rhel-7.2.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-rhel-7.2.sh-t f=`echo "test-firstboot-debian-6.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-debian-6.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-debian-6.sh-t rm -f test-firstboot-debian-7.sh test-firstboot-debian-7.sh-t f=`echo "test-firstboot-debian-7.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-debian-7.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-debian-7.sh-t chmod 0755 test-firstboot-rhel-7.2.sh-t chmod 0755 test-firstboot-debian-6.sh-t chmod 0755 test-firstboot-debian-7.sh-t mv test-firstboot-rhel-7.2.sh-t test-firstboot-rhel-7.2.sh mv test-firstboot-debian-6.sh-t test-firstboot-debian-6.sh mv test-firstboot-debian-7.sh-t test-firstboot-debian-7.sh rm -f test-firstboot-debian-8.sh test-firstboot-debian-8.sh-t rm -f test-firstboot-fedora-25.sh test-firstboot-fedora-25.sh-t f=`echo "test-firstboot-debian-8.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-debian-8.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-debian-8.sh-t rm -f test-firstboot-fedora-26.sh test-firstboot-fedora-26.sh-t f=`echo "test-firstboot-fedora-25.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-fedora-25.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-fedora-25.sh-t f=`echo "test-firstboot-fedora-26.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-fedora-26.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-fedora-26.sh-t chmod 0755 test-firstboot-debian-8.sh-t mv test-firstboot-debian-8.sh-t test-firstboot-debian-8.sh rm -f test-firstboot-ubuntu-10.04.sh test-firstboot-ubuntu-10.04.sh-t f=`echo "test-firstboot-ubuntu-10.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-10.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-10.04.sh-t chmod 0755 test-firstboot-fedora-25.sh-t chmod 0755 test-firstboot-fedora-26.sh-t mv test-firstboot-fedora-25.sh-t test-firstboot-fedora-25.sh mv test-firstboot-fedora-26.sh-t test-firstboot-fedora-26.sh chmod 0755 test-firstboot-ubuntu-10.04.sh-t rm -f test-firstboot-ubuntu-12.04.sh test-firstboot-ubuntu-12.04.sh-t mv test-firstboot-ubuntu-10.04.sh-t test-firstboot-ubuntu-10.04.sh rm -f test-firstboot-ubuntu-14.04.sh test-firstboot-ubuntu-14.04.sh-t f=`echo "test-firstboot-ubuntu-12.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-12.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-12.04.sh-t rm -f test-firstboot-ubuntu-16.04.sh test-firstboot-ubuntu-16.04.sh-t f=`echo "test-firstboot-ubuntu-14.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-14.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-14.04.sh-t f=`echo "test-firstboot-ubuntu-16.04.sh" | /usr/bin/sed 's/test-firstboot-\(.*\).sh/\1/'`; \ echo 'script=test-firstboot-ubuntu-16.04.sh exec $srcdir/test-firstboot.sh' "$f" > test-firstboot-ubuntu-16.04.sh-t chmod 0755 test-firstboot-ubuntu-12.04.sh-t mv test-firstboot-ubuntu-12.04.sh-t test-firstboot-ubuntu-12.04.sh chmod 0755 test-firstboot-ubuntu-14.04.sh-t rm -f test-password-centos-7.2.sh test-password-centos-7.2.sh-t mv test-firstboot-ubuntu-14.04.sh-t test-firstboot-ubuntu-14.04.sh chmod 0755 test-firstboot-ubuntu-16.04.sh-t f=`echo "test-password-centos-7.2.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-centos-7.2.sh exec $srcdir/test-password.pl' "$f" > test-password-centos-7.2.sh-t mv test-firstboot-ubuntu-16.04.sh-t test-firstboot-ubuntu-16.04.sh rm -f test-password-debian-6.sh test-password-debian-6.sh-t f=`echo "test-password-debian-6.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-debian-6.sh exec $srcdir/test-password.pl' "$f" > test-password-debian-6.sh-t rm -f test-password-debian-7.sh test-password-debian-7.sh-t f=`echo "test-password-debian-7.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-debian-7.sh exec $srcdir/test-password.pl' "$f" > test-password-debian-7.sh-t chmod 0755 test-password-centos-7.2.sh-t mv test-password-centos-7.2.sh-t test-password-centos-7.2.sh chmod 0755 test-password-debian-6.sh-t rm -f test-password-debian-8.sh test-password-debian-8.sh-t chmod 0755 test-password-debian-7.sh-t mv test-password-debian-6.sh-t test-password-debian-6.sh f=`echo "test-password-debian-8.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-debian-8.sh exec $srcdir/test-password.pl' "$f" > test-password-debian-8.sh-t mv test-password-debian-7.sh-t test-password-debian-7.sh rm -f test-password-fedora-25.sh test-password-fedora-25.sh-t rm -f test-password-rhel-3.9.sh test-password-rhel-3.9.sh-t f=`echo "test-password-fedora-25.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-fedora-25.sh exec $srcdir/test-password.pl' "$f" > test-password-fedora-25.sh-t f=`echo "test-password-rhel-3.9.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-3.9.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-3.9.sh-t chmod 0755 test-password-debian-8.sh-t mv test-password-debian-8.sh-t test-password-debian-8.sh chmod 0755 test-password-fedora-25.sh-t chmod 0755 test-password-rhel-3.9.sh-t mv test-password-fedora-25.sh-t test-password-fedora-25.sh mv test-password-rhel-3.9.sh-t test-password-rhel-3.9.sh rm -f test-password-rhel-4.9.sh test-password-rhel-4.9.sh-t rm -f test-password-rhel-5.11.sh test-password-rhel-5.11.sh-t f=`echo "test-password-rhel-4.9.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-4.9.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-4.9.sh-t f=`echo "test-password-rhel-5.11.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-5.11.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-5.11.sh-t rm -f test-password-rhel-6.9.sh test-password-rhel-6.9.sh-t f=`echo "test-password-rhel-6.9.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-6.9.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-6.9.sh-t chmod 0755 test-password-rhel-4.9.sh-t chmod 0755 test-password-rhel-5.11.sh-t mv test-password-rhel-4.9.sh-t test-password-rhel-4.9.sh mv test-password-rhel-5.11.sh-t test-password-rhel-5.11.sh rm -f test-password-rhel-7.2.sh test-password-rhel-7.2.sh-t rm -f test-password-ubuntu-10.04.sh test-password-ubuntu-10.04.sh-t f=`echo "test-password-rhel-7.2.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-rhel-7.2.sh exec $srcdir/test-password.pl' "$f" > test-password-rhel-7.2.sh-t f=`echo "test-password-ubuntu-10.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-10.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-10.04.sh-t chmod 0755 test-password-rhel-6.9.sh-t mv test-password-rhel-6.9.sh-t test-password-rhel-6.9.sh chmod 0755 test-password-rhel-7.2.sh-t rm -f test-password-ubuntu-12.04.sh test-password-ubuntu-12.04.sh-t mv test-password-rhel-7.2.sh-t test-password-rhel-7.2.sh f=`echo "test-password-ubuntu-12.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-12.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-12.04.sh-t chmod 0755 test-password-ubuntu-10.04.sh-t rm -f test-password-ubuntu-14.04.sh test-password-ubuntu-14.04.sh-t mv test-password-ubuntu-10.04.sh-t test-password-ubuntu-10.04.sh chmod 0755 test-password-ubuntu-12.04.sh-t f=`echo "test-password-ubuntu-14.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-14.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-14.04.sh-t mv test-password-ubuntu-12.04.sh-t test-password-ubuntu-12.04.sh rm -f test-password-ubuntu-16.04.sh test-password-ubuntu-16.04.sh-t chmod 0755 test-password-ubuntu-14.04.sh-t rm -f test-settings-rhel-4.9.sh test-settings-rhel-4.9.sh-t f=`echo "test-password-ubuntu-16.04.sh" | /usr/bin/sed 's/test-password-\(.*\).sh/\1/'`; \ echo 'script=test-password-ubuntu-16.04.sh exec $srcdir/test-password.pl' "$f" > test-password-ubuntu-16.04.sh-t mv test-password-ubuntu-14.04.sh-t test-password-ubuntu-14.04.sh f=`echo "test-settings-rhel-4.9.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-4.9.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-4.9.sh-t rm -f test-settings-rhel-5.11.sh test-settings-rhel-5.11.sh-t f=`echo "test-settings-rhel-5.11.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-5.11.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-5.11.sh-t chmod 0755 test-password-ubuntu-16.04.sh-t chmod 0755 test-settings-rhel-4.9.sh-t mv test-password-ubuntu-16.04.sh-t test-password-ubuntu-16.04.sh mv test-settings-rhel-4.9.sh-t test-settings-rhel-4.9.sh rm -f test-settings-rhel-6.8.sh test-settings-rhel-6.8.sh-t chmod 0755 test-settings-rhel-5.11.sh-t f=`echo "test-settings-rhel-6.8.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-6.8.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-6.8.sh-t mv test-settings-rhel-5.11.sh-t test-settings-rhel-5.11.sh rm -f test-settings-rhel-7.2.sh test-settings-rhel-7.2.sh-t rm -f test-settings-debian-6.sh test-settings-debian-6.sh-t f=`echo "test-settings-rhel-7.2.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-rhel-7.2.sh exec $srcdir/test-settings.sh' "$f" > test-settings-rhel-7.2.sh-t f=`echo "test-settings-debian-6.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-debian-6.sh exec $srcdir/test-settings.sh' "$f" > test-settings-debian-6.sh-t chmod 0755 test-settings-rhel-6.8.sh-t mv test-settings-rhel-6.8.sh-t test-settings-rhel-6.8.sh chmod 0755 test-settings-rhel-7.2.sh-t mv test-settings-rhel-7.2.sh-t test-settings-rhel-7.2.sh rm -f test-settings-debian-7.sh test-settings-debian-7.sh-t chmod 0755 test-settings-debian-6.sh-t f=`echo "test-settings-debian-7.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-debian-7.sh exec $srcdir/test-settings.sh' "$f" > test-settings-debian-7.sh-t mv test-settings-debian-6.sh-t test-settings-debian-6.sh rm -f test-settings-debian-8.sh test-settings-debian-8.sh-t rm -f test-settings-fedora-25.sh test-settings-fedora-25.sh-t f=`echo "test-settings-debian-8.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-debian-8.sh exec $srcdir/test-settings.sh' "$f" > test-settings-debian-8.sh-t f=`echo "test-settings-fedora-25.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-fedora-25.sh exec $srcdir/test-settings.sh' "$f" > test-settings-fedora-25.sh-t chmod 0755 test-settings-debian-7.sh-t chmod 0755 test-settings-fedora-25.sh-t chmod 0755 test-settings-debian-8.sh-t mv test-settings-debian-7.sh-t test-settings-debian-7.sh mv test-settings-fedora-25.sh-t test-settings-fedora-25.sh mv test-settings-debian-8.sh-t test-settings-debian-8.sh rm -f test-settings-ubuntu-10.04.sh test-settings-ubuntu-10.04.sh-t rm -f test-settings-ubuntu-12.04.sh test-settings-ubuntu-12.04.sh-t f=`echo "test-settings-ubuntu-10.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-10.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-10.04.sh-t f=`echo "test-settings-ubuntu-12.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-12.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-12.04.sh-t rm -f test-settings-ubuntu-14.04.sh test-settings-ubuntu-14.04.sh-t chmod 0755 test-settings-ubuntu-10.04.sh-t chmod 0755 test-settings-ubuntu-12.04.sh-t f=`echo "test-settings-ubuntu-14.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-14.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-14.04.sh-t mv test-settings-ubuntu-10.04.sh-t test-settings-ubuntu-10.04.sh mv test-settings-ubuntu-12.04.sh-t test-settings-ubuntu-12.04.sh rm -f test-settings-ubuntu-16.04.sh test-settings-ubuntu-16.04.sh-t chmod 0755 test-settings-ubuntu-14.04.sh-t f=`echo "test-settings-ubuntu-16.04.sh" | /usr/bin/sed 's/test-settings-\(.*\).sh/\1/'`; \ echo 'script=test-settings-ubuntu-16.04.sh exec $srcdir/test-settings.sh' "$f" > test-settings-ubuntu-16.04.sh-t mv test-settings-ubuntu-14.04.sh-t test-settings-ubuntu-14.04.sh chmod 0755 test-settings-ubuntu-16.04.sh-t mv test-settings-ubuntu-16.04.sh-t test-settings-ubuntu-16.04.sh SKIP: test-firstboot-rhel-4.9.sh SKIP: test-firstboot-rhel-5.11.sh SKIP: test-firstboot-rhel-6.8.sh PASS: test-virt-customize-docs.sh SKIP: test-firstboot-debian-6.sh SKIP: test-firstboot-rhel-7.2.sh SKIP: test-firstboot-debian-7.sh SKIP: test-firstboot-debian-8.sh SKIP: test-firstboot-fedora-25.sh SKIP: test-firstboot-fedora-26.sh SKIP: test-firstboot-ubuntu-10.04.sh SKIP: test-firstboot-ubuntu-12.04.sh SKIP: test-firstboot-ubuntu-14.04.sh SKIP: test-firstboot-ubuntu-16.04.sh SKIP: test-password-centos-7.2.sh SKIP: test-password-debian-6.sh SKIP: test-password-debian-7.sh SKIP: test-password-debian-8.sh SKIP: test-password-fedora-25.sh SKIP: test-password-rhel-3.9.sh SKIP: test-password-rhel-4.9.sh SKIP: test-password-rhel-5.11.sh SKIP: test-password-rhel-6.9.sh SKIP: test-password-rhel-7.2.sh SKIP: test-password-ubuntu-10.04.sh SKIP: test-password-ubuntu-12.04.sh SKIP: test-password-ubuntu-14.04.sh SKIP: test-password-ubuntu-16.04.sh SKIP: test-settings-rhel-4.9.sh SKIP: test-settings-rhel-5.11.sh SKIP: test-settings-rhel-6.8.sh SKIP: test-settings-rhel-7.2.sh SKIP: test-settings-debian-7.sh SKIP: test-settings-debian-6.sh SKIP: test-settings-debian-8.sh SKIP: test-settings-fedora-25.sh SKIP: test-settings-ubuntu-10.04.sh SKIP: test-settings-ubuntu-12.04.sh SKIP: test-settings-ubuntu-14.04.sh SKIP: test-settings-ubuntu-16.04.sh PASS: test-virt-customize.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 41 # PASS: 2 # SKIP: 39 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/customize' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/customize' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/customize' Making check in builder make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder' make yajl_tests debian.xz fedora.xz ubuntu.xz windows.xz fedora.qcow2 fedora.qcow2.xz make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder' CC yajl_tests-yajl-c.o OCAMLOPT yajl_tests.cmx rm -f debian.xz debian.xz-t rm -f fedora.xz fedora.xz-t xz --best -c ../test-data/phony-guests/debian.img > debian.xz-t xz --best -c ../test-data/phony-guests/fedora.img > fedora.xz-t rm -f ubuntu.xz ubuntu.xz-t xz --best -c ../test-data/phony-guests/ubuntu.img > ubuntu.xz-t rm -f windows.xz windows.xz-t xz --best -c ../test-data/phony-guests/windows.img > windows.xz-t rm -f fedora.qcow2 fedora.qcow2-t qemu-img convert -f raw -O qcow2 ../test-data/phony-guests/fedora.img fedora.qcow2-t mv fedora.qcow2-t fedora.qcow2 GEN yajl_tests rm -f fedora.qcow2.xz fedora.qcow2.xz-t xz --best -c fedora.qcow2 > fedora.qcow2.xz-t mv fedora.qcow2.xz-t fedora.qcow2.xz mv ubuntu.xz-t ubuntu.xz mv windows.xz-t windows.xz mv debian.xz-t debian.xz mv fedora.xz-t fedora.xz make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder' rm -f test-console-centos-7.2.sh test-console-centos-7.2.sh-t rm -f test-console-rhel-6.8.sh test-console-rhel-6.8.sh-t f=`echo "test-console-centos-7.2.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-centos-7.2.sh exec $srcdir/test-console.sh' "$f" > test-console-centos-7.2.sh-t f=`echo "test-console-rhel-6.8.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-rhel-6.8.sh exec $srcdir/test-console.sh' "$f" > test-console-rhel-6.8.sh-t chmod 0755 test-console-centos-7.2.sh-t mv test-console-centos-7.2.sh-t test-console-centos-7.2.sh chmod 0755 test-console-rhel-6.8.sh-t rm -f test-console-rhel-7.2.sh test-console-rhel-7.2.sh-t mv test-console-rhel-6.8.sh-t test-console-rhel-6.8.sh f=`echo "test-console-rhel-7.2.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-rhel-7.2.sh exec $srcdir/test-console.sh' "$f" > test-console-rhel-7.2.sh-t rm -f test-console-debian-7.sh test-console-debian-7.sh-t f=`echo "test-console-debian-7.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-debian-7.sh exec $srcdir/test-console.sh' "$f" > test-console-debian-7.sh-t chmod 0755 test-console-rhel-7.2.sh-t mv test-console-rhel-7.2.sh-t test-console-rhel-7.2.sh chmod 0755 test-console-debian-7.sh-t rm -f test-console-debian-8.sh test-console-debian-8.sh-t mv test-console-debian-7.sh-t test-console-debian-7.sh f=`echo "test-console-debian-8.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-debian-8.sh exec $srcdir/test-console.sh' "$f" > test-console-debian-8.sh-t rm -f test-console-fedora-24.sh test-console-fedora-24.sh-t f=`echo "test-console-fedora-24.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-fedora-24.sh exec $srcdir/test-console.sh' "$f" > test-console-fedora-24.sh-t chmod 0755 test-console-debian-8.sh-t mv test-console-debian-8.sh-t test-console-debian-8.sh rm -f test-console-ubuntu-12.04.sh test-console-ubuntu-12.04.sh-t f=`echo "test-console-ubuntu-12.04.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-ubuntu-12.04.sh exec $srcdir/test-console.sh' "$f" > test-console-ubuntu-12.04.sh-t chmod 0755 test-console-fedora-24.sh-t mv test-console-fedora-24.sh-t test-console-fedora-24.sh rm -f test-console-ubuntu-14.04.sh test-console-ubuntu-14.04.sh-t f=`echo "test-console-ubuntu-14.04.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-ubuntu-14.04.sh exec $srcdir/test-console.sh' "$f" > test-console-ubuntu-14.04.sh-t chmod 0755 test-console-ubuntu-12.04.sh-t mv test-console-ubuntu-12.04.sh-t test-console-ubuntu-12.04.sh rm -f test-console-ubuntu-16.04.sh test-console-ubuntu-16.04.sh-t f=`echo "test-console-ubuntu-16.04.sh" | /usr/bin/sed 's/test-console-\(.*\).sh/\1/'`; \ echo 'script=test-console-ubuntu-16.04.sh exec $srcdir/test-console.sh' "$f" > test-console-ubuntu-16.04.sh-t chmod 0755 test-console-ubuntu-14.04.sh-t mv test-console-ubuntu-14.04.sh-t test-console-ubuntu-14.04.sh chmod 0755 test-console-ubuntu-16.04.sh-t mv test-console-ubuntu-16.04.sh-t test-console-ubuntu-16.04.sh PASS: test-virt-index-validate.sh SKIP: test-virt-builder-planner.sh PASS: test-virt-builder-docs.sh PASS: test-virt-builder-list.sh PASS: test-virt-builder-list-simplestreams.sh PASS: yajl_tests SKIP: test-console-centos-7.2.sh SKIP: test-console-rhel-7.2.sh SKIP: test-console-rhel-6.8.sh SKIP: test-console-debian-7.sh SKIP: test-console-fedora-24.sh SKIP: test-console-debian-8.sh SKIP: test-console-ubuntu-12.04.sh SKIP: test-console-ubuntu-14.04.sh SKIP: test-console-ubuntu-16.04.sh PASS: test-virt-builder.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 16 # PASS: 6 # SKIP: 10 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder' Making check in builder/templates make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder/templates' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder/templates' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/builder/templates' PASS: validate.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder/templates' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder/templates' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/builder/templates' Making check in get-kernel make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/get-kernel' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/get-kernel' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/get-kernel' PASS: test-virt-get-kernel-docs.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/get-kernel' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/get-kernel' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/get-kernel' Making check in resize make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/resize' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/resize' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/resize' PASS: test-virt-resize-docs.sh PASS: test-virt-resize.pl ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 2 # PASS: 2 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/resize' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/resize' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/resize' Making check in sparsify make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/sparsify' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/sparsify' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/sparsify' PASS: test-virt-sparsify-docs.sh PASS: test-virt-sparsify-in-place.sh PASS: test-virt-sparsify.sh PASS: test-virt-sparsify-in-place-fstrim-unsupported.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 4 # PASS: 4 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/sparsify' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/sparsify' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/sparsify' Making check in sysprep make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/sysprep' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/sysprep' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/sysprep' PASS: test-virt-sysprep-docs.sh PASS: test-virt-sysprep-passwords.sh PASS: test-virt-sysprep-backup-files.sh PASS: test-virt-sysprep.sh PASS: test-virt-sysprep-script.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 5 # PASS: 5 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/sysprep' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/sysprep' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/sysprep' Making check in v2v make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/v2v' make v2v_unit_tests windows.vmdk make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/v2v' CC v2v_unit_tests-libvirt_utils-c.o CC v2v_unit_tests-qemuopts-c.o rm -f windows.vmdk windows.vmdk-t OCAMLOPT v2v_unit_tests.cmx if [ -s ../test-data/phony-guests/windows.img ]; then \ qemu-img convert -f raw ../test-data/phony-guests/windows.img -O vmdk windows.vmdk-t; \ mv windows.vmdk-t windows.vmdk; \ else \ touch windows.vmdk; \ fi GEN v2v_unit_tests make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/v2v' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/v2v' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/v2v' PASS: test-v2v-docs.sh PASS: test-v2v-i-ova-good-checksums.sh PASS: test-v2v-i-ova-bad-sha1.sh PASS: test-v2v-i-ova-bad-sha256.sh PASS: test-v2v-i-ova-formats.sh PASS: test-v2v-i-ova-invalid-manifest2.sh PASS: test-v2v-i-ova-invalid-manifest1.sh PASS: test-v2v-i-ova-gz.sh PASS: test-v2v-i-ova-subfolders.sh PASS: test-v2v-i-ova-tar.sh PASS: test-v2v-copy-to-local.sh PASS: test-v2v-i-vmx.sh PASS: test-v2v-i-ova-two-disks.sh PASS: v2v_unit_tests PASS: test-v2v-bad-networks-and-bridges.sh PASS: test-v2v-machine-readable.sh PASS: test-v2v-i-disk.sh PASS: test-v2v-i-ova.sh PASS: test-v2v-cdrom.sh PASS: test-v2v-windows-conversion.sh PASS: test-v2v-virtio-win-iso.sh PASS: test-v2v-floppy.sh PASS: test-v2v-networks-and-bridges.sh PASS: test-v2v-in-place.sh PASS: test-v2v-o-glance.sh PASS: test-v2v-o-null.sh PASS: test-v2v-o-libvirt.sh PASS: test-v2v-no-copy.sh PASS: test-v2v-o-qemu.sh PASS: test-v2v-o-rhv.sh PASS: test-v2v-o-vdsm-options.sh PASS: test-v2v-print-source.sh rm -f test-v2v-conversion-of-centos-6.sh test-v2v-conversion-of-centos-6.sh-t f=`echo "test-v2v-conversion-of-centos-6.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-centos-6.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-centos-6.sh-t chmod 0755 test-v2v-conversion-of-centos-6.sh-t mv test-v2v-conversion-of-centos-6.sh-t test-v2v-conversion-of-centos-6.sh rm -f test-v2v-conversion-of-centos-7.0.sh test-v2v-conversion-of-centos-7.0.sh-t f=`echo "test-v2v-conversion-of-centos-7.0.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-centos-7.0.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-centos-7.0.sh-t chmod 0755 test-v2v-conversion-of-centos-7.0.sh-t mv test-v2v-conversion-of-centos-7.0.sh-t test-v2v-conversion-of-centos-7.0.sh rm -f test-v2v-conversion-of-debian-6.sh test-v2v-conversion-of-debian-6.sh-t f=`echo "test-v2v-conversion-of-debian-6.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-debian-6.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-debian-6.sh-t chmod 0755 test-v2v-conversion-of-debian-6.sh-t mv test-v2v-conversion-of-debian-6.sh-t test-v2v-conversion-of-debian-6.sh rm -f test-v2v-conversion-of-debian-7.sh test-v2v-conversion-of-debian-7.sh-t f=`echo "test-v2v-conversion-of-debian-7.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-debian-7.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-debian-7.sh-t chmod 0755 test-v2v-conversion-of-debian-7.sh-t mv test-v2v-conversion-of-debian-7.sh-t test-v2v-conversion-of-debian-7.sh rm -f test-v2v-conversion-of-debian-8.sh test-v2v-conversion-of-debian-8.sh-t f=`echo "test-v2v-conversion-of-debian-8.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-debian-8.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-debian-8.sh-t chmod 0755 test-v2v-conversion-of-debian-8.sh-t mv test-v2v-conversion-of-debian-8.sh-t test-v2v-conversion-of-debian-8.sh rm -f test-v2v-conversion-of-fedora-20.sh test-v2v-conversion-of-fedora-20.sh-t f=`echo "test-v2v-conversion-of-fedora-20.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-fedora-20.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-fedora-20.sh-t chmod 0755 test-v2v-conversion-of-fedora-20.sh-t mv test-v2v-conversion-of-fedora-20.sh-t test-v2v-conversion-of-fedora-20.sh rm -f test-v2v-conversion-of-fedora-23.sh test-v2v-conversion-of-fedora-23.sh-t f=`echo "test-v2v-conversion-of-fedora-23.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-fedora-23.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-fedora-23.sh-t chmod 0755 test-v2v-conversion-of-fedora-23.sh-t mv test-v2v-conversion-of-fedora-23.sh-t test-v2v-conversion-of-fedora-23.sh rm -f test-v2v-conversion-of-rhel-5.10.sh test-v2v-conversion-of-rhel-5.10.sh-t f=`echo "test-v2v-conversion-of-rhel-5.10.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-5.10.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-5.10.sh-t chmod 0755 test-v2v-conversion-of-rhel-5.10.sh-t mv test-v2v-conversion-of-rhel-5.10.sh-t test-v2v-conversion-of-rhel-5.10.sh rm -f test-v2v-conversion-of-rhel-6.8.sh test-v2v-conversion-of-rhel-6.8.sh-t f=`echo "test-v2v-conversion-of-rhel-6.8.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-6.8.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-6.8.sh-t chmod 0755 test-v2v-conversion-of-rhel-6.8.sh-t mv test-v2v-conversion-of-rhel-6.8.sh-t test-v2v-conversion-of-rhel-6.8.sh rm -f test-v2v-conversion-of-rhel-7.0.sh test-v2v-conversion-of-rhel-7.0.sh-t f=`echo "test-v2v-conversion-of-rhel-7.0.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-7.0.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-7.0.sh-t chmod 0755 test-v2v-conversion-of-rhel-7.0.sh-t mv test-v2v-conversion-of-rhel-7.0.sh-t test-v2v-conversion-of-rhel-7.0.sh rm -f test-v2v-conversion-of-rhel-7.2.sh test-v2v-conversion-of-rhel-7.2.sh-t f=`echo "test-v2v-conversion-of-rhel-7.2.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-rhel-7.2.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-rhel-7.2.sh-t chmod 0755 test-v2v-conversion-of-rhel-7.2.sh-t mv test-v2v-conversion-of-rhel-7.2.sh-t test-v2v-conversion-of-rhel-7.2.sh rm -f test-v2v-conversion-of-ubuntu-10.04.sh test-v2v-conversion-of-ubuntu-10.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-10.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-10.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-10.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-10.04.sh-t mv test-v2v-conversion-of-ubuntu-10.04.sh-t test-v2v-conversion-of-ubuntu-10.04.sh rm -f test-v2v-conversion-of-ubuntu-12.04.sh test-v2v-conversion-of-ubuntu-12.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-12.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-12.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-12.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-12.04.sh-t mv test-v2v-conversion-of-ubuntu-12.04.sh-t test-v2v-conversion-of-ubuntu-12.04.sh rm -f test-v2v-conversion-of-ubuntu-14.04.sh test-v2v-conversion-of-ubuntu-14.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-14.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-14.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-14.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-14.04.sh-t mv test-v2v-conversion-of-ubuntu-14.04.sh-t test-v2v-conversion-of-ubuntu-14.04.sh rm -f test-v2v-conversion-of-ubuntu-16.04.sh test-v2v-conversion-of-ubuntu-16.04.sh-t f=`echo "test-v2v-conversion-of-ubuntu-16.04.sh" | /usr/bin/sed 's/test-v2v-conversion-of-\(.*\).sh/\1/'`; \ echo 'script=test-v2v-conversion-of-ubuntu-16.04.sh exec $srcdir/test-v2v-conversion-of.sh' "$f" > test-v2v-conversion-of-ubuntu-16.04.sh-t chmod 0755 test-v2v-conversion-of-ubuntu-16.04.sh-t mv test-v2v-conversion-of-ubuntu-16.04.sh-t test-v2v-conversion-of-ubuntu-16.04.sh PASS: test-v2v-oa-option.sh SKIP: test-v2v-trim.sh SKIP: test-v2v-i-ova-as-root.sh SKIP: test-v2v-conversion-of-centos-6.sh SKIP: test-v2v-conversion-of-centos-7.0.sh PASS: test-v2v-of-option.sh SKIP: test-v2v-conversion-of-debian-6.sh SKIP: test-v2v-conversion-of-debian-7.sh SKIP: test-v2v-conversion-of-debian-8.sh SKIP: test-v2v-conversion-of-fedora-20.sh SKIP: test-v2v-conversion-of-fedora-23.sh SKIP: test-v2v-conversion-of-rhel-5.10.sh SKIP: test-v2v-conversion-of-rhel-6.8.sh SKIP: test-v2v-conversion-of-rhel-7.0.sh SKIP: test-v2v-conversion-of-rhel-7.2.sh SKIP: test-v2v-conversion-of-ubuntu-10.04.sh SKIP: test-v2v-conversion-of-ubuntu-12.04.sh SKIP: test-v2v-conversion-of-ubuntu-14.04.sh SKIP: test-v2v-conversion-of-ubuntu-16.04.sh PASS: test-v2v-on-option.sh PASS: test-v2v-sound.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 53 # PASS: 36 # SKIP: 17 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/v2v' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/v2v' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/v2v' Making check in v2v/test-harness make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/v2v/test-harness' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/v2v/test-harness' Making check in dib make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/dib' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/dib' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/dib' PASS: test-virt-dib-docs.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/dib' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/dib' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/dib' Making check in tools make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/tools' for f in tools/virt-list-filesystems tools/virt-list-partitions tools/virt-tar tools/virt-win-reg; do echo $f; done > ../po/POTFILES-pl make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/tools' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/tools' PASS: test-virt-list-filesystems.sh PASS: test-virt-tar.sh ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 2 # PASS: 2 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/tools' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/tools' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/tools' Making check in fuse make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/fuse' make test-fuse test-guestmount-fd test-guestunmount-fd make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/fuse' CC test_fuse-test-fuse.o CC test_guestmount_fd-test-guestmount-fd.o CC test_guestunmount_fd-test-guestunmount-fd.o CCLD test-guestunmount-fd CCLD test-guestmount-fd CCLD test-fuse make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/fuse' make check-TESTS make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/fuse' make[3]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/fuse' SKIP: test-fuse-umount-race.sh PASS: test-guestunmount-not-mounted.sh PASS: test-docs.sh SKIP: /var/tmp/tmp2lYq06/libguestfs/fuse/.libs/lt-test-guestmount-fd PASS: /var/tmp/tmp2lYq06/libguestfs/fuse/.libs/lt-test-guestunmount-fd PASS: /var/tmp/tmp2lYq06/libguestfs/fuse/.libs/lt-test-fuse ===========================================================================Testsuite summary for libguestfs 1.37.18 ===========================================================================# TOTAL: 6 # PASS: 4 # SKIP: 2 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ===========================================================================make[3]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/fuse' make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/fuse' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/fuse' Making check in utils/boot-analysis make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/utils/boot-analysis' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/utils/boot-analysis' Making check in utils/boot-benchmark make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/utils/boot-benchmark' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/utils/boot-benchmark' Making check in utils/qemu-boot make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/utils/qemu-boot' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/utils/qemu-boot' Making check in utils/qemu-speed-test make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/utils/qemu-speed-test' make[1]: Nothing to be done for 'check'. make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/utils/qemu-speed-test' Making check in po-docs make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/po-docs' Making check in ja make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/po-docs/ja' make[2]: Nothing to be done for 'check'. make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/po-docs/ja' Making check in uk make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/po-docs/uk' make[2]: Nothing to be done for 'check'. make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/po-docs/uk' make[2]: Entering directory '/var/tmp/tmp2lYq06/libguestfs/po-docs' make[2]: Nothing to be done for 'check-am'. make[2]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/po-docs' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs/po-docs' make[1]: Entering directory '/var/tmp/tmp2lYq06/libguestfs' make[1]: Leaving directory '/var/tmp/tmp2lYq06/libguestfs'
Possibly Parallel Threads
- [PATCH v3 0/5] threads: Add support for thread-safe handle.
- [PATCH threads v2 0/5] Add support for thread-safe handle.
- [PATCH 0/5] Add support for thread-safe handle.
- [PATCH v3 3/5] threads: Use thread-local storage for errors.
- [PATCH 3/5] threads: Use thread-local storage for errors.