[libvirt] [PATCH 1/3] vz: support boot order specification on define domain
Maxim Nestratov
mnestratov at virtuozzo.com
Thu Apr 7 09:47:37 UTC 2016
22.03.2016 16:56, Nikolay Shirokovskiy пишет:
> 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 at virtuozzo.com>
> ---
> src/vz/vz_sdk.c | 148 ++++++++++++++++++++++++++++++++++++++------------------
> 1 file changed, 101 insertions(+), 47 deletions(-)
>
> diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
> index c0fb4fb..528a253 100644
> --- a/src/vz/vz_sdk.c
> +++ b/src/vz/vz_sdk.c
> @@ -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,86 @@ 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);
> +
> + if (idx[virType] >= num) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("Too many devices of type '%s' in boot spec"),
> + virDomainBootTypeToString(virType));
> + return -1;
> + }
I would ease this strictness and remove the check as we didn't have it
before and it actually doesn't solve any potential problem and only
prohibits what was allowed before.
> +
> + pret = prlsdkAddDeviceToBootList(sdkdom, idx[virType]++, sdkType, bootIndex++);
> + prlsdkCheckRetExit(pret, -1);
> + }
> +
> + return 0;
> +}
> +
> static int
> prlsdkDoApplyConfig(virConnectPtr conn,
> PRL_HANDLE sdkdom,
> @@ -3309,7 +3370,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 +3448,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 (needBoot &&
> - def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
> + if (prlsdkAddDisk(conn->privateData, sdkdom, def->disks[i]) < 0)
> + goto error;
> + }
>
> - 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;
> }
>
More information about the libvir-list
mailing list