diff --git a/include/Image.h b/include/Image.h index 63feb4f996..639a5533e2 100644 --- a/include/Image.h +++ b/include/Image.h @@ -204,8 +204,11 @@ public: * - Several DATABLOCK images can be mounted, they will be set to * prefix + (d + index) : hdd, hde, hdf... * @param disk attribute for the VM template + * @param index number of datablock images used by the same VM. Will be + * automatically increased. + * @param img_type will be set to the used image's type */ - int disk_attribute(VectorAttribute * disk, int * index); + int disk_attribute(VectorAttribute * disk, int* index, ImageType& img_type); // ------------------------------------------------------------------------ // Template diff --git a/include/ImagePool.h b/include/ImagePool.h index 968188178d..73289a1f36 100644 --- a/include/ImagePool.h +++ b/include/ImagePool.h @@ -168,9 +168,13 @@ public: /** * Generates a DISK attribute for VM templates using the Image metadata * @param disk the disk to be generated + * @param index number of datablock images used by the same VM. Will be + * automatically increased. + * @param img_type will be set to the used image's type * @return 0 on success, -1 error, -2 not using the pool */ - int disk_attribute(VectorAttribute * disk, int * index); + int disk_attribute(VectorAttribute * disk, int* index, + Image::ImageType& img_type); /** * Generates an Authorization token for the DISK attribute diff --git a/src/image/Image.cc b/src/image/Image.cc index d59f00f7e8..31f6f80438 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -546,7 +546,9 @@ void Image::release_image() /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -int Image::disk_attribute(VectorAttribute * disk, int * index) +int Image::disk_attribute( VectorAttribute * disk, + int * index, + ImageType& img_type) { string overwrite; string saveas; @@ -554,6 +556,8 @@ int Image::disk_attribute(VectorAttribute * disk, int * index) ostringstream iid; + img_type = type; + overwrite = disk->vector_value("OVERWRITE"); saveas = disk->vector_value("SAVE_AS"); bus = disk->vector_value("BUS"); diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 6982dda21b..09854fedf9 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -165,7 +165,9 @@ int ImagePool::dump(ostringstream& oss, const string& where) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int ImagePool::disk_attribute(VectorAttribute * disk, int * index) +int ImagePool::disk_attribute( VectorAttribute * disk, + int * index, + Image::ImageType& img_type) { string source; Image * img = 0; @@ -202,7 +204,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk, int * index) return -1; } - int rc = img->disk_attribute(disk,index); + int rc = img->disk_attribute(disk,index, img_type); img->unlock(); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index feca468b3f..bbde093e17 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -388,7 +388,6 @@ error_leases: return -1; error_images: - NebulaLog::log("ONE",Log::ERROR, "Could not get disk image for VM"); goto error_common; error_context: @@ -826,6 +825,10 @@ int VirtualMachine::get_disk_images() ImagePool * ipool; VectorAttribute * disk; + int n_os = 0; + int n_cd = 0; + string type; + Nebula& nd = Nebula::instance(); ipool = nd.get_ipool(); @@ -841,41 +844,86 @@ int VirtualMachine::get_disk_images() continue; } - rc = ipool->disk_attribute(disk, &index); + Image::ImageType img_type; + rc = ipool->disk_attribute(disk, &index, img_type); - if (rc == -1) // 0 OK, -1 ERROR + switch(rc) { - return -1; - } - - // -2 not using the Image pool, and type is swap - if ( rc == -2 ) - { - string type = disk->vector_value("TYPE"); - - transform (type.begin(), type.end(), type.begin(), - (int(*)(int))toupper); - - if( type == "SWAP" ) - { - string target = disk->vector_value("TARGET"); - - if ( target.empty() ) + case 0: // OK + switch(img_type) { - Nebula& nd = Nebula::instance(); - string dev_prefix; - - nd.get_configuration_attribute("DEFAULT_DEVICE_PREFIX", - dev_prefix); - dev_prefix += "d"; - - disk->replace("TARGET", dev_prefix); + case Image::OS: + n_os++; + break; + case Image::CDROM: + n_cd++; + break; + default: + break; } - } + + if( n_os > 1 ) // Max. number of OS images is 1 + { + goto error_max_os; + } + + if( n_cd > 1 ) // Max. number of CDROM images is 1 + { + goto error_max_cd; + } + + break; + + case -2: // not using the Image pool + type = disk->vector_value("TYPE"); + + transform (type.begin(), type.end(), type.begin(), + (int(*)(int))toupper); + + if( type == "SWAP" ) + { + string target = disk->vector_value("TARGET"); + + if ( target.empty() ) + { + Nebula& nd = Nebula::instance(); + string dev_prefix; + + nd.get_configuration_attribute("DEFAULT_DEVICE_PREFIX", + dev_prefix); + dev_prefix += "d"; + + disk->replace("TARGET", dev_prefix); + } + } + + break; + + case -1: // ERROR + goto error_image; + break; } } return 0; + + +error_max_os: + NebulaLog::log("ONE",Log::ERROR, + "VM can not use more than one OS image."); + goto error_common; + +error_max_cd: + NebulaLog::log("ONE",Log::ERROR, + "VM can not use more than one CDROM image."); + goto error_common; + +error_image: + NebulaLog::log("ONE",Log::ERROR, "Could not get disk image for VM"); + +error_common: + return -1; + } /* -------------------------------------------------------------------------- */