[Libguestfs] [PATCH 3/3] New API: get-sockdir

Richard W.M. Jones rjones at redhat.com
Wed Feb 3 10:31:20 UTC 2016


On Tue, Feb 02, 2016 at 03:27:41PM +0100, Pino Toscano wrote:
> Introduce a new read-only API to get a path where to store temporary
> sockets: this is different than tmpdir, as we need short paths for
> sockets (due to sockaddr_un::sun_path), and is either XDG_RUNTIME_DIR
> if set, or /tmp.
> 
> Adapt guestfs_int_create_socketname to create sockets in that location,
> checking whether the resulting path still fits in the limited buffer.
> 
> Furthermore, print sockdir and XDG_RUNTIME_DIR in test-tool for
> debugging.
> ---
>  fish/guestfish.pod     | 11 +++++++++++
>  generator/actions.ml   | 16 ++++++++++++++++
>  src/guestfs-internal.h |  7 ++++++-
>  src/handle.c           |  9 ++++++++-
>  src/launch.c           | 10 ++++++++--
>  src/tmpdirs.c          | 33 +++++++++++++++++++++++++++++++++
>  test-tool/test-tool.c  |  6 ++++++
>  7 files changed, 88 insertions(+), 4 deletions(-)
> 
> diff --git a/fish/guestfish.pod b/fish/guestfish.pod
> index c6f5663..bbeea82 100644
> --- a/fish/guestfish.pod
> +++ b/fish/guestfish.pod
> @@ -1519,6 +1519,17 @@ about kernel selection, see L<supermin(1)>.
>  
>  See L</LIBGUESTFS_CACHEDIR>, L</LIBGUESTFS_TMPDIR>.
>  
> +=item XDG_RUNTIME_DIR
> +
> +This directory represents a user-specific directory for storing
> +non-essential runtime files.
> +
> +If it is set, then is used to store temporary sockets.  Otherwise,
> +F</tmp> is used.
> +
> +See also L</get-sockdir>,
> +L<http://www.freedesktop.org/wiki/Specifications/basedir-spec/>.
> +
>  =back

I think this section needs to be duplicated in guestfs(3) too?  Since
both man pages list environment variables.

>  =head1 FILES
> diff --git a/generator/actions.ml b/generator/actions.ml
> index 24c6eb7..5b6898c 100644
> --- a/generator/actions.ml
> +++ b/generator/actions.ml
> @@ -3504,6 +3504,22 @@ call it returns a simple true/false boolean result, instead
>  of throwing an exception if a feature is not found.  For
>  other documentation see C<guestfs_available>." };
>  
> +  { defaults with
> +    name = "get_sockdir"; added = (1, 33, 8);
> +    style = RString "sockdir", [], [];
> +    blocking = false;
> +    shortdesc = "get the temporary directory for sockets";
> +    longdesc = "\
> +Get the directory used by the handle to store temporary socket files.
> +
> +This is different than C<guestfs_tmpdir>, as we need shorter paths for

different from

> +sockets (due to the limited buffers of filenames for UNIX sockets),
> +and C<guestfs_tmpdir> may be too long for them.
> +
> +The environment variable C<XDG_RUNTIME_DIR> controls the default
> +value: If C<XDG_RUNTIME_DIR> is set, then that is the default.
> +Else F</tmp> is the default." };
> +
>  ]
>  
>  (* daemon_functions are any functions which cause some action
> diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
> index bff9f64..6e441e4 100644
> --- a/src/guestfs-internal.h
> +++ b/src/guestfs-internal.h
> @@ -434,8 +434,10 @@ struct guestfs_h
>     * handle, you have to call guestfs_int_lazy_make_tmpdir.
>     */
>    char *tmpdir;
> -  /* Environment variables that affect tmpdir/cachedir locations. */
> +  char *sockdir;
> +  /* Environment variables that affect tmpdir/cachedir/sockdir locations. */
>    char *env_tmpdir;             /* $TMPDIR (NULL if not set) */
> +  char *env_runtimedir;         /* $XDG_RUNTIME_DIR (NULL if not set)*/
>    char *int_tmpdir;   /* $LIBGUESTFS_TMPDIR or guestfs_set_tmpdir or NULL */
>    char *int_cachedir; /* $LIBGUESTFS_CACHEDIR or guestfs_set_cachedir or NULL */
>  
> @@ -757,8 +759,11 @@ extern void guestfs_int_call_callbacks_array (guestfs_h *g, uint64_t event, cons
>  
>  /* 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_lazy_make_tmpdir (guestfs_h *g);
> +extern int guestfs_int_lazy_make_sockdir (guestfs_h *g);
>  extern void guestfs_int_remove_tmpdir (guestfs_h *g);
> +extern void guestfs_int_remove_sockdir (guestfs_h *g);
>  extern void guestfs_int_recursive_remove_dir (guestfs_h *g, const char *dir);
>  
>  /* whole-file.c */
> diff --git a/src/handle.c b/src/handle.c
> index 947818c..25d3c99 100644
> --- a/src/handle.c
> +++ b/src/handle.c
> @@ -273,6 +273,10 @@ parse_environment (guestfs_h *g,
>        return -1;
>    }
>  
> +  str = do_getenv (data, "XDG_RUNTIME_DIR");
> +  if (guestfs_int_set_env_runtimedir (g, str) == -1)
> +    return -1;
> +
>    return 0;
>  }
>  
> @@ -347,8 +351,9 @@ guestfs_close (guestfs_h *g)
>    if (g->test_fp != NULL)
>      fclose (g->test_fp);
>  
> -  /* Remove temporary directory. */
> +  /* Remove temporary directories. */
>    guestfs_int_remove_tmpdir (g);
> +  guestfs_int_remove_sockdir (g);
>  
>    /* Mark the handle as dead and then free up all memory. */
>    g->state = NO_HANDLE;
> @@ -377,7 +382,9 @@ guestfs_close (guestfs_h *g)
>    if (g->pda)
>      hash_free (g->pda);
>    free (g->tmpdir);
> +  free (g->sockdir);
>    free (g->env_tmpdir);
> +  free (g->env_runtimedir);
>    free (g->int_tmpdir);
>    free (g->int_cachedir);
>    free (g->last_error);
> diff --git a/src/launch.c b/src/launch.c
> index ec061e3..e6972d1 100644
> --- a/src/launch.c
> +++ b/src/launch.c
> @@ -425,9 +425,15 @@ int
>  guestfs_int_create_socketname (guestfs_h *g, const char *filename,
>                                 char (*sockpath)[UNIX_PATH_MAX])
>  {
> -  char *path = g->tmpdir;
> +  if (guestfs_int_lazy_make_sockdir (g) == -1)
> +    return -1;
> +
> +  if (strlen (g->sockdir) + 1 + strlen (filename) > UNIX_PATH_MAX-1) {
> +    error (g, _("socket path too long: %s/%s"), g->sockdir, filename);
> +    return -1;
> +  }
>  
> -  snprintf (*sockpath, UNIX_PATH_MAX-1, "%s/%s", path, filename);
> +  snprintf (*sockpath, UNIX_PATH_MAX-1, "%s/%s", g->sockdir, filename);
>    (*sockpath)[UNIX_PATH_MAX-1] = '\0';
>  
>    return 0;
> diff --git a/src/tmpdirs.c b/src/tmpdirs.c
> index 2ae9c74..e66ab9c 100644
> --- a/src/tmpdirs.c
> +++ b/src/tmpdirs.c
> @@ -76,6 +76,12 @@ guestfs_int_set_env_tmpdir (guestfs_h *g, const char *tmpdir)
>  }
>  
>  int
> +guestfs_int_set_env_runtimedir (guestfs_h *g, const char *runtimedir)
> +{
> +  return set_abs_path (g, runtimedir, &g->env_runtimedir);
> +}
> +
> +int
>  guestfs_impl_set_tmpdir (guestfs_h *g, const char *tmpdir)
>  {
>    return set_abs_path (g, tmpdir, &g->int_tmpdir);
> @@ -119,6 +125,20 @@ guestfs_impl_get_cachedir (guestfs_h *g)
>    return safe_strdup (g, str);
>  }
>  
> +/* Note this actually calculates the sockdir, so it never returns NULL. */
> +char *
> +guestfs_impl_get_sockdir (guestfs_h *g)
> +{
> +  const char *str;
> +
> +  if (g->env_runtimedir)
> +    str = g->env_runtimedir;
> +  else
> +    str = "/tmp";
> +
> +  return safe_strdup (g, str);
> +}
> +
>  static int
>  lazy_make_tmpdir (guestfs_h *g, char *(*getdir) (guestfs_h *g), char **dest)
>  {
> @@ -145,6 +165,12 @@ guestfs_int_lazy_make_tmpdir (guestfs_h *g)
>    return lazy_make_tmpdir (g, guestfs_get_tmpdir, &g->tmpdir);
>  }
>  
> +int
> +guestfs_int_lazy_make_sockdir (guestfs_h *g)
> +{
> +  return lazy_make_tmpdir (g, guestfs_get_sockdir, &g->sockdir);
> +}
> +
>  /* Recursively remove a temporary directory.  If removal fails, just
>   * return (it's a temporary directory so it'll eventually be cleaned
>   * up by a temp cleaner).  This is done using "rm -rf" because that's
> @@ -167,3 +193,10 @@ guestfs_int_remove_tmpdir (guestfs_h *g)
>    if (g->tmpdir)
>      guestfs_int_recursive_remove_dir (g, g->tmpdir);
>  }
> +
> +void
> +guestfs_int_remove_sockdir (guestfs_h *g)
> +{
> +  if (g->sockdir)
> +    guestfs_int_recursive_remove_dir (g, g->sockdir);
> +}
> diff --git a/test-tool/test-tool.c b/test-tool/test-tool.c
> index 9d23d6d..495316b 100644
> --- a/test-tool/test-tool.c
> +++ b/test-tool/test-tool.c
> @@ -210,6 +210,9 @@ main (int argc, char *argv[])
>    p = getenv ("PATH");
>    if (p)
>      printf ("PATH=%s\n", p);
> +  p = getenv ("XDG_RUNTIME_DIR");
> +  if (p)
> +    printf ("XDG_RUNTIME_DIR=%s\n", p);
>  
>    /* Print SELinux mode (don't worry if this fails, or if the command
>     * doesn't even exist).
> @@ -255,6 +258,9 @@ main (int argc, char *argv[])
>    printf ("guestfs_get_recovery_proc: %d\n", guestfs_get_recovery_proc (g));
>    printf ("guestfs_get_selinux: %d\n", guestfs_get_selinux (g));
>    printf ("guestfs_get_smp: %d\n", guestfs_get_smp (g));
> +  p = guestfs_get_sockdir (g);
> +  printf ("guestfs_get_sockdir: %s\n", p ? : "(null)");
> +  free (p);
>    p = guestfs_get_tmpdir (g);
>    printf ("guestfs_get_tmpdir: %s\n", p ? : "(null)");
>    free (p);
> -- 
> 2.5.0
> 
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v




More information about the Libguestfs mailing list