New APIs: set-identifier, get-identifier

Add a per-handle identifier.  The main effect of this is to change
trace output from:

  libguestfs: trace: foo

to:

  libguestfs: trace: ID: foo

which makes it simpler to follow traces from multi-threaded programs.
This commit is contained in:
Richard W.M. Jones
2015-10-07 17:53:58 +01:00
parent 5f352f6eea
commit f6e13aeb65
5 changed files with 89 additions and 2 deletions

View File

@@ -3369,6 +3369,49 @@ To download to the current directory, use C<.> as in:
Wildcards cannot be used." };
{ defaults with
name = "set_identifier"; added = (1, 31, 14);
style = RErr, [String "identifier"], [];
fish_alias = ["identifier"];
blocking = false;
shortdesc = "set the handle identifier";
longdesc = "\
This is an informative string which the caller may optionally
set in the handle. It is printed in various places, allowing
the current handle to be identified in debugging output.
One important place is when tracing is enabled. If the
identifier string is not an empty string, then trace messages
change from this:
libguestfs: trace: get_tmpdir
libguestfs: trace: get_tmpdir = \"/tmp\"
to this:
libguestfs: trace: ID: get_tmpdir
libguestfs: trace: ID: get_tmpdir = \"/tmp\"
where C<ID> is the identifier string set by this call.
The identifier must only contain alphanumeric ASCII characters,
underscore and minus sign. The default is the empty string.
See also C<guestfs_set_program>, C<guestfs_set_trace>,
C<guestfs_get_identifier>." };
{ defaults with
name = "get_identifier"; added = (1, 31, 14);
style = RConstString "identifier", [], [];
blocking = false;
tests = [
InitNone, Always, TestRun (
[["get_identifier"]]), []
];
shortdesc = "get the handle identifier";
longdesc = "\
Get the handle identifier. See C<guestfs_set_identifier>." };
]
(* daemon_functions are any functions which cause some action

View File

@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "c-ctype.h"
@@ -136,7 +137,7 @@ guestfs_int_call_callbacks_message (guestfs_h *g, uint64_t event,
/* APPLIANCE => <buf>
* LIBRARY => libguestfs: <buf>\n
* WARNING => libguestfs: warning: <buf>\n
* TRACE => libguestfs: trace: <buf>\n (RHBZ#673479)
* TRACE => libguestfs: trace: [<ID>:] <buf>\n (RHBZ#673479)
*/
if (event != GUESTFS_EVENT_APPLIANCE)
@@ -145,8 +146,13 @@ guestfs_int_call_callbacks_message (guestfs_h *g, uint64_t event,
if (event == GUESTFS_EVENT_WARNING)
fputs ("warning: ", stderr);
if (event == GUESTFS_EVENT_TRACE)
if (event == GUESTFS_EVENT_TRACE) {
fputs ("trace: ", stderr);
if (STRNEQ (g->identifier, "")) {
fputs (g->identifier, stderr);
fputs (": ", stderr);
}
}
/* Special or non-printing characters in the buffer must be
* escaped (RHBZ#731744). The buffer can contain any 8 bit

View File

@@ -371,6 +371,7 @@ struct guestfs_h
struct hv_param *hv_params; /* Extra hv parameters. */
char *program; /* Program name. */
char *identifier; /* Handle identifier. */
/* Array of drives added by add-drive* APIs.
*

View File

@@ -32,6 +32,7 @@
#include "glthread/lock.h"
#include "ignore-value.h"
#include "c-ctype.h"
#include "guestfs.h"
#include "guestfs-internal.h"
@@ -128,6 +129,9 @@ guestfs_create_flags (unsigned flags, ...)
#endif
if (!g->program) goto error;
g->identifier = strdup ("");
if (!g->identifier) goto error;
if (guestfs_int_set_backend (g, DEFAULT_BACKEND) == -1) {
warning (g, _("libguestfs was built with an invalid default backend, using 'direct' instead"));
if (guestfs_int_set_backend (g, "direct") == -1) {
@@ -666,6 +670,34 @@ guestfs_impl_get_program (guestfs_h *g)
return g->program;
}
int
guestfs_impl_set_identifier (guestfs_h *g, const char *identifier)
{
size_t i, len;
/* Check the identifier contains only permitted characters. */
len = strlen (identifier);
for (i = 0; i < len; ++i) {
char c = identifier[i];
if (!c_isalnum (c) && c != '_' && c != '-') {
error (g, _("identifier must contain only alphanumeric characters, underscore or minus sign"));
return -1;
}
}
free (g->identifier);
g->identifier = safe_strdup (g, identifier);
return 0;
}
const char *
guestfs_impl_get_identifier (guestfs_h *g)
{
return g->identifier;
}
int
guestfs_impl_set_backend (guestfs_h *g, const char *method)
{

View File

@@ -75,6 +75,8 @@ guestfs_impl_launch (guestfs_h *g)
CLEANUP_FREE char *backend = guestfs_get_backend (g);
debug (g, "launch: program=%s", g->program);
if (STRNEQ (g->identifier, ""))
debug (g, "launch: identifier=%s", g->identifier);
debug (g, "launch: version=%"PRIi64".%"PRIi64".%"PRIi64"%s",
v->major, v->minor, v->release, v->extra);
@@ -359,6 +361,7 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev,
"%s" /* verbose */
"%s" /* network */
" TERM=%s" /* TERM environment variable */
"%s%s" /* handle identifier */
"%s%s", /* append */
#ifdef __arm__
g->memsize,
@@ -369,6 +372,8 @@ guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev,
g->verbose ? " guestfs_verbose=1" : "",
g->enable_network ? " guestfs_network=1" : "",
term ? term : "linux",
STRNEQ (g->identifier, "") ? " guestfs_identifier=" : "",
g->identifier,
g->append ? " " : "", g->append ? g->append : "");
return ret;