vz: support boot order specification on define domain

The patch makes some refactoring of the existing code. Current boot order spec code
makes very simple thing in somewhat obscure way. In case of VMs
it sets the first hdd as the only bootable device. In case of CTs it
doesn't touch the boot order at all if one of the filesystems is mounted to root.
Otherwise like in case of VMs it sets the first hdd as the only bootable
device and additionally sets this device mount point to root. Refactored
code makes all this explicit.

The actual boot order support is simple. Common libvirt domain xml parsing
code makes the exact ordering of disks devices as described in docs
for boot ordering (disks are sorted by bus order first, device target
second. Bus order is the order of disk buses appearence in original
xml. Device targets order is alphabetical). We add devices in the
same order and SDK designates device indexes sequentially for each
device type. Thus device index is equal to its boot index. For
example N-th cdrom in boot specification refers to sdk cdrom with
it's device index N.

If there is no boot spec in xml the parsing code will add <boot dev='hdd'>
for HVMs automatically and we backward compatibly set fist hdd as
bootable.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Signed-off-by: Maxim Nestratov <mnestratov@virtuozzo.com>
This commit is contained in:
Nikolay Shirokovskiy 2016-03-22 16:56:36 +03:00 committed by Maxim Nestratov
parent 03e8d5fb54
commit 497dcafc2e

View File

