handle: Improve error messaging if XDG_RUNTIME_DIR path does not exist.

If an environment variable such as XDG_RUNTIME_DIR or one of the
tmpdirs or cachedir is set to a non-existent directory, improve the
error message that the user will see so that (where possible) it
includes the environment variable or API call.

This is still not bullet-proof because it's hard to display the
environment variable if it is LIBGUESTFS_TMPDIR or
LIBGUESTFS_CACHEDIR, but the main problem is with XDG_RUNTIME_DIR
(because of systemd bugs).

Thanks: Hilko Bengen for identifying the bug.
This commit is contained in:
Richard W.M. Jones
2016-10-31 08:47:15 +00:00
parent a8b206234c
commit c7ce5e47fa
3 changed files with 24 additions and 14 deletions

View File

@@ -803,8 +803,8 @@ extern void guestfs_int_call_callbacks_message (guestfs_h *g, uint64_t event, co
extern void guestfs_int_call_callbacks_array (guestfs_h *g, uint64_t event, const uint64_t *array, size_t array_len);
/* tmpdirs.c */
extern int guestfs_int_set_env_tmpdir (guestfs_h *g, const char *tmpdir);
extern int guestfs_int_set_env_runtimedir (guestfs_h *g, const char *runtimedir);
extern int guestfs_int_set_env_tmpdir (guestfs_h *g, const char *envname, const char *tmpdir);
extern int guestfs_int_set_env_runtimedir (guestfs_h *g, const char *envname, const char *runtimedir);
extern int guestfs_int_lazy_make_tmpdir (guestfs_h *g);
extern int guestfs_int_lazy_make_sockdir (guestfs_h *g);
extern char *guestfs_int_lazy_make_supermin_appliance_dir (guestfs_h *g);

View File

@@ -218,7 +218,7 @@ parse_environment (guestfs_h *g,
}
str = do_getenv (data, "TMPDIR");
if (guestfs_int_set_env_tmpdir (g, str) == -1)
if (guestfs_int_set_env_tmpdir (g, "TMPDIR", str) == -1)
return -1;
str = do_getenv (data, "LIBGUESTFS_PATH");
@@ -277,7 +277,7 @@ parse_environment (guestfs_h *g,
}
str = do_getenv (data, "XDG_RUNTIME_DIR");
if (guestfs_int_set_env_runtimedir (g, str) == -1)
if (guestfs_int_set_env_runtimedir (g, "XDG_RUNTIME_DIR", str) == -1)
return -1;
return 0;

View File

@@ -39,9 +39,14 @@
* We need to make all tmpdir paths absolute because lots of places in
* the code assume this. Do it at the time we set the path or read
* the environment variable (L<https://bugzilla.redhat.com/882417>).
*
* The C<ctxstr> parameter is a string displayed in error messages
* giving the context of the operation (eg. name of environment
* variable being used, or API function being called).
*/
static int
set_abs_path (guestfs_h *g, const char *tmpdir, char **tmpdir_ret)
set_abs_path (guestfs_h *g, const char *ctxstr,
const char *tmpdir, char **tmpdir_ret)
{
char *ret;
struct stat statbuf;
@@ -57,17 +62,20 @@ set_abs_path (guestfs_h *g, const char *tmpdir, char **tmpdir_ret)
ret = realpath (tmpdir, NULL);
if (ret == NULL) {
perrorf (g, _("failed to set temporary directory: %s"), tmpdir);
perrorf (g, _("converting path to absolute path: %s: %s: realpath"),
ctxstr, tmpdir);
return -1;
}
if (stat (ret, &statbuf) == -1) {
perrorf (g, _("failed to set temporary directory: %s"), tmpdir);
perrorf (g, "%s: %s: %s: stat",
_("setting temporary directory"), ctxstr, tmpdir);
return -1;
}
if (!S_ISDIR (statbuf.st_mode)) {
error (g, _("temporary directory '%s' is not a directory"), tmpdir);
error (g, _("%s: %s: '%s' is not a directory"),
_("setting temporary directory"), ctxstr, tmpdir);
return -1;
}
@@ -76,21 +84,23 @@ set_abs_path (guestfs_h *g, const char *tmpdir, char **tmpdir_ret)
}
int
guestfs_int_set_env_tmpdir (guestfs_h *g, const char *tmpdir)
guestfs_int_set_env_tmpdir (guestfs_h *g, const char *envname,
const char *tmpdir)
{
return set_abs_path (g, tmpdir, &g->env_tmpdir);
return set_abs_path (g, envname, tmpdir, &g->env_tmpdir);
}
int
guestfs_int_set_env_runtimedir (guestfs_h *g, const char *runtimedir)
guestfs_int_set_env_runtimedir (guestfs_h *g, const char *envname,
const char *runtimedir)
{
return set_abs_path (g, runtimedir, &g->env_runtimedir);
return set_abs_path (g, envname, runtimedir, &g->env_runtimedir);
}
int
guestfs_impl_set_tmpdir (guestfs_h *g, const char *tmpdir)
{
return set_abs_path (g, tmpdir, &g->int_tmpdir);
return set_abs_path (g, "set_tmpdir", tmpdir, &g->int_tmpdir);
}
/**
@@ -117,7 +127,7 @@ guestfs_impl_get_tmpdir (guestfs_h *g)
int
guestfs_impl_set_cachedir (guestfs_h *g, const char *cachedir)
{
return set_abs_path (g, cachedir, &g->int_cachedir);
return set_abs_path (g, "set_cachedir", cachedir, &g->int_cachedir);
}
/**