Merge lp:~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages into lp:ubuntu/raring/libvirt
- Raring (13.04)
- libvirt-hugepages
- Merge into raring
Status: | Needs review |
---|---|
Proposed branch: | lp:~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages |
Merge into: | lp:ubuntu/raring/libvirt |
Diff against target: |
11034 lines (+10828/-0) 24 files modified
.pc/apparmor-allow-hugepages/src/libvirt_private.syms (+1840/-0) .pc/apparmor-allow-hugepages/src/qemu/qemu_process.c (+4474/-0) .pc/apparmor-allow-hugepages/src/security/security_apparmor.c (+911/-0) .pc/apparmor-allow-hugepages/src/security/security_driver.h (+148/-0) .pc/apparmor-allow-hugepages/src/security/security_manager.c (+513/-0) .pc/apparmor-allow-hugepages/src/security/security_manager.h (+116/-0) .pc/apparmor-allow-hugepages/src/security/security_stack.c (+532/-0) .pc/apparmor-allow-hugepages/tests/virt-aa-helper-test (+326/-0) .pc/applied-patches (+2/-0) .pc/vnc-socket.patch/src/security/virt-aa-helper.c (+1314/-0) .pc/vnc-socket.patch/tests/virt-aa-helper-test (+329/-0) debian/changelog (+9/-0) debian/patches/apparmor-allow-hugepages (+189/-0) debian/patches/series (+2/-0) debian/patches/vnc-socket.patch (+37/-0) src/libvirt_private.syms (+1/-0) src/qemu/qemu_process.c (+9/-0) src/security/security_apparmor.c (+27/-0) src/security/security_driver.h (+4/-0) src/security/security_manager.c (+10/-0) src/security/security_manager.h (+3/-0) src/security/security_stack.c (+19/-0) src/security/virt-aa-helper.c (+7/-0) tests/virt-aa-helper-test (+6/-0) |
To merge this branch: | bzr merge lp:~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jamie Strandboge | Pending | ||
Review via email: mp+138341@code.launchpad.net |
Commit message
Description of the change
This has proposed changes for vnc socket files and hugepages backing stores. Both have been tested and appear to work, but given my un-familiarity with the relevant code before I started, I'd appreciate a review to make sure I didn't mis-interpret any of the code.
- 228. By Serge Hallyn
-
Switch to using virBuffer
- 229. By Serge Hallyn
-
add tests for vnc and hugepages apparmor extensions
- 230. By Serge Hallyn
-
fix bad cut-pastes
Unmerged revisions
- 230. By Serge Hallyn
-
fix bad cut-pastes
- 229. By Serge Hallyn
-
add tests for vnc and hugepages apparmor extensions
- 228. By Serge Hallyn
-
Switch to using virBuffer
- 227. By Serge Hallyn
-
debian/
patches/ vnc-socket. patch: If a vnc socket is in use, add it's
path to the apparmor policy. (LP: #1069534)Note - I'm not sure whether there are non-unix-socket cases which are
mis-handled by this. - 226. By Serge Hallyn
-
debian/
patches/ apparmor- allow-hugepages : update apparmor policies to
allow use of hugepages. (LP: #646468)
Preview Diff
1 | === added directory '.pc/apparmor-allow-hugepages' | |||
2 | === added file '.pc/apparmor-allow-hugepages/.timestamp' | |||
3 | === added directory '.pc/apparmor-allow-hugepages/src' | |||
4 | === added file '.pc/apparmor-allow-hugepages/src/libvirt_private.syms' | |||
5 | --- .pc/apparmor-allow-hugepages/src/libvirt_private.syms 1970-01-01 00:00:00 +0000 | |||
6 | +++ .pc/apparmor-allow-hugepages/src/libvirt_private.syms 2012-12-11 20:02:29 +0000 | |||
7 | @@ -0,0 +1,1840 @@ | |||
8 | 1 | # | ||
9 | 2 | # General private symbols. Add symbols here, and see Makefile.am for | ||
10 | 3 | # more details. | ||
11 | 4 | # | ||
12 | 5 | # Keep this file sorted by header name, then by symbols with each header. | ||
13 | 6 | # | ||
14 | 7 | |||
15 | 8 | # bitmap.h | ||
16 | 9 | virBitmapClearAll; | ||
17 | 10 | virBitmapClearBit; | ||
18 | 11 | virBitmapCopy; | ||
19 | 12 | virBitmapCountBits; | ||
20 | 13 | virBitmapEqual; | ||
21 | 14 | virBitmapFormat; | ||
22 | 15 | virBitmapFree; | ||
23 | 16 | virBitmapGetBit; | ||
24 | 17 | virBitmapIsAllSet; | ||
25 | 18 | virBitmapNew; | ||
26 | 19 | virBitmapNewCopy; | ||
27 | 20 | virBitmapNewData; | ||
28 | 21 | virBitmapNextSetBit; | ||
29 | 22 | virBitmapParse; | ||
30 | 23 | virBitmapSetAll; | ||
31 | 24 | virBitmapSetBit; | ||
32 | 25 | virBitmapSize; | ||
33 | 26 | virBitmapString; | ||
34 | 27 | virBitmapToData; | ||
35 | 28 | |||
36 | 29 | |||
37 | 30 | # buf.h | ||
38 | 31 | virBufferAdd; | ||
39 | 32 | virBufferAddChar; | ||
40 | 33 | virBufferAdjustIndent; | ||
41 | 34 | virBufferAsprintf; | ||
42 | 35 | virBufferContentAndReset; | ||
43 | 36 | virBufferCurrentContent; | ||
44 | 37 | virBufferError; | ||
45 | 38 | virBufferEscape; | ||
46 | 39 | virBufferEscapeSexpr; | ||
47 | 40 | virBufferEscapeShell; | ||
48 | 41 | virBufferEscapeString; | ||
49 | 42 | virBufferFreeAndReset; | ||
50 | 43 | virBufferGetIndent; | ||
51 | 44 | virBufferStrcat; | ||
52 | 45 | virBufferTrim; | ||
53 | 46 | virBufferURIEncodeString; | ||
54 | 47 | virBufferUse; | ||
55 | 48 | virBufferVasprintf; | ||
56 | 49 | |||
57 | 50 | |||
58 | 51 | # caps.h | ||
59 | 52 | virCapabilitiesAddGuest; | ||
60 | 53 | virCapabilitiesAddGuestDomain; | ||
61 | 54 | virCapabilitiesAddGuestFeature; | ||
62 | 55 | virCapabilitiesAddHostFeature; | ||
63 | 56 | virCapabilitiesAddHostMigrateTransport; | ||
64 | 57 | virCapabilitiesAddHostNUMACell; | ||
65 | 58 | virCapabilitiesAllocMachines; | ||
66 | 59 | virCapabilitiesDefaultGuestArch; | ||
67 | 60 | virCapabilitiesDefaultGuestEmulator; | ||
68 | 61 | virCapabilitiesDefaultGuestMachine; | ||
69 | 62 | virCapabilitiesFormatXML; | ||
70 | 63 | virCapabilitiesFree; | ||
71 | 64 | virCapabilitiesFreeMachines; | ||
72 | 65 | virCapabilitiesFreeNUMAInfo; | ||
73 | 66 | virCapabilitiesGenerateMac; | ||
74 | 67 | virCapabilitiesIsEmulatorRequired; | ||
75 | 68 | virCapabilitiesNew; | ||
76 | 69 | virCapabilitiesSetEmulatorRequired; | ||
77 | 70 | virCapabilitiesSetHostCPU; | ||
78 | 71 | virCapabilitiesSetMacPrefix; | ||
79 | 72 | |||
80 | 73 | |||
81 | 74 | # cgroup.h | ||
82 | 75 | virCgroupAddTask; | ||
83 | 76 | virCgroupAddTaskController; | ||
84 | 77 | virCgroupAllowDevice; | ||
85 | 78 | virCgroupAllowDeviceMajor; | ||
86 | 79 | virCgroupAllowDevicePath; | ||
87 | 80 | virCgroupControllerTypeFromString; | ||
88 | 81 | virCgroupControllerTypeToString; | ||
89 | 82 | virCgroupDenyAllDevices; | ||
90 | 83 | virCgroupDenyDevice; | ||
91 | 84 | virCgroupDenyDeviceMajor; | ||
92 | 85 | virCgroupDenyDevicePath; | ||
93 | 86 | virCgroupForDomain; | ||
94 | 87 | virCgroupForDriver; | ||
95 | 88 | virCgroupForEmulator; | ||
96 | 89 | virCgroupForVcpu; | ||
97 | 90 | virCgroupFree; | ||
98 | 91 | virCgroupGetBlkioWeight; | ||
99 | 92 | virCgroupGetCpuCfsPeriod; | ||
100 | 93 | virCgroupGetCpuCfsQuota; | ||
101 | 94 | virCgroupGetCpuShares; | ||
102 | 95 | virCgroupGetCpuacctPercpuUsage; | ||
103 | 96 | virCgroupGetCpuacctStat; | ||
104 | 97 | virCgroupGetCpuacctUsage; | ||
105 | 98 | virCgroupGetCpusetCpus; | ||
106 | 99 | virCgroupGetCpusetMems; | ||
107 | 100 | virCgroupGetFreezerState; | ||
108 | 101 | virCgroupGetMemSwapHardLimit; | ||
109 | 102 | virCgroupGetMemoryHardLimit; | ||
110 | 103 | virCgroupGetMemorySoftLimit; | ||
111 | 104 | virCgroupGetMemoryUsage; | ||
112 | 105 | virCgroupKill; | ||
113 | 106 | virCgroupKillPainfully; | ||
114 | 107 | virCgroupKillRecursive; | ||
115 | 108 | virCgroupMounted; | ||
116 | 109 | virCgroupMoveTask; | ||
117 | 110 | virCgroupPathOfController; | ||
118 | 111 | virCgroupRemove; | ||
119 | 112 | virCgroupSetBlkioDeviceWeight; | ||
120 | 113 | virCgroupSetBlkioWeight; | ||
121 | 114 | virCgroupSetCpuCfsPeriod; | ||
122 | 115 | virCgroupSetCpuCfsQuota; | ||
123 | 116 | virCgroupSetCpuShares; | ||
124 | 117 | virCgroupSetCpusetCpus; | ||
125 | 118 | virCgroupSetCpusetMems; | ||
126 | 119 | virCgroupSetFreezerState; | ||
127 | 120 | virCgroupSetMemSwapHardLimit; | ||
128 | 121 | virCgroupSetMemory; | ||
129 | 122 | virCgroupSetMemoryHardLimit; | ||
130 | 123 | virCgroupSetMemorySoftLimit; | ||
131 | 124 | |||
132 | 125 | |||
133 | 126 | # command.h | ||
134 | 127 | virCommandAbort; | ||
135 | 128 | virCommandAddArg; | ||
136 | 129 | virCommandAddArgBuffer; | ||
137 | 130 | virCommandAddArgFormat; | ||
138 | 131 | virCommandAddArgList; | ||
139 | 132 | virCommandAddArgPair; | ||
140 | 133 | virCommandAddArgSet; | ||
141 | 134 | virCommandAddEnvBuffer; | ||
142 | 135 | virCommandAddEnvFormat; | ||
143 | 136 | virCommandAddEnvPair; | ||
144 | 137 | virCommandAddEnvPass; | ||
145 | 138 | virCommandAddEnvPassCommon; | ||
146 | 139 | virCommandAddEnvString; | ||
147 | 140 | virCommandAllowCap; | ||
148 | 141 | virCommandClearCaps; | ||
149 | 142 | virCommandDaemonize; | ||
150 | 143 | virCommandExec; | ||
151 | 144 | virCommandFree; | ||
152 | 145 | virCommandHandshakeNotify; | ||
153 | 146 | virCommandHandshakeWait; | ||
154 | 147 | virCommandNew; | ||
155 | 148 | virCommandNewArgList; | ||
156 | 149 | virCommandNewArgs; | ||
157 | 150 | virCommandNonblockingFDs; | ||
158 | 151 | virCommandPreserveFD; | ||
159 | 152 | virCommandRequireHandshake; | ||
160 | 153 | virCommandRun; | ||
161 | 154 | virCommandRunAsync; | ||
162 | 155 | virCommandSetErrorBuffer; | ||
163 | 156 | virCommandSetErrorFD; | ||
164 | 157 | virCommandSetInputBuffer; | ||
165 | 158 | virCommandSetInputFD; | ||
166 | 159 | virCommandSetOutputBuffer; | ||
167 | 160 | virCommandSetOutputFD; | ||
168 | 161 | virCommandSetPidFile; | ||
169 | 162 | virCommandSetPreExecHook; | ||
170 | 163 | virCommandSetWorkingDirectory; | ||
171 | 164 | virCommandToString; | ||
172 | 165 | virCommandTransferFD; | ||
173 | 166 | virCommandWait; | ||
174 | 167 | virCommandWriteArgLog; | ||
175 | 168 | virFork; | ||
176 | 169 | virRun; | ||
177 | 170 | |||
178 | 171 | |||
179 | 172 | # conf.h | ||
180 | 173 | virConfFree; | ||
181 | 174 | virConfFreeValue; | ||
182 | 175 | virConfGetValue; | ||
183 | 176 | virConfNew; | ||
184 | 177 | virConfReadFile; | ||
185 | 178 | virConfReadMem; | ||
186 | 179 | virConfSetValue; | ||
187 | 180 | virConfWriteFile; | ||
188 | 181 | virConfWriteMem; | ||
189 | 182 | |||
190 | 183 | |||
191 | 184 | # cpu.h | ||
192 | 185 | cpuBaseline; | ||
193 | 186 | cpuBaselineXML; | ||
194 | 187 | cpuCompare; | ||
195 | 188 | cpuCompareXML; | ||
196 | 189 | cpuDataFree; | ||
197 | 190 | cpuDecode; | ||
198 | 191 | cpuEncode; | ||
199 | 192 | cpuGuestData; | ||
200 | 193 | cpuHasFeature; | ||
201 | 194 | cpuMapOverride; | ||
202 | 195 | cpuNodeData; | ||
203 | 196 | cpuUpdate; | ||
204 | 197 | |||
205 | 198 | |||
206 | 199 | # cpu_conf.h | ||
207 | 200 | virCPUDefAddFeature; | ||
208 | 201 | virCPUDefCopy; | ||
209 | 202 | virCPUDefCopyModel; | ||
210 | 203 | virCPUDefFormat; | ||
211 | 204 | virCPUDefFormatBuf; | ||
212 | 205 | virCPUDefFree; | ||
213 | 206 | virCPUDefFreeModel; | ||
214 | 207 | virCPUDefParseXML; | ||
215 | 208 | virCPUModeTypeToString; | ||
216 | 209 | |||
217 | 210 | |||
218 | 211 | # datatypes.h | ||
219 | 212 | virConnectClass; | ||
220 | 213 | virDomainClass; | ||
221 | 214 | virDomainSnapshotClass; | ||
222 | 215 | virGetConnect; | ||
223 | 216 | virGetDomain; | ||
224 | 217 | virGetDomainSnapshot; | ||
225 | 218 | virGetInterface; | ||
226 | 219 | virGetNWFilter; | ||
227 | 220 | virGetNetwork; | ||
228 | 221 | virGetNodeDevice; | ||
229 | 222 | virGetSecret; | ||
230 | 223 | virGetStoragePool; | ||
231 | 224 | virGetStorageVol; | ||
232 | 225 | virGetStream; | ||
233 | 226 | virInterfaceClass; | ||
234 | 227 | virNetworkClass; | ||
235 | 228 | virNodeDeviceClass; | ||
236 | 229 | virNWFilterClass; | ||
237 | 230 | virSecretClass; | ||
238 | 231 | virStoragePoolClass; | ||
239 | 232 | virStorageVolClass; | ||
240 | 233 | virStreamClass; | ||
241 | 234 | |||
242 | 235 | |||
243 | 236 | # device_conf.h | ||
244 | 237 | virDeviceAddressPciMultiTypeFromString; | ||
245 | 238 | virDeviceAddressPciMultiTypeToString; | ||
246 | 239 | virDevicePCIAddressEqual; | ||
247 | 240 | virDevicePCIAddressFormat; | ||
248 | 241 | virDevicePCIAddressIsValid; | ||
249 | 242 | virDevicePCIAddressParseXML; | ||
250 | 243 | |||
251 | 244 | # dnsmasq.h | ||
252 | 245 | dnsmasqAddDhcpHost; | ||
253 | 246 | dnsmasqAddHost; | ||
254 | 247 | dnsmasqContextFree; | ||
255 | 248 | dnsmasqContextNew; | ||
256 | 249 | dnsmasqDelete; | ||
257 | 250 | dnsmasqReload; | ||
258 | 251 | dnsmasqSave; | ||
259 | 252 | |||
260 | 253 | |||
261 | 254 | # domain_audit.h | ||
262 | 255 | virDomainAuditCgroup; | ||
263 | 256 | virDomainAuditCgroupMajor; | ||
264 | 257 | virDomainAuditCgroupPath; | ||
265 | 258 | virDomainAuditDisk; | ||
266 | 259 | virDomainAuditFS; | ||
267 | 260 | virDomainAuditHostdev; | ||
268 | 261 | virDomainAuditMemory; | ||
269 | 262 | virDomainAuditNet; | ||
270 | 263 | virDomainAuditNetDevice; | ||
271 | 264 | virDomainAuditRedirdev; | ||
272 | 265 | virDomainAuditSecurityLabel; | ||
273 | 266 | virDomainAuditStart; | ||
274 | 267 | virDomainAuditStop; | ||
275 | 268 | virDomainAuditVcpu; | ||
276 | 269 | |||
277 | 270 | |||
278 | 271 | # domain_conf.h | ||
279 | 272 | virBlkioDeviceWeightArrayClear; | ||
280 | 273 | virDiskNameToBusDeviceIndex; | ||
281 | 274 | virDiskNameToIndex; | ||
282 | 275 | virDomainActualNetDefFree; | ||
283 | 276 | virDomainAssignDef; | ||
284 | 277 | virDomainBlockedReasonTypeFromString; | ||
285 | 278 | virDomainBlockedReasonTypeToString; | ||
286 | 279 | virDomainBootMenuTypeFromString; | ||
287 | 280 | virDomainBootMenuTypeToString; | ||
288 | 281 | virDomainChrConsoleTargetTypeFromString; | ||
289 | 282 | virDomainChrConsoleTargetTypeToString; | ||
290 | 283 | virDomainChrDefForeach; | ||
291 | 284 | virDomainChrDefFree; | ||
292 | 285 | virDomainChrDefNew; | ||
293 | 286 | virDomainChrSourceDefCopy; | ||
294 | 287 | virDomainChrSourceDefFree; | ||
295 | 288 | virDomainChrSpicevmcTypeFromString; | ||
296 | 289 | virDomainChrSpicevmcTypeToString; | ||
297 | 290 | virDomainChrTcpProtocolTypeFromString; | ||
298 | 291 | virDomainChrTcpProtocolTypeToString; | ||
299 | 292 | virDomainChrTypeFromString; | ||
300 | 293 | virDomainChrTypeToString; | ||
301 | 294 | virDomainClockBasisTypeToString; | ||
302 | 295 | virDomainClockOffsetTypeFromString; | ||
303 | 296 | virDomainClockOffsetTypeToString; | ||
304 | 297 | virDomainConfigFile; | ||
305 | 298 | virDomainControllerDefFree; | ||
306 | 299 | virDomainControllerFind; | ||
307 | 300 | virDomainControllerInsert; | ||
308 | 301 | virDomainControllerInsertPreAlloced; | ||
309 | 302 | virDomainControllerModelSCSITypeFromString; | ||
310 | 303 | virDomainControllerModelSCSITypeToString; | ||
311 | 304 | virDomainControllerModelUSBTypeFromString; | ||
312 | 305 | virDomainControllerModelUSBTypeToString; | ||
313 | 306 | virDomainControllerRemove; | ||
314 | 307 | virDomainControllerTypeToString; | ||
315 | 308 | virDomainCpuPlacementModeTypeFromString; | ||
316 | 309 | virDomainCpuPlacementModeTypeToString; | ||
317 | 310 | virDomainDefAddImplicitControllers; | ||
318 | 311 | virDomainDefCheckABIStability; | ||
319 | 312 | virDomainDefClearDeviceAliases; | ||
320 | 313 | virDomainDefClearPCIAddresses; | ||
321 | 314 | virDomainDefCompatibleDevice; | ||
322 | 315 | virDomainDefFormat; | ||
323 | 316 | virDomainDefFormatInternal; | ||
324 | 317 | virDomainDefFree; | ||
325 | 318 | virDomainDefGetSecurityLabelDef; | ||
326 | 319 | virDomainDiskDefGetSecurityLabelDef; | ||
327 | 320 | virDomainDefAddSecurityLabelDef; | ||
328 | 321 | virDomainDefParseFile; | ||
329 | 322 | virDomainDefParseNode; | ||
330 | 323 | virDomainDefParseString; | ||
331 | 324 | virDomainDeleteConfig; | ||
332 | 325 | virDomainDeviceAddressIsValid; | ||
333 | 326 | virDomainDeviceAddressTypeToString; | ||
334 | 327 | virDomainDeviceDefCopy; | ||
335 | 328 | virDomainDeviceDefFree; | ||
336 | 329 | virDomainDeviceDefParse; | ||
337 | 330 | virDomainDeviceInfoCopy; | ||
338 | 331 | virDomainDeviceInfoIterate; | ||
339 | 332 | virDomainDeviceTypeToString; | ||
340 | 333 | virDomainDiskBusTypeToString; | ||
341 | 334 | virDomainDiskCacheTypeFromString; | ||
342 | 335 | virDomainDiskCacheTypeToString; | ||
343 | 336 | virDomainDiskCopyOnReadTypeFromString; | ||
344 | 337 | virDomainDiskCopyOnReadTypeToString; | ||
345 | 338 | virDomainDiskDefAssignAddress; | ||
346 | 339 | virDomainDiskDefForeachPath; | ||
347 | 340 | virDomainDiskDefFree; | ||
348 | 341 | virDomainDiskDeviceTypeToString; | ||
349 | 342 | virDomainDiskErrorPolicyTypeFromString; | ||
350 | 343 | virDomainDiskErrorPolicyTypeToString; | ||
351 | 344 | virDomainDiskFindControllerModel; | ||
352 | 345 | virDomainDiskGeometryTransTypeFromString; | ||
353 | 346 | virDomainDiskGeometryTransTypeToString; | ||
354 | 347 | virDomainDiskIndexByName; | ||
355 | 348 | virDomainDiskInsert; | ||
356 | 349 | virDomainDiskInsertPreAlloced; | ||
357 | 350 | virDomainDiskIoTypeFromString; | ||
358 | 351 | virDomainDiskIoTypeToString; | ||
359 | 352 | virDomainDiskPathByName; | ||
360 | 353 | virDomainDiskRemove; | ||
361 | 354 | virDomainDiskRemoveByName; | ||
362 | 355 | virDomainDiskTypeFromString; | ||
363 | 356 | virDomainDiskTypeToString; | ||
364 | 357 | virDomainEmulatorPinAdd; | ||
365 | 358 | virDomainEmulatorPinDel; | ||
366 | 359 | virDomainFSDefFree; | ||
367 | 360 | virDomainFSIndexByName; | ||
368 | 361 | virDomainFSTypeFromString; | ||
369 | 362 | virDomainFSTypeToString; | ||
370 | 363 | virDomainFSWrpolicyTypeFromString; | ||
371 | 364 | virDomainFSWrpolicyTypeToString; | ||
372 | 365 | virDomainFeatureStateTypeFromString; | ||
373 | 366 | virDomainFeatureStateTypeToString; | ||
374 | 367 | virDomainFindByID; | ||
375 | 368 | virDomainFindByName; | ||
376 | 369 | virDomainFindByUUID; | ||
377 | 370 | virDomainGetRootFilesystem; | ||
378 | 371 | virDomainGraphicsAuthConnectedTypeFromString; | ||
379 | 372 | virDomainGraphicsAuthConnectedTypeToString; | ||
380 | 373 | virDomainGraphicsDefFree; | ||
381 | 374 | virDomainGraphicsListenGetAddress; | ||
382 | 375 | virDomainGraphicsListenGetNetwork; | ||
383 | 376 | virDomainGraphicsListenGetType; | ||
384 | 377 | virDomainGraphicsListenSetAddress; | ||
385 | 378 | virDomainGraphicsListenSetNetwork; | ||
386 | 379 | virDomainGraphicsListenSetType; | ||
387 | 380 | virDomainGraphicsSpiceChannelModeTypeFromString; | ||
388 | 381 | virDomainGraphicsSpiceChannelModeTypeToString; | ||
389 | 382 | virDomainGraphicsSpiceChannelNameTypeFromString; | ||
390 | 383 | virDomainGraphicsSpiceChannelNameTypeToString; | ||
391 | 384 | virDomainGraphicsSpiceClipboardCopypasteTypeFromString; | ||
392 | 385 | virDomainGraphicsSpiceClipboardCopypasteTypeToString; | ||
393 | 386 | virDomainGraphicsSpiceImageCompressionTypeFromString; | ||
394 | 387 | virDomainGraphicsSpiceImageCompressionTypeToString; | ||
395 | 388 | virDomainGraphicsSpiceJpegCompressionTypeFromString; | ||
396 | 389 | virDomainGraphicsSpiceJpegCompressionTypeToString; | ||
397 | 390 | virDomainGraphicsSpiceMouseModeTypeFromString; | ||
398 | 391 | virDomainGraphicsSpiceMouseModeTypeToString; | ||
399 | 392 | virDomainGraphicsSpicePlaybackCompressionTypeFromString; | ||
400 | 393 | virDomainGraphicsSpicePlaybackCompressionTypeToString; | ||
401 | 394 | virDomainGraphicsSpiceStreamingModeTypeFromString; | ||
402 | 395 | virDomainGraphicsSpiceStreamingModeTypeToString; | ||
403 | 396 | virDomainGraphicsSpiceZlibCompressionTypeFromString; | ||
404 | 397 | virDomainGraphicsSpiceZlibCompressionTypeToString; | ||
405 | 398 | virDomainGraphicsTypeFromString; | ||
406 | 399 | virDomainGraphicsTypeToString; | ||
407 | 400 | virDomainHasDiskMirror; | ||
408 | 401 | virDomainHostdevDefAlloc; | ||
409 | 402 | virDomainHostdevDefClear; | ||
410 | 403 | virDomainHostdevDefFree; | ||
411 | 404 | virDomainHostdevFind; | ||
412 | 405 | virDomainHostdevInsert; | ||
413 | 406 | virDomainHostdevModeTypeToString; | ||
414 | 407 | virDomainHostdevRemove; | ||
415 | 408 | virDomainHostdevSubsysTypeToString; | ||
416 | 409 | virDomainHubTypeFromString; | ||
417 | 410 | virDomainHubTypeToString; | ||
418 | 411 | virDomainHypervTypeFromString; | ||
419 | 412 | virDomainHypervTypeToString; | ||
420 | 413 | virDomainInputDefFree; | ||
421 | 414 | virDomainIoEventFdTypeFromString; | ||
422 | 415 | virDomainIoEventFdTypeToString; | ||
423 | 416 | virDomainLeaseDefFree; | ||
424 | 417 | virDomainLeaseIndex; | ||
425 | 418 | virDomainLeaseInsert; | ||
426 | 419 | virDomainLeaseInsertPreAlloc; | ||
427 | 420 | virDomainLeaseInsertPreAlloced; | ||
428 | 421 | virDomainLeaseRemove; | ||
429 | 422 | virDomainLeaseRemoveAt; | ||
430 | 423 | virDomainLifecycleCrashTypeFromString; | ||
431 | 424 | virDomainLifecycleCrashTypeToString; | ||
432 | 425 | virDomainLifecycleTypeFromString; | ||
433 | 426 | virDomainLifecycleTypeToString; | ||
434 | 427 | virDomainList; | ||
435 | 428 | virDomainLiveConfigHelperMethod; | ||
436 | 429 | virDomainLoadAllConfigs; | ||
437 | 430 | virDomainLockFailureTypeFromString; | ||
438 | 431 | virDomainLockFailureTypeToString; | ||
439 | 432 | virDomainLookupVcpuPin; | ||
440 | 433 | virDomainMemballoonModelTypeFromString; | ||
441 | 434 | virDomainMemballoonModelTypeToString; | ||
442 | 435 | virDomainMemDumpTypeFromString; | ||
443 | 436 | virDomainMemDumpTypeToString; | ||
444 | 437 | virDomainNetDefFree; | ||
445 | 438 | virDomainNetFind; | ||
446 | 439 | virDomainNetFindIdx; | ||
447 | 440 | virDomainNetGetActualBandwidth; | ||
448 | 441 | virDomainNetGetActualBridgeName; | ||
449 | 442 | virDomainNetGetActualDirectDev; | ||
450 | 443 | virDomainNetGetActualDirectMode; | ||
451 | 444 | virDomainNetGetActualHostdev; | ||
452 | 445 | virDomainNetGetActualType; | ||
453 | 446 | virDomainNetGetActualVirtPortProfile; | ||
454 | 447 | virDomainNetGetActualVlan; | ||
455 | 448 | virDomainNetInsert; | ||
456 | 449 | virDomainNetRemove; | ||
457 | 450 | virDomainNetTypeToString; | ||
458 | 451 | virDomainNostateReasonTypeFromString; | ||
459 | 452 | virDomainNostateReasonTypeToString; | ||
460 | 453 | virDomainNumatuneMemModeTypeFromString; | ||
461 | 454 | virDomainNumatuneMemModeTypeToString; | ||
462 | 455 | virDomainNumatuneMemPlacementModeTypeFromString; | ||
463 | 456 | virDomainNumatuneMemPlacementModeTypeToString; | ||
464 | 457 | virDomainObjAssignDef; | ||
465 | 458 | virDomainObjCopyPersistentDef; | ||
466 | 459 | virDomainObjGetPersistentDef; | ||
467 | 460 | virDomainObjGetState; | ||
468 | 461 | virDomainObjIsDuplicate; | ||
469 | 462 | virDomainObjListDeinit; | ||
470 | 463 | virDomainObjListGetActiveIDs; | ||
471 | 464 | virDomainObjListGetInactiveNames; | ||
472 | 465 | virDomainObjListInit; | ||
473 | 466 | virDomainObjListNumOfDomains; | ||
474 | 467 | virDomainObjLock; | ||
475 | 468 | virDomainObjNew; | ||
476 | 469 | virDomainObjSetDefTransient; | ||
477 | 470 | virDomainObjSetState; | ||
478 | 471 | virDomainObjTaint; | ||
479 | 472 | virDomainObjUnlock; | ||
480 | 473 | virDomainPausedReasonTypeFromString; | ||
481 | 474 | virDomainPausedReasonTypeToString; | ||
482 | 475 | virDomainPciRombarModeTypeFromString; | ||
483 | 476 | virDomainPciRombarModeTypeToString; | ||
484 | 477 | virDomainPMStateTypeFromString; | ||
485 | 478 | virDomainPMStateTypeToString; | ||
486 | 479 | virDomainRedirdevBusTypeFromString; | ||
487 | 480 | virDomainRedirdevBusTypeToString; | ||
488 | 481 | virDomainRemoveInactive; | ||
489 | 482 | virDomainRunningReasonTypeFromString; | ||
490 | 483 | virDomainRunningReasonTypeToString; | ||
491 | 484 | virDomainSaveConfig; | ||
492 | 485 | virDomainSaveStatus; | ||
493 | 486 | virDomainSaveXML; | ||
494 | 487 | virDomainSeclabelTypeFromString; | ||
495 | 488 | virDomainSeclabelTypeToString; | ||
496 | 489 | virDomainShutdownReasonTypeFromString; | ||
497 | 490 | virDomainShutdownReasonTypeToString; | ||
498 | 491 | virDomainShutoffReasonTypeFromString; | ||
499 | 492 | virDomainShutoffReasonTypeToString; | ||
500 | 493 | virDomainSmartcardDefForeach; | ||
501 | 494 | virDomainSmartcardDefFree; | ||
502 | 495 | virDomainSmartcardTypeFromString; | ||
503 | 496 | virDomainSmartcardTypeToString; | ||
504 | 497 | virDomainSmbiosModeTypeFromString; | ||
505 | 498 | virDomainSmbiosModeTypeToString; | ||
506 | 499 | virDomainSoundDefFree; | ||
507 | 500 | virDomainSoundModelTypeFromString; | ||
508 | 501 | virDomainSoundModelTypeToString; | ||
509 | 502 | virDomainStartupPolicyTypeFromString; | ||
510 | 503 | virDomainStartupPolicyTypeToString; | ||
511 | 504 | virDomainStateReasonFromString; | ||
512 | 505 | virDomainStateReasonToString; | ||
513 | 506 | virDomainStateTypeFromString; | ||
514 | 507 | virDomainStateTypeToString; | ||
515 | 508 | virDomainTaintTypeFromString; | ||
516 | 509 | virDomainTaintTypeToString; | ||
517 | 510 | virDomainTimerModeTypeFromString; | ||
518 | 511 | virDomainTimerModeTypeToString; | ||
519 | 512 | virDomainTimerNameTypeFromString; | ||
520 | 513 | virDomainTimerNameTypeToString; | ||
521 | 514 | virDomainTimerTickpolicyTypeFromString; | ||
522 | 515 | virDomainTimerTickpolicyTypeToString; | ||
523 | 516 | virDomainTimerTrackTypeFromString; | ||
524 | 517 | virDomainTimerTrackTypeToString; | ||
525 | 518 | virDomainVcpuPinAdd; | ||
526 | 519 | virDomainVcpuPinDefArrayFree; | ||
527 | 520 | virDomainVcpuPinDefCopy; | ||
528 | 521 | virDomainVcpuPinDefFree; | ||
529 | 522 | virDomainVcpuPinDel; | ||
530 | 523 | virDomainVcpuPinFindByVcpu; | ||
531 | 524 | virDomainVcpuPinIsDuplicate; | ||
532 | 525 | virDomainVideoDefFree; | ||
533 | 526 | virDomainVideoDefaultRAM; | ||
534 | 527 | virDomainVideoDefaultType; | ||
535 | 528 | virDomainVideoTypeFromString; | ||
536 | 529 | virDomainVideoTypeToString; | ||
537 | 530 | virDomainVirtTypeToString; | ||
538 | 531 | virDomainVirtioEventIdxTypeFromString; | ||
539 | 532 | virDomainVirtioEventIdxTypeToString; | ||
540 | 533 | virDomainWatchdogActionTypeFromString; | ||
541 | 534 | virDomainWatchdogActionTypeToString; | ||
542 | 535 | virDomainWatchdogModelTypeFromString; | ||
543 | 536 | virDomainWatchdogModelTypeToString; | ||
544 | 537 | |||
545 | 538 | |||
546 | 539 | # domain_event.h | ||
547 | 540 | virDomainEventBalloonChangeNewFromDom; | ||
548 | 541 | virDomainEventBalloonChangeNewFromObj; | ||
549 | 542 | virDomainEventBlockJobNewFromObj; | ||
550 | 543 | virDomainEventBlockJobNewFromDom; | ||
551 | 544 | virDomainEventControlErrorNewFromDom; | ||
552 | 545 | virDomainEventControlErrorNewFromObj; | ||
553 | 546 | virDomainEventDiskChangeNewFromDom; | ||
554 | 547 | virDomainEventDiskChangeNewFromObj; | ||
555 | 548 | virDomainEventFree; | ||
556 | 549 | virDomainEventGraphicsNewFromDom; | ||
557 | 550 | virDomainEventGraphicsNewFromObj; | ||
558 | 551 | virDomainEventIOErrorNewFromDom; | ||
559 | 552 | virDomainEventIOErrorNewFromObj; | ||
560 | 553 | virDomainEventIOErrorReasonNewFromDom; | ||
561 | 554 | virDomainEventIOErrorReasonNewFromObj; | ||
562 | 555 | virDomainEventNew; | ||
563 | 556 | virDomainEventNewFromDef; | ||
564 | 557 | virDomainEventNewFromDom; | ||
565 | 558 | virDomainEventNewFromObj; | ||
566 | 559 | virDomainEventPMSuspendNewFromDom; | ||
567 | 560 | virDomainEventPMSuspendNewFromObj; | ||
568 | 561 | virDomainEventPMWakeupNewFromDom; | ||
569 | 562 | virDomainEventPMWakeupNewFromObj; | ||
570 | 563 | virDomainEventRTCChangeNewFromDom; | ||
571 | 564 | virDomainEventRTCChangeNewFromObj; | ||
572 | 565 | virDomainEventRebootNew; | ||
573 | 566 | virDomainEventRebootNewFromDom; | ||
574 | 567 | virDomainEventRebootNewFromObj; | ||
575 | 568 | virDomainEventStateDeregister; | ||
576 | 569 | virDomainEventStateDeregisterID; | ||
577 | 570 | virDomainEventStateEventID; | ||
578 | 571 | virDomainEventStateRegister; | ||
579 | 572 | virDomainEventStateRegisterID; | ||
580 | 573 | virDomainEventStateFree; | ||
581 | 574 | virDomainEventStateNew; | ||
582 | 575 | virDomainEventStateQueue; | ||
583 | 576 | virDomainEventPMSuspendDiskNewFromDom; | ||
584 | 577 | virDomainEventPMSuspendDiskNewFromObj; | ||
585 | 578 | virDomainEventTrayChangeNewFromDom; | ||
586 | 579 | virDomainEventTrayChangeNewFromObj; | ||
587 | 580 | virDomainEventWatchdogNewFromDom; | ||
588 | 581 | virDomainEventWatchdogNewFromObj; | ||
589 | 582 | |||
590 | 583 | |||
591 | 584 | # domain_lock.h | ||
592 | 585 | virDomainLockProcessStart; | ||
593 | 586 | virDomainLockProcessInquire; | ||
594 | 587 | virDomainLockProcessPause; | ||
595 | 588 | virDomainLockProcessResume; | ||
596 | 589 | virDomainLockDiskAttach; | ||
597 | 590 | virDomainLockDiskDetach; | ||
598 | 591 | virDomainLockLeaseAttach; | ||
599 | 592 | virDomainLockLeaseDetach; | ||
600 | 593 | |||
601 | 594 | |||
602 | 595 | # domain_nwfilter.h | ||
603 | 596 | virDomainConfNWFilterInstantiate; | ||
604 | 597 | virDomainConfNWFilterRegister; | ||
605 | 598 | virDomainConfNWFilterTeardown; | ||
606 | 599 | virDomainConfVMNWFilterTeardown; | ||
607 | 600 | |||
608 | 601 | |||
609 | 602 | # ebtables.h | ||
610 | 603 | ebtablesAddForwardAllowIn; | ||
611 | 604 | ebtablesAddForwardPolicyReject; | ||
612 | 605 | ebtablesContextFree; | ||
613 | 606 | ebtablesContextNew; | ||
614 | 607 | ebtablesRemoveForwardAllowIn; | ||
615 | 608 | |||
616 | 609 | |||
617 | 610 | # event_poll.h | ||
618 | 611 | virEventPollAddHandle; | ||
619 | 612 | virEventPollAddTimeout; | ||
620 | 613 | virEventPollFromNativeEvents; | ||
621 | 614 | virEventPollInit; | ||
622 | 615 | virEventPollRemoveHandle; | ||
623 | 616 | virEventPollRemoveTimeout; | ||
624 | 617 | virEventPollRunOnce; | ||
625 | 618 | virEventPollToNativeEvents; | ||
626 | 619 | virEventPollUpdateHandle; | ||
627 | 620 | virEventPollUpdateTimeout; | ||
628 | 621 | |||
629 | 622 | |||
630 | 623 | # fdstream.h | ||
631 | 624 | virFDStreamOpen; | ||
632 | 625 | virFDStreamConnectUNIX; | ||
633 | 626 | virFDStreamOpenFile; | ||
634 | 627 | virFDStreamCreateFile; | ||
635 | 628 | |||
636 | 629 | |||
637 | 630 | # hash.h | ||
638 | 631 | virHashAddEntry; | ||
639 | 632 | virHashCreate; | ||
640 | 633 | virHashEqual; | ||
641 | 634 | virHashForEach; | ||
642 | 635 | virHashFree; | ||
643 | 636 | virHashGetItems; | ||
644 | 637 | virHashLookup; | ||
645 | 638 | virHashRemoveAll; | ||
646 | 639 | virHashRemoveEntry; | ||
647 | 640 | virHashRemoveSet; | ||
648 | 641 | virHashSearch; | ||
649 | 642 | virHashSize; | ||
650 | 643 | virHashSteal; | ||
651 | 644 | virHashTableSize; | ||
652 | 645 | virHashUpdateEntry; | ||
653 | 646 | |||
654 | 647 | |||
655 | 648 | # hooks.h | ||
656 | 649 | virHookCall; | ||
657 | 650 | virHookInitialize; | ||
658 | 651 | virHookPresent; | ||
659 | 652 | |||
660 | 653 | |||
661 | 654 | # interface_conf.h | ||
662 | 655 | virInterfaceAssignDef; | ||
663 | 656 | virInterfaceDefFormat; | ||
664 | 657 | virInterfaceDefFree; | ||
665 | 658 | virInterfaceDefParseFile; | ||
666 | 659 | virInterfaceDefParseNode; | ||
667 | 660 | virInterfaceDefParseString; | ||
668 | 661 | virInterfaceFindByMACString; | ||
669 | 662 | virInterfaceFindByName; | ||
670 | 663 | virInterfaceObjListClone; | ||
671 | 664 | virInterfaceObjListFree; | ||
672 | 665 | virInterfaceObjLock; | ||
673 | 666 | virInterfaceObjUnlock; | ||
674 | 667 | virInterfaceRemove; | ||
675 | 668 | |||
676 | 669 | |||
677 | 670 | # iptables.h | ||
678 | 671 | iptablesAddForwardAllowCross; | ||
679 | 672 | iptablesAddForwardAllowIn; | ||
680 | 673 | iptablesAddForwardAllowOut; | ||
681 | 674 | iptablesAddForwardAllowRelatedIn; | ||
682 | 675 | iptablesAddForwardMasquerade; | ||
683 | 676 | iptablesAddForwardRejectIn; | ||
684 | 677 | iptablesAddForwardRejectOut; | ||
685 | 678 | iptablesAddOutputFixUdpChecksum; | ||
686 | 679 | iptablesAddTcpInput; | ||
687 | 680 | iptablesAddUdpInput; | ||
688 | 681 | iptablesContextFree; | ||
689 | 682 | iptablesContextNew; | ||
690 | 683 | iptablesRemoveForwardAllowCross; | ||
691 | 684 | iptablesRemoveForwardAllowIn; | ||
692 | 685 | iptablesRemoveForwardAllowOut; | ||
693 | 686 | iptablesRemoveForwardAllowRelatedIn; | ||
694 | 687 | iptablesRemoveForwardMasquerade; | ||
695 | 688 | iptablesRemoveForwardRejectIn; | ||
696 | 689 | iptablesRemoveForwardRejectOut; | ||
697 | 690 | iptablesRemoveOutputFixUdpChecksum; | ||
698 | 691 | iptablesRemoveTcpInput; | ||
699 | 692 | iptablesRemoveUdpInput; | ||
700 | 693 | |||
701 | 694 | |||
702 | 695 | # json.h | ||
703 | 696 | virJSONValueArrayAppend; | ||
704 | 697 | virJSONValueArrayGet; | ||
705 | 698 | virJSONValueArraySize; | ||
706 | 699 | virJSONValueFree; | ||
707 | 700 | virJSONValueFromString; | ||
708 | 701 | virJSONValueGetBoolean; | ||
709 | 702 | virJSONValueGetNumberDouble; | ||
710 | 703 | virJSONValueGetNumberInt; | ||
711 | 704 | virJSONValueGetNumberLong; | ||
712 | 705 | virJSONValueGetNumberUint; | ||
713 | 706 | virJSONValueGetNumberUlong; | ||
714 | 707 | virJSONValueGetString; | ||
715 | 708 | virJSONValueIsNull; | ||
716 | 709 | virJSONValueNewArray; | ||
717 | 710 | virJSONValueNewBoolean; | ||
718 | 711 | virJSONValueNewNull; | ||
719 | 712 | virJSONValueNewNumberDouble; | ||
720 | 713 | virJSONValueNewNumberInt; | ||
721 | 714 | virJSONValueNewNumberLong; | ||
722 | 715 | virJSONValueNewNumberUint; | ||
723 | 716 | virJSONValueNewNumberUlong; | ||
724 | 717 | virJSONValueNewObject; | ||
725 | 718 | virJSONValueNewString; | ||
726 | 719 | virJSONValueNewStringLen; | ||
727 | 720 | virJSONValueObjectAppend; | ||
728 | 721 | virJSONValueObjectAppendBoolean; | ||
729 | 722 | virJSONValueObjectAppendNull; | ||
730 | 723 | virJSONValueObjectAppendNumberDouble; | ||
731 | 724 | virJSONValueObjectAppendNumberInt; | ||
732 | 725 | virJSONValueObjectAppendNumberLong; | ||
733 | 726 | virJSONValueObjectAppendNumberUint; | ||
734 | 727 | virJSONValueObjectAppendNumberUlong; | ||
735 | 728 | virJSONValueObjectAppendString; | ||
736 | 729 | virJSONValueObjectGet; | ||
737 | 730 | virJSONValueObjectGetBoolean; | ||
738 | 731 | virJSONValueObjectGetKey; | ||
739 | 732 | virJSONValueObjectGetNumberDouble; | ||
740 | 733 | virJSONValueObjectGetNumberInt; | ||
741 | 734 | virJSONValueObjectGetNumberLong; | ||
742 | 735 | virJSONValueObjectGetNumberUint; | ||
743 | 736 | virJSONValueObjectGetNumberUlong; | ||
744 | 737 | virJSONValueObjectGetString; | ||
745 | 738 | virJSONValueObjectGetValue; | ||
746 | 739 | virJSONValueObjectHasKey; | ||
747 | 740 | virJSONValueObjectIsNull; | ||
748 | 741 | virJSONValueObjectKeysNumber; | ||
749 | 742 | virJSONValueToString; | ||
750 | 743 | |||
751 | 744 | |||
752 | 745 | # libvirt_internal.h | ||
753 | 746 | virDomainMigrateFinish2; | ||
754 | 747 | virDomainMigrateFinish; | ||
755 | 748 | virDomainMigratePerform; | ||
756 | 749 | virDomainMigratePrepare2; | ||
757 | 750 | virDomainMigratePrepare; | ||
758 | 751 | virDomainMigratePrepareTunnel; | ||
759 | 752 | virDomainMigrateBegin3; | ||
760 | 753 | virDomainMigratePrepare3; | ||
761 | 754 | virDomainMigratePrepareTunnel3; | ||
762 | 755 | virDomainMigratePerform3; | ||
763 | 756 | virDomainMigrateFinish3; | ||
764 | 757 | virDomainMigrateConfirm3; | ||
765 | 758 | virDrvSupportsFeature; | ||
766 | 759 | virRegisterDeviceMonitor; | ||
767 | 760 | virRegisterDriver; | ||
768 | 761 | virRegisterInterfaceDriver; | ||
769 | 762 | virRegisterNWFilterDriver; | ||
770 | 763 | virRegisterNetworkDriver; | ||
771 | 764 | virRegisterSecretDriver; | ||
772 | 765 | virRegisterStorageDriver; | ||
773 | 766 | |||
774 | 767 | |||
775 | 768 | # locking.h | ||
776 | 769 | virLockManagerAcquire; | ||
777 | 770 | virLockManagerAddResource; | ||
778 | 771 | virLockManagerFree; | ||
779 | 772 | virLockManagerInquire; | ||
780 | 773 | virLockManagerNew; | ||
781 | 774 | virLockManagerPluginNew; | ||
782 | 775 | virLockManagerPluginRef; | ||
783 | 776 | virLockManagerPluginUnref; | ||
784 | 777 | virLockManagerPluginUsesState; | ||
785 | 778 | virLockManagerPluginGetName; | ||
786 | 779 | virLockManagerRelease; | ||
787 | 780 | virLockManagerSetPluginDir; | ||
788 | 781 | |||
789 | 782 | |||
790 | 783 | # logging.h | ||
791 | 784 | virLogDefineFilter; | ||
792 | 785 | virLogDefineOutput; | ||
793 | 786 | virLogEmergencyDumpAll; | ||
794 | 787 | virLogGetDefaultPriority; | ||
795 | 788 | virLogGetFilters; | ||
796 | 789 | virLogGetNbFilters; | ||
797 | 790 | virLogGetNbOutputs; | ||
798 | 791 | virLogGetOutputs; | ||
799 | 792 | virLogLock; | ||
800 | 793 | virLogMessage; | ||
801 | 794 | virLogParseDefaultPriority; | ||
802 | 795 | virLogParseFilters; | ||
803 | 796 | virLogParseOutputs; | ||
804 | 797 | virLogReset; | ||
805 | 798 | virLogSetBufferSize; | ||
806 | 799 | virLogSetDefaultPriority; | ||
807 | 800 | virLogSetFromEnv; | ||
808 | 801 | virLogUnlock; | ||
809 | 802 | |||
810 | 803 | |||
811 | 804 | # memory.h | ||
812 | 805 | virAlloc; | ||
813 | 806 | virAllocN; | ||
814 | 807 | virAllocVar; | ||
815 | 808 | virExpandN; | ||
816 | 809 | virFree; | ||
817 | 810 | virReallocN; | ||
818 | 811 | virResizeN; | ||
819 | 812 | virShrinkN; | ||
820 | 813 | |||
821 | 814 | |||
822 | 815 | # netdev_bandwidth_conf.h | ||
823 | 816 | virNetDevBandwidthFormat; | ||
824 | 817 | virNetDevBandwidthParse; | ||
825 | 818 | |||
826 | 819 | |||
827 | 820 | #netdev_vlan_conf.h | ||
828 | 821 | virNetDevVlanFormat; | ||
829 | 822 | virNetDevVlanParse; | ||
830 | 823 | |||
831 | 824 | |||
832 | 825 | # netdev_vportprofile_conf.h | ||
833 | 826 | virNetDevVPortProfileFormat; | ||
834 | 827 | virNetDevVPortProfileParse; | ||
835 | 828 | virNetDevVPortTypeFromString; | ||
836 | 829 | virNetDevVPortTypeToString; | ||
837 | 830 | |||
838 | 831 | |||
839 | 832 | # network_conf.h | ||
840 | 833 | virNetworkAssignDef; | ||
841 | 834 | virNetworkConfigFile; | ||
842 | 835 | virNetworkConfigChangeSetup; | ||
843 | 836 | virNetworkDefCopy; | ||
844 | 837 | virNetworkDefFormat; | ||
845 | 838 | virNetworkDefFree; | ||
846 | 839 | virNetworkDefGetIpByIndex; | ||
847 | 840 | virNetworkDefParseFile; | ||
848 | 841 | virNetworkDefParseNode; | ||
849 | 842 | virNetworkDefParseString; | ||
850 | 843 | virNetworkDeleteConfig; | ||
851 | 844 | virNetworkFindByName; | ||
852 | 845 | virNetworkFindByUUID; | ||
853 | 846 | virNetworkIpDefNetmask; | ||
854 | 847 | virNetworkIpDefPrefix; | ||
855 | 848 | virNetworkList; | ||
856 | 849 | virNetworkLoadAllConfigs; | ||
857 | 850 | virNetworkObjAssignDef; | ||
858 | 851 | virNetworkObjFree; | ||
859 | 852 | virNetworkObjGetPersistentDef; | ||
860 | 853 | virNetworkObjIsDuplicate; | ||
861 | 854 | virNetworkObjListFree; | ||
862 | 855 | virNetworkObjLock; | ||
863 | 856 | virNetworkObjReplacePersistentDef; | ||
864 | 857 | virNetworkObjSetDefTransient; | ||
865 | 858 | virNetworkObjUnlock; | ||
866 | 859 | virNetworkObjUnsetDefTransient; | ||
867 | 860 | virNetworkObjUpdate; | ||
868 | 861 | virNetworkRemoveInactive; | ||
869 | 862 | virNetworkSaveConfig; | ||
870 | 863 | virNetworkSaveStatus; | ||
871 | 864 | virNetworkSetBridgeMacAddr; | ||
872 | 865 | virNetworkSetBridgeName; | ||
873 | 866 | virPortGroupFindByName; | ||
874 | 867 | |||
875 | 868 | |||
876 | 869 | # node_device_conf.h | ||
877 | 870 | virNodeDevCapTypeFromString; | ||
878 | 871 | virNodeDevCapTypeToString; | ||
879 | 872 | virNodeDevCapsDefFree; | ||
880 | 873 | virNodeDeviceAssignDef; | ||
881 | 874 | virNodeDeviceDefFormat; | ||
882 | 875 | virNodeDeviceDefFree; | ||
883 | 876 | virNodeDeviceDefParseFile; | ||
884 | 877 | virNodeDeviceDefParseNode; | ||
885 | 878 | virNodeDeviceDefParseString; | ||
886 | 879 | virNodeDeviceFindByName; | ||
887 | 880 | virNodeDeviceFindBySysfsPath; | ||
888 | 881 | virNodeDeviceGetParentHost; | ||
889 | 882 | virNodeDeviceGetWWNs; | ||
890 | 883 | virNodeDeviceHasCap; | ||
891 | 884 | virNodeDeviceList; | ||
892 | 885 | virNodeDeviceObjListFree; | ||
893 | 886 | virNodeDeviceObjLock; | ||
894 | 887 | virNodeDeviceObjRemove; | ||
895 | 888 | virNodeDeviceObjUnlock; | ||
896 | 889 | |||
897 | 890 | |||
898 | 891 | # nodeinfo.h | ||
899 | 892 | nodeCapsInitNUMA; | ||
900 | 893 | nodeGetCPUBitmap; | ||
901 | 894 | nodeGetCPUCount; | ||
902 | 895 | nodeGetCPUMap; | ||
903 | 896 | nodeGetCPUStats; | ||
904 | 897 | nodeGetCellsFreeMemory; | ||
905 | 898 | nodeGetFreeMemory; | ||
906 | 899 | nodeGetInfo; | ||
907 | 900 | nodeGetMemoryParameters; | ||
908 | 901 | nodeGetMemoryStats; | ||
909 | 902 | nodeSetMemoryParameters; | ||
910 | 903 | |||
911 | 904 | |||
912 | 905 | # nwfilter_conf.h | ||
913 | 906 | virNWFilterCallbackDriversLock; | ||
914 | 907 | virNWFilterCallbackDriversUnlock; | ||
915 | 908 | virNWFilterChainSuffixTypeToString; | ||
916 | 909 | virNWFilterConfLayerInit; | ||
917 | 910 | virNWFilterConfLayerShutdown; | ||
918 | 911 | virNWFilterDefFormat; | ||
919 | 912 | virNWFilterDefFree; | ||
920 | 913 | virNWFilterDefParseString; | ||
921 | 914 | virNWFilterInstFiltersOnAllVMs; | ||
922 | 915 | virNWFilterJumpTargetTypeToString; | ||
923 | 916 | virNWFilterLoadAllConfigs; | ||
924 | 917 | virNWFilterLockFilterUpdates; | ||
925 | 918 | virNWFilterObjAssignDef; | ||
926 | 919 | virNWFilterObjDeleteDef; | ||
927 | 920 | virNWFilterObjFindByName; | ||
928 | 921 | virNWFilterObjFindByUUID; | ||
929 | 922 | virNWFilterObjListFree; | ||
930 | 923 | virNWFilterObjLock; | ||
931 | 924 | virNWFilterObjRemove; | ||
932 | 925 | virNWFilterObjSaveDef; | ||
933 | 926 | virNWFilterObjUnlock; | ||
934 | 927 | virNWFilterPrintStateMatchFlags; | ||
935 | 928 | virNWFilterPrintTCPFlags; | ||
936 | 929 | virNWFilterRegisterCallbackDriver; | ||
937 | 930 | virNWFilterRuleActionTypeToString; | ||
938 | 931 | virNWFilterRuleDirectionTypeToString; | ||
939 | 932 | virNWFilterRuleProtocolTypeToString; | ||
940 | 933 | virNWFilterTestUnassignDef; | ||
941 | 934 | virNWFilterUnRegisterCallbackDriver; | ||
942 | 935 | virNWFilterUnlockFilterUpdates; | ||
943 | 936 | |||
944 | 937 | |||
945 | 938 | # nwfilter_ipaddrmap | ||
946 | 939 | virNWFilterIPAddrMapAddIPAddr; | ||
947 | 940 | virNWFilterIPAddrMapDelIPAddr; | ||
948 | 941 | virNWFilterIPAddrMapGetIPAddr; | ||
949 | 942 | virNWFilterIPAddrMapInit; | ||
950 | 943 | virNWFilterIPAddrMapShutdown; | ||
951 | 944 | |||
952 | 945 | |||
953 | 946 | # nwfilter_params.h | ||
954 | 947 | virNWFilterHashTableCreate; | ||
955 | 948 | virNWFilterHashTableFree; | ||
956 | 949 | virNWFilterHashTablePut; | ||
957 | 950 | virNWFilterHashTablePutAll; | ||
958 | 951 | virNWFilterHashTableRemoveEntry; | ||
959 | 952 | virNWFilterVarAccessGetVarName; | ||
960 | 953 | virNWFilterVarAccessIsAvailable; | ||
961 | 954 | virNWFilterVarAccessPrint; | ||
962 | 955 | virNWFilterVarCombIterCreate; | ||
963 | 956 | virNWFilterVarCombIterFree; | ||
964 | 957 | virNWFilterVarCombIterGetVarValue; | ||
965 | 958 | virNWFilterVarCombIterNext; | ||
966 | 959 | virNWFilterVarValueAddValue; | ||
967 | 960 | virNWFilterVarValueCopy; | ||
968 | 961 | virNWFilterVarValueCreateSimple; | ||
969 | 962 | virNWFilterVarValueCreateSimpleCopyValue; | ||
970 | 963 | virNWFilterVarValueDelValue; | ||
971 | 964 | virNWFilterVarValueFree; | ||
972 | 965 | virNWFilterVarValueGetCardinality; | ||
973 | 966 | virNWFilterVarValueGetNthValue; | ||
974 | 967 | virNWFilterVarValueGetSimple; | ||
975 | 968 | |||
976 | 969 | |||
977 | 970 | # pci.h | ||
978 | 971 | pciConfigAddressToSysfsFile; | ||
979 | 972 | pciDettachDevice; | ||
980 | 973 | pciDeviceFileIterate; | ||
981 | 974 | pciDeviceGetManaged; | ||
982 | 975 | pciDeviceGetName; | ||
983 | 976 | pciDeviceGetRemoveSlot; | ||
984 | 977 | pciDeviceGetReprobe; | ||
985 | 978 | pciDeviceGetUnbindFromStub; | ||
986 | 979 | pciDeviceGetUsedBy; | ||
987 | 980 | pciDeviceGetVirtualFunctionInfo; | ||
988 | 981 | pciDeviceIsAssignable; | ||
989 | 982 | pciDeviceIsVirtualFunction; | ||
990 | 983 | pciDeviceListAdd; | ||
991 | 984 | pciDeviceListCount; | ||
992 | 985 | pciDeviceListDel; | ||
993 | 986 | pciDeviceListFind; | ||
994 | 987 | pciDeviceListFree; | ||
995 | 988 | pciDeviceListGet; | ||
996 | 989 | pciDeviceListNew; | ||
997 | 990 | pciDeviceListSteal; | ||
998 | 991 | pciDeviceNetName; | ||
999 | 992 | pciDeviceReAttachInit; | ||
1000 | 993 | pciDeviceSetManaged; | ||
1001 | 994 | pciDeviceSetRemoveSlot; | ||
1002 | 995 | pciDeviceSetReprobe; | ||
1003 | 996 | pciDeviceSetUnbindFromStub; | ||
1004 | 997 | pciDeviceSetUsedBy; | ||
1005 | 998 | pciFreeDevice; | ||
1006 | 999 | pciGetDevice; | ||
1007 | 1000 | pciGetPhysicalFunction; | ||
1008 | 1001 | pciGetVirtualFunctionIndex; | ||
1009 | 1002 | pciGetVirtualFunctions; | ||
1010 | 1003 | pciReAttachDevice; | ||
1011 | 1004 | pciResetDevice; | ||
1012 | 1005 | pciWaitForDeviceCleanup; | ||
1013 | 1006 | |||
1014 | 1007 | |||
1015 | 1008 | # processinfo.h | ||
1016 | 1009 | virProcessInfoGetAffinity; | ||
1017 | 1010 | virProcessInfoSetAffinity; | ||
1018 | 1011 | |||
1019 | 1012 | |||
1020 | 1013 | # secret_conf.h | ||
1021 | 1014 | virSecretDefFormat; | ||
1022 | 1015 | virSecretDefFree; | ||
1023 | 1016 | virSecretDefParseFile; | ||
1024 | 1017 | virSecretDefParseString; | ||
1025 | 1018 | virSecretUsageTypeTypeFromString; | ||
1026 | 1019 | virSecretUsageTypeTypeToString; | ||
1027 | 1020 | |||
1028 | 1021 | |||
1029 | 1022 | # security_driver.h | ||
1030 | 1023 | virSecurityDriverLookup; | ||
1031 | 1024 | |||
1032 | 1025 | |||
1033 | 1026 | # security_manager.h | ||
1034 | 1027 | virSecurityManagerClearSocketLabel; | ||
1035 | 1028 | virSecurityManagerFree; | ||
1036 | 1029 | virSecurityManagerGenLabel; | ||
1037 | 1030 | virSecurityManagerGetDOI; | ||
1038 | 1031 | virSecurityManagerGetModel; | ||
1039 | 1032 | virSecurityManagerGetNested; | ||
1040 | 1033 | virSecurityManagerGetProcessLabel; | ||
1041 | 1034 | virSecurityManagerNew; | ||
1042 | 1035 | virSecurityManagerNewStack; | ||
1043 | 1036 | virSecurityManagerNewDAC; | ||
1044 | 1037 | virSecurityManagerReleaseLabel; | ||
1045 | 1038 | virSecurityManagerReserveLabel; | ||
1046 | 1039 | virSecurityManagerRestoreImageLabel; | ||
1047 | 1040 | virSecurityManagerRestoreAllLabel; | ||
1048 | 1041 | virSecurityManagerRestoreHostdevLabel; | ||
1049 | 1042 | virSecurityManagerRestoreSavedStateLabel; | ||
1050 | 1043 | virSecurityManagerSetAllLabel; | ||
1051 | 1044 | virSecurityManagerSetDaemonSocketLabel; | ||
1052 | 1045 | virSecurityManagerSetImageFDLabel; | ||
1053 | 1046 | virSecurityManagerSetImageLabel; | ||
1054 | 1047 | virSecurityManagerSetHostdevLabel; | ||
1055 | 1048 | virSecurityManagerSetProcessLabel; | ||
1056 | 1049 | virSecurityManagerSetSavedStateLabel; | ||
1057 | 1050 | virSecurityManagerSetSocketLabel; | ||
1058 | 1051 | virSecurityManagerSetTapFDLabel; | ||
1059 | 1052 | virSecurityManagerStackAddNested; | ||
1060 | 1053 | virSecurityManagerVerify; | ||
1061 | 1054 | virSecurityManagerGetMountOptions; | ||
1062 | 1055 | |||
1063 | 1056 | # sexpr.h | ||
1064 | 1057 | sexpr_append; | ||
1065 | 1058 | sexpr_cons; | ||
1066 | 1059 | sexpr_float; | ||
1067 | 1060 | sexpr_fmt_node; | ||
1068 | 1061 | sexpr_free; | ||
1069 | 1062 | sexpr_has; | ||
1070 | 1063 | sexpr_int; | ||
1071 | 1064 | sexpr_lookup; | ||
1072 | 1065 | sexpr_nil; | ||
1073 | 1066 | sexpr_node; | ||
1074 | 1067 | sexpr_node_copy; | ||
1075 | 1068 | sexpr_string; | ||
1076 | 1069 | sexpr_u64; | ||
1077 | 1070 | sexpr2string; | ||
1078 | 1071 | string2sexpr; | ||
1079 | 1072 | |||
1080 | 1073 | |||
1081 | 1074 | # snapshot_conf.h | ||
1082 | 1075 | virDomainListSnapshots; | ||
1083 | 1076 | virDomainSnapshotAlignDisks; | ||
1084 | 1077 | virDomainSnapshotAssignDef; | ||
1085 | 1078 | virDomainSnapshotDefFormat; | ||
1086 | 1079 | virDomainSnapshotDefFree; | ||
1087 | 1080 | virDomainSnapshotDefParseString; | ||
1088 | 1081 | virDomainSnapshotDropParent; | ||
1089 | 1082 | virDomainSnapshotFindByName; | ||
1090 | 1083 | virDomainSnapshotForEach; | ||
1091 | 1084 | virDomainSnapshotForEachChild; | ||
1092 | 1085 | virDomainSnapshotForEachDescendant; | ||
1093 | 1086 | virDomainSnapshotLocationTypeFromString; | ||
1094 | 1087 | virDomainSnapshotLocationTypeToString; | ||
1095 | 1088 | virDomainSnapshotObjListGetNames; | ||
1096 | 1089 | virDomainSnapshotObjListNum; | ||
1097 | 1090 | virDomainSnapshotObjListRemove; | ||
1098 | 1091 | virDomainSnapshotStateTypeFromString; | ||
1099 | 1092 | virDomainSnapshotStateTypeToString; | ||
1100 | 1093 | virDomainSnapshotUpdateRelations; | ||
1101 | 1094 | |||
1102 | 1095 | |||
1103 | 1096 | # storage_conf.h | ||
1104 | 1097 | virStoragePartedFsTypeTypeToString; | ||
1105 | 1098 | virStoragePoolDefFormat; | ||
1106 | 1099 | virStoragePoolDefFree; | ||
1107 | 1100 | virStoragePoolDefParseFile; | ||
1108 | 1101 | virStoragePoolDefParseNode; | ||
1109 | 1102 | virStoragePoolDefParseSourceString; | ||
1110 | 1103 | virStoragePoolDefParseString; | ||
1111 | 1104 | virStoragePoolFormatDiskTypeToString; | ||
1112 | 1105 | virStoragePoolFormatFileSystemNetTypeToString; | ||
1113 | 1106 | virStoragePoolFormatFileSystemTypeToString; | ||
1114 | 1107 | virStoragePoolList; | ||
1115 | 1108 | virStoragePoolLoadAllConfigs; | ||
1116 | 1109 | virStoragePoolObjAssignDef; | ||
1117 | 1110 | virStoragePoolObjClearVols; | ||
1118 | 1111 | virStoragePoolObjDeleteDef; | ||
1119 | 1112 | virStoragePoolObjFindByName; | ||
1120 | 1113 | virStoragePoolObjFindByUUID; | ||
1121 | 1114 | virStoragePoolObjIsDuplicate; | ||
1122 | 1115 | virStoragePoolObjListFree; | ||
1123 | 1116 | virStoragePoolObjLock; | ||
1124 | 1117 | virStoragePoolObjRemove; | ||
1125 | 1118 | virStoragePoolObjSaveDef; | ||
1126 | 1119 | virStoragePoolObjUnlock; | ||
1127 | 1120 | virStoragePoolSourceClear; | ||
1128 | 1121 | virStoragePoolSourceFindDuplicate; | ||
1129 | 1122 | virStoragePoolSourceFindDuplicateDevices; | ||
1130 | 1123 | virStoragePoolSourceFree; | ||
1131 | 1124 | virStoragePoolSourceListFormat; | ||
1132 | 1125 | virStoragePoolSourceListNewSource; | ||
1133 | 1126 | virStoragePoolTypeFromString; | ||
1134 | 1127 | virStorageVolDefFindByKey; | ||
1135 | 1128 | virStorageVolDefFindByName; | ||
1136 | 1129 | virStorageVolDefFindByPath; | ||
1137 | 1130 | virStorageVolDefFormat; | ||
1138 | 1131 | virStorageVolDefFree; | ||
1139 | 1132 | virStorageVolDefParseFile; | ||
1140 | 1133 | virStorageVolDefParseNode; | ||
1141 | 1134 | virStorageVolDefParseString; | ||
1142 | 1135 | |||
1143 | 1136 | |||
1144 | 1137 | # storage_encryption_conf.h | ||
1145 | 1138 | virStorageEncryptionFormat; | ||
1146 | 1139 | virStorageEncryptionFree; | ||
1147 | 1140 | virStorageEncryptionParseNode; | ||
1148 | 1141 | virStorageGenerateQcowPassphrase; | ||
1149 | 1142 | |||
1150 | 1143 | |||
1151 | 1144 | # storage_file.h | ||
1152 | 1145 | virStorageFileChainLookup; | ||
1153 | 1146 | virStorageFileFormatTypeFromString; | ||
1154 | 1147 | virStorageFileFormatTypeToString; | ||
1155 | 1148 | virStorageFileFreeMetadata; | ||
1156 | 1149 | virStorageFileGetMetadata; | ||
1157 | 1150 | virStorageFileGetMetadataFromFD; | ||
1158 | 1151 | virStorageFileIsClusterFS; | ||
1159 | 1152 | virStorageFileIsSharedFS; | ||
1160 | 1153 | virStorageFileIsSharedFSType; | ||
1161 | 1154 | virStorageFileProbeFormat; | ||
1162 | 1155 | virStorageFileProbeFormatFromFD; | ||
1163 | 1156 | virStorageFileResize; | ||
1164 | 1157 | |||
1165 | 1158 | # sysinfo.h | ||
1166 | 1159 | virSysinfoDefFree; | ||
1167 | 1160 | virSysinfoFormat; | ||
1168 | 1161 | virSysinfoRead; | ||
1169 | 1162 | |||
1170 | 1163 | |||
1171 | 1164 | # threadpool.h | ||
1172 | 1165 | virThreadPoolFree; | ||
1173 | 1166 | virThreadPoolNew; | ||
1174 | 1167 | virThreadPoolSendJob; | ||
1175 | 1168 | virThreadPoolGetMinWorkers; | ||
1176 | 1169 | virThreadPoolGetMaxWorkers; | ||
1177 | 1170 | virThreadPoolGetPriorityWorkers; | ||
1178 | 1171 | |||
1179 | 1172 | |||
1180 | 1173 | # threads.h | ||
1181 | 1174 | virCondBroadcast; | ||
1182 | 1175 | virCondDestroy; | ||
1183 | 1176 | virCondInit; | ||
1184 | 1177 | virCondSignal; | ||
1185 | 1178 | virCondWait; | ||
1186 | 1179 | virCondWaitUntil; | ||
1187 | 1180 | virMutexDestroy; | ||
1188 | 1181 | virMutexInit; | ||
1189 | 1182 | virMutexInitRecursive; | ||
1190 | 1183 | virMutexLock; | ||
1191 | 1184 | virMutexUnlock; | ||
1192 | 1185 | virOnce; | ||
1193 | 1186 | virThreadCreate; | ||
1194 | 1187 | virThreadID; | ||
1195 | 1188 | virThreadInitialize; | ||
1196 | 1189 | virThreadIsSelf; | ||
1197 | 1190 | virThreadJoin; | ||
1198 | 1191 | virThreadSelf; | ||
1199 | 1192 | virThreadSelfID; | ||
1200 | 1193 | |||
1201 | 1194 | |||
1202 | 1195 | # usb.h | ||
1203 | 1196 | usbDeviceFileIterate; | ||
1204 | 1197 | usbDeviceGetBus; | ||
1205 | 1198 | usbDeviceGetDevno; | ||
1206 | 1199 | usbDeviceGetName; | ||
1207 | 1200 | usbDeviceGetUsedBy; | ||
1208 | 1201 | usbDeviceListAdd; | ||
1209 | 1202 | usbDeviceListCount; | ||
1210 | 1203 | usbDeviceListDel; | ||
1211 | 1204 | usbDeviceListFind; | ||
1212 | 1205 | usbDeviceListFree; | ||
1213 | 1206 | usbDeviceListGet; | ||
1214 | 1207 | usbDeviceListNew; | ||
1215 | 1208 | usbDeviceListSteal; | ||
1216 | 1209 | usbDeviceSetUsedBy; | ||
1217 | 1210 | usbFindDevice; | ||
1218 | 1211 | usbFindDeviceByBus; | ||
1219 | 1212 | usbFindDeviceByVendor; | ||
1220 | 1213 | usbFreeDevice; | ||
1221 | 1214 | usbGetDevice; | ||
1222 | 1215 | |||
1223 | 1216 | |||
1224 | 1217 | # util.h | ||
1225 | 1218 | saferead; | ||
1226 | 1219 | safewrite; | ||
1227 | 1220 | safezero; | ||
1228 | 1221 | virArgvToString; | ||
1229 | 1222 | virAsprintf; | ||
1230 | 1223 | virBuildPathInternal; | ||
1231 | 1224 | virDirCreate; | ||
1232 | 1225 | virDoubleToStr; | ||
1233 | 1226 | virEnumFromString; | ||
1234 | 1227 | virEnumToString; | ||
1235 | 1228 | virFileAbsPath; | ||
1236 | 1229 | virFileAccessibleAs; | ||
1237 | 1230 | virFileBuildPath; | ||
1238 | 1231 | virFileExists; | ||
1239 | 1232 | virFileFindMountPoint; | ||
1240 | 1233 | virFileHasSuffix; | ||
1241 | 1234 | virFileIsAbsPath; | ||
1242 | 1235 | virFileIsExecutable; | ||
1243 | 1236 | virFileIsLink; | ||
1244 | 1237 | virFileIsDir; | ||
1245 | 1238 | virFileLinkPointsTo; | ||
1246 | 1239 | virFileLock; | ||
1247 | 1240 | virFileMakePath; | ||
1248 | 1241 | virFileMakePathWithMode; | ||
1249 | 1242 | virFileMatchesNameSuffix; | ||
1250 | 1243 | virFileOpenAs; | ||
1251 | 1244 | virFileOpenTty; | ||
1252 | 1245 | virFileReadAll; | ||
1253 | 1246 | virFileReadLimFD; | ||
1254 | 1247 | virFileResolveAllLinks; | ||
1255 | 1248 | virFileResolveLink; | ||
1256 | 1249 | virFileSanitizePath; | ||
1257 | 1250 | virFileSkipRoot; | ||
1258 | 1251 | virFileStripSuffix; | ||
1259 | 1252 | virFileUnlock; | ||
1260 | 1253 | virFileWaitForDevices; | ||
1261 | 1254 | virFileWriteStr; | ||
1262 | 1255 | virFindFileInPath; | ||
1263 | 1256 | virFormatIntDecimal; | ||
1264 | 1257 | virGetGroupID; | ||
1265 | 1258 | virGetGroupName; | ||
1266 | 1259 | virGetHostname; | ||
1267 | 1260 | virGetUserDirectory; | ||
1268 | 1261 | virGetUserConfigDirectory; | ||
1269 | 1262 | virGetUserCacheDirectory; | ||
1270 | 1263 | virGetUserRuntimeDirectory; | ||
1271 | 1264 | virGetUserID; | ||
1272 | 1265 | virGetUserName; | ||
1273 | 1266 | virHexToBin; | ||
1274 | 1267 | virIndexToDiskName; | ||
1275 | 1268 | virIsDevMapperDevice; | ||
1276 | 1269 | virParseNumber; | ||
1277 | 1270 | virParseVersionString; | ||
1278 | 1271 | virPipeReadUntilEOF; | ||
1279 | 1272 | virScaleInteger; | ||
1280 | 1273 | virSetBlocking; | ||
1281 | 1274 | virSetCloseExec; | ||
1282 | 1275 | virSetInherit; | ||
1283 | 1276 | virSetNonBlock; | ||
1284 | 1277 | virSetUIDGID; | ||
1285 | 1278 | virSkipSpaces; | ||
1286 | 1279 | virSkipSpacesAndBackslash; | ||
1287 | 1280 | virSkipSpacesBackwards; | ||
1288 | 1281 | virStrToDouble; | ||
1289 | 1282 | virStrToLong_i; | ||
1290 | 1283 | virStrToLong_l; | ||
1291 | 1284 | virStrToLong_ll; | ||
1292 | 1285 | virStrToLong_ui; | ||
1293 | 1286 | virStrToLong_ul; | ||
1294 | 1287 | virStrToLong_ull; | ||
1295 | 1288 | virStrcpy; | ||
1296 | 1289 | virStrncpy; | ||
1297 | 1290 | virTrimSpaces; | ||
1298 | 1291 | virValidateWWN; | ||
1299 | 1292 | virVasprintf; | ||
1300 | 1293 | |||
1301 | 1294 | |||
1302 | 1295 | # uuid.h | ||
1303 | 1296 | virGetHostUUID; | ||
1304 | 1297 | virSetHostUUIDStr; | ||
1305 | 1298 | virUUIDFormat; | ||
1306 | 1299 | virUUIDGenerate; | ||
1307 | 1300 | virUUIDIsValid; | ||
1308 | 1301 | virUUIDParse; | ||
1309 | 1302 | |||
1310 | 1303 | |||
1311 | 1304 | # virauth.h | ||
1312 | 1305 | virAuthGetConfigFilePath; | ||
1313 | 1306 | virAuthGetPassword; | ||
1314 | 1307 | virAuthGetUsername; | ||
1315 | 1308 | |||
1316 | 1309 | |||
1317 | 1310 | # virauthconfig.h | ||
1318 | 1311 | virAuthConfigFree; | ||
1319 | 1312 | virAuthConfigLookup; | ||
1320 | 1313 | virAuthConfigNew; | ||
1321 | 1314 | virAuthConfigNewData; | ||
1322 | 1315 | |||
1323 | 1316 | |||
1324 | 1317 | # viraudit.h | ||
1325 | 1318 | virAuditClose; | ||
1326 | 1319 | virAuditEncode; | ||
1327 | 1320 | virAuditLog; | ||
1328 | 1321 | virAuditOpen; | ||
1329 | 1322 | virAuditSend; | ||
1330 | 1323 | |||
1331 | 1324 | |||
1332 | 1325 | # virconsole.h | ||
1333 | 1326 | virConsoleAlloc; | ||
1334 | 1327 | virConsoleFree; | ||
1335 | 1328 | virConsoleOpen; | ||
1336 | 1329 | |||
1337 | 1330 | |||
1338 | 1331 | # virdbus.h | ||
1339 | 1332 | virDBusGetSystemBus; | ||
1340 | 1333 | |||
1341 | 1334 | |||
1342 | 1335 | # virfile.h | ||
1343 | 1336 | virFileLoopDeviceAssociate; | ||
1344 | 1337 | virFileClose; | ||
1345 | 1338 | virFileDirectFdFlag; | ||
1346 | 1339 | virFileWrapperFdCatchError; | ||
1347 | 1340 | virFileWrapperFdClose; | ||
1348 | 1341 | virFileWrapperFdFree; | ||
1349 | 1342 | virFileWrapperFdNew; | ||
1350 | 1343 | virFileFclose; | ||
1351 | 1344 | virFileFdopen; | ||
1352 | 1345 | virFileRewrite; | ||
1353 | 1346 | virFileTouch; | ||
1354 | 1347 | virFileUpdatePerm; | ||
1355 | 1348 | |||
1356 | 1349 | |||
1357 | 1350 | # virkeycode.h | ||
1358 | 1351 | virKeycodeSetTypeFromString; | ||
1359 | 1352 | virKeycodeSetTypeToString; | ||
1360 | 1353 | virKeycodeValueFromString; | ||
1361 | 1354 | virKeycodeValueTranslate; | ||
1362 | 1355 | |||
1363 | 1356 | |||
1364 | 1357 | # virkeyfile.h | ||
1365 | 1358 | virKeyFileNew; | ||
1366 | 1359 | virKeyFileLoadFile; | ||
1367 | 1360 | virKeyFileLoadData; | ||
1368 | 1361 | virKeyFileFree; | ||
1369 | 1362 | virKeyFileHasValue; | ||
1370 | 1363 | virKeyFileHasGroup; | ||
1371 | 1364 | virKeyFileGetValueString; | ||
1372 | 1365 | |||
1373 | 1366 | |||
1374 | 1367 | # virlockspace.h | ||
1375 | 1368 | virLockSpaceAcquireResource; | ||
1376 | 1369 | virLockSpaceCreateResource; | ||
1377 | 1370 | virLockSpaceDeleteResource; | ||
1378 | 1371 | virLockSpaceFree; | ||
1379 | 1372 | virLockSpaceGetDirectory; | ||
1380 | 1373 | virLockSpaceNew; | ||
1381 | 1374 | virLockSpaceNewPostExecRestart; | ||
1382 | 1375 | virLockSpacePreExecRestart; | ||
1383 | 1376 | virLockSpaceReleaseResource; | ||
1384 | 1377 | virLockSpaceReleaseResourcesForOwner; | ||
1385 | 1378 | |||
1386 | 1379 | |||
1387 | 1380 | # virmacaddr.h | ||
1388 | 1381 | virMacAddrCmp; | ||
1389 | 1382 | virMacAddrCmpRaw; | ||
1390 | 1383 | virMacAddrCompare; | ||
1391 | 1384 | virMacAddrFormat; | ||
1392 | 1385 | virMacAddrGenerate; | ||
1393 | 1386 | virMacAddrGetRaw; | ||
1394 | 1387 | virMacAddrIsBroadcastRaw; | ||
1395 | 1388 | virMacAddrIsMulticast; | ||
1396 | 1389 | virMacAddrIsUnicast; | ||
1397 | 1390 | virMacAddrParse; | ||
1398 | 1391 | virMacAddrSet; | ||
1399 | 1392 | virMacAddrSetRaw; | ||
1400 | 1393 | |||
1401 | 1394 | |||
1402 | 1395 | # virnetclient.h | ||
1403 | 1396 | virNetClientAddProgram; | ||
1404 | 1397 | virNetClientAddStream; | ||
1405 | 1398 | virNetClientClose; | ||
1406 | 1399 | virNetClientDupFD; | ||
1407 | 1400 | virNetClientGetFD; | ||
1408 | 1401 | virNetClientGetTLSKeySize; | ||
1409 | 1402 | virNetClientHasPassFD; | ||
1410 | 1403 | virNetClientIsEncrypted; | ||
1411 | 1404 | virNetClientIsOpen; | ||
1412 | 1405 | virNetClientKeepAliveIsSupported; | ||
1413 | 1406 | virNetClientKeepAliveStart; | ||
1414 | 1407 | virNetClientKeepAliveStop; | ||
1415 | 1408 | virNetClientLocalAddrString; | ||
1416 | 1409 | virNetClientNewExternal; | ||
1417 | 1410 | virNetClientNewLibSSH2; | ||
1418 | 1411 | virNetClientNewSSH; | ||
1419 | 1412 | virNetClientNewTCP; | ||
1420 | 1413 | virNetClientNewUNIX; | ||
1421 | 1414 | virNetClientRegisterAsyncIO; | ||
1422 | 1415 | virNetClientRegisterKeepAlive; | ||
1423 | 1416 | virNetClientRemoteAddrString; | ||
1424 | 1417 | virNetClientRemoveStream; | ||
1425 | 1418 | virNetClientSendNoReply; | ||
1426 | 1419 | virNetClientSendNonBlock; | ||
1427 | 1420 | virNetClientSendWithReply; | ||
1428 | 1421 | virNetClientSendWithReplyStream; | ||
1429 | 1422 | virNetClientSetCloseCallback; | ||
1430 | 1423 | virNetClientSetTLSSession; | ||
1431 | 1424 | |||
1432 | 1425 | |||
1433 | 1426 | # virnetclientprogram.h | ||
1434 | 1427 | virNetClientProgramCall; | ||
1435 | 1428 | virNetClientProgramDispatch; | ||
1436 | 1429 | virNetClientProgramGetProgram; | ||
1437 | 1430 | virNetClientProgramGetVersion; | ||
1438 | 1431 | virNetClientProgramMatches; | ||
1439 | 1432 | virNetClientProgramNew; | ||
1440 | 1433 | |||
1441 | 1434 | |||
1442 | 1435 | # virnetclientstream.h | ||
1443 | 1436 | virNetClientStreamEOF; | ||
1444 | 1437 | virNetClientStreamEventAddCallback; | ||
1445 | 1438 | virNetClientStreamEventRemoveCallback; | ||
1446 | 1439 | virNetClientStreamEventUpdateCallback; | ||
1447 | 1440 | virNetClientStreamMatches; | ||
1448 | 1441 | virNetClientStreamNew; | ||
1449 | 1442 | virNetClientStreamQueuePacket; | ||
1450 | 1443 | virNetClientStreamRaiseError; | ||
1451 | 1444 | virNetClientStreamRecvPacket; | ||
1452 | 1445 | virNetClientStreamSendPacket; | ||
1453 | 1446 | virNetClientStreamSetError; | ||
1454 | 1447 | |||
1455 | 1448 | |||
1456 | 1449 | # virnetdev.h | ||
1457 | 1450 | virNetDevClearIPv4Address; | ||
1458 | 1451 | virNetDevExists; | ||
1459 | 1452 | virNetDevGetIPv4Address; | ||
1460 | 1453 | virNetDevGetIndex; | ||
1461 | 1454 | virNetDevGetMAC; | ||
1462 | 1455 | virNetDevGetMTU; | ||
1463 | 1456 | virNetDevGetPhysicalFunction; | ||
1464 | 1457 | virNetDevGetVLanID; | ||
1465 | 1458 | virNetDevGetVirtualFunctionIndex; | ||
1466 | 1459 | virNetDevGetVirtualFunctionInfo; | ||
1467 | 1460 | virNetDevGetVirtualFunctions; | ||
1468 | 1461 | virNetDevIsOnline; | ||
1469 | 1462 | virNetDevIsVirtualFunction; | ||
1470 | 1463 | virNetDevLinkDump; | ||
1471 | 1464 | virNetDevReplaceMacAddress; | ||
1472 | 1465 | virNetDevReplaceNetConfig; | ||
1473 | 1466 | virNetDevRestoreMacAddress; | ||
1474 | 1467 | virNetDevRestoreNetConfig; | ||
1475 | 1468 | virNetDevSetIPv4Address; | ||
1476 | 1469 | virNetDevSetMAC; | ||
1477 | 1470 | virNetDevSetMTU; | ||
1478 | 1471 | virNetDevSetMTUFromDevice; | ||
1479 | 1472 | virNetDevSetName; | ||
1480 | 1473 | virNetDevSetNamespace; | ||
1481 | 1474 | virNetDevSetOnline; | ||
1482 | 1475 | virNetDevValidateConfig; | ||
1483 | 1476 | |||
1484 | 1477 | |||
1485 | 1478 | # virnetdevbandwidth.h | ||
1486 | 1479 | virNetDevBandwidthClear; | ||
1487 | 1480 | virNetDevBandwidthCopy; | ||
1488 | 1481 | virNetDevBandwidthEqual; | ||
1489 | 1482 | virNetDevBandwidthFree; | ||
1490 | 1483 | virNetDevBandwidthSet; | ||
1491 | 1484 | |||
1492 | 1485 | |||
1493 | 1486 | # virnetdevbridge.h | ||
1494 | 1487 | virNetDevBridgeAddPort; | ||
1495 | 1488 | virNetDevBridgeCreate; | ||
1496 | 1489 | virNetDevBridgeDelete; | ||
1497 | 1490 | virNetDevBridgeGetSTP; | ||
1498 | 1491 | virNetDevBridgeGetSTPDelay; | ||
1499 | 1492 | virNetDevBridgeRemovePort; | ||
1500 | 1493 | virNetDevBridgeSetSTP; | ||
1501 | 1494 | virNetDevBridgeSetSTPDelay; | ||
1502 | 1495 | |||
1503 | 1496 | |||
1504 | 1497 | # virnetdevmacvlan.h | ||
1505 | 1498 | virNetDevMacVLanCreate; | ||
1506 | 1499 | virNetDevMacVLanDelete; | ||
1507 | 1500 | virNetDevMacVLanCreateWithVPortProfile; | ||
1508 | 1501 | virNetDevMacVLanDeleteWithVPortProfile; | ||
1509 | 1502 | virNetDevMacVLanRestartWithVPortProfile; | ||
1510 | 1503 | virNetDevMacVLanVPortProfileRegisterCallback; | ||
1511 | 1504 | |||
1512 | 1505 | |||
1513 | 1506 | # virnetdevopenvswitch.h | ||
1514 | 1507 | virNetDevOpenvswitchAddPort; | ||
1515 | 1508 | virNetDevOpenvswitchGetMigrateData; | ||
1516 | 1509 | virNetDevOpenvswitchRemovePort; | ||
1517 | 1510 | virNetDevOpenvswitchSetMigrateData; | ||
1518 | 1511 | |||
1519 | 1512 | |||
1520 | 1513 | # virnetdevtap.h | ||
1521 | 1514 | virNetDevTapCreate; | ||
1522 | 1515 | virNetDevTapCreateInBridgePort; | ||
1523 | 1516 | virNetDevTapDelete; | ||
1524 | 1517 | |||
1525 | 1518 | |||
1526 | 1519 | # virnetdevveth.h | ||
1527 | 1520 | virNetDevVethCreate; | ||
1528 | 1521 | virNetDevVethDelete; | ||
1529 | 1522 | |||
1530 | 1523 | |||
1531 | 1524 | # virnetdevvlan.h | ||
1532 | 1525 | virNetDevVlanClear; | ||
1533 | 1526 | virNetDevVlanCopy; | ||
1534 | 1527 | virNetDevVlanEqual; | ||
1535 | 1528 | virNetDevVlanFree; | ||
1536 | 1529 | |||
1537 | 1530 | # virnetdevvportprofile.h | ||
1538 | 1531 | virNetDevVPortProfileAssociate; | ||
1539 | 1532 | virNetDevVPortProfileCheckComplete; | ||
1540 | 1533 | virNetDevVPortProfileCheckNoExtras; | ||
1541 | 1534 | virNetDevVPortProfileDisassociate; | ||
1542 | 1535 | virNetDevVPortProfileEqual; | ||
1543 | 1536 | virNetDevVPortProfileMerge3; | ||
1544 | 1537 | virNetDevVPortProfileOpTypeFromString; | ||
1545 | 1538 | virNetDevVPortProfileOpTypeToString; | ||
1546 | 1539 | |||
1547 | 1540 | |||
1548 | 1541 | #virnetlink.h | ||
1549 | 1542 | virNetlinkCommand; | ||
1550 | 1543 | virNetlinkEventAddClient; | ||
1551 | 1544 | virNetlinkEventRemoveClient; | ||
1552 | 1545 | virNetlinkEventServiceIsRunning; | ||
1553 | 1546 | virNetlinkEventServiceLocalPid; | ||
1554 | 1547 | virNetlinkEventServiceStop; | ||
1555 | 1548 | virNetlinkEventServiceStopAll; | ||
1556 | 1549 | virNetlinkEventServiceStart; | ||
1557 | 1550 | virNetlinkShutdown; | ||
1558 | 1551 | virNetlinkStartup; | ||
1559 | 1552 | |||
1560 | 1553 | |||
1561 | 1554 | # virnetmessage.h | ||
1562 | 1555 | virNetMessageClear; | ||
1563 | 1556 | virNetMessageDecodeHeader; | ||
1564 | 1557 | virNetMessageDecodeNumFDs; | ||
1565 | 1558 | virNetMessageDecodeLength; | ||
1566 | 1559 | virNetMessageDecodePayload; | ||
1567 | 1560 | virNetMessageDupFD; | ||
1568 | 1561 | virNetMessageEncodeHeader; | ||
1569 | 1562 | virNetMessageEncodePayload; | ||
1570 | 1563 | virNetMessageEncodePayloadRaw; | ||
1571 | 1564 | virNetMessageEncodeNumFDs; | ||
1572 | 1565 | virNetMessageFree; | ||
1573 | 1566 | virNetMessageNew; | ||
1574 | 1567 | virNetMessageQueuePush; | ||
1575 | 1568 | virNetMessageQueueServe; | ||
1576 | 1569 | virNetMessageSaveError; | ||
1577 | 1570 | xdr_virNetMessageError; | ||
1578 | 1571 | |||
1579 | 1572 | |||
1580 | 1573 | # virnetserver.h | ||
1581 | 1574 | virNetServerAddProgram; | ||
1582 | 1575 | virNetServerAddService; | ||
1583 | 1576 | virNetServerAddSignalHandler; | ||
1584 | 1577 | virNetServerAutoShutdown; | ||
1585 | 1578 | virNetServerClose; | ||
1586 | 1579 | virNetServerIsPrivileged; | ||
1587 | 1580 | virNetServerKeepAliveRequired; | ||
1588 | 1581 | virNetServerNew; | ||
1589 | 1582 | virNetServerNewPostExecRestart; | ||
1590 | 1583 | virNetServerPreExecRestart; | ||
1591 | 1584 | virNetServerQuit; | ||
1592 | 1585 | virNetServerRun; | ||
1593 | 1586 | virNetServerSetTLSContext; | ||
1594 | 1587 | virNetServerUpdateServices; | ||
1595 | 1588 | |||
1596 | 1589 | |||
1597 | 1590 | # virnetserverclient.h | ||
1598 | 1591 | virNetServerClientAddFilter; | ||
1599 | 1592 | virNetServerClientClose; | ||
1600 | 1593 | virNetServerClientDelayedClose; | ||
1601 | 1594 | virNetServerClientGetAuth; | ||
1602 | 1595 | virNetServerClientGetFD; | ||
1603 | 1596 | virNetServerClientGetIdentity; | ||
1604 | 1597 | virNetServerClientGetPrivateData; | ||
1605 | 1598 | virNetServerClientGetReadonly; | ||
1606 | 1599 | virNetServerClientGetTLSKeySize; | ||
1607 | 1600 | virNetServerClientGetUNIXIdentity; | ||
1608 | 1601 | virNetServerClientHasTLSSession; | ||
1609 | 1602 | virNetServerClientImmediateClose; | ||
1610 | 1603 | virNetServerClientInit; | ||
1611 | 1604 | virNetServerClientInitKeepAlive; | ||
1612 | 1605 | virNetServerClientIsClosed; | ||
1613 | 1606 | virNetServerClientIsSecure; | ||
1614 | 1607 | virNetServerClientLocalAddrString; | ||
1615 | 1608 | virNetServerClientNeedAuth; | ||
1616 | 1609 | virNetServerClientNew; | ||
1617 | 1610 | virNetServerClientNewPostExecRestart; | ||
1618 | 1611 | virNetServerClientPreExecRestart; | ||
1619 | 1612 | virNetServerClientRemoteAddrString; | ||
1620 | 1613 | virNetServerClientRemoveFilter; | ||
1621 | 1614 | virNetServerClientSendMessage; | ||
1622 | 1615 | virNetServerClientSetCloseHook; | ||
1623 | 1616 | virNetServerClientSetDispatcher; | ||
1624 | 1617 | virNetServerClientSetIdentity; | ||
1625 | 1618 | virNetServerClientStartKeepAlive; | ||
1626 | 1619 | virNetServerClientWantClose; | ||
1627 | 1620 | |||
1628 | 1621 | |||
1629 | 1622 | # virnetservermdns.h | ||
1630 | 1623 | virNetServerMDNSAddEntry; | ||
1631 | 1624 | virNetServerMDNSAddGroup; | ||
1632 | 1625 | virNetServerMDNSEntryFree; | ||
1633 | 1626 | virNetServerMDNSFree; | ||
1634 | 1627 | virNetServerMDNSGroupFree; | ||
1635 | 1628 | virNetServerMDNSNew; | ||
1636 | 1629 | virNetServerMDNSRemoveEntry; | ||
1637 | 1630 | virNetServerMDNSRemoveGroup; | ||
1638 | 1631 | virNetServerMDNSStart; | ||
1639 | 1632 | virNetServerMDNSStop; | ||
1640 | 1633 | |||
1641 | 1634 | |||
1642 | 1635 | # virnetserverprogram.h | ||
1643 | 1636 | virNetServerProgramDispatch; | ||
1644 | 1637 | virNetServerProgramGetID; | ||
1645 | 1638 | virNetServerProgramGetPriority; | ||
1646 | 1639 | virNetServerProgramGetVersion; | ||
1647 | 1640 | virNetServerProgramMatches; | ||
1648 | 1641 | virNetServerProgramNew; | ||
1649 | 1642 | virNetServerProgramSendReplyError; | ||
1650 | 1643 | virNetServerProgramSendStreamData; | ||
1651 | 1644 | virNetServerProgramSendStreamError; | ||
1652 | 1645 | virNetServerProgramUnknownError; | ||
1653 | 1646 | |||
1654 | 1647 | |||
1655 | 1648 | # virnetserverservice.h | ||
1656 | 1649 | virNetServerServiceClose; | ||
1657 | 1650 | virNetServerServiceGetAuth; | ||
1658 | 1651 | virNetServerServiceGetMaxRequests; | ||
1659 | 1652 | virNetServerServiceGetPort; | ||
1660 | 1653 | virNetServerServiceGetTLSContext; | ||
1661 | 1654 | virNetServerServiceIsReadonly; | ||
1662 | 1655 | virNetServerServiceNewFD; | ||
1663 | 1656 | virNetServerServiceNewPostExecRestart; | ||
1664 | 1657 | virNetServerServiceNewTCP; | ||
1665 | 1658 | virNetServerServiceNewUNIX; | ||
1666 | 1659 | virNetServerServicePreExecRestart; | ||
1667 | 1660 | virNetServerServiceSetDispatcher; | ||
1668 | 1661 | virNetServerServiceToggle; | ||
1669 | 1662 | |||
1670 | 1663 | |||
1671 | 1664 | # virnetsocket.h | ||
1672 | 1665 | virNetSocketAccept; | ||
1673 | 1666 | virNetSocketAddIOCallback; | ||
1674 | 1667 | virNetSocketClose; | ||
1675 | 1668 | virNetSocketDupFD; | ||
1676 | 1669 | virNetSocketGetFD; | ||
1677 | 1670 | virNetSocketGetPort; | ||
1678 | 1671 | virNetSocketGetUNIXIdentity; | ||
1679 | 1672 | virNetSocketHasCachedData; | ||
1680 | 1673 | virNetSocketHasPassFD; | ||
1681 | 1674 | virNetSocketHasPendingData; | ||
1682 | 1675 | virNetSocketIsLocal; | ||
1683 | 1676 | virNetSocketListen; | ||
1684 | 1677 | virNetSocketLocalAddrString; | ||
1685 | 1678 | virNetSocketNewConnectCommand; | ||
1686 | 1679 | virNetSocketNewConnectExternal; | ||
1687 | 1680 | virNetSocketNewConnectLibSSH2; | ||
1688 | 1681 | virNetSocketNewConnectSSH; | ||
1689 | 1682 | virNetSocketNewConnectTCP; | ||
1690 | 1683 | virNetSocketNewConnectUNIX; | ||
1691 | 1684 | virNetSocketNewListenFD; | ||
1692 | 1685 | virNetSocketNewListenTCP; | ||
1693 | 1686 | virNetSocketNewListenUNIX; | ||
1694 | 1687 | virNetSocketNewPostExecRestart; | ||
1695 | 1688 | virNetSocketPreExecRestart; | ||
1696 | 1689 | virNetSocketRead; | ||
1697 | 1690 | virNetSocketRecvFD; | ||
1698 | 1691 | virNetSocketRemoteAddrString; | ||
1699 | 1692 | virNetSocketRemoveIOCallback; | ||
1700 | 1693 | virNetSocketSendFD; | ||
1701 | 1694 | virNetSocketSetBlocking; | ||
1702 | 1695 | virNetSocketSetTLSSession; | ||
1703 | 1696 | virNetSocketUpdateIOCallback; | ||
1704 | 1697 | virNetSocketWrite; | ||
1705 | 1698 | |||
1706 | 1699 | |||
1707 | 1700 | # virnettlscontext.h | ||
1708 | 1701 | virNetTLSContextCheckCertificate; | ||
1709 | 1702 | virNetTLSContextNewClient; | ||
1710 | 1703 | virNetTLSContextNewClientPath; | ||
1711 | 1704 | virNetTLSContextNewServer; | ||
1712 | 1705 | virNetTLSContextNewServerPath; | ||
1713 | 1706 | virNetTLSInit; | ||
1714 | 1707 | virNetTLSSessionGetHandshakeStatus; | ||
1715 | 1708 | virNetTLSSessionGetKeySize; | ||
1716 | 1709 | virNetTLSSessionHandshake; | ||
1717 | 1710 | virNetTLSSessionNew; | ||
1718 | 1711 | virNetTLSSessionRead; | ||
1719 | 1712 | virNetTLSSessionSetIOCallbacks; | ||
1720 | 1713 | virNetTLSSessionWrite; | ||
1721 | 1714 | |||
1722 | 1715 | |||
1723 | 1716 | # virnodesuspend.h | ||
1724 | 1717 | nodeSuspendForDuration; | ||
1725 | 1718 | virNodeSuspendGetTargetMask; | ||
1726 | 1719 | |||
1727 | 1720 | |||
1728 | 1721 | # virobject.h | ||
1729 | 1722 | virClassName; | ||
1730 | 1723 | virClassNew; | ||
1731 | 1724 | virObjectFreeCallback; | ||
1732 | 1725 | virObjectIsClass; | ||
1733 | 1726 | virObjectNew; | ||
1734 | 1727 | virObjectRef; | ||
1735 | 1728 | virObjectUnref; | ||
1736 | 1729 | |||
1737 | 1730 | |||
1738 | 1731 | # virpidfile.h | ||
1739 | 1732 | virPidFileAcquire; | ||
1740 | 1733 | virPidFileAcquirePath; | ||
1741 | 1734 | virPidFileBuildPath; | ||
1742 | 1735 | virPidFileRead; | ||
1743 | 1736 | virPidFileReadIfAlive; | ||
1744 | 1737 | virPidFileReadPath; | ||
1745 | 1738 | virPidFileReadPathIfAlive; | ||
1746 | 1739 | virPidFileRelease; | ||
1747 | 1740 | virPidFileReleasePath; | ||
1748 | 1741 | virPidFileWrite; | ||
1749 | 1742 | virPidFileWritePath; | ||
1750 | 1743 | virPidFileDelete; | ||
1751 | 1744 | virPidFileDeletePath; | ||
1752 | 1745 | |||
1753 | 1746 | |||
1754 | 1747 | # virprocess.h | ||
1755 | 1748 | virProcessAbort; | ||
1756 | 1749 | virProcessKill; | ||
1757 | 1750 | virProcessKillPainfully; | ||
1758 | 1751 | virProcessTranslateStatus; | ||
1759 | 1752 | virProcessWait; | ||
1760 | 1753 | |||
1761 | 1754 | |||
1762 | 1755 | # virrandom.h | ||
1763 | 1756 | virRandom; | ||
1764 | 1757 | virRandomBits; | ||
1765 | 1758 | virRandomGenerateWWN; | ||
1766 | 1759 | virRandomInt; | ||
1767 | 1760 | |||
1768 | 1761 | |||
1769 | 1762 | # virsocketaddr.h | ||
1770 | 1763 | virSocketAddrBroadcast; | ||
1771 | 1764 | virSocketAddrBroadcastByPrefix; | ||
1772 | 1765 | virSocketAddrCheckNetmask; | ||
1773 | 1766 | virSocketAddrEqual; | ||
1774 | 1767 | virSocketAddrFormat; | ||
1775 | 1768 | virSocketAddrFormatFull; | ||
1776 | 1769 | virSocketAddrGetPort; | ||
1777 | 1770 | virSocketAddrGetRange; | ||
1778 | 1771 | virSocketAddrIsNetmask; | ||
1779 | 1772 | virSocketAddrMask; | ||
1780 | 1773 | virSocketAddrMaskByPrefix; | ||
1781 | 1774 | virSocketAddrParse; | ||
1782 | 1775 | virSocketAddrParseIPv4; | ||
1783 | 1776 | virSocketAddrParseIPv6; | ||
1784 | 1777 | virSocketAddrPrefixToNetmask; | ||
1785 | 1778 | virSocketAddrSetIPv4Addr; | ||
1786 | 1779 | virSocketAddrSetPort; | ||
1787 | 1780 | |||
1788 | 1781 | |||
1789 | 1782 | # virterror_internal.h | ||
1790 | 1783 | virDispatchError; | ||
1791 | 1784 | virErrorInitialize; | ||
1792 | 1785 | virRaiseErrorFull; | ||
1793 | 1786 | virReportErrorHelper; | ||
1794 | 1787 | virReportOOMErrorFull; | ||
1795 | 1788 | virReportSystemErrorFull; | ||
1796 | 1789 | virSetError; | ||
1797 | 1790 | virSetErrorLogPriorityFunc; | ||
1798 | 1791 | virStrerror; | ||
1799 | 1792 | |||
1800 | 1793 | |||
1801 | 1794 | # virtime.h | ||
1802 | 1795 | virTimeFieldsNow; | ||
1803 | 1796 | virTimeFieldsNowRaw; | ||
1804 | 1797 | virTimeFieldsThen; | ||
1805 | 1798 | virTimeFieldsThenRaw; | ||
1806 | 1799 | virTimeMillisNow; | ||
1807 | 1800 | virTimeMillisNowRaw; | ||
1808 | 1801 | virTimeStringNow; | ||
1809 | 1802 | virTimeStringNowRaw; | ||
1810 | 1803 | virTimeStringThen; | ||
1811 | 1804 | virTimeStringThenRaw; | ||
1812 | 1805 | |||
1813 | 1806 | |||
1814 | 1807 | # virtypedparam.h | ||
1815 | 1808 | virTypedParameterArrayClear; | ||
1816 | 1809 | virTypedParameterArrayValidate; | ||
1817 | 1810 | virTypedParameterAssign; | ||
1818 | 1811 | virTypedParameterAssignFromStr; | ||
1819 | 1812 | |||
1820 | 1813 | |||
1821 | 1814 | # viruri.h | ||
1822 | 1815 | virURIFormat; | ||
1823 | 1816 | virURIFormatParams; | ||
1824 | 1817 | virURIFree; | ||
1825 | 1818 | virURIParse; | ||
1826 | 1819 | |||
1827 | 1820 | |||
1828 | 1821 | # xml.h | ||
1829 | 1822 | virXMLChildElementCount; | ||
1830 | 1823 | virXMLParseHelper; | ||
1831 | 1824 | virXMLPickShellSafeComment; | ||
1832 | 1825 | virXMLPropString; | ||
1833 | 1826 | virXMLSaveFile; | ||
1834 | 1827 | virXPathBoolean; | ||
1835 | 1828 | virXPathInt; | ||
1836 | 1829 | virXPathLong; | ||
1837 | 1830 | virXPathLongHex; | ||
1838 | 1831 | virXPathLongLong; | ||
1839 | 1832 | virXPathNode; | ||
1840 | 1833 | virXPathNodeSet; | ||
1841 | 1834 | virXPathNumber; | ||
1842 | 1835 | virXPathString; | ||
1843 | 1836 | virXPathStringLimit; | ||
1844 | 1837 | virXPathUInt; | ||
1845 | 1838 | virXPathULong; | ||
1846 | 1839 | virXPathULongHex; | ||
1847 | 1840 | virXPathULongLong; | ||
1848 | 0 | 1841 | ||
1849 | === added directory '.pc/apparmor-allow-hugepages/src/qemu' | |||
1850 | === added file '.pc/apparmor-allow-hugepages/src/qemu/qemu_process.c' | |||
1851 | --- .pc/apparmor-allow-hugepages/src/qemu/qemu_process.c 1970-01-01 00:00:00 +0000 | |||
1852 | +++ .pc/apparmor-allow-hugepages/src/qemu/qemu_process.c 2012-12-11 20:02:29 +0000 | |||
1853 | @@ -0,0 +1,4474 @@ | |||
1854 | 1 | /* | ||
1855 | 2 | * qemu_process.h: QEMU process management | ||
1856 | 3 | * | ||
1857 | 4 | * Copyright (C) 2006-2012 Red Hat, Inc. | ||
1858 | 5 | * | ||
1859 | 6 | * This library is free software; you can redistribute it and/or | ||
1860 | 7 | * modify it under the terms of the GNU Lesser General Public | ||
1861 | 8 | * License as published by the Free Software Foundation; either | ||
1862 | 9 | * version 2.1 of the License, or (at your option) any later version. | ||
1863 | 10 | * | ||
1864 | 11 | * This library is distributed in the hope that it will be useful, | ||
1865 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1866 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1867 | 14 | * Lesser General Public License for more details. | ||
1868 | 15 | * | ||
1869 | 16 | * You should have received a copy of the GNU Lesser General Public | ||
1870 | 17 | * License along with this library. If not, see | ||
1871 | 18 | * <http://www.gnu.org/licenses/>. | ||
1872 | 19 | * | ||
1873 | 20 | */ | ||
1874 | 21 | |||
1875 | 22 | #include <config.h> | ||
1876 | 23 | |||
1877 | 24 | #include <fcntl.h> | ||
1878 | 25 | #include <unistd.h> | ||
1879 | 26 | #include <signal.h> | ||
1880 | 27 | #include <sys/stat.h> | ||
1881 | 28 | #include <sys/time.h> | ||
1882 | 29 | #include <sys/resource.h> | ||
1883 | 30 | #include <linux/capability.h> | ||
1884 | 31 | |||
1885 | 32 | #include "qemu_process.h" | ||
1886 | 33 | #include "qemu_domain.h" | ||
1887 | 34 | #include "qemu_cgroup.h" | ||
1888 | 35 | #include "qemu_capabilities.h" | ||
1889 | 36 | #include "qemu_monitor.h" | ||
1890 | 37 | #include "qemu_command.h" | ||
1891 | 38 | #include "qemu_hostdev.h" | ||
1892 | 39 | #include "qemu_hotplug.h" | ||
1893 | 40 | #include "qemu_bridge_filter.h" | ||
1894 | 41 | #include "qemu_migration.h" | ||
1895 | 42 | |||
1896 | 43 | #if HAVE_NUMACTL | ||
1897 | 44 | # define NUMA_VERSION1_COMPATIBILITY 1 | ||
1898 | 45 | # include <numa.h> | ||
1899 | 46 | #endif | ||
1900 | 47 | |||
1901 | 48 | #include "datatypes.h" | ||
1902 | 49 | #include "logging.h" | ||
1903 | 50 | #include "virterror_internal.h" | ||
1904 | 51 | #include "memory.h" | ||
1905 | 52 | #include "hooks.h" | ||
1906 | 53 | #include "virfile.h" | ||
1907 | 54 | #include "virpidfile.h" | ||
1908 | 55 | #include "util.h" | ||
1909 | 56 | #include "c-ctype.h" | ||
1910 | 57 | #include "nodeinfo.h" | ||
1911 | 58 | #include "processinfo.h" | ||
1912 | 59 | #include "domain_audit.h" | ||
1913 | 60 | #include "domain_nwfilter.h" | ||
1914 | 61 | #include "locking/domain_lock.h" | ||
1915 | 62 | #include "network/bridge_driver.h" | ||
1916 | 63 | #include "uuid.h" | ||
1917 | 64 | #include "virprocess.h" | ||
1918 | 65 | #include "virtime.h" | ||
1919 | 66 | #include "virnetdevtap.h" | ||
1920 | 67 | #include "bitmap.h" | ||
1921 | 68 | |||
1922 | 69 | #define VIR_FROM_THIS VIR_FROM_QEMU | ||
1923 | 70 | |||
1924 | 71 | #define START_POSTFIX ": starting up\n" | ||
1925 | 72 | #define ATTACH_POSTFIX ": attaching\n" | ||
1926 | 73 | #define SHUTDOWN_POSTFIX ": shutting down\n" | ||
1927 | 74 | |||
1928 | 75 | /** | ||
1929 | 76 | * qemudRemoveDomainStatus | ||
1930 | 77 | * | ||
1931 | 78 | * remove all state files of a domain from statedir | ||
1932 | 79 | * | ||
1933 | 80 | * Returns 0 on success | ||
1934 | 81 | */ | ||
1935 | 82 | static int | ||
1936 | 83 | qemuProcessRemoveDomainStatus(struct qemud_driver *driver, | ||
1937 | 84 | virDomainObjPtr vm) | ||
1938 | 85 | { | ||
1939 | 86 | char ebuf[1024]; | ||
1940 | 87 | char *file = NULL; | ||
1941 | 88 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
1942 | 89 | |||
1943 | 90 | if (virAsprintf(&file, "%s/%s.xml", driver->stateDir, vm->def->name) < 0) { | ||
1944 | 91 | virReportOOMError(); | ||
1945 | 92 | return -1; | ||
1946 | 93 | } | ||
1947 | 94 | |||
1948 | 95 | if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR) | ||
1949 | 96 | VIR_WARN("Failed to remove domain XML for %s: %s", | ||
1950 | 97 | vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf))); | ||
1951 | 98 | VIR_FREE(file); | ||
1952 | 99 | |||
1953 | 100 | if (priv->pidfile && | ||
1954 | 101 | unlink(priv->pidfile) < 0 && | ||
1955 | 102 | errno != ENOENT) | ||
1956 | 103 | VIR_WARN("Failed to remove PID file for %s: %s", | ||
1957 | 104 | vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf))); | ||
1958 | 105 | |||
1959 | 106 | return 0; | ||
1960 | 107 | } | ||
1961 | 108 | |||
1962 | 109 | |||
1963 | 110 | /* XXX figure out how to remove this */ | ||
1964 | 111 | extern struct qemud_driver *qemu_driver; | ||
1965 | 112 | |||
1966 | 113 | /* | ||
1967 | 114 | * This is a callback registered with a qemuAgentPtr instance, | ||
1968 | 115 | * and to be invoked when the agent console hits an end of file | ||
1969 | 116 | * condition, or error, thus indicating VM shutdown should be | ||
1970 | 117 | * performed | ||
1971 | 118 | */ | ||
1972 | 119 | static void | ||
1973 | 120 | qemuProcessHandleAgentEOF(qemuAgentPtr agent, | ||
1974 | 121 | virDomainObjPtr vm) | ||
1975 | 122 | { | ||
1976 | 123 | struct qemud_driver *driver = qemu_driver; | ||
1977 | 124 | qemuDomainObjPrivatePtr priv; | ||
1978 | 125 | |||
1979 | 126 | VIR_DEBUG("Received EOF from agent on %p '%s'", vm, vm->def->name); | ||
1980 | 127 | |||
1981 | 128 | qemuDriverLock(driver); | ||
1982 | 129 | virDomainObjLock(vm); | ||
1983 | 130 | |||
1984 | 131 | priv = vm->privateData; | ||
1985 | 132 | if (priv->agent == agent) | ||
1986 | 133 | priv->agent = NULL; | ||
1987 | 134 | |||
1988 | 135 | virDomainObjUnlock(vm); | ||
1989 | 136 | qemuDriverUnlock(driver); | ||
1990 | 137 | |||
1991 | 138 | qemuAgentClose(agent); | ||
1992 | 139 | } | ||
1993 | 140 | |||
1994 | 141 | |||
1995 | 142 | /* | ||
1996 | 143 | * This is invoked when there is some kind of error | ||
1997 | 144 | * parsing data to/from the agent. The VM can continue | ||
1998 | 145 | * to run, but no further agent commands will be | ||
1999 | 146 | * allowed | ||
2000 | 147 | */ | ||
2001 | 148 | static void | ||
2002 | 149 | qemuProcessHandleAgentError(qemuAgentPtr agent ATTRIBUTE_UNUSED, | ||
2003 | 150 | virDomainObjPtr vm) | ||
2004 | 151 | { | ||
2005 | 152 | struct qemud_driver *driver = qemu_driver; | ||
2006 | 153 | qemuDomainObjPrivatePtr priv; | ||
2007 | 154 | |||
2008 | 155 | VIR_DEBUG("Received error from agent on %p '%s'", vm, vm->def->name); | ||
2009 | 156 | |||
2010 | 157 | qemuDriverLock(driver); | ||
2011 | 158 | virDomainObjLock(vm); | ||
2012 | 159 | |||
2013 | 160 | priv = vm->privateData; | ||
2014 | 161 | |||
2015 | 162 | priv->agentError = true; | ||
2016 | 163 | |||
2017 | 164 | virDomainObjUnlock(vm); | ||
2018 | 165 | qemuDriverUnlock(driver); | ||
2019 | 166 | } | ||
2020 | 167 | |||
2021 | 168 | static void qemuProcessHandleAgentDestroy(qemuAgentPtr agent, | ||
2022 | 169 | virDomainObjPtr vm) | ||
2023 | 170 | { | ||
2024 | 171 | VIR_DEBUG("Received destroy agent=%p vm=%p", agent, vm); | ||
2025 | 172 | |||
2026 | 173 | virObjectUnref(vm); | ||
2027 | 174 | } | ||
2028 | 175 | |||
2029 | 176 | |||
2030 | 177 | static qemuAgentCallbacks agentCallbacks = { | ||
2031 | 178 | .destroy = qemuProcessHandleAgentDestroy, | ||
2032 | 179 | .eofNotify = qemuProcessHandleAgentEOF, | ||
2033 | 180 | .errorNotify = qemuProcessHandleAgentError, | ||
2034 | 181 | }; | ||
2035 | 182 | |||
2036 | 183 | static virDomainChrSourceDefPtr | ||
2037 | 184 | qemuFindAgentConfig(virDomainDefPtr def) | ||
2038 | 185 | { | ||
2039 | 186 | virDomainChrSourceDefPtr config = NULL; | ||
2040 | 187 | int i; | ||
2041 | 188 | |||
2042 | 189 | for (i = 0 ; i < def->nchannels ; i++) { | ||
2043 | 190 | virDomainChrDefPtr channel = def->channels[i]; | ||
2044 | 191 | |||
2045 | 192 | if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) | ||
2046 | 193 | continue; | ||
2047 | 194 | |||
2048 | 195 | if (STREQ_NULLABLE(channel->target.name, "org.qemu.guest_agent.0")) { | ||
2049 | 196 | config = &channel->source; | ||
2050 | 197 | break; | ||
2051 | 198 | } | ||
2052 | 199 | } | ||
2053 | 200 | |||
2054 | 201 | return config; | ||
2055 | 202 | } | ||
2056 | 203 | |||
2057 | 204 | static int | ||
2058 | 205 | qemuConnectAgent(struct qemud_driver *driver, virDomainObjPtr vm) | ||
2059 | 206 | { | ||
2060 | 207 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2061 | 208 | int ret = -1; | ||
2062 | 209 | qemuAgentPtr agent = NULL; | ||
2063 | 210 | virDomainChrSourceDefPtr config = qemuFindAgentConfig(vm->def); | ||
2064 | 211 | |||
2065 | 212 | if (!config) | ||
2066 | 213 | return 0; | ||
2067 | 214 | |||
2068 | 215 | if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager, | ||
2069 | 216 | vm->def) < 0) { | ||
2070 | 217 | VIR_ERROR(_("Failed to set security context for agent for %s"), | ||
2071 | 218 | vm->def->name); | ||
2072 | 219 | goto cleanup; | ||
2073 | 220 | } | ||
2074 | 221 | |||
2075 | 222 | /* Hold an extra reference because we can't allow 'vm' to be | ||
2076 | 223 | * deleted while the agent is active */ | ||
2077 | 224 | virObjectRef(vm); | ||
2078 | 225 | |||
2079 | 226 | ignore_value(virTimeMillisNow(&priv->agentStart)); | ||
2080 | 227 | virDomainObjUnlock(vm); | ||
2081 | 228 | qemuDriverUnlock(driver); | ||
2082 | 229 | |||
2083 | 230 | agent = qemuAgentOpen(vm, | ||
2084 | 231 | config, | ||
2085 | 232 | &agentCallbacks); | ||
2086 | 233 | |||
2087 | 234 | qemuDriverLock(driver); | ||
2088 | 235 | virDomainObjLock(vm); | ||
2089 | 236 | priv->agentStart = 0; | ||
2090 | 237 | |||
2091 | 238 | if (virSecurityManagerClearSocketLabel(driver->securityManager, | ||
2092 | 239 | vm->def) < 0) { | ||
2093 | 240 | VIR_ERROR(_("Failed to clear security context for agent for %s"), | ||
2094 | 241 | vm->def->name); | ||
2095 | 242 | goto cleanup; | ||
2096 | 243 | } | ||
2097 | 244 | |||
2098 | 245 | if (agent == NULL) | ||
2099 | 246 | virObjectUnref(vm); | ||
2100 | 247 | |||
2101 | 248 | if (!virDomainObjIsActive(vm)) { | ||
2102 | 249 | qemuAgentClose(agent); | ||
2103 | 250 | goto cleanup; | ||
2104 | 251 | } | ||
2105 | 252 | priv->agent = agent; | ||
2106 | 253 | |||
2107 | 254 | if (priv->agent == NULL) { | ||
2108 | 255 | VIR_INFO("Failed to connect agent for %s", vm->def->name); | ||
2109 | 256 | goto cleanup; | ||
2110 | 257 | } | ||
2111 | 258 | |||
2112 | 259 | ret = 0; | ||
2113 | 260 | |||
2114 | 261 | cleanup: | ||
2115 | 262 | return ret; | ||
2116 | 263 | } | ||
2117 | 264 | |||
2118 | 265 | |||
2119 | 266 | /* | ||
2120 | 267 | * This is a callback registered with a qemuMonitorPtr instance, | ||
2121 | 268 | * and to be invoked when the monitor console hits an end of file | ||
2122 | 269 | * condition, or error, thus indicating VM shutdown should be | ||
2123 | 270 | * performed | ||
2124 | 271 | */ | ||
2125 | 272 | static void | ||
2126 | 273 | qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2127 | 274 | virDomainObjPtr vm) | ||
2128 | 275 | { | ||
2129 | 276 | struct qemud_driver *driver = qemu_driver; | ||
2130 | 277 | virDomainEventPtr event = NULL; | ||
2131 | 278 | qemuDomainObjPrivatePtr priv; | ||
2132 | 279 | int eventReason = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN; | ||
2133 | 280 | int stopReason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; | ||
2134 | 281 | const char *auditReason = "shutdown"; | ||
2135 | 282 | |||
2136 | 283 | VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name); | ||
2137 | 284 | |||
2138 | 285 | qemuDriverLock(driver); | ||
2139 | 286 | virDomainObjLock(vm); | ||
2140 | 287 | |||
2141 | 288 | priv = vm->privateData; | ||
2142 | 289 | |||
2143 | 290 | if (priv->beingDestroyed) { | ||
2144 | 291 | VIR_DEBUG("Domain is being destroyed, EOF is expected"); | ||
2145 | 292 | goto unlock; | ||
2146 | 293 | } | ||
2147 | 294 | |||
2148 | 295 | if (!virDomainObjIsActive(vm)) { | ||
2149 | 296 | VIR_DEBUG("Domain %p is not active, ignoring EOF", vm); | ||
2150 | 297 | goto unlock; | ||
2151 | 298 | } | ||
2152 | 299 | |||
2153 | 300 | if (priv->monJSON && !priv->gotShutdown) { | ||
2154 | 301 | VIR_DEBUG("Monitor connection to '%s' closed without SHUTDOWN event; " | ||
2155 | 302 | "assuming the domain crashed", vm->def->name); | ||
2156 | 303 | eventReason = VIR_DOMAIN_EVENT_STOPPED_FAILED; | ||
2157 | 304 | stopReason = VIR_DOMAIN_SHUTOFF_CRASHED; | ||
2158 | 305 | auditReason = "failed"; | ||
2159 | 306 | } | ||
2160 | 307 | |||
2161 | 308 | event = virDomainEventNewFromObj(vm, | ||
2162 | 309 | VIR_DOMAIN_EVENT_STOPPED, | ||
2163 | 310 | eventReason); | ||
2164 | 311 | qemuProcessStop(driver, vm, stopReason, 0); | ||
2165 | 312 | virDomainAuditStop(vm, auditReason); | ||
2166 | 313 | |||
2167 | 314 | if (!vm->persistent) { | ||
2168 | 315 | qemuDomainRemoveInactive(driver, vm); | ||
2169 | 316 | goto cleanup; | ||
2170 | 317 | } | ||
2171 | 318 | |||
2172 | 319 | unlock: | ||
2173 | 320 | virDomainObjUnlock(vm); | ||
2174 | 321 | |||
2175 | 322 | cleanup: | ||
2176 | 323 | if (event) | ||
2177 | 324 | qemuDomainEventQueue(driver, event); | ||
2178 | 325 | qemuDriverUnlock(driver); | ||
2179 | 326 | } | ||
2180 | 327 | |||
2181 | 328 | |||
2182 | 329 | /* | ||
2183 | 330 | * This is invoked when there is some kind of error | ||
2184 | 331 | * parsing data to/from the monitor. The VM can continue | ||
2185 | 332 | * to run, but no further monitor commands will be | ||
2186 | 333 | * allowed | ||
2187 | 334 | */ | ||
2188 | 335 | static void | ||
2189 | 336 | qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2190 | 337 | virDomainObjPtr vm) | ||
2191 | 338 | { | ||
2192 | 339 | struct qemud_driver *driver = qemu_driver; | ||
2193 | 340 | virDomainEventPtr event = NULL; | ||
2194 | 341 | |||
2195 | 342 | VIR_DEBUG("Received error on %p '%s'", vm, vm->def->name); | ||
2196 | 343 | |||
2197 | 344 | qemuDriverLock(driver); | ||
2198 | 345 | virDomainObjLock(vm); | ||
2199 | 346 | |||
2200 | 347 | ((qemuDomainObjPrivatePtr) vm->privateData)->monError = true; | ||
2201 | 348 | event = virDomainEventControlErrorNewFromObj(vm); | ||
2202 | 349 | if (event) | ||
2203 | 350 | qemuDomainEventQueue(driver, event); | ||
2204 | 351 | |||
2205 | 352 | virDomainObjUnlock(vm); | ||
2206 | 353 | qemuDriverUnlock(driver); | ||
2207 | 354 | } | ||
2208 | 355 | |||
2209 | 356 | |||
2210 | 357 | static virDomainDiskDefPtr | ||
2211 | 358 | qemuProcessFindDomainDiskByPath(virDomainObjPtr vm, | ||
2212 | 359 | const char *path) | ||
2213 | 360 | { | ||
2214 | 361 | int i = virDomainDiskIndexByName(vm->def, path, true); | ||
2215 | 362 | |||
2216 | 363 | if (i >= 0) | ||
2217 | 364 | return vm->def->disks[i]; | ||
2218 | 365 | |||
2219 | 366 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
2220 | 367 | _("no disk found with path %s"), | ||
2221 | 368 | path); | ||
2222 | 369 | return NULL; | ||
2223 | 370 | } | ||
2224 | 371 | |||
2225 | 372 | static virDomainDiskDefPtr | ||
2226 | 373 | qemuProcessFindDomainDiskByAlias(virDomainObjPtr vm, | ||
2227 | 374 | const char *alias) | ||
2228 | 375 | { | ||
2229 | 376 | int i; | ||
2230 | 377 | |||
2231 | 378 | if (STRPREFIX(alias, QEMU_DRIVE_HOST_PREFIX)) | ||
2232 | 379 | alias += strlen(QEMU_DRIVE_HOST_PREFIX); | ||
2233 | 380 | |||
2234 | 381 | for (i = 0; i < vm->def->ndisks; i++) { | ||
2235 | 382 | virDomainDiskDefPtr disk; | ||
2236 | 383 | |||
2237 | 384 | disk = vm->def->disks[i]; | ||
2238 | 385 | if (disk->info.alias != NULL && STREQ(disk->info.alias, alias)) | ||
2239 | 386 | return disk; | ||
2240 | 387 | } | ||
2241 | 388 | |||
2242 | 389 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
2243 | 390 | _("no disk found with alias %s"), | ||
2244 | 391 | alias); | ||
2245 | 392 | return NULL; | ||
2246 | 393 | } | ||
2247 | 394 | |||
2248 | 395 | static int | ||
2249 | 396 | qemuProcessGetVolumeQcowPassphrase(virConnectPtr conn, | ||
2250 | 397 | virDomainDiskDefPtr disk, | ||
2251 | 398 | char **secretRet, | ||
2252 | 399 | size_t *secretLen) | ||
2253 | 400 | { | ||
2254 | 401 | virSecretPtr secret; | ||
2255 | 402 | char *passphrase; | ||
2256 | 403 | unsigned char *data; | ||
2257 | 404 | size_t size; | ||
2258 | 405 | int ret = -1; | ||
2259 | 406 | virStorageEncryptionPtr enc; | ||
2260 | 407 | |||
2261 | 408 | if (!disk->encryption) { | ||
2262 | 409 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
2263 | 410 | _("disk %s does not have any encryption information"), | ||
2264 | 411 | disk->src); | ||
2265 | 412 | return -1; | ||
2266 | 413 | } | ||
2267 | 414 | enc = disk->encryption; | ||
2268 | 415 | |||
2269 | 416 | if (!conn) { | ||
2270 | 417 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
2271 | 418 | "%s", _("cannot find secrets without a connection")); | ||
2272 | 419 | goto cleanup; | ||
2273 | 420 | } | ||
2274 | 421 | |||
2275 | 422 | if (conn->secretDriver == NULL || | ||
2276 | 423 | conn->secretDriver->lookupByUUID == NULL || | ||
2277 | 424 | conn->secretDriver->getValue == NULL) { | ||
2278 | 425 | virReportError(VIR_ERR_OPERATION_INVALID, "%s", | ||
2279 | 426 | _("secret storage not supported")); | ||
2280 | 427 | goto cleanup; | ||
2281 | 428 | } | ||
2282 | 429 | |||
2283 | 430 | if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW || | ||
2284 | 431 | enc->nsecrets != 1 || | ||
2285 | 432 | enc->secrets[0]->type != | ||
2286 | 433 | VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE) { | ||
2287 | 434 | virReportError(VIR_ERR_XML_ERROR, | ||
2288 | 435 | _("invalid <encryption> for volume %s"), disk->src); | ||
2289 | 436 | goto cleanup; | ||
2290 | 437 | } | ||
2291 | 438 | |||
2292 | 439 | secret = conn->secretDriver->lookupByUUID(conn, | ||
2293 | 440 | enc->secrets[0]->uuid); | ||
2294 | 441 | if (secret == NULL) | ||
2295 | 442 | goto cleanup; | ||
2296 | 443 | data = conn->secretDriver->getValue(secret, &size, 0, | ||
2297 | 444 | VIR_SECRET_GET_VALUE_INTERNAL_CALL); | ||
2298 | 445 | virObjectUnref(secret); | ||
2299 | 446 | if (data == NULL) | ||
2300 | 447 | goto cleanup; | ||
2301 | 448 | |||
2302 | 449 | if (memchr(data, '\0', size) != NULL) { | ||
2303 | 450 | memset(data, 0, size); | ||
2304 | 451 | VIR_FREE(data); | ||
2305 | 452 | virReportError(VIR_ERR_XML_ERROR, | ||
2306 | 453 | _("format='qcow' passphrase for %s must not contain a " | ||
2307 | 454 | "'\\0'"), disk->src); | ||
2308 | 455 | goto cleanup; | ||
2309 | 456 | } | ||
2310 | 457 | |||
2311 | 458 | if (VIR_ALLOC_N(passphrase, size + 1) < 0) { | ||
2312 | 459 | memset(data, 0, size); | ||
2313 | 460 | VIR_FREE(data); | ||
2314 | 461 | virReportOOMError(); | ||
2315 | 462 | goto cleanup; | ||
2316 | 463 | } | ||
2317 | 464 | memcpy(passphrase, data, size); | ||
2318 | 465 | passphrase[size] = '\0'; | ||
2319 | 466 | |||
2320 | 467 | memset(data, 0, size); | ||
2321 | 468 | VIR_FREE(data); | ||
2322 | 469 | |||
2323 | 470 | *secretRet = passphrase; | ||
2324 | 471 | *secretLen = size; | ||
2325 | 472 | |||
2326 | 473 | ret = 0; | ||
2327 | 474 | |||
2328 | 475 | cleanup: | ||
2329 | 476 | return ret; | ||
2330 | 477 | } | ||
2331 | 478 | |||
2332 | 479 | static int | ||
2333 | 480 | qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2334 | 481 | virConnectPtr conn, | ||
2335 | 482 | virDomainObjPtr vm, | ||
2336 | 483 | const char *path, | ||
2337 | 484 | char **secretRet, | ||
2338 | 485 | size_t *secretLen) | ||
2339 | 486 | { | ||
2340 | 487 | virDomainDiskDefPtr disk; | ||
2341 | 488 | int ret = -1; | ||
2342 | 489 | |||
2343 | 490 | virDomainObjLock(vm); | ||
2344 | 491 | disk = qemuProcessFindDomainDiskByPath(vm, path); | ||
2345 | 492 | |||
2346 | 493 | if (!disk) | ||
2347 | 494 | goto cleanup; | ||
2348 | 495 | |||
2349 | 496 | ret = qemuProcessGetVolumeQcowPassphrase(conn, disk, secretRet, secretLen); | ||
2350 | 497 | |||
2351 | 498 | cleanup: | ||
2352 | 499 | virDomainObjUnlock(vm); | ||
2353 | 500 | return ret; | ||
2354 | 501 | } | ||
2355 | 502 | |||
2356 | 503 | |||
2357 | 504 | static int | ||
2358 | 505 | qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2359 | 506 | virDomainObjPtr vm) | ||
2360 | 507 | { | ||
2361 | 508 | struct qemud_driver *driver = qemu_driver; | ||
2362 | 509 | virDomainEventPtr event; | ||
2363 | 510 | qemuDomainObjPrivatePtr priv; | ||
2364 | 511 | |||
2365 | 512 | virDomainObjLock(vm); | ||
2366 | 513 | |||
2367 | 514 | event = virDomainEventRebootNewFromObj(vm); | ||
2368 | 515 | priv = vm->privateData; | ||
2369 | 516 | if (priv->agent) | ||
2370 | 517 | qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_RESET); | ||
2371 | 518 | |||
2372 | 519 | virDomainObjUnlock(vm); | ||
2373 | 520 | |||
2374 | 521 | if (event) { | ||
2375 | 522 | qemuDriverLock(driver); | ||
2376 | 523 | qemuDomainEventQueue(driver, event); | ||
2377 | 524 | qemuDriverUnlock(driver); | ||
2378 | 525 | } | ||
2379 | 526 | |||
2380 | 527 | return 0; | ||
2381 | 528 | } | ||
2382 | 529 | |||
2383 | 530 | |||
2384 | 531 | /* | ||
2385 | 532 | * Since we have the '-no-shutdown' flag set, the | ||
2386 | 533 | * QEMU process will currently have guest OS shutdown | ||
2387 | 534 | * and the CPUS stopped. To fake the reboot, we thus | ||
2388 | 535 | * want todo a reset of the virtual hardware, followed | ||
2389 | 536 | * by restart of the CPUs. This should result in the | ||
2390 | 537 | * guest OS booting up again | ||
2391 | 538 | */ | ||
2392 | 539 | static void | ||
2393 | 540 | qemuProcessFakeReboot(void *opaque) | ||
2394 | 541 | { | ||
2395 | 542 | struct qemud_driver *driver = qemu_driver; | ||
2396 | 543 | virDomainObjPtr vm = opaque; | ||
2397 | 544 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2398 | 545 | virDomainEventPtr event = NULL; | ||
2399 | 546 | int ret = -1; | ||
2400 | 547 | VIR_DEBUG("vm=%p", vm); | ||
2401 | 548 | qemuDriverLock(driver); | ||
2402 | 549 | virDomainObjLock(vm); | ||
2403 | 550 | if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) | ||
2404 | 551 | goto cleanup; | ||
2405 | 552 | |||
2406 | 553 | if (!virDomainObjIsActive(vm)) { | ||
2407 | 554 | virReportError(VIR_ERR_INTERNAL_ERROR, "%s", | ||
2408 | 555 | _("guest unexpectedly quit")); | ||
2409 | 556 | goto endjob; | ||
2410 | 557 | } | ||
2411 | 558 | |||
2412 | 559 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
2413 | 560 | if (qemuMonitorSystemReset(priv->mon) < 0) { | ||
2414 | 561 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
2415 | 562 | goto endjob; | ||
2416 | 563 | } | ||
2417 | 564 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
2418 | 565 | |||
2419 | 566 | if (!virDomainObjIsActive(vm)) { | ||
2420 | 567 | virReportError(VIR_ERR_INTERNAL_ERROR, "%s", | ||
2421 | 568 | _("guest unexpectedly quit")); | ||
2422 | 569 | goto endjob; | ||
2423 | 570 | } | ||
2424 | 571 | |||
2425 | 572 | if (qemuProcessStartCPUs(driver, vm, NULL, | ||
2426 | 573 | VIR_DOMAIN_RUNNING_BOOTED, | ||
2427 | 574 | QEMU_ASYNC_JOB_NONE) < 0) { | ||
2428 | 575 | if (virGetLastError() == NULL) | ||
2429 | 576 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
2430 | 577 | "%s", _("resume operation failed")); | ||
2431 | 578 | goto endjob; | ||
2432 | 579 | } | ||
2433 | 580 | priv->gotShutdown = false; | ||
2434 | 581 | event = virDomainEventNewFromObj(vm, | ||
2435 | 582 | VIR_DOMAIN_EVENT_RESUMED, | ||
2436 | 583 | VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); | ||
2437 | 584 | |||
2438 | 585 | ret = 0; | ||
2439 | 586 | |||
2440 | 587 | endjob: | ||
2441 | 588 | if (!qemuDomainObjEndJob(driver, vm)) | ||
2442 | 589 | vm = NULL; | ||
2443 | 590 | |||
2444 | 591 | cleanup: | ||
2445 | 592 | if (vm) { | ||
2446 | 593 | if (ret == -1) { | ||
2447 | 594 | ignore_value(qemuProcessKill(driver, vm, | ||
2448 | 595 | VIR_QEMU_PROCESS_KILL_FORCE)); | ||
2449 | 596 | } | ||
2450 | 597 | if (virObjectUnref(vm)) | ||
2451 | 598 | virDomainObjUnlock(vm); | ||
2452 | 599 | } | ||
2453 | 600 | if (event) | ||
2454 | 601 | qemuDomainEventQueue(driver, event); | ||
2455 | 602 | qemuDriverUnlock(driver); | ||
2456 | 603 | } | ||
2457 | 604 | |||
2458 | 605 | |||
2459 | 606 | static void | ||
2460 | 607 | qemuProcessShutdownOrReboot(struct qemud_driver *driver, | ||
2461 | 608 | virDomainObjPtr vm) | ||
2462 | 609 | { | ||
2463 | 610 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2464 | 611 | |||
2465 | 612 | if (priv->fakeReboot) { | ||
2466 | 613 | qemuDomainSetFakeReboot(driver, vm, false); | ||
2467 | 614 | virObjectRef(vm); | ||
2468 | 615 | virThread th; | ||
2469 | 616 | if (virThreadCreate(&th, | ||
2470 | 617 | false, | ||
2471 | 618 | qemuProcessFakeReboot, | ||
2472 | 619 | vm) < 0) { | ||
2473 | 620 | VIR_ERROR(_("Failed to create reboot thread, killing domain")); | ||
2474 | 621 | ignore_value(qemuProcessKill(driver, vm, | ||
2475 | 622 | VIR_QEMU_PROCESS_KILL_NOWAIT)); | ||
2476 | 623 | virObjectUnref(vm); | ||
2477 | 624 | } | ||
2478 | 625 | } else { | ||
2479 | 626 | ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_NOWAIT)); | ||
2480 | 627 | } | ||
2481 | 628 | } | ||
2482 | 629 | |||
2483 | 630 | static int | ||
2484 | 631 | qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2485 | 632 | virDomainObjPtr vm) | ||
2486 | 633 | { | ||
2487 | 634 | struct qemud_driver *driver = qemu_driver; | ||
2488 | 635 | qemuDomainObjPrivatePtr priv; | ||
2489 | 636 | virDomainEventPtr event = NULL; | ||
2490 | 637 | |||
2491 | 638 | VIR_DEBUG("vm=%p", vm); | ||
2492 | 639 | |||
2493 | 640 | virDomainObjLock(vm); | ||
2494 | 641 | |||
2495 | 642 | priv = vm->privateData; | ||
2496 | 643 | if (priv->gotShutdown) { | ||
2497 | 644 | VIR_DEBUG("Ignoring repeated SHUTDOWN event from domain %s", | ||
2498 | 645 | vm->def->name); | ||
2499 | 646 | goto unlock; | ||
2500 | 647 | } else if (!virDomainObjIsActive(vm)) { | ||
2501 | 648 | VIR_DEBUG("Ignoring SHUTDOWN event from inactive domain %s", | ||
2502 | 649 | vm->def->name); | ||
2503 | 650 | goto unlock; | ||
2504 | 651 | } | ||
2505 | 652 | priv->gotShutdown = true; | ||
2506 | 653 | |||
2507 | 654 | VIR_DEBUG("Transitioned guest %s to shutdown state", | ||
2508 | 655 | vm->def->name); | ||
2509 | 656 | virDomainObjSetState(vm, | ||
2510 | 657 | VIR_DOMAIN_SHUTDOWN, | ||
2511 | 658 | VIR_DOMAIN_SHUTDOWN_UNKNOWN); | ||
2512 | 659 | event = virDomainEventNewFromObj(vm, | ||
2513 | 660 | VIR_DOMAIN_EVENT_SHUTDOWN, | ||
2514 | 661 | VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED); | ||
2515 | 662 | |||
2516 | 663 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
2517 | 664 | VIR_WARN("Unable to save status on vm %s after state change", | ||
2518 | 665 | vm->def->name); | ||
2519 | 666 | } | ||
2520 | 667 | |||
2521 | 668 | if (priv->agent) | ||
2522 | 669 | qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SHUTDOWN); | ||
2523 | 670 | |||
2524 | 671 | qemuProcessShutdownOrReboot(driver, vm); | ||
2525 | 672 | |||
2526 | 673 | unlock: | ||
2527 | 674 | virDomainObjUnlock(vm); | ||
2528 | 675 | |||
2529 | 676 | if (event) { | ||
2530 | 677 | qemuDriverLock(driver); | ||
2531 | 678 | qemuDomainEventQueue(driver, event); | ||
2532 | 679 | qemuDriverUnlock(driver); | ||
2533 | 680 | } | ||
2534 | 681 | |||
2535 | 682 | return 0; | ||
2536 | 683 | } | ||
2537 | 684 | |||
2538 | 685 | |||
2539 | 686 | static int | ||
2540 | 687 | qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2541 | 688 | virDomainObjPtr vm) | ||
2542 | 689 | { | ||
2543 | 690 | struct qemud_driver *driver = qemu_driver; | ||
2544 | 691 | virDomainEventPtr event = NULL; | ||
2545 | 692 | |||
2546 | 693 | virDomainObjLock(vm); | ||
2547 | 694 | if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { | ||
2548 | 695 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2549 | 696 | |||
2550 | 697 | if (priv->gotShutdown) { | ||
2551 | 698 | VIR_DEBUG("Ignoring STOP event after SHUTDOWN"); | ||
2552 | 699 | goto unlock; | ||
2553 | 700 | } | ||
2554 | 701 | |||
2555 | 702 | VIR_DEBUG("Transitioned guest %s to paused state", | ||
2556 | 703 | vm->def->name); | ||
2557 | 704 | |||
2558 | 705 | virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_UNKNOWN); | ||
2559 | 706 | event = virDomainEventNewFromObj(vm, | ||
2560 | 707 | VIR_DOMAIN_EVENT_SUSPENDED, | ||
2561 | 708 | VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); | ||
2562 | 709 | |||
2563 | 710 | VIR_FREE(priv->lockState); | ||
2564 | 711 | if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) | ||
2565 | 712 | VIR_WARN("Unable to release lease on %s", vm->def->name); | ||
2566 | 713 | VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); | ||
2567 | 714 | |||
2568 | 715 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
2569 | 716 | VIR_WARN("Unable to save status on vm %s after state change", | ||
2570 | 717 | vm->def->name); | ||
2571 | 718 | } | ||
2572 | 719 | } | ||
2573 | 720 | |||
2574 | 721 | unlock: | ||
2575 | 722 | virDomainObjUnlock(vm); | ||
2576 | 723 | |||
2577 | 724 | if (event) { | ||
2578 | 725 | qemuDriverLock(driver); | ||
2579 | 726 | qemuDomainEventQueue(driver, event); | ||
2580 | 727 | qemuDriverUnlock(driver); | ||
2581 | 728 | } | ||
2582 | 729 | |||
2583 | 730 | return 0; | ||
2584 | 731 | } | ||
2585 | 732 | |||
2586 | 733 | |||
2587 | 734 | static int | ||
2588 | 735 | qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2589 | 736 | virDomainObjPtr vm, | ||
2590 | 737 | long long offset) | ||
2591 | 738 | { | ||
2592 | 739 | struct qemud_driver *driver = qemu_driver; | ||
2593 | 740 | virDomainEventPtr event; | ||
2594 | 741 | |||
2595 | 742 | virDomainObjLock(vm); | ||
2596 | 743 | event = virDomainEventRTCChangeNewFromObj(vm, offset); | ||
2597 | 744 | |||
2598 | 745 | if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) | ||
2599 | 746 | vm->def->clock.data.variable.adjustment = offset; | ||
2600 | 747 | |||
2601 | 748 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) | ||
2602 | 749 | VIR_WARN("unable to save domain status with RTC change"); | ||
2603 | 750 | |||
2604 | 751 | virDomainObjUnlock(vm); | ||
2605 | 752 | |||
2606 | 753 | if (event) { | ||
2607 | 754 | qemuDriverLock(driver); | ||
2608 | 755 | qemuDomainEventQueue(driver, event); | ||
2609 | 756 | qemuDriverUnlock(driver); | ||
2610 | 757 | } | ||
2611 | 758 | |||
2612 | 759 | return 0; | ||
2613 | 760 | } | ||
2614 | 761 | |||
2615 | 762 | |||
2616 | 763 | static int | ||
2617 | 764 | qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2618 | 765 | virDomainObjPtr vm, | ||
2619 | 766 | int action) | ||
2620 | 767 | { | ||
2621 | 768 | struct qemud_driver *driver = qemu_driver; | ||
2622 | 769 | virDomainEventPtr watchdogEvent = NULL; | ||
2623 | 770 | virDomainEventPtr lifecycleEvent = NULL; | ||
2624 | 771 | |||
2625 | 772 | virDomainObjLock(vm); | ||
2626 | 773 | watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action); | ||
2627 | 774 | |||
2628 | 775 | if (action == VIR_DOMAIN_EVENT_WATCHDOG_PAUSE && | ||
2629 | 776 | virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { | ||
2630 | 777 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2631 | 778 | VIR_DEBUG("Transitioned guest %s to paused state due to watchdog", vm->def->name); | ||
2632 | 779 | |||
2633 | 780 | virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_WATCHDOG); | ||
2634 | 781 | lifecycleEvent = virDomainEventNewFromObj(vm, | ||
2635 | 782 | VIR_DOMAIN_EVENT_SUSPENDED, | ||
2636 | 783 | VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG); | ||
2637 | 784 | |||
2638 | 785 | VIR_FREE(priv->lockState); | ||
2639 | 786 | if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) | ||
2640 | 787 | VIR_WARN("Unable to release lease on %s", vm->def->name); | ||
2641 | 788 | VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); | ||
2642 | 789 | |||
2643 | 790 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
2644 | 791 | VIR_WARN("Unable to save status on vm %s after watchdog event", | ||
2645 | 792 | vm->def->name); | ||
2646 | 793 | } | ||
2647 | 794 | } | ||
2648 | 795 | |||
2649 | 796 | if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) { | ||
2650 | 797 | struct qemuDomainWatchdogEvent *wdEvent; | ||
2651 | 798 | if (VIR_ALLOC(wdEvent) == 0) { | ||
2652 | 799 | wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP; | ||
2653 | 800 | wdEvent->vm = vm; | ||
2654 | 801 | /* Hold an extra reference because we can't allow 'vm' to be | ||
2655 | 802 | * deleted before handling watchdog event is finished. | ||
2656 | 803 | */ | ||
2657 | 804 | virObjectRef(vm); | ||
2658 | 805 | if (virThreadPoolSendJob(driver->workerPool, 0, wdEvent) < 0) { | ||
2659 | 806 | if (!virObjectUnref(vm)) | ||
2660 | 807 | vm = NULL; | ||
2661 | 808 | VIR_FREE(wdEvent); | ||
2662 | 809 | } | ||
2663 | 810 | } else { | ||
2664 | 811 | virReportOOMError(); | ||
2665 | 812 | } | ||
2666 | 813 | } | ||
2667 | 814 | |||
2668 | 815 | if (vm) | ||
2669 | 816 | virDomainObjUnlock(vm); | ||
2670 | 817 | |||
2671 | 818 | if (watchdogEvent || lifecycleEvent) { | ||
2672 | 819 | qemuDriverLock(driver); | ||
2673 | 820 | if (watchdogEvent) | ||
2674 | 821 | qemuDomainEventQueue(driver, watchdogEvent); | ||
2675 | 822 | if (lifecycleEvent) | ||
2676 | 823 | qemuDomainEventQueue(driver, lifecycleEvent); | ||
2677 | 824 | qemuDriverUnlock(driver); | ||
2678 | 825 | } | ||
2679 | 826 | |||
2680 | 827 | return 0; | ||
2681 | 828 | } | ||
2682 | 829 | |||
2683 | 830 | |||
2684 | 831 | static int | ||
2685 | 832 | qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2686 | 833 | virDomainObjPtr vm, | ||
2687 | 834 | const char *diskAlias, | ||
2688 | 835 | int action, | ||
2689 | 836 | const char *reason) | ||
2690 | 837 | { | ||
2691 | 838 | struct qemud_driver *driver = qemu_driver; | ||
2692 | 839 | virDomainEventPtr ioErrorEvent = NULL; | ||
2693 | 840 | virDomainEventPtr ioErrorEvent2 = NULL; | ||
2694 | 841 | virDomainEventPtr lifecycleEvent = NULL; | ||
2695 | 842 | const char *srcPath; | ||
2696 | 843 | const char *devAlias; | ||
2697 | 844 | virDomainDiskDefPtr disk; | ||
2698 | 845 | |||
2699 | 846 | virDomainObjLock(vm); | ||
2700 | 847 | disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias); | ||
2701 | 848 | |||
2702 | 849 | if (disk) { | ||
2703 | 850 | srcPath = disk->src; | ||
2704 | 851 | devAlias = disk->info.alias; | ||
2705 | 852 | } else { | ||
2706 | 853 | srcPath = ""; | ||
2707 | 854 | devAlias = ""; | ||
2708 | 855 | } | ||
2709 | 856 | |||
2710 | 857 | ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, srcPath, devAlias, action); | ||
2711 | 858 | ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, srcPath, devAlias, action, reason); | ||
2712 | 859 | |||
2713 | 860 | if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE && | ||
2714 | 861 | virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { | ||
2715 | 862 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2716 | 863 | VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name); | ||
2717 | 864 | |||
2718 | 865 | virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR); | ||
2719 | 866 | lifecycleEvent = virDomainEventNewFromObj(vm, | ||
2720 | 867 | VIR_DOMAIN_EVENT_SUSPENDED, | ||
2721 | 868 | VIR_DOMAIN_EVENT_SUSPENDED_IOERROR); | ||
2722 | 869 | |||
2723 | 870 | VIR_FREE(priv->lockState); | ||
2724 | 871 | if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) | ||
2725 | 872 | VIR_WARN("Unable to release lease on %s", vm->def->name); | ||
2726 | 873 | VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); | ||
2727 | 874 | |||
2728 | 875 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) | ||
2729 | 876 | VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name); | ||
2730 | 877 | } | ||
2731 | 878 | virDomainObjUnlock(vm); | ||
2732 | 879 | |||
2733 | 880 | if (ioErrorEvent || ioErrorEvent2 || lifecycleEvent) { | ||
2734 | 881 | qemuDriverLock(driver); | ||
2735 | 882 | if (ioErrorEvent) | ||
2736 | 883 | qemuDomainEventQueue(driver, ioErrorEvent); | ||
2737 | 884 | if (ioErrorEvent2) | ||
2738 | 885 | qemuDomainEventQueue(driver, ioErrorEvent2); | ||
2739 | 886 | if (lifecycleEvent) | ||
2740 | 887 | qemuDomainEventQueue(driver, lifecycleEvent); | ||
2741 | 888 | qemuDriverUnlock(driver); | ||
2742 | 889 | } | ||
2743 | 890 | |||
2744 | 891 | return 0; | ||
2745 | 892 | } | ||
2746 | 893 | |||
2747 | 894 | static int | ||
2748 | 895 | qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2749 | 896 | virDomainObjPtr vm, | ||
2750 | 897 | const char *diskAlias, | ||
2751 | 898 | int type, | ||
2752 | 899 | int status) | ||
2753 | 900 | { | ||
2754 | 901 | struct qemud_driver *driver = qemu_driver; | ||
2755 | 902 | virDomainEventPtr event = NULL; | ||
2756 | 903 | const char *path; | ||
2757 | 904 | virDomainDiskDefPtr disk; | ||
2758 | 905 | |||
2759 | 906 | virDomainObjLock(vm); | ||
2760 | 907 | disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias); | ||
2761 | 908 | |||
2762 | 909 | if (disk) { | ||
2763 | 910 | path = disk->src; | ||
2764 | 911 | event = virDomainEventBlockJobNewFromObj(vm, path, type, status); | ||
2765 | 912 | /* XXX If we completed a block pull or commit, then recompute | ||
2766 | 913 | * the cached backing chain to match. Better would be storing | ||
2767 | 914 | * the chain ourselves rather than reprobing, but this | ||
2768 | 915 | * requires modifying domain_conf and our XML to fully track | ||
2769 | 916 | * the chain across libvirtd restarts. For that matter, if | ||
2770 | 917 | * qemu gains support for committing the active layer, we have | ||
2771 | 918 | * to update disk->src. */ | ||
2772 | 919 | if ((type == VIR_DOMAIN_BLOCK_JOB_TYPE_PULL || | ||
2773 | 920 | type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT) && | ||
2774 | 921 | status == VIR_DOMAIN_BLOCK_JOB_COMPLETED) | ||
2775 | 922 | qemuDomainDetermineDiskChain(driver, disk, true); | ||
2776 | 923 | if (disk->mirror && type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY && | ||
2777 | 924 | status == VIR_DOMAIN_BLOCK_JOB_READY) | ||
2778 | 925 | disk->mirroring = true; | ||
2779 | 926 | } | ||
2780 | 927 | |||
2781 | 928 | virDomainObjUnlock(vm); | ||
2782 | 929 | |||
2783 | 930 | if (event) { | ||
2784 | 931 | qemuDriverLock(driver); | ||
2785 | 932 | qemuDomainEventQueue(driver, event); | ||
2786 | 933 | qemuDriverUnlock(driver); | ||
2787 | 934 | } | ||
2788 | 935 | |||
2789 | 936 | return 0; | ||
2790 | 937 | } | ||
2791 | 938 | |||
2792 | 939 | static int | ||
2793 | 940 | qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2794 | 941 | virDomainObjPtr vm, | ||
2795 | 942 | int phase, | ||
2796 | 943 | int localFamily, | ||
2797 | 944 | const char *localNode, | ||
2798 | 945 | const char *localService, | ||
2799 | 946 | int remoteFamily, | ||
2800 | 947 | const char *remoteNode, | ||
2801 | 948 | const char *remoteService, | ||
2802 | 949 | const char *authScheme, | ||
2803 | 950 | const char *x509dname, | ||
2804 | 951 | const char *saslUsername) | ||
2805 | 952 | { | ||
2806 | 953 | struct qemud_driver *driver = qemu_driver; | ||
2807 | 954 | virDomainEventPtr event; | ||
2808 | 955 | virDomainEventGraphicsAddressPtr localAddr = NULL; | ||
2809 | 956 | virDomainEventGraphicsAddressPtr remoteAddr = NULL; | ||
2810 | 957 | virDomainEventGraphicsSubjectPtr subject = NULL; | ||
2811 | 958 | int i; | ||
2812 | 959 | |||
2813 | 960 | if (VIR_ALLOC(localAddr) < 0) | ||
2814 | 961 | goto no_memory; | ||
2815 | 962 | localAddr->family = localFamily; | ||
2816 | 963 | if (!(localAddr->service = strdup(localService)) || | ||
2817 | 964 | !(localAddr->node = strdup(localNode))) | ||
2818 | 965 | goto no_memory; | ||
2819 | 966 | |||
2820 | 967 | if (VIR_ALLOC(remoteAddr) < 0) | ||
2821 | 968 | goto no_memory; | ||
2822 | 969 | remoteAddr->family = remoteFamily; | ||
2823 | 970 | if (!(remoteAddr->service = strdup(remoteService)) || | ||
2824 | 971 | !(remoteAddr->node = strdup(remoteNode))) | ||
2825 | 972 | goto no_memory; | ||
2826 | 973 | |||
2827 | 974 | if (VIR_ALLOC(subject) < 0) | ||
2828 | 975 | goto no_memory; | ||
2829 | 976 | if (x509dname) { | ||
2830 | 977 | if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0) | ||
2831 | 978 | goto no_memory; | ||
2832 | 979 | subject->nidentity++; | ||
2833 | 980 | if (!(subject->identities[subject->nidentity-1].type = strdup("x509dname")) || | ||
2834 | 981 | !(subject->identities[subject->nidentity-1].name = strdup(x509dname))) | ||
2835 | 982 | goto no_memory; | ||
2836 | 983 | } | ||
2837 | 984 | if (saslUsername) { | ||
2838 | 985 | if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0) | ||
2839 | 986 | goto no_memory; | ||
2840 | 987 | subject->nidentity++; | ||
2841 | 988 | if (!(subject->identities[subject->nidentity-1].type = strdup("saslUsername")) || | ||
2842 | 989 | !(subject->identities[subject->nidentity-1].name = strdup(saslUsername))) | ||
2843 | 990 | goto no_memory; | ||
2844 | 991 | } | ||
2845 | 992 | |||
2846 | 993 | virDomainObjLock(vm); | ||
2847 | 994 | event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject); | ||
2848 | 995 | virDomainObjUnlock(vm); | ||
2849 | 996 | |||
2850 | 997 | if (event) { | ||
2851 | 998 | qemuDriverLock(driver); | ||
2852 | 999 | qemuDomainEventQueue(driver, event); | ||
2853 | 1000 | qemuDriverUnlock(driver); | ||
2854 | 1001 | } | ||
2855 | 1002 | |||
2856 | 1003 | return 0; | ||
2857 | 1004 | |||
2858 | 1005 | no_memory: | ||
2859 | 1006 | virReportOOMError(); | ||
2860 | 1007 | if (localAddr) { | ||
2861 | 1008 | VIR_FREE(localAddr->service); | ||
2862 | 1009 | VIR_FREE(localAddr->node); | ||
2863 | 1010 | VIR_FREE(localAddr); | ||
2864 | 1011 | } | ||
2865 | 1012 | if (remoteAddr) { | ||
2866 | 1013 | VIR_FREE(remoteAddr->service); | ||
2867 | 1014 | VIR_FREE(remoteAddr->node); | ||
2868 | 1015 | VIR_FREE(remoteAddr); | ||
2869 | 1016 | } | ||
2870 | 1017 | if (subject) { | ||
2871 | 1018 | for (i = 0 ; i < subject->nidentity ; i++) { | ||
2872 | 1019 | VIR_FREE(subject->identities[i].type); | ||
2873 | 1020 | VIR_FREE(subject->identities[i].name); | ||
2874 | 1021 | } | ||
2875 | 1022 | VIR_FREE(subject->identities); | ||
2876 | 1023 | VIR_FREE(subject); | ||
2877 | 1024 | } | ||
2878 | 1025 | |||
2879 | 1026 | return -1; | ||
2880 | 1027 | } | ||
2881 | 1028 | |||
2882 | 1029 | |||
2883 | 1030 | static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2884 | 1031 | virDomainObjPtr vm) | ||
2885 | 1032 | { | ||
2886 | 1033 | virObjectUnref(vm); | ||
2887 | 1034 | } | ||
2888 | 1035 | |||
2889 | 1036 | static int | ||
2890 | 1037 | qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2891 | 1038 | virDomainObjPtr vm, | ||
2892 | 1039 | const char *devAlias, | ||
2893 | 1040 | int reason) | ||
2894 | 1041 | { | ||
2895 | 1042 | struct qemud_driver *driver = qemu_driver; | ||
2896 | 1043 | virDomainEventPtr event = NULL; | ||
2897 | 1044 | virDomainDiskDefPtr disk; | ||
2898 | 1045 | |||
2899 | 1046 | virDomainObjLock(vm); | ||
2900 | 1047 | disk = qemuProcessFindDomainDiskByAlias(vm, devAlias); | ||
2901 | 1048 | |||
2902 | 1049 | if (disk) { | ||
2903 | 1050 | event = virDomainEventTrayChangeNewFromObj(vm, | ||
2904 | 1051 | devAlias, | ||
2905 | 1052 | reason); | ||
2906 | 1053 | /* Update disk tray status */ | ||
2907 | 1054 | if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN) | ||
2908 | 1055 | disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN; | ||
2909 | 1056 | else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE) | ||
2910 | 1057 | disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED; | ||
2911 | 1058 | |||
2912 | 1059 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
2913 | 1060 | VIR_WARN("Unable to save status on vm %s after tray moved event", | ||
2914 | 1061 | vm->def->name); | ||
2915 | 1062 | } | ||
2916 | 1063 | } | ||
2917 | 1064 | |||
2918 | 1065 | virDomainObjUnlock(vm); | ||
2919 | 1066 | |||
2920 | 1067 | if (event) { | ||
2921 | 1068 | qemuDriverLock(driver); | ||
2922 | 1069 | qemuDomainEventQueue(driver, event); | ||
2923 | 1070 | qemuDriverUnlock(driver); | ||
2924 | 1071 | } | ||
2925 | 1072 | |||
2926 | 1073 | return 0; | ||
2927 | 1074 | } | ||
2928 | 1075 | |||
2929 | 1076 | static int | ||
2930 | 1077 | qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2931 | 1078 | virDomainObjPtr vm) | ||
2932 | 1079 | { | ||
2933 | 1080 | struct qemud_driver *driver = qemu_driver; | ||
2934 | 1081 | virDomainEventPtr event = NULL; | ||
2935 | 1082 | virDomainEventPtr lifecycleEvent = NULL; | ||
2936 | 1083 | |||
2937 | 1084 | virDomainObjLock(vm); | ||
2938 | 1085 | event = virDomainEventPMWakeupNewFromObj(vm); | ||
2939 | 1086 | |||
2940 | 1087 | /* Don't set domain status back to running if it wasn't paused | ||
2941 | 1088 | * from guest side, otherwise it can just cause confusion. | ||
2942 | 1089 | */ | ||
2943 | 1090 | if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PMSUSPENDED) { | ||
2944 | 1091 | VIR_DEBUG("Transitioned guest %s from pmsuspended to running " | ||
2945 | 1092 | "state due to QMP wakeup event", vm->def->name); | ||
2946 | 1093 | |||
2947 | 1094 | virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, | ||
2948 | 1095 | VIR_DOMAIN_RUNNING_WAKEUP); | ||
2949 | 1096 | lifecycleEvent = virDomainEventNewFromObj(vm, | ||
2950 | 1097 | VIR_DOMAIN_EVENT_STARTED, | ||
2951 | 1098 | VIR_DOMAIN_EVENT_STARTED_WAKEUP); | ||
2952 | 1099 | |||
2953 | 1100 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
2954 | 1101 | VIR_WARN("Unable to save status on vm %s after wakeup event", | ||
2955 | 1102 | vm->def->name); | ||
2956 | 1103 | } | ||
2957 | 1104 | } | ||
2958 | 1105 | |||
2959 | 1106 | virDomainObjUnlock(vm); | ||
2960 | 1107 | |||
2961 | 1108 | if (event || lifecycleEvent) { | ||
2962 | 1109 | qemuDriverLock(driver); | ||
2963 | 1110 | if (event) | ||
2964 | 1111 | qemuDomainEventQueue(driver, event); | ||
2965 | 1112 | if (lifecycleEvent) | ||
2966 | 1113 | qemuDomainEventQueue(driver, lifecycleEvent); | ||
2967 | 1114 | qemuDriverUnlock(driver); | ||
2968 | 1115 | } | ||
2969 | 1116 | |||
2970 | 1117 | return 0; | ||
2971 | 1118 | } | ||
2972 | 1119 | |||
2973 | 1120 | static int | ||
2974 | 1121 | qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
2975 | 1122 | virDomainObjPtr vm) | ||
2976 | 1123 | { | ||
2977 | 1124 | struct qemud_driver *driver = qemu_driver; | ||
2978 | 1125 | virDomainEventPtr event = NULL; | ||
2979 | 1126 | virDomainEventPtr lifecycleEvent = NULL; | ||
2980 | 1127 | |||
2981 | 1128 | virDomainObjLock(vm); | ||
2982 | 1129 | event = virDomainEventPMSuspendNewFromObj(vm); | ||
2983 | 1130 | |||
2984 | 1131 | if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { | ||
2985 | 1132 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
2986 | 1133 | VIR_DEBUG("Transitioned guest %s to pmsuspended state due to " | ||
2987 | 1134 | "QMP suspend event", vm->def->name); | ||
2988 | 1135 | |||
2989 | 1136 | virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED, | ||
2990 | 1137 | VIR_DOMAIN_PMSUSPENDED_UNKNOWN); | ||
2991 | 1138 | lifecycleEvent = | ||
2992 | 1139 | virDomainEventNewFromObj(vm, | ||
2993 | 1140 | VIR_DOMAIN_EVENT_PMSUSPENDED, | ||
2994 | 1141 | VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY); | ||
2995 | 1142 | |||
2996 | 1143 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
2997 | 1144 | VIR_WARN("Unable to save status on vm %s after suspend event", | ||
2998 | 1145 | vm->def->name); | ||
2999 | 1146 | } | ||
3000 | 1147 | |||
3001 | 1148 | if (priv->agent) | ||
3002 | 1149 | qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND); | ||
3003 | 1150 | } | ||
3004 | 1151 | |||
3005 | 1152 | virDomainObjUnlock(vm); | ||
3006 | 1153 | |||
3007 | 1154 | if (event || lifecycleEvent) { | ||
3008 | 1155 | qemuDriverLock(driver); | ||
3009 | 1156 | if (event) | ||
3010 | 1157 | qemuDomainEventQueue(driver, event); | ||
3011 | 1158 | if (lifecycleEvent) | ||
3012 | 1159 | qemuDomainEventQueue(driver, lifecycleEvent); | ||
3013 | 1160 | qemuDriverUnlock(driver); | ||
3014 | 1161 | } | ||
3015 | 1162 | |||
3016 | 1163 | return 0; | ||
3017 | 1164 | } | ||
3018 | 1165 | |||
3019 | 1166 | static int | ||
3020 | 1167 | qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
3021 | 1168 | virDomainObjPtr vm, | ||
3022 | 1169 | unsigned long long actual) | ||
3023 | 1170 | { | ||
3024 | 1171 | struct qemud_driver *driver = qemu_driver; | ||
3025 | 1172 | virDomainEventPtr event; | ||
3026 | 1173 | |||
3027 | 1174 | virDomainObjLock(vm); | ||
3028 | 1175 | event = virDomainEventBalloonChangeNewFromObj(vm, actual); | ||
3029 | 1176 | |||
3030 | 1177 | VIR_DEBUG("Updating balloon from %lld to %lld kb", | ||
3031 | 1178 | vm->def->mem.cur_balloon, actual); | ||
3032 | 1179 | vm->def->mem.cur_balloon = actual; | ||
3033 | 1180 | |||
3034 | 1181 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) | ||
3035 | 1182 | VIR_WARN("unable to save domain status with balloon change"); | ||
3036 | 1183 | |||
3037 | 1184 | virDomainObjUnlock(vm); | ||
3038 | 1185 | |||
3039 | 1186 | if (event) { | ||
3040 | 1187 | qemuDriverLock(driver); | ||
3041 | 1188 | qemuDomainEventQueue(driver, event); | ||
3042 | 1189 | qemuDriverUnlock(driver); | ||
3043 | 1190 | } | ||
3044 | 1191 | |||
3045 | 1192 | return 0; | ||
3046 | 1193 | } | ||
3047 | 1194 | |||
3048 | 1195 | static int | ||
3049 | 1196 | qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, | ||
3050 | 1197 | virDomainObjPtr vm) | ||
3051 | 1198 | { | ||
3052 | 1199 | struct qemud_driver *driver = qemu_driver; | ||
3053 | 1200 | virDomainEventPtr event = NULL; | ||
3054 | 1201 | virDomainEventPtr lifecycleEvent = NULL; | ||
3055 | 1202 | |||
3056 | 1203 | virDomainObjLock(vm); | ||
3057 | 1204 | event = virDomainEventPMSuspendDiskNewFromObj(vm); | ||
3058 | 1205 | |||
3059 | 1206 | if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { | ||
3060 | 1207 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
3061 | 1208 | VIR_DEBUG("Transitioned guest %s to pmsuspended state due to " | ||
3062 | 1209 | "QMP suspend_disk event", vm->def->name); | ||
3063 | 1210 | |||
3064 | 1211 | virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED, | ||
3065 | 1212 | VIR_DOMAIN_PMSUSPENDED_UNKNOWN); | ||
3066 | 1213 | lifecycleEvent = | ||
3067 | 1214 | virDomainEventNewFromObj(vm, | ||
3068 | 1215 | VIR_DOMAIN_EVENT_PMSUSPENDED, | ||
3069 | 1216 | VIR_DOMAIN_EVENT_PMSUSPENDED_DISK); | ||
3070 | 1217 | |||
3071 | 1218 | if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { | ||
3072 | 1219 | VIR_WARN("Unable to save status on vm %s after suspend event", | ||
3073 | 1220 | vm->def->name); | ||
3074 | 1221 | } | ||
3075 | 1222 | |||
3076 | 1223 | if (priv->agent) | ||
3077 | 1224 | qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND); | ||
3078 | 1225 | } | ||
3079 | 1226 | |||
3080 | 1227 | virDomainObjUnlock(vm); | ||
3081 | 1228 | |||
3082 | 1229 | if (event || lifecycleEvent) { | ||
3083 | 1230 | qemuDriverLock(driver); | ||
3084 | 1231 | if (event) | ||
3085 | 1232 | qemuDomainEventQueue(driver, event); | ||
3086 | 1233 | if (lifecycleEvent) | ||
3087 | 1234 | qemuDomainEventQueue(driver, lifecycleEvent); | ||
3088 | 1235 | qemuDriverUnlock(driver); | ||
3089 | 1236 | } | ||
3090 | 1237 | |||
3091 | 1238 | return 0; | ||
3092 | 1239 | } | ||
3093 | 1240 | |||
3094 | 1241 | |||
3095 | 1242 | static qemuMonitorCallbacks monitorCallbacks = { | ||
3096 | 1243 | .destroy = qemuProcessHandleMonitorDestroy, | ||
3097 | 1244 | .eofNotify = qemuProcessHandleMonitorEOF, | ||
3098 | 1245 | .errorNotify = qemuProcessHandleMonitorError, | ||
3099 | 1246 | .diskSecretLookup = qemuProcessFindVolumeQcowPassphrase, | ||
3100 | 1247 | .domainShutdown = qemuProcessHandleShutdown, | ||
3101 | 1248 | .domainStop = qemuProcessHandleStop, | ||
3102 | 1249 | .domainReset = qemuProcessHandleReset, | ||
3103 | 1250 | .domainRTCChange = qemuProcessHandleRTCChange, | ||
3104 | 1251 | .domainWatchdog = qemuProcessHandleWatchdog, | ||
3105 | 1252 | .domainIOError = qemuProcessHandleIOError, | ||
3106 | 1253 | .domainGraphics = qemuProcessHandleGraphics, | ||
3107 | 1254 | .domainBlockJob = qemuProcessHandleBlockJob, | ||
3108 | 1255 | .domainTrayChange = qemuProcessHandleTrayChange, | ||
3109 | 1256 | .domainPMWakeup = qemuProcessHandlePMWakeup, | ||
3110 | 1257 | .domainPMSuspend = qemuProcessHandlePMSuspend, | ||
3111 | 1258 | .domainBalloonChange = qemuProcessHandleBalloonChange, | ||
3112 | 1259 | .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk, | ||
3113 | 1260 | }; | ||
3114 | 1261 | |||
3115 | 1262 | static int | ||
3116 | 1263 | qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm) | ||
3117 | 1264 | { | ||
3118 | 1265 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
3119 | 1266 | int ret = -1; | ||
3120 | 1267 | qemuMonitorPtr mon = NULL; | ||
3121 | 1268 | |||
3122 | 1269 | if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager, | ||
3123 | 1270 | vm->def) < 0) { | ||
3124 | 1271 | VIR_ERROR(_("Failed to set security context for monitor for %s"), | ||
3125 | 1272 | vm->def->name); | ||
3126 | 1273 | goto error; | ||
3127 | 1274 | } | ||
3128 | 1275 | |||
3129 | 1276 | /* Hold an extra reference because we can't allow 'vm' to be | ||
3130 | 1277 | * deleted while the monitor is active */ | ||
3131 | 1278 | virObjectRef(vm); | ||
3132 | 1279 | |||
3133 | 1280 | ignore_value(virTimeMillisNow(&priv->monStart)); | ||
3134 | 1281 | virDomainObjUnlock(vm); | ||
3135 | 1282 | qemuDriverUnlock(driver); | ||
3136 | 1283 | |||
3137 | 1284 | mon = qemuMonitorOpen(vm, | ||
3138 | 1285 | priv->monConfig, | ||
3139 | 1286 | priv->monJSON, | ||
3140 | 1287 | &monitorCallbacks); | ||
3141 | 1288 | |||
3142 | 1289 | qemuDriverLock(driver); | ||
3143 | 1290 | virDomainObjLock(vm); | ||
3144 | 1291 | priv->monStart = 0; | ||
3145 | 1292 | |||
3146 | 1293 | if (mon == NULL) { | ||
3147 | 1294 | virObjectUnref(vm); | ||
3148 | 1295 | } else if (!virDomainObjIsActive(vm)) { | ||
3149 | 1296 | qemuMonitorClose(mon); | ||
3150 | 1297 | mon = NULL; | ||
3151 | 1298 | } | ||
3152 | 1299 | priv->mon = mon; | ||
3153 | 1300 | |||
3154 | 1301 | if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) { | ||
3155 | 1302 | VIR_ERROR(_("Failed to clear security context for monitor for %s"), | ||
3156 | 1303 | vm->def->name); | ||
3157 | 1304 | goto error; | ||
3158 | 1305 | } | ||
3159 | 1306 | |||
3160 | 1307 | if (priv->mon == NULL) { | ||
3161 | 1308 | VIR_INFO("Failed to connect monitor for %s", vm->def->name); | ||
3162 | 1309 | goto error; | ||
3163 | 1310 | } | ||
3164 | 1311 | |||
3165 | 1312 | |||
3166 | 1313 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
3167 | 1314 | ret = qemuMonitorSetCapabilities(priv->mon); | ||
3168 | 1315 | if (ret == 0 && | ||
3169 | 1316 | qemuCapsGet(priv->caps, QEMU_CAPS_MONITOR_JSON)) | ||
3170 | 1317 | ret = qemuCapsProbeQMP(priv->caps, priv->mon); | ||
3171 | 1318 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
3172 | 1319 | |||
3173 | 1320 | error: | ||
3174 | 1321 | |||
3175 | 1322 | return ret; | ||
3176 | 1323 | } | ||
3177 | 1324 | |||
3178 | 1325 | typedef int qemuProcessLogHandleOutput(virDomainObjPtr vm, | ||
3179 | 1326 | const char *output, | ||
3180 | 1327 | int fd); | ||
3181 | 1328 | |||
3182 | 1329 | /* | ||
3183 | 1330 | * Returns -1 for error, 0 on success | ||
3184 | 1331 | */ | ||
3185 | 1332 | static int | ||
3186 | 1333 | qemuProcessReadLogOutput(virDomainObjPtr vm, | ||
3187 | 1334 | int fd, | ||
3188 | 1335 | char *buf, | ||
3189 | 1336 | size_t buflen, | ||
3190 | 1337 | qemuProcessLogHandleOutput func, | ||
3191 | 1338 | const char *what, | ||
3192 | 1339 | int timeout) | ||
3193 | 1340 | { | ||
3194 | 1341 | int retries = (timeout*10); | ||
3195 | 1342 | int got = 0; | ||
3196 | 1343 | char *debug = NULL; | ||
3197 | 1344 | int ret = -1; | ||
3198 | 1345 | char *filter_next = buf; | ||
3199 | 1346 | |||
3200 | 1347 | buf[0] = '\0'; | ||
3201 | 1348 | |||
3202 | 1349 | /* This relies on log message format generated by virLogFormatString() and | ||
3203 | 1350 | * might need to be modified when message format changes. */ | ||
3204 | 1351 | if (virAsprintf(&debug, ": %d: debug : ", vm->pid) < 0) { | ||
3205 | 1352 | virReportOOMError(); | ||
3206 | 1353 | return -1; | ||
3207 | 1354 | } | ||
3208 | 1355 | |||
3209 | 1356 | while (retries) { | ||
3210 | 1357 | ssize_t func_ret, bytes; | ||
3211 | 1358 | int isdead = 0; | ||
3212 | 1359 | char *eol; | ||
3213 | 1360 | |||
3214 | 1361 | func_ret = func(vm, buf, fd); | ||
3215 | 1362 | |||
3216 | 1363 | if (kill(vm->pid, 0) == -1 && errno == ESRCH) | ||
3217 | 1364 | isdead = 1; | ||
3218 | 1365 | |||
3219 | 1366 | /* Any failures should be detected before we read the log, so we | ||
3220 | 1367 | * always have something useful to report on failure. */ | ||
3221 | 1368 | bytes = saferead(fd, buf+got, buflen-got-1); | ||
3222 | 1369 | if (bytes < 0) { | ||
3223 | 1370 | virReportSystemError(errno, | ||
3224 | 1371 | _("Failure while reading %s log output"), | ||
3225 | 1372 | what); | ||
3226 | 1373 | goto cleanup; | ||
3227 | 1374 | } | ||
3228 | 1375 | |||
3229 | 1376 | got += bytes; | ||
3230 | 1377 | buf[got] = '\0'; | ||
3231 | 1378 | |||
3232 | 1379 | /* Filter out debug messages from intermediate libvirt process */ | ||
3233 | 1380 | while ((eol = strchr(filter_next, '\n'))) { | ||
3234 | 1381 | *eol = '\0'; | ||
3235 | 1382 | if (strstr(filter_next, debug)) { | ||
3236 | 1383 | memmove(filter_next, eol + 1, got - (eol - buf)); | ||
3237 | 1384 | got -= eol + 1 - filter_next; | ||
3238 | 1385 | } else { | ||
3239 | 1386 | filter_next = eol + 1; | ||
3240 | 1387 | *eol = '\n'; | ||
3241 | 1388 | } | ||
3242 | 1389 | } | ||
3243 | 1390 | |||
3244 | 1391 | if (got == buflen-1) { | ||
3245 | 1392 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3246 | 1393 | _("Out of space while reading %s log output: %s"), | ||
3247 | 1394 | what, buf); | ||
3248 | 1395 | goto cleanup; | ||
3249 | 1396 | } | ||
3250 | 1397 | |||
3251 | 1398 | if (isdead) { | ||
3252 | 1399 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3253 | 1400 | _("Process exited while reading %s log output: %s"), | ||
3254 | 1401 | what, buf); | ||
3255 | 1402 | goto cleanup; | ||
3256 | 1403 | } | ||
3257 | 1404 | |||
3258 | 1405 | if (func_ret <= 0) { | ||
3259 | 1406 | ret = func_ret; | ||
3260 | 1407 | goto cleanup; | ||
3261 | 1408 | } | ||
3262 | 1409 | |||
3263 | 1410 | usleep(100*1000); | ||
3264 | 1411 | retries--; | ||
3265 | 1412 | } | ||
3266 | 1413 | |||
3267 | 1414 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3268 | 1415 | _("Timed out while reading %s log output: %s"), | ||
3269 | 1416 | what, buf); | ||
3270 | 1417 | |||
3271 | 1418 | cleanup: | ||
3272 | 1419 | VIR_FREE(debug); | ||
3273 | 1420 | return ret; | ||
3274 | 1421 | } | ||
3275 | 1422 | |||
3276 | 1423 | |||
3277 | 1424 | /* | ||
3278 | 1425 | * Look at a chunk of data from the QEMU stdout logs and try to | ||
3279 | 1426 | * find a TTY device, as indicated by a line like | ||
3280 | 1427 | * | ||
3281 | 1428 | * char device redirected to /dev/pts/3 | ||
3282 | 1429 | * | ||
3283 | 1430 | * Returns -1 for error, 0 success, 1 continue reading | ||
3284 | 1431 | */ | ||
3285 | 1432 | static int | ||
3286 | 1433 | qemuProcessExtractTTYPath(const char *haystack, | ||
3287 | 1434 | size_t *offset, | ||
3288 | 1435 | char **path) | ||
3289 | 1436 | { | ||
3290 | 1437 | static const char needle[] = "char device redirected to"; | ||
3291 | 1438 | char *tmp, *dev; | ||
3292 | 1439 | |||
3293 | 1440 | VIR_FREE(*path); | ||
3294 | 1441 | /* First look for our magic string */ | ||
3295 | 1442 | if (!(tmp = strstr(haystack + *offset, needle))) { | ||
3296 | 1443 | return 1; | ||
3297 | 1444 | } | ||
3298 | 1445 | tmp += sizeof(needle); | ||
3299 | 1446 | dev = tmp; | ||
3300 | 1447 | |||
3301 | 1448 | /* | ||
3302 | 1449 | * And look for first whitespace character and nul terminate | ||
3303 | 1450 | * to mark end of the pty path | ||
3304 | 1451 | */ | ||
3305 | 1452 | while (*tmp) { | ||
3306 | 1453 | if (c_isspace(*tmp)) { | ||
3307 | 1454 | *path = strndup(dev, tmp-dev); | ||
3308 | 1455 | if (*path == NULL) { | ||
3309 | 1456 | virReportOOMError(); | ||
3310 | 1457 | return -1; | ||
3311 | 1458 | } | ||
3312 | 1459 | |||
3313 | 1460 | /* ... now further update offset till we get EOL */ | ||
3314 | 1461 | *offset = tmp - haystack; | ||
3315 | 1462 | return 0; | ||
3316 | 1463 | } | ||
3317 | 1464 | tmp++; | ||
3318 | 1465 | } | ||
3319 | 1466 | |||
3320 | 1467 | /* | ||
3321 | 1468 | * We found a path, but didn't find any whitespace, | ||
3322 | 1469 | * so it must be still incomplete - we should at | ||
3323 | 1470 | * least see a \n - indicate that we want to carry | ||
3324 | 1471 | * on trying again | ||
3325 | 1472 | */ | ||
3326 | 1473 | return 1; | ||
3327 | 1474 | } | ||
3328 | 1475 | |||
3329 | 1476 | static int | ||
3330 | 1477 | qemuProcessLookupPTYs(virDomainChrDefPtr *devices, | ||
3331 | 1478 | int count, | ||
3332 | 1479 | virHashTablePtr paths, | ||
3333 | 1480 | bool chardevfmt) | ||
3334 | 1481 | { | ||
3335 | 1482 | int i; | ||
3336 | 1483 | const char *prefix = chardevfmt ? "char" : ""; | ||
3337 | 1484 | |||
3338 | 1485 | for (i = 0 ; i < count ; i++) { | ||
3339 | 1486 | virDomainChrDefPtr chr = devices[i]; | ||
3340 | 1487 | if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) { | ||
3341 | 1488 | char id[32]; | ||
3342 | 1489 | const char *path; | ||
3343 | 1490 | |||
3344 | 1491 | if (snprintf(id, sizeof(id), "%s%s", | ||
3345 | 1492 | prefix, chr->info.alias) >= sizeof(id)) | ||
3346 | 1493 | return -1; | ||
3347 | 1494 | |||
3348 | 1495 | path = (const char *) virHashLookup(paths, id); | ||
3349 | 1496 | if (path == NULL) { | ||
3350 | 1497 | if (chr->source.data.file.path == NULL) { | ||
3351 | 1498 | /* neither the log output nor 'info chardev' had a | ||
3352 | 1499 | * pty path for this chardev, report an error | ||
3353 | 1500 | */ | ||
3354 | 1501 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3355 | 1502 | _("no assigned pty for device %s"), id); | ||
3356 | 1503 | return -1; | ||
3357 | 1504 | } else { | ||
3358 | 1505 | /* 'info chardev' had no pty path for this chardev, | ||
3359 | 1506 | * but the log output had, so we're fine | ||
3360 | 1507 | */ | ||
3361 | 1508 | continue; | ||
3362 | 1509 | } | ||
3363 | 1510 | } | ||
3364 | 1511 | |||
3365 | 1512 | VIR_FREE(chr->source.data.file.path); | ||
3366 | 1513 | chr->source.data.file.path = strdup(path); | ||
3367 | 1514 | |||
3368 | 1515 | if (chr->source.data.file.path == NULL) { | ||
3369 | 1516 | virReportOOMError(); | ||
3370 | 1517 | return -1; | ||
3371 | 1518 | } | ||
3372 | 1519 | } | ||
3373 | 1520 | } | ||
3374 | 1521 | |||
3375 | 1522 | return 0; | ||
3376 | 1523 | } | ||
3377 | 1524 | |||
3378 | 1525 | static int | ||
3379 | 1526 | qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm, | ||
3380 | 1527 | qemuCapsPtr caps, | ||
3381 | 1528 | virHashTablePtr paths) | ||
3382 | 1529 | { | ||
3383 | 1530 | bool chardevfmt = qemuCapsGet(caps, QEMU_CAPS_CHARDEV); | ||
3384 | 1531 | |||
3385 | 1532 | if (qemuProcessLookupPTYs(vm->def->serials, vm->def->nserials, | ||
3386 | 1533 | paths, chardevfmt) < 0) | ||
3387 | 1534 | return -1; | ||
3388 | 1535 | |||
3389 | 1536 | if (qemuProcessLookupPTYs(vm->def->parallels, vm->def->nparallels, | ||
3390 | 1537 | paths, chardevfmt) < 0) | ||
3391 | 1538 | return -1; | ||
3392 | 1539 | |||
3393 | 1540 | if (qemuProcessLookupPTYs(vm->def->channels, vm->def->nchannels, | ||
3394 | 1541 | paths, chardevfmt) < 0) | ||
3395 | 1542 | return -1; | ||
3396 | 1543 | |||
3397 | 1544 | if (qemuProcessLookupPTYs(vm->def->consoles, vm->def->nconsoles, | ||
3398 | 1545 | paths, chardevfmt) < 0) | ||
3399 | 1546 | return -1; | ||
3400 | 1547 | |||
3401 | 1548 | return 0; | ||
3402 | 1549 | } | ||
3403 | 1550 | |||
3404 | 1551 | static int | ||
3405 | 1552 | qemuProcessFindCharDevicePTYs(virDomainObjPtr vm, | ||
3406 | 1553 | const char *output, | ||
3407 | 1554 | int fd ATTRIBUTE_UNUSED) | ||
3408 | 1555 | { | ||
3409 | 1556 | size_t offset = 0; | ||
3410 | 1557 | int ret, i; | ||
3411 | 1558 | |||
3412 | 1559 | /* The order in which QEMU prints out the PTY paths is | ||
3413 | 1560 | the order in which it procsses its serial and parallel | ||
3414 | 1561 | device args. This code must match that ordering.... */ | ||
3415 | 1562 | |||
3416 | 1563 | /* first comes the serial devices */ | ||
3417 | 1564 | for (i = 0 ; i < vm->def->nserials ; i++) { | ||
3418 | 1565 | virDomainChrDefPtr chr = vm->def->serials[i]; | ||
3419 | 1566 | if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) { | ||
3420 | 1567 | if ((ret = qemuProcessExtractTTYPath(output, &offset, | ||
3421 | 1568 | &chr->source.data.file.path)) != 0) | ||
3422 | 1569 | return ret; | ||
3423 | 1570 | } | ||
3424 | 1571 | } | ||
3425 | 1572 | |||
3426 | 1573 | /* then the parallel devices */ | ||
3427 | 1574 | for (i = 0 ; i < vm->def->nparallels ; i++) { | ||
3428 | 1575 | virDomainChrDefPtr chr = vm->def->parallels[i]; | ||
3429 | 1576 | if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) { | ||
3430 | 1577 | if ((ret = qemuProcessExtractTTYPath(output, &offset, | ||
3431 | 1578 | &chr->source.data.file.path)) != 0) | ||
3432 | 1579 | return ret; | ||
3433 | 1580 | } | ||
3434 | 1581 | } | ||
3435 | 1582 | |||
3436 | 1583 | /* then the channel devices */ | ||
3437 | 1584 | for (i = 0 ; i < vm->def->nchannels ; i++) { | ||
3438 | 1585 | virDomainChrDefPtr chr = vm->def->channels[i]; | ||
3439 | 1586 | if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) { | ||
3440 | 1587 | if ((ret = qemuProcessExtractTTYPath(output, &offset, | ||
3441 | 1588 | &chr->source.data.file.path)) != 0) | ||
3442 | 1589 | return ret; | ||
3443 | 1590 | } | ||
3444 | 1591 | } | ||
3445 | 1592 | |||
3446 | 1593 | for (i = 0 ; i < vm->def->nconsoles ; i++) { | ||
3447 | 1594 | virDomainChrDefPtr chr = vm->def->consoles[i]; | ||
3448 | 1595 | /* For historical reasons, console[0] can be just an alias | ||
3449 | 1596 | * for serial[0]; That's why we need to update it as well */ | ||
3450 | 1597 | if (i == 0 && vm->def->nserials && | ||
3451 | 1598 | chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && | ||
3452 | 1599 | chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) { | ||
3453 | 1600 | if ((ret = virDomainChrSourceDefCopy(&chr->source, | ||
3454 | 1601 | &((vm->def->serials[0])->source))) != 0) | ||
3455 | 1602 | return ret; | ||
3456 | 1603 | } else { | ||
3457 | 1604 | if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY && | ||
3458 | 1605 | chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) { | ||
3459 | 1606 | if ((ret = qemuProcessExtractTTYPath(output, &offset, | ||
3460 | 1607 | &chr->source.data.file.path)) != 0) | ||
3461 | 1608 | return ret; | ||
3462 | 1609 | } | ||
3463 | 1610 | } | ||
3464 | 1611 | } | ||
3465 | 1612 | |||
3466 | 1613 | return 0; | ||
3467 | 1614 | } | ||
3468 | 1615 | |||
3469 | 1616 | static void qemuProcessFreePtyPath(void *payload, const void *name ATTRIBUTE_UNUSED) | ||
3470 | 1617 | { | ||
3471 | 1618 | VIR_FREE(payload); | ||
3472 | 1619 | } | ||
3473 | 1620 | |||
3474 | 1621 | static void | ||
3475 | 1622 | qemuProcessReadLogFD(int logfd, char *buf, int maxlen, int off) | ||
3476 | 1623 | { | ||
3477 | 1624 | int ret; | ||
3478 | 1625 | char *tmpbuf = buf + off; | ||
3479 | 1626 | |||
3480 | 1627 | ret = saferead(logfd, tmpbuf, maxlen - off - 1); | ||
3481 | 1628 | if (ret < 0) { | ||
3482 | 1629 | ret = 0; | ||
3483 | 1630 | } | ||
3484 | 1631 | |||
3485 | 1632 | tmpbuf[ret] = '\0'; | ||
3486 | 1633 | } | ||
3487 | 1634 | |||
3488 | 1635 | |||
3489 | 1636 | static int | ||
3490 | 1637 | qemuProcessWaitForMonitor(struct qemud_driver* driver, | ||
3491 | 1638 | virDomainObjPtr vm, | ||
3492 | 1639 | qemuCapsPtr caps, | ||
3493 | 1640 | off_t pos) | ||
3494 | 1641 | { | ||
3495 | 1642 | char *buf = NULL; | ||
3496 | 1643 | size_t buf_size = 4096; /* Plenty of space to get startup greeting */ | ||
3497 | 1644 | int logfd = -1; | ||
3498 | 1645 | int ret = -1; | ||
3499 | 1646 | virHashTablePtr paths = NULL; | ||
3500 | 1647 | qemuDomainObjPrivatePtr priv; | ||
3501 | 1648 | |||
3502 | 1649 | if (pos != -1) { | ||
3503 | 1650 | if ((logfd = qemuDomainOpenLog(driver, vm, pos)) < 0) | ||
3504 | 1651 | return -1; | ||
3505 | 1652 | |||
3506 | 1653 | if (VIR_ALLOC_N(buf, buf_size) < 0) { | ||
3507 | 1654 | virReportOOMError(); | ||
3508 | 1655 | goto closelog; | ||
3509 | 1656 | } | ||
3510 | 1657 | |||
3511 | 1658 | if (qemuProcessReadLogOutput(vm, logfd, buf, buf_size, | ||
3512 | 1659 | qemuProcessFindCharDevicePTYs, | ||
3513 | 1660 | "console", 30) < 0) | ||
3514 | 1661 | goto closelog; | ||
3515 | 1662 | } | ||
3516 | 1663 | |||
3517 | 1664 | VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name); | ||
3518 | 1665 | if (qemuConnectMonitor(driver, vm) < 0) { | ||
3519 | 1666 | goto cleanup; | ||
3520 | 1667 | } | ||
3521 | 1668 | |||
3522 | 1669 | /* Try to get the pty path mappings again via the monitor. This is much more | ||
3523 | 1670 | * reliable if it's available. | ||
3524 | 1671 | * Note that the monitor itself can be on a pty, so we still need to try the | ||
3525 | 1672 | * log output method. */ | ||
3526 | 1673 | paths = virHashCreate(0, qemuProcessFreePtyPath); | ||
3527 | 1674 | if (paths == NULL) | ||
3528 | 1675 | goto cleanup; | ||
3529 | 1676 | |||
3530 | 1677 | priv = vm->privateData; | ||
3531 | 1678 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
3532 | 1679 | ret = qemuMonitorGetPtyPaths(priv->mon, paths); | ||
3533 | 1680 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
3534 | 1681 | |||
3535 | 1682 | VIR_DEBUG("qemuMonitorGetPtyPaths returned %i", ret); | ||
3536 | 1683 | if (ret == 0) | ||
3537 | 1684 | ret = qemuProcessFindCharDevicePTYsMonitor(vm, caps, paths); | ||
3538 | 1685 | |||
3539 | 1686 | cleanup: | ||
3540 | 1687 | virHashFree(paths); | ||
3541 | 1688 | |||
3542 | 1689 | if (pos != -1 && kill(vm->pid, 0) == -1 && errno == ESRCH) { | ||
3543 | 1690 | /* VM is dead, any other error raised in the interim is probably | ||
3544 | 1691 | * not as important as the qemu cmdline output */ | ||
3545 | 1692 | qemuProcessReadLogFD(logfd, buf, buf_size, strlen(buf)); | ||
3546 | 1693 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3547 | 1694 | _("process exited while connecting to monitor: %s"), | ||
3548 | 1695 | buf); | ||
3549 | 1696 | ret = -1; | ||
3550 | 1697 | } | ||
3551 | 1698 | |||
3552 | 1699 | closelog: | ||
3553 | 1700 | if (VIR_CLOSE(logfd) < 0) { | ||
3554 | 1701 | char ebuf[1024]; | ||
3555 | 1702 | VIR_WARN("Unable to close logfile: %s", | ||
3556 | 1703 | virStrerror(errno, ebuf, sizeof(ebuf))); | ||
3557 | 1704 | } | ||
3558 | 1705 | |||
3559 | 1706 | VIR_FREE(buf); | ||
3560 | 1707 | |||
3561 | 1708 | return ret; | ||
3562 | 1709 | } | ||
3563 | 1710 | |||
3564 | 1711 | static int | ||
3565 | 1712 | qemuProcessDetectVcpuPIDs(struct qemud_driver *driver, | ||
3566 | 1713 | virDomainObjPtr vm) | ||
3567 | 1714 | { | ||
3568 | 1715 | pid_t *cpupids = NULL; | ||
3569 | 1716 | int ncpupids; | ||
3570 | 1717 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
3571 | 1718 | |||
3572 | 1719 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
3573 | 1720 | /* failure to get the VCPU<-> PID mapping or to execute the query | ||
3574 | 1721 | * command will not be treated fatal as some versions of qemu don't | ||
3575 | 1722 | * support this command */ | ||
3576 | 1723 | if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) <= 0) { | ||
3577 | 1724 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
3578 | 1725 | virResetLastError(); | ||
3579 | 1726 | |||
3580 | 1727 | priv->nvcpupids = 1; | ||
3581 | 1728 | if (VIR_ALLOC_N(priv->vcpupids, priv->nvcpupids) < 0) { | ||
3582 | 1729 | virReportOOMError(); | ||
3583 | 1730 | return -1; | ||
3584 | 1731 | } | ||
3585 | 1732 | priv->vcpupids[0] = vm->pid; | ||
3586 | 1733 | return 0; | ||
3587 | 1734 | } | ||
3588 | 1735 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
3589 | 1736 | |||
3590 | 1737 | if (ncpupids != vm->def->vcpus) { | ||
3591 | 1738 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3592 | 1739 | _("got wrong number of vCPU pids from QEMU monitor. " | ||
3593 | 1740 | "got %d, wanted %d"), | ||
3594 | 1741 | ncpupids, vm->def->vcpus); | ||
3595 | 1742 | VIR_FREE(cpupids); | ||
3596 | 1743 | return -1; | ||
3597 | 1744 | } | ||
3598 | 1745 | |||
3599 | 1746 | priv->nvcpupids = ncpupids; | ||
3600 | 1747 | priv->vcpupids = cpupids; | ||
3601 | 1748 | return 0; | ||
3602 | 1749 | } | ||
3603 | 1750 | |||
3604 | 1751 | |||
3605 | 1752 | /* | ||
3606 | 1753 | * Set NUMA memory policy for qemu process, to be run between | ||
3607 | 1754 | * fork/exec of QEMU only. | ||
3608 | 1755 | */ | ||
3609 | 1756 | #if HAVE_NUMACTL | ||
3610 | 1757 | static int | ||
3611 | 1758 | qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm, | ||
3612 | 1759 | virBitmapPtr nodemask) | ||
3613 | 1760 | { | ||
3614 | 1761 | nodemask_t mask; | ||
3615 | 1762 | int mode = -1; | ||
3616 | 1763 | int node = -1; | ||
3617 | 1764 | int ret = -1; | ||
3618 | 1765 | int i = 0; | ||
3619 | 1766 | int maxnode = 0; | ||
3620 | 1767 | bool warned = false; | ||
3621 | 1768 | virDomainNumatuneDef numatune = vm->def->numatune; | ||
3622 | 1769 | virBitmapPtr tmp_nodemask = NULL; | ||
3623 | 1770 | |||
3624 | 1771 | if (numatune.memory.placement_mode == | ||
3625 | 1772 | VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) { | ||
3626 | 1773 | if (!numatune.memory.nodemask) | ||
3627 | 1774 | return 0; | ||
3628 | 1775 | VIR_DEBUG("Set NUMA memory policy with specified nodeset"); | ||
3629 | 1776 | tmp_nodemask = numatune.memory.nodemask; | ||
3630 | 1777 | } else if (numatune.memory.placement_mode == | ||
3631 | 1778 | VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) { | ||
3632 | 1779 | VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad"); | ||
3633 | 1780 | tmp_nodemask = nodemask; | ||
3634 | 1781 | } else { | ||
3635 | 1782 | return 0; | ||
3636 | 1783 | } | ||
3637 | 1784 | |||
3638 | 1785 | if (numa_available() < 0) { | ||
3639 | 1786 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3640 | 1787 | "%s", _("Host kernel is not aware of NUMA.")); | ||
3641 | 1788 | return -1; | ||
3642 | 1789 | } | ||
3643 | 1790 | |||
3644 | 1791 | maxnode = numa_max_node() + 1; | ||
3645 | 1792 | /* Convert nodemask to NUMA bitmask. */ | ||
3646 | 1793 | nodemask_zero(&mask); | ||
3647 | 1794 | i = -1; | ||
3648 | 1795 | while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) { | ||
3649 | 1796 | if (i > NUMA_NUM_NODES) { | ||
3650 | 1797 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3651 | 1798 | _("Host cannot support NUMA node %d"), i); | ||
3652 | 1799 | return -1; | ||
3653 | 1800 | } | ||
3654 | 1801 | if (i > maxnode && !warned) { | ||
3655 | 1802 | VIR_WARN("nodeset is out of range, there is only %d NUMA " | ||
3656 | 1803 | "nodes on host", maxnode); | ||
3657 | 1804 | warned = true; | ||
3658 | 1805 | } | ||
3659 | 1806 | nodemask_set(&mask, i); | ||
3660 | 1807 | } | ||
3661 | 1808 | |||
3662 | 1809 | mode = numatune.memory.mode; | ||
3663 | 1810 | |||
3664 | 1811 | if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) { | ||
3665 | 1812 | numa_set_bind_policy(1); | ||
3666 | 1813 | numa_set_membind(&mask); | ||
3667 | 1814 | numa_set_bind_policy(0); | ||
3668 | 1815 | } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) { | ||
3669 | 1816 | int nnodes = 0; | ||
3670 | 1817 | for (i = 0; i < NUMA_NUM_NODES; i++) { | ||
3671 | 1818 | if (nodemask_isset(&mask, i)) { | ||
3672 | 1819 | node = i; | ||
3673 | 1820 | nnodes++; | ||
3674 | 1821 | } | ||
3675 | 1822 | } | ||
3676 | 1823 | |||
3677 | 1824 | if (nnodes != 1) { | ||
3678 | 1825 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
3679 | 1826 | "%s", _("NUMA memory tuning in 'preferred' mode " | ||
3680 | 1827 | "only supports single node")); | ||
3681 | 1828 | goto cleanup; | ||
3682 | 1829 | } | ||
3683 | 1830 | |||
3684 | 1831 | numa_set_bind_policy(0); | ||
3685 | 1832 | numa_set_preferred(node); | ||
3686 | 1833 | } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) { | ||
3687 | 1834 | numa_set_interleave_mask(&mask); | ||
3688 | 1835 | } else { | ||
3689 | 1836 | /* XXX: Shouldn't go here, as we already do checking when | ||
3690 | 1837 | * parsing domain XML. | ||
3691 | 1838 | */ | ||
3692 | 1839 | virReportError(VIR_ERR_XML_ERROR, | ||
3693 | 1840 | "%s", _("Invalid mode for memory NUMA tuning.")); | ||
3694 | 1841 | goto cleanup; | ||
3695 | 1842 | } | ||
3696 | 1843 | |||
3697 | 1844 | ret = 0; | ||
3698 | 1845 | |||
3699 | 1846 | cleanup: | ||
3700 | 1847 | return ret; | ||
3701 | 1848 | } | ||
3702 | 1849 | #else | ||
3703 | 1850 | static int | ||
3704 | 1851 | qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm, | ||
3705 | 1852 | virBitmapPtr nodemask ATTRIBUTE_UNUSED) | ||
3706 | 1853 | { | ||
3707 | 1854 | if (vm->def->numatune.memory.nodemask) { | ||
3708 | 1855 | virReportError(VIR_ERR_INTERNAL_ERROR, "%s", | ||
3709 | 1856 | _("libvirt is compiled without NUMA tuning support")); | ||
3710 | 1857 | |||
3711 | 1858 | return -1; | ||
3712 | 1859 | } | ||
3713 | 1860 | |||
3714 | 1861 | return 0; | ||
3715 | 1862 | } | ||
3716 | 1863 | #endif | ||
3717 | 1864 | |||
3718 | 1865 | #if HAVE_NUMAD | ||
3719 | 1866 | static char * | ||
3720 | 1867 | qemuGetNumadAdvice(virDomainDefPtr def) | ||
3721 | 1868 | { | ||
3722 | 1869 | virCommandPtr cmd = NULL; | ||
3723 | 1870 | char *output = NULL; | ||
3724 | 1871 | |||
3725 | 1872 | cmd = virCommandNewArgList(NUMAD, "-w", NULL); | ||
3726 | 1873 | virCommandAddArgFormat(cmd, "%d:%llu", def->vcpus, | ||
3727 | 1874 | VIR_DIV_UP(def->mem.cur_balloon, 1024)); | ||
3728 | 1875 | |||
3729 | 1876 | virCommandSetOutputBuffer(cmd, &output); | ||
3730 | 1877 | |||
3731 | 1878 | if (virCommandRun(cmd, NULL) < 0) | ||
3732 | 1879 | virReportError(VIR_ERR_INTERNAL_ERROR, "%s", | ||
3733 | 1880 | _("Failed to query numad for the " | ||
3734 | 1881 | "advisory nodeset")); | ||
3735 | 1882 | |||
3736 | 1883 | virCommandFree(cmd); | ||
3737 | 1884 | return output; | ||
3738 | 1885 | } | ||
3739 | 1886 | #else | ||
3740 | 1887 | static char * | ||
3741 | 1888 | qemuGetNumadAdvice(virDomainDefPtr def ATTRIBUTE_UNUSED) | ||
3742 | 1889 | { | ||
3743 | 1890 | virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", | ||
3744 | 1891 | _("numad is not available on this host")); | ||
3745 | 1892 | return NULL; | ||
3746 | 1893 | } | ||
3747 | 1894 | #endif | ||
3748 | 1895 | |||
3749 | 1896 | /* Helper to prepare cpumap for affinity setting, convert | ||
3750 | 1897 | * NUMA nodeset into cpuset if @nodemask is not NULL, otherwise | ||
3751 | 1898 | * just return a new allocated bitmap. | ||
3752 | 1899 | */ | ||
3753 | 1900 | virBitmapPtr | ||
3754 | 1901 | qemuPrepareCpumap(struct qemud_driver *driver, | ||
3755 | 1902 | virBitmapPtr nodemask) | ||
3756 | 1903 | { | ||
3757 | 1904 | int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN; | ||
3758 | 1905 | virNodeInfo nodeinfo; | ||
3759 | 1906 | virBitmapPtr cpumap = NULL; | ||
3760 | 1907 | |||
3761 | 1908 | if (nodeGetInfo(NULL, &nodeinfo) < 0) | ||
3762 | 1909 | return NULL; | ||
3763 | 1910 | |||
3764 | 1911 | /* setaffinity fails if you set bits for CPUs which | ||
3765 | 1912 | * aren't present, so we have to limit ourselves */ | ||
3766 | 1913 | hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); | ||
3767 | 1914 | if (maxcpu > hostcpus) | ||
3768 | 1915 | maxcpu = hostcpus; | ||
3769 | 1916 | |||
3770 | 1917 | if (!(cpumap = virBitmapNew(maxcpu))) { | ||
3771 | 1918 | virReportOOMError(); | ||
3772 | 1919 | return NULL; | ||
3773 | 1920 | } | ||
3774 | 1921 | |||
3775 | 1922 | if (nodemask) { | ||
3776 | 1923 | for (i = 0; i < driver->caps->host.nnumaCell; i++) { | ||
3777 | 1924 | int j; | ||
3778 | 1925 | int cur_ncpus = driver->caps->host.numaCell[i]->ncpus; | ||
3779 | 1926 | bool result; | ||
3780 | 1927 | if (virBitmapGetBit(nodemask, i, &result) < 0) { | ||
3781 | 1928 | virReportError(VIR_ERR_INTERNAL_ERROR, "%s", | ||
3782 | 1929 | _("Failed to convert nodeset to cpuset")); | ||
3783 | 1930 | virBitmapFree(cpumap); | ||
3784 | 1931 | return NULL; | ||
3785 | 1932 | } | ||
3786 | 1933 | if (result) { | ||
3787 | 1934 | for (j = 0; j < cur_ncpus; j++) | ||
3788 | 1935 | ignore_value(virBitmapSetBit(cpumap, | ||
3789 | 1936 | driver->caps->host.numaCell[i]->cpus[j])); | ||
3790 | 1937 | } | ||
3791 | 1938 | } | ||
3792 | 1939 | } | ||
3793 | 1940 | |||
3794 | 1941 | return cpumap; | ||
3795 | 1942 | } | ||
3796 | 1943 | |||
3797 | 1944 | /* | ||
3798 | 1945 | * To be run between fork/exec of QEMU only | ||
3799 | 1946 | */ | ||
3800 | 1947 | static int | ||
3801 | 1948 | qemuProcessInitCpuAffinity(struct qemud_driver *driver, | ||
3802 | 1949 | virDomainObjPtr vm, | ||
3803 | 1950 | virBitmapPtr nodemask) | ||
3804 | 1951 | { | ||
3805 | 1952 | int ret = -1; | ||
3806 | 1953 | virBitmapPtr cpumap = NULL; | ||
3807 | 1954 | virBitmapPtr cpumapToSet = NULL; | ||
3808 | 1955 | |||
3809 | 1956 | if (!(cpumap = qemuPrepareCpumap(driver, nodemask))) | ||
3810 | 1957 | return -1; | ||
3811 | 1958 | |||
3812 | 1959 | if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { | ||
3813 | 1960 | VIR_DEBUG("Set CPU affinity with advisory nodeset from numad"); | ||
3814 | 1961 | cpumapToSet = cpumap; | ||
3815 | 1962 | } else { | ||
3816 | 1963 | VIR_DEBUG("Set CPU affinity with specified cpuset"); | ||
3817 | 1964 | if (vm->def->cpumask) { | ||
3818 | 1965 | cpumapToSet = vm->def->cpumask; | ||
3819 | 1966 | } else { | ||
3820 | 1967 | cpumapToSet = cpumap; | ||
3821 | 1968 | /* You may think this is redundant, but we can't assume libvirtd | ||
3822 | 1969 | * itself is running on all pCPUs, so we need to explicitly set | ||
3823 | 1970 | * the spawned QEMU instance to all pCPUs if no map is given in | ||
3824 | 1971 | * its config file */ | ||
3825 | 1972 | virBitmapSetAll(cpumap); | ||
3826 | 1973 | } | ||
3827 | 1974 | } | ||
3828 | 1975 | |||
3829 | 1976 | /* We are pressuming we are running between fork/exec of QEMU | ||
3830 | 1977 | * so use '0' to indicate our own process ID. No threads are | ||
3831 | 1978 | * running at this point | ||
3832 | 1979 | */ | ||
3833 | 1980 | if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0) | ||
3834 | 1981 | goto cleanup; | ||
3835 | 1982 | |||
3836 | 1983 | ret = 0; | ||
3837 | 1984 | |||
3838 | 1985 | cleanup: | ||
3839 | 1986 | virBitmapFree(cpumap); | ||
3840 | 1987 | return ret; | ||
3841 | 1988 | } | ||
3842 | 1989 | |||
3843 | 1990 | /* set link states to down on interfaces at qemu start */ | ||
3844 | 1991 | static int | ||
3845 | 1992 | qemuProcessSetLinkStates(virDomainObjPtr vm) | ||
3846 | 1993 | { | ||
3847 | 1994 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
3848 | 1995 | virDomainDefPtr def = vm->def; | ||
3849 | 1996 | int i; | ||
3850 | 1997 | int ret = 0; | ||
3851 | 1998 | |||
3852 | 1999 | for (i = 0; i < def->nnets; i++) { | ||
3853 | 2000 | if (def->nets[i]->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) { | ||
3854 | 2001 | VIR_DEBUG("Setting link state: %s", def->nets[i]->info.alias); | ||
3855 | 2002 | |||
3856 | 2003 | if (!qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV)) { | ||
3857 | 2004 | virReportError(VIR_ERR_NO_SUPPORT, "%s", | ||
3858 | 2005 | _("Setting of link state is not supported by this qemu")); | ||
3859 | 2006 | return -1; | ||
3860 | 2007 | } | ||
3861 | 2008 | |||
3862 | 2009 | ret = qemuMonitorSetLink(priv->mon, | ||
3863 | 2010 | def->nets[i]->info.alias, | ||
3864 | 2011 | VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN); | ||
3865 | 2012 | if (ret != 0) { | ||
3866 | 2013 | virReportError(VIR_ERR_OPERATION_FAILED, | ||
3867 | 2014 | _("Couldn't set link state on interface: %s"), def->nets[i]->info.alias); | ||
3868 | 2015 | break; | ||
3869 | 2016 | } | ||
3870 | 2017 | } | ||
3871 | 2018 | } | ||
3872 | 2019 | |||
3873 | 2020 | return ret; | ||
3874 | 2021 | } | ||
3875 | 2022 | |||
3876 | 2023 | /* Set CPU affinities for vcpus if vcpupin xml provided. */ | ||
3877 | 2024 | static int | ||
3878 | 2025 | qemuProcessSetVcpuAffinites(virConnectPtr conn ATTRIBUTE_UNUSED, | ||
3879 | 2026 | virDomainObjPtr vm) | ||
3880 | 2027 | { | ||
3881 | 2028 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
3882 | 2029 | virDomainDefPtr def = vm->def; | ||
3883 | 2030 | int vcpu, n; | ||
3884 | 2031 | int ret = -1; | ||
3885 | 2032 | |||
3886 | 2033 | if (!def->cputune.nvcpupin) | ||
3887 | 2034 | return 0; | ||
3888 | 2035 | |||
3889 | 2036 | if (priv->vcpupids == NULL) { | ||
3890 | 2037 | virReportError(VIR_ERR_OPERATION_INVALID, | ||
3891 | 2038 | "%s", _("cpu affinity is not supported")); | ||
3892 | 2039 | return -1; | ||
3893 | 2040 | } | ||
3894 | 2041 | |||
3895 | 2042 | for (n = 0; n < def->cputune.nvcpupin; n++) { | ||
3896 | 2043 | vcpu = def->cputune.vcpupin[n]->vcpuid; | ||
3897 | 2044 | |||
3898 | 2045 | if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], | ||
3899 | 2046 | def->cputune.vcpupin[n]->cpumask) < 0) { | ||
3900 | 2047 | goto cleanup; | ||
3901 | 2048 | } | ||
3902 | 2049 | } | ||
3903 | 2050 | |||
3904 | 2051 | ret = 0; | ||
3905 | 2052 | cleanup: | ||
3906 | 2053 | return ret; | ||
3907 | 2054 | } | ||
3908 | 2055 | |||
3909 | 2056 | /* Set CPU affinities for emulator threads. */ | ||
3910 | 2057 | static int | ||
3911 | 2058 | qemuProcessSetEmulatorAffinites(virConnectPtr conn ATTRIBUTE_UNUSED, | ||
3912 | 2059 | virDomainObjPtr vm) | ||
3913 | 2060 | { | ||
3914 | 2061 | virBitmapPtr cpumask; | ||
3915 | 2062 | virDomainDefPtr def = vm->def; | ||
3916 | 2063 | int ret = -1; | ||
3917 | 2064 | |||
3918 | 2065 | if (def->cputune.emulatorpin) | ||
3919 | 2066 | cpumask = def->cputune.emulatorpin->cpumask; | ||
3920 | 2067 | else if (def->cpumask) | ||
3921 | 2068 | cpumask = def->cpumask; | ||
3922 | 2069 | else | ||
3923 | 2070 | return 0; | ||
3924 | 2071 | |||
3925 | 2072 | ret = virProcessInfoSetAffinity(vm->pid, cpumask); | ||
3926 | 2073 | return ret; | ||
3927 | 2074 | } | ||
3928 | 2075 | |||
3929 | 2076 | static int | ||
3930 | 2077 | qemuProcessInitPasswords(virConnectPtr conn, | ||
3931 | 2078 | struct qemud_driver *driver, | ||
3932 | 2079 | virDomainObjPtr vm) | ||
3933 | 2080 | { | ||
3934 | 2081 | int ret = 0; | ||
3935 | 2082 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
3936 | 2083 | |||
3937 | 2084 | if (vm->def->ngraphics == 1) { | ||
3938 | 2085 | if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) { | ||
3939 | 2086 | ret = qemuDomainChangeGraphicsPasswords(driver, vm, | ||
3940 | 2087 | VIR_DOMAIN_GRAPHICS_TYPE_VNC, | ||
3941 | 2088 | &vm->def->graphics[0]->data.vnc.auth, | ||
3942 | 2089 | driver->vncPassword); | ||
3943 | 2090 | } else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { | ||
3944 | 2091 | ret = qemuDomainChangeGraphicsPasswords(driver, vm, | ||
3945 | 2092 | VIR_DOMAIN_GRAPHICS_TYPE_SPICE, | ||
3946 | 2093 | &vm->def->graphics[0]->data.spice.auth, | ||
3947 | 2094 | driver->spicePassword); | ||
3948 | 2095 | } | ||
3949 | 2096 | } | ||
3950 | 2097 | |||
3951 | 2098 | if (ret < 0) | ||
3952 | 2099 | goto cleanup; | ||
3953 | 2100 | |||
3954 | 2101 | if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) { | ||
3955 | 2102 | int i; | ||
3956 | 2103 | |||
3957 | 2104 | for (i = 0 ; i < vm->def->ndisks ; i++) { | ||
3958 | 2105 | char *secret; | ||
3959 | 2106 | size_t secretLen; | ||
3960 | 2107 | const char *alias; | ||
3961 | 2108 | |||
3962 | 2109 | if (!vm->def->disks[i]->encryption || | ||
3963 | 2110 | !vm->def->disks[i]->src) | ||
3964 | 2111 | continue; | ||
3965 | 2112 | |||
3966 | 2113 | if (qemuProcessGetVolumeQcowPassphrase(conn, | ||
3967 | 2114 | vm->def->disks[i], | ||
3968 | 2115 | &secret, &secretLen) < 0) | ||
3969 | 2116 | goto cleanup; | ||
3970 | 2117 | |||
3971 | 2118 | alias = vm->def->disks[i]->info.alias; | ||
3972 | 2119 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
3973 | 2120 | ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret); | ||
3974 | 2121 | VIR_FREE(secret); | ||
3975 | 2122 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
3976 | 2123 | if (ret < 0) | ||
3977 | 2124 | goto cleanup; | ||
3978 | 2125 | } | ||
3979 | 2126 | } | ||
3980 | 2127 | |||
3981 | 2128 | cleanup: | ||
3982 | 2129 | return ret; | ||
3983 | 2130 | } | ||
3984 | 2131 | |||
3985 | 2132 | |||
3986 | 2133 | #define QEMU_PCI_VENDOR_INTEL 0x8086 | ||
3987 | 2134 | #define QEMU_PCI_VENDOR_LSI_LOGIC 0x1000 | ||
3988 | 2135 | #define QEMU_PCI_VENDOR_REDHAT 0x1af4 | ||
3989 | 2136 | #define QEMU_PCI_VENDOR_CIRRUS 0x1013 | ||
3990 | 2137 | #define QEMU_PCI_VENDOR_REALTEK 0x10ec | ||
3991 | 2138 | #define QEMU_PCI_VENDOR_AMD 0x1022 | ||
3992 | 2139 | #define QEMU_PCI_VENDOR_ENSONIQ 0x1274 | ||
3993 | 2140 | #define QEMU_PCI_VENDOR_VMWARE 0x15ad | ||
3994 | 2141 | #define QEMU_PCI_VENDOR_QEMU 0x1234 | ||
3995 | 2142 | |||
3996 | 2143 | #define QEMU_PCI_PRODUCT_DISK_VIRTIO 0x1001 | ||
3997 | 2144 | |||
3998 | 2145 | #define QEMU_PCI_PRODUCT_BALLOON_VIRTIO 0x1002 | ||
3999 | 2146 | |||
4000 | 2147 | #define QEMU_PCI_PRODUCT_NIC_NE2K 0x8029 | ||
4001 | 2148 | #define QEMU_PCI_PRODUCT_NIC_PCNET 0x2000 | ||
4002 | 2149 | #define QEMU_PCI_PRODUCT_NIC_RTL8139 0x8139 | ||
4003 | 2150 | #define QEMU_PCI_PRODUCT_NIC_E1000 0x100E | ||
4004 | 2151 | #define QEMU_PCI_PRODUCT_NIC_VIRTIO 0x1000 | ||
4005 | 2152 | |||
4006 | 2153 | #define QEMU_PCI_PRODUCT_VGA_CIRRUS 0x00b8 | ||
4007 | 2154 | #define QEMU_PCI_PRODUCT_VGA_VMWARE 0x0405 | ||
4008 | 2155 | #define QEMU_PCI_PRODUCT_VGA_STDVGA 0x1111 | ||
4009 | 2156 | |||
4010 | 2157 | #define QEMU_PCI_PRODUCT_AUDIO_AC97 0x2415 | ||
4011 | 2158 | #define QEMU_PCI_PRODUCT_AUDIO_ES1370 0x5000 | ||
4012 | 2159 | |||
4013 | 2160 | #define QEMU_PCI_PRODUCT_CONTROLLER_PIIX 0x7010 | ||
4014 | 2161 | #define QEMU_PCI_PRODUCT_CONTROLLER_LSI 0x0012 | ||
4015 | 2162 | |||
4016 | 2163 | #define QEMU_PCI_PRODUCT_WATCHDOG_I63000ESB 0x25ab | ||
4017 | 2164 | |||
4018 | 2165 | static int | ||
4019 | 2166 | qemuProcessAssignNextPCIAddress(virDomainDeviceInfo *info, | ||
4020 | 2167 | int vendor, | ||
4021 | 2168 | int product, | ||
4022 | 2169 | qemuMonitorPCIAddress *addrs, | ||
4023 | 2170 | int naddrs) | ||
4024 | 2171 | { | ||
4025 | 2172 | int found = 0; | ||
4026 | 2173 | int i; | ||
4027 | 2174 | |||
4028 | 2175 | VIR_DEBUG("Look for %x:%x out of %d", vendor, product, naddrs); | ||
4029 | 2176 | |||
4030 | 2177 | for (i = 0 ; (i < naddrs) && !found; i++) { | ||
4031 | 2178 | VIR_DEBUG("Maybe %x:%x", addrs[i].vendor, addrs[i].product); | ||
4032 | 2179 | if (addrs[i].vendor == vendor && | ||
4033 | 2180 | addrs[i].product == product) { | ||
4034 | 2181 | VIR_DEBUG("Match %d", i); | ||
4035 | 2182 | found = 1; | ||
4036 | 2183 | break; | ||
4037 | 2184 | } | ||
4038 | 2185 | } | ||
4039 | 2186 | if (!found) { | ||
4040 | 2187 | return -1; | ||
4041 | 2188 | } | ||
4042 | 2189 | |||
4043 | 2190 | /* Blank it out so this device isn't matched again */ | ||
4044 | 2191 | addrs[i].vendor = 0; | ||
4045 | 2192 | addrs[i].product = 0; | ||
4046 | 2193 | |||
4047 | 2194 | if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) | ||
4048 | 2195 | info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; | ||
4049 | 2196 | |||
4050 | 2197 | if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { | ||
4051 | 2198 | info->addr.pci.domain = addrs[i].addr.domain; | ||
4052 | 2199 | info->addr.pci.bus = addrs[i].addr.bus; | ||
4053 | 2200 | info->addr.pci.slot = addrs[i].addr.slot; | ||
4054 | 2201 | info->addr.pci.function = addrs[i].addr.function; | ||
4055 | 2202 | } | ||
4056 | 2203 | |||
4057 | 2204 | return 0; | ||
4058 | 2205 | } | ||
4059 | 2206 | |||
4060 | 2207 | static int | ||
4061 | 2208 | qemuProcessGetPCIDiskVendorProduct(virDomainDiskDefPtr def, | ||
4062 | 2209 | unsigned *vendor, | ||
4063 | 2210 | unsigned *product) | ||
4064 | 2211 | { | ||
4065 | 2212 | switch (def->bus) { | ||
4066 | 2213 | case VIR_DOMAIN_DISK_BUS_VIRTIO: | ||
4067 | 2214 | *vendor = QEMU_PCI_VENDOR_REDHAT; | ||
4068 | 2215 | *product = QEMU_PCI_PRODUCT_DISK_VIRTIO; | ||
4069 | 2216 | break; | ||
4070 | 2217 | |||
4071 | 2218 | default: | ||
4072 | 2219 | return -1; | ||
4073 | 2220 | } | ||
4074 | 2221 | |||
4075 | 2222 | return 0; | ||
4076 | 2223 | } | ||
4077 | 2224 | |||
4078 | 2225 | static int | ||
4079 | 2226 | qemuProcessGetPCINetVendorProduct(virDomainNetDefPtr def, | ||
4080 | 2227 | unsigned *vendor, | ||
4081 | 2228 | unsigned *product) | ||
4082 | 2229 | { | ||
4083 | 2230 | if (!def->model) | ||
4084 | 2231 | return -1; | ||
4085 | 2232 | |||
4086 | 2233 | if (STREQ(def->model, "ne2k_pci")) { | ||
4087 | 2234 | *vendor = QEMU_PCI_VENDOR_REALTEK; | ||
4088 | 2235 | *product = QEMU_PCI_PRODUCT_NIC_NE2K; | ||
4089 | 2236 | } else if (STREQ(def->model, "pcnet")) { | ||
4090 | 2237 | *vendor = QEMU_PCI_VENDOR_AMD; | ||
4091 | 2238 | *product = QEMU_PCI_PRODUCT_NIC_PCNET; | ||
4092 | 2239 | } else if (STREQ(def->model, "rtl8139")) { | ||
4093 | 2240 | *vendor = QEMU_PCI_VENDOR_REALTEK; | ||
4094 | 2241 | *product = QEMU_PCI_PRODUCT_NIC_RTL8139; | ||
4095 | 2242 | } else if (STREQ(def->model, "e1000")) { | ||
4096 | 2243 | *vendor = QEMU_PCI_VENDOR_INTEL; | ||
4097 | 2244 | *product = QEMU_PCI_PRODUCT_NIC_E1000; | ||
4098 | 2245 | } else if (STREQ(def->model, "virtio")) { | ||
4099 | 2246 | *vendor = QEMU_PCI_VENDOR_REDHAT; | ||
4100 | 2247 | *product = QEMU_PCI_PRODUCT_NIC_VIRTIO; | ||
4101 | 2248 | } else { | ||
4102 | 2249 | VIR_INFO("Unexpected NIC model %s, cannot get PCI address", | ||
4103 | 2250 | def->model); | ||
4104 | 2251 | return -1; | ||
4105 | 2252 | } | ||
4106 | 2253 | return 0; | ||
4107 | 2254 | } | ||
4108 | 2255 | |||
4109 | 2256 | static int | ||
4110 | 2257 | qemuProcessGetPCIControllerVendorProduct(virDomainControllerDefPtr def, | ||
4111 | 2258 | unsigned *vendor, | ||
4112 | 2259 | unsigned *product) | ||
4113 | 2260 | { | ||
4114 | 2261 | switch (def->type) { | ||
4115 | 2262 | case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: | ||
4116 | 2263 | *vendor = QEMU_PCI_VENDOR_LSI_LOGIC; | ||
4117 | 2264 | *product = QEMU_PCI_PRODUCT_CONTROLLER_LSI; | ||
4118 | 2265 | break; | ||
4119 | 2266 | |||
4120 | 2267 | case VIR_DOMAIN_CONTROLLER_TYPE_FDC: | ||
4121 | 2268 | /* XXX we could put in the ISA bridge address, but | ||
4122 | 2269 | that's not technically the FDC's address */ | ||
4123 | 2270 | return -1; | ||
4124 | 2271 | |||
4125 | 2272 | case VIR_DOMAIN_CONTROLLER_TYPE_IDE: | ||
4126 | 2273 | *vendor = QEMU_PCI_VENDOR_INTEL; | ||
4127 | 2274 | *product = QEMU_PCI_PRODUCT_CONTROLLER_PIIX; | ||
4128 | 2275 | break; | ||
4129 | 2276 | |||
4130 | 2277 | default: | ||
4131 | 2278 | VIR_INFO("Unexpected controller type %s, cannot get PCI address", | ||
4132 | 2279 | virDomainControllerTypeToString(def->type)); | ||
4133 | 2280 | return -1; | ||
4134 | 2281 | } | ||
4135 | 2282 | |||
4136 | 2283 | return 0; | ||
4137 | 2284 | } | ||
4138 | 2285 | |||
4139 | 2286 | static int | ||
4140 | 2287 | qemuProcessGetPCIVideoVendorProduct(virDomainVideoDefPtr def, | ||
4141 | 2288 | unsigned *vendor, | ||
4142 | 2289 | unsigned *product) | ||
4143 | 2290 | { | ||
4144 | 2291 | switch (def->type) { | ||
4145 | 2292 | case VIR_DOMAIN_VIDEO_TYPE_CIRRUS: | ||
4146 | 2293 | *vendor = QEMU_PCI_VENDOR_CIRRUS; | ||
4147 | 2294 | *product = QEMU_PCI_PRODUCT_VGA_CIRRUS; | ||
4148 | 2295 | break; | ||
4149 | 2296 | |||
4150 | 2297 | case VIR_DOMAIN_VIDEO_TYPE_VGA: | ||
4151 | 2298 | *vendor = QEMU_PCI_VENDOR_QEMU; | ||
4152 | 2299 | *product = QEMU_PCI_PRODUCT_VGA_STDVGA; | ||
4153 | 2300 | break; | ||
4154 | 2301 | |||
4155 | 2302 | case VIR_DOMAIN_VIDEO_TYPE_VMVGA: | ||
4156 | 2303 | *vendor = QEMU_PCI_VENDOR_VMWARE; | ||
4157 | 2304 | *product = QEMU_PCI_PRODUCT_VGA_VMWARE; | ||
4158 | 2305 | break; | ||
4159 | 2306 | |||
4160 | 2307 | default: | ||
4161 | 2308 | return -1; | ||
4162 | 2309 | } | ||
4163 | 2310 | return 0; | ||
4164 | 2311 | } | ||
4165 | 2312 | |||
4166 | 2313 | static int | ||
4167 | 2314 | qemuProcessGetPCISoundVendorProduct(virDomainSoundDefPtr def, | ||
4168 | 2315 | unsigned *vendor, | ||
4169 | 2316 | unsigned *product) | ||
4170 | 2317 | { | ||
4171 | 2318 | switch (def->model) { | ||
4172 | 2319 | case VIR_DOMAIN_SOUND_MODEL_ES1370: | ||
4173 | 2320 | *vendor = QEMU_PCI_VENDOR_ENSONIQ; | ||
4174 | 2321 | *product = QEMU_PCI_PRODUCT_AUDIO_ES1370; | ||
4175 | 2322 | break; | ||
4176 | 2323 | |||
4177 | 2324 | case VIR_DOMAIN_SOUND_MODEL_AC97: | ||
4178 | 2325 | *vendor = QEMU_PCI_VENDOR_INTEL; | ||
4179 | 2326 | *product = QEMU_PCI_PRODUCT_AUDIO_AC97; | ||
4180 | 2327 | break; | ||
4181 | 2328 | |||
4182 | 2329 | default: | ||
4183 | 2330 | return -1; | ||
4184 | 2331 | } | ||
4185 | 2332 | |||
4186 | 2333 | return 0; | ||
4187 | 2334 | } | ||
4188 | 2335 | |||
4189 | 2336 | static int | ||
4190 | 2337 | qemuProcessGetPCIWatchdogVendorProduct(virDomainWatchdogDefPtr def, | ||
4191 | 2338 | unsigned *vendor, | ||
4192 | 2339 | unsigned *product) | ||
4193 | 2340 | { | ||
4194 | 2341 | switch (def->model) { | ||
4195 | 2342 | case VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB: | ||
4196 | 2343 | *vendor = QEMU_PCI_VENDOR_INTEL; | ||
4197 | 2344 | *product = QEMU_PCI_PRODUCT_WATCHDOG_I63000ESB; | ||
4198 | 2345 | break; | ||
4199 | 2346 | |||
4200 | 2347 | default: | ||
4201 | 2348 | return -1; | ||
4202 | 2349 | } | ||
4203 | 2350 | |||
4204 | 2351 | return 0; | ||
4205 | 2352 | } | ||
4206 | 2353 | |||
4207 | 2354 | |||
4208 | 2355 | static int | ||
4209 | 2356 | qemuProcessGetPCIMemballoonVendorProduct(virDomainMemballoonDefPtr def, | ||
4210 | 2357 | unsigned *vendor, | ||
4211 | 2358 | unsigned *product) | ||
4212 | 2359 | { | ||
4213 | 2360 | switch (def->model) { | ||
4214 | 2361 | case VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO: | ||
4215 | 2362 | *vendor = QEMU_PCI_VENDOR_REDHAT; | ||
4216 | 2363 | *product = QEMU_PCI_PRODUCT_BALLOON_VIRTIO; | ||
4217 | 2364 | break; | ||
4218 | 2365 | |||
4219 | 2366 | default: | ||
4220 | 2367 | return -1; | ||
4221 | 2368 | } | ||
4222 | 2369 | |||
4223 | 2370 | return 0; | ||
4224 | 2371 | } | ||
4225 | 2372 | |||
4226 | 2373 | |||
4227 | 2374 | /* | ||
4228 | 2375 | * This entire method assumes that PCI devices in 'info pci' | ||
4229 | 2376 | * match ordering of devices specified on the command line | ||
4230 | 2377 | * wrt to devices of matching vendor+product | ||
4231 | 2378 | * | ||
4232 | 2379 | * XXXX this might not be a valid assumption if we assign | ||
4233 | 2380 | * some static addrs on CLI. Have to check that... | ||
4234 | 2381 | */ | ||
4235 | 2382 | static int | ||
4236 | 2383 | qemuProcessDetectPCIAddresses(virDomainObjPtr vm, | ||
4237 | 2384 | qemuMonitorPCIAddress *addrs, | ||
4238 | 2385 | int naddrs) | ||
4239 | 2386 | { | ||
4240 | 2387 | unsigned int vendor = 0, product = 0; | ||
4241 | 2388 | int i; | ||
4242 | 2389 | |||
4243 | 2390 | /* XXX should all these vendor/product IDs be kept in the | ||
4244 | 2391 | * actual device data structure instead ? | ||
4245 | 2392 | */ | ||
4246 | 2393 | |||
4247 | 2394 | for (i = 0 ; i < vm->def->ndisks ; i++) { | ||
4248 | 2395 | if (qemuProcessGetPCIDiskVendorProduct(vm->def->disks[i], &vendor, &product) < 0) | ||
4249 | 2396 | continue; | ||
4250 | 2397 | |||
4251 | 2398 | if (qemuProcessAssignNextPCIAddress(&(vm->def->disks[i]->info), | ||
4252 | 2399 | vendor, product, | ||
4253 | 2400 | addrs, naddrs) < 0) { | ||
4254 | 2401 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4255 | 2402 | _("cannot find PCI address for VirtIO disk %s"), | ||
4256 | 2403 | vm->def->disks[i]->dst); | ||
4257 | 2404 | return -1; | ||
4258 | 2405 | } | ||
4259 | 2406 | } | ||
4260 | 2407 | |||
4261 | 2408 | for (i = 0 ; i < vm->def->nnets ; i++) { | ||
4262 | 2409 | if (qemuProcessGetPCINetVendorProduct(vm->def->nets[i], &vendor, &product) < 0) | ||
4263 | 2410 | continue; | ||
4264 | 2411 | |||
4265 | 2412 | if (qemuProcessAssignNextPCIAddress(&(vm->def->nets[i]->info), | ||
4266 | 2413 | vendor, product, | ||
4267 | 2414 | addrs, naddrs) < 0) { | ||
4268 | 2415 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4269 | 2416 | _("cannot find PCI address for %s NIC"), | ||
4270 | 2417 | vm->def->nets[i]->model); | ||
4271 | 2418 | return -1; | ||
4272 | 2419 | } | ||
4273 | 2420 | } | ||
4274 | 2421 | |||
4275 | 2422 | for (i = 0 ; i < vm->def->ncontrollers ; i++) { | ||
4276 | 2423 | if (qemuProcessGetPCIControllerVendorProduct(vm->def->controllers[i], &vendor, &product) < 0) | ||
4277 | 2424 | continue; | ||
4278 | 2425 | |||
4279 | 2426 | if (qemuProcessAssignNextPCIAddress(&(vm->def->controllers[i]->info), | ||
4280 | 2427 | vendor, product, | ||
4281 | 2428 | addrs, naddrs) < 0) { | ||
4282 | 2429 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4283 | 2430 | _("cannot find PCI address for controller %s"), | ||
4284 | 2431 | virDomainControllerTypeToString(vm->def->controllers[i]->type)); | ||
4285 | 2432 | return -1; | ||
4286 | 2433 | } | ||
4287 | 2434 | } | ||
4288 | 2435 | |||
4289 | 2436 | for (i = 0 ; i < vm->def->nvideos ; i++) { | ||
4290 | 2437 | if (qemuProcessGetPCIVideoVendorProduct(vm->def->videos[i], &vendor, &product) < 0) | ||
4291 | 2438 | continue; | ||
4292 | 2439 | |||
4293 | 2440 | if (qemuProcessAssignNextPCIAddress(&(vm->def->videos[i]->info), | ||
4294 | 2441 | vendor, product, | ||
4295 | 2442 | addrs, naddrs) < 0) { | ||
4296 | 2443 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4297 | 2444 | _("cannot find PCI address for video adapter %s"), | ||
4298 | 2445 | virDomainVideoTypeToString(vm->def->videos[i]->type)); | ||
4299 | 2446 | return -1; | ||
4300 | 2447 | } | ||
4301 | 2448 | } | ||
4302 | 2449 | |||
4303 | 2450 | for (i = 0 ; i < vm->def->nsounds ; i++) { | ||
4304 | 2451 | if (qemuProcessGetPCISoundVendorProduct(vm->def->sounds[i], &vendor, &product) < 0) | ||
4305 | 2452 | continue; | ||
4306 | 2453 | |||
4307 | 2454 | if (qemuProcessAssignNextPCIAddress(&(vm->def->sounds[i]->info), | ||
4308 | 2455 | vendor, product, | ||
4309 | 2456 | addrs, naddrs) < 0) { | ||
4310 | 2457 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4311 | 2458 | _("cannot find PCI address for sound adapter %s"), | ||
4312 | 2459 | virDomainSoundModelTypeToString(vm->def->sounds[i]->model)); | ||
4313 | 2460 | return -1; | ||
4314 | 2461 | } | ||
4315 | 2462 | } | ||
4316 | 2463 | |||
4317 | 2464 | |||
4318 | 2465 | if (vm->def->watchdog && | ||
4319 | 2466 | qemuProcessGetPCIWatchdogVendorProduct(vm->def->watchdog, &vendor, &product) == 0) { | ||
4320 | 2467 | if (qemuProcessAssignNextPCIAddress(&(vm->def->watchdog->info), | ||
4321 | 2468 | vendor, product, | ||
4322 | 2469 | addrs, naddrs) < 0) { | ||
4323 | 2470 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4324 | 2471 | _("cannot find PCI address for watchdog %s"), | ||
4325 | 2472 | virDomainWatchdogModelTypeToString(vm->def->watchdog->model)); | ||
4326 | 2473 | return -1; | ||
4327 | 2474 | } | ||
4328 | 2475 | } | ||
4329 | 2476 | |||
4330 | 2477 | if (vm->def->memballoon && | ||
4331 | 2478 | qemuProcessGetPCIMemballoonVendorProduct(vm->def->memballoon, &vendor, &product) == 0) { | ||
4332 | 2479 | if (qemuProcessAssignNextPCIAddress(&(vm->def->memballoon->info), | ||
4333 | 2480 | vendor, product, | ||
4334 | 2481 | addrs, naddrs) < 0) { | ||
4335 | 2482 | virReportError(VIR_ERR_INTERNAL_ERROR, | ||
4336 | 2483 | _("cannot find PCI address for balloon %s"), | ||
4337 | 2484 | virDomainMemballoonModelTypeToString(vm->def->memballoon->model)); | ||
4338 | 2485 | return -1; | ||
4339 | 2486 | } | ||
4340 | 2487 | } | ||
4341 | 2488 | |||
4342 | 2489 | /* XXX console (virtio) */ | ||
4343 | 2490 | |||
4344 | 2491 | |||
4345 | 2492 | /* ... and now things we don't have in our xml */ | ||
4346 | 2493 | |||
4347 | 2494 | /* XXX USB controller ? */ | ||
4348 | 2495 | |||
4349 | 2496 | /* XXX what about other PCI devices (ie bridges) */ | ||
4350 | 2497 | |||
4351 | 2498 | return 0; | ||
4352 | 2499 | } | ||
4353 | 2500 | |||
4354 | 2501 | static int | ||
4355 | 2502 | qemuProcessInitPCIAddresses(struct qemud_driver *driver, | ||
4356 | 2503 | virDomainObjPtr vm) | ||
4357 | 2504 | { | ||
4358 | 2505 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
4359 | 2506 | int naddrs; | ||
4360 | 2507 | int ret; | ||
4361 | 2508 | qemuMonitorPCIAddress *addrs = NULL; | ||
4362 | 2509 | |||
4363 | 2510 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
4364 | 2511 | naddrs = qemuMonitorGetAllPCIAddresses(priv->mon, | ||
4365 | 2512 | &addrs); | ||
4366 | 2513 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
4367 | 2514 | |||
4368 | 2515 | ret = qemuProcessDetectPCIAddresses(vm, addrs, naddrs); | ||
4369 | 2516 | |||
4370 | 2517 | VIR_FREE(addrs); | ||
4371 | 2518 | |||
4372 | 2519 | return ret; | ||
4373 | 2520 | } | ||
4374 | 2521 | |||
4375 | 2522 | |||
4376 | 2523 | static int qemuProcessNextFreePort(struct qemud_driver *driver, | ||
4377 | 2524 | int startPort) | ||
4378 | 2525 | { | ||
4379 | 2526 | int i; | ||
4380 | 2527 | |||
4381 | 2528 | for (i = startPort ; i < driver->remotePortMax; i++) { | ||
4382 | 2529 | int fd; | ||
4383 | 2530 | int reuse = 1; | ||
4384 | 2531 | struct sockaddr_in addr; | ||
4385 | 2532 | bool used = false; | ||
4386 | 2533 | |||
4387 | 2534 | if (virBitmapGetBit(driver->reservedRemotePorts, | ||
4388 | 2535 | i - driver->remotePortMin, &used) < 0) | ||
4389 | 2536 | VIR_DEBUG("virBitmapGetBit failed on bit %d", i - driver->remotePortMin); | ||
4390 | 2537 | |||
4391 | 2538 | if (used) | ||
4392 | 2539 | continue; | ||
4393 | 2540 | |||
4394 | 2541 | addr.sin_family = AF_INET; | ||
4395 | 2542 | addr.sin_port = htons(i); | ||
4396 | 2543 | addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
4397 | 2544 | fd = socket(PF_INET, SOCK_STREAM, 0); | ||
4398 | 2545 | if (fd < 0) | ||
4399 | 2546 | return -1; | ||
4400 | 2547 | |||
4401 | 2548 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) { | ||
4402 | 2549 | VIR_FORCE_CLOSE(fd); | ||
4403 | 2550 | break; | ||
4404 | 2551 | } | ||
4405 | 2552 | |||
4406 | 2553 | if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { | ||
4407 | 2554 | /* Not in use, lets grab it */ | ||
4408 | 2555 | VIR_FORCE_CLOSE(fd); | ||
4409 | 2556 | /* Add port to bitmap of reserved ports */ | ||
4410 | 2557 | if (virBitmapSetBit(driver->reservedRemotePorts, | ||
4411 | 2558 | i - driver->remotePortMin) < 0) { | ||
4412 | 2559 | VIR_DEBUG("virBitmapSetBit failed on bit %d", | ||
4413 | 2560 | i - driver->remotePortMin); | ||
4414 | 2561 | } | ||
4415 | 2562 | return i; | ||
4416 | 2563 | } | ||
4417 | 2564 | VIR_FORCE_CLOSE(fd); | ||
4418 | 2565 | |||
4419 | 2566 | if (errno == EADDRINUSE) { | ||
4420 | 2567 | /* In use, try next */ | ||
4421 | 2568 | continue; | ||
4422 | 2569 | } | ||
4423 | 2570 | /* Some other bad failure, get out.. */ | ||
4424 | 2571 | break; | ||
4425 | 2572 | } | ||
4426 | 2573 | return -1; | ||
4427 | 2574 | } | ||
4428 | 2575 | |||
4429 | 2576 | |||
4430 | 2577 | static void | ||
4431 | 2578 | qemuProcessReturnPort(struct qemud_driver *driver, | ||
4432 | 2579 | int port) | ||
4433 | 2580 | { | ||
4434 | 2581 | if (port < driver->remotePortMin) | ||
4435 | 2582 | return; | ||
4436 | 2583 | |||
4437 | 2584 | if (virBitmapClearBit(driver->reservedRemotePorts, | ||
4438 | 2585 | port - driver->remotePortMin) < 0) | ||
4439 | 2586 | VIR_DEBUG("Could not mark port %d as unused", port); | ||
4440 | 2587 | } | ||
4441 | 2588 | |||
4442 | 2589 | |||
4443 | 2590 | static int | ||
4444 | 2591 | qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED, | ||
4445 | 2592 | virDomainChrDefPtr dev, | ||
4446 | 2593 | void *opaque ATTRIBUTE_UNUSED) | ||
4447 | 2594 | { | ||
4448 | 2595 | int fd; | ||
4449 | 2596 | if (dev->source.type != VIR_DOMAIN_CHR_TYPE_FILE) | ||
4450 | 2597 | return 0; | ||
4451 | 2598 | |||
4452 | 2599 | if ((fd = open(dev->source.data.file.path, | ||
4453 | 2600 | O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) { | ||
4454 | 2601 | virReportSystemError(errno, | ||
4455 | 2602 | _("Unable to pre-create chardev file '%s'"), | ||
4456 | 2603 | dev->source.data.file.path); | ||
4457 | 2604 | return -1; | ||
4458 | 2605 | } | ||
4459 | 2606 | |||
4460 | 2607 | VIR_FORCE_CLOSE(fd); | ||
4461 | 2608 | |||
4462 | 2609 | return 0; | ||
4463 | 2610 | } | ||
4464 | 2611 | |||
4465 | 2612 | |||
4466 | 2613 | static int | ||
4467 | 2614 | qemuProcessLimits(struct qemud_driver *driver) | ||
4468 | 2615 | { | ||
4469 | 2616 | struct rlimit rlim; | ||
4470 | 2617 | |||
4471 | 2618 | if (driver->maxProcesses > 0) { | ||
4472 | 2619 | rlim.rlim_cur = rlim.rlim_max = driver->maxProcesses; | ||
4473 | 2620 | if (setrlimit(RLIMIT_NPROC, &rlim) < 0) { | ||
4474 | 2621 | virReportSystemError(errno, | ||
4475 | 2622 | _("cannot limit number of processes to %d"), | ||
4476 | 2623 | driver->maxProcesses); | ||
4477 | 2624 | return -1; | ||
4478 | 2625 | } | ||
4479 | 2626 | } | ||
4480 | 2627 | |||
4481 | 2628 | if (driver->maxFiles > 0) { | ||
4482 | 2629 | /* Max number of opened files is one greater than | ||
4483 | 2630 | * actual limit. See man setrlimit */ | ||
4484 | 2631 | rlim.rlim_cur = rlim.rlim_max = driver->maxFiles + 1; | ||
4485 | 2632 | if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { | ||
4486 | 2633 | virReportSystemError(errno, | ||
4487 | 2634 | _("cannot set max opened files to %d"), | ||
4488 | 2635 | driver->maxFiles); | ||
4489 | 2636 | return -1; | ||
4490 | 2637 | } | ||
4491 | 2638 | } | ||
4492 | 2639 | |||
4493 | 2640 | return 0; | ||
4494 | 2641 | } | ||
4495 | 2642 | |||
4496 | 2643 | |||
4497 | 2644 | struct qemuProcessHookData { | ||
4498 | 2645 | virConnectPtr conn; | ||
4499 | 2646 | virDomainObjPtr vm; | ||
4500 | 2647 | struct qemud_driver *driver; | ||
4501 | 2648 | virBitmapPtr nodemask; | ||
4502 | 2649 | }; | ||
4503 | 2650 | |||
4504 | 2651 | static int qemuProcessHook(void *data) | ||
4505 | 2652 | { | ||
4506 | 2653 | struct qemuProcessHookData *h = data; | ||
4507 | 2654 | int ret = -1; | ||
4508 | 2655 | int fd; | ||
4509 | 2656 | |||
4510 | 2657 | /* Some later calls want pid present */ | ||
4511 | 2658 | h->vm->pid = getpid(); | ||
4512 | 2659 | |||
4513 | 2660 | VIR_DEBUG("Obtaining domain lock"); | ||
4514 | 2661 | /* | ||
4515 | 2662 | * Since we're going to leak the returned FD to QEMU, | ||
4516 | 2663 | * we need to make sure it gets a sensible label. | ||
4517 | 2664 | * This mildly sucks, because there could be other | ||
4518 | 2665 | * sockets the lock driver opens that we don't want | ||
4519 | 2666 | * labelled. So far we're ok though. | ||
4520 | 2667 | */ | ||
4521 | 2668 | if (virSecurityManagerSetSocketLabel(h->driver->securityManager, h->vm->def) < 0) | ||
4522 | 2669 | goto cleanup; | ||
4523 | 2670 | if (virDomainLockProcessStart(h->driver->lockManager, | ||
4524 | 2671 | h->driver->uri, | ||
4525 | 2672 | h->vm, | ||
4526 | 2673 | /* QEMU is always paused initially */ | ||
4527 | 2674 | true, | ||
4528 | 2675 | &fd) < 0) | ||
4529 | 2676 | goto cleanup; | ||
4530 | 2677 | if (virSecurityManagerClearSocketLabel(h->driver->securityManager, h->vm->def) < 0) | ||
4531 | 2678 | goto cleanup; | ||
4532 | 2679 | |||
4533 | 2680 | if (qemuProcessLimits(h->driver) < 0) | ||
4534 | 2681 | goto cleanup; | ||
4535 | 2682 | |||
4536 | 2683 | /* This must take place before exec(), so that all QEMU | ||
4537 | 2684 | * memory allocation is on the correct NUMA node | ||
4538 | 2685 | */ | ||
4539 | 2686 | VIR_DEBUG("Moving process to cgroup"); | ||
4540 | 2687 | if (qemuAddToCgroup(h->driver, h->vm->def) < 0) | ||
4541 | 2688 | goto cleanup; | ||
4542 | 2689 | |||
4543 | 2690 | /* This must be done after cgroup placement to avoid resetting CPU | ||
4544 | 2691 | * affinity */ | ||
4545 | 2692 | if (!h->vm->def->cputune.emulatorpin && | ||
4546 | 2693 | qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0) | ||
4547 | 2694 | goto cleanup; | ||
4548 | 2695 | |||
4549 | 2696 | if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0) | ||
4550 | 2697 | goto cleanup; | ||
4551 | 2698 | |||
4552 | 2699 | VIR_DEBUG("Setting up security labelling"); | ||
4553 | 2700 | if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm->def) < 0) | ||
4554 | 2701 | goto cleanup; | ||
4555 | 2702 | |||
4556 | 2703 | ret = 0; | ||
4557 | 2704 | |||
4558 | 2705 | cleanup: | ||
4559 | 2706 | VIR_DEBUG("Hook complete ret=%d", ret); | ||
4560 | 2707 | return ret; | ||
4561 | 2708 | } | ||
4562 | 2709 | |||
4563 | 2710 | int | ||
4564 | 2711 | qemuProcessPrepareMonitorChr(struct qemud_driver *driver, | ||
4565 | 2712 | virDomainChrSourceDefPtr monConfig, | ||
4566 | 2713 | const char *vm) | ||
4567 | 2714 | { | ||
4568 | 2715 | monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX; | ||
4569 | 2716 | monConfig->data.nix.listen = true; | ||
4570 | 2717 | |||
4571 | 2718 | if (virAsprintf(&monConfig->data.nix.path, "%s/%s.monitor", | ||
4572 | 2719 | driver->libDir, vm) < 0) { | ||
4573 | 2720 | virReportOOMError(); | ||
4574 | 2721 | return -1; | ||
4575 | 2722 | } | ||
4576 | 2723 | |||
4577 | 2724 | return 0; | ||
4578 | 2725 | } | ||
4579 | 2726 | |||
4580 | 2727 | |||
4581 | 2728 | /* | ||
4582 | 2729 | * Precondition: Both driver and vm must be locked, | ||
4583 | 2730 | * and a job must be active. This method will call | ||
4584 | 2731 | * {Enter,Exit}MonitorWithDriver | ||
4585 | 2732 | */ | ||
4586 | 2733 | int | ||
4587 | 2734 | qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm, | ||
4588 | 2735 | virConnectPtr conn, virDomainRunningReason reason, | ||
4589 | 2736 | enum qemuDomainAsyncJob asyncJob) | ||
4590 | 2737 | { | ||
4591 | 2738 | int ret; | ||
4592 | 2739 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
4593 | 2740 | |||
4594 | 2741 | VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState)); | ||
4595 | 2742 | if (virDomainLockProcessResume(driver->lockManager, driver->uri, | ||
4596 | 2743 | vm, priv->lockState) < 0) { | ||
4597 | 2744 | /* Don't free priv->lockState on error, because we need | ||
4598 | 2745 | * to make sure we have state still present if the user | ||
4599 | 2746 | * tries to resume again | ||
4600 | 2747 | */ | ||
4601 | 2748 | return -1; | ||
4602 | 2749 | } | ||
4603 | 2750 | VIR_FREE(priv->lockState); | ||
4604 | 2751 | |||
4605 | 2752 | ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob); | ||
4606 | 2753 | if (ret == 0) { | ||
4607 | 2754 | ret = qemuMonitorStartCPUs(priv->mon, conn); | ||
4608 | 2755 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
4609 | 2756 | } | ||
4610 | 2757 | |||
4611 | 2758 | if (ret == 0) { | ||
4612 | 2759 | virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); | ||
4613 | 2760 | } else { | ||
4614 | 2761 | if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) | ||
4615 | 2762 | VIR_WARN("Unable to release lease on %s", vm->def->name); | ||
4616 | 2763 | VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); | ||
4617 | 2764 | } | ||
4618 | 2765 | |||
4619 | 2766 | return ret; | ||
4620 | 2767 | } | ||
4621 | 2768 | |||
4622 | 2769 | |||
4623 | 2770 | int qemuProcessStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm, | ||
4624 | 2771 | virDomainPausedReason reason, | ||
4625 | 2772 | enum qemuDomainAsyncJob asyncJob) | ||
4626 | 2773 | { | ||
4627 | 2774 | int ret; | ||
4628 | 2775 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
4629 | 2776 | |||
4630 | 2777 | VIR_FREE(priv->lockState); | ||
4631 | 2778 | |||
4632 | 2779 | ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob); | ||
4633 | 2780 | if (ret == 0) { | ||
4634 | 2781 | ret = qemuMonitorStopCPUs(priv->mon); | ||
4635 | 2782 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
4636 | 2783 | } | ||
4637 | 2784 | |||
4638 | 2785 | if (ret == 0) { | ||
4639 | 2786 | virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason); | ||
4640 | 2787 | if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) | ||
4641 | 2788 | VIR_WARN("Unable to release lease on %s", vm->def->name); | ||
4642 | 2789 | VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); | ||
4643 | 2790 | } | ||
4644 | 2791 | |||
4645 | 2792 | return ret; | ||
4646 | 2793 | } | ||
4647 | 2794 | |||
4648 | 2795 | |||
4649 | 2796 | |||
4650 | 2797 | static int | ||
4651 | 2798 | qemuProcessNotifyNets(virDomainDefPtr def) | ||
4652 | 2799 | { | ||
4653 | 2800 | int ii; | ||
4654 | 2801 | |||
4655 | 2802 | for (ii = 0 ; ii < def->nnets ; ii++) { | ||
4656 | 2803 | virDomainNetDefPtr net = def->nets[ii]; | ||
4657 | 2804 | if (networkNotifyActualDevice(net) < 0) | ||
4658 | 2805 | return -1; | ||
4659 | 2806 | } | ||
4660 | 2807 | return 0; | ||
4661 | 2808 | } | ||
4662 | 2809 | |||
4663 | 2810 | static int | ||
4664 | 2811 | qemuProcessFiltersInstantiate(virConnectPtr conn, | ||
4665 | 2812 | virDomainDefPtr def) | ||
4666 | 2813 | { | ||
4667 | 2814 | int err = 0; | ||
4668 | 2815 | int i; | ||
4669 | 2816 | |||
4670 | 2817 | if (!conn) | ||
4671 | 2818 | return 1; | ||
4672 | 2819 | |||
4673 | 2820 | for (i = 0 ; i < def->nnets ; i++) { | ||
4674 | 2821 | virDomainNetDefPtr net = def->nets[i]; | ||
4675 | 2822 | if ((net->filter) && (net->ifname)) { | ||
4676 | 2823 | if (virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) { | ||
4677 | 2824 | err = 1; | ||
4678 | 2825 | break; | ||
4679 | 2826 | } | ||
4680 | 2827 | } | ||
4681 | 2828 | } | ||
4682 | 2829 | |||
4683 | 2830 | return err; | ||
4684 | 2831 | } | ||
4685 | 2832 | |||
4686 | 2833 | static int | ||
4687 | 2834 | qemuProcessUpdateState(struct qemud_driver *driver, virDomainObjPtr vm) | ||
4688 | 2835 | { | ||
4689 | 2836 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
4690 | 2837 | virDomainState state; | ||
4691 | 2838 | virDomainPausedReason reason; | ||
4692 | 2839 | virDomainState newState = VIR_DOMAIN_NOSTATE; | ||
4693 | 2840 | int newReason; | ||
4694 | 2841 | bool running; | ||
4695 | 2842 | char *msg = NULL; | ||
4696 | 2843 | int ret; | ||
4697 | 2844 | |||
4698 | 2845 | qemuDomainObjEnterMonitorWithDriver(driver, vm); | ||
4699 | 2846 | ret = qemuMonitorGetStatus(priv->mon, &running, &reason); | ||
4700 | 2847 | qemuDomainObjExitMonitorWithDriver(driver, vm); | ||
4701 | 2848 | |||
4702 | 2849 | if (ret < 0 || !virDomainObjIsActive(vm)) | ||
4703 | 2850 | return -1; | ||
4704 | 2851 | |||
4705 | 2852 | state = virDomainObjGetState(vm, NULL); | ||
4706 | 2853 | |||
4707 | 2854 | if (state == VIR_DOMAIN_PAUSED && running) { | ||
4708 | 2855 | newState = VIR_DOMAIN_RUNNING; | ||
4709 | 2856 | newReason = VIR_DOMAIN_RUNNING_UNPAUSED; | ||
4710 | 2857 | msg = strdup("was unpaused"); | ||
4711 | 2858 | } else if (state == VIR_DOMAIN_RUNNING && !running) { | ||
4712 | 2859 | if (reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN) { | ||
4713 | 2860 | newState = VIR_DOMAIN_SHUTDOWN; | ||
4714 | 2861 | newReason = VIR_DOMAIN_SHUTDOWN_UNKNOWN; | ||
4715 | 2862 | msg = strdup("shutdown"); | ||
4716 | 2863 | } else { | ||
4717 | 2864 | newState = VIR_DOMAIN_PAUSED; | ||
4718 | 2865 | newReason = reason; | ||
4719 | 2866 | ignore_value(virAsprintf(&msg, "was paused (%s)", | ||
4720 | 2867 | virDomainPausedReasonTypeToString(reason))); | ||
4721 | 2868 | } | ||
4722 | 2869 | } else if (state == VIR_DOMAIN_SHUTOFF && running) { | ||
4723 | 2870 | newState = VIR_DOMAIN_RUNNING; | ||
4724 | 2871 | newReason = VIR_DOMAIN_RUNNING_BOOTED; | ||
4725 | 2872 | msg = strdup("finished booting"); | ||
4726 | 2873 | } | ||
4727 | 2874 | |||
4728 | 2875 | if (newState != VIR_DOMAIN_NOSTATE) { | ||
4729 | 2876 | if (!msg) { | ||
4730 | 2877 | virReportOOMError(); | ||
4731 | 2878 | return -1; | ||
4732 | 2879 | } | ||
4733 | 2880 | |||
4734 | 2881 | VIR_DEBUG("Domain %s %s while its monitor was disconnected;" | ||
4735 | 2882 | " changing state to %s (%s)", | ||
4736 | 2883 | vm->def->name, | ||
4737 | 2884 | msg, | ||
4738 | 2885 | virDomainStateTypeToString(newState), | ||
4739 | 2886 | virDomainStateReasonToString(newState, newReason)); | ||
4740 | 2887 | VIR_FREE(msg); | ||
4741 | 2888 | virDomainObjSetState(vm, newState, newReason); | ||
4742 | 2889 | } | ||
4743 | 2890 | |||
4744 | 2891 | return 0; | ||
4745 | 2892 | } | ||
4746 | 2893 | |||
4747 | 2894 | static int | ||
4748 | 2895 | qemuProcessRecoverMigration(struct qemud_driver *driver, | ||
4749 | 2896 | virDomainObjPtr vm, | ||
4750 | 2897 | virConnectPtr conn, | ||
4751 | 2898 | enum qemuDomainAsyncJob job, | ||
4752 | 2899 | enum qemuMigrationJobPhase phase, | ||
4753 | 2900 | virDomainState state, | ||
4754 | 2901 | int reason) | ||
4755 | 2902 | { | ||
4756 | 2903 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
4757 | 2904 | |||
4758 | 2905 | if (job == QEMU_ASYNC_JOB_MIGRATION_IN) { | ||
4759 | 2906 | switch (phase) { | ||
4760 | 2907 | case QEMU_MIGRATION_PHASE_NONE: | ||
4761 | 2908 | case QEMU_MIGRATION_PHASE_PERFORM2: | ||
4762 | 2909 | case QEMU_MIGRATION_PHASE_BEGIN3: | ||
4763 | 2910 | case QEMU_MIGRATION_PHASE_PERFORM3: | ||
4764 | 2911 | case QEMU_MIGRATION_PHASE_PERFORM3_DONE: | ||
4765 | 2912 | case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: | ||
4766 | 2913 | case QEMU_MIGRATION_PHASE_CONFIRM3: | ||
4767 | 2914 | case QEMU_MIGRATION_PHASE_LAST: | ||
4768 | 2915 | break; | ||
4769 | 2916 | |||
4770 | 2917 | case QEMU_MIGRATION_PHASE_PREPARE: | ||
4771 | 2918 | VIR_DEBUG("Killing unfinished incoming migration for domain %s", | ||
4772 | 2919 | vm->def->name); | ||
4773 | 2920 | return -1; | ||
4774 | 2921 | |||
4775 | 2922 | case QEMU_MIGRATION_PHASE_FINISH2: | ||
4776 | 2923 | /* source domain is already killed so let's just resume the domain | ||
4777 | 2924 | * and hope we are all set */ | ||
4778 | 2925 | VIR_DEBUG("Incoming migration finished, resuming domain %s", | ||
4779 | 2926 | vm->def->name); | ||
4780 | 2927 | if (qemuProcessStartCPUs(driver, vm, conn, | ||
4781 | 2928 | VIR_DOMAIN_RUNNING_UNPAUSED, | ||
4782 | 2929 | QEMU_ASYNC_JOB_NONE) < 0) { | ||
4783 | 2930 | VIR_WARN("Could not resume domain %s", vm->def->name); | ||
4784 | 2931 | } | ||
4785 | 2932 | break; | ||
4786 | 2933 | |||
4787 | 2934 | case QEMU_MIGRATION_PHASE_FINISH3: | ||
4788 | 2935 | /* migration finished, we started resuming the domain but didn't | ||
4789 | 2936 | * confirm success or failure yet; killing it seems safest */ | ||
4790 | 2937 | VIR_DEBUG("Killing migrated domain %s", vm->def->name); | ||
4791 | 2938 | return -1; | ||
4792 | 2939 | } | ||
4793 | 2940 | } else if (job == QEMU_ASYNC_JOB_MIGRATION_OUT) { | ||
4794 | 2941 | switch (phase) { | ||
4795 | 2942 | case QEMU_MIGRATION_PHASE_NONE: | ||
4796 | 2943 | case QEMU_MIGRATION_PHASE_PREPARE: | ||
4797 | 2944 | case QEMU_MIGRATION_PHASE_FINISH2: | ||
4798 | 2945 | case QEMU_MIGRATION_PHASE_FINISH3: | ||
4799 | 2946 | case QEMU_MIGRATION_PHASE_LAST: | ||
4800 | 2947 | break; | ||
4801 | 2948 | |||
4802 | 2949 | case QEMU_MIGRATION_PHASE_BEGIN3: | ||
4803 | 2950 | /* nothing happen so far, just forget we were about to migrate the | ||
4804 | 2951 | * domain */ | ||
4805 | 2952 | break; | ||
4806 | 2953 | |||
4807 | 2954 | case QEMU_MIGRATION_PHASE_PERFORM2: | ||
4808 | 2955 | case QEMU_MIGRATION_PHASE_PERFORM3: | ||
4809 | 2956 | /* migration is still in progress, let's cancel it and resume the | ||
4810 | 2957 | * domain */ | ||
4811 | 2958 | VIR_DEBUG("Canceling unfinished outgoing migration of domain %s", | ||
4812 | 2959 | vm->def->name); | ||
4813 | 2960 | qemuDomainObjEnterMonitor(driver, vm); | ||
4814 | 2961 | ignore_value(qemuMonitorMigrateCancel(priv->mon)); | ||
4815 | 2962 | qemuDomainObjExitMonitor(driver, vm); | ||
4816 | 2963 | /* resume the domain but only if it was paused as a result of | ||
4817 | 2964 | * migration */ | ||
4818 | 2965 | if (state == VIR_DOMAIN_PAUSED && | ||
4819 | 2966 | (reason == VIR_DOMAIN_PAUSED_MIGRATION || | ||
4820 | 2967 | reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { | ||
4821 | 2968 | if (qemuProcessStartCPUs(driver, vm, conn, | ||
4822 | 2969 | VIR_DOMAIN_RUNNING_UNPAUSED, | ||
4823 | 2970 | QEMU_ASYNC_JOB_NONE) < 0) { | ||
4824 | 2971 | VIR_WARN("Could not resume domain %s", vm->def->name); | ||
4825 | 2972 | } | ||
4826 | 2973 | } | ||
4827 | 2974 | break; | ||
4828 | 2975 | |||
4829 | 2976 | case QEMU_MIGRATION_PHASE_PERFORM3_DONE: | ||
4830 | 2977 | /* migration finished but we didn't have a chance to get the result | ||
4831 | 2978 | * of Finish3 step; third party needs to check what to do next | ||
4832 | 2979 | */ | ||
4833 | 2980 | break; | ||
4834 | 2981 | |||
4835 | 2982 | case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: | ||
4836 | 2983 | /* Finish3 failed, we need to resume the domain */ | ||
4837 | 2984 | VIR_DEBUG("Resuming domain %s after failed migration", | ||
4838 | 2985 | vm->def->name); | ||
4839 | 2986 | if (state == VIR_DOMAIN_PAUSED && | ||
4840 | 2987 | (reason == VIR_DOMAIN_PAUSED_MIGRATION || | ||
4841 | 2988 | reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { | ||
4842 | 2989 | if (qemuProcessStartCPUs(driver, vm, conn, | ||
4843 | 2990 | VIR_DOMAIN_RUNNING_UNPAUSED, | ||
4844 | 2991 | QEMU_ASYNC_JOB_NONE) < 0) { | ||
4845 | 2992 | VIR_WARN("Could not resume domain %s", vm->def->name); | ||
4846 | 2993 | } | ||
4847 | 2994 | } | ||
4848 | 2995 | break; | ||
4849 | 2996 | |||
4850 | 2997 | case QEMU_MIGRATION_PHASE_CONFIRM3: | ||
4851 | 2998 | /* migration completed, we need to kill the domain here */ | ||
4852 | 2999 | return -1; | ||
4853 | 3000 | } | ||
4854 | 3001 | } | ||
4855 | 3002 | |||
4856 | 3003 | return 0; | ||
4857 | 3004 | } | ||
4858 | 3005 | |||
4859 | 3006 | static int | ||
4860 | 3007 | qemuProcessRecoverJob(struct qemud_driver *driver, | ||
4861 | 3008 | virDomainObjPtr vm, | ||
4862 | 3009 | virConnectPtr conn, | ||
4863 | 3010 | const struct qemuDomainJobObj *job) | ||
4864 | 3011 | { | ||
4865 | 3012 | qemuDomainObjPrivatePtr priv = vm->privateData; | ||
4866 | 3013 | virDomainState state; | ||
4867 | 3014 | int reason; | ||
4868 | 3015 | |||
4869 | 3016 | state = virDomainObjGetState(vm, &reason); | ||
4870 | 3017 | |||
4871 | 3018 | switch (job->asyncJob) { | ||
4872 | 3019 | case QEMU_ASYNC_JOB_MIGRATION_OUT: | ||
4873 | 3020 | case QEMU_ASYNC_JOB_MIGRATION_IN: | ||
4874 | 3021 | if (qemuProcessRecoverMigration(driver, vm, conn, job->asyncJob, | ||
4875 | 3022 | job->phase, state, reason) < 0) | ||
4876 | 3023 | return -1; | ||
4877 | 3024 | break; | ||
4878 | 3025 | |||
4879 | 3026 | case QEMU_ASYNC_JOB_SAVE: | ||
4880 | 3027 | case QEMU_ASYNC_JOB_DUMP: | ||
4881 | 3028 | qemuDomainObjEnterMonitor(driver, vm); | ||
4882 | 3029 | ignore_value(qemuMonitorMigrateCancel(priv->mon)); | ||
4883 | 3030 | qemuDomainObjExitMonitor(driver, vm); | ||
4884 | 3031 | /* resume the domain but only if it was paused as a result of | ||
4885 | 3032 | * running save/dump operation. Although we are recovering an | ||
4886 | 3033 | * async job, this function is run at startup and must resume | ||
4887 | 3034 | * things using sync monitor connections. */ | ||
4888 | 3035 | if (state == VIR_DOMAIN_PAUSED && | ||
4889 | 3036 | ((job->asyncJob == QEMU_ASYNC_JOB_DUMP && | ||
4890 | 3037 | reason == VIR_DOMAIN_PAUSED_DUMP) || | ||
4891 | 3038 | (job->asyncJob == QEMU_ASYNC_JOB_SAVE && | ||
4892 | 3039 | reason == VIR_DOMAIN_PAUSED_SAVE) || | ||
4893 | 3040 | reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { | ||
4894 | 3041 | if (qemuProcessStartCPUs(driver, vm, conn, | ||
4895 | 3042 | VIR_DOMAIN_RUNNING_UNPAUSED, | ||
4896 | 3043 | QEMU_ASYNC_JOB_NONE) < 0) { | ||
4897 | 3044 | VIR_WARN("Could not resume domain %s after", vm->def->name); | ||
4898 | 3045 | } | ||
4899 | 3046 | } | ||
4900 | 3047 | break; | ||
4901 | 3048 | |||
4902 | 3049 | case QEMU_ASYNC_JOB_NONE: | ||
4903 | 3050 | case QEMU_ASYNC_JOB_LAST: | ||
4904 | 3051 | break; | ||
4905 | 3052 | } | ||
4906 | 3053 | |||
4907 | 3054 | if (!virDomainObjIsActive(vm)) | ||
4908 | 3055 | return -1; | ||
4909 | 3056 | |||
4910 | 3057 | /* In case any special handling is added for job type that has been ignored | ||
4911 | 3058 | * before, QEMU_DOMAIN_TRACK_JOBS (from qemu_domain.h) needs to be updated | ||
4912 | 3059 | * for the job to be properly tracked in domain state XML. | ||
4913 | 3060 | */ | ||
4914 | 3061 | switch (job->active) { | ||
4915 | 3062 | case QEMU_JOB_QUERY: | ||
4916 | 3063 | /* harmless */ | ||
4917 | 3064 | break; | ||
4918 | 3065 | |||
4919 | 3066 | case QEMU_JOB_DESTROY: | ||
4920 | 3067 | VIR_DEBUG("Domain %s should have already been destroyed", | ||
4921 | 3068 | vm->def->name); | ||
4922 | 3069 | return -1; | ||
4923 | 3070 | |||
4924 | 3071 | case QEMU_JOB_SUSPEND: | ||
4925 | 3072 | /* mostly harmless */ | ||
4926 | 3073 | break; | ||
4927 | 3074 | |||
4928 | 3075 | case QEMU_JOB_MODIFY: | ||
4929 | 3076 | /* XXX depending on the command we may be in an inconsistent state and | ||
4930 | 3077 | * we should probably fall back to "monitor error" state and refuse to | ||
4931 | 3078 | */ | ||
4932 | 3079 | break; | ||
4933 | 3080 | |||
4934 | 3081 | case QEMU_JOB_MIGRATION_OP: | ||
4935 | 3082 | case QEMU_JOB_ABORT: | ||
4936 | 3083 | case QEMU_JOB_ASYNC: | ||
4937 | 3084 | case QEMU_JOB_ASYNC_NESTED: | ||
4938 | 3085 | /* async job was already handled above */ | ||
4939 | 3086 | case QEMU_JOB_NONE: | ||
4940 | 3087 | case QEMU_JOB_LAST: | ||
4941 | 3088 | break; | ||
4942 | 3089 | } | ||
4943 | 3090 | |||
4944 | 3091 | return 0; | ||
4945 | 3092 | } | ||
4946 | 3093 | |||
4947 | 3094 | struct qemuProcessReconnectData { | ||
4948 | 3095 | virConnectPtr conn; | ||
4949 | 3096 | struct qemud_driver *driver; | ||
4950 | 3097 | void *payload; | ||
4951 | 3098 | struct qemuDomainJobObj oldjob; | ||
4952 | 3099 | }; | ||
4953 | 3100 | /* | ||
4954 | 3101 | * Open an existing VM's monitor, re-detect VCPU threads | ||
4955 | 3102 | * and re-reserve the security labels in use | ||
4956 | 3103 | * | ||
4957 | 3104 | * We own the virConnectPtr we are passed here - whoever started | ||
4958 | 3105 | * this thread function has increased the reference counter to it | ||
4959 | 3106 | * so that we now have to close it. | ||
4960 | 3107 | */ | ||
4961 | 3108 | static void | ||
4962 | 3109 | qemuProcessReconnect(void *opaque) | ||
4963 | 3110 | { | ||
4964 | 3111 | struct qemuProcessReconnectData *data = opaque; | ||
4965 | 3112 | struct qemud_driver *driver = data->driver; | ||
4966 | 3113 | virDomainObjPtr obj = data->payload; | ||
4967 | 3114 | qemuDomainObjPrivatePtr priv; | ||
4968 | 3115 | virConnectPtr conn = data->conn; | ||
4969 | 3116 | struct qemuDomainJobObj oldjob; | ||
4970 | 3117 | int state; | ||
4971 | 3118 | int reason; | ||
4972 | 3119 | |||
4973 | 3120 | memcpy(&oldjob, &data->oldjob, sizeof(oldjob)); | ||
4974 | 3121 | |||
4975 | 3122 | VIR_FREE(data); | ||
4976 | 3123 | |||
4977 | 3124 | qemuDriverLock(driver); | ||
4978 | 3125 | virDomainObjLock(obj); | ||
4979 | 3126 | |||
4980 | 3127 | |||
4981 | 3128 | VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name); | ||
4982 | 3129 | |||
4983 | 3130 | priv = obj->privateData; | ||
4984 | 3131 | |||
4985 | 3132 | /* Job was started by the caller for us */ | ||
4986 | 3133 | qemuDomainObjTransferJob(obj); | ||
4987 | 3134 | |||
4988 | 3135 | /* Hold an extra reference because we can't allow 'vm' to be | ||
4989 | 3136 | * deleted if qemuConnectMonitor() failed */ | ||
4990 | 3137 | virObjectRef(obj); | ||
4991 | 3138 | |||
4992 | 3139 | /* XXX check PID liveliness & EXE path */ | ||
4993 | 3140 | if (qemuConnectMonitor(driver, obj) < 0) | ||
4994 | 3141 | goto error; | ||
4995 | 3142 | |||
4996 | 3143 | /* Failure to connect to agent shouldn't be fatal */ | ||
4997 | 3144 | if (qemuConnectAgent(driver, obj) < 0) { | ||
4998 | 3145 | VIR_WARN("Cannot connect to QEMU guest agent for %s", | ||
4999 | 3146 | obj->def->name); | ||
5000 | 3147 | virResetLastError(); |