/
gpu.go
165 lines (147 loc) · 5.03 KB
/
gpu.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package device
import (
"fmt"
"github.com/canonical/lxd/lxd/device/config"
"github.com/canonical/lxd/shared/api"
"github.com/canonical/lxd/shared/validate"
)
func gpuValidationRules(requiredFields []string, optionalFields []string) map[string]func(value string) error {
// Define a set of default validators for each field name.
defaultValidators := map[string]func(value string) error{
// lxdmeta:generate(entities=device-gpu-{physical+mdev+mig}; group=device-conf; key=vendorid)
//
// ---
// type: string
// shortdesc: Vendor ID of the GPU device
// lxdmeta:generate(entities=device-gpu-sriov; group=device-conf; key=vendorid)
//
// ---
// type: string
// shortdesc: Vendor ID of the parent GPU device
"vendorid": validate.Optional(validate.IsDeviceID),
// lxdmeta:generate(entities=device-gpu-{physical+mdev+mig}; group=device-conf; key=productid)
//
// ---
// type: string
// shortdesc: Product ID of the GPU device
// lxdmeta:generate(entities=device-gpu-sriov; group=device-conf; key=productid)
//
// ---
// type: string
// shortdesc: Product ID of the parent GPU device
"productid": validate.Optional(validate.IsDeviceID),
// lxdmeta:generate(entities=device-gpu-{physical+mdev+mig}; group=device-conf; key=id)
//
// ---
// type: string
// shortdesc: DRM card ID of the GPU device
// lxdmeta:generate(entities=device-gpu-sriov; group=device-conf; key=id)
//
// ---
// type: string
// shortdesc: DRM card ID of the parent GPU device
"id": validate.IsAny,
// lxdmeta:generate(entities=device-gpu-{physical+mdev+mig}; group=device-conf; key=pci)
//
// ---
// type: string
// shortdesc: PCI address of the GPU device
// lxdmeta:generate(entities=device-gpu-sriov; group=device-conf; key=pci)
//
// ---
// type: string
// shortdesc: PCI address of the parent GPU device
"pci": validate.IsPCIAddress,
// lxdmeta:generate(entities=device-gpu-physical; group=device-conf; key=uid)
//
// ---
// type: integer
// defaultdesc: `0`
// condition: container
// shortdesc: UID of the device owner in the container
"uid": unixValidUserID,
// lxdmeta:generate(entities=device-gpu-physical; group=device-conf; key=gid)
//
// ---
// type: integer
// defaultdesc: `0`
// condition: container
// shortdesc: GID of the device owner in the container
"gid": unixValidUserID,
// lxdmeta:generate(entities=device-gpu-physical; group=device-conf; key=mode)
//
// ---
// type: integer
// defaultdesc: `0660`
// condition: container
// shortdesc: Mode of the device in the container
"mode": unixValidOctalFileMode,
// lxdmeta:generate(entities=device-gpu-mig; group=device-conf; key=mig.gi)
//
// ---
// type: integer
// shortdesc: Existing MIG GPU instance ID
"mig.gi": validate.IsUint8,
// lxdmeta:generate(entities=device-gpu-mig; group=device-conf; key=mig.ci)
//
// ---
// type: integer
// shortdesc: Existing MIG compute instance ID
"mig.ci": validate.IsUint8,
// lxdmeta:generate(entities=device-gpu-mig; group=device-conf; key=mig.uuid)
// You can omit the `MIG-` prefix when specifying this option.
// ---
// type: string
// shortdesc: Existing MIG device UUID
"mig.uuid": gpuValidMigUUID,
// lxdmeta:generate(entities=device-gpu-mdev; group=device-conf; key=mdev)
// For example: `i915-GVTg_V5_4`
// ---
// type: string
// defaultdesc: `0`
// required: yes
// shortdesc: The `mdev` profile to use
"mdev": validate.IsAny,
}
validators := map[string]func(value string) error{}
for _, k := range optionalFields {
defaultValidator := defaultValidators[k]
// If field doesn't have a known validator, it is an unknown field, skip.
if defaultValidator == nil {
continue
}
// Wrap the default validator in an empty check as field is optional.
validators[k] = func(value string) error {
if value == "" {
return nil
}
return defaultValidator(value)
}
}
// Add required fields last, that way if they are specified in both required and optional
// field sets, the required one will overwrite the optional validators.
for _, k := range requiredFields {
defaultValidator := defaultValidators[k]
// If field doesn't have a known validator, it is an unknown field, skip.
if defaultValidator == nil {
continue
}
// Wrap the default validator in a not empty check as field is required.
validators[k] = func(value string) error {
err := validate.IsNotEmpty(value)
if err != nil {
return err
}
return defaultValidator(value)
}
}
return validators
}
// Check if the device matches the given GPU card.
// It matches based on vendorid, pci, productid or id setting of the device.
func gpuSelected(device config.Device, gpu api.ResourcesGPUCard) bool {
return !((device["vendorid"] != "" && gpu.VendorID != device["vendorid"]) ||
(device["pci"] != "" && gpu.PCIAddress != device["pci"]) ||
(device["productid"] != "" && gpu.ProductID != device["productid"]) ||
(device["id"] != "" && (gpu.DRM == nil || fmt.Sprintf("%d", gpu.DRM.ID) != device["id"])))
}