[PATCH 3/7] util: Add virPolkitAgentAvailable

Martin Kletzander mkletzan at redhat.com
Sat Nov 20 23:10:04 UTC 2021


With this function we can decide whether to try running the polkit text agent
only if it is available, removing a potential needless error saying that the
agent binary does not exist, which is useful especially when running the agent
before knowing whether it is going to be needed.

Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virpolkit.c     | 44 ++++++++++++++++++++++++++++++++++++++++
 src/util/virpolkit.h     |  1 +
 3 files changed, 46 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a7bc50a4d16d..c11be4eafa19 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3078,6 +3078,7 @@ virPidFileWritePath;
 
 
 # util/virpolkit.h
+virPolkitAgentAvailable;
 virPolkitAgentCreate;
 virPolkitAgentDestroy;
 virPolkitCheckAuth;
diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c
index 86255a96760f..3b333547d70b 100644
--- a/src/util/virpolkit.c
+++ b/src/util/virpolkit.c
@@ -20,6 +20,7 @@
  */
 
 #include <config.h>
+#include <fcntl.h>
 #include <unistd.h>
 
 #include "virpolkit.h"
@@ -217,6 +218,42 @@ virPolkitAgentCreate(void)
 }
 
 
+/*
+ * virPolkitAgentAvailable
+ *
+ * This function does some preliminary checking that the pkttyagent does not
+ * fail starting so that it can be started without waiting for first failed
+ * connection with VIR_ERR_AUTH_UNAVAILABLE.
+ */
+bool
+virPolkitAgentAvailable(void)
+{
+    const char *termid = ctermid(NULL);
+    VIR_AUTOCLOSE fd = -1;
+
+    if (!virFileExists(PKTTYAGENT))
+        return false;
+
+    if (!termid)
+        return false;
+
+    /*
+     *The pkttyagent needs to open the controlling terminal.
+     *
+     * Just in case we are running without a ctty make sure this open() does not
+     * change that.
+     *
+     * We could check if our session has a controlling terminal available
+     * instead, but it would require parsing `/proc/self/stat` on Linux, which
+     * is not portable and moreover requires way more work than just open().
+     */
+    fd = open(termid, O_RDWR | O_NOCTTY);
+    if (fd < 0)
+        return false;
+
+    return true;
+}
+
 #else /* ! WITH_POLKIT */
 
 int virPolkitCheckAuth(const char *actionid G_GNUC_UNUSED,
@@ -247,4 +284,11 @@ virPolkitAgentCreate(void)
                    _("polkit text authentication agent unavailable"));
     return NULL;
 }
+
+bool
+virPolkitAgentAvailable(void)
+{
+    return false;
+}
+
 #endif /* WITH_POLKIT */
diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h
index a577d59452ba..7bcd040e5e06 100644
--- a/src/util/virpolkit.h
+++ b/src/util/virpolkit.h
@@ -37,3 +37,4 @@ typedef struct _virPolkitAgent virPolkitAgent;
 
 void virPolkitAgentDestroy(virPolkitAgent *cmd);
 virPolkitAgent *virPolkitAgentCreate(void);
+bool virPolkitAgentAvailable(void);
-- 
2.34.0




More information about the libvir-list mailing list