已开启
ub: support UB hostdev hotplug and hot-unplug #456
ub: support UB hostdev hotplug and hot-unplug #456
已开启
xiangzixuan123创建于 11 天前
共 6 个文件变更+117-16
@@ -14592,8 +14592,8 @@ virDomainHostdevMatchSubsys(virDomainHostdevDef *a,
14592 return STREQ(a->source.subsys.u.vdpa.devpath,14592 return STREQ(a->source.subsys.u.vdpa.devpath,
14593 b->source.subsys.u.vdpa.devpath);14593 b->source.subsys.u.vdpa.devpath);
14594 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:14594 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:
14595- VIR_INFO("TODO: %s", __func__);14595+ return STREQ(a->source.subsys.u.ub.addr.guidStr,
14596- return 0;14596+ b->source.subsys.u.ub.addr.guidStr);
14597 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:14597 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
14598 return 0;14598 return 0;
14599 }14599 }
@@ -5270,7 +5270,7 @@ qemuBuildHostdevSCSICommandLine(virCommand *cmd,
5270 return 0;5270 return 0;
5271}5271}
5272 5272 
5273-static virJSONValue *5273+virJSONValue *
5274qemuBuildHostdevUBDevProps(const virDomainDef *domainDef,5274qemuBuildHostdevUBDevProps(const virDomainDef *domainDef,
5275 virDomainHostdevDef *dev)5275 virDomainHostdevDef *dev)
5276{5276{
@@ -202,6 +202,10 @@ virJSONValue *
202qemuBuildHostdevVDPADevProps(const virDomainDef *def,202qemuBuildHostdevVDPADevProps(const virDomainDef *def,
203 virDomainHostdevDef *dev);203 virDomainHostdevDef *dev);
204 204 
205+virJSONValue *
206+qemuBuildHostdevUBDevProps(const virDomainDef *def,
207+ virDomainHostdevDef *dev);
208+ 
205virJSONValue *209virJSONValue *
206qemuBuildRedirdevDevProps(const virDomainDef *def,210qemuBuildRedirdevDevProps(const virDomainDef *def,
207 virDomainRedirdevDef *dev);211 virDomainRedirdevDef *dev);
@@ -363,7 +363,8 @@ qemuHostdevPrepareMediatedDevices(virQEMUDriver *driver,
363 363 
364 364 
365static int365static int
366-qemuHostdevCheckUBDevices(virDomainDef *def)366+qemuHostdevCheckUBDevices(virDomainControllerDef **controllers,
367+ int ncontrollers)
367{368{
368 bool supportsPassthroughVFIO;369 bool supportsPassthroughVFIO;
369 bool supportsIOMMUFD;370 bool supportsIOMMUFD;
@@ -394,8 +395,8 @@ qemuHostdevCheckUBDevices(virDomainDef *def)
394 return -1;395 return -1;
395 }396 }
396 397 
397- for (i = 0; i < def->ncontrollers; i++) {398+ for (i = 0; i < ncontrollers; i++) {
398- cont = def->controllers[i];399+ cont = controllers[i];
399 if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_UB) {400 if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_UB) {
400 bus_instance_guid_str = cont->info.busInstance.guidStr;401 bus_instance_guid_str = cont->info.busInstance.guidStr;
401 break;402 break;
@@ -426,17 +427,17 @@ qemuHostdevCheckUBDevices(virDomainDef *def)
426 427 
427int428int
428qemuHostdevPrepareUBDevices(virQEMUDriver *driver,429qemuHostdevPrepareUBDevices(virQEMUDriver *driver,
429- virDomainDef *def)430+ const char *name,
431+ virDomainControllerDef **controllers,
432+ int ncontrollers,
433+ virDomainHostdevDef **hostdevs,
434+ int nhostdevs)
430{435{
431- const char *name = def->name;
432- virDomainHostdevDef **hostdevs = def->hostdevs;
433- int nhostdevs = def->nhostdevs;
434- 
435 if (!virHostdevHasUBDevice(hostdevs, nhostdevs)) {436 if (!virHostdevHasUBDevice(hostdevs, nhostdevs)) {
436 return 0;437 return 0;
437 }438 }
438 439 
439- if (qemuHostdevCheckUBDevices(def) < 0) {440+ if (qemuHostdevCheckUBDevices(controllers, ncontrollers) < 0) {
440 return -1;441 return -1;
441 }442 }
442 443 
@@ -477,7 +478,9 @@ qemuHostdevPrepareDomainDevices(virQEMUDriver *driver,
477 def->hostdevs, def->nhostdevs) < 0)478 def->hostdevs, def->nhostdevs) < 0)
478 return -1;479 return -1;
479 480 
480- if (qemuHostdevPrepareUBDevices(driver, def) < 0)481+ if (qemuHostdevPrepareUBDevices(driver, def->name,
482+ def->controllers, def->ncontrollers,
483+ def->hostdevs, def->nhostdevs) < 0)
481 return -1;484 return -1;
482 485 
483 return 0;486 return 0;
@@ -81,7 +81,11 @@ int qemuHostdevPrepareMediatedDevices(virQEMUDriver *driver,
81 virDomainHostdevDef **hostdevs,81 virDomainHostdevDef **hostdevs,
82 int nhostdevs);82 int nhostdevs);
83int qemuHostdevPrepareUBDevices(virQEMUDriver *driver,83int qemuHostdevPrepareUBDevices(virQEMUDriver *driver,
84- virDomainDef *def);84+ const char *name,
85+ virDomainControllerDef **controllers,
86+ int ncontrollers,
87+ virDomainHostdevDef **hostdevs,
88+ int nhostdevs);
85int qemuHostdevPrepareDomainDevices(virQEMUDriver *driver,89int qemuHostdevPrepareDomainDevices(virQEMUDriver *driver,
86 virDomainDef *def,90 virDomainDef *def,
87 unsigned int flags);91 unsigned int flags);
@@ -2838,6 +2838,77 @@ qemuDomainAttachVDPADevice(virQEMUDriver *driver,
2838 return -1;2838 return -1;
2839}2839}
2840 2840 
2841+static int
2842+qemuDomainAttachUBDevice(virQEMUDriver *driver,
2843+ virDomainObj *vm,
2844+ virDomainHostdevDef *hostdev)
2845+{
2846+ int ret = -1;
2847+ g_autoptr(virJSONValue) devprops = NULL;
2848+ bool teardowncgroup = false;
2849+ bool teardownlabel = false;
2850+ bool teardowndevice = false;
2851+ bool teardownmemlock = false;
2852+ qemuDomainObjPrivate *priv = vm->privateData;
2853+ 
2854+ if (qemuHostdevPrepareUBDevices(driver, vm->def->name,
2855+ vm->def->controllers, vm->def->ncontrollers,
2856+ &hostdev, 1) < 0)
2857+ return -1;
2858+ 
2859+ if (qemuDomainAdjustMaxMemLockHostdev(vm, hostdev) < 0)
2860+ goto cleanup;
2861+ teardownmemlock = true;
2862+ 
2863+ if (qemuDomainNamespaceSetupHostdev(vm, hostdev, &teardowndevice) < 0)
2864+ goto cleanup;
2865+ 
2866+ if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
2867+ goto cleanup;
2868+ teardowncgroup = true;
2869+ 
2870+ if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
2871+ goto cleanup;
2872+ teardownlabel = true;
2873+ 
2874+ qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1);
2875+ 
2876+ if (!(devprops = qemuBuildHostdevUBDevProps(vm->def, hostdev)))
2877+ goto cleanup;
2878+ 
2879+ qemuDomainObjEnterMonitor(vm);
2880+ ret = qemuMonitorAddDeviceProps(priv->mon, &devprops);
2881+ qemuDomainObjExitMonitor(vm);
2882+ 
2883+ virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
2884+ if (ret < 0)
2885+ goto cleanup;
2886+ 
2887+ VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1);
2888+ VIR_APPEND_ELEMENT_INPLACE(vm->def->hostdevs, vm->def->nhostdevs, hostdev);
2889+ ret = 0;
2890+ cleanup:
2891+ if (ret < 0) {
2892+ if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm) < 0)
2893+ VIR_WARN("Unable to reset maximum locked memory on hotplug fail");
2894+ if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2895+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
2896+ if (teardownlabel &&
2897+ qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
2898+ VIR_WARN("Unable to restore host device labelling on hotplug fail");
2899+ if (teardowndevice &&
2900+ qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
2901+ VIR_WARN("Unable to remove host device from /dev");
2902+ qemuHostdevReAttachUBDevices(driver,
2903+ vm->def->name,
2904+ &hostdev,
2905+ 1);
2906+ qemuDomainReleaseDeviceAddress(vm, hostdev->info);
2907+ }
2908+ return ret;
2909+}
2910+ 
2911+ 
2841static int2912static int
2842qemuDomainAttachHostDevice(virQEMUDriver *driver,2913qemuDomainAttachHostDevice(virQEMUDriver *driver,
2843 virDomainObj *vm,2914 virDomainObj *vm,
@@ -2885,8 +2956,10 @@ qemuDomainAttachHostDevice(virQEMUDriver *driver,
2885 if (qemuDomainAttachVDPADevice(driver, vm, hostdev) < 0)2956 if (qemuDomainAttachVDPADevice(driver, vm, hostdev) < 0)
2886 return -1;2957 return -1;
2887 break;2958 break;
2888- /* ub current not supprot hotplug */
2889 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:2959 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:
2960+ if (qemuDomainAttachUBDevice(driver, vm, hostdev) < 0)
2961+ return -1;
2962+ break;
2890 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:2963 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
2891 default:2964 default:
2892 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,2965 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -4787,6 +4860,16 @@ qemuDomainRemoveVDPADevice(virDomainObj *vm,
4787}4860}
4788 4861 
4789 4862 
4863+static void
4864+qemuDomainRemoveUBDevice(virQEMUDriver *driver,
4865+ virDomainObj *vm,
4866+ virDomainHostdevDef *hostdev)
4867+{
4868+ qemuHostdevReAttachUBDevices(driver, vm->def->name, &hostdev, 1);
4869+ qemuDomainReleaseDeviceAddress(vm, hostdev->info);
4870+}
4871+ 
4872+ 
4790static int4873static int
4791qemuDomainRemoveHostDevice(virQEMUDriver *driver,4874qemuDomainRemoveHostDevice(virQEMUDriver *driver,
4792 virDomainObj *vm,4875 virDomainObj *vm,
@@ -4861,8 +4944,11 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver,
4861 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA:4944 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA:
4862 qemuDomainRemoveVDPADevice(vm, hostdev);4945 qemuDomainRemoveVDPADevice(vm, hostdev);
4863 break;4946 break;
4864- /* UB current not support hot remove */
4865 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:4947 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:
4948+ qemuDomainRemoveUBDevice(driver, vm, hostdev);
4949+ if (qemuDomainAdjustMaxMemLock(vm) < 0)
4950+ VIR_WARN("Failed to adjust locked memory limit");
4951+ break;
4866 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:4952 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
4867 break;4953 break;
4868 }4954 }
@@ -5900,6 +5986,10 @@ qemuDomainDetachPrepHostdev(virDomainObj *vm,
5900 vdpasrc->devpath);5986 vdpasrc->devpath);
5901 break;5987 break;
5902 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:5988 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_UB:
5989+ virReportError(VIR_ERR_DEVICE_MISSING,
5990+ _("host ub device '%1$s' not found"),
5991+ subsys->u.ub.addr.guidStr);
5992+ break;
5903 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:5993 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
5904 default:5994 default:
5905 virReportError(VIR_ERR_INTERNAL_ERROR,5995 virReportError(VIR_ERR_INTERNAL_ERROR,