Skip to content

Commit c857ac8

Browse files
committed
Add reconnect support for CH
Allow CH domains to be reconnected to after restarting libvirt. This change enables the creation of the pidfile and domain definiton file alongside the socket file. With these files in place (and getting updated). The CH domain is now able to track what domains were running when libvirt was closed. From there add the matching restore code to allow the VM state to be read in and processed by libvirt. Changes to hardware device management will necessitate more development on this feature in order to track the state of different devices in use (this is fairly different than the equivalent QEMU code).
1 parent 82dc4ca commit c857ac8

File tree

10 files changed

+609
-27
lines changed

10 files changed

+609
-27
lines changed

src/ch/ch_domain.c

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,26 @@ virCHDomainObjInitJob(virCHDomainObjPrivatePtr priv)
5454
static void
5555
virCHDomainObjResetJob(virCHDomainObjPrivatePtr priv)
5656
{
57-
struct virCHDomainJobObj *job = &priv->job;
57+
virCHDomainJobObjPtr job = &priv->job;
5858

5959
job->active = CH_JOB_NONE;
6060
job->owner = 0;
6161
}
6262

63+
int
64+
virCHDomainObjRestoreJob(virDomainObjPtr obj,
65+
virCHDomainJobObjPtr job)
66+
{
67+
virCHDomainObjPrivatePtr priv = obj->privateData;
68+
69+
memset(job, 0, sizeof(*job));
70+
job->active = priv->job.active;
71+
job->owner = priv->job.owner;
72+
73+
virCHDomainObjResetJob(priv);
74+
return 0;
75+
}
76+
6377
static void
6478
virCHDomainObjFreeJob(virCHDomainObjPrivatePtr priv)
6579
{
@@ -137,21 +151,98 @@ virCHDomainObjEndJob(virDomainObjPtr obj)
137151
virCondSignal(&priv->job.cond);
138152
}
139153

154+
/**
155+
* virCHDomainRemoveInactive:
156+
*
157+
* The caller must hold a lock to the vm.
158+
*/
159+
void
160+
virCHDomainRemoveInactive(virCHDriverPtr driver,
161+
virDomainObjPtr vm)
162+
{
163+
if (vm->persistent) {
164+
/* Short-circuit, we don't want to remove a persistent domain */
165+
return;
166+
}
167+
168+
virDomainObjListRemove(driver->domains, vm);
169+
}
170+
171+
/**
172+
* virCHDomainRemoveInactiveLocked:
173+
*
174+
* The caller must hold a lock to the vm and must hold the
175+
* lock on driver->domains in order to call the remove obj
176+
* from locked list method.
177+
*/
178+
static void
179+
virCHDomainRemoveInactiveLocked(virCHDriverPtr driver,
180+
virDomainObjPtr vm)
181+
{
182+
if (vm->persistent) {
183+
/* Short-circuit, we don't want to remove a persistent domain */
184+
return;
185+
}
186+
187+
virDomainObjListRemoveLocked(driver->domains, vm);
188+
}
189+
190+
/**
191+
* virCHDomainRemoveInactiveJob:
192+
*
193+
* Just like virCHDomainRemoveInactive but it tries to grab a
194+
* CH_JOB_MODIFY first. Even though it doesn't succeed in
195+
* grabbing the job the control carries with
196+
* virCHDomainRemoveInactive call.
197+
*/
198+
void
199+
virCHDomainRemoveInactiveJob(virCHDriverPtr driver,
200+
virDomainObjPtr vm)
201+
{
202+
bool haveJob;
203+
204+
haveJob = virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) >= 0;
205+
206+
virCHDomainRemoveInactive(driver, vm);
207+
208+
if (haveJob)
209+
virCHDomainObjEndJob(vm);
210+
}
211+
212+
/**
213+
* virCHDomainRemoveInactiveJobLocked:
214+
*
215+
* Similar to virCHomainRemoveInactiveJob,
216+
* except that the caller must also hold the lock @driver->domains
217+
*/
218+
void
219+
virCHDomainRemoveInactiveJobLocked(virCHDriverPtr driver,
220+
virDomainObjPtr vm)
221+
{
222+
bool haveJob;
223+
224+
haveJob = virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) >= 0;
225+
226+
virCHDomainRemoveInactiveLocked(driver, vm);
227+
228+
if (haveJob)
229+
virCHDomainObjEndJob(vm);
230+
}
231+
140232
static void *
141233
virCHDomainObjPrivateAlloc(void *opaque)
142234
{
143235
virCHDomainObjPrivatePtr priv;
144236

145-
if (VIR_ALLOC(priv) < 0)
146-
return NULL;
237+
priv = g_new0(virCHDomainObjPrivate, 1);
147238

148239
if (virCHDomainObjInitJob(priv) < 0) {
149-
VIR_FREE(priv);
240+
g_free(priv);
150241
return NULL;
151242
}
152243

153244
if (!(priv->devs = virChrdevAlloc())) {
154-
VIR_FREE(priv);
245+
g_free(priv);
155246
return NULL;
156247
}
157248

@@ -167,7 +258,9 @@ virCHDomainObjPrivateFree(void *data)
167258

168259
virChrdevFree(priv->devs);
169260
virCHDomainObjFreeJob(priv);
170-
VIR_FREE(priv);
261+
if (priv->pidfile)
262+
g_free(priv->pidfile);
263+
g_free(priv);
171264
}
172265

173266
static int

src/ch/ch_domain.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,21 @@ enum virCHDomainJob {
4444
VIR_ENUM_DECL(virCHDomainJob);
4545

4646

47-
struct virCHDomainJobObj {
47+
struct _virCHDomainJobObj {
4848
virCond cond; /* Use to coordinate jobs */
4949
enum virCHDomainJob active; /* Currently running job */
5050
int owner; /* Thread which set current job */
5151
};
5252

53+
typedef struct _virCHDomainJobObj virCHDomainJobObj;
54+
typedef virCHDomainJobObj *virCHDomainJobObjPtr;
5355

5456
typedef struct _virCHDomainObjPrivate virCHDomainObjPrivate;
5557
typedef virCHDomainObjPrivate *virCHDomainObjPrivatePtr;
5658
struct _virCHDomainObjPrivate {
5759
pid_t initpid;
5860

59-
struct virCHDomainJobObj job;
61+
virCHDomainJobObj job;
6062

6163
virCHDriverPtr driver;
6264

@@ -66,6 +68,8 @@ struct _virCHDomainObjPrivate {
6668

6769
char *machineName;
6870

71+
char *pidfile;
72+
6973
virBitmapPtr autoNodeset;
7074
virBitmapPtr autoCpuset;
7175

@@ -105,8 +109,26 @@ virCHDomainObjBeginJob(virDomainObjPtr obj, enum virCHDomainJob job)
105109
void
106110
virCHDomainObjEndJob(virDomainObjPtr obj);
107111

112+
void
113+
virCHDomainRemoveInactive(virCHDriverPtr driver,
114+
virDomainObjPtr vm);
115+
116+
void
117+
virCHDomainRemoveInactiveJob(virCHDriverPtr driver,
118+
virDomainObjPtr vm);
119+
120+
void
121+
virCHDomainRemoveInactiveJobLocked(virCHDriverPtr driver,
122+
virDomainObjPtr vm);
123+
124+
int virCHDomainRefreshThreadInfo(virDomainObjPtr vm);
125+
108126
pid_t virCHDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpuid);
109127
bool virCHDomainHasVcpuPids(virDomainObjPtr vm);
110128

111129
char *virCHDomainGetMachineName(virDomainObjPtr vm);
112130
virDomainObjPtr virCHDomainObjFromDomain(virDomainPtr domain);
131+
132+
int
133+
virCHDomainObjRestoreJob(virDomainObjPtr obj,
134+
virCHDomainJobObjPtr job);

src/ch/ch_driver.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,16 @@ static int chStateInitialize(bool privileged,
956956
if (chExtractVersion(ch_driver) < 0)
957957
goto cleanup;
958958

959+
/* Get all the running persistent or transient configs first */
960+
if (virDomainObjListLoadAllConfigs(ch_driver->domains,
961+
ch_driver->config->stateDir,
962+
NULL, true,
963+
ch_driver->xmlopt,
964+
NULL, NULL) < 0)
965+
goto cleanup;
966+
967+
chProcessReconnectAll(ch_driver);
968+
959969
ch_driver->privileged = privileged;
960970

961971
return VIR_DRV_STATE_INIT_COMPLETE;

src/ch/ch_hostdev.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ int
213213
chHostdevPrepareDomainDevices(virCHDriverPtr driver,
214214
virDomainDefPtr def,
215215
unsigned int flags)
216-
217216
{
218217
if (!def->nhostdevs && !def->ndisks)
219218
return 0;
@@ -356,3 +355,92 @@ chHostdevReAttachDomainDevices(virCHDriverPtr driver,
356355
chHostdevReAttachMediatedDevices(driver, def->name, def->hostdevs,
357356
def->nhostdevs);
358357
}
358+
359+
int
360+
chHostdevUpdateActivePCIDevices(virCHDriverPtr driver,
361+
virDomainDefPtr def)
362+
{
363+
virHostdevManagerPtr mgr = driver->hostdevMgr;
364+
365+
if (!def->nhostdevs)
366+
return 0;
367+
368+
return virHostdevUpdateActivePCIDevices(mgr, def->hostdevs, def->nhostdevs,
369+
CH_DRIVER_NAME, def->name);
370+
}
371+
372+
int
373+
chHostdevUpdateActiveUSBDevices(virCHDriverPtr driver,
374+
virDomainDefPtr def)
375+
{
376+
virHostdevManagerPtr mgr = driver->hostdevMgr;
377+
378+
if (!def->nhostdevs)
379+
return 0;
380+
381+
return virHostdevUpdateActiveUSBDevices(mgr, def->hostdevs, def->nhostdevs,
382+
CH_DRIVER_NAME, def->name);
383+
}
384+
385+
int
386+
chHostdevUpdateActiveSCSIDevices(virCHDriverPtr driver,
387+
virDomainDefPtr def)
388+
{
389+
virHostdevManagerPtr mgr = driver->hostdevMgr;
390+
391+
if (!def->nhostdevs)
392+
return 0;
393+
394+
return virHostdevUpdateActiveSCSIDevices(mgr, def->hostdevs, def->nhostdevs,
395+
CH_DRIVER_NAME, def->name);
396+
}
397+
398+
int
399+
chHostdevUpdateActiveMediatedDevices(virCHDriverPtr driver,
400+
virDomainDefPtr def)
401+
{
402+
virHostdevManagerPtr mgr = driver->hostdevMgr;
403+
404+
if (!def->nhostdevs)
405+
return 0;
406+
407+
return virHostdevUpdateActiveMediatedDevices(mgr, def->hostdevs,
408+
def->nhostdevs,
409+
CH_DRIVER_NAME, def->name);
410+
}
411+
412+
int
413+
chHostdevUpdateActiveNVMeDisks(virCHDriverPtr driver,
414+
virDomainDefPtr def)
415+
{
416+
return virHostdevUpdateActiveNVMeDevices(driver->hostdevMgr,
417+
CH_DRIVER_NAME,
418+
def->name,
419+
def->disks,
420+
def->ndisks);
421+
}
422+
423+
int
424+
chHostdevUpdateActiveDomainDevices(virCHDriverPtr driver,
425+
virDomainDefPtr def)
426+
{
427+
if (!def->nhostdevs && !def->ndisks)
428+
return 0;
429+
430+
if (chHostdevUpdateActiveNVMeDisks(driver, def) < 0)
431+
return -1;
432+
433+
if (chHostdevUpdateActivePCIDevices(driver, def) < 0)
434+
return -1;
435+
436+
if (chHostdevUpdateActiveUSBDevices(driver, def) < 0)
437+
return -1;
438+
439+
if (chHostdevUpdateActiveSCSIDevices(driver, def) < 0)
440+
return -1;
441+
442+
if (chHostdevUpdateActiveMediatedDevices(driver, def) < 0)
443+
return -1;
444+
445+
return 0;
446+
}

src/ch/ch_hostdev.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,27 @@ chHostdevReAttachMediatedDevices(virCHDriverPtr driver,
124124
void
125125
chHostdevReAttachDomainDevices(virCHDriverPtr driver,
126126
virDomainDefPtr def);
127+
128+
int
129+
chHostdevUpdateActivePCIDevices(virCHDriverPtr driver,
130+
virDomainDefPtr def)
131+
132+
int
133+
chHostdevUpdateActiveUSBDevices(virCHDriverPtr driver,
134+
virDomainDefPtr def)
135+
136+
int
137+
chHostdevUpdateActiveSCSIDevices(virCHDriverPtr driver,
138+
virDomainDefPtr def)
139+
140+
int
141+
chHostdevUpdateActiveMediatedDevices(virCHDriverPtr driver,
142+
virDomainDefPtr def)
143+
144+
int
145+
chHostdevUpdateActiveNVMeDisks(virCHDriverPtr driver,
146+
virDomainDefPtr def);
147+
148+
int
149+
chHostdevUpdateActiveDomainDevices(virCHDriverPtr driver,
150+
virDomainDefPtr def);

0 commit comments

Comments
 (0)