This can notify the VM that it has to reload the vdi object. In addition, this can also prevent snapshot objects from being updated wrongly.
Signed-off-by: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp> --- include/sheep.h | 1 + include/sheepdog_proto.h | 5 +++-- sheep/gateway.c | 10 ++++++++++ sheep/sheep_priv.h | 1 + sheep/vdi.c | 25 +++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/sheep.h b/include/sheep.h index 1c3d847..72d50a9 100644 --- a/include/sheep.h +++ b/include/sheep.h @@ -207,6 +207,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 aef97dd..0916948 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..1a37ad8 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 (oid_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 (oid_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 99b44a2..d01d408 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -260,6 +260,7 @@ int init_disk_space(const char *d); int lock_base_dir(const char *d); int fill_vdi_state_list(void *data); +bool oid_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 3085148..7e67ff1 100644 --- a/sheep/vdi.c +++ b/sheep/vdi.c @@ -71,6 +71,31 @@ static struct vdi_state_entry *vdi_state_insert(struct rb_root *root, return NULL; /* insert successfully */ } +static bool vid_is_snapshot(uint32_t vid) +{ + struct vdi_state_entry *entry; + + pthread_rwlock_rdlock(&vdi_state_lock); + entry = vdi_state_search(&vdi_state_root, vid); + pthread_rwlock_unlock(&vdi_state_lock); + + if (!entry) { + sd_eprintf("No VDI entry for %" PRIx32 " found", vid); + return 0; + } + + return entry->snapshot; +} + +bool oid_is_readonly(uint64_t oid) +{ + /* we allow changing snapshot attributes */ + if (!is_data_obj(oid)) + return false; + + return vid_is_snapshot(oid_to_vid(oid)); +} + int get_vdi_copy_number(uint32_t vid) { struct vdi_state_entry *entry; -- 1.8.1.3.566.gaa39828 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog