Skip to content

Commit

Permalink
Add reconnect support for CH
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
bryteise committed Feb 23, 2021
1 parent 82dc4ca commit c857ac8
Show file tree
Hide file tree
Showing 10 changed files with 609 additions and 27 deletions.
105 changes: 99 additions & 6 deletions src/ch/ch_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,26 @@ virCHDomainObjInitJob(virCHDomainObjPrivatePtr priv)
static void
virCHDomainObjResetJob(virCHDomainObjPrivatePtr priv)
{
struct virCHDomainJobObj *job = &priv->job;
virCHDomainJobObjPtr job = &priv->job;

job->active = CH_JOB_NONE;
job->owner = 0;
}

int
virCHDomainObjRestoreJob(virDomainObjPtr obj,
virCHDomainJobObjPtr job)
{
virCHDomainObjPrivatePtr priv = obj->privateData;

memset(job, 0, sizeof(*job));
job->active = priv->job.active;
job->owner = priv->job.owner;

virCHDomainObjResetJob(priv);
return 0;
}

static void
virCHDomainObjFreeJob(virCHDomainObjPrivatePtr priv)
{
Expand Down Expand Up @@ -137,21 +151,98 @@ virCHDomainObjEndJob(virDomainObjPtr obj)
virCondSignal(&priv->job.cond);
}

/**
* virCHDomainRemoveInactive:
*
* The caller must hold a lock to the vm.
*/
void
virCHDomainRemoveInactive(virCHDriverPtr driver,
virDomainObjPtr vm)
{
if (vm->persistent) {
/* Short-circuit, we don't want to remove a persistent domain */
return;
}

virDomainObjListRemove(driver->domains, vm);
}

/**
* virCHDomainRemoveInactiveLocked:
*
* The caller must hold a lock to the vm and must hold the
* lock on driver->domains in order to call the remove obj
* from locked list method.
*/
static void
virCHDomainRemoveInactiveLocked(virCHDriverPtr driver,
virDomainObjPtr vm)
{
if (vm->persistent) {
/* Short-circuit, we don't want to remove a persistent domain */
return;
}

virDomainObjListRemoveLocked(driver->domains, vm);
}

/**
* virCHDomainRemoveInactiveJob:
*
* Just like virCHDomainRemoveInactive but it tries to grab a
* CH_JOB_MODIFY first. Even though it doesn't succeed in
* grabbing the job the control carries with
* virCHDomainRemoveInactive call.
*/
void
virCHDomainRemoveInactiveJob(virCHDriverPtr driver,
virDomainObjPtr vm)
{
bool haveJob;

haveJob = virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) >= 0;

virCHDomainRemoveInactive(driver, vm);

if (haveJob)
virCHDomainObjEndJob(vm);
}

/**
* virCHDomainRemoveInactiveJobLocked:
*
* Similar to virCHomainRemoveInactiveJob,
* except that the caller must also hold the lock @driver->domains
*/
void
virCHDomainRemoveInactiveJobLocked(virCHDriverPtr driver,
virDomainObjPtr vm)
{
bool haveJob;

haveJob = virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) >= 0;

virCHDomainRemoveInactiveLocked(driver, vm);

if (haveJob)
virCHDomainObjEndJob(vm);
}

static void *
virCHDomainObjPrivateAlloc(void *opaque)
{
virCHDomainObjPrivatePtr priv;

if (VIR_ALLOC(priv) < 0)
return NULL;
priv = g_new0(virCHDomainObjPrivate, 1);

if (virCHDomainObjInitJob(priv) < 0) {
VIR_FREE(priv);
g_free(priv);
return NULL;
}

if (!(priv->devs = virChrdevAlloc())) {
VIR_FREE(priv);
g_free(priv);
return NULL;
}

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

virChrdevFree(priv->devs);
virCHDomainObjFreeJob(priv);
VIR_FREE(priv);
if (priv->pidfile)
g_free(priv->pidfile);
g_free(priv);
}

static int
Expand Down
26 changes: 24 additions & 2 deletions src/ch/ch_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,21 @@ enum virCHDomainJob {
VIR_ENUM_DECL(virCHDomainJob);


struct virCHDomainJobObj {
struct _virCHDomainJobObj {
virCond cond; /* Use to coordinate jobs */
enum virCHDomainJob active; /* Currently running job */
int owner; /* Thread which set current job */
};

typedef struct _virCHDomainJobObj virCHDomainJobObj;
typedef virCHDomainJobObj *virCHDomainJobObjPtr;

typedef struct _virCHDomainObjPrivate virCHDomainObjPrivate;
typedef virCHDomainObjPrivate *virCHDomainObjPrivatePtr;
struct _virCHDomainObjPrivate {
pid_t initpid;

struct virCHDomainJobObj job;
virCHDomainJobObj job;

virCHDriverPtr driver;

Expand All @@ -66,6 +68,8 @@ struct _virCHDomainObjPrivate {

char *machineName;

char *pidfile;

virBitmapPtr autoNodeset;
virBitmapPtr autoCpuset;

Expand Down Expand Up @@ -105,8 +109,26 @@ virCHDomainObjBeginJob(virDomainObjPtr obj, enum virCHDomainJob job)
void
virCHDomainObjEndJob(virDomainObjPtr obj);

void
virCHDomainRemoveInactive(virCHDriverPtr driver,
virDomainObjPtr vm);

void
virCHDomainRemoveInactiveJob(virCHDriverPtr driver,
virDomainObjPtr vm);

void
virCHDomainRemoveInactiveJobLocked(virCHDriverPtr driver,
virDomainObjPtr vm);

int virCHDomainRefreshThreadInfo(virDomainObjPtr vm);

pid_t virCHDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpuid);
bool virCHDomainHasVcpuPids(virDomainObjPtr vm);

char *virCHDomainGetMachineName(virDomainObjPtr vm);
virDomainObjPtr virCHDomainObjFromDomain(virDomainPtr domain);

int
virCHDomainObjRestoreJob(virDomainObjPtr obj,
virCHDomainJobObjPtr job);
10 changes: 10 additions & 0 deletions src/ch/ch_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,16 @@ static int chStateInitialize(bool privileged,
if (chExtractVersion(ch_driver) < 0)
goto cleanup;

/* Get all the running persistent or transient configs first */
if (virDomainObjListLoadAllConfigs(ch_driver->domains,
ch_driver->config->stateDir,
NULL, true,
ch_driver->xmlopt,
NULL, NULL) < 0)
goto cleanup;

chProcessReconnectAll(ch_driver);

ch_driver->privileged = privileged;

return VIR_DRV_STATE_INIT_COMPLETE;
Expand Down
90 changes: 89 additions & 1 deletion src/ch/ch_hostdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ int
chHostdevPrepareDomainDevices(virCHDriverPtr driver,
virDomainDefPtr def,
unsigned int flags)

{
if (!def->nhostdevs && !def->ndisks)
return 0;
Expand Down Expand Up @@ -356,3 +355,92 @@ chHostdevReAttachDomainDevices(virCHDriverPtr driver,
chHostdevReAttachMediatedDevices(driver, def->name, def->hostdevs,
def->nhostdevs);
}

int
chHostdevUpdateActivePCIDevices(virCHDriverPtr driver,
virDomainDefPtr def)
{
virHostdevManagerPtr mgr = driver->hostdevMgr;

if (!def->nhostdevs)
return 0;

return virHostdevUpdateActivePCIDevices(mgr, def->hostdevs, def->nhostdevs,
CH_DRIVER_NAME, def->name);
}

int
chHostdevUpdateActiveUSBDevices(virCHDriverPtr driver,
virDomainDefPtr def)
{
virHostdevManagerPtr mgr = driver->hostdevMgr;

if (!def->nhostdevs)
return 0;

return virHostdevUpdateActiveUSBDevices(mgr, def->hostdevs, def->nhostdevs,
CH_DRIVER_NAME, def->name);
}

int
chHostdevUpdateActiveSCSIDevices(virCHDriverPtr driver,
virDomainDefPtr def)
{
virHostdevManagerPtr mgr = driver->hostdevMgr;

if (!def->nhostdevs)
return 0;

return virHostdevUpdateActiveSCSIDevices(mgr, def->hostdevs, def->nhostdevs,
CH_DRIVER_NAME, def->name);
}

int
chHostdevUpdateActiveMediatedDevices(virCHDriverPtr driver,
virDomainDefPtr def)
{
virHostdevManagerPtr mgr = driver->hostdevMgr;

if (!def->nhostdevs)
return 0;

return virHostdevUpdateActiveMediatedDevices(mgr, def->hostdevs,
def->nhostdevs,
CH_DRIVER_NAME, def->name);
}

int
chHostdevUpdateActiveNVMeDisks(virCHDriverPtr driver,
virDomainDefPtr def)
{
return virHostdevUpdateActiveNVMeDevices(driver->hostdevMgr,
CH_DRIVER_NAME,
def->name,
def->disks,
def->ndisks);
}

int
chHostdevUpdateActiveDomainDevices(virCHDriverPtr driver,
virDomainDefPtr def)
{
if (!def->nhostdevs && !def->ndisks)
return 0;

if (chHostdevUpdateActiveNVMeDisks(driver, def) < 0)
return -1;

if (chHostdevUpdateActivePCIDevices(driver, def) < 0)
return -1;

if (chHostdevUpdateActiveUSBDevices(driver, def) < 0)
return -1;

if (chHostdevUpdateActiveSCSIDevices(driver, def) < 0)
return -1;

if (chHostdevUpdateActiveMediatedDevices(driver, def) < 0)
return -1;

return 0;
}
24 changes: 24 additions & 0 deletions src/ch/ch_hostdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,27 @@ chHostdevReAttachMediatedDevices(virCHDriverPtr driver,
void
chHostdevReAttachDomainDevices(virCHDriverPtr driver,
virDomainDefPtr def);

int
chHostdevUpdateActivePCIDevices(virCHDriverPtr driver,
virDomainDefPtr def)

int
chHostdevUpdateActiveUSBDevices(virCHDriverPtr driver,
virDomainDefPtr def)

int
chHostdevUpdateActiveSCSIDevices(virCHDriverPtr driver,
virDomainDefPtr def)

int
chHostdevUpdateActiveMediatedDevices(virCHDriverPtr driver,
virDomainDefPtr def)

int
chHostdevUpdateActiveNVMeDisks(virCHDriverPtr driver,
virDomainDefPtr def);

int
chHostdevUpdateActiveDomainDevices(virCHDriverPtr driver,
virDomainDefPtr def);
Loading

0 comments on commit c857ac8

Please sign in to comment.