Merge lp:~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages into lp:ubuntu/raring/libvirt

Proposed by Serge Hallyn
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
Reviewer Review Type Date Requested Status
Jamie Strandboge Pending
Review via email: mp+138341@code.launchpad.net

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.

To post a comment you must log in.
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory '.pc/apparmor-allow-hugepages'
=== added file '.pc/apparmor-allow-hugepages/.timestamp'
=== added directory '.pc/apparmor-allow-hugepages/src'
=== added file '.pc/apparmor-allow-hugepages/src/libvirt_private.syms'
--- .pc/apparmor-allow-hugepages/src/libvirt_private.syms 1970-01-01 00:00:00 +0000
+++ .pc/apparmor-allow-hugepages/src/libvirt_private.syms 2012-12-11 20:02:29 +0000
@@ -0,0 +1,1840 @@
1#
2# General private symbols. Add symbols here, and see Makefile.am for
3# more details.
4#
5# Keep this file sorted by header name, then by symbols with each header.
6#
7
8# bitmap.h
9virBitmapClearAll;
10virBitmapClearBit;
11virBitmapCopy;
12virBitmapCountBits;
13virBitmapEqual;
14virBitmapFormat;
15virBitmapFree;
16virBitmapGetBit;
17virBitmapIsAllSet;
18virBitmapNew;
19virBitmapNewCopy;
20virBitmapNewData;
21virBitmapNextSetBit;
22virBitmapParse;
23virBitmapSetAll;
24virBitmapSetBit;
25virBitmapSize;
26virBitmapString;
27virBitmapToData;
28
29
30# buf.h
31virBufferAdd;
32virBufferAddChar;
33virBufferAdjustIndent;
34virBufferAsprintf;
35virBufferContentAndReset;
36virBufferCurrentContent;
37virBufferError;
38virBufferEscape;
39virBufferEscapeSexpr;
40virBufferEscapeShell;
41virBufferEscapeString;
42virBufferFreeAndReset;
43virBufferGetIndent;
44virBufferStrcat;
45virBufferTrim;
46virBufferURIEncodeString;
47virBufferUse;
48virBufferVasprintf;
49
50
51# caps.h
52virCapabilitiesAddGuest;
53virCapabilitiesAddGuestDomain;
54virCapabilitiesAddGuestFeature;
55virCapabilitiesAddHostFeature;
56virCapabilitiesAddHostMigrateTransport;
57virCapabilitiesAddHostNUMACell;
58virCapabilitiesAllocMachines;
59virCapabilitiesDefaultGuestArch;
60virCapabilitiesDefaultGuestEmulator;
61virCapabilitiesDefaultGuestMachine;
62virCapabilitiesFormatXML;
63virCapabilitiesFree;
64virCapabilitiesFreeMachines;
65virCapabilitiesFreeNUMAInfo;
66virCapabilitiesGenerateMac;
67virCapabilitiesIsEmulatorRequired;
68virCapabilitiesNew;
69virCapabilitiesSetEmulatorRequired;
70virCapabilitiesSetHostCPU;
71virCapabilitiesSetMacPrefix;
72
73
74# cgroup.h
75virCgroupAddTask;
76virCgroupAddTaskController;
77virCgroupAllowDevice;
78virCgroupAllowDeviceMajor;
79virCgroupAllowDevicePath;
80virCgroupControllerTypeFromString;
81virCgroupControllerTypeToString;
82virCgroupDenyAllDevices;
83virCgroupDenyDevice;
84virCgroupDenyDeviceMajor;
85virCgroupDenyDevicePath;
86virCgroupForDomain;
87virCgroupForDriver;
88virCgroupForEmulator;
89virCgroupForVcpu;
90virCgroupFree;
91virCgroupGetBlkioWeight;
92virCgroupGetCpuCfsPeriod;
93virCgroupGetCpuCfsQuota;
94virCgroupGetCpuShares;
95virCgroupGetCpuacctPercpuUsage;
96virCgroupGetCpuacctStat;
97virCgroupGetCpuacctUsage;
98virCgroupGetCpusetCpus;
99virCgroupGetCpusetMems;
100virCgroupGetFreezerState;
101virCgroupGetMemSwapHardLimit;
102virCgroupGetMemoryHardLimit;
103virCgroupGetMemorySoftLimit;
104virCgroupGetMemoryUsage;
105virCgroupKill;
106virCgroupKillPainfully;
107virCgroupKillRecursive;
108virCgroupMounted;
109virCgroupMoveTask;
110virCgroupPathOfController;
111virCgroupRemove;
112virCgroupSetBlkioDeviceWeight;
113virCgroupSetBlkioWeight;
114virCgroupSetCpuCfsPeriod;
115virCgroupSetCpuCfsQuota;
116virCgroupSetCpuShares;
117virCgroupSetCpusetCpus;
118virCgroupSetCpusetMems;
119virCgroupSetFreezerState;
120virCgroupSetMemSwapHardLimit;
121virCgroupSetMemory;
122virCgroupSetMemoryHardLimit;
123virCgroupSetMemorySoftLimit;
124
125
126# command.h
127virCommandAbort;
128virCommandAddArg;
129virCommandAddArgBuffer;
130virCommandAddArgFormat;
131virCommandAddArgList;
132virCommandAddArgPair;
133virCommandAddArgSet;
134virCommandAddEnvBuffer;
135virCommandAddEnvFormat;
136virCommandAddEnvPair;
137virCommandAddEnvPass;
138virCommandAddEnvPassCommon;
139virCommandAddEnvString;
140virCommandAllowCap;
141virCommandClearCaps;
142virCommandDaemonize;
143virCommandExec;
144virCommandFree;
145virCommandHandshakeNotify;
146virCommandHandshakeWait;
147virCommandNew;
148virCommandNewArgList;
149virCommandNewArgs;
150virCommandNonblockingFDs;
151virCommandPreserveFD;
152virCommandRequireHandshake;
153virCommandRun;
154virCommandRunAsync;
155virCommandSetErrorBuffer;
156virCommandSetErrorFD;
157virCommandSetInputBuffer;
158virCommandSetInputFD;
159virCommandSetOutputBuffer;
160virCommandSetOutputFD;
161virCommandSetPidFile;
162virCommandSetPreExecHook;
163virCommandSetWorkingDirectory;
164virCommandToString;
165virCommandTransferFD;
166virCommandWait;
167virCommandWriteArgLog;
168virFork;
169virRun;
170
171
172# conf.h
173virConfFree;
174virConfFreeValue;
175virConfGetValue;
176virConfNew;
177virConfReadFile;
178virConfReadMem;
179virConfSetValue;
180virConfWriteFile;
181virConfWriteMem;
182
183
184# cpu.h
185cpuBaseline;
186cpuBaselineXML;
187cpuCompare;
188cpuCompareXML;
189cpuDataFree;
190cpuDecode;
191cpuEncode;
192cpuGuestData;
193cpuHasFeature;
194cpuMapOverride;
195cpuNodeData;
196cpuUpdate;
197
198
199# cpu_conf.h
200virCPUDefAddFeature;
201virCPUDefCopy;
202virCPUDefCopyModel;
203virCPUDefFormat;
204virCPUDefFormatBuf;
205virCPUDefFree;
206virCPUDefFreeModel;
207virCPUDefParseXML;
208virCPUModeTypeToString;
209
210
211# datatypes.h
212virConnectClass;
213virDomainClass;
214virDomainSnapshotClass;
215virGetConnect;
216virGetDomain;
217virGetDomainSnapshot;
218virGetInterface;
219virGetNWFilter;
220virGetNetwork;
221virGetNodeDevice;
222virGetSecret;
223virGetStoragePool;
224virGetStorageVol;
225virGetStream;
226virInterfaceClass;
227virNetworkClass;
228virNodeDeviceClass;
229virNWFilterClass;
230virSecretClass;
231virStoragePoolClass;
232virStorageVolClass;
233virStreamClass;
234
235
236# device_conf.h
237virDeviceAddressPciMultiTypeFromString;
238virDeviceAddressPciMultiTypeToString;
239virDevicePCIAddressEqual;
240virDevicePCIAddressFormat;
241virDevicePCIAddressIsValid;
242virDevicePCIAddressParseXML;
243
244# dnsmasq.h
245dnsmasqAddDhcpHost;
246dnsmasqAddHost;
247dnsmasqContextFree;
248dnsmasqContextNew;
249dnsmasqDelete;
250dnsmasqReload;
251dnsmasqSave;
252
253
254# domain_audit.h
255virDomainAuditCgroup;
256virDomainAuditCgroupMajor;
257virDomainAuditCgroupPath;
258virDomainAuditDisk;
259virDomainAuditFS;
260virDomainAuditHostdev;
261virDomainAuditMemory;
262virDomainAuditNet;
263virDomainAuditNetDevice;
264virDomainAuditRedirdev;
265virDomainAuditSecurityLabel;
266virDomainAuditStart;
267virDomainAuditStop;
268virDomainAuditVcpu;
269
270
271# domain_conf.h
272virBlkioDeviceWeightArrayClear;
273virDiskNameToBusDeviceIndex;
274virDiskNameToIndex;
275virDomainActualNetDefFree;
276virDomainAssignDef;
277virDomainBlockedReasonTypeFromString;
278virDomainBlockedReasonTypeToString;
279virDomainBootMenuTypeFromString;
280virDomainBootMenuTypeToString;
281virDomainChrConsoleTargetTypeFromString;
282virDomainChrConsoleTargetTypeToString;
283virDomainChrDefForeach;
284virDomainChrDefFree;
285virDomainChrDefNew;
286virDomainChrSourceDefCopy;
287virDomainChrSourceDefFree;
288virDomainChrSpicevmcTypeFromString;
289virDomainChrSpicevmcTypeToString;
290virDomainChrTcpProtocolTypeFromString;
291virDomainChrTcpProtocolTypeToString;
292virDomainChrTypeFromString;
293virDomainChrTypeToString;
294virDomainClockBasisTypeToString;
295virDomainClockOffsetTypeFromString;
296virDomainClockOffsetTypeToString;
297virDomainConfigFile;
298virDomainControllerDefFree;
299virDomainControllerFind;
300virDomainControllerInsert;
301virDomainControllerInsertPreAlloced;
302virDomainControllerModelSCSITypeFromString;
303virDomainControllerModelSCSITypeToString;
304virDomainControllerModelUSBTypeFromString;
305virDomainControllerModelUSBTypeToString;
306virDomainControllerRemove;
307virDomainControllerTypeToString;
308virDomainCpuPlacementModeTypeFromString;
309virDomainCpuPlacementModeTypeToString;
310virDomainDefAddImplicitControllers;
311virDomainDefCheckABIStability;
312virDomainDefClearDeviceAliases;
313virDomainDefClearPCIAddresses;
314virDomainDefCompatibleDevice;
315virDomainDefFormat;
316virDomainDefFormatInternal;
317virDomainDefFree;
318virDomainDefGetSecurityLabelDef;
319virDomainDiskDefGetSecurityLabelDef;
320virDomainDefAddSecurityLabelDef;
321virDomainDefParseFile;
322virDomainDefParseNode;
323virDomainDefParseString;
324virDomainDeleteConfig;
325virDomainDeviceAddressIsValid;
326virDomainDeviceAddressTypeToString;
327virDomainDeviceDefCopy;
328virDomainDeviceDefFree;
329virDomainDeviceDefParse;
330virDomainDeviceInfoCopy;
331virDomainDeviceInfoIterate;
332virDomainDeviceTypeToString;
333virDomainDiskBusTypeToString;
334virDomainDiskCacheTypeFromString;
335virDomainDiskCacheTypeToString;
336virDomainDiskCopyOnReadTypeFromString;
337virDomainDiskCopyOnReadTypeToString;
338virDomainDiskDefAssignAddress;
339virDomainDiskDefForeachPath;
340virDomainDiskDefFree;
341virDomainDiskDeviceTypeToString;
342virDomainDiskErrorPolicyTypeFromString;
343virDomainDiskErrorPolicyTypeToString;
344virDomainDiskFindControllerModel;
345virDomainDiskGeometryTransTypeFromString;
346virDomainDiskGeometryTransTypeToString;
347virDomainDiskIndexByName;
348virDomainDiskInsert;
349virDomainDiskInsertPreAlloced;
350virDomainDiskIoTypeFromString;
351virDomainDiskIoTypeToString;
352virDomainDiskPathByName;
353virDomainDiskRemove;
354virDomainDiskRemoveByName;
355virDomainDiskTypeFromString;
356virDomainDiskTypeToString;
357virDomainEmulatorPinAdd;
358virDomainEmulatorPinDel;
359virDomainFSDefFree;
360virDomainFSIndexByName;
361virDomainFSTypeFromString;
362virDomainFSTypeToString;
363virDomainFSWrpolicyTypeFromString;
364virDomainFSWrpolicyTypeToString;
365virDomainFeatureStateTypeFromString;
366virDomainFeatureStateTypeToString;
367virDomainFindByID;
368virDomainFindByName;
369virDomainFindByUUID;
370virDomainGetRootFilesystem;
371virDomainGraphicsAuthConnectedTypeFromString;
372virDomainGraphicsAuthConnectedTypeToString;
373virDomainGraphicsDefFree;
374virDomainGraphicsListenGetAddress;
375virDomainGraphicsListenGetNetwork;
376virDomainGraphicsListenGetType;
377virDomainGraphicsListenSetAddress;
378virDomainGraphicsListenSetNetwork;
379virDomainGraphicsListenSetType;
380virDomainGraphicsSpiceChannelModeTypeFromString;
381virDomainGraphicsSpiceChannelModeTypeToString;
382virDomainGraphicsSpiceChannelNameTypeFromString;
383virDomainGraphicsSpiceChannelNameTypeToString;
384virDomainGraphicsSpiceClipboardCopypasteTypeFromString;
385virDomainGraphicsSpiceClipboardCopypasteTypeToString;
386virDomainGraphicsSpiceImageCompressionTypeFromString;
387virDomainGraphicsSpiceImageCompressionTypeToString;
388virDomainGraphicsSpiceJpegCompressionTypeFromString;
389virDomainGraphicsSpiceJpegCompressionTypeToString;
390virDomainGraphicsSpiceMouseModeTypeFromString;
391virDomainGraphicsSpiceMouseModeTypeToString;
392virDomainGraphicsSpicePlaybackCompressionTypeFromString;
393virDomainGraphicsSpicePlaybackCompressionTypeToString;
394virDomainGraphicsSpiceStreamingModeTypeFromString;
395virDomainGraphicsSpiceStreamingModeTypeToString;
396virDomainGraphicsSpiceZlibCompressionTypeFromString;
397virDomainGraphicsSpiceZlibCompressionTypeToString;
398virDomainGraphicsTypeFromString;
399virDomainGraphicsTypeToString;
400virDomainHasDiskMirror;
401virDomainHostdevDefAlloc;
402virDomainHostdevDefClear;
403virDomainHostdevDefFree;
404virDomainHostdevFind;
405virDomainHostdevInsert;
406virDomainHostdevModeTypeToString;
407virDomainHostdevRemove;
408virDomainHostdevSubsysTypeToString;
409virDomainHubTypeFromString;
410virDomainHubTypeToString;
411virDomainHypervTypeFromString;
412virDomainHypervTypeToString;
413virDomainInputDefFree;
414virDomainIoEventFdTypeFromString;
415virDomainIoEventFdTypeToString;
416virDomainLeaseDefFree;
417virDomainLeaseIndex;
418virDomainLeaseInsert;
419virDomainLeaseInsertPreAlloc;
420virDomainLeaseInsertPreAlloced;
421virDomainLeaseRemove;
422virDomainLeaseRemoveAt;
423virDomainLifecycleCrashTypeFromString;
424virDomainLifecycleCrashTypeToString;
425virDomainLifecycleTypeFromString;
426virDomainLifecycleTypeToString;
427virDomainList;
428virDomainLiveConfigHelperMethod;
429virDomainLoadAllConfigs;
430virDomainLockFailureTypeFromString;
431virDomainLockFailureTypeToString;
432virDomainLookupVcpuPin;
433virDomainMemballoonModelTypeFromString;
434virDomainMemballoonModelTypeToString;
435virDomainMemDumpTypeFromString;
436virDomainMemDumpTypeToString;
437virDomainNetDefFree;
438virDomainNetFind;
439virDomainNetFindIdx;
440virDomainNetGetActualBandwidth;
441virDomainNetGetActualBridgeName;
442virDomainNetGetActualDirectDev;
443virDomainNetGetActualDirectMode;
444virDomainNetGetActualHostdev;
445virDomainNetGetActualType;
446virDomainNetGetActualVirtPortProfile;
447virDomainNetGetActualVlan;
448virDomainNetInsert;
449virDomainNetRemove;
450virDomainNetTypeToString;
451virDomainNostateReasonTypeFromString;
452virDomainNostateReasonTypeToString;
453virDomainNumatuneMemModeTypeFromString;
454virDomainNumatuneMemModeTypeToString;
455virDomainNumatuneMemPlacementModeTypeFromString;
456virDomainNumatuneMemPlacementModeTypeToString;
457virDomainObjAssignDef;
458virDomainObjCopyPersistentDef;
459virDomainObjGetPersistentDef;
460virDomainObjGetState;
461virDomainObjIsDuplicate;
462virDomainObjListDeinit;
463virDomainObjListGetActiveIDs;
464virDomainObjListGetInactiveNames;
465virDomainObjListInit;
466virDomainObjListNumOfDomains;
467virDomainObjLock;
468virDomainObjNew;
469virDomainObjSetDefTransient;
470virDomainObjSetState;
471virDomainObjTaint;
472virDomainObjUnlock;
473virDomainPausedReasonTypeFromString;
474virDomainPausedReasonTypeToString;
475virDomainPciRombarModeTypeFromString;
476virDomainPciRombarModeTypeToString;
477virDomainPMStateTypeFromString;
478virDomainPMStateTypeToString;
479virDomainRedirdevBusTypeFromString;
480virDomainRedirdevBusTypeToString;
481virDomainRemoveInactive;
482virDomainRunningReasonTypeFromString;
483virDomainRunningReasonTypeToString;
484virDomainSaveConfig;
485virDomainSaveStatus;
486virDomainSaveXML;
487virDomainSeclabelTypeFromString;
488virDomainSeclabelTypeToString;
489virDomainShutdownReasonTypeFromString;
490virDomainShutdownReasonTypeToString;
491virDomainShutoffReasonTypeFromString;
492virDomainShutoffReasonTypeToString;
493virDomainSmartcardDefForeach;
494virDomainSmartcardDefFree;
495virDomainSmartcardTypeFromString;
496virDomainSmartcardTypeToString;
497virDomainSmbiosModeTypeFromString;
498virDomainSmbiosModeTypeToString;
499virDomainSoundDefFree;
500virDomainSoundModelTypeFromString;
501virDomainSoundModelTypeToString;
502virDomainStartupPolicyTypeFromString;
503virDomainStartupPolicyTypeToString;
504virDomainStateReasonFromString;
505virDomainStateReasonToString;
506virDomainStateTypeFromString;
507virDomainStateTypeToString;
508virDomainTaintTypeFromString;
509virDomainTaintTypeToString;
510virDomainTimerModeTypeFromString;
511virDomainTimerModeTypeToString;
512virDomainTimerNameTypeFromString;
513virDomainTimerNameTypeToString;
514virDomainTimerTickpolicyTypeFromString;
515virDomainTimerTickpolicyTypeToString;
516virDomainTimerTrackTypeFromString;
517virDomainTimerTrackTypeToString;
518virDomainVcpuPinAdd;
519virDomainVcpuPinDefArrayFree;
520virDomainVcpuPinDefCopy;
521virDomainVcpuPinDefFree;
522virDomainVcpuPinDel;
523virDomainVcpuPinFindByVcpu;
524virDomainVcpuPinIsDuplicate;
525virDomainVideoDefFree;
526virDomainVideoDefaultRAM;
527virDomainVideoDefaultType;
528virDomainVideoTypeFromString;
529virDomainVideoTypeToString;
530virDomainVirtTypeToString;
531virDomainVirtioEventIdxTypeFromString;
532virDomainVirtioEventIdxTypeToString;
533virDomainWatchdogActionTypeFromString;
534virDomainWatchdogActionTypeToString;
535virDomainWatchdogModelTypeFromString;
536virDomainWatchdogModelTypeToString;
537
538
539# domain_event.h
540virDomainEventBalloonChangeNewFromDom;
541virDomainEventBalloonChangeNewFromObj;
542virDomainEventBlockJobNewFromObj;
543virDomainEventBlockJobNewFromDom;
544virDomainEventControlErrorNewFromDom;
545virDomainEventControlErrorNewFromObj;
546virDomainEventDiskChangeNewFromDom;
547virDomainEventDiskChangeNewFromObj;
548virDomainEventFree;
549virDomainEventGraphicsNewFromDom;
550virDomainEventGraphicsNewFromObj;
551virDomainEventIOErrorNewFromDom;
552virDomainEventIOErrorNewFromObj;
553virDomainEventIOErrorReasonNewFromDom;
554virDomainEventIOErrorReasonNewFromObj;
555virDomainEventNew;
556virDomainEventNewFromDef;
557virDomainEventNewFromDom;
558virDomainEventNewFromObj;
559virDomainEventPMSuspendNewFromDom;
560virDomainEventPMSuspendNewFromObj;
561virDomainEventPMWakeupNewFromDom;
562virDomainEventPMWakeupNewFromObj;
563virDomainEventRTCChangeNewFromDom;
564virDomainEventRTCChangeNewFromObj;
565virDomainEventRebootNew;
566virDomainEventRebootNewFromDom;
567virDomainEventRebootNewFromObj;
568virDomainEventStateDeregister;
569virDomainEventStateDeregisterID;
570virDomainEventStateEventID;
571virDomainEventStateRegister;
572virDomainEventStateRegisterID;
573virDomainEventStateFree;
574virDomainEventStateNew;
575virDomainEventStateQueue;
576virDomainEventPMSuspendDiskNewFromDom;
577virDomainEventPMSuspendDiskNewFromObj;
578virDomainEventTrayChangeNewFromDom;
579virDomainEventTrayChangeNewFromObj;
580virDomainEventWatchdogNewFromDom;
581virDomainEventWatchdogNewFromObj;
582
583
584# domain_lock.h
585virDomainLockProcessStart;
586virDomainLockProcessInquire;
587virDomainLockProcessPause;
588virDomainLockProcessResume;
589virDomainLockDiskAttach;
590virDomainLockDiskDetach;
591virDomainLockLeaseAttach;
592virDomainLockLeaseDetach;
593
594
595# domain_nwfilter.h
596virDomainConfNWFilterInstantiate;
597virDomainConfNWFilterRegister;
598virDomainConfNWFilterTeardown;
599virDomainConfVMNWFilterTeardown;
600
601
602# ebtables.h
603ebtablesAddForwardAllowIn;
604ebtablesAddForwardPolicyReject;
605ebtablesContextFree;
606ebtablesContextNew;
607ebtablesRemoveForwardAllowIn;
608
609
610# event_poll.h
611virEventPollAddHandle;
612virEventPollAddTimeout;
613virEventPollFromNativeEvents;
614virEventPollInit;
615virEventPollRemoveHandle;
616virEventPollRemoveTimeout;
617virEventPollRunOnce;
618virEventPollToNativeEvents;
619virEventPollUpdateHandle;
620virEventPollUpdateTimeout;
621
622
623# fdstream.h
624virFDStreamOpen;
625virFDStreamConnectUNIX;
626virFDStreamOpenFile;
627virFDStreamCreateFile;
628
629
630# hash.h
631virHashAddEntry;
632virHashCreate;
633virHashEqual;
634virHashForEach;
635virHashFree;
636virHashGetItems;
637virHashLookup;
638virHashRemoveAll;
639virHashRemoveEntry;
640virHashRemoveSet;
641virHashSearch;
642virHashSize;
643virHashSteal;
644virHashTableSize;
645virHashUpdateEntry;
646
647
648# hooks.h
649virHookCall;
650virHookInitialize;
651virHookPresent;
652
653
654# interface_conf.h
655virInterfaceAssignDef;
656virInterfaceDefFormat;
657virInterfaceDefFree;
658virInterfaceDefParseFile;
659virInterfaceDefParseNode;
660virInterfaceDefParseString;
661virInterfaceFindByMACString;
662virInterfaceFindByName;
663virInterfaceObjListClone;
664virInterfaceObjListFree;
665virInterfaceObjLock;
666virInterfaceObjUnlock;
667virInterfaceRemove;
668
669
670# iptables.h
671iptablesAddForwardAllowCross;
672iptablesAddForwardAllowIn;
673iptablesAddForwardAllowOut;
674iptablesAddForwardAllowRelatedIn;
675iptablesAddForwardMasquerade;
676iptablesAddForwardRejectIn;
677iptablesAddForwardRejectOut;
678iptablesAddOutputFixUdpChecksum;
679iptablesAddTcpInput;
680iptablesAddUdpInput;
681iptablesContextFree;
682iptablesContextNew;
683iptablesRemoveForwardAllowCross;
684iptablesRemoveForwardAllowIn;
685iptablesRemoveForwardAllowOut;
686iptablesRemoveForwardAllowRelatedIn;
687iptablesRemoveForwardMasquerade;
688iptablesRemoveForwardRejectIn;
689iptablesRemoveForwardRejectOut;
690iptablesRemoveOutputFixUdpChecksum;
691iptablesRemoveTcpInput;
692iptablesRemoveUdpInput;
693
694
695# json.h
696virJSONValueArrayAppend;
697virJSONValueArrayGet;
698virJSONValueArraySize;
699virJSONValueFree;
700virJSONValueFromString;
701virJSONValueGetBoolean;
702virJSONValueGetNumberDouble;
703virJSONValueGetNumberInt;
704virJSONValueGetNumberLong;
705virJSONValueGetNumberUint;
706virJSONValueGetNumberUlong;
707virJSONValueGetString;
708virJSONValueIsNull;
709virJSONValueNewArray;
710virJSONValueNewBoolean;
711virJSONValueNewNull;
712virJSONValueNewNumberDouble;
713virJSONValueNewNumberInt;
714virJSONValueNewNumberLong;
715virJSONValueNewNumberUint;
716virJSONValueNewNumberUlong;
717virJSONValueNewObject;
718virJSONValueNewString;
719virJSONValueNewStringLen;
720virJSONValueObjectAppend;
721virJSONValueObjectAppendBoolean;
722virJSONValueObjectAppendNull;
723virJSONValueObjectAppendNumberDouble;
724virJSONValueObjectAppendNumberInt;
725virJSONValueObjectAppendNumberLong;
726virJSONValueObjectAppendNumberUint;
727virJSONValueObjectAppendNumberUlong;
728virJSONValueObjectAppendString;
729virJSONValueObjectGet;
730virJSONValueObjectGetBoolean;
731virJSONValueObjectGetKey;
732virJSONValueObjectGetNumberDouble;
733virJSONValueObjectGetNumberInt;
734virJSONValueObjectGetNumberLong;
735virJSONValueObjectGetNumberUint;
736virJSONValueObjectGetNumberUlong;
737virJSONValueObjectGetString;
738virJSONValueObjectGetValue;
739virJSONValueObjectHasKey;
740virJSONValueObjectIsNull;
741virJSONValueObjectKeysNumber;
742virJSONValueToString;
743
744
745# libvirt_internal.h
746virDomainMigrateFinish2;
747virDomainMigrateFinish;
748virDomainMigratePerform;
749virDomainMigratePrepare2;
750virDomainMigratePrepare;
751virDomainMigratePrepareTunnel;
752virDomainMigrateBegin3;
753virDomainMigratePrepare3;
754virDomainMigratePrepareTunnel3;
755virDomainMigratePerform3;
756virDomainMigrateFinish3;
757virDomainMigrateConfirm3;
758virDrvSupportsFeature;
759virRegisterDeviceMonitor;
760virRegisterDriver;
761virRegisterInterfaceDriver;
762virRegisterNWFilterDriver;
763virRegisterNetworkDriver;
764virRegisterSecretDriver;
765virRegisterStorageDriver;
766
767
768# locking.h
769virLockManagerAcquire;
770virLockManagerAddResource;
771virLockManagerFree;
772virLockManagerInquire;
773virLockManagerNew;
774virLockManagerPluginNew;
775virLockManagerPluginRef;
776virLockManagerPluginUnref;
777virLockManagerPluginUsesState;
778virLockManagerPluginGetName;
779virLockManagerRelease;
780virLockManagerSetPluginDir;
781
782
783# logging.h
784virLogDefineFilter;
785virLogDefineOutput;
786virLogEmergencyDumpAll;
787virLogGetDefaultPriority;
788virLogGetFilters;
789virLogGetNbFilters;
790virLogGetNbOutputs;
791virLogGetOutputs;
792virLogLock;
793virLogMessage;
794virLogParseDefaultPriority;
795virLogParseFilters;
796virLogParseOutputs;
797virLogReset;
798virLogSetBufferSize;
799virLogSetDefaultPriority;
800virLogSetFromEnv;
801virLogUnlock;
802
803
804# memory.h
805virAlloc;
806virAllocN;
807virAllocVar;
808virExpandN;
809virFree;
810virReallocN;
811virResizeN;
812virShrinkN;
813
814
815# netdev_bandwidth_conf.h
816virNetDevBandwidthFormat;
817virNetDevBandwidthParse;
818
819
820#netdev_vlan_conf.h
821virNetDevVlanFormat;
822virNetDevVlanParse;
823
824
825# netdev_vportprofile_conf.h
826virNetDevVPortProfileFormat;
827virNetDevVPortProfileParse;
828virNetDevVPortTypeFromString;
829virNetDevVPortTypeToString;
830
831
832# network_conf.h
833virNetworkAssignDef;
834virNetworkConfigFile;
835virNetworkConfigChangeSetup;
836virNetworkDefCopy;
837virNetworkDefFormat;
838virNetworkDefFree;
839virNetworkDefGetIpByIndex;
840virNetworkDefParseFile;
841virNetworkDefParseNode;
842virNetworkDefParseString;
843virNetworkDeleteConfig;
844virNetworkFindByName;
845virNetworkFindByUUID;
846virNetworkIpDefNetmask;
847virNetworkIpDefPrefix;
848virNetworkList;
849virNetworkLoadAllConfigs;
850virNetworkObjAssignDef;
851virNetworkObjFree;
852virNetworkObjGetPersistentDef;
853virNetworkObjIsDuplicate;
854virNetworkObjListFree;
855virNetworkObjLock;
856virNetworkObjReplacePersistentDef;
857virNetworkObjSetDefTransient;
858virNetworkObjUnlock;
859virNetworkObjUnsetDefTransient;
860virNetworkObjUpdate;
861virNetworkRemoveInactive;
862virNetworkSaveConfig;
863virNetworkSaveStatus;
864virNetworkSetBridgeMacAddr;
865virNetworkSetBridgeName;
866virPortGroupFindByName;
867
868
869# node_device_conf.h
870virNodeDevCapTypeFromString;
871virNodeDevCapTypeToString;
872virNodeDevCapsDefFree;
873virNodeDeviceAssignDef;
874virNodeDeviceDefFormat;
875virNodeDeviceDefFree;
876virNodeDeviceDefParseFile;
877virNodeDeviceDefParseNode;
878virNodeDeviceDefParseString;
879virNodeDeviceFindByName;
880virNodeDeviceFindBySysfsPath;
881virNodeDeviceGetParentHost;
882virNodeDeviceGetWWNs;
883virNodeDeviceHasCap;
884virNodeDeviceList;
885virNodeDeviceObjListFree;
886virNodeDeviceObjLock;
887virNodeDeviceObjRemove;
888virNodeDeviceObjUnlock;
889
890
891# nodeinfo.h
892nodeCapsInitNUMA;
893nodeGetCPUBitmap;
894nodeGetCPUCount;
895nodeGetCPUMap;
896nodeGetCPUStats;
897nodeGetCellsFreeMemory;
898nodeGetFreeMemory;
899nodeGetInfo;
900nodeGetMemoryParameters;
901nodeGetMemoryStats;
902nodeSetMemoryParameters;
903
904
905# nwfilter_conf.h
906virNWFilterCallbackDriversLock;
907virNWFilterCallbackDriversUnlock;
908virNWFilterChainSuffixTypeToString;
909virNWFilterConfLayerInit;
910virNWFilterConfLayerShutdown;
911virNWFilterDefFormat;
912virNWFilterDefFree;
913virNWFilterDefParseString;
914virNWFilterInstFiltersOnAllVMs;
915virNWFilterJumpTargetTypeToString;
916virNWFilterLoadAllConfigs;
917virNWFilterLockFilterUpdates;
918virNWFilterObjAssignDef;
919virNWFilterObjDeleteDef;
920virNWFilterObjFindByName;
921virNWFilterObjFindByUUID;
922virNWFilterObjListFree;
923virNWFilterObjLock;
924virNWFilterObjRemove;
925virNWFilterObjSaveDef;
926virNWFilterObjUnlock;
927virNWFilterPrintStateMatchFlags;
928virNWFilterPrintTCPFlags;
929virNWFilterRegisterCallbackDriver;
930virNWFilterRuleActionTypeToString;
931virNWFilterRuleDirectionTypeToString;
932virNWFilterRuleProtocolTypeToString;
933virNWFilterTestUnassignDef;
934virNWFilterUnRegisterCallbackDriver;
935virNWFilterUnlockFilterUpdates;
936
937
938# nwfilter_ipaddrmap
939virNWFilterIPAddrMapAddIPAddr;
940virNWFilterIPAddrMapDelIPAddr;
941virNWFilterIPAddrMapGetIPAddr;
942virNWFilterIPAddrMapInit;
943virNWFilterIPAddrMapShutdown;
944
945
946# nwfilter_params.h
947virNWFilterHashTableCreate;
948virNWFilterHashTableFree;
949virNWFilterHashTablePut;
950virNWFilterHashTablePutAll;
951virNWFilterHashTableRemoveEntry;
952virNWFilterVarAccessGetVarName;
953virNWFilterVarAccessIsAvailable;
954virNWFilterVarAccessPrint;
955virNWFilterVarCombIterCreate;
956virNWFilterVarCombIterFree;
957virNWFilterVarCombIterGetVarValue;
958virNWFilterVarCombIterNext;
959virNWFilterVarValueAddValue;
960virNWFilterVarValueCopy;
961virNWFilterVarValueCreateSimple;
962virNWFilterVarValueCreateSimpleCopyValue;
963virNWFilterVarValueDelValue;
964virNWFilterVarValueFree;
965virNWFilterVarValueGetCardinality;
966virNWFilterVarValueGetNthValue;
967virNWFilterVarValueGetSimple;
968
969
970# pci.h
971pciConfigAddressToSysfsFile;
972pciDettachDevice;
973pciDeviceFileIterate;
974pciDeviceGetManaged;
975pciDeviceGetName;
976pciDeviceGetRemoveSlot;
977pciDeviceGetReprobe;
978pciDeviceGetUnbindFromStub;
979pciDeviceGetUsedBy;
980pciDeviceGetVirtualFunctionInfo;
981pciDeviceIsAssignable;
982pciDeviceIsVirtualFunction;
983pciDeviceListAdd;
984pciDeviceListCount;
985pciDeviceListDel;
986pciDeviceListFind;
987pciDeviceListFree;
988pciDeviceListGet;
989pciDeviceListNew;
990pciDeviceListSteal;
991pciDeviceNetName;
992pciDeviceReAttachInit;
993pciDeviceSetManaged;
994pciDeviceSetRemoveSlot;
995pciDeviceSetReprobe;
996pciDeviceSetUnbindFromStub;
997pciDeviceSetUsedBy;
998pciFreeDevice;
999pciGetDevice;
1000pciGetPhysicalFunction;
1001pciGetVirtualFunctionIndex;
1002pciGetVirtualFunctions;
1003pciReAttachDevice;
1004pciResetDevice;
1005pciWaitForDeviceCleanup;
1006
1007
1008# processinfo.h
1009virProcessInfoGetAffinity;
1010virProcessInfoSetAffinity;
1011
1012
1013# secret_conf.h
1014virSecretDefFormat;
1015virSecretDefFree;
1016virSecretDefParseFile;
1017virSecretDefParseString;
1018virSecretUsageTypeTypeFromString;
1019virSecretUsageTypeTypeToString;
1020
1021
1022# security_driver.h
1023virSecurityDriverLookup;
1024
1025
1026# security_manager.h
1027virSecurityManagerClearSocketLabel;
1028virSecurityManagerFree;
1029virSecurityManagerGenLabel;
1030virSecurityManagerGetDOI;
1031virSecurityManagerGetModel;
1032virSecurityManagerGetNested;
1033virSecurityManagerGetProcessLabel;
1034virSecurityManagerNew;
1035virSecurityManagerNewStack;
1036virSecurityManagerNewDAC;
1037virSecurityManagerReleaseLabel;
1038virSecurityManagerReserveLabel;
1039virSecurityManagerRestoreImageLabel;
1040virSecurityManagerRestoreAllLabel;
1041virSecurityManagerRestoreHostdevLabel;
1042virSecurityManagerRestoreSavedStateLabel;
1043virSecurityManagerSetAllLabel;
1044virSecurityManagerSetDaemonSocketLabel;
1045virSecurityManagerSetImageFDLabel;
1046virSecurityManagerSetImageLabel;
1047virSecurityManagerSetHostdevLabel;
1048virSecurityManagerSetProcessLabel;
1049virSecurityManagerSetSavedStateLabel;
1050virSecurityManagerSetSocketLabel;
1051virSecurityManagerSetTapFDLabel;
1052virSecurityManagerStackAddNested;
1053virSecurityManagerVerify;
1054virSecurityManagerGetMountOptions;
1055
1056# sexpr.h
1057sexpr_append;
1058sexpr_cons;
1059sexpr_float;
1060sexpr_fmt_node;
1061sexpr_free;
1062sexpr_has;
1063sexpr_int;
1064sexpr_lookup;
1065sexpr_nil;
1066sexpr_node;
1067sexpr_node_copy;
1068sexpr_string;
1069sexpr_u64;
1070sexpr2string;
1071string2sexpr;
1072
1073
1074# snapshot_conf.h
1075virDomainListSnapshots;
1076virDomainSnapshotAlignDisks;
1077virDomainSnapshotAssignDef;
1078virDomainSnapshotDefFormat;
1079virDomainSnapshotDefFree;
1080virDomainSnapshotDefParseString;
1081virDomainSnapshotDropParent;
1082virDomainSnapshotFindByName;
1083virDomainSnapshotForEach;
1084virDomainSnapshotForEachChild;
1085virDomainSnapshotForEachDescendant;
1086virDomainSnapshotLocationTypeFromString;
1087virDomainSnapshotLocationTypeToString;
1088virDomainSnapshotObjListGetNames;
1089virDomainSnapshotObjListNum;
1090virDomainSnapshotObjListRemove;
1091virDomainSnapshotStateTypeFromString;
1092virDomainSnapshotStateTypeToString;
1093virDomainSnapshotUpdateRelations;
1094
1095
1096# storage_conf.h
1097virStoragePartedFsTypeTypeToString;
1098virStoragePoolDefFormat;
1099virStoragePoolDefFree;
1100virStoragePoolDefParseFile;
1101virStoragePoolDefParseNode;
1102virStoragePoolDefParseSourceString;
1103virStoragePoolDefParseString;
1104virStoragePoolFormatDiskTypeToString;
1105virStoragePoolFormatFileSystemNetTypeToString;
1106virStoragePoolFormatFileSystemTypeToString;
1107virStoragePoolList;
1108virStoragePoolLoadAllConfigs;
1109virStoragePoolObjAssignDef;
1110virStoragePoolObjClearVols;
1111virStoragePoolObjDeleteDef;
1112virStoragePoolObjFindByName;
1113virStoragePoolObjFindByUUID;
1114virStoragePoolObjIsDuplicate;
1115virStoragePoolObjListFree;
1116virStoragePoolObjLock;
1117virStoragePoolObjRemove;
1118virStoragePoolObjSaveDef;
1119virStoragePoolObjUnlock;
1120virStoragePoolSourceClear;
1121virStoragePoolSourceFindDuplicate;
1122virStoragePoolSourceFindDuplicateDevices;
1123virStoragePoolSourceFree;
1124virStoragePoolSourceListFormat;
1125virStoragePoolSourceListNewSource;
1126virStoragePoolTypeFromString;
1127virStorageVolDefFindByKey;
1128virStorageVolDefFindByName;
1129virStorageVolDefFindByPath;
1130virStorageVolDefFormat;
1131virStorageVolDefFree;
1132virStorageVolDefParseFile;
1133virStorageVolDefParseNode;
1134virStorageVolDefParseString;
1135
1136
1137# storage_encryption_conf.h
1138virStorageEncryptionFormat;
1139virStorageEncryptionFree;
1140virStorageEncryptionParseNode;
1141virStorageGenerateQcowPassphrase;
1142
1143
1144# storage_file.h
1145virStorageFileChainLookup;
1146virStorageFileFormatTypeFromString;
1147virStorageFileFormatTypeToString;
1148virStorageFileFreeMetadata;
1149virStorageFileGetMetadata;
1150virStorageFileGetMetadataFromFD;
1151virStorageFileIsClusterFS;
1152virStorageFileIsSharedFS;
1153virStorageFileIsSharedFSType;
1154virStorageFileProbeFormat;
1155virStorageFileProbeFormatFromFD;
1156virStorageFileResize;
1157
1158# sysinfo.h
1159virSysinfoDefFree;
1160virSysinfoFormat;
1161virSysinfoRead;
1162
1163
1164# threadpool.h
1165virThreadPoolFree;
1166virThreadPoolNew;
1167virThreadPoolSendJob;
1168virThreadPoolGetMinWorkers;
1169virThreadPoolGetMaxWorkers;
1170virThreadPoolGetPriorityWorkers;
1171
1172
1173# threads.h
1174virCondBroadcast;
1175virCondDestroy;
1176virCondInit;
1177virCondSignal;
1178virCondWait;
1179virCondWaitUntil;
1180virMutexDestroy;
1181virMutexInit;
1182virMutexInitRecursive;
1183virMutexLock;
1184virMutexUnlock;
1185virOnce;
1186virThreadCreate;
1187virThreadID;
1188virThreadInitialize;
1189virThreadIsSelf;
1190virThreadJoin;
1191virThreadSelf;
1192virThreadSelfID;
1193
1194
1195# usb.h
1196usbDeviceFileIterate;
1197usbDeviceGetBus;
1198usbDeviceGetDevno;
1199usbDeviceGetName;
1200usbDeviceGetUsedBy;
1201usbDeviceListAdd;
1202usbDeviceListCount;
1203usbDeviceListDel;
1204usbDeviceListFind;
1205usbDeviceListFree;
1206usbDeviceListGet;
1207usbDeviceListNew;
1208usbDeviceListSteal;
1209usbDeviceSetUsedBy;
1210usbFindDevice;
1211usbFindDeviceByBus;
1212usbFindDeviceByVendor;
1213usbFreeDevice;
1214usbGetDevice;
1215
1216
1217# util.h
1218saferead;
1219safewrite;
1220safezero;
1221virArgvToString;
1222virAsprintf;
1223virBuildPathInternal;
1224virDirCreate;
1225virDoubleToStr;
1226virEnumFromString;
1227virEnumToString;
1228virFileAbsPath;
1229virFileAccessibleAs;
1230virFileBuildPath;
1231virFileExists;
1232virFileFindMountPoint;
1233virFileHasSuffix;
1234virFileIsAbsPath;
1235virFileIsExecutable;
1236virFileIsLink;
1237virFileIsDir;
1238virFileLinkPointsTo;
1239virFileLock;
1240virFileMakePath;
1241virFileMakePathWithMode;
1242virFileMatchesNameSuffix;
1243virFileOpenAs;
1244virFileOpenTty;
1245virFileReadAll;
1246virFileReadLimFD;
1247virFileResolveAllLinks;
1248virFileResolveLink;
1249virFileSanitizePath;
1250virFileSkipRoot;
1251virFileStripSuffix;
1252virFileUnlock;
1253virFileWaitForDevices;
1254virFileWriteStr;
1255virFindFileInPath;
1256virFormatIntDecimal;
1257virGetGroupID;
1258virGetGroupName;
1259virGetHostname;
1260virGetUserDirectory;
1261virGetUserConfigDirectory;
1262virGetUserCacheDirectory;
1263virGetUserRuntimeDirectory;
1264virGetUserID;
1265virGetUserName;
1266virHexToBin;
1267virIndexToDiskName;
1268virIsDevMapperDevice;
1269virParseNumber;
1270virParseVersionString;
1271virPipeReadUntilEOF;
1272virScaleInteger;
1273virSetBlocking;
1274virSetCloseExec;
1275virSetInherit;
1276virSetNonBlock;
1277virSetUIDGID;
1278virSkipSpaces;
1279virSkipSpacesAndBackslash;
1280virSkipSpacesBackwards;
1281virStrToDouble;
1282virStrToLong_i;
1283virStrToLong_l;
1284virStrToLong_ll;
1285virStrToLong_ui;
1286virStrToLong_ul;
1287virStrToLong_ull;
1288virStrcpy;
1289virStrncpy;
1290virTrimSpaces;
1291virValidateWWN;
1292virVasprintf;
1293
1294
1295# uuid.h
1296virGetHostUUID;
1297virSetHostUUIDStr;
1298virUUIDFormat;
1299virUUIDGenerate;
1300virUUIDIsValid;
1301virUUIDParse;
1302
1303
1304# virauth.h
1305virAuthGetConfigFilePath;
1306virAuthGetPassword;
1307virAuthGetUsername;
1308
1309
1310# virauthconfig.h
1311virAuthConfigFree;
1312virAuthConfigLookup;
1313virAuthConfigNew;
1314virAuthConfigNewData;
1315
1316
1317# viraudit.h
1318virAuditClose;
1319virAuditEncode;
1320virAuditLog;
1321virAuditOpen;
1322virAuditSend;
1323
1324
1325# virconsole.h
1326virConsoleAlloc;
1327virConsoleFree;
1328virConsoleOpen;
1329
1330
1331# virdbus.h
1332virDBusGetSystemBus;
1333
1334
1335# virfile.h
1336virFileLoopDeviceAssociate;
1337virFileClose;
1338virFileDirectFdFlag;
1339virFileWrapperFdCatchError;
1340virFileWrapperFdClose;
1341virFileWrapperFdFree;
1342virFileWrapperFdNew;
1343virFileFclose;
1344virFileFdopen;
1345virFileRewrite;
1346virFileTouch;
1347virFileUpdatePerm;
1348
1349
1350# virkeycode.h
1351virKeycodeSetTypeFromString;
1352virKeycodeSetTypeToString;
1353virKeycodeValueFromString;
1354virKeycodeValueTranslate;
1355
1356
1357# virkeyfile.h
1358virKeyFileNew;
1359virKeyFileLoadFile;
1360virKeyFileLoadData;
1361virKeyFileFree;
1362virKeyFileHasValue;
1363virKeyFileHasGroup;
1364virKeyFileGetValueString;
1365
1366
1367# virlockspace.h
1368virLockSpaceAcquireResource;
1369virLockSpaceCreateResource;
1370virLockSpaceDeleteResource;
1371virLockSpaceFree;
1372virLockSpaceGetDirectory;
1373virLockSpaceNew;
1374virLockSpaceNewPostExecRestart;
1375virLockSpacePreExecRestart;
1376virLockSpaceReleaseResource;
1377virLockSpaceReleaseResourcesForOwner;
1378
1379
1380# virmacaddr.h
1381virMacAddrCmp;
1382virMacAddrCmpRaw;
1383virMacAddrCompare;
1384virMacAddrFormat;
1385virMacAddrGenerate;
1386virMacAddrGetRaw;
1387virMacAddrIsBroadcastRaw;
1388virMacAddrIsMulticast;
1389virMacAddrIsUnicast;
1390virMacAddrParse;
1391virMacAddrSet;
1392virMacAddrSetRaw;
1393
1394
1395# virnetclient.h
1396virNetClientAddProgram;
1397virNetClientAddStream;
1398virNetClientClose;
1399virNetClientDupFD;
1400virNetClientGetFD;
1401virNetClientGetTLSKeySize;
1402virNetClientHasPassFD;
1403virNetClientIsEncrypted;
1404virNetClientIsOpen;
1405virNetClientKeepAliveIsSupported;
1406virNetClientKeepAliveStart;
1407virNetClientKeepAliveStop;
1408virNetClientLocalAddrString;
1409virNetClientNewExternal;
1410virNetClientNewLibSSH2;
1411virNetClientNewSSH;
1412virNetClientNewTCP;
1413virNetClientNewUNIX;
1414virNetClientRegisterAsyncIO;
1415virNetClientRegisterKeepAlive;
1416virNetClientRemoteAddrString;
1417virNetClientRemoveStream;
1418virNetClientSendNoReply;
1419virNetClientSendNonBlock;
1420virNetClientSendWithReply;
1421virNetClientSendWithReplyStream;
1422virNetClientSetCloseCallback;
1423virNetClientSetTLSSession;
1424
1425
1426# virnetclientprogram.h
1427virNetClientProgramCall;
1428virNetClientProgramDispatch;
1429virNetClientProgramGetProgram;
1430virNetClientProgramGetVersion;
1431virNetClientProgramMatches;
1432virNetClientProgramNew;
1433
1434
1435# virnetclientstream.h
1436virNetClientStreamEOF;
1437virNetClientStreamEventAddCallback;
1438virNetClientStreamEventRemoveCallback;
1439virNetClientStreamEventUpdateCallback;
1440virNetClientStreamMatches;
1441virNetClientStreamNew;
1442virNetClientStreamQueuePacket;
1443virNetClientStreamRaiseError;
1444virNetClientStreamRecvPacket;
1445virNetClientStreamSendPacket;
1446virNetClientStreamSetError;
1447
1448
1449# virnetdev.h
1450virNetDevClearIPv4Address;
1451virNetDevExists;
1452virNetDevGetIPv4Address;
1453virNetDevGetIndex;
1454virNetDevGetMAC;
1455virNetDevGetMTU;
1456virNetDevGetPhysicalFunction;
1457virNetDevGetVLanID;
1458virNetDevGetVirtualFunctionIndex;
1459virNetDevGetVirtualFunctionInfo;
1460virNetDevGetVirtualFunctions;
1461virNetDevIsOnline;
1462virNetDevIsVirtualFunction;
1463virNetDevLinkDump;
1464virNetDevReplaceMacAddress;
1465virNetDevReplaceNetConfig;
1466virNetDevRestoreMacAddress;
1467virNetDevRestoreNetConfig;
1468virNetDevSetIPv4Address;
1469virNetDevSetMAC;
1470virNetDevSetMTU;
1471virNetDevSetMTUFromDevice;
1472virNetDevSetName;
1473virNetDevSetNamespace;
1474virNetDevSetOnline;
1475virNetDevValidateConfig;
1476
1477
1478# virnetdevbandwidth.h
1479virNetDevBandwidthClear;
1480virNetDevBandwidthCopy;
1481virNetDevBandwidthEqual;
1482virNetDevBandwidthFree;
1483virNetDevBandwidthSet;
1484
1485
1486# virnetdevbridge.h
1487virNetDevBridgeAddPort;
1488virNetDevBridgeCreate;
1489virNetDevBridgeDelete;
1490virNetDevBridgeGetSTP;
1491virNetDevBridgeGetSTPDelay;
1492virNetDevBridgeRemovePort;
1493virNetDevBridgeSetSTP;
1494virNetDevBridgeSetSTPDelay;
1495
1496
1497# virnetdevmacvlan.h
1498virNetDevMacVLanCreate;
1499virNetDevMacVLanDelete;
1500virNetDevMacVLanCreateWithVPortProfile;
1501virNetDevMacVLanDeleteWithVPortProfile;
1502virNetDevMacVLanRestartWithVPortProfile;
1503virNetDevMacVLanVPortProfileRegisterCallback;
1504
1505
1506# virnetdevopenvswitch.h
1507virNetDevOpenvswitchAddPort;
1508virNetDevOpenvswitchGetMigrateData;
1509virNetDevOpenvswitchRemovePort;
1510virNetDevOpenvswitchSetMigrateData;
1511
1512
1513# virnetdevtap.h
1514virNetDevTapCreate;
1515virNetDevTapCreateInBridgePort;
1516virNetDevTapDelete;
1517
1518
1519# virnetdevveth.h
1520virNetDevVethCreate;
1521virNetDevVethDelete;
1522
1523
1524# virnetdevvlan.h
1525virNetDevVlanClear;
1526virNetDevVlanCopy;
1527virNetDevVlanEqual;
1528virNetDevVlanFree;
1529
1530# virnetdevvportprofile.h
1531virNetDevVPortProfileAssociate;
1532virNetDevVPortProfileCheckComplete;
1533virNetDevVPortProfileCheckNoExtras;
1534virNetDevVPortProfileDisassociate;
1535virNetDevVPortProfileEqual;
1536virNetDevVPortProfileMerge3;
1537virNetDevVPortProfileOpTypeFromString;
1538virNetDevVPortProfileOpTypeToString;
1539
1540
1541#virnetlink.h
1542virNetlinkCommand;
1543virNetlinkEventAddClient;
1544virNetlinkEventRemoveClient;
1545virNetlinkEventServiceIsRunning;
1546virNetlinkEventServiceLocalPid;
1547virNetlinkEventServiceStop;
1548virNetlinkEventServiceStopAll;
1549virNetlinkEventServiceStart;
1550virNetlinkShutdown;
1551virNetlinkStartup;
1552
1553
1554# virnetmessage.h
1555virNetMessageClear;
1556virNetMessageDecodeHeader;
1557virNetMessageDecodeNumFDs;
1558virNetMessageDecodeLength;
1559virNetMessageDecodePayload;
1560virNetMessageDupFD;
1561virNetMessageEncodeHeader;
1562virNetMessageEncodePayload;
1563virNetMessageEncodePayloadRaw;
1564virNetMessageEncodeNumFDs;
1565virNetMessageFree;
1566virNetMessageNew;
1567virNetMessageQueuePush;
1568virNetMessageQueueServe;
1569virNetMessageSaveError;
1570xdr_virNetMessageError;
1571
1572
1573# virnetserver.h
1574virNetServerAddProgram;
1575virNetServerAddService;
1576virNetServerAddSignalHandler;
1577virNetServerAutoShutdown;
1578virNetServerClose;
1579virNetServerIsPrivileged;
1580virNetServerKeepAliveRequired;
1581virNetServerNew;
1582virNetServerNewPostExecRestart;
1583virNetServerPreExecRestart;
1584virNetServerQuit;
1585virNetServerRun;
1586virNetServerSetTLSContext;
1587virNetServerUpdateServices;
1588
1589
1590# virnetserverclient.h
1591virNetServerClientAddFilter;
1592virNetServerClientClose;
1593virNetServerClientDelayedClose;
1594virNetServerClientGetAuth;
1595virNetServerClientGetFD;
1596virNetServerClientGetIdentity;
1597virNetServerClientGetPrivateData;
1598virNetServerClientGetReadonly;
1599virNetServerClientGetTLSKeySize;
1600virNetServerClientGetUNIXIdentity;
1601virNetServerClientHasTLSSession;
1602virNetServerClientImmediateClose;
1603virNetServerClientInit;
1604virNetServerClientInitKeepAlive;
1605virNetServerClientIsClosed;
1606virNetServerClientIsSecure;
1607virNetServerClientLocalAddrString;
1608virNetServerClientNeedAuth;
1609virNetServerClientNew;
1610virNetServerClientNewPostExecRestart;
1611virNetServerClientPreExecRestart;
1612virNetServerClientRemoteAddrString;
1613virNetServerClientRemoveFilter;
1614virNetServerClientSendMessage;
1615virNetServerClientSetCloseHook;
1616virNetServerClientSetDispatcher;
1617virNetServerClientSetIdentity;
1618virNetServerClientStartKeepAlive;
1619virNetServerClientWantClose;
1620
1621
1622# virnetservermdns.h
1623virNetServerMDNSAddEntry;
1624virNetServerMDNSAddGroup;
1625virNetServerMDNSEntryFree;
1626virNetServerMDNSFree;
1627virNetServerMDNSGroupFree;
1628virNetServerMDNSNew;
1629virNetServerMDNSRemoveEntry;
1630virNetServerMDNSRemoveGroup;
1631virNetServerMDNSStart;
1632virNetServerMDNSStop;
1633
1634
1635# virnetserverprogram.h
1636virNetServerProgramDispatch;
1637virNetServerProgramGetID;
1638virNetServerProgramGetPriority;
1639virNetServerProgramGetVersion;
1640virNetServerProgramMatches;
1641virNetServerProgramNew;
1642virNetServerProgramSendReplyError;
1643virNetServerProgramSendStreamData;
1644virNetServerProgramSendStreamError;
1645virNetServerProgramUnknownError;
1646
1647
1648# virnetserverservice.h
1649virNetServerServiceClose;
1650virNetServerServiceGetAuth;
1651virNetServerServiceGetMaxRequests;
1652virNetServerServiceGetPort;
1653virNetServerServiceGetTLSContext;
1654virNetServerServiceIsReadonly;
1655virNetServerServiceNewFD;
1656virNetServerServiceNewPostExecRestart;
1657virNetServerServiceNewTCP;
1658virNetServerServiceNewUNIX;
1659virNetServerServicePreExecRestart;
1660virNetServerServiceSetDispatcher;
1661virNetServerServiceToggle;
1662
1663
1664# virnetsocket.h
1665virNetSocketAccept;
1666virNetSocketAddIOCallback;
1667virNetSocketClose;
1668virNetSocketDupFD;
1669virNetSocketGetFD;
1670virNetSocketGetPort;
1671virNetSocketGetUNIXIdentity;
1672virNetSocketHasCachedData;
1673virNetSocketHasPassFD;
1674virNetSocketHasPendingData;
1675virNetSocketIsLocal;
1676virNetSocketListen;
1677virNetSocketLocalAddrString;
1678virNetSocketNewConnectCommand;
1679virNetSocketNewConnectExternal;
1680virNetSocketNewConnectLibSSH2;
1681virNetSocketNewConnectSSH;
1682virNetSocketNewConnectTCP;
1683virNetSocketNewConnectUNIX;
1684virNetSocketNewListenFD;
1685virNetSocketNewListenTCP;
1686virNetSocketNewListenUNIX;
1687virNetSocketNewPostExecRestart;
1688virNetSocketPreExecRestart;
1689virNetSocketRead;
1690virNetSocketRecvFD;
1691virNetSocketRemoteAddrString;
1692virNetSocketRemoveIOCallback;
1693virNetSocketSendFD;
1694virNetSocketSetBlocking;
1695virNetSocketSetTLSSession;
1696virNetSocketUpdateIOCallback;
1697virNetSocketWrite;
1698
1699
1700# virnettlscontext.h
1701virNetTLSContextCheckCertificate;
1702virNetTLSContextNewClient;
1703virNetTLSContextNewClientPath;
1704virNetTLSContextNewServer;
1705virNetTLSContextNewServerPath;
1706virNetTLSInit;
1707virNetTLSSessionGetHandshakeStatus;
1708virNetTLSSessionGetKeySize;
1709virNetTLSSessionHandshake;
1710virNetTLSSessionNew;
1711virNetTLSSessionRead;
1712virNetTLSSessionSetIOCallbacks;
1713virNetTLSSessionWrite;
1714
1715
1716# virnodesuspend.h
1717nodeSuspendForDuration;
1718virNodeSuspendGetTargetMask;
1719
1720
1721# virobject.h
1722virClassName;
1723virClassNew;
1724virObjectFreeCallback;
1725virObjectIsClass;
1726virObjectNew;
1727virObjectRef;
1728virObjectUnref;
1729
1730
1731# virpidfile.h
1732virPidFileAcquire;
1733virPidFileAcquirePath;
1734virPidFileBuildPath;
1735virPidFileRead;
1736virPidFileReadIfAlive;
1737virPidFileReadPath;
1738virPidFileReadPathIfAlive;
1739virPidFileRelease;
1740virPidFileReleasePath;
1741virPidFileWrite;
1742virPidFileWritePath;
1743virPidFileDelete;
1744virPidFileDeletePath;
1745
1746
1747# virprocess.h
1748virProcessAbort;
1749virProcessKill;
1750virProcessKillPainfully;
1751virProcessTranslateStatus;
1752virProcessWait;
1753
1754
1755# virrandom.h
1756virRandom;
1757virRandomBits;
1758virRandomGenerateWWN;
1759virRandomInt;
1760
1761
1762# virsocketaddr.h
1763virSocketAddrBroadcast;
1764virSocketAddrBroadcastByPrefix;
1765virSocketAddrCheckNetmask;
1766virSocketAddrEqual;
1767virSocketAddrFormat;
1768virSocketAddrFormatFull;
1769virSocketAddrGetPort;
1770virSocketAddrGetRange;
1771virSocketAddrIsNetmask;
1772virSocketAddrMask;
1773virSocketAddrMaskByPrefix;
1774virSocketAddrParse;
1775virSocketAddrParseIPv4;
1776virSocketAddrParseIPv6;
1777virSocketAddrPrefixToNetmask;
1778virSocketAddrSetIPv4Addr;
1779virSocketAddrSetPort;
1780
1781
1782# virterror_internal.h
1783virDispatchError;
1784virErrorInitialize;
1785virRaiseErrorFull;
1786virReportErrorHelper;
1787virReportOOMErrorFull;
1788virReportSystemErrorFull;
1789virSetError;
1790virSetErrorLogPriorityFunc;
1791virStrerror;
1792
1793
1794# virtime.h
1795virTimeFieldsNow;
1796virTimeFieldsNowRaw;
1797virTimeFieldsThen;
1798virTimeFieldsThenRaw;
1799virTimeMillisNow;
1800virTimeMillisNowRaw;
1801virTimeStringNow;
1802virTimeStringNowRaw;
1803virTimeStringThen;
1804virTimeStringThenRaw;
1805
1806
1807# virtypedparam.h
1808virTypedParameterArrayClear;
1809virTypedParameterArrayValidate;
1810virTypedParameterAssign;
1811virTypedParameterAssignFromStr;
1812
1813
1814# viruri.h
1815virURIFormat;
1816virURIFormatParams;
1817virURIFree;
1818virURIParse;
1819
1820
1821# xml.h
1822virXMLChildElementCount;
1823virXMLParseHelper;
1824virXMLPickShellSafeComment;
1825virXMLPropString;
1826virXMLSaveFile;
1827virXPathBoolean;
1828virXPathInt;
1829virXPathLong;
1830virXPathLongHex;
1831virXPathLongLong;
1832virXPathNode;
1833virXPathNodeSet;
1834virXPathNumber;
1835virXPathString;
1836virXPathStringLimit;
1837virXPathUInt;
1838virXPathULong;
1839virXPathULongHex;
1840virXPathULongLong;
01841
=== added directory '.pc/apparmor-allow-hugepages/src/qemu'
=== added file '.pc/apparmor-allow-hugepages/src/qemu/qemu_process.c'
--- .pc/apparmor-allow-hugepages/src/qemu/qemu_process.c 1970-01-01 00:00:00 +0000
+++ .pc/apparmor-allow-hugepages/src/qemu/qemu_process.c 2012-12-11 20:02:29 +0000
@@ -0,0 +1,4474 @@
1/*
2 * qemu_process.h: QEMU process management
3 *
4 * Copyright (C) 2006-2012 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include <config.h>
23
24#include <fcntl.h>
25#include <unistd.h>
26#include <signal.h>
27#include <sys/stat.h>
28#include <sys/time.h>
29#include <sys/resource.h>
30#include <linux/capability.h>
31
32#include "qemu_process.h"
33#include "qemu_domain.h"
34#include "qemu_cgroup.h"
35#include "qemu_capabilities.h"
36#include "qemu_monitor.h"
37#include "qemu_command.h"
38#include "qemu_hostdev.h"
39#include "qemu_hotplug.h"
40#include "qemu_bridge_filter.h"
41#include "qemu_migration.h"
42
43#if HAVE_NUMACTL
44# define NUMA_VERSION1_COMPATIBILITY 1
45# include <numa.h>
46#endif
47
48#include "datatypes.h"
49#include "logging.h"
50#include "virterror_internal.h"
51#include "memory.h"
52#include "hooks.h"
53#include "virfile.h"
54#include "virpidfile.h"
55#include "util.h"
56#include "c-ctype.h"
57#include "nodeinfo.h"
58#include "processinfo.h"
59#include "domain_audit.h"
60#include "domain_nwfilter.h"
61#include "locking/domain_lock.h"
62#include "network/bridge_driver.h"
63#include "uuid.h"
64#include "virprocess.h"
65#include "virtime.h"
66#include "virnetdevtap.h"
67#include "bitmap.h"
68
69#define VIR_FROM_THIS VIR_FROM_QEMU
70
71#define START_POSTFIX ": starting up\n"
72#define ATTACH_POSTFIX ": attaching\n"
73#define SHUTDOWN_POSTFIX ": shutting down\n"
74
75/**
76 * qemudRemoveDomainStatus
77 *
78 * remove all state files of a domain from statedir
79 *
80 * Returns 0 on success
81 */
82static int
83qemuProcessRemoveDomainStatus(struct qemud_driver *driver,
84 virDomainObjPtr vm)
85{
86 char ebuf[1024];
87 char *file = NULL;
88 qemuDomainObjPrivatePtr priv = vm->privateData;
89
90 if (virAsprintf(&file, "%s/%s.xml", driver->stateDir, vm->def->name) < 0) {
91 virReportOOMError();
92 return -1;
93 }
94
95 if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR)
96 VIR_WARN("Failed to remove domain XML for %s: %s",
97 vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf)));
98 VIR_FREE(file);
99
100 if (priv->pidfile &&
101 unlink(priv->pidfile) < 0 &&
102 errno != ENOENT)
103 VIR_WARN("Failed to remove PID file for %s: %s",
104 vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf)));
105
106 return 0;
107}
108
109
110/* XXX figure out how to remove this */
111extern struct qemud_driver *qemu_driver;
112
113/*
114 * This is a callback registered with a qemuAgentPtr instance,
115 * and to be invoked when the agent console hits an end of file
116 * condition, or error, thus indicating VM shutdown should be
117 * performed
118 */
119static void
120qemuProcessHandleAgentEOF(qemuAgentPtr agent,
121 virDomainObjPtr vm)
122{
123 struct qemud_driver *driver = qemu_driver;
124 qemuDomainObjPrivatePtr priv;
125
126 VIR_DEBUG("Received EOF from agent on %p '%s'", vm, vm->def->name);
127
128 qemuDriverLock(driver);
129 virDomainObjLock(vm);
130
131 priv = vm->privateData;
132 if (priv->agent == agent)
133 priv->agent = NULL;
134
135 virDomainObjUnlock(vm);
136 qemuDriverUnlock(driver);
137
138 qemuAgentClose(agent);
139}
140
141
142/*
143 * This is invoked when there is some kind of error
144 * parsing data to/from the agent. The VM can continue
145 * to run, but no further agent commands will be
146 * allowed
147 */
148static void
149qemuProcessHandleAgentError(qemuAgentPtr agent ATTRIBUTE_UNUSED,
150 virDomainObjPtr vm)
151{
152 struct qemud_driver *driver = qemu_driver;
153 qemuDomainObjPrivatePtr priv;
154
155 VIR_DEBUG("Received error from agent on %p '%s'", vm, vm->def->name);
156
157 qemuDriverLock(driver);
158 virDomainObjLock(vm);
159
160 priv = vm->privateData;
161
162 priv->agentError = true;
163
164 virDomainObjUnlock(vm);
165 qemuDriverUnlock(driver);
166}
167
168static void qemuProcessHandleAgentDestroy(qemuAgentPtr agent,
169 virDomainObjPtr vm)
170{
171 VIR_DEBUG("Received destroy agent=%p vm=%p", agent, vm);
172
173 virObjectUnref(vm);
174}
175
176
177static qemuAgentCallbacks agentCallbacks = {
178 .destroy = qemuProcessHandleAgentDestroy,
179 .eofNotify = qemuProcessHandleAgentEOF,
180 .errorNotify = qemuProcessHandleAgentError,
181};
182
183static virDomainChrSourceDefPtr
184qemuFindAgentConfig(virDomainDefPtr def)
185{
186 virDomainChrSourceDefPtr config = NULL;
187 int i;
188
189 for (i = 0 ; i < def->nchannels ; i++) {
190 virDomainChrDefPtr channel = def->channels[i];
191
192 if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO)
193 continue;
194
195 if (STREQ_NULLABLE(channel->target.name, "org.qemu.guest_agent.0")) {
196 config = &channel->source;
197 break;
198 }
199 }
200
201 return config;
202}
203
204static int
205qemuConnectAgent(struct qemud_driver *driver, virDomainObjPtr vm)
206{
207 qemuDomainObjPrivatePtr priv = vm->privateData;
208 int ret = -1;
209 qemuAgentPtr agent = NULL;
210 virDomainChrSourceDefPtr config = qemuFindAgentConfig(vm->def);
211
212 if (!config)
213 return 0;
214
215 if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager,
216 vm->def) < 0) {
217 VIR_ERROR(_("Failed to set security context for agent for %s"),
218 vm->def->name);
219 goto cleanup;
220 }
221
222 /* Hold an extra reference because we can't allow 'vm' to be
223 * deleted while the agent is active */
224 virObjectRef(vm);
225
226 ignore_value(virTimeMillisNow(&priv->agentStart));
227 virDomainObjUnlock(vm);
228 qemuDriverUnlock(driver);
229
230 agent = qemuAgentOpen(vm,
231 config,
232 &agentCallbacks);
233
234 qemuDriverLock(driver);
235 virDomainObjLock(vm);
236 priv->agentStart = 0;
237
238 if (virSecurityManagerClearSocketLabel(driver->securityManager,
239 vm->def) < 0) {
240 VIR_ERROR(_("Failed to clear security context for agent for %s"),
241 vm->def->name);
242 goto cleanup;
243 }
244
245 if (agent == NULL)
246 virObjectUnref(vm);
247
248 if (!virDomainObjIsActive(vm)) {
249 qemuAgentClose(agent);
250 goto cleanup;
251 }
252 priv->agent = agent;
253
254 if (priv->agent == NULL) {
255 VIR_INFO("Failed to connect agent for %s", vm->def->name);
256 goto cleanup;
257 }
258
259 ret = 0;
260
261cleanup:
262 return ret;
263}
264
265
266/*
267 * This is a callback registered with a qemuMonitorPtr instance,
268 * and to be invoked when the monitor console hits an end of file
269 * condition, or error, thus indicating VM shutdown should be
270 * performed
271 */
272static void
273qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
274 virDomainObjPtr vm)
275{
276 struct qemud_driver *driver = qemu_driver;
277 virDomainEventPtr event = NULL;
278 qemuDomainObjPrivatePtr priv;
279 int eventReason = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN;
280 int stopReason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
281 const char *auditReason = "shutdown";
282
283 VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name);
284
285 qemuDriverLock(driver);
286 virDomainObjLock(vm);
287
288 priv = vm->privateData;
289
290 if (priv->beingDestroyed) {
291 VIR_DEBUG("Domain is being destroyed, EOF is expected");
292 goto unlock;
293 }
294
295 if (!virDomainObjIsActive(vm)) {
296 VIR_DEBUG("Domain %p is not active, ignoring EOF", vm);
297 goto unlock;
298 }
299
300 if (priv->monJSON && !priv->gotShutdown) {
301 VIR_DEBUG("Monitor connection to '%s' closed without SHUTDOWN event; "
302 "assuming the domain crashed", vm->def->name);
303 eventReason = VIR_DOMAIN_EVENT_STOPPED_FAILED;
304 stopReason = VIR_DOMAIN_SHUTOFF_CRASHED;
305 auditReason = "failed";
306 }
307
308 event = virDomainEventNewFromObj(vm,
309 VIR_DOMAIN_EVENT_STOPPED,
310 eventReason);
311 qemuProcessStop(driver, vm, stopReason, 0);
312 virDomainAuditStop(vm, auditReason);
313
314 if (!vm->persistent) {
315 qemuDomainRemoveInactive(driver, vm);
316 goto cleanup;
317 }
318
319unlock:
320 virDomainObjUnlock(vm);
321
322cleanup:
323 if (event)
324 qemuDomainEventQueue(driver, event);
325 qemuDriverUnlock(driver);
326}
327
328
329/*
330 * This is invoked when there is some kind of error
331 * parsing data to/from the monitor. The VM can continue
332 * to run, but no further monitor commands will be
333 * allowed
334 */
335static void
336qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
337 virDomainObjPtr vm)
338{
339 struct qemud_driver *driver = qemu_driver;
340 virDomainEventPtr event = NULL;
341
342 VIR_DEBUG("Received error on %p '%s'", vm, vm->def->name);
343
344 qemuDriverLock(driver);
345 virDomainObjLock(vm);
346
347 ((qemuDomainObjPrivatePtr) vm->privateData)->monError = true;
348 event = virDomainEventControlErrorNewFromObj(vm);
349 if (event)
350 qemuDomainEventQueue(driver, event);
351
352 virDomainObjUnlock(vm);
353 qemuDriverUnlock(driver);
354}
355
356
357static virDomainDiskDefPtr
358qemuProcessFindDomainDiskByPath(virDomainObjPtr vm,
359 const char *path)
360{
361 int i = virDomainDiskIndexByName(vm->def, path, true);
362
363 if (i >= 0)
364 return vm->def->disks[i];
365
366 virReportError(VIR_ERR_INTERNAL_ERROR,
367 _("no disk found with path %s"),
368 path);
369 return NULL;
370}
371
372static virDomainDiskDefPtr
373qemuProcessFindDomainDiskByAlias(virDomainObjPtr vm,
374 const char *alias)
375{
376 int i;
377
378 if (STRPREFIX(alias, QEMU_DRIVE_HOST_PREFIX))
379 alias += strlen(QEMU_DRIVE_HOST_PREFIX);
380
381 for (i = 0; i < vm->def->ndisks; i++) {
382 virDomainDiskDefPtr disk;
383
384 disk = vm->def->disks[i];
385 if (disk->info.alias != NULL && STREQ(disk->info.alias, alias))
386 return disk;
387 }
388
389 virReportError(VIR_ERR_INTERNAL_ERROR,
390 _("no disk found with alias %s"),
391 alias);
392 return NULL;
393}
394
395static int
396qemuProcessGetVolumeQcowPassphrase(virConnectPtr conn,
397 virDomainDiskDefPtr disk,
398 char **secretRet,
399 size_t *secretLen)
400{
401 virSecretPtr secret;
402 char *passphrase;
403 unsigned char *data;
404 size_t size;
405 int ret = -1;
406 virStorageEncryptionPtr enc;
407
408 if (!disk->encryption) {
409 virReportError(VIR_ERR_INTERNAL_ERROR,
410 _("disk %s does not have any encryption information"),
411 disk->src);
412 return -1;
413 }
414 enc = disk->encryption;
415
416 if (!conn) {
417 virReportError(VIR_ERR_INTERNAL_ERROR,
418 "%s", _("cannot find secrets without a connection"));
419 goto cleanup;
420 }
421
422 if (conn->secretDriver == NULL ||
423 conn->secretDriver->lookupByUUID == NULL ||
424 conn->secretDriver->getValue == NULL) {
425 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
426 _("secret storage not supported"));
427 goto cleanup;
428 }
429
430 if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW ||
431 enc->nsecrets != 1 ||
432 enc->secrets[0]->type !=
433 VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE) {
434 virReportError(VIR_ERR_XML_ERROR,
435 _("invalid <encryption> for volume %s"), disk->src);
436 goto cleanup;
437 }
438
439 secret = conn->secretDriver->lookupByUUID(conn,
440 enc->secrets[0]->uuid);
441 if (secret == NULL)
442 goto cleanup;
443 data = conn->secretDriver->getValue(secret, &size, 0,
444 VIR_SECRET_GET_VALUE_INTERNAL_CALL);
445 virObjectUnref(secret);
446 if (data == NULL)
447 goto cleanup;
448
449 if (memchr(data, '\0', size) != NULL) {
450 memset(data, 0, size);
451 VIR_FREE(data);
452 virReportError(VIR_ERR_XML_ERROR,
453 _("format='qcow' passphrase for %s must not contain a "
454 "'\\0'"), disk->src);
455 goto cleanup;
456 }
457
458 if (VIR_ALLOC_N(passphrase, size + 1) < 0) {
459 memset(data, 0, size);
460 VIR_FREE(data);
461 virReportOOMError();
462 goto cleanup;
463 }
464 memcpy(passphrase, data, size);
465 passphrase[size] = '\0';
466
467 memset(data, 0, size);
468 VIR_FREE(data);
469
470 *secretRet = passphrase;
471 *secretLen = size;
472
473 ret = 0;
474
475cleanup:
476 return ret;
477}
478
479static int
480qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
481 virConnectPtr conn,
482 virDomainObjPtr vm,
483 const char *path,
484 char **secretRet,
485 size_t *secretLen)
486{
487 virDomainDiskDefPtr disk;
488 int ret = -1;
489
490 virDomainObjLock(vm);
491 disk = qemuProcessFindDomainDiskByPath(vm, path);
492
493 if (!disk)
494 goto cleanup;
495
496 ret = qemuProcessGetVolumeQcowPassphrase(conn, disk, secretRet, secretLen);
497
498cleanup:
499 virDomainObjUnlock(vm);
500 return ret;
501}
502
503
504static int
505qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
506 virDomainObjPtr vm)
507{
508 struct qemud_driver *driver = qemu_driver;
509 virDomainEventPtr event;
510 qemuDomainObjPrivatePtr priv;
511
512 virDomainObjLock(vm);
513
514 event = virDomainEventRebootNewFromObj(vm);
515 priv = vm->privateData;
516 if (priv->agent)
517 qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_RESET);
518
519 virDomainObjUnlock(vm);
520
521 if (event) {
522 qemuDriverLock(driver);
523 qemuDomainEventQueue(driver, event);
524 qemuDriverUnlock(driver);
525 }
526
527 return 0;
528}
529
530
531/*
532 * Since we have the '-no-shutdown' flag set, the
533 * QEMU process will currently have guest OS shutdown
534 * and the CPUS stopped. To fake the reboot, we thus
535 * want todo a reset of the virtual hardware, followed
536 * by restart of the CPUs. This should result in the
537 * guest OS booting up again
538 */
539static void
540qemuProcessFakeReboot(void *opaque)
541{
542 struct qemud_driver *driver = qemu_driver;
543 virDomainObjPtr vm = opaque;
544 qemuDomainObjPrivatePtr priv = vm->privateData;
545 virDomainEventPtr event = NULL;
546 int ret = -1;
547 VIR_DEBUG("vm=%p", vm);
548 qemuDriverLock(driver);
549 virDomainObjLock(vm);
550 if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
551 goto cleanup;
552
553 if (!virDomainObjIsActive(vm)) {
554 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
555 _("guest unexpectedly quit"));
556 goto endjob;
557 }
558
559 qemuDomainObjEnterMonitorWithDriver(driver, vm);
560 if (qemuMonitorSystemReset(priv->mon) < 0) {
561 qemuDomainObjExitMonitorWithDriver(driver, vm);
562 goto endjob;
563 }
564 qemuDomainObjExitMonitorWithDriver(driver, vm);
565
566 if (!virDomainObjIsActive(vm)) {
567 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
568 _("guest unexpectedly quit"));
569 goto endjob;
570 }
571
572 if (qemuProcessStartCPUs(driver, vm, NULL,
573 VIR_DOMAIN_RUNNING_BOOTED,
574 QEMU_ASYNC_JOB_NONE) < 0) {
575 if (virGetLastError() == NULL)
576 virReportError(VIR_ERR_INTERNAL_ERROR,
577 "%s", _("resume operation failed"));
578 goto endjob;
579 }
580 priv->gotShutdown = false;
581 event = virDomainEventNewFromObj(vm,
582 VIR_DOMAIN_EVENT_RESUMED,
583 VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
584
585 ret = 0;
586
587endjob:
588 if (!qemuDomainObjEndJob(driver, vm))
589 vm = NULL;
590
591cleanup:
592 if (vm) {
593 if (ret == -1) {
594 ignore_value(qemuProcessKill(driver, vm,
595 VIR_QEMU_PROCESS_KILL_FORCE));
596 }
597 if (virObjectUnref(vm))
598 virDomainObjUnlock(vm);
599 }
600 if (event)
601 qemuDomainEventQueue(driver, event);
602 qemuDriverUnlock(driver);
603}
604
605
606static void
607qemuProcessShutdownOrReboot(struct qemud_driver *driver,
608 virDomainObjPtr vm)
609{
610 qemuDomainObjPrivatePtr priv = vm->privateData;
611
612 if (priv->fakeReboot) {
613 qemuDomainSetFakeReboot(driver, vm, false);
614 virObjectRef(vm);
615 virThread th;
616 if (virThreadCreate(&th,
617 false,
618 qemuProcessFakeReboot,
619 vm) < 0) {
620 VIR_ERROR(_("Failed to create reboot thread, killing domain"));
621 ignore_value(qemuProcessKill(driver, vm,
622 VIR_QEMU_PROCESS_KILL_NOWAIT));
623 virObjectUnref(vm);
624 }
625 } else {
626 ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
627 }
628}
629
630static int
631qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
632 virDomainObjPtr vm)
633{
634 struct qemud_driver *driver = qemu_driver;
635 qemuDomainObjPrivatePtr priv;
636 virDomainEventPtr event = NULL;
637
638 VIR_DEBUG("vm=%p", vm);
639
640 virDomainObjLock(vm);
641
642 priv = vm->privateData;
643 if (priv->gotShutdown) {
644 VIR_DEBUG("Ignoring repeated SHUTDOWN event from domain %s",
645 vm->def->name);
646 goto unlock;
647 } else if (!virDomainObjIsActive(vm)) {
648 VIR_DEBUG("Ignoring SHUTDOWN event from inactive domain %s",
649 vm->def->name);
650 goto unlock;
651 }
652 priv->gotShutdown = true;
653
654 VIR_DEBUG("Transitioned guest %s to shutdown state",
655 vm->def->name);
656 virDomainObjSetState(vm,
657 VIR_DOMAIN_SHUTDOWN,
658 VIR_DOMAIN_SHUTDOWN_UNKNOWN);
659 event = virDomainEventNewFromObj(vm,
660 VIR_DOMAIN_EVENT_SHUTDOWN,
661 VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED);
662
663 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
664 VIR_WARN("Unable to save status on vm %s after state change",
665 vm->def->name);
666 }
667
668 if (priv->agent)
669 qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SHUTDOWN);
670
671 qemuProcessShutdownOrReboot(driver, vm);
672
673unlock:
674 virDomainObjUnlock(vm);
675
676 if (event) {
677 qemuDriverLock(driver);
678 qemuDomainEventQueue(driver, event);
679 qemuDriverUnlock(driver);
680 }
681
682 return 0;
683}
684
685
686static int
687qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
688 virDomainObjPtr vm)
689{
690 struct qemud_driver *driver = qemu_driver;
691 virDomainEventPtr event = NULL;
692
693 virDomainObjLock(vm);
694 if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
695 qemuDomainObjPrivatePtr priv = vm->privateData;
696
697 if (priv->gotShutdown) {
698 VIR_DEBUG("Ignoring STOP event after SHUTDOWN");
699 goto unlock;
700 }
701
702 VIR_DEBUG("Transitioned guest %s to paused state",
703 vm->def->name);
704
705 virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_UNKNOWN);
706 event = virDomainEventNewFromObj(vm,
707 VIR_DOMAIN_EVENT_SUSPENDED,
708 VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
709
710 VIR_FREE(priv->lockState);
711 if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
712 VIR_WARN("Unable to release lease on %s", vm->def->name);
713 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
714
715 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
716 VIR_WARN("Unable to save status on vm %s after state change",
717 vm->def->name);
718 }
719 }
720
721unlock:
722 virDomainObjUnlock(vm);
723
724 if (event) {
725 qemuDriverLock(driver);
726 qemuDomainEventQueue(driver, event);
727 qemuDriverUnlock(driver);
728 }
729
730 return 0;
731}
732
733
734static int
735qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
736 virDomainObjPtr vm,
737 long long offset)
738{
739 struct qemud_driver *driver = qemu_driver;
740 virDomainEventPtr event;
741
742 virDomainObjLock(vm);
743 event = virDomainEventRTCChangeNewFromObj(vm, offset);
744
745 if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE)
746 vm->def->clock.data.variable.adjustment = offset;
747
748 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
749 VIR_WARN("unable to save domain status with RTC change");
750
751 virDomainObjUnlock(vm);
752
753 if (event) {
754 qemuDriverLock(driver);
755 qemuDomainEventQueue(driver, event);
756 qemuDriverUnlock(driver);
757 }
758
759 return 0;
760}
761
762
763static int
764qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
765 virDomainObjPtr vm,
766 int action)
767{
768 struct qemud_driver *driver = qemu_driver;
769 virDomainEventPtr watchdogEvent = NULL;
770 virDomainEventPtr lifecycleEvent = NULL;
771
772 virDomainObjLock(vm);
773 watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action);
774
775 if (action == VIR_DOMAIN_EVENT_WATCHDOG_PAUSE &&
776 virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
777 qemuDomainObjPrivatePtr priv = vm->privateData;
778 VIR_DEBUG("Transitioned guest %s to paused state due to watchdog", vm->def->name);
779
780 virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_WATCHDOG);
781 lifecycleEvent = virDomainEventNewFromObj(vm,
782 VIR_DOMAIN_EVENT_SUSPENDED,
783 VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG);
784
785 VIR_FREE(priv->lockState);
786 if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
787 VIR_WARN("Unable to release lease on %s", vm->def->name);
788 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
789
790 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
791 VIR_WARN("Unable to save status on vm %s after watchdog event",
792 vm->def->name);
793 }
794 }
795
796 if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) {
797 struct qemuDomainWatchdogEvent *wdEvent;
798 if (VIR_ALLOC(wdEvent) == 0) {
799 wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
800 wdEvent->vm = vm;
801 /* Hold an extra reference because we can't allow 'vm' to be
802 * deleted before handling watchdog event is finished.
803 */
804 virObjectRef(vm);
805 if (virThreadPoolSendJob(driver->workerPool, 0, wdEvent) < 0) {
806 if (!virObjectUnref(vm))
807 vm = NULL;
808 VIR_FREE(wdEvent);
809 }
810 } else {
811 virReportOOMError();
812 }
813 }
814
815 if (vm)
816 virDomainObjUnlock(vm);
817
818 if (watchdogEvent || lifecycleEvent) {
819 qemuDriverLock(driver);
820 if (watchdogEvent)
821 qemuDomainEventQueue(driver, watchdogEvent);
822 if (lifecycleEvent)
823 qemuDomainEventQueue(driver, lifecycleEvent);
824 qemuDriverUnlock(driver);
825 }
826
827 return 0;
828}
829
830
831static int
832qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
833 virDomainObjPtr vm,
834 const char *diskAlias,
835 int action,
836 const char *reason)
837{
838 struct qemud_driver *driver = qemu_driver;
839 virDomainEventPtr ioErrorEvent = NULL;
840 virDomainEventPtr ioErrorEvent2 = NULL;
841 virDomainEventPtr lifecycleEvent = NULL;
842 const char *srcPath;
843 const char *devAlias;
844 virDomainDiskDefPtr disk;
845
846 virDomainObjLock(vm);
847 disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
848
849 if (disk) {
850 srcPath = disk->src;
851 devAlias = disk->info.alias;
852 } else {
853 srcPath = "";
854 devAlias = "";
855 }
856
857 ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, srcPath, devAlias, action);
858 ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, srcPath, devAlias, action, reason);
859
860 if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
861 virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
862 qemuDomainObjPrivatePtr priv = vm->privateData;
863 VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name);
864
865 virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR);
866 lifecycleEvent = virDomainEventNewFromObj(vm,
867 VIR_DOMAIN_EVENT_SUSPENDED,
868 VIR_DOMAIN_EVENT_SUSPENDED_IOERROR);
869
870 VIR_FREE(priv->lockState);
871 if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
872 VIR_WARN("Unable to release lease on %s", vm->def->name);
873 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
874
875 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
876 VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name);
877 }
878 virDomainObjUnlock(vm);
879
880 if (ioErrorEvent || ioErrorEvent2 || lifecycleEvent) {
881 qemuDriverLock(driver);
882 if (ioErrorEvent)
883 qemuDomainEventQueue(driver, ioErrorEvent);
884 if (ioErrorEvent2)
885 qemuDomainEventQueue(driver, ioErrorEvent2);
886 if (lifecycleEvent)
887 qemuDomainEventQueue(driver, lifecycleEvent);
888 qemuDriverUnlock(driver);
889 }
890
891 return 0;
892}
893
894static int
895qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
896 virDomainObjPtr vm,
897 const char *diskAlias,
898 int type,
899 int status)
900{
901 struct qemud_driver *driver = qemu_driver;
902 virDomainEventPtr event = NULL;
903 const char *path;
904 virDomainDiskDefPtr disk;
905
906 virDomainObjLock(vm);
907 disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
908
909 if (disk) {
910 path = disk->src;
911 event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
912 /* XXX If we completed a block pull or commit, then recompute
913 * the cached backing chain to match. Better would be storing
914 * the chain ourselves rather than reprobing, but this
915 * requires modifying domain_conf and our XML to fully track
916 * the chain across libvirtd restarts. For that matter, if
917 * qemu gains support for committing the active layer, we have
918 * to update disk->src. */
919 if ((type == VIR_DOMAIN_BLOCK_JOB_TYPE_PULL ||
920 type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT) &&
921 status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
922 qemuDomainDetermineDiskChain(driver, disk, true);
923 if (disk->mirror && type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY &&
924 status == VIR_DOMAIN_BLOCK_JOB_READY)
925 disk->mirroring = true;
926 }
927
928 virDomainObjUnlock(vm);
929
930 if (event) {
931 qemuDriverLock(driver);
932 qemuDomainEventQueue(driver, event);
933 qemuDriverUnlock(driver);
934 }
935
936 return 0;
937}
938
939static int
940qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
941 virDomainObjPtr vm,
942 int phase,
943 int localFamily,
944 const char *localNode,
945 const char *localService,
946 int remoteFamily,
947 const char *remoteNode,
948 const char *remoteService,
949 const char *authScheme,
950 const char *x509dname,
951 const char *saslUsername)
952{
953 struct qemud_driver *driver = qemu_driver;
954 virDomainEventPtr event;
955 virDomainEventGraphicsAddressPtr localAddr = NULL;
956 virDomainEventGraphicsAddressPtr remoteAddr = NULL;
957 virDomainEventGraphicsSubjectPtr subject = NULL;
958 int i;
959
960 if (VIR_ALLOC(localAddr) < 0)
961 goto no_memory;
962 localAddr->family = localFamily;
963 if (!(localAddr->service = strdup(localService)) ||
964 !(localAddr->node = strdup(localNode)))
965 goto no_memory;
966
967 if (VIR_ALLOC(remoteAddr) < 0)
968 goto no_memory;
969 remoteAddr->family = remoteFamily;
970 if (!(remoteAddr->service = strdup(remoteService)) ||
971 !(remoteAddr->node = strdup(remoteNode)))
972 goto no_memory;
973
974 if (VIR_ALLOC(subject) < 0)
975 goto no_memory;
976 if (x509dname) {
977 if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
978 goto no_memory;
979 subject->nidentity++;
980 if (!(subject->identities[subject->nidentity-1].type = strdup("x509dname")) ||
981 !(subject->identities[subject->nidentity-1].name = strdup(x509dname)))
982 goto no_memory;
983 }
984 if (saslUsername) {
985 if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
986 goto no_memory;
987 subject->nidentity++;
988 if (!(subject->identities[subject->nidentity-1].type = strdup("saslUsername")) ||
989 !(subject->identities[subject->nidentity-1].name = strdup(saslUsername)))
990 goto no_memory;
991 }
992
993 virDomainObjLock(vm);
994 event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject);
995 virDomainObjUnlock(vm);
996
997 if (event) {
998 qemuDriverLock(driver);
999 qemuDomainEventQueue(driver, event);
1000 qemuDriverUnlock(driver);
1001 }
1002
1003 return 0;
1004
1005no_memory:
1006 virReportOOMError();
1007 if (localAddr) {
1008 VIR_FREE(localAddr->service);
1009 VIR_FREE(localAddr->node);
1010 VIR_FREE(localAddr);
1011 }
1012 if (remoteAddr) {
1013 VIR_FREE(remoteAddr->service);
1014 VIR_FREE(remoteAddr->node);
1015 VIR_FREE(remoteAddr);
1016 }
1017 if (subject) {
1018 for (i = 0 ; i < subject->nidentity ; i++) {
1019 VIR_FREE(subject->identities[i].type);
1020 VIR_FREE(subject->identities[i].name);
1021 }
1022 VIR_FREE(subject->identities);
1023 VIR_FREE(subject);
1024 }
1025
1026 return -1;
1027}
1028
1029
1030static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1031 virDomainObjPtr vm)
1032{
1033 virObjectUnref(vm);
1034}
1035
1036static int
1037qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1038 virDomainObjPtr vm,
1039 const char *devAlias,
1040 int reason)
1041{
1042 struct qemud_driver *driver = qemu_driver;
1043 virDomainEventPtr event = NULL;
1044 virDomainDiskDefPtr disk;
1045
1046 virDomainObjLock(vm);
1047 disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);
1048
1049 if (disk) {
1050 event = virDomainEventTrayChangeNewFromObj(vm,
1051 devAlias,
1052 reason);
1053 /* Update disk tray status */
1054 if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN)
1055 disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
1056 else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE)
1057 disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
1058
1059 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
1060 VIR_WARN("Unable to save status on vm %s after tray moved event",
1061 vm->def->name);
1062 }
1063 }
1064
1065 virDomainObjUnlock(vm);
1066
1067 if (event) {
1068 qemuDriverLock(driver);
1069 qemuDomainEventQueue(driver, event);
1070 qemuDriverUnlock(driver);
1071 }
1072
1073 return 0;
1074}
1075
1076static int
1077qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1078 virDomainObjPtr vm)
1079{
1080 struct qemud_driver *driver = qemu_driver;
1081 virDomainEventPtr event = NULL;
1082 virDomainEventPtr lifecycleEvent = NULL;
1083
1084 virDomainObjLock(vm);
1085 event = virDomainEventPMWakeupNewFromObj(vm);
1086
1087 /* Don't set domain status back to running if it wasn't paused
1088 * from guest side, otherwise it can just cause confusion.
1089 */
1090 if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PMSUSPENDED) {
1091 VIR_DEBUG("Transitioned guest %s from pmsuspended to running "
1092 "state due to QMP wakeup event", vm->def->name);
1093
1094 virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
1095 VIR_DOMAIN_RUNNING_WAKEUP);
1096 lifecycleEvent = virDomainEventNewFromObj(vm,
1097 VIR_DOMAIN_EVENT_STARTED,
1098 VIR_DOMAIN_EVENT_STARTED_WAKEUP);
1099
1100 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
1101 VIR_WARN("Unable to save status on vm %s after wakeup event",
1102 vm->def->name);
1103 }
1104 }
1105
1106 virDomainObjUnlock(vm);
1107
1108 if (event || lifecycleEvent) {
1109 qemuDriverLock(driver);
1110 if (event)
1111 qemuDomainEventQueue(driver, event);
1112 if (lifecycleEvent)
1113 qemuDomainEventQueue(driver, lifecycleEvent);
1114 qemuDriverUnlock(driver);
1115 }
1116
1117 return 0;
1118}
1119
1120static int
1121qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1122 virDomainObjPtr vm)
1123{
1124 struct qemud_driver *driver = qemu_driver;
1125 virDomainEventPtr event = NULL;
1126 virDomainEventPtr lifecycleEvent = NULL;
1127
1128 virDomainObjLock(vm);
1129 event = virDomainEventPMSuspendNewFromObj(vm);
1130
1131 if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
1132 qemuDomainObjPrivatePtr priv = vm->privateData;
1133 VIR_DEBUG("Transitioned guest %s to pmsuspended state due to "
1134 "QMP suspend event", vm->def->name);
1135
1136 virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED,
1137 VIR_DOMAIN_PMSUSPENDED_UNKNOWN);
1138 lifecycleEvent =
1139 virDomainEventNewFromObj(vm,
1140 VIR_DOMAIN_EVENT_PMSUSPENDED,
1141 VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY);
1142
1143 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
1144 VIR_WARN("Unable to save status on vm %s after suspend event",
1145 vm->def->name);
1146 }
1147
1148 if (priv->agent)
1149 qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
1150 }
1151
1152 virDomainObjUnlock(vm);
1153
1154 if (event || lifecycleEvent) {
1155 qemuDriverLock(driver);
1156 if (event)
1157 qemuDomainEventQueue(driver, event);
1158 if (lifecycleEvent)
1159 qemuDomainEventQueue(driver, lifecycleEvent);
1160 qemuDriverUnlock(driver);
1161 }
1162
1163 return 0;
1164}
1165
1166static int
1167qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1168 virDomainObjPtr vm,
1169 unsigned long long actual)
1170{
1171 struct qemud_driver *driver = qemu_driver;
1172 virDomainEventPtr event;
1173
1174 virDomainObjLock(vm);
1175 event = virDomainEventBalloonChangeNewFromObj(vm, actual);
1176
1177 VIR_DEBUG("Updating balloon from %lld to %lld kb",
1178 vm->def->mem.cur_balloon, actual);
1179 vm->def->mem.cur_balloon = actual;
1180
1181 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
1182 VIR_WARN("unable to save domain status with balloon change");
1183
1184 virDomainObjUnlock(vm);
1185
1186 if (event) {
1187 qemuDriverLock(driver);
1188 qemuDomainEventQueue(driver, event);
1189 qemuDriverUnlock(driver);
1190 }
1191
1192 return 0;
1193}
1194
1195static int
1196qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1197 virDomainObjPtr vm)
1198{
1199 struct qemud_driver *driver = qemu_driver;
1200 virDomainEventPtr event = NULL;
1201 virDomainEventPtr lifecycleEvent = NULL;
1202
1203 virDomainObjLock(vm);
1204 event = virDomainEventPMSuspendDiskNewFromObj(vm);
1205
1206 if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
1207 qemuDomainObjPrivatePtr priv = vm->privateData;
1208 VIR_DEBUG("Transitioned guest %s to pmsuspended state due to "
1209 "QMP suspend_disk event", vm->def->name);
1210
1211 virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED,
1212 VIR_DOMAIN_PMSUSPENDED_UNKNOWN);
1213 lifecycleEvent =
1214 virDomainEventNewFromObj(vm,
1215 VIR_DOMAIN_EVENT_PMSUSPENDED,
1216 VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);
1217
1218 if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
1219 VIR_WARN("Unable to save status on vm %s after suspend event",
1220 vm->def->name);
1221 }
1222
1223 if (priv->agent)
1224 qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
1225 }
1226
1227 virDomainObjUnlock(vm);
1228
1229 if (event || lifecycleEvent) {
1230 qemuDriverLock(driver);
1231 if (event)
1232 qemuDomainEventQueue(driver, event);
1233 if (lifecycleEvent)
1234 qemuDomainEventQueue(driver, lifecycleEvent);
1235 qemuDriverUnlock(driver);
1236 }
1237
1238 return 0;
1239}
1240
1241
1242static qemuMonitorCallbacks monitorCallbacks = {
1243 .destroy = qemuProcessHandleMonitorDestroy,
1244 .eofNotify = qemuProcessHandleMonitorEOF,
1245 .errorNotify = qemuProcessHandleMonitorError,
1246 .diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
1247 .domainShutdown = qemuProcessHandleShutdown,
1248 .domainStop = qemuProcessHandleStop,
1249 .domainReset = qemuProcessHandleReset,
1250 .domainRTCChange = qemuProcessHandleRTCChange,
1251 .domainWatchdog = qemuProcessHandleWatchdog,
1252 .domainIOError = qemuProcessHandleIOError,
1253 .domainGraphics = qemuProcessHandleGraphics,
1254 .domainBlockJob = qemuProcessHandleBlockJob,
1255 .domainTrayChange = qemuProcessHandleTrayChange,
1256 .domainPMWakeup = qemuProcessHandlePMWakeup,
1257 .domainPMSuspend = qemuProcessHandlePMSuspend,
1258 .domainBalloonChange = qemuProcessHandleBalloonChange,
1259 .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
1260};
1261
1262static int
1263qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
1264{
1265 qemuDomainObjPrivatePtr priv = vm->privateData;
1266 int ret = -1;
1267 qemuMonitorPtr mon = NULL;
1268
1269 if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager,
1270 vm->def) < 0) {
1271 VIR_ERROR(_("Failed to set security context for monitor for %s"),
1272 vm->def->name);
1273 goto error;
1274 }
1275
1276 /* Hold an extra reference because we can't allow 'vm' to be
1277 * deleted while the monitor is active */
1278 virObjectRef(vm);
1279
1280 ignore_value(virTimeMillisNow(&priv->monStart));
1281 virDomainObjUnlock(vm);
1282 qemuDriverUnlock(driver);
1283
1284 mon = qemuMonitorOpen(vm,
1285 priv->monConfig,
1286 priv->monJSON,
1287 &monitorCallbacks);
1288
1289 qemuDriverLock(driver);
1290 virDomainObjLock(vm);
1291 priv->monStart = 0;
1292
1293 if (mon == NULL) {
1294 virObjectUnref(vm);
1295 } else if (!virDomainObjIsActive(vm)) {
1296 qemuMonitorClose(mon);
1297 mon = NULL;
1298 }
1299 priv->mon = mon;
1300
1301 if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
1302 VIR_ERROR(_("Failed to clear security context for monitor for %s"),
1303 vm->def->name);
1304 goto error;
1305 }
1306
1307 if (priv->mon == NULL) {
1308 VIR_INFO("Failed to connect monitor for %s", vm->def->name);
1309 goto error;
1310 }
1311
1312
1313 qemuDomainObjEnterMonitorWithDriver(driver, vm);
1314 ret = qemuMonitorSetCapabilities(priv->mon);
1315 if (ret == 0 &&
1316 qemuCapsGet(priv->caps, QEMU_CAPS_MONITOR_JSON))
1317 ret = qemuCapsProbeQMP(priv->caps, priv->mon);
1318 qemuDomainObjExitMonitorWithDriver(driver, vm);
1319
1320error:
1321
1322 return ret;
1323}
1324
1325typedef int qemuProcessLogHandleOutput(virDomainObjPtr vm,
1326 const char *output,
1327 int fd);
1328
1329/*
1330 * Returns -1 for error, 0 on success
1331 */
1332static int
1333qemuProcessReadLogOutput(virDomainObjPtr vm,
1334 int fd,
1335 char *buf,
1336 size_t buflen,
1337 qemuProcessLogHandleOutput func,
1338 const char *what,
1339 int timeout)
1340{
1341 int retries = (timeout*10);
1342 int got = 0;
1343 char *debug = NULL;
1344 int ret = -1;
1345 char *filter_next = buf;
1346
1347 buf[0] = '\0';
1348
1349 /* This relies on log message format generated by virLogFormatString() and
1350 * might need to be modified when message format changes. */
1351 if (virAsprintf(&debug, ": %d: debug : ", vm->pid) < 0) {
1352 virReportOOMError();
1353 return -1;
1354 }
1355
1356 while (retries) {
1357 ssize_t func_ret, bytes;
1358 int isdead = 0;
1359 char *eol;
1360
1361 func_ret = func(vm, buf, fd);
1362
1363 if (kill(vm->pid, 0) == -1 && errno == ESRCH)
1364 isdead = 1;
1365
1366 /* Any failures should be detected before we read the log, so we
1367 * always have something useful to report on failure. */
1368 bytes = saferead(fd, buf+got, buflen-got-1);
1369 if (bytes < 0) {
1370 virReportSystemError(errno,
1371 _("Failure while reading %s log output"),
1372 what);
1373 goto cleanup;
1374 }
1375
1376 got += bytes;
1377 buf[got] = '\0';
1378
1379 /* Filter out debug messages from intermediate libvirt process */
1380 while ((eol = strchr(filter_next, '\n'))) {
1381 *eol = '\0';
1382 if (strstr(filter_next, debug)) {
1383 memmove(filter_next, eol + 1, got - (eol - buf));
1384 got -= eol + 1 - filter_next;
1385 } else {
1386 filter_next = eol + 1;
1387 *eol = '\n';
1388 }
1389 }
1390
1391 if (got == buflen-1) {
1392 virReportError(VIR_ERR_INTERNAL_ERROR,
1393 _("Out of space while reading %s log output: %s"),
1394 what, buf);
1395 goto cleanup;
1396 }
1397
1398 if (isdead) {
1399 virReportError(VIR_ERR_INTERNAL_ERROR,
1400 _("Process exited while reading %s log output: %s"),
1401 what, buf);
1402 goto cleanup;
1403 }
1404
1405 if (func_ret <= 0) {
1406 ret = func_ret;
1407 goto cleanup;
1408 }
1409
1410 usleep(100*1000);
1411 retries--;
1412 }
1413
1414 virReportError(VIR_ERR_INTERNAL_ERROR,
1415 _("Timed out while reading %s log output: %s"),
1416 what, buf);
1417
1418cleanup:
1419 VIR_FREE(debug);
1420 return ret;
1421}
1422
1423
1424/*
1425 * Look at a chunk of data from the QEMU stdout logs and try to
1426 * find a TTY device, as indicated by a line like
1427 *
1428 * char device redirected to /dev/pts/3
1429 *
1430 * Returns -1 for error, 0 success, 1 continue reading
1431 */
1432static int
1433qemuProcessExtractTTYPath(const char *haystack,
1434 size_t *offset,
1435 char **path)
1436{
1437 static const char needle[] = "char device redirected to";
1438 char *tmp, *dev;
1439
1440 VIR_FREE(*path);
1441 /* First look for our magic string */
1442 if (!(tmp = strstr(haystack + *offset, needle))) {
1443 return 1;
1444 }
1445 tmp += sizeof(needle);
1446 dev = tmp;
1447
1448 /*
1449 * And look for first whitespace character and nul terminate
1450 * to mark end of the pty path
1451 */
1452 while (*tmp) {
1453 if (c_isspace(*tmp)) {
1454 *path = strndup(dev, tmp-dev);
1455 if (*path == NULL) {
1456 virReportOOMError();
1457 return -1;
1458 }
1459
1460 /* ... now further update offset till we get EOL */
1461 *offset = tmp - haystack;
1462 return 0;
1463 }
1464 tmp++;
1465 }
1466
1467 /*
1468 * We found a path, but didn't find any whitespace,
1469 * so it must be still incomplete - we should at
1470 * least see a \n - indicate that we want to carry
1471 * on trying again
1472 */
1473 return 1;
1474}
1475
1476static int
1477qemuProcessLookupPTYs(virDomainChrDefPtr *devices,
1478 int count,
1479 virHashTablePtr paths,
1480 bool chardevfmt)
1481{
1482 int i;
1483 const char *prefix = chardevfmt ? "char" : "";
1484
1485 for (i = 0 ; i < count ; i++) {
1486 virDomainChrDefPtr chr = devices[i];
1487 if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
1488 char id[32];
1489 const char *path;
1490
1491 if (snprintf(id, sizeof(id), "%s%s",
1492 prefix, chr->info.alias) >= sizeof(id))
1493 return -1;
1494
1495 path = (const char *) virHashLookup(paths, id);
1496 if (path == NULL) {
1497 if (chr->source.data.file.path == NULL) {
1498 /* neither the log output nor 'info chardev' had a
1499 * pty path for this chardev, report an error
1500 */
1501 virReportError(VIR_ERR_INTERNAL_ERROR,
1502 _("no assigned pty for device %s"), id);
1503 return -1;
1504 } else {
1505 /* 'info chardev' had no pty path for this chardev,
1506 * but the log output had, so we're fine
1507 */
1508 continue;
1509 }
1510 }
1511
1512 VIR_FREE(chr->source.data.file.path);
1513 chr->source.data.file.path = strdup(path);
1514
1515 if (chr->source.data.file.path == NULL) {
1516 virReportOOMError();
1517 return -1;
1518 }
1519 }
1520 }
1521
1522 return 0;
1523}
1524
1525static int
1526qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm,
1527 qemuCapsPtr caps,
1528 virHashTablePtr paths)
1529{
1530 bool chardevfmt = qemuCapsGet(caps, QEMU_CAPS_CHARDEV);
1531
1532 if (qemuProcessLookupPTYs(vm->def->serials, vm->def->nserials,
1533 paths, chardevfmt) < 0)
1534 return -1;
1535
1536 if (qemuProcessLookupPTYs(vm->def->parallels, vm->def->nparallels,
1537 paths, chardevfmt) < 0)
1538 return -1;
1539
1540 if (qemuProcessLookupPTYs(vm->def->channels, vm->def->nchannels,
1541 paths, chardevfmt) < 0)
1542 return -1;
1543
1544 if (qemuProcessLookupPTYs(vm->def->consoles, vm->def->nconsoles,
1545 paths, chardevfmt) < 0)
1546 return -1;
1547
1548 return 0;
1549}
1550
1551static int
1552qemuProcessFindCharDevicePTYs(virDomainObjPtr vm,
1553 const char *output,
1554 int fd ATTRIBUTE_UNUSED)
1555{
1556 size_t offset = 0;
1557 int ret, i;
1558
1559 /* The order in which QEMU prints out the PTY paths is
1560 the order in which it procsses its serial and parallel
1561 device args. This code must match that ordering.... */
1562
1563 /* first comes the serial devices */
1564 for (i = 0 ; i < vm->def->nserials ; i++) {
1565 virDomainChrDefPtr chr = vm->def->serials[i];
1566 if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
1567 if ((ret = qemuProcessExtractTTYPath(output, &offset,
1568 &chr->source.data.file.path)) != 0)
1569 return ret;
1570 }
1571 }
1572
1573 /* then the parallel devices */
1574 for (i = 0 ; i < vm->def->nparallels ; i++) {
1575 virDomainChrDefPtr chr = vm->def->parallels[i];
1576 if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
1577 if ((ret = qemuProcessExtractTTYPath(output, &offset,
1578 &chr->source.data.file.path)) != 0)
1579 return ret;
1580 }
1581 }
1582
1583 /* then the channel devices */
1584 for (i = 0 ; i < vm->def->nchannels ; i++) {
1585 virDomainChrDefPtr chr = vm->def->channels[i];
1586 if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
1587 if ((ret = qemuProcessExtractTTYPath(output, &offset,
1588 &chr->source.data.file.path)) != 0)
1589 return ret;
1590 }
1591 }
1592
1593 for (i = 0 ; i < vm->def->nconsoles ; i++) {
1594 virDomainChrDefPtr chr = vm->def->consoles[i];
1595 /* For historical reasons, console[0] can be just an alias
1596 * for serial[0]; That's why we need to update it as well */
1597 if (i == 0 && vm->def->nserials &&
1598 chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
1599 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
1600 if ((ret = virDomainChrSourceDefCopy(&chr->source,
1601 &((vm->def->serials[0])->source))) != 0)
1602 return ret;
1603 } else {
1604 if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY &&
1605 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) {
1606 if ((ret = qemuProcessExtractTTYPath(output, &offset,
1607 &chr->source.data.file.path)) != 0)
1608 return ret;
1609 }
1610 }
1611 }
1612
1613 return 0;
1614}
1615
1616static void qemuProcessFreePtyPath(void *payload, const void *name ATTRIBUTE_UNUSED)
1617{
1618 VIR_FREE(payload);
1619}
1620
1621static void
1622qemuProcessReadLogFD(int logfd, char *buf, int maxlen, int off)
1623{
1624 int ret;
1625 char *tmpbuf = buf + off;
1626
1627 ret = saferead(logfd, tmpbuf, maxlen - off - 1);
1628 if (ret < 0) {
1629 ret = 0;
1630 }
1631
1632 tmpbuf[ret] = '\0';
1633}
1634
1635
1636static int
1637qemuProcessWaitForMonitor(struct qemud_driver* driver,
1638 virDomainObjPtr vm,
1639 qemuCapsPtr caps,
1640 off_t pos)
1641{
1642 char *buf = NULL;
1643 size_t buf_size = 4096; /* Plenty of space to get startup greeting */
1644 int logfd = -1;
1645 int ret = -1;
1646 virHashTablePtr paths = NULL;
1647 qemuDomainObjPrivatePtr priv;
1648
1649 if (pos != -1) {
1650 if ((logfd = qemuDomainOpenLog(driver, vm, pos)) < 0)
1651 return -1;
1652
1653 if (VIR_ALLOC_N(buf, buf_size) < 0) {
1654 virReportOOMError();
1655 goto closelog;
1656 }
1657
1658 if (qemuProcessReadLogOutput(vm, logfd, buf, buf_size,
1659 qemuProcessFindCharDevicePTYs,
1660 "console", 30) < 0)
1661 goto closelog;
1662 }
1663
1664 VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
1665 if (qemuConnectMonitor(driver, vm) < 0) {
1666 goto cleanup;
1667 }
1668
1669 /* Try to get the pty path mappings again via the monitor. This is much more
1670 * reliable if it's available.
1671 * Note that the monitor itself can be on a pty, so we still need to try the
1672 * log output method. */
1673 paths = virHashCreate(0, qemuProcessFreePtyPath);
1674 if (paths == NULL)
1675 goto cleanup;
1676
1677 priv = vm->privateData;
1678 qemuDomainObjEnterMonitorWithDriver(driver, vm);
1679 ret = qemuMonitorGetPtyPaths(priv->mon, paths);
1680 qemuDomainObjExitMonitorWithDriver(driver, vm);
1681
1682 VIR_DEBUG("qemuMonitorGetPtyPaths returned %i", ret);
1683 if (ret == 0)
1684 ret = qemuProcessFindCharDevicePTYsMonitor(vm, caps, paths);
1685
1686cleanup:
1687 virHashFree(paths);
1688
1689 if (pos != -1 && kill(vm->pid, 0) == -1 && errno == ESRCH) {
1690 /* VM is dead, any other error raised in the interim is probably
1691 * not as important as the qemu cmdline output */
1692 qemuProcessReadLogFD(logfd, buf, buf_size, strlen(buf));
1693 virReportError(VIR_ERR_INTERNAL_ERROR,
1694 _("process exited while connecting to monitor: %s"),
1695 buf);
1696 ret = -1;
1697 }
1698
1699closelog:
1700 if (VIR_CLOSE(logfd) < 0) {
1701 char ebuf[1024];
1702 VIR_WARN("Unable to close logfile: %s",
1703 virStrerror(errno, ebuf, sizeof(ebuf)));
1704 }
1705
1706 VIR_FREE(buf);
1707
1708 return ret;
1709}
1710
1711static int
1712qemuProcessDetectVcpuPIDs(struct qemud_driver *driver,
1713 virDomainObjPtr vm)
1714{
1715 pid_t *cpupids = NULL;
1716 int ncpupids;
1717 qemuDomainObjPrivatePtr priv = vm->privateData;
1718
1719 qemuDomainObjEnterMonitorWithDriver(driver, vm);
1720 /* failure to get the VCPU<-> PID mapping or to execute the query
1721 * command will not be treated fatal as some versions of qemu don't
1722 * support this command */
1723 if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) <= 0) {
1724 qemuDomainObjExitMonitorWithDriver(driver, vm);
1725 virResetLastError();
1726
1727 priv->nvcpupids = 1;
1728 if (VIR_ALLOC_N(priv->vcpupids, priv->nvcpupids) < 0) {
1729 virReportOOMError();
1730 return -1;
1731 }
1732 priv->vcpupids[0] = vm->pid;
1733 return 0;
1734 }
1735 qemuDomainObjExitMonitorWithDriver(driver, vm);
1736
1737 if (ncpupids != vm->def->vcpus) {
1738 virReportError(VIR_ERR_INTERNAL_ERROR,
1739 _("got wrong number of vCPU pids from QEMU monitor. "
1740 "got %d, wanted %d"),
1741 ncpupids, vm->def->vcpus);
1742 VIR_FREE(cpupids);
1743 return -1;
1744 }
1745
1746 priv->nvcpupids = ncpupids;
1747 priv->vcpupids = cpupids;
1748 return 0;
1749}
1750
1751
1752/*
1753 * Set NUMA memory policy for qemu process, to be run between
1754 * fork/exec of QEMU only.
1755 */
1756#if HAVE_NUMACTL
1757static int
1758qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
1759 virBitmapPtr nodemask)
1760{
1761 nodemask_t mask;
1762 int mode = -1;
1763 int node = -1;
1764 int ret = -1;
1765 int i = 0;
1766 int maxnode = 0;
1767 bool warned = false;
1768 virDomainNumatuneDef numatune = vm->def->numatune;
1769 virBitmapPtr tmp_nodemask = NULL;
1770
1771 if (numatune.memory.placement_mode ==
1772 VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
1773 if (!numatune.memory.nodemask)
1774 return 0;
1775 VIR_DEBUG("Set NUMA memory policy with specified nodeset");
1776 tmp_nodemask = numatune.memory.nodemask;
1777 } else if (numatune.memory.placement_mode ==
1778 VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
1779 VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
1780 tmp_nodemask = nodemask;
1781 } else {
1782 return 0;
1783 }
1784
1785 if (numa_available() < 0) {
1786 virReportError(VIR_ERR_INTERNAL_ERROR,
1787 "%s", _("Host kernel is not aware of NUMA."));
1788 return -1;
1789 }
1790
1791 maxnode = numa_max_node() + 1;
1792 /* Convert nodemask to NUMA bitmask. */
1793 nodemask_zero(&mask);
1794 i = -1;
1795 while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
1796 if (i > NUMA_NUM_NODES) {
1797 virReportError(VIR_ERR_INTERNAL_ERROR,
1798 _("Host cannot support NUMA node %d"), i);
1799 return -1;
1800 }
1801 if (i > maxnode && !warned) {
1802 VIR_WARN("nodeset is out of range, there is only %d NUMA "
1803 "nodes on host", maxnode);
1804 warned = true;
1805 }
1806 nodemask_set(&mask, i);
1807 }
1808
1809 mode = numatune.memory.mode;
1810
1811 if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
1812 numa_set_bind_policy(1);
1813 numa_set_membind(&mask);
1814 numa_set_bind_policy(0);
1815 } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
1816 int nnodes = 0;
1817 for (i = 0; i < NUMA_NUM_NODES; i++) {
1818 if (nodemask_isset(&mask, i)) {
1819 node = i;
1820 nnodes++;
1821 }
1822 }
1823
1824 if (nnodes != 1) {
1825 virReportError(VIR_ERR_INTERNAL_ERROR,
1826 "%s", _("NUMA memory tuning in 'preferred' mode "
1827 "only supports single node"));
1828 goto cleanup;
1829 }
1830
1831 numa_set_bind_policy(0);
1832 numa_set_preferred(node);
1833 } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
1834 numa_set_interleave_mask(&mask);
1835 } else {
1836 /* XXX: Shouldn't go here, as we already do checking when
1837 * parsing domain XML.
1838 */
1839 virReportError(VIR_ERR_XML_ERROR,
1840 "%s", _("Invalid mode for memory NUMA tuning."));
1841 goto cleanup;
1842 }
1843
1844 ret = 0;
1845
1846cleanup:
1847 return ret;
1848}
1849#else
1850static int
1851qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
1852 virBitmapPtr nodemask ATTRIBUTE_UNUSED)
1853{
1854 if (vm->def->numatune.memory.nodemask) {
1855 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1856 _("libvirt is compiled without NUMA tuning support"));
1857
1858 return -1;
1859 }
1860
1861 return 0;
1862}
1863#endif
1864
1865#if HAVE_NUMAD
1866static char *
1867qemuGetNumadAdvice(virDomainDefPtr def)
1868{
1869 virCommandPtr cmd = NULL;
1870 char *output = NULL;
1871
1872 cmd = virCommandNewArgList(NUMAD, "-w", NULL);
1873 virCommandAddArgFormat(cmd, "%d:%llu", def->vcpus,
1874 VIR_DIV_UP(def->mem.cur_balloon, 1024));
1875
1876 virCommandSetOutputBuffer(cmd, &output);
1877
1878 if (virCommandRun(cmd, NULL) < 0)
1879 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1880 _("Failed to query numad for the "
1881 "advisory nodeset"));
1882
1883 virCommandFree(cmd);
1884 return output;
1885}
1886#else
1887static char *
1888qemuGetNumadAdvice(virDomainDefPtr def ATTRIBUTE_UNUSED)
1889{
1890 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
1891 _("numad is not available on this host"));
1892 return NULL;
1893}
1894#endif
1895
1896/* Helper to prepare cpumap for affinity setting, convert
1897 * NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
1898 * just return a new allocated bitmap.
1899 */
1900virBitmapPtr
1901qemuPrepareCpumap(struct qemud_driver *driver,
1902 virBitmapPtr nodemask)
1903{
1904 int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
1905 virNodeInfo nodeinfo;
1906 virBitmapPtr cpumap = NULL;
1907
1908 if (nodeGetInfo(NULL, &nodeinfo) < 0)
1909 return NULL;
1910
1911 /* setaffinity fails if you set bits for CPUs which
1912 * aren't present, so we have to limit ourselves */
1913 hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
1914 if (maxcpu > hostcpus)
1915 maxcpu = hostcpus;
1916
1917 if (!(cpumap = virBitmapNew(maxcpu))) {
1918 virReportOOMError();
1919 return NULL;
1920 }
1921
1922 if (nodemask) {
1923 for (i = 0; i < driver->caps->host.nnumaCell; i++) {
1924 int j;
1925 int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
1926 bool result;
1927 if (virBitmapGetBit(nodemask, i, &result) < 0) {
1928 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1929 _("Failed to convert nodeset to cpuset"));
1930 virBitmapFree(cpumap);
1931 return NULL;
1932 }
1933 if (result) {
1934 for (j = 0; j < cur_ncpus; j++)
1935 ignore_value(virBitmapSetBit(cpumap,
1936 driver->caps->host.numaCell[i]->cpus[j]));
1937 }
1938 }
1939 }
1940
1941 return cpumap;
1942}
1943
1944/*
1945 * To be run between fork/exec of QEMU only
1946 */
1947static int
1948qemuProcessInitCpuAffinity(struct qemud_driver *driver,
1949 virDomainObjPtr vm,
1950 virBitmapPtr nodemask)
1951{
1952 int ret = -1;
1953 virBitmapPtr cpumap = NULL;
1954 virBitmapPtr cpumapToSet = NULL;
1955
1956 if (!(cpumap = qemuPrepareCpumap(driver, nodemask)))
1957 return -1;
1958
1959 if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
1960 VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
1961 cpumapToSet = cpumap;
1962 } else {
1963 VIR_DEBUG("Set CPU affinity with specified cpuset");
1964 if (vm->def->cpumask) {
1965 cpumapToSet = vm->def->cpumask;
1966 } else {
1967 cpumapToSet = cpumap;
1968 /* You may think this is redundant, but we can't assume libvirtd
1969 * itself is running on all pCPUs, so we need to explicitly set
1970 * the spawned QEMU instance to all pCPUs if no map is given in
1971 * its config file */
1972 virBitmapSetAll(cpumap);
1973 }
1974 }
1975
1976 /* We are pressuming we are running between fork/exec of QEMU
1977 * so use '0' to indicate our own process ID. No threads are
1978 * running at this point
1979 */
1980 if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0)
1981 goto cleanup;
1982
1983 ret = 0;
1984
1985cleanup:
1986 virBitmapFree(cpumap);
1987 return ret;
1988}
1989
1990/* set link states to down on interfaces at qemu start */
1991static int
1992qemuProcessSetLinkStates(virDomainObjPtr vm)
1993{
1994 qemuDomainObjPrivatePtr priv = vm->privateData;
1995 virDomainDefPtr def = vm->def;
1996 int i;
1997 int ret = 0;
1998
1999 for (i = 0; i < def->nnets; i++) {
2000 if (def->nets[i]->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
2001 VIR_DEBUG("Setting link state: %s", def->nets[i]->info.alias);
2002
2003 if (!qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV)) {
2004 virReportError(VIR_ERR_NO_SUPPORT, "%s",
2005 _("Setting of link state is not supported by this qemu"));
2006 return -1;
2007 }
2008
2009 ret = qemuMonitorSetLink(priv->mon,
2010 def->nets[i]->info.alias,
2011 VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN);
2012 if (ret != 0) {
2013 virReportError(VIR_ERR_OPERATION_FAILED,
2014 _("Couldn't set link state on interface: %s"), def->nets[i]->info.alias);
2015 break;
2016 }
2017 }
2018 }
2019
2020 return ret;
2021}
2022
2023/* Set CPU affinities for vcpus if vcpupin xml provided. */
2024static int
2025qemuProcessSetVcpuAffinites(virConnectPtr conn ATTRIBUTE_UNUSED,
2026 virDomainObjPtr vm)
2027{
2028 qemuDomainObjPrivatePtr priv = vm->privateData;
2029 virDomainDefPtr def = vm->def;
2030 int vcpu, n;
2031 int ret = -1;
2032
2033 if (!def->cputune.nvcpupin)
2034 return 0;
2035
2036 if (priv->vcpupids == NULL) {
2037 virReportError(VIR_ERR_OPERATION_INVALID,
2038 "%s", _("cpu affinity is not supported"));
2039 return -1;
2040 }
2041
2042 for (n = 0; n < def->cputune.nvcpupin; n++) {
2043 vcpu = def->cputune.vcpupin[n]->vcpuid;
2044
2045 if (virProcessInfoSetAffinity(priv->vcpupids[vcpu],
2046 def->cputune.vcpupin[n]->cpumask) < 0) {
2047 goto cleanup;
2048 }
2049 }
2050
2051 ret = 0;
2052cleanup:
2053 return ret;
2054}
2055
2056/* Set CPU affinities for emulator threads. */
2057static int
2058qemuProcessSetEmulatorAffinites(virConnectPtr conn ATTRIBUTE_UNUSED,
2059 virDomainObjPtr vm)
2060{
2061 virBitmapPtr cpumask;
2062 virDomainDefPtr def = vm->def;
2063 int ret = -1;
2064
2065 if (def->cputune.emulatorpin)
2066 cpumask = def->cputune.emulatorpin->cpumask;
2067 else if (def->cpumask)
2068 cpumask = def->cpumask;
2069 else
2070 return 0;
2071
2072 ret = virProcessInfoSetAffinity(vm->pid, cpumask);
2073 return ret;
2074}
2075
2076static int
2077qemuProcessInitPasswords(virConnectPtr conn,
2078 struct qemud_driver *driver,
2079 virDomainObjPtr vm)
2080{
2081 int ret = 0;
2082 qemuDomainObjPrivatePtr priv = vm->privateData;
2083
2084 if (vm->def->ngraphics == 1) {
2085 if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
2086 ret = qemuDomainChangeGraphicsPasswords(driver, vm,
2087 VIR_DOMAIN_GRAPHICS_TYPE_VNC,
2088 &vm->def->graphics[0]->data.vnc.auth,
2089 driver->vncPassword);
2090 } else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
2091 ret = qemuDomainChangeGraphicsPasswords(driver, vm,
2092 VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
2093 &vm->def->graphics[0]->data.spice.auth,
2094 driver->spicePassword);
2095 }
2096 }
2097
2098 if (ret < 0)
2099 goto cleanup;
2100
2101 if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) {
2102 int i;
2103
2104 for (i = 0 ; i < vm->def->ndisks ; i++) {
2105 char *secret;
2106 size_t secretLen;
2107 const char *alias;
2108
2109 if (!vm->def->disks[i]->encryption ||
2110 !vm->def->disks[i]->src)
2111 continue;
2112
2113 if (qemuProcessGetVolumeQcowPassphrase(conn,
2114 vm->def->disks[i],
2115 &secret, &secretLen) < 0)
2116 goto cleanup;
2117
2118 alias = vm->def->disks[i]->info.alias;
2119 qemuDomainObjEnterMonitorWithDriver(driver, vm);
2120 ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret);
2121 VIR_FREE(secret);
2122 qemuDomainObjExitMonitorWithDriver(driver, vm);
2123 if (ret < 0)
2124 goto cleanup;
2125 }
2126 }
2127
2128cleanup:
2129 return ret;
2130}
2131
2132
2133#define QEMU_PCI_VENDOR_INTEL 0x8086
2134#define QEMU_PCI_VENDOR_LSI_LOGIC 0x1000
2135#define QEMU_PCI_VENDOR_REDHAT 0x1af4
2136#define QEMU_PCI_VENDOR_CIRRUS 0x1013
2137#define QEMU_PCI_VENDOR_REALTEK 0x10ec
2138#define QEMU_PCI_VENDOR_AMD 0x1022
2139#define QEMU_PCI_VENDOR_ENSONIQ 0x1274
2140#define QEMU_PCI_VENDOR_VMWARE 0x15ad
2141#define QEMU_PCI_VENDOR_QEMU 0x1234
2142
2143#define QEMU_PCI_PRODUCT_DISK_VIRTIO 0x1001
2144
2145#define QEMU_PCI_PRODUCT_BALLOON_VIRTIO 0x1002
2146
2147#define QEMU_PCI_PRODUCT_NIC_NE2K 0x8029
2148#define QEMU_PCI_PRODUCT_NIC_PCNET 0x2000
2149#define QEMU_PCI_PRODUCT_NIC_RTL8139 0x8139
2150#define QEMU_PCI_PRODUCT_NIC_E1000 0x100E
2151#define QEMU_PCI_PRODUCT_NIC_VIRTIO 0x1000
2152
2153#define QEMU_PCI_PRODUCT_VGA_CIRRUS 0x00b8
2154#define QEMU_PCI_PRODUCT_VGA_VMWARE 0x0405
2155#define QEMU_PCI_PRODUCT_VGA_STDVGA 0x1111
2156
2157#define QEMU_PCI_PRODUCT_AUDIO_AC97 0x2415
2158#define QEMU_PCI_PRODUCT_AUDIO_ES1370 0x5000
2159
2160#define QEMU_PCI_PRODUCT_CONTROLLER_PIIX 0x7010
2161#define QEMU_PCI_PRODUCT_CONTROLLER_LSI 0x0012
2162
2163#define QEMU_PCI_PRODUCT_WATCHDOG_I63000ESB 0x25ab
2164
2165static int
2166qemuProcessAssignNextPCIAddress(virDomainDeviceInfo *info,
2167 int vendor,
2168 int product,
2169 qemuMonitorPCIAddress *addrs,
2170 int naddrs)
2171{
2172 int found = 0;
2173 int i;
2174
2175 VIR_DEBUG("Look for %x:%x out of %d", vendor, product, naddrs);
2176
2177 for (i = 0 ; (i < naddrs) && !found; i++) {
2178 VIR_DEBUG("Maybe %x:%x", addrs[i].vendor, addrs[i].product);
2179 if (addrs[i].vendor == vendor &&
2180 addrs[i].product == product) {
2181 VIR_DEBUG("Match %d", i);
2182 found = 1;
2183 break;
2184 }
2185 }
2186 if (!found) {
2187 return -1;
2188 }
2189
2190 /* Blank it out so this device isn't matched again */
2191 addrs[i].vendor = 0;
2192 addrs[i].product = 0;
2193
2194 if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
2195 info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
2196
2197 if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2198 info->addr.pci.domain = addrs[i].addr.domain;
2199 info->addr.pci.bus = addrs[i].addr.bus;
2200 info->addr.pci.slot = addrs[i].addr.slot;
2201 info->addr.pci.function = addrs[i].addr.function;
2202 }
2203
2204 return 0;
2205}
2206
2207static int
2208qemuProcessGetPCIDiskVendorProduct(virDomainDiskDefPtr def,
2209 unsigned *vendor,
2210 unsigned *product)
2211{
2212 switch (def->bus) {
2213 case VIR_DOMAIN_DISK_BUS_VIRTIO:
2214 *vendor = QEMU_PCI_VENDOR_REDHAT;
2215 *product = QEMU_PCI_PRODUCT_DISK_VIRTIO;
2216 break;
2217
2218 default:
2219 return -1;
2220 }
2221
2222 return 0;
2223}
2224
2225static int
2226qemuProcessGetPCINetVendorProduct(virDomainNetDefPtr def,
2227 unsigned *vendor,
2228 unsigned *product)
2229{
2230 if (!def->model)
2231 return -1;
2232
2233 if (STREQ(def->model, "ne2k_pci")) {
2234 *vendor = QEMU_PCI_VENDOR_REALTEK;
2235 *product = QEMU_PCI_PRODUCT_NIC_NE2K;
2236 } else if (STREQ(def->model, "pcnet")) {
2237 *vendor = QEMU_PCI_VENDOR_AMD;
2238 *product = QEMU_PCI_PRODUCT_NIC_PCNET;
2239 } else if (STREQ(def->model, "rtl8139")) {
2240 *vendor = QEMU_PCI_VENDOR_REALTEK;
2241 *product = QEMU_PCI_PRODUCT_NIC_RTL8139;
2242 } else if (STREQ(def->model, "e1000")) {
2243 *vendor = QEMU_PCI_VENDOR_INTEL;
2244 *product = QEMU_PCI_PRODUCT_NIC_E1000;
2245 } else if (STREQ(def->model, "virtio")) {
2246 *vendor = QEMU_PCI_VENDOR_REDHAT;
2247 *product = QEMU_PCI_PRODUCT_NIC_VIRTIO;
2248 } else {
2249 VIR_INFO("Unexpected NIC model %s, cannot get PCI address",
2250 def->model);
2251 return -1;
2252 }
2253 return 0;
2254}
2255
2256static int
2257qemuProcessGetPCIControllerVendorProduct(virDomainControllerDefPtr def,
2258 unsigned *vendor,
2259 unsigned *product)
2260{
2261 switch (def->type) {
2262 case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
2263 *vendor = QEMU_PCI_VENDOR_LSI_LOGIC;
2264 *product = QEMU_PCI_PRODUCT_CONTROLLER_LSI;
2265 break;
2266
2267 case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
2268 /* XXX we could put in the ISA bridge address, but
2269 that's not technically the FDC's address */
2270 return -1;
2271
2272 case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
2273 *vendor = QEMU_PCI_VENDOR_INTEL;
2274 *product = QEMU_PCI_PRODUCT_CONTROLLER_PIIX;
2275 break;
2276
2277 default:
2278 VIR_INFO("Unexpected controller type %s, cannot get PCI address",
2279 virDomainControllerTypeToString(def->type));
2280 return -1;
2281 }
2282
2283 return 0;
2284}
2285
2286static int
2287qemuProcessGetPCIVideoVendorProduct(virDomainVideoDefPtr def,
2288 unsigned *vendor,
2289 unsigned *product)
2290{
2291 switch (def->type) {
2292 case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
2293 *vendor = QEMU_PCI_VENDOR_CIRRUS;
2294 *product = QEMU_PCI_PRODUCT_VGA_CIRRUS;
2295 break;
2296
2297 case VIR_DOMAIN_VIDEO_TYPE_VGA:
2298 *vendor = QEMU_PCI_VENDOR_QEMU;
2299 *product = QEMU_PCI_PRODUCT_VGA_STDVGA;
2300 break;
2301
2302 case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
2303 *vendor = QEMU_PCI_VENDOR_VMWARE;
2304 *product = QEMU_PCI_PRODUCT_VGA_VMWARE;
2305 break;
2306
2307 default:
2308 return -1;
2309 }
2310 return 0;
2311}
2312
2313static int
2314qemuProcessGetPCISoundVendorProduct(virDomainSoundDefPtr def,
2315 unsigned *vendor,
2316 unsigned *product)
2317{
2318 switch (def->model) {
2319 case VIR_DOMAIN_SOUND_MODEL_ES1370:
2320 *vendor = QEMU_PCI_VENDOR_ENSONIQ;
2321 *product = QEMU_PCI_PRODUCT_AUDIO_ES1370;
2322 break;
2323
2324 case VIR_DOMAIN_SOUND_MODEL_AC97:
2325 *vendor = QEMU_PCI_VENDOR_INTEL;
2326 *product = QEMU_PCI_PRODUCT_AUDIO_AC97;
2327 break;
2328
2329 default:
2330 return -1;
2331 }
2332
2333 return 0;
2334}
2335
2336static int
2337qemuProcessGetPCIWatchdogVendorProduct(virDomainWatchdogDefPtr def,
2338 unsigned *vendor,
2339 unsigned *product)
2340{
2341 switch (def->model) {
2342 case VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB:
2343 *vendor = QEMU_PCI_VENDOR_INTEL;
2344 *product = QEMU_PCI_PRODUCT_WATCHDOG_I63000ESB;
2345 break;
2346
2347 default:
2348 return -1;
2349 }
2350
2351 return 0;
2352}
2353
2354
2355static int
2356qemuProcessGetPCIMemballoonVendorProduct(virDomainMemballoonDefPtr def,
2357 unsigned *vendor,
2358 unsigned *product)
2359{
2360 switch (def->model) {
2361 case VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO:
2362 *vendor = QEMU_PCI_VENDOR_REDHAT;
2363 *product = QEMU_PCI_PRODUCT_BALLOON_VIRTIO;
2364 break;
2365
2366 default:
2367 return -1;
2368 }
2369
2370 return 0;
2371}
2372
2373
2374/*
2375 * This entire method assumes that PCI devices in 'info pci'
2376 * match ordering of devices specified on the command line
2377 * wrt to devices of matching vendor+product
2378 *
2379 * XXXX this might not be a valid assumption if we assign
2380 * some static addrs on CLI. Have to check that...
2381 */
2382static int
2383qemuProcessDetectPCIAddresses(virDomainObjPtr vm,
2384 qemuMonitorPCIAddress *addrs,
2385 int naddrs)
2386{
2387 unsigned int vendor = 0, product = 0;
2388 int i;
2389
2390 /* XXX should all these vendor/product IDs be kept in the
2391 * actual device data structure instead ?
2392 */
2393
2394 for (i = 0 ; i < vm->def->ndisks ; i++) {
2395 if (qemuProcessGetPCIDiskVendorProduct(vm->def->disks[i], &vendor, &product) < 0)
2396 continue;
2397
2398 if (qemuProcessAssignNextPCIAddress(&(vm->def->disks[i]->info),
2399 vendor, product,
2400 addrs, naddrs) < 0) {
2401 virReportError(VIR_ERR_INTERNAL_ERROR,
2402 _("cannot find PCI address for VirtIO disk %s"),
2403 vm->def->disks[i]->dst);
2404 return -1;
2405 }
2406 }
2407
2408 for (i = 0 ; i < vm->def->nnets ; i++) {
2409 if (qemuProcessGetPCINetVendorProduct(vm->def->nets[i], &vendor, &product) < 0)
2410 continue;
2411
2412 if (qemuProcessAssignNextPCIAddress(&(vm->def->nets[i]->info),
2413 vendor, product,
2414 addrs, naddrs) < 0) {
2415 virReportError(VIR_ERR_INTERNAL_ERROR,
2416 _("cannot find PCI address for %s NIC"),
2417 vm->def->nets[i]->model);
2418 return -1;
2419 }
2420 }
2421
2422 for (i = 0 ; i < vm->def->ncontrollers ; i++) {
2423 if (qemuProcessGetPCIControllerVendorProduct(vm->def->controllers[i], &vendor, &product) < 0)
2424 continue;
2425
2426 if (qemuProcessAssignNextPCIAddress(&(vm->def->controllers[i]->info),
2427 vendor, product,
2428 addrs, naddrs) < 0) {
2429 virReportError(VIR_ERR_INTERNAL_ERROR,
2430 _("cannot find PCI address for controller %s"),
2431 virDomainControllerTypeToString(vm->def->controllers[i]->type));
2432 return -1;
2433 }
2434 }
2435
2436 for (i = 0 ; i < vm->def->nvideos ; i++) {
2437 if (qemuProcessGetPCIVideoVendorProduct(vm->def->videos[i], &vendor, &product) < 0)
2438 continue;
2439
2440 if (qemuProcessAssignNextPCIAddress(&(vm->def->videos[i]->info),
2441 vendor, product,
2442 addrs, naddrs) < 0) {
2443 virReportError(VIR_ERR_INTERNAL_ERROR,
2444 _("cannot find PCI address for video adapter %s"),
2445 virDomainVideoTypeToString(vm->def->videos[i]->type));
2446 return -1;
2447 }
2448 }
2449
2450 for (i = 0 ; i < vm->def->nsounds ; i++) {
2451 if (qemuProcessGetPCISoundVendorProduct(vm->def->sounds[i], &vendor, &product) < 0)
2452 continue;
2453
2454 if (qemuProcessAssignNextPCIAddress(&(vm->def->sounds[i]->info),
2455 vendor, product,
2456 addrs, naddrs) < 0) {
2457 virReportError(VIR_ERR_INTERNAL_ERROR,
2458 _("cannot find PCI address for sound adapter %s"),
2459 virDomainSoundModelTypeToString(vm->def->sounds[i]->model));
2460 return -1;
2461 }
2462 }
2463
2464
2465 if (vm->def->watchdog &&
2466 qemuProcessGetPCIWatchdogVendorProduct(vm->def->watchdog, &vendor, &product) == 0) {
2467 if (qemuProcessAssignNextPCIAddress(&(vm->def->watchdog->info),
2468 vendor, product,
2469 addrs, naddrs) < 0) {
2470 virReportError(VIR_ERR_INTERNAL_ERROR,
2471 _("cannot find PCI address for watchdog %s"),
2472 virDomainWatchdogModelTypeToString(vm->def->watchdog->model));
2473 return -1;
2474 }
2475 }
2476
2477 if (vm->def->memballoon &&
2478 qemuProcessGetPCIMemballoonVendorProduct(vm->def->memballoon, &vendor, &product) == 0) {
2479 if (qemuProcessAssignNextPCIAddress(&(vm->def->memballoon->info),
2480 vendor, product,
2481 addrs, naddrs) < 0) {
2482 virReportError(VIR_ERR_INTERNAL_ERROR,
2483 _("cannot find PCI address for balloon %s"),
2484 virDomainMemballoonModelTypeToString(vm->def->memballoon->model));
2485 return -1;
2486 }
2487 }
2488
2489 /* XXX console (virtio) */
2490
2491
2492 /* ... and now things we don't have in our xml */
2493
2494 /* XXX USB controller ? */
2495
2496 /* XXX what about other PCI devices (ie bridges) */
2497
2498 return 0;
2499}
2500
2501static int
2502qemuProcessInitPCIAddresses(struct qemud_driver *driver,
2503 virDomainObjPtr vm)
2504{
2505 qemuDomainObjPrivatePtr priv = vm->privateData;
2506 int naddrs;
2507 int ret;
2508 qemuMonitorPCIAddress *addrs = NULL;
2509
2510 qemuDomainObjEnterMonitorWithDriver(driver, vm);
2511 naddrs = qemuMonitorGetAllPCIAddresses(priv->mon,
2512 &addrs);
2513 qemuDomainObjExitMonitorWithDriver(driver, vm);
2514
2515 ret = qemuProcessDetectPCIAddresses(vm, addrs, naddrs);
2516
2517 VIR_FREE(addrs);
2518
2519 return ret;
2520}
2521
2522
2523static int qemuProcessNextFreePort(struct qemud_driver *driver,
2524 int startPort)
2525{
2526 int i;
2527
2528 for (i = startPort ; i < driver->remotePortMax; i++) {
2529 int fd;
2530 int reuse = 1;
2531 struct sockaddr_in addr;
2532 bool used = false;
2533
2534 if (virBitmapGetBit(driver->reservedRemotePorts,
2535 i - driver->remotePortMin, &used) < 0)
2536 VIR_DEBUG("virBitmapGetBit failed on bit %d", i - driver->remotePortMin);
2537
2538 if (used)
2539 continue;
2540
2541 addr.sin_family = AF_INET;
2542 addr.sin_port = htons(i);
2543 addr.sin_addr.s_addr = htonl(INADDR_ANY);
2544 fd = socket(PF_INET, SOCK_STREAM, 0);
2545 if (fd < 0)
2546 return -1;
2547
2548 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
2549 VIR_FORCE_CLOSE(fd);
2550 break;
2551 }
2552
2553 if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
2554 /* Not in use, lets grab it */
2555 VIR_FORCE_CLOSE(fd);
2556 /* Add port to bitmap of reserved ports */
2557 if (virBitmapSetBit(driver->reservedRemotePorts,
2558 i - driver->remotePortMin) < 0) {
2559 VIR_DEBUG("virBitmapSetBit failed on bit %d",
2560 i - driver->remotePortMin);
2561 }
2562 return i;
2563 }
2564 VIR_FORCE_CLOSE(fd);
2565
2566 if (errno == EADDRINUSE) {
2567 /* In use, try next */
2568 continue;
2569 }
2570 /* Some other bad failure, get out.. */
2571 break;
2572 }
2573 return -1;
2574}
2575
2576
2577static void
2578qemuProcessReturnPort(struct qemud_driver *driver,
2579 int port)
2580{
2581 if (port < driver->remotePortMin)
2582 return;
2583
2584 if (virBitmapClearBit(driver->reservedRemotePorts,
2585 port - driver->remotePortMin) < 0)
2586 VIR_DEBUG("Could not mark port %d as unused", port);
2587}
2588
2589
2590static int
2591qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
2592 virDomainChrDefPtr dev,
2593 void *opaque ATTRIBUTE_UNUSED)
2594{
2595 int fd;
2596 if (dev->source.type != VIR_DOMAIN_CHR_TYPE_FILE)
2597 return 0;
2598
2599 if ((fd = open(dev->source.data.file.path,
2600 O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) {
2601 virReportSystemError(errno,
2602 _("Unable to pre-create chardev file '%s'"),
2603 dev->source.data.file.path);
2604 return -1;
2605 }
2606
2607 VIR_FORCE_CLOSE(fd);
2608
2609 return 0;
2610}
2611
2612
2613static int
2614qemuProcessLimits(struct qemud_driver *driver)
2615{
2616 struct rlimit rlim;
2617
2618 if (driver->maxProcesses > 0) {
2619 rlim.rlim_cur = rlim.rlim_max = driver->maxProcesses;
2620 if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
2621 virReportSystemError(errno,
2622 _("cannot limit number of processes to %d"),
2623 driver->maxProcesses);
2624 return -1;
2625 }
2626 }
2627
2628 if (driver->maxFiles > 0) {
2629 /* Max number of opened files is one greater than
2630 * actual limit. See man setrlimit */
2631 rlim.rlim_cur = rlim.rlim_max = driver->maxFiles + 1;
2632 if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
2633 virReportSystemError(errno,
2634 _("cannot set max opened files to %d"),
2635 driver->maxFiles);
2636 return -1;
2637 }
2638 }
2639
2640 return 0;
2641}
2642
2643
2644struct qemuProcessHookData {
2645 virConnectPtr conn;
2646 virDomainObjPtr vm;
2647 struct qemud_driver *driver;
2648 virBitmapPtr nodemask;
2649};
2650
2651static int qemuProcessHook(void *data)
2652{
2653 struct qemuProcessHookData *h = data;
2654 int ret = -1;
2655 int fd;
2656
2657 /* Some later calls want pid present */
2658 h->vm->pid = getpid();
2659
2660 VIR_DEBUG("Obtaining domain lock");
2661 /*
2662 * Since we're going to leak the returned FD to QEMU,
2663 * we need to make sure it gets a sensible label.
2664 * This mildly sucks, because there could be other
2665 * sockets the lock driver opens that we don't want
2666 * labelled. So far we're ok though.
2667 */
2668 if (virSecurityManagerSetSocketLabel(h->driver->securityManager, h->vm->def) < 0)
2669 goto cleanup;
2670 if (virDomainLockProcessStart(h->driver->lockManager,
2671 h->driver->uri,
2672 h->vm,
2673 /* QEMU is always paused initially */
2674 true,
2675 &fd) < 0)
2676 goto cleanup;
2677 if (virSecurityManagerClearSocketLabel(h->driver->securityManager, h->vm->def) < 0)
2678 goto cleanup;
2679
2680 if (qemuProcessLimits(h->driver) < 0)
2681 goto cleanup;
2682
2683 /* This must take place before exec(), so that all QEMU
2684 * memory allocation is on the correct NUMA node
2685 */
2686 VIR_DEBUG("Moving process to cgroup");
2687 if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
2688 goto cleanup;
2689
2690 /* This must be done after cgroup placement to avoid resetting CPU
2691 * affinity */
2692 if (!h->vm->def->cputune.emulatorpin &&
2693 qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
2694 goto cleanup;
2695
2696 if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
2697 goto cleanup;
2698
2699 VIR_DEBUG("Setting up security labelling");
2700 if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm->def) < 0)
2701 goto cleanup;
2702
2703 ret = 0;
2704
2705cleanup:
2706 VIR_DEBUG("Hook complete ret=%d", ret);
2707 return ret;
2708}
2709
2710int
2711qemuProcessPrepareMonitorChr(struct qemud_driver *driver,
2712 virDomainChrSourceDefPtr monConfig,
2713 const char *vm)
2714{
2715 monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX;
2716 monConfig->data.nix.listen = true;
2717
2718 if (virAsprintf(&monConfig->data.nix.path, "%s/%s.monitor",
2719 driver->libDir, vm) < 0) {
2720 virReportOOMError();
2721 return -1;
2722 }
2723
2724 return 0;
2725}
2726
2727
2728/*
2729 * Precondition: Both driver and vm must be locked,
2730 * and a job must be active. This method will call
2731 * {Enter,Exit}MonitorWithDriver
2732 */
2733int
2734qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm,
2735 virConnectPtr conn, virDomainRunningReason reason,
2736 enum qemuDomainAsyncJob asyncJob)
2737{
2738 int ret;
2739 qemuDomainObjPrivatePtr priv = vm->privateData;
2740
2741 VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
2742 if (virDomainLockProcessResume(driver->lockManager, driver->uri,
2743 vm, priv->lockState) < 0) {
2744 /* Don't free priv->lockState on error, because we need
2745 * to make sure we have state still present if the user
2746 * tries to resume again
2747 */
2748 return -1;
2749 }
2750 VIR_FREE(priv->lockState);
2751
2752 ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
2753 if (ret == 0) {
2754 ret = qemuMonitorStartCPUs(priv->mon, conn);
2755 qemuDomainObjExitMonitorWithDriver(driver, vm);
2756 }
2757
2758 if (ret == 0) {
2759 virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
2760 } else {
2761 if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
2762 VIR_WARN("Unable to release lease on %s", vm->def->name);
2763 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
2764 }
2765
2766 return ret;
2767}
2768
2769
2770int qemuProcessStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm,
2771 virDomainPausedReason reason,
2772 enum qemuDomainAsyncJob asyncJob)
2773{
2774 int ret;
2775 qemuDomainObjPrivatePtr priv = vm->privateData;
2776
2777 VIR_FREE(priv->lockState);
2778
2779 ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
2780 if (ret == 0) {
2781 ret = qemuMonitorStopCPUs(priv->mon);
2782 qemuDomainObjExitMonitorWithDriver(driver, vm);
2783 }
2784
2785 if (ret == 0) {
2786 virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
2787 if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
2788 VIR_WARN("Unable to release lease on %s", vm->def->name);
2789 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
2790 }
2791
2792 return ret;
2793}
2794
2795
2796
2797static int
2798qemuProcessNotifyNets(virDomainDefPtr def)
2799{
2800 int ii;
2801
2802 for (ii = 0 ; ii < def->nnets ; ii++) {
2803 virDomainNetDefPtr net = def->nets[ii];
2804 if (networkNotifyActualDevice(net) < 0)
2805 return -1;
2806 }
2807 return 0;
2808}
2809
2810static int
2811qemuProcessFiltersInstantiate(virConnectPtr conn,
2812 virDomainDefPtr def)
2813{
2814 int err = 0;
2815 int i;
2816
2817 if (!conn)
2818 return 1;
2819
2820 for (i = 0 ; i < def->nnets ; i++) {
2821 virDomainNetDefPtr net = def->nets[i];
2822 if ((net->filter) && (net->ifname)) {
2823 if (virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) {
2824 err = 1;
2825 break;
2826 }
2827 }
2828 }
2829
2830 return err;
2831}
2832
2833static int
2834qemuProcessUpdateState(struct qemud_driver *driver, virDomainObjPtr vm)
2835{
2836 qemuDomainObjPrivatePtr priv = vm->privateData;
2837 virDomainState state;
2838 virDomainPausedReason reason;
2839 virDomainState newState = VIR_DOMAIN_NOSTATE;
2840 int newReason;
2841 bool running;
2842 char *msg = NULL;
2843 int ret;
2844
2845 qemuDomainObjEnterMonitorWithDriver(driver, vm);
2846 ret = qemuMonitorGetStatus(priv->mon, &running, &reason);
2847 qemuDomainObjExitMonitorWithDriver(driver, vm);
2848
2849 if (ret < 0 || !virDomainObjIsActive(vm))
2850 return -1;
2851
2852 state = virDomainObjGetState(vm, NULL);
2853
2854 if (state == VIR_DOMAIN_PAUSED && running) {
2855 newState = VIR_DOMAIN_RUNNING;
2856 newReason = VIR_DOMAIN_RUNNING_UNPAUSED;
2857 msg = strdup("was unpaused");
2858 } else if (state == VIR_DOMAIN_RUNNING && !running) {
2859 if (reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN) {
2860 newState = VIR_DOMAIN_SHUTDOWN;
2861 newReason = VIR_DOMAIN_SHUTDOWN_UNKNOWN;
2862 msg = strdup("shutdown");
2863 } else {
2864 newState = VIR_DOMAIN_PAUSED;
2865 newReason = reason;
2866 ignore_value(virAsprintf(&msg, "was paused (%s)",
2867 virDomainPausedReasonTypeToString(reason)));
2868 }
2869 } else if (state == VIR_DOMAIN_SHUTOFF && running) {
2870 newState = VIR_DOMAIN_RUNNING;
2871 newReason = VIR_DOMAIN_RUNNING_BOOTED;
2872 msg = strdup("finished booting");
2873 }
2874
2875 if (newState != VIR_DOMAIN_NOSTATE) {
2876 if (!msg) {
2877 virReportOOMError();
2878 return -1;
2879 }
2880
2881 VIR_DEBUG("Domain %s %s while its monitor was disconnected;"
2882 " changing state to %s (%s)",
2883 vm->def->name,
2884 msg,
2885 virDomainStateTypeToString(newState),
2886 virDomainStateReasonToString(newState, newReason));
2887 VIR_FREE(msg);
2888 virDomainObjSetState(vm, newState, newReason);
2889 }
2890
2891 return 0;
2892}
2893
2894static int
2895qemuProcessRecoverMigration(struct qemud_driver *driver,
2896 virDomainObjPtr vm,
2897 virConnectPtr conn,
2898 enum qemuDomainAsyncJob job,
2899 enum qemuMigrationJobPhase phase,
2900 virDomainState state,
2901 int reason)
2902{
2903 qemuDomainObjPrivatePtr priv = vm->privateData;
2904
2905 if (job == QEMU_ASYNC_JOB_MIGRATION_IN) {
2906 switch (phase) {
2907 case QEMU_MIGRATION_PHASE_NONE:
2908 case QEMU_MIGRATION_PHASE_PERFORM2:
2909 case QEMU_MIGRATION_PHASE_BEGIN3:
2910 case QEMU_MIGRATION_PHASE_PERFORM3:
2911 case QEMU_MIGRATION_PHASE_PERFORM3_DONE:
2912 case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED:
2913 case QEMU_MIGRATION_PHASE_CONFIRM3:
2914 case QEMU_MIGRATION_PHASE_LAST:
2915 break;
2916
2917 case QEMU_MIGRATION_PHASE_PREPARE:
2918 VIR_DEBUG("Killing unfinished incoming migration for domain %s",
2919 vm->def->name);
2920 return -1;
2921
2922 case QEMU_MIGRATION_PHASE_FINISH2:
2923 /* source domain is already killed so let's just resume the domain
2924 * and hope we are all set */
2925 VIR_DEBUG("Incoming migration finished, resuming domain %s",
2926 vm->def->name);
2927 if (qemuProcessStartCPUs(driver, vm, conn,
2928 VIR_DOMAIN_RUNNING_UNPAUSED,
2929 QEMU_ASYNC_JOB_NONE) < 0) {
2930 VIR_WARN("Could not resume domain %s", vm->def->name);
2931 }
2932 break;
2933
2934 case QEMU_MIGRATION_PHASE_FINISH3:
2935 /* migration finished, we started resuming the domain but didn't
2936 * confirm success or failure yet; killing it seems safest */
2937 VIR_DEBUG("Killing migrated domain %s", vm->def->name);
2938 return -1;
2939 }
2940 } else if (job == QEMU_ASYNC_JOB_MIGRATION_OUT) {
2941 switch (phase) {
2942 case QEMU_MIGRATION_PHASE_NONE:
2943 case QEMU_MIGRATION_PHASE_PREPARE:
2944 case QEMU_MIGRATION_PHASE_FINISH2:
2945 case QEMU_MIGRATION_PHASE_FINISH3:
2946 case QEMU_MIGRATION_PHASE_LAST:
2947 break;
2948
2949 case QEMU_MIGRATION_PHASE_BEGIN3:
2950 /* nothing happen so far, just forget we were about to migrate the
2951 * domain */
2952 break;
2953
2954 case QEMU_MIGRATION_PHASE_PERFORM2:
2955 case QEMU_MIGRATION_PHASE_PERFORM3:
2956 /* migration is still in progress, let's cancel it and resume the
2957 * domain */
2958 VIR_DEBUG("Canceling unfinished outgoing migration of domain %s",
2959 vm->def->name);
2960 qemuDomainObjEnterMonitor(driver, vm);
2961 ignore_value(qemuMonitorMigrateCancel(priv->mon));
2962 qemuDomainObjExitMonitor(driver, vm);
2963 /* resume the domain but only if it was paused as a result of
2964 * migration */
2965 if (state == VIR_DOMAIN_PAUSED &&
2966 (reason == VIR_DOMAIN_PAUSED_MIGRATION ||
2967 reason == VIR_DOMAIN_PAUSED_UNKNOWN)) {
2968 if (qemuProcessStartCPUs(driver, vm, conn,
2969 VIR_DOMAIN_RUNNING_UNPAUSED,
2970 QEMU_ASYNC_JOB_NONE) < 0) {
2971 VIR_WARN("Could not resume domain %s", vm->def->name);
2972 }
2973 }
2974 break;
2975
2976 case QEMU_MIGRATION_PHASE_PERFORM3_DONE:
2977 /* migration finished but we didn't have a chance to get the result
2978 * of Finish3 step; third party needs to check what to do next
2979 */
2980 break;
2981
2982 case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED:
2983 /* Finish3 failed, we need to resume the domain */
2984 VIR_DEBUG("Resuming domain %s after failed migration",
2985 vm->def->name);
2986 if (state == VIR_DOMAIN_PAUSED &&
2987 (reason == VIR_DOMAIN_PAUSED_MIGRATION ||
2988 reason == VIR_DOMAIN_PAUSED_UNKNOWN)) {
2989 if (qemuProcessStartCPUs(driver, vm, conn,
2990 VIR_DOMAIN_RUNNING_UNPAUSED,
2991 QEMU_ASYNC_JOB_NONE) < 0) {
2992 VIR_WARN("Could not resume domain %s", vm->def->name);
2993 }
2994 }
2995 break;
2996
2997 case QEMU_MIGRATION_PHASE_CONFIRM3:
2998 /* migration completed, we need to kill the domain here */
2999 return -1;
3000 }
3001 }
3002
3003 return 0;
3004}
3005
3006static int
3007qemuProcessRecoverJob(struct qemud_driver *driver,
3008 virDomainObjPtr vm,
3009 virConnectPtr conn,
3010 const struct qemuDomainJobObj *job)
3011{
3012 qemuDomainObjPrivatePtr priv = vm->privateData;
3013 virDomainState state;
3014 int reason;
3015
3016 state = virDomainObjGetState(vm, &reason);
3017
3018 switch (job->asyncJob) {
3019 case QEMU_ASYNC_JOB_MIGRATION_OUT:
3020 case QEMU_ASYNC_JOB_MIGRATION_IN:
3021 if (qemuProcessRecoverMigration(driver, vm, conn, job->asyncJob,
3022 job->phase, state, reason) < 0)
3023 return -1;
3024 break;
3025
3026 case QEMU_ASYNC_JOB_SAVE:
3027 case QEMU_ASYNC_JOB_DUMP:
3028 qemuDomainObjEnterMonitor(driver, vm);
3029 ignore_value(qemuMonitorMigrateCancel(priv->mon));
3030 qemuDomainObjExitMonitor(driver, vm);
3031 /* resume the domain but only if it was paused as a result of
3032 * running save/dump operation. Although we are recovering an
3033 * async job, this function is run at startup and must resume
3034 * things using sync monitor connections. */
3035 if (state == VIR_DOMAIN_PAUSED &&
3036 ((job->asyncJob == QEMU_ASYNC_JOB_DUMP &&
3037 reason == VIR_DOMAIN_PAUSED_DUMP) ||
3038 (job->asyncJob == QEMU_ASYNC_JOB_SAVE &&
3039 reason == VIR_DOMAIN_PAUSED_SAVE) ||
3040 reason == VIR_DOMAIN_PAUSED_UNKNOWN)) {
3041 if (qemuProcessStartCPUs(driver, vm, conn,
3042 VIR_DOMAIN_RUNNING_UNPAUSED,
3043 QEMU_ASYNC_JOB_NONE) < 0) {
3044 VIR_WARN("Could not resume domain %s after", vm->def->name);
3045 }
3046 }
3047 break;
3048
3049 case QEMU_ASYNC_JOB_NONE:
3050 case QEMU_ASYNC_JOB_LAST:
3051 break;
3052 }
3053
3054 if (!virDomainObjIsActive(vm))
3055 return -1;
3056
3057 /* In case any special handling is added for job type that has been ignored
3058 * before, QEMU_DOMAIN_TRACK_JOBS (from qemu_domain.h) needs to be updated
3059 * for the job to be properly tracked in domain state XML.
3060 */
3061 switch (job->active) {
3062 case QEMU_JOB_QUERY:
3063 /* harmless */
3064 break;
3065
3066 case QEMU_JOB_DESTROY:
3067 VIR_DEBUG("Domain %s should have already been destroyed",
3068 vm->def->name);
3069 return -1;
3070
3071 case QEMU_JOB_SUSPEND:
3072 /* mostly harmless */
3073 break;
3074
3075 case QEMU_JOB_MODIFY:
3076 /* XXX depending on the command we may be in an inconsistent state and
3077 * we should probably fall back to "monitor error" state and refuse to
3078 */
3079 break;
3080
3081 case QEMU_JOB_MIGRATION_OP:
3082 case QEMU_JOB_ABORT:
3083 case QEMU_JOB_ASYNC:
3084 case QEMU_JOB_ASYNC_NESTED:
3085 /* async job was already handled above */
3086 case QEMU_JOB_NONE:
3087 case QEMU_JOB_LAST:
3088 break;
3089 }
3090
3091 return 0;
3092}
3093
3094struct qemuProcessReconnectData {
3095 virConnectPtr conn;
3096 struct qemud_driver *driver;
3097 void *payload;
3098 struct qemuDomainJobObj oldjob;
3099};
3100/*
3101 * Open an existing VM's monitor, re-detect VCPU threads
3102 * and re-reserve the security labels in use
3103 *
3104 * We own the virConnectPtr we are passed here - whoever started
3105 * this thread function has increased the reference counter to it
3106 * so that we now have to close it.
3107 */
3108static void
3109qemuProcessReconnect(void *opaque)
3110{
3111 struct qemuProcessReconnectData *data = opaque;
3112 struct qemud_driver *driver = data->driver;
3113 virDomainObjPtr obj = data->payload;
3114 qemuDomainObjPrivatePtr priv;
3115 virConnectPtr conn = data->conn;
3116 struct qemuDomainJobObj oldjob;
3117 int state;
3118 int reason;
3119
3120 memcpy(&oldjob, &data->oldjob, sizeof(oldjob));
3121
3122 VIR_FREE(data);
3123
3124 qemuDriverLock(driver);
3125 virDomainObjLock(obj);
3126
3127
3128 VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);
3129
3130 priv = obj->privateData;
3131
3132 /* Job was started by the caller for us */
3133 qemuDomainObjTransferJob(obj);
3134
3135 /* Hold an extra reference because we can't allow 'vm' to be
3136 * deleted if qemuConnectMonitor() failed */
3137 virObjectRef(obj);
3138
3139 /* XXX check PID liveliness & EXE path */
3140 if (qemuConnectMonitor(driver, obj) < 0)
3141 goto error;
3142
3143 /* Failure to connect to agent shouldn't be fatal */
3144 if (qemuConnectAgent(driver, obj) < 0) {
3145 VIR_WARN("Cannot connect to QEMU guest agent for %s",
3146 obj->def->name);
3147 virResetLastError();
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: