mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
ch_driver: Implement domain restore callbacks
Following callbacks have been implemented * domainRestore * domainRestoreFlags The path parameter to these callbacks has to be of the directory where libvirt has performed save. Additionally, call restore in `domainCreate` if the domain has managedsave. Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
ed12c63f89
commit
53ec0fd09d
@ -252,6 +252,8 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
|
||||
{
|
||||
virCHDriver *driver = dom->conn->privateData;
|
||||
virDomainObj *vm;
|
||||
virCHDomainObjPrivate *priv;
|
||||
g_autofree char *managed_save_path = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(0, -1);
|
||||
@ -265,8 +267,34 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
|
||||
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
|
||||
if (vm->hasManagedSave) {
|
||||
priv = vm->privateData;
|
||||
managed_save_path = chDomainManagedSavePath(driver, vm);
|
||||
if (virCHProcessStartRestore(driver, vm, managed_save_path) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("failed to restore domain from managed save"));
|
||||
goto endjob;
|
||||
}
|
||||
if (virCHMonitorResumeVM(priv->monitor) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("failed to resume domain after restore from managed save"));
|
||||
goto endjob;
|
||||
}
|
||||
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_RESTORED);
|
||||
/* cleanup the save dir after restore */
|
||||
if (virFileDeleteTree(managed_save_path) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to remove managed save path '%1$s'"),
|
||||
managed_save_path);
|
||||
goto endjob;
|
||||
}
|
||||
vm->hasManagedSave = false;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
|
||||
}
|
||||
|
||||
endjob:
|
||||
virDomainObjEndJob(vm);
|
||||
|
||||
cleanup:
|
||||
@ -989,6 +1017,70 @@ chDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
chDomainRestoreFlags(virConnectPtr conn,
|
||||
const char *from,
|
||||
const char *dxml,
|
||||
unsigned int flags)
|
||||
{
|
||||
virCHDriver *driver = conn->privateData;
|
||||
virDomainObj *vm = NULL;
|
||||
virCHDomainObjPrivate *priv;
|
||||
g_autoptr(virDomainDef) def = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(0, -1);
|
||||
|
||||
if (dxml) {
|
||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||
_("xml modification unsupported"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chDomainSaveImageRead(driver, from, &def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainRestoreFlagsEnsureACL(conn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(vm = virDomainObjListAdd(driver->domains, &def,
|
||||
driver->xmlopt,
|
||||
VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
|
||||
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
|
||||
NULL)))
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virCHProcessStartRestore(driver, vm, from) < 0)
|
||||
goto endjob;
|
||||
|
||||
priv = vm->privateData;
|
||||
if (virCHMonitorResumeVM(priv->monitor) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("failed to resume domain after restore"));
|
||||
goto endjob;
|
||||
}
|
||||
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_RESTORED);
|
||||
ret = 0;
|
||||
|
||||
endjob:
|
||||
virDomainObjEndJob(vm);
|
||||
|
||||
cleanup:
|
||||
if (vm && ret < 0)
|
||||
virCHDomainRemoveInactive(driver, vm);
|
||||
virDomainObjEndAPI(&vm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
chDomainRestore(virConnectPtr conn, const char *from)
|
||||
{
|
||||
return chDomainRestoreFlags(conn, from, NULL, 0);
|
||||
}
|
||||
|
||||
static virDomainPtr chDomainLookupByID(virConnectPtr conn,
|
||||
int id)
|
||||
{
|
||||
@ -2117,6 +2209,8 @@ static virHypervisorDriver chHypervisorDriver = {
|
||||
.domainManagedSaveRemove = chDomainManagedSaveRemove, /* 10.2.0 */
|
||||
.domainManagedSaveGetXMLDesc = chDomainManagedSaveGetXMLDesc, /* 10.2.0 */
|
||||
.domainHasManagedSaveImage = chDomainHasManagedSaveImage, /* 10.2.0 */
|
||||
.domainRestore = chDomainRestore, /* 10.2.0 */
|
||||
.domainRestoreFlags = chDomainRestoreFlags, /* 10.2.0 */
|
||||
};
|
||||
|
||||
static virConnectDriver chConnectDriver = {
|
||||
|
@ -853,3 +853,56 @@ virCHProcessStop(virCHDriver *driver G_GNUC_UNUSED,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* virCHProcessStartRestore:
|
||||
* @driver: pointer to driver structure
|
||||
* @vm: pointer to virtual machine structure
|
||||
* @from: directory path to restore the VM from
|
||||
*
|
||||
* Starts Cloud-Hypervisor process with the restored VM
|
||||
*
|
||||
* Returns 0 on success or -1 in case of error
|
||||
*/
|
||||
int
|
||||
virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from)
|
||||
{
|
||||
virCHDomainObjPrivate *priv = vm->privateData;
|
||||
g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(priv->driver);
|
||||
|
||||
if (!priv->monitor) {
|
||||
/* Get the first monitor connection if not already */
|
||||
if (!(priv->monitor = virCHProcessConnectMonitor(driver, vm))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("failed to create connection to CH socket"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
vm->pid = priv->monitor->pid;
|
||||
vm->def->id = vm->pid;
|
||||
priv->machineName = virCHDomainGetMachineName(vm);
|
||||
|
||||
if (virCHMonitorRestoreVM(priv->monitor, from) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("failed to restore domain"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Pass 0, NULL as restore only works without networking support */
|
||||
if (virDomainCgroupSetupCgroup("ch", vm,
|
||||
0, NULL, /* nnicindexes, nicindexes */
|
||||
&priv->cgroup,
|
||||
cfg->cgroupControllers,
|
||||
0, /*maxThreadsPerProc*/
|
||||
priv->driver->privileged,
|
||||
priv->machineName) < 0)
|
||||
return -1;
|
||||
|
||||
if (virCHProcessSetup(vm) < 0)
|
||||
return -1;
|
||||
|
||||
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_FROM_SNAPSHOT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -32,3 +32,7 @@ int virCHProcessStop(virCHDriver *driver,
|
||||
|
||||
int virCHProcessSetupVcpu(virDomainObj *vm,
|
||||
unsigned int vcpuid);
|
||||
|
||||
int virCHProcessStartRestore(virCHDriver *driver,
|
||||
virDomainObj *vm,
|
||||
const char *from);
|
||||
|
Loading…
Reference in New Issue
Block a user