Extend virFindFileInPath to search in custom extra paths as well. Some
binaries that libvirt needs are not usually in $PATH so we need to have
a way to look for these as well.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/libvirt_private.syms | 2 +-
src/util/virfile.c | 16 ++++++++++++++--
src/util/virfile.h | 5 ++++-
tests/domaincapsmock.c | 3 ++-
tests/virfirewallmock.c | 3 ++-
5 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index abd3dc4bd1..717686ddee 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2254,7 +2254,7 @@ virFileWrapperFdClose;
virFileWrapperFdFree;
virFileWrapperFdNew;
virFileWriteStr;
-virFindFileInPath;
+virFindFileInPathFull;
# util/virfilecache.h
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 03a7725dd3..7922fda2e5 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -1654,13 +1654,15 @@ virFileIsLink(const char *linkpath)
}
/*
- * Finds a requested executable file in the PATH env. e.g.:
+ * Finds a requested executable file in the paths provided by @extra_paths
+ * argument or in PATH env. e.g.:
* "qemu-img" will return "/usr/bin/qemu-img"
*
* You must free the result
*/
char *
-virFindFileInPath(const char *file)
+virFindFileInPathFull(const char *file,
+ const GStrv extra_paths)
{
const char *origpath = NULL;
g_auto(GStrv) paths = NULL;
@@ -1692,6 +1694,16 @@ virFindFileInPath(const char *file)
return abspath;
}
+ /* First search in paths provided by caller.
+ */
+ if (extra_paths) {
+ for (pathiter = extra_paths; *pathiter; pathiter++) {
+ g_autofree char *fullpath = g_strdup_printf("%s/%s", *pathiter,
file);
+ if (virFileIsExecutable(fullpath))
+ return g_steal_pointer(&fullpath);
+ }
+ }
+
/* copy PATH env so we can tweak it */
origpath = getenv("PATH");
if (!origpath)
diff --git a/src/util/virfile.h b/src/util/virfile.h
index b9f7b1766f..eee27c2efc 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -184,9 +184,12 @@ int virFileResolveAllLinks(const char *linkpath,
int virFileIsLink(const char *linkpath)
ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
-char *virFindFileInPath(const char *file)
+char *virFindFileInPathFull(const char *file,
+ const GStrv extra_paths)
G_GNUC_NO_INLINE;
+#define virFindFileInPath(file) virFindFileInPathFull(file, NULL)
+
char *virFileFindResource(const char *filename,
const char *builddir,
const char *installdir)
diff --git a/tests/domaincapsmock.c b/tests/domaincapsmock.c
index 73690f0b9e..4bef2b72d0 100644
--- a/tests/domaincapsmock.c
+++ b/tests/domaincapsmock.c
@@ -43,7 +43,8 @@ virHostCPUGetMicrocodeVersion(virArch hostArch G_GNUC_UNUSED)
}
char *
-virFindFileInPath(const char *file)
+virFindFileInPathFull(const char *file,
+ const GStrv extra_args G_GNUC_UNUSED)
{
if (g_str_has_prefix(file, "qemu-system") ||
g_str_equal(file, "qemu-kvm")) {
diff --git a/tests/virfirewallmock.c b/tests/virfirewallmock.c
index 6b096701c9..a047e56bd9 100644
--- a/tests/virfirewallmock.c
+++ b/tests/virfirewallmock.c
@@ -20,7 +20,8 @@
#include "virfile.h"
char *
-virFindFileInPath(const char *file)
+virFindFileInPathFull(const char *file,
+ const GStrv extra_args G_GNUC_UNUSED)
{
if (file &&
(g_strrstr(file, "ebtables") ||
--
2.30.2