New API: set-backend-settings, get-backend-settings.

Allow settings (an arbitrary list of strings) to be passed to the
current backend.  This will allow us to tweak how the backend works,
eg. by forcing TCG.
This commit is contained in:
Richard W.M. Jones
2014-01-18 15:33:10 +00:00
parent 815e739d12
commit 1e4663858b
8 changed files with 162 additions and 0 deletions

View File

@@ -1413,6 +1413,11 @@ This is the old way to set C<LIBGUESTFS_BACKEND>.
Choose the default way to create the appliance. See
L<guestfs(3)/guestfs_set_backend>.
=item LIBGUESTFS_BACKEND_SETTINGS
A colon-separated list of backend-specific settings.
See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>.
=item LIBGUESTFS_CACHEDIR
The location where libguestfs will cache its appliance, when

View File

@@ -3060,6 +3060,39 @@ If you set the data threshold to unlimited (C<0>) then this call
can read a journal entry of any size, ie. it is not limited by
the libguestfs protocol." };
{ defaults with
name = "set_backend_settings";
style = RErr, [StringList "settings"], [];
config_only = true;
blocking = false;
shortdesc = "set per-backend settings";
longdesc = "\
Set a list of zero or more settings which are passed through to
the current backend. Each setting is a string which is interpreted
in a backend-specific way, or ignored if not understood by the
backend.
The default value is an empty list, unless the environment
variable C<LIBGUESTFS_BACKEND_SETTINGS> was set when the handle
was created. This environment variable contains a colon-separated
list of settings.
See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
{ defaults with
name = "get_backend_settings";
style = RStringList "settings", [], [];
blocking = false;
tests = [
InitNone, Always, TestRun (
[["get_backend_settings"]]), []
];
shortdesc = "get per-backend settings";
longdesc = "\
Return the current backend settings.
See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
]
(* daemon_functions are any functions which cause some action

View File

@@ -46,6 +46,7 @@
#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
#define STRCASEPREFIX(a,b) (strncasecmp((a),(b),strlen((b))) == 0)
#define STRSUFFIX(a,b) (strlen((a)) >= strlen((b)) && STREQ((a)+strlen((a))-strlen((b)),(b)))
#ifndef SOCK_CLOEXEC

View File

@@ -407,6 +407,7 @@ struct guestfs_h
char *backend_arg; /* Pointer to the argument part. */
const struct backend_ops *backend_ops;
void *backend_data; /* Per-handle data. */
char **backend_settings; /* Backend settings (can be NULL). */
/**** Runtime information. ****/
char *last_error; /* Last error on handle. */
@@ -724,6 +725,8 @@ extern char *guestfs___appliance_command_line (guestfs_h *g, const char *applian
#define APPLIANCE_COMMAND_LINE_IS_TCG 1
extern void guestfs___register_backend (const char *name, const struct backend_ops *);
extern int guestfs___set_backend (guestfs_h *g, const char *method);
extern const char *guestfs___get_backend_setting (guestfs_h *g, const char *name);
extern int guestfs___get_backend_setting_bool (guestfs_h *g, const char *name);
/* inspect.c */
extern void guestfs___free_inspect_info (guestfs_h *g);

View File

@@ -1483,6 +1483,13 @@ backend, do:
unset LIBGUESTFS_BACKEND
guestfish get-backend
=head2 BACKEND SETTINGS
Each backend can be configured by passing a list of strings. You can
either call L</guestfs_set_backend_settings> with a list of strings,
or set the C<LIBGUESTFS_BACKEND_SETTINGS> environment variable to a
colon-separated list of strings (before creating the handle).
=head2 ATTACHING TO RUNNING DAEMONS
I<Note (1):> This is B<highly experimental> and has a tendency to eat
@@ -4613,6 +4620,11 @@ This is the old way to set C<LIBGUESTFS_BACKEND>.
Choose the default way to create the appliance. See
L</guestfs_set_backend> and L</BACKEND>.
=item LIBGUESTFS_BACKEND_SETTINGS
A colon-separated list of backend-specific settings.
See L</BACKEND>, L</BACKEND SETTINGS>.
=item LIBGUESTFS_CACHEDIR
The location where libguestfs will cache its appliance, when

View File

@@ -245,6 +245,19 @@ parse_environment (guestfs_h *g,
}
}
str = do_getenv (data, "LIBGUESTFS_BACKEND_SETTINGS");
if (str && STRNEQ (str, "")) {
CLEANUP_FREE_STRING_LIST char **settings = guestfs___split_string (':', str);
if (settings == NULL) {
perrorf (g, "split_string: malloc");
return -1;
}
if (guestfs_set_backend_settings (g, settings) == -1)
return -1;
}
return 0;
}
@@ -673,6 +686,42 @@ guestfs__get_attach_method (guestfs_h *g)
return guestfs_get_backend (g);
}
int
guestfs__set_backend_settings (guestfs_h *g, char *const *settings)
{
char **copy;
copy = guestfs___copy_string_list (settings);
if (copy == NULL) {
perrorf (g, "copy: malloc");
return -1;
}
guestfs___free_string_list (g->backend_settings);
g->backend_settings = copy;
return 0;
}
char **
guestfs__get_backend_settings (guestfs_h *g)
{
char *empty_list[1] = { NULL };
char **ret;
if (g->backend_settings == NULL)
ret = guestfs___copy_string_list (empty_list);
else
ret = guestfs___copy_string_list (g->backend_settings);
if (ret == NULL) {
perrorf (g, "copy: malloc");
return NULL;
}
return ret; /* caller frees */
}
int
guestfs__set_pgroup (guestfs_h *g, int v)
{

View File

@@ -481,3 +481,51 @@ guestfs___set_backend (guestfs_h *g, const char *method)
return 0;
}
/* Convenience functions for backends to read settings. */
/* Return the string value of a setting, or NULL if not set. */
const char *
guestfs___get_backend_setting (guestfs_h *g, const char *name)
{
char **settings = g->backend_settings;
size_t namelen = strlen (name);
size_t i;
if (settings == NULL)
return NULL;
for (i = 0; settings[i] != NULL; ++i) {
if (STRCASEEQ (settings[i], name))
return ""; /* setting exists, no value */
if (STRCASEPREFIX (settings[i], name) && settings[i][namelen] == '=')
return &settings[i][namelen+1]; /* "name=...", return value */
}
return NULL;
}
/* If there a setting "name", "name=1", etc? This is similar to
* fish/fish.c:is_true.
*/
int
guestfs___get_backend_setting_bool (guestfs_h *g, const char *name)
{
const char *value = guestfs___get_backend_setting (g, name);
if (value == NULL)
return 0;
if (STREQ (value, ""))
return 1;
if (STREQ (value, "1") ||
STRCASEEQ (value, "true") ||
STRCASEEQ (value, "t") ||
STRCASEEQ (value, "yes") ||
STRCASEEQ (value, "y") ||
STRCASEEQ (value, "on"))
return 1;
return 0;
}

View File

@@ -90,6 +90,7 @@ main (int argc, char *argv[])
size_t i;
struct guestfs_version *vers;
char *p;
char **pp;
guestfs_h *g;
char *qemu = NULL;
int qemu_use_wrapper;
@@ -230,6 +231,16 @@ main (int argc, char *argv[])
p = guestfs_get_backend (g);
printf ("guestfs_get_backend: %s\n", p ? : "(null)");
free (p);
pp = guestfs_get_backend_settings (g);
printf ("guestfs_get_backend_settings: [");
for (i = 0; pp[i] != NULL; ++i) {
if (i > 0)
printf (", ");
printf ("%s", pp[i]);
free (pp[i]);
}
printf ("]\n");
free (pp);
printf ("guestfs_get_autosync: %d\n", guestfs_get_autosync (g));
p = guestfs_get_cachedir (g);
printf ("guestfs_get_cachedir: %s\n", p ? : "(null)");