diff --git a/src/image/Image.cc b/src/image/Image.cc
index f7eaadcc8e..24923e236b 100644
--- a/src/image/Image.cc
+++ b/src/image/Image.cc
@@ -613,6 +613,12 @@ void Image::disk_attribute(VirtualMachineDisk * disk,
disk->replace("PERSISTENT", "YES");
disk->replace("CLONE", "NO");
disk->replace("SAVE", "YES");
+
+ if (template_ptype == "SHAREABLE" &&
+ one_util::tolower(format) == "raw")
+ {
+ disk->replace("SHAREABLE", "YES");
+ }
}
else
{
diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc
index 81a27d77f8..aee09750ab 100644
--- a/src/image/ImageManagerActions.cc
+++ b/src/image/ImageManagerActions.cc
@@ -89,8 +89,11 @@ int ImageManager::acquire_image(int vm_id, Image *img, bool attach, string& erro
{
int rc = 0;
- ostringstream oss;
+ bool shareable;
+ string persistent_type;
+ ostringstream oss;
+
switch(img->get_type())
{
case Image::OS:
@@ -108,7 +111,11 @@ int ImageManager::acquire_image(int vm_id, Image *img, bool attach, string& erro
error = oss.str();
return -1;
}
-
+
+ img->get_template_attribute("PERSISTENT_TYPE", persistent_type);
+
+ shareable = one_util::toupper(persistent_type) == "SHAREABLE";
+
switch (img->get_state())
{
case Image::READY:
@@ -153,19 +160,32 @@ int ImageManager::acquire_image(int vm_id, Image *img, bool attach, string& erro
break;
case Image::USED_PERS:
- case Image::LOCKED_USED_PERS:
- oss << "Cannot acquire image " << img->get_oid()
- << ", it is persistent and already in use";
-
- error = oss.str();
- rc = -1;
- break;
+ if (!shareable)
+ {
+ oss << "Cannot acquire image " << img->get_oid()
+ << ", it is persistent and already in use";
+ error = oss.str();
+ rc = -1;
+ break;
+ }
+ // Fallthrough
case Image::USED:
img->inc_running(vm_id);
ipool->update(img);
break;
+ case Image::LOCKED_USED_PERS:
+ if (!shareable)
+ {
+ oss << "Cannot acquire image " << img->get_oid()
+ << ", it is persistent and already in use";
+
+ error = oss.str();
+ rc = -1;
+ break;
+ }
+ // Fallthrough
case Image::LOCKED_USED:
if (attach)
{
@@ -230,13 +250,13 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
switch (img->get_state())
{
case Image::USED_PERS:
- img->dec_running(vm_id);
+ int num_vms = img->dec_running(vm_id);
- if (failed == true)
+ if (failed)
{
img->set_state(Image::ERROR);
}
- else
+ else if (num_vms == 0)
{
img->set_state(Image::READY);
}
@@ -245,13 +265,13 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
break;
case Image::LOCKED_USED_PERS:
- img->dec_running(vm_id);
+ int num_vms = img->dec_running(vm_id);
- if (failed == true)
+ if (failed)
{
img->set_state(Image::ERROR);
}
- else
+ else if (num_vms == 0)
{
img->set_state(Image::LOCKED);
}
diff --git a/src/vmm/LibVirtDriverKVM.cc b/src/vmm/LibVirtDriverKVM.cc
index 0a72520082..b6b943ea27 100644
--- a/src/vmm/LibVirtDriverKVM.cc
+++ b/src/vmm/LibVirtDriverKVM.cc
@@ -447,6 +447,7 @@ int LibVirtDriver::deployment_description_kvm(
string discard = "";
string source = "";
string clone = "";
+ string shareable = "";
string ceph_host = "";
string ceph_secret = "";
string ceph_user = "";
@@ -893,6 +894,7 @@ int LibVirtDriver::deployment_description_kvm(
discard = disk[i]->vector_value("DISCARD");
source = disk[i]->vector_value("SOURCE");
clone = disk[i]->vector_value("CLONE");
+ shareable = disk[i]->vector_value("SHAREABLE");
ceph_host = disk[i]->vector_value("CEPH_HOST");
ceph_secret = disk[i]->vector_value("CEPH_SECRET");
@@ -1196,6 +1198,13 @@ int LibVirtDriver::deployment_description_kvm(
file << "\t\t\t" << endl;
}
+ // ---- shareable attribute for the disk ----
+
+ if (shareable == "YES")
+ {
+ file << "\t\t\t" << endl;
+ }
+
// ---- Image Format using qemu driver ----
file << "\t\t\t