[sheepdog] [PATCH RFC 4/4] sheep: return SD_RES_READONLY when write requests are sent to snapshots

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Thu Apr 25 12:23:27 CEST 2013


Currently, when we take a snapshot of online VMs, qemu and collie have
no ways to detect it and can break the snapshot.  This prevents the
snapshot from being overwritten in such case.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 include/sheep.h          |    1 +
 include/sheepdog_proto.h |    5 +++--
 sheep/gateway.c          |   10 ++++++++++
 sheep/sheep_priv.h       |    2 ++
 sheep/vdi.c              |   25 +++++++++++++++++++++++++
 5 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index 7ee22fd..0a64c7d 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -214,6 +214,7 @@ static inline const char *sd_strerror(int err)
 		{SD_RES_WAIT_FOR_JOIN, "Waiting for other nodes to join cluster"},
 		{SD_RES_JOIN_FAILED, "Node has failed to join cluster"},
 		{SD_RES_HALT, "IO has halted as there are too few living nodes"},
+		{SD_RES_READONLY, "Object is read-only"},
 		{SD_RES_FORCE_RECOVER, "Cluster is running/halted and cannot be force recovered"},
 		{SD_RES_NO_STORE, "Targeted backend store is not found"},
 		{SD_RES_NO_SUPPORT, "Operation is not supported"},
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index d015281..0b2cfba 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -67,9 +67,10 @@
 #define SD_RES_VER_MISMATCH  0x14 /* Protocol version mismatch */
 #define SD_RES_NO_SPACE      0x15 /* Server has no room for new objects */
 #define SD_RES_WAIT_FOR_FORMAT  0x16 /* Sheepdog is waiting for a format operation */
-#define SD_RES_WAIT_FOR_JOIN    0x17 /* Sheepdog is waiting for other nodes joining */
+#define SD_RES_WAIT_FOR_JOIN 0x17 /* Sheepdog is waiting for other nodes joining */
 #define SD_RES_JOIN_FAILED   0x18 /* Target node had failed to join sheepdog */
-#define SD_RES_HALT 0x19 /* Sheepdog is stopped doing IO */
+#define SD_RES_HALT          0x19 /* Sheepdog is stopped doing IO */
+#define SD_RES_READONLY      0x1A /* Object is read-only */
 
 /* errors above 0x80 are sheepdog-internal */
 
diff --git a/sheep/gateway.c b/sheep/gateway.c
index e52e8cd..283da4d 100644
--- a/sheep/gateway.c
+++ b/sheep/gateway.c
@@ -319,6 +319,11 @@ static int gateway_forward_request(struct request *req)
 
 int gateway_write_obj(struct request *req)
 {
+	uint64_t oid = req->rq.obj.oid;
+
+	if (obj_is_readonly(oid))
+		return SD_RES_READONLY;
+
 	if (!bypass_object_cache(req))
 		return object_cache_handle_request(req);
 
@@ -327,6 +332,11 @@ int gateway_write_obj(struct request *req)
 
 int gateway_create_and_write_obj(struct request *req)
 {
+	uint64_t oid = req->rq.obj.oid;
+
+	if (obj_is_readonly(oid))
+		return SD_RES_READONLY;
+
 	if (!bypass_object_cache(req))
 		return object_cache_handle_request(req);
 
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 048197b..8ae5d95 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -244,6 +244,8 @@ int init_base_path(const char *dir);
 int init_disk_space(const char *d);
 
 int fill_vdi_copy_list(void *data);
+bool vdi_is_snapshot(uint32_t vid);
+bool obj_is_readonly(uint64_t oid);
 int get_vdi_copy_number(uint32_t vid);
 int get_obj_copy_number(uint64_t oid, int nr_zones);
 int get_max_copy_number(void);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 160f39b..ff55a01 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -71,6 +71,31 @@ static struct vdi_copy_entry *vdi_copy_insert(struct rb_root *root,
 	return NULL; /* insert successfully */
 }
 
+bool vdi_is_snapshot(uint32_t vid)
+{
+	struct vdi_copy_entry *entry;
+
+	pthread_rwlock_rdlock(&vdi_copy_lock);
+	entry = vdi_copy_search(&vdi_copy_root, vid);
+	pthread_rwlock_unlock(&vdi_copy_lock);
+
+	if (!entry) {
+		sd_eprintf("No VDI entry for %" PRIx32 " found", vid);
+		return 0;
+	}
+
+	return entry->snapshot;
+}
+
+bool obj_is_readonly(uint64_t oid)
+{
+	/* we allow changing snapshot attributes */
+	if (!is_data_obj(oid))
+	    return false;
+
+	return vdi_is_snapshot(oid_to_vid(oid));
+}
+
 int get_vdi_copy_number(uint32_t vid)
 {
 	struct vdi_copy_entry *entry;
-- 
1.7.2.5




More information about the sheepdog mailing list