]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
ch_monitor: Get nicindexes in prep for cgroup mgmt
authorVineeth Pillai <viremana@linux.microsoft.com>
Fri, 10 Dec 2021 20:34:41 +0000 (20:34 +0000)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 6 Jan 2022 15:03:55 +0000 (16:03 +0100)
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/ch/ch_conf.h
src/ch/ch_domain.c
src/ch/ch_domain.h
src/ch/ch_driver.c
src/ch/ch_monitor.c
src/ch/ch_monitor.h
src/ch/ch_process.c
src/ch/meson.build

index 37c36d9a096ecebdbbfe4022f0d00a08a229060d..8fe69c8545652f237c12ec51a2c9099341d656aa 100644 (file)
@@ -44,6 +44,8 @@ struct _virCHDriver
 {
     virMutex lock;
 
+    bool privileged;
+
     /* Require lock to get a reference on the object,
      * lockless access thereafter */
     virCaps *caps;
index abd176eda6ef12bb759f43e3b0bdd31322a2deb7..a746d0f5fd2da0ba34ff1159f09427db7a7839f4 100644 (file)
 #include <config.h>
 
 #include "ch_domain.h"
+#include "domain_driver.h"
 #include "viralloc.h"
 #include "virchrdev.h"
 #include "virlog.h"
 #include "virtime.h"
+#include "virsystemd.h"
 
 #define VIR_FROM_THIS VIR_FROM_CH
 
@@ -134,7 +136,7 @@ virCHDomainObjEndJob(virDomainObj *obj)
 }
 
 static void *
-virCHDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
+virCHDomainObjPrivateAlloc(void *opaque)
 {
     virCHDomainObjPrivate *priv;
 
@@ -150,6 +152,7 @@ virCHDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
         g_free(priv);
         return NULL;
     }
+    priv->driver = opaque;
 
     return priv;
 }
@@ -161,6 +164,7 @@ virCHDomainObjPrivateFree(void *data)
 
     virChrdevFree(priv->chrdevs);
     virCHDomainObjFreeJob(priv);
+    g_free(priv->machineName);
     g_free(priv);
 }
 
@@ -356,3 +360,25 @@ virCHDomainHasVcpuPids(virDomainObj *vm)
 
     return false;
 }
+
+char *
+virCHDomainGetMachineName(virDomainObj *vm)
+{
+    virCHDomainObjPrivate *priv = CH_DOMAIN_PRIVATE(vm);
+    virCHDriver *driver = priv->driver;
+    char *ret = NULL;
+
+    if (vm->pid > 0) {
+        ret = virSystemdGetMachineNameByPID(vm->pid);
+        if (!ret)
+            virResetLastError();
+    }
+
+    if (!ret)
+        ret = virDomainDriverGenerateMachineName("ch",
+                                                 NULL,
+                                                 vm->def->id, vm->def->name,
+                                                 driver->privileged);
+
+    return ret;
+}
index aabe421596c6abbade0990a1274ff9ae6a699aaf..4d0b5479b8fa7f98a046e64790cb27cb6789ddac 100644 (file)
@@ -54,7 +54,9 @@ struct _virCHDomainObjPrivate {
     struct virCHDomainJobObj job;
 
     virChrdevs *chrdevs;
+    virCHDriver *driver;
     virCHMonitor *monitor;
+    char *machineName;
     virBitmap *autoCpuset;
 };
 
@@ -91,3 +93,6 @@ virCHDomainGetVcpuPid(virDomainObj *vm,
                       unsigned int vcpuid);
 bool
 virCHDomainHasVcpuPids(virDomainObj *vm);
+
+char *
+virCHDomainGetMachineName(virDomainObj *vm);
index 11cdbfd46090f06f848776aa168fb9efa616eefb..53e0872207cba12d9932a3f5aaa9d6ea1270ef58 100644 (file)
@@ -933,6 +933,7 @@ static int chStateInitialize(bool privileged,
         goto cleanup;
     }
 
+    ch_driver->privileged = privileged;
     ret = VIR_DRV_STATE_INIT_COMPLETE;
 
  cleanup:
index 12c10da8746ba5f6ec5a14a7a01b8d4113c5ef9b..a19f0c7e33f88a905fabd400db3d87b03130d8a7 100644 (file)
@@ -226,7 +226,10 @@ virCHMonitorBuildDisksJson(virJSONValue *content, virDomainDef *vmdef)
 }
 
 static int
-virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef)
+virCHMonitorBuildNetJson(virJSONValue *nets,
+                         virDomainNetDef *netdef,
+                         size_t *nnicindexes,
+                         int **nicindexes)
 {
     virDomainNetType netType = virDomainNetGetActualType(netdef);
     char macaddr[VIR_MAC_STRING_BUFLEN];
@@ -236,59 +239,72 @@ virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef)
     net = virJSONValueNewObject();
 
     switch (netType) {
-    case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        if (netdef->guestIP.nips == 1) {
-            const virNetDevIPAddr *ip = netdef->guestIP.ips[0];
-            g_autofree char *addr = NULL;
-            virSocketAddr netmask;
-            g_autofree char *netmaskStr = NULL;
-            if (!(addr = virSocketAddrFormat(&ip->address)))
-                return -1;
-            if (virJSONValueObjectAppendString(net, "ip", addr) < 0)
-                return -1;
+        case VIR_DOMAIN_NET_TYPE_ETHERNET:
+            if (netdef->guestIP.nips == 1) {
+                const virNetDevIPAddr *ip = netdef->guestIP.ips[0];
+                g_autofree char *addr = NULL;
+                virSocketAddr netmask;
+                g_autofree char *netmaskStr = NULL;
+
+                if (!(addr = virSocketAddrFormat(&ip->address)))
+                    return -1;
+                if (virJSONValueObjectAppendString(net, "ip", addr) < 0)
+                    return -1;
+
+                if (virSocketAddrPrefixToNetmask(ip->prefix, &netmask, AF_INET) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR,
+                                   _("Failed to translate net prefix %d to netmask"),
+                                   ip->prefix);
+                    return -1;
+                }
+                if (!(netmaskStr = virSocketAddrFormat(&netmask)))
+                    return -1;
+                if (virJSONValueObjectAppendString(net, "mask", netmaskStr) < 0)
+                    return -1;
+            } else if (netdef->guestIP.nips > 1) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("ethernet type supports a single guest ip"));
+            }
 
-            if (virSocketAddrPrefixToNetmask(ip->prefix, &netmask, AF_INET) < 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("Failed to translate net prefix %d to netmask"),
-                               ip->prefix);
-                return -1;
+            /* network and bridge use a tap device, and direct uses a
+             * macvtap device
+             */
+            if (nicindexes && nnicindexes && netdef->ifname) {
+                int nicindex = 0;
+
+                if (virNetDevGetIndex(netdef->ifname, &nicindex) < 0)
+                    return -1;
+
+                VIR_APPEND_ELEMENT(*nicindexes, *nnicindexes, nicindex);
             }
-            if (!(netmaskStr = virSocketAddrFormat(&netmask)))
-                return -1;
-            if (virJSONValueObjectAppendString(net, "mask", netmaskStr) < 0)
-                return -1;
-        } else if (netdef->guestIP.nips > 1) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("ethernet type supports a single guest ip"));
-        }
-        break;
-    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
-        if ((virDomainChrType)netdef->data.vhostuser->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+            break;
+        case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+            if ((virDomainChrType)netdef->data.vhostuser->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("vhost_user type support UNIX socket in this CH"));
-            return -1;
-        } else {
-            if (virJSONValueObjectAppendString(net, "vhost_socket", netdef->data.vhostuser->data.nix.path) < 0)
-                return -1;
-            if (virJSONValueObjectAppendBoolean(net, "vhost_user", true) < 0)
                 return -1;
-        }
-        break;
-    case VIR_DOMAIN_NET_TYPE_BRIDGE:
-    case VIR_DOMAIN_NET_TYPE_NETWORK:
-    case VIR_DOMAIN_NET_TYPE_DIRECT:
-    case VIR_DOMAIN_NET_TYPE_USER:
-    case VIR_DOMAIN_NET_TYPE_SERVER:
-    case VIR_DOMAIN_NET_TYPE_CLIENT:
-    case VIR_DOMAIN_NET_TYPE_MCAST:
-    case VIR_DOMAIN_NET_TYPE_INTERNAL:
-    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
-    case VIR_DOMAIN_NET_TYPE_UDP:
-    case VIR_DOMAIN_NET_TYPE_VDPA:
-    case VIR_DOMAIN_NET_TYPE_LAST:
-    default:
-        virReportEnumRangeError(virDomainNetType, netType);
-        return -1;
+            } else {
+                if (virJSONValueObjectAppendString(net, "vhost_socket", netdef->data.vhostuser->data.nix.path) < 0)
+                    return -1;
+                if (virJSONValueObjectAppendBoolean(net, "vhost_user", true) < 0)
+                    return -1;
+            }
+            break;
+        case VIR_DOMAIN_NET_TYPE_BRIDGE:
+        case VIR_DOMAIN_NET_TYPE_NETWORK:
+        case VIR_DOMAIN_NET_TYPE_DIRECT:
+        case VIR_DOMAIN_NET_TYPE_USER:
+        case VIR_DOMAIN_NET_TYPE_SERVER:
+        case VIR_DOMAIN_NET_TYPE_CLIENT:
+        case VIR_DOMAIN_NET_TYPE_MCAST:
+        case VIR_DOMAIN_NET_TYPE_INTERNAL:
+        case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+        case VIR_DOMAIN_NET_TYPE_UDP:
+        case VIR_DOMAIN_NET_TYPE_VDPA:
+        case VIR_DOMAIN_NET_TYPE_LAST:
+        default:
+            virReportEnumRangeError(virDomainNetType, netType);
+            return -1;
     }
 
     if (netdef->ifname != NULL) {
@@ -329,7 +345,10 @@ virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef)
 }
 
 static int
-virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef *vmdef)
+virCHMonitorBuildNetsJson(virJSONValue *content,
+                          virDomainDef *vmdef,
+                          size_t *nnicindexes,
+                          int **nicindexes)
 {
     g_autoptr(virJSONValue) nets = NULL;
     size_t i;
@@ -338,7 +357,8 @@ virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef *vmdef)
         nets = virJSONValueNewArray();
 
         for (i = 0; i < vmdef->nnets; i++) {
-            if (virCHMonitorBuildNetJson(nets, vmdef->nets[i]) < 0)
+            if (virCHMonitorBuildNetJson(nets, vmdef->nets[i],
+                                         nnicindexes, nicindexes) < 0)
                 return -1;
         }
         if (virJSONValueObjectAppend(content, "net", &nets) < 0)
@@ -349,7 +369,62 @@ virCHMonitorBuildNetsJson(virJSONValue *content, virDomainDef *vmdef)
 }
 
 static int
-virCHMonitorBuildVMJson(virDomainDef *vmdef, char **jsonstr)
+virCHMonitorBuildDeviceJson(virJSONValue *devices,
+                            virDomainHostdevDef *hostdevdef)
+{
+    g_autoptr(virJSONValue) device = NULL;
+
+
+    if (hostdevdef->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+        hostdevdef->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+        g_autofree char *name = NULL;
+        g_autofree char *path = NULL;
+        virDomainHostdevSubsysPCI *pcisrc = &hostdevdef->source.subsys.u.pci;
+
+        device = virJSONValueNewObject();
+        name = virPCIDeviceAddressAsString(&pcisrc->addr);
+        path = g_strdup_printf("/sys/bus/pci/devices/%s/", name);
+        if (!virFileExists(path)) {
+            virReportError(VIR_ERR_DEVICE_MISSING,
+                           _("host pci device %s not found"), path);
+            return -1;
+        }
+        if (virJSONValueObjectAppendString(device, "path", path) < 0)
+            return -1;
+        if (virJSONValueArrayAppend(devices, &device) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+static int
+virCHMonitorBuildDevicesJson(virJSONValue *content,
+                             virDomainDef *vmdef)
+{
+    size_t i;
+
+    g_autoptr(virJSONValue) devices = NULL;
+
+    if (vmdef->nhostdevs == 0)
+        return 0;
+
+    devices = virJSONValueNewArray();
+    for (i = 0; i < vmdef->nhostdevs; i++) {
+        if (virCHMonitorBuildDeviceJson(devices, vmdef->hostdevs[i]) < 0)
+            return -1;
+    }
+    if (virJSONValueObjectAppend(content, "devices", &devices) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int
+virCHMonitorBuildVMJson(virDomainDef *vmdef,
+                        char **jsonstr,
+                        size_t *nnicindexes,
+                        int **nicindexes)
 {
     g_autoptr(virJSONValue) content = virJSONValueNewObject();
 
@@ -374,7 +449,11 @@ virCHMonitorBuildVMJson(virDomainDef *vmdef, char **jsonstr)
     if (virCHMonitorBuildDisksJson(content, vmdef) < 0)
         return -1;
 
-    if (virCHMonitorBuildNetsJson(content, vmdef) < 0)
+
+    if (virCHMonitorBuildNetsJson(content, vmdef, nnicindexes, nicindexes) < 0)
+        return -1;
+
+    if (virCHMonitorBuildDevicesJson(content, vmdef) < 0)
         return -1;
 
     if (!(*jsonstr = virJSONValueToString(content, false)))
@@ -671,7 +750,9 @@ virCHMonitorShutdownVMM(virCHMonitor *mon)
 }
 
 int
-virCHMonitorCreateVM(virCHMonitor *mon)
+virCHMonitorCreateVM(virCHMonitor *mon,
+                     size_t *nnicindexes,
+                     int **nicindexes)
 {
     g_autofree char *url = NULL;
     int responseCode = 0;
@@ -683,7 +764,8 @@ virCHMonitorCreateVM(virCHMonitor *mon)
     headers = curl_slist_append(headers, "Accept: application/json");
     headers = curl_slist_append(headers, "Content-Type: application/json");
 
-    if (virCHMonitorBuildVMJson(mon->vm->def, &payload) != 0)
+    if (virCHMonitorBuildVMJson(mon->vm->def, &payload,
+                                nnicindexes, nicindexes) != 0)
         return -1;
 
     virObjectLock(mon);
index 0f684ca5838a6dd3238daf545b493c6401b09873..f3b6978366c22285602fca6c267606144438a3c8 100644 (file)
@@ -55,10 +55,23 @@ virCHMonitor *virCHMonitorNew(virDomainObj *vm, const char *socketdir);
 void virCHMonitorClose(virCHMonitor *mon);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCHMonitor, virCHMonitorClose);
 
-int virCHMonitorCreateVM(virCHMonitor *mon);
+
+int virCHMonitorCreateVM(virCHMonitor *mon,
+                         size_t *nnicindexes,
+                         int **nicindexes);
 int virCHMonitorBootVM(virCHMonitor *mon);
 int virCHMonitorShutdownVM(virCHMonitor *mon);
 int virCHMonitorRebootVM(virCHMonitor *mon);
 int virCHMonitorSuspendVM(virCHMonitor *mon);
 int virCHMonitorResumeVM(virCHMonitor *mon);
 int virCHMonitorGetInfo(virCHMonitor *mon, virJSONValue **info);
+
+typedef struct _virCHMonitorCPUInfo virCHMonitorCPUInfo;
+struct _virCHMonitorCPUInfo {
+    pid_t tid;
+    bool online;
+};
+void virCHMonitorCPUInfoFree(virCHMonitorCPUInfo *cpus);
+int virCHMonitorGetCPUInfo(virCHMonitor *mon,
+                           virCHMonitorCPUInfo **vcpus,
+                           size_t maxvcpus);
index 9f82e04485ebd86f00aef618b768571c35aebecb..49976d769eb961002e3ccead086822d8706b7a66 100644 (file)
@@ -147,6 +147,8 @@ int virCHProcessStart(virCHDriver *driver,
 {
     int ret = -1;
     virCHDomainObjPrivate *priv = vm->privateData;
+    g_autofree int *nicindexes = NULL;
+    size_t nnicindexes = 0;
 
     if (!priv->monitor) {
         /* And we can get the first monitor connection now too */
@@ -156,7 +158,8 @@ int virCHProcessStart(virCHDriver *driver,
             goto cleanup;
         }
 
-        if (virCHMonitorCreateVM(priv->monitor) < 0) {
+        if (virCHMonitorCreateVM(priv->monitor,
+                                 &nnicindexes, &nicindexes) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                         _("failed to create guest VM"));
             goto cleanup;
@@ -169,6 +172,7 @@ int virCHProcessStart(virCHDriver *driver,
         goto cleanup;
     }
 
+    priv->machineName = virCHDomainGetMachineName(vm);
     vm->pid = priv->monitor->pid;
     vm->def->id = vm->pid;
 
@@ -201,6 +205,7 @@ int virCHProcessStop(virCHDriver *driver G_GNUC_UNUSED,
 
     vm->pid = -1;
     vm->def->id = -1;
+    g_clear_pointer(&priv->machineName, g_free);
 
     virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
 
index e34974d56c6354c1e3f5527a12306b4b7f2adc5a..e0afdb390a63e0e100f1fa76619d3fc0b8574f2e 100644 (file)
@@ -29,6 +29,7 @@ if conf.has('WITH_CH')
     ],
     include_directories: [
       conf_inc_dir,
+      hypervisor_inc_dir,
     ],
   )