From: xiexingguo Date: Sun, 20 Dec 2015 08:19:59 +0000 (+0800) Subject: librbd: fix snap_exists API overflow issue X-Git-Tag: v10.0.3~190^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c97b1a68aee78bea6010462756c986ac6875adcc;p=ceph.git librbd: fix snap_exists API overflow issue The original one may overflow and thus not be safe. Fixes: #14129 Signed-off-by: xie xingguo --- diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 288e450aab8..d9bf1de65d0 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -206,7 +206,9 @@ public: /* snapshots */ int snap_list(std::vector& snaps); - bool snap_exists(const char *snapname); + /* DEPRECATED; use snap_exists2 */ + bool snap_exists(const char *snapname) __attribute__ ((deprecated)); + int snap_exists2(const char *snapname, bool *exists); int snap_create(const char *snapname); int snap_remove(const char *snapname); int snap_rollback(const char *snap_name); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index abaf475e7e0..db39dbed9c6 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -2223,7 +2223,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { return 0; } - bool snap_exists(ImageCtx *ictx, const char *snap_name) + int snap_exists(ImageCtx *ictx, const char *snap_name, bool *exists) { ldout(ictx->cct, 20) << "snap_exists " << ictx << " " << snap_name << dendl; @@ -2232,7 +2232,8 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { return r; RWLock::RLocker l(ictx->snap_lock); - return ictx->get_snap_id(snap_name) != CEPH_NOSNAP; + *exists = ictx->get_snap_id(snap_name) != CEPH_NOSNAP; + return 0; } int snap_rollback(ImageCtx *ictx, const char *snap_name, diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 81368a84567..cbcc8b10c89 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -126,7 +126,7 @@ namespace librbd { int snap_create(ImageCtx *ictx, const char *snap_name); void snap_create_helper(ImageCtx *ictx, Context* ctx, const char *snap_name); int snap_list(ImageCtx *ictx, std::vector& snaps); - bool snap_exists(ImageCtx *ictx, const char *snap_name); + int snap_exists(ImageCtx *ictx, const char *snap_name, bool *exists); int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx); int snap_remove(ImageCtx *ictx, const char *snap_name); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index d4edc227b7e..0807359af16 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -816,7 +816,27 @@ namespace librbd { bool Image::snap_exists(const char *snap_name) { ImageCtx *ictx = (ImageCtx *)ctx; - return librbd::snap_exists(ictx, snap_name); + tracepoint(librbd, snap_exists_enter, ictx, ictx->name.c_str(), + ictx->snap_name.c_str(), ictx->read_only, snap_name); + bool exists; + int r = librbd::snap_exists(ictx, snap_name, &exists); + tracepoint(librbd, snap_exists_exit, r, exists); + if (r < 0) { + // lie to caller since we don't know the real answer yet. + return false; + } + return exists; + } + + // A safer verion of snap_exists. + int Image::snap_exists2(const char *snap_name, bool *exists) + { + ImageCtx *ictx = (ImageCtx *)ctx; + tracepoint(librbd, snap_exists_enter, ictx, ictx->name.c_str(), + ictx->snap_name.c_str(), ictx->read_only, snap_name); + int r = librbd::snap_exists(ictx, snap_name, exists); + tracepoint(librbd, snap_exists_exit, r, *exists); + return r; } int Image::snap_set(const char *snap_name) diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index 146e06ebc8d..58cbc13a78d 100644 --- a/src/tracing/librbd.tp +++ b/src/tracing/librbd.tp @@ -1217,6 +1217,32 @@ TRACEPOINT_EVENT(librbd, snap_is_protected_exit, ) ) +TRACEPOINT_EVENT(librbd, snap_exists_enter, + TP_ARGS( + void*, imagectx, + const char*, name, + const char*, snap_name, + char, read_only, + const char*, snap_name_to_check), + TP_FIELDS( + ctf_integer_hex(void*, imagectx, imagectx) + ctf_string(name, name) + ctf_string(snap_name, snap_name) + ctf_integer(char, read_only, read_only) + ctf_string(snap_name_to_check, snap_name_to_check) + ) +) + +TRACEPOINT_EVENT(librbd, snap_exists_exit, + TP_ARGS( + int, retval, + int, exists), + TP_FIELDS( + ctf_integer(int, retval, retval) + ctf_integer(int, exists, exists) + ) +) + TRACEPOINT_EVENT(librbd, snap_set_enter, TP_ARGS( void*, imagectx,