[PATCH v3 2/8] virCommand: Introduce APIs for core scheduling

Michal Privoznik mprivozn at redhat.com
Fri Aug 12 10:04:17 UTC 2022


There are two modes of core scheduling that are handy wrt
virCommand:

1) create new trusted group when executing a virCommand

2) place freshly executed virCommand into the trusted group of
   another process.

Therefore, implement these two new operations as new APIs:
virCommandSetRunAlone() and virCommandSetRunAmong(),
respectively.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/libvirt_private.syms |  2 ++
 src/util/vircommand.c    | 63 ++++++++++++++++++++++++++++++++++++++++
 src/util/vircommand.h    |  5 ++++
 3 files changed, 70 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 23abf663f6..02d1c753a4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2103,6 +2103,8 @@ virCommandSetOutputBuffer;
 virCommandSetOutputFD;
 virCommandSetPidFile;
 virCommandSetPreExecHook;
+virCommandSetRunAlone;
+virCommandSetRunAmong;
 virCommandSetSELinuxLabel;
 virCommandSetSendBuffer;
 virCommandSetUID;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index d78c666f28..745e7c560c 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -148,6 +148,13 @@ struct _virCommand {
 #endif
     int mask;
 
+    /* schedCore values:
+     *  0: no core scheduling
+     * >0: copy scheduling group from PID
+     * -1: create new scheduling group
+     */
+    pid_t schedCore;
+
     virCommandSendBuffer *sendBuffers;
     size_t numSendBuffers;
 };
@@ -434,6 +441,22 @@ virCommandHandshakeChild(virCommand *cmd)
 static int
 virExecCommon(virCommand *cmd, gid_t *groups, int ngroups)
 {
+    /* Do this before dropping capabilities. */
+    if (cmd->schedCore == -1 &&
+        virProcessSchedCoreCreate() < 0) {
+        virReportSystemError(errno, "%s",
+                             _("Unable to set SCHED_CORE"));
+        return -1;
+    }
+
+    if (cmd->schedCore > 0 &&
+        virProcessSchedCoreShareFrom(cmd->schedCore) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to run among %llu"),
+                             (unsigned long long) cmd->schedCore);
+        return -1;
+    }
+
     if (cmd->uid != (uid_t)-1 || cmd->gid != (gid_t)-1 ||
         cmd->capabilities || (cmd->flags & VIR_EXEC_CLEAR_CAPS)) {
         VIR_DEBUG("Setting child uid:gid to %d:%d with caps %llx",
@@ -3386,3 +3409,43 @@ virCommandRunNul(virCommand *cmd G_GNUC_UNUSED,
     return -1;
 }
 #endif /* WIN32 */
+
+/**
+ * virCommandSetRunAlone:
+ *
+ * Create new trusted group when running the command. In other words, the
+ * process won't be scheduled to run on a core among with processes from
+ * another, untrusted group.
+ */
+void
+virCommandSetRunAlone(virCommand *cmd)
+{
+    if (virCommandHasError(cmd))
+        return;
+
+    cmd->schedCore = -1;
+}
+
+/**
+ * virCommandSetRunAmong:
+ * @pid: pid from a trusted group
+ *
+ * When spawning the command place it into the trusted group of @pid so that
+ * these two processes can run on Hyper Threads of a single core at the same
+ * time.
+ */
+void
+virCommandSetRunAmong(virCommand *cmd,
+                      pid_t pid)
+{
+    if (virCommandHasError(cmd))
+        return;
+
+    if (pid <= 0) {
+        VIR_DEBUG("invalid pid value: %lld", (long long) pid);
+        cmd->has_error = -1;
+        return;
+    }
+
+    cmd->schedCore = pid;
+}
diff --git a/src/util/vircommand.h b/src/util/vircommand.h
index c7a580e152..98788bcbf7 100644
--- a/src/util/vircommand.h
+++ b/src/util/vircommand.h
@@ -217,4 +217,9 @@ int virCommandRunNul(virCommand *cmd,
                      virCommandRunNulFunc func,
                      void *data);
 
+void virCommandSetRunAlone(virCommand *cmd);
+
+void virCommandSetRunAmong(virCommand *cmd,
+                           pid_t pid);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCommand, virCommandFree);
-- 
2.35.1



More information about the libvir-list mailing list