@ -87,6 +87,14 @@ logPrlErrorHelper(PRL_RESULT err, const char *filename,
} \
} while (0)
#define prlsdkCheckRetExit(ret, code) \
do { \
if (PRL_FAILED(ret)) { \
logPrlError(ret); \
return code; \
} \
} while (0)
static PRL_RESULT
logPrlEventErrorHelper(PRL_HANDLE event, const char *filename,
const char *funcname, size_t linenr)
@ -1988,13 +1996,9 @@ prlsdkCheckUnsupportedParams(PRL_HANDLE sdkdom, virDomainDefPtr def)
}
if (!IS_CT(def)) {
if (def->os.nBootDevs != 1 ||
def->os.bootDevs[0] != VIR_DOMAIN_BOOT_DISK ||
def->os.init != NULL || def->os.initargv != NULL) {
if (def->os.init != NULL || def->os.initargv != NULL) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("changing OS parameters is not supported "
"by vz driver"));
_("unsupported OS parameters"));
return -1;
}
} else {
@ -2003,8 +2007,7 @@ prlsdkCheckUnsupportedParams(PRL_HANDLE sdkdom, virDomainDefPtr def)
(def->os.initargv != NULL && def->os.initargv[0] != NULL)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("changing OS parameters is not supported "
"by vz driver"));
_("unsupported OS parameters"));
return -1;
}
}
@ -2991,9 +2994,7 @@ static int prlsdkDelDisk(PRL_HANDLE sdkdom, int idx)
static int prlsdkAddDisk(vzConnPtr privconn,
PRL_HANDLE sdkdom,
virDomainDiskDefPtr disk,
bool bootDisk,
bool isCt)
virDomainDiskDefPtr disk)
{
PRL_RESULT pret;
PRL_HANDLE sdkdisk = PRL_INVALID_HANDLE;
@ -3002,7 +3003,6 @@ static int prlsdkAddDisk(vzConnPtr privconn,
PRL_MASS_STORAGE_INTERFACE_TYPE sdkbus;
int idx;
virDomainDeviceDriveAddressPtr drive;
PRL_UINT32 devIndex;
PRL_DEVICE_TYPE devType;
PRL_CLUSTERED_DEVICE_SUBTYPE scsiModel;
char *dst = NULL;
@ -3133,21 +3133,6 @@ static int prlsdkAddDisk(vzConnPtr privconn,
goto cleanup;
}
if (bootDisk) {
pret = PrlVmDev_GetIndex(sdkdisk, &devIndex);
prlsdkCheckRetGoto(pret, cleanup);
if (prlsdkAddDeviceToBootList(sdkdom, devIndex, devType, 0) < 0)
goto cleanup;
/* If we add physical device as a boot disk to container
* we have to specify mount point for it */
if (isCt) {
pret = PrlVmDevHd_SetMountPoint(sdkdisk, "/");
prlsdkCheckRetGoto(pret, cleanup);
}
}
return 0;
cleanup:
PrlHandle_Free(sdkdisk);
@ -3168,11 +3153,7 @@ prlsdkAttachVolume(vzConnPtr privconn,
if (PRL_FAILED(waitJob(job)))
goto cleanup;
ret = prlsdkAddDisk(privconn,
privdom->sdkdom,
disk,
false,
IS_CT(dom->def));
ret = prlsdkAddDisk(privconn, privdom->sdkdom, disk);
if (ret == 0) {
job = PrlVm_CommitEx(privdom->sdkdom, PVCF_DETACH_HDD_BUNDLE);
if (PRL_FAILED(waitJob(job))) {
@ -3300,6 +3281,79 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs)
PrlHandle_Free(sdkdisk);
return ret;
}
static int
prlsdkSetBootOrderCt(PRL_HANDLE sdkdom, virDomainDefPtr def)
{
size_t i;
PRL_HANDLE hdd = PRL_INVALID_HANDLE;
PRL_RESULT pret;
int ret = -1;
/* if we have root mounted we don't need to explicitly set boot order */
for (i = 0; i < def->nfss; i++) {
if (STREQ(def->fss[i]->dst, "/"))
return 0;
}
/* else set first hard disk as boot device */
pret = prlsdkAddDeviceToBootList(sdkdom, 0, PDE_HARD_DISK, 0);
prlsdkCheckRetExit(pret, -1);
pret = PrlVmCfg_GetHardDisk(sdkdom, 0, &hdd);
prlsdkCheckRetExit(pret, -1);
PrlVmDevHd_SetMountPoint(hdd, "/");
prlsdkCheckRetGoto(pret, cleanup);
ret = 0;
cleanup:
PrlHandle_Free(hdd);
return ret;
}
static int
prlsdkSetBootOrderVm(PRL_HANDLE sdkdom, virDomainDefPtr def)
{
size_t i;
int idx[VIR_DOMAIN_BOOT_LAST] = { 0 };
int bootIndex = 0;
PRL_RESULT pret;
PRL_UINT32 num;
int sdkType;
virDomainBootOrder virType;
for (i = 0; i < def->os.nBootDevs; ++i) {
virType = def->os.bootDevs[i];
switch (virType) {
case VIR_DOMAIN_BOOT_CDROM:
sdkType = PDE_OPTICAL_DISK;
break;
case VIR_DOMAIN_BOOT_DISK:
sdkType = PDE_HARD_DISK;
break;
case VIR_DOMAIN_BOOT_NET:
sdkType = PDE_GENERIC_NETWORK_ADAPTER;
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported boot device type: '%s'"),
virDomainBootTypeToString(virType));
return -1;
}
pret = PrlVmCfg_GetDevsCountByType(sdkdom, sdkType, &num);
prlsdkCheckRetExit(pret, -1);
pret = prlsdkAddDeviceToBootList(sdkdom, idx[virType]++, sdkType, bootIndex++);
prlsdkCheckRetExit(pret, -1);
}
return 0;
}
static int
prlsdkDoApplyConfig(virConnectPtr conn,
PRL_HANDLE sdkdom,
@ -3309,7 +3363,6 @@ prlsdkDoApplyConfig(virConnectPtr conn,
PRL_RESULT pret;
size_t i;
char uuidstr[VIR_UUID_STRING_BUFLEN + 2];
bool needBoot = true;
char *mask = NULL;
if (prlsdkCheckUnsupportedParams(sdkdom, def) < 0)
@ -3388,26 +3441,20 @@ prlsdkDoApplyConfig(virConnectPtr conn,
}
for (i = 0; i < def->nfss; i++) {
if (STREQ(def->fss[i]->dst, "/"))
needBoot = false;
if (prlsdkAddFS(sdkdom, def->fss[i]) < 0)
goto error;
}
for (i = 0; i < def->ndisks; i++) {
bool bootDisk = false;
if (prlsdkAddDisk(conn->privateData, sdkdom, def->disks[i]) < 0)
goto error;
}
if (needBoot &&
def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
needBoot = false;
bootDisk = true;
}
if (prlsdkAddDisk(conn->privateData,
sdkdom,
def->disks[i],
bootDisk,
IS_CT(def)) < 0)
if (IS_CT(def)) {
if (prlsdkSetBootOrderCt(sdkdom, def) < 0)
goto error;
} else {
if (prlsdkSetBootOrderVm(sdkdom, def) < 0)
goto error;
}