From 3ece4457a31755930afa2a8f5b6712e8093e8b7f Mon Sep 17 00:00:00 2001 From: Takashi Menjo Date: Wed, 28 Sep 2016 13:20:28 +0900 Subject: [PATCH] sheep: handle OOM error gracefully when receive SD_OP_GET_OBJ_LIST When a sheep receives SD_OP_GET_OBJ_LIST request, xrealloc is called to allocate memory for object list which is being sent to the requesting. However, xrealloc panics if out-of-memory (OOM) error occurs. In this case, the sheep goes down. This is not good for stable running. This commit lets sheep handle OOM error gracefully when it receives SD_OP_GET_OBJ_LIST. If OOM error occurs, sheep returns SD_RES_NO_MEM. This is realized by using realloc instead of xrealloc (note "x") and check whether errno is set to ENOMEM or not. Signed-off-by: Takashi Menjo --- sheep/object_list_cache.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sheep/object_list_cache.c b/sheep/object_list_cache.c index 93c11f962..5118aca98 100644 --- a/sheep/object_list_cache.c +++ b/sheep/object_list_cache.c @@ -99,6 +99,7 @@ int get_obj_list(const struct sd_req *hdr, struct sd_rsp *rsp, void *data) { int nr = 0; struct objlist_cache_entry *entry; + uint64_t *newbuf = NULL; /* first try getting the cached buffer with only a read lock held */ sd_read_lock(&obj_list_cache.lock); @@ -111,9 +112,17 @@ int get_obj_list(const struct sd_req *hdr, struct sd_rsp *rsp, void *data) if (obj_list_cache.tree_version == obj_list_cache.buf_version) goto out; + /* Update obj_list_cache.buf indirectly to keep previous pointer */ + newbuf = realloc(obj_list_cache.buf, + obj_list_cache.cache_size * sizeof(uint64_t)); + if (!newbuf && errno == ENOMEM) { + sd_rw_unlock(&obj_list_cache.lock); + sd_err("Failed to allocate memory for object list"); + return SD_RES_NO_MEM; + } + obj_list_cache.buf_version = obj_list_cache.tree_version; - obj_list_cache.buf = xrealloc(obj_list_cache.buf, - obj_list_cache.cache_size * sizeof(uint64_t)); + obj_list_cache.buf = newbuf; rb_for_each_entry(entry, &obj_list_cache.root, node) { obj_list_cache.buf[nr++] = entry->oid;