diff --git a/configure.ac b/configure.ac index 13d80856f0060..01eef82ee875c 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ AC_PREREQ(2.59) # VERSION define is not used by the code. It gets a version string # from 'git describe'; see src/ceph_ver.[ch] -AC_INIT([ceph], [0.72-rc1], [ceph-devel@vger.kernel.org]) +AC_INIT([ceph], [0.72], [ceph-devel@vger.kernel.org]) # Create release string. Used with VERSION for RPMs. RPM_RELEASE=0 @@ -539,6 +539,17 @@ AC_CHECK_FUNC([fallocate], [AC_DEFINE([CEPH_HAVE_FALLOCATE], [], [fallocate(2) is supported])], []) +# +# Test for time-related `struct stat` members. +# + +AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec], + [AC_DEFINE(HAVE_STAT_ST_MTIM_TV_NSEC, 1, + [Define if you have struct stat.st_mtim.tv_nsec])]) + +AC_CHECK_MEMBER([struct stat.st_mtimespec.tv_nsec], + [AC_DEFINE(HAVE_STAT_ST_MTIMESPEC_TV_NSEC, 1, + [Define if you have struct stat.st_mtimespec.tv_nsec])]) AC_CHECK_HEADERS([arpa/nameser_compat.h]) AC_CHECK_HEADERS([sys/prctl.h]) diff --git a/debian/changelog b/debian/changelog index f6575c29a726c..dd2dbb95ce4f6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ceph (0.72-1) stable; urgency=low + + * New upstream release + + -- Gary Lowell Thu, 07 Nov 2013 20:25:18 +0000 + ceph (0.72-rc1-1) stable; urgency=low * New upstream release diff --git a/doc/release-notes.rst b/doc/release-notes.rst index b8264146c88a6..6738e2f21e241 100644 --- a/doc/release-notes.rst +++ b/doc/release-notes.rst @@ -407,6 +407,12 @@ v0.69 Upgrading ~~~~~~~~~ +* The sysvinit /etc/init.d/ceph script will, by default, update the + CRUSH location of an OSD when it starts. Previously, if the + monitors were not available, this command would hang indefinitely. + Now, that step will time out after 10 seconds and the ceph-osd daemon + will not be started. + * Users of the librados C++ API should replace users of get_version() with get_version64() as the old method only returns a 32-bit value for a 64-bit field. The existing 32-bit get_version() method is now diff --git a/qa/run_xfstests.sh b/qa/run_xfstests.sh index f9c3e55a79d60..3f5e2eca9f507 100644 --- a/qa/run_xfstests.sh +++ b/qa/run_xfstests.sh @@ -48,7 +48,7 @@ XFS_MKFS_OPTIONS="-l su=32k" # Override the default test list with a list of tests known to pass # until we can work through getting them all passing reliably. -TESTS="1-9 11-15 17 19-21 26-29 31-34 41 46-48 50-54 56 61 63-67 69-70 74-76" +TESTS="1-7 9 11-15 17 19-21 26-29 31-34 41 46-48 50-54 56 61 63-67 69-70 74-76" TESTS="${TESTS} 78 79 84-89 91-92 100 103 105 108 110 116-121 124 126" TESTS="${TESTS} 129-135 137-141 164-167 182 184 187-190 192 194" TESTS="${TESTS} 196 199 201 203 214-216 220-227 234 236-238 241 243-249" @@ -59,6 +59,9 @@ TESTS="${TESTS} 253 257-259 261 262 269 273 275 277 278 280 285 286" ###### # Some explanation of why tests have been excluded above: # +# Test 008 was pulled because it contained a race condition leading to +# spurious failures. +# # Test 049 was pulled because it caused a kernel fault. # http://tracker.newdream.net/issues/2260 # Test 232 was pulled because it caused an XFS error diff --git a/qa/run_xfstests_qemu.sh b/qa/run_xfstests_qemu.sh index 919e46a4d59fc..9dcced7edab38 100644 --- a/qa/run_xfstests_qemu.sh +++ b/qa/run_xfstests_qemu.sh @@ -7,4 +7,4 @@ chmod +x run_xfstests.sh # tests excluded fail in the current testing vm regardless of whether # rbd is used -./run_xfstests.sh -c 1 -f xfs -t /dev/vdb -s /dev/vdc 1-17 19-26 28-49 51-61 63 66-67 69-79 83 85-105 108-110 112-135 137-170 174-191 193-204 206-217 220-227 230-231 233 235-241 243-249 251-262 264-278 281-286 288-289 +./run_xfstests.sh -c 1 -f xfs -t /dev/vdb -s /dev/vdc 1-7 9-17 19-26 28-49 51-61 63 66-67 69-79 83 85-105 108-110 112-135 137-170 174-191 193-204 206-217 220-227 230-231 233 235-241 243-249 251-262 264-278 281-286 288-289 diff --git a/src/client/Client.cc b/src/client/Client.cc index 89de94ee6ea5b..a4d5550849519 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -84,6 +84,7 @@ using namespace std; #include "ObjecterWriteback.h" #include "include/assert.h" +#include "include/stat.h" #undef dout_prefix #define dout_prefix *_dout << "client." << whoami << " " @@ -109,7 +110,6 @@ Client::CommandHook::CommandHook(Client *client) : bool Client::CommandHook::call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { - stringstream ss; Formatter *f = new_formatter(format); f->open_object_section("result"); m_client->client_lock.Lock(); @@ -4503,9 +4503,9 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid, I if (in->caps_issued_mask(CEPH_CAP_FILE_EXCL)) { if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME)) { if (mask & CEPH_SETATTR_MTIME) - in->mtime = utime_t(attr->st_mtim.tv_sec, attr->st_mtim.tv_nsec); + in->mtime = utime_t(stat_get_mtime_sec(attr), stat_get_mtime_nsec(attr)); if (mask & CEPH_SETATTR_ATIME) - in->atime = utime_t(attr->st_atim.tv_sec, attr->st_atim.tv_nsec); + in->atime = utime_t(stat_get_atime_sec(attr), stat_get_atime_nsec(attr)); in->ctime = ceph_clock_now(cct); in->time_warp_seq++; mark_caps_dirty(in, CEPH_CAP_FILE_EXCL); @@ -4535,14 +4535,14 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid, I req->inode_drop |= CEPH_CAP_AUTH_SHARED; } if (mask & CEPH_SETATTR_MTIME) { - req->head.args.setattr.mtime = - utime_t(attr->st_mtim.tv_sec, attr->st_mtim.tv_nsec); + utime_t mtime = utime_t(stat_get_mtime_sec(attr), stat_get_mtime_nsec(attr)); + req->head.args.setattr.mtime = mtime; req->inode_drop |= CEPH_CAP_AUTH_SHARED | CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR; } if (mask & CEPH_SETATTR_ATIME) { - req->head.args.setattr.atime = - utime_t(attr->st_atim.tv_sec, attr->st_atim.tv_nsec); + utime_t atime = utime_t(stat_get_atime_sec(attr), stat_get_atime_nsec(attr)); + req->head.args.setattr.atime = atime; req->inode_drop |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR; } @@ -4652,16 +4652,16 @@ int Client::fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat, nest_inf st->st_uid = in->uid; st->st_gid = in->gid; if (in->ctime.sec() > in->mtime.sec()) { - st->st_ctim.tv_sec = in->ctime.sec(); - st->st_ctim.tv_nsec = in->ctime.nsec(); + stat_set_ctime_sec(st, in->ctime.sec()); + stat_set_ctime_nsec(st, in->ctime.nsec()); } else { - st->st_ctim.tv_sec = in->mtime.sec(); - st->st_ctim.tv_nsec = in->mtime.nsec(); + stat_set_ctime_sec(st, in->mtime.sec()); + stat_set_ctime_nsec(st, in->mtime.nsec()); } - st->st_atim.tv_sec = in->atime.sec(); - st->st_atim.tv_nsec = in->atime.nsec(); - st->st_mtim.tv_sec = in->mtime.sec(); - st->st_mtim.tv_nsec = in->mtime.nsec(); + stat_set_atime_sec(st, in->atime.sec()); + stat_set_atime_nsec(st, in->atime.nsec()); + stat_set_mtime_sec(st, in->mtime.sec()); + stat_set_mtime_nsec(st, in->mtime.nsec()); if (in->is_dir()) { //st->st_size = in->dirstat.size(); st->st_size = in->rstat.rbytes; @@ -4807,10 +4807,10 @@ int Client::utime(const char *relpath, struct utimbuf *buf) if (r < 0) return r; struct stat attr; - attr.st_mtim.tv_sec = buf->modtime; - attr.st_mtim.tv_nsec = 0; - attr.st_atim.tv_sec = buf->actime; - attr.st_atim.tv_nsec = 0; + stat_set_mtime_sec(&attr, buf->modtime); + stat_set_mtime_nsec(&attr, 0); + stat_set_atime_sec(&attr, buf->actime); + stat_set_atime_nsec(&attr, 0); return _setattr(in, &attr, CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME); } @@ -4828,10 +4828,10 @@ int Client::lutime(const char *relpath, struct utimbuf *buf) if (r < 0) return r; struct stat attr; - attr.st_mtim.tv_sec = buf->modtime; - attr.st_mtim.tv_nsec = 0; - attr.st_atim.tv_sec = buf->actime; - attr.st_atim.tv_nsec = 0; + stat_set_mtime_sec(&attr, buf->modtime); + stat_set_mtime_nsec(&attr, 0); + stat_set_atime_sec(&attr, buf->actime); + stat_set_atime_nsec(&attr, 0); return _setattr(in, &attr, CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME); } diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 95c7acdb694a2..819d767d006ff 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1045,7 +1045,7 @@ void buffer::list::rebuild_page_aligned() return 0; // no buffers std::list::const_iterator iter = _buffers.begin(); - iter++; + ++iter; if (iter != _buffers.end()) rebuild(); diff --git a/src/common/hobject.h b/src/common/hobject.h index 8e56d660e3af7..3c2202df4b1b5 100644 --- a/src/common/hobject.h +++ b/src/common/hobject.h @@ -86,6 +86,11 @@ struct hobject_t { return ret; } + /// @return true if object is snapdir + bool is_snapdir() const { + return snap == CEPH_SNAPDIR; + } + /// @return snapdir version of this hobject_t hobject_t get_snapdir() const { hobject_t ret(*this); diff --git a/src/common/sharedptr_registry.hpp b/src/common/sharedptr_registry.hpp index 9fe2fe6be1a10..83396b8cc5f67 100644 --- a/src/common/sharedptr_registry.hpp +++ b/src/common/sharedptr_registry.hpp @@ -149,6 +149,11 @@ class SharedPtrRegistry { return retval; } + unsigned size() { + Mutex::Locker l(lock); + return contents.size(); + } + void remove(const K &key) { Mutex::Locker l(lock); contents.erase(key); diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 34976a6cc2990..6e076600e273c 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -78,4 +78,5 @@ noinst_HEADERS += \ include/rbd/features.h \ include/rbd/librbd.h \ include/rbd/librbd.hpp\ - include/util.h + include/util.h\ + include/stat.h diff --git a/src/include/stat.h b/src/include/stat.h new file mode 100644 index 0000000000000..19398758e210d --- /dev/null +++ b/src/include/stat.h @@ -0,0 +1,145 @@ +#ifndef CEPH_STAT_H +#define CEPH_STAT_H + +#include + +#include + +/* + * Access time-related `struct stat` members. + * + * Note that for each of the stat member get/set functions below, setting a + * high-res value (stat_set_*_nsec) on a platform without high-res support is + * a no-op. + */ + +#ifdef HAVE_STAT_ST_MTIM_TV_NSEC + +static inline uint32_t stat_get_mtime_nsec(struct stat *st) +{ + return st->st_mtim.tv_nsec; +} + +static inline void stat_set_mtime_nsec(struct stat *st, uint32_t nsec) +{ + st->st_mtim.tv_nsec = nsec; +} + +static inline uint32_t stat_get_atime_nsec(struct stat *st) +{ + return st->st_atim.tv_nsec; +} + +static inline void stat_set_atime_nsec(struct stat *st, uint32_t nsec) +{ + st->st_atim.tv_nsec = nsec; +} + +static inline uint32_t stat_get_ctime_nsec(struct stat *st) +{ + return st->st_ctim.tv_nsec; +} + +static inline void stat_set_ctime_nsec(struct stat *st, uint32_t nsec) +{ + st->st_ctim.tv_nsec = nsec; +} + +#elif defined(HAVE_STAT_ST_MTIMESPEC_TV_NSEC) + +static inline uint32_t stat_get_mtime_nsec(struct stat *st) +{ + return st->st_mtimespec.tv_nsec; +} + +static inline void stat_set_mtime_nsec(struct stat *st, uint32_t nsec) +{ + st->st_mtimespec.tv_nsec = nsec; +} + +static inline uint32_t stat_get_atime_nsec(struct stat *st) +{ + return st->st_atimespec.tv_nsec; +} + +static inline void stat_set_atime_nsec(struct stat *st, uint32_t nsec) +{ + st->st_atimespec.tv_nsec = nsec; +} + +static inline uint32_t stat_get_ctime_nsec(struct stat *st) +{ + return st->st_ctimespec.tv_nsec; +} + +static inline void stat_set_ctime_nsec(struct stat *st, uint32_t nsec) +{ + st->st_ctimespec.tv_nsec = nsec; +} + +#else + +static inline uint32_t stat_get_mtime_nsec(struct stat *st) +{ + return 0; +} + +static inline void stat_set_mtime_nsec(struct stat *st, uint32_t nsec) +{ +} + +static inline uint32_t stat_get_atime_nsec(struct stat *st) +{ + return 0; +} + +static inline void stat_set_atime_nsec(struct stat *st, uint32_t nsec) +{ +} + +static inline uint32_t stat_get_ctime_nsec(struct stat *st) +{ + return 0; +} + +static inline void stat_set_ctime_nsec(struct stat *st, uint32_t nsec) +{ +} + +#endif + +/* + * Access second-resolution `struct stat` members. + */ + +static inline uint32_t stat_get_mtime_sec(struct stat *st) +{ + return st->st_mtime; +} + +static inline void stat_set_mtime_sec(struct stat *st, uint32_t sec) +{ + st->st_mtime = sec; +} + +static inline uint32_t stat_get_atime_sec(struct stat *st) +{ + return st->st_atime; +} + +static inline void stat_set_atime_sec(struct stat *st, uint32_t sec) +{ + st->st_atime = sec; +} + +static inline uint32_t stat_get_ctime_sec(struct stat *st) +{ + return st->st_ctime; +} + +static inline void stat_set_ctime_sec(struct stat *st, uint32_t sec) +{ + st->st_ctime = sec; +} + +#endif diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index eb0f6e1d66790..117f84f85f611 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -570,7 +570,6 @@ bool MDSMonitor::preprocess_command(MMonCommand *m) } r = 0; } else if (prefix == "mds dump") { - string val; int64_t epocharg; epoch_t epoch; @@ -633,7 +632,6 @@ bool MDSMonitor::preprocess_command(MMonCommand *m) } else if (prefix == "mds tell") { string whostr; cmd_getval(g_ceph_context, cmdmap, "who", whostr); - string args; vectorargs_vec; cmd_getval(g_ceph_context, cmdmap, "args", args_vec); diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index f976e3101a8e3..2c17cca85b7eb 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -2659,7 +2659,7 @@ int OSDMonitor::prepare_new_pool(string& name, uint64_t auid, int crush_rule, pi->auid = auid; for (vector::const_iterator i = properties.begin(); i != properties.end(); - i++) { + ++i) { size_t equal = i->find('='); if (equal == string::npos) pi->properties[*i] = string(); @@ -2796,10 +2796,15 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, } if (n <= (int)p.get_pg_num()) { ss << "specified pg_num " << n << " <= current " << p.get_pg_num(); - } else if (!mon->pgmon()->pg_map.creating_pgs.empty()) { - ss << "currently creating pgs, wait"; - return -EAGAIN; } else { + for(set::iterator i = mon->pgmon()->pg_map.creating_pgs.begin(); + i != mon->pgmon()->pg_map.creating_pgs.end(); + ++i) { + if (i->m_pool == static_cast(pool)) { + ss << "currently creating pgs, wait"; + return -EAGAIN; + } + } p.set_pg_num(n); ss << "set pool " << pool << " pg_num to " << n; } @@ -2812,10 +2817,15 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, ss << "specified pgp_num must > 0, but you set to " << n; } else if (n > (int)p.get_pg_num()) { ss << "specified pgp_num " << n << " > pg_num " << p.get_pg_num(); - } else if (!mon->pgmon()->pg_map.creating_pgs.empty()) { - ss << "still creating pgs, wait"; - return -EAGAIN; } else { + for(set::iterator i = mon->pgmon()->pg_map.creating_pgs.begin(); + i != mon->pgmon()->pg_map.creating_pgs.end(); + ++i) { + if (i->m_pool == static_cast(pool)) { + ss << "currently creating pgs, wait"; + return -EAGAIN; + } + } p.set_pgp_num(n); ss << "set pool " << pool << " pgp_num to " << n; } diff --git a/src/mon/PGMap.cc b/src/mon/PGMap.cc index ab4c885df4c02..2ba8402b34f60 100644 --- a/src/mon/PGMap.cc +++ b/src/mon/PGMap.cc @@ -787,7 +787,7 @@ void PGMap::print_osd_perf_stats(std::ostream *ss) const } void PGMap::recovery_summary(Formatter *f, ostream *out, - pool_stat_t delta_sum) const + const pool_stat_t& delta_sum) const { bool first = true; if (delta_sum.stats.sum.num_objects_degraded) { @@ -825,7 +825,7 @@ void PGMap::recovery_summary(Formatter *f, ostream *out, } void PGMap::recovery_rate_summary(Formatter *f, ostream *out, - pool_stat_t delta_sum, + const pool_stat_t& delta_sum, utime_t delta_stamp) const { // make non-negative; we can get negative values if osds send @@ -886,7 +886,7 @@ void PGMap::pool_recovery_summary(Formatter *f, ostream *out, } void PGMap::client_io_rate_summary(Formatter *f, ostream *out, - pool_stat_t delta_sum, + const pool_stat_t& delta_sum, utime_t delta_stamp) const { pool_stat_t pos_delta = delta_sum; diff --git a/src/mon/PGMap.h b/src/mon/PGMap.h index c8ce7fd973eba..8a931ecbcca67 100644 --- a/src/mon/PGMap.h +++ b/src/mon/PGMap.h @@ -244,12 +244,12 @@ class PGMap { void print_osd_perf_stats(std::ostream *ss) const; void recovery_summary(Formatter *f, ostream *out, - pool_stat_t delta_sum) const; + const pool_stat_t& delta_sum) const; void overall_recovery_summary(Formatter *f, ostream *out) const; void pool_recovery_summary(Formatter *f, ostream *out, uint64_t poolid) const; void recovery_rate_summary(Formatter *f, ostream *out, - pool_stat_t delta_sum, + const pool_stat_t& delta_sum, utime_t delta_stamp) const; void overall_recovery_rate_summary(Formatter *f, ostream *out) const; void pool_recovery_rate_summary(Formatter *f, ostream *out, @@ -259,7 +259,7 @@ class PGMap { * given @p delta_sum pool over a given @p delta_stamp period of time. */ void client_io_rate_summary(Formatter *f, ostream *out, - pool_stat_t delta_sum, + const pool_stat_t& delta_sum, utime_t delta_stamp) const; /** * Obtain a formatted/plain output for the overall client I/O, which is diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index ffac501aaf20d..89a55b393db7c 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -4273,6 +4273,14 @@ int FileStore::_collection_move_rename(coll_t oldcid, const ghobject_t& oldoid, int r = 0; int dstcmp, srccmp; + if (replaying) { + /* If the destination collection doesn't exist during replay, + * we need to delete the src object and continue on + */ + if (!collection_exists(c)) + goto out_rm_src; + } + dstcmp = _check_replay_guard(c, o, spos); if (dstcmp < 0) goto out_rm_src; diff --git a/src/os/ObjectStore.cc b/src/os/ObjectStore.cc index 1a1bbcb0b67de..327c64167d5cf 100644 --- a/src/os/ObjectStore.cc +++ b/src/os/ObjectStore.cc @@ -504,7 +504,7 @@ int ObjectStore::collection_list(coll_t c, vector& o) int ret = collection_list(c, go); if (ret == 0) { o.reserve(go.size()); - for (vector::iterator i = go.begin(); i != go.end() ; i++) + for (vector::iterator i = go.begin(); i != go.end() ; ++i) o.push_back(i->hobj); } return ret; @@ -520,7 +520,7 @@ int ObjectStore::collection_list_partial(coll_t c, hobject_t start, if (ret == 0) { *next = gnext.hobj; ls->reserve(go.size()); - for (vector::iterator i = go.begin(); i != go.end() ; i++) + for (vector::iterator i = go.begin(); i != go.end() ; ++i) ls->push_back(i->hobj); } return ret; @@ -534,7 +534,7 @@ int ObjectStore::collection_list_range(coll_t c, hobject_t start, hobject_t end, int ret = collection_list_range(c, gstart, gend, seq, &go); if (ret == 0) { ls->reserve(go.size()); - for (vector::iterator i = go.begin(); i != go.end() ; i++) + for (vector::iterator i = go.begin(); i != go.end() ; ++i) ls->push_back(i->hobj); } return ret; diff --git a/src/os/chain_xattr.cc b/src/os/chain_xattr.cc index 8ca815689ed36..c020c9db84398 100644 --- a/src/os/chain_xattr.cc +++ b/src/os/chain_xattr.cc @@ -388,6 +388,10 @@ int chain_listxattr(const char *fn, char *names, size_t len) { int chain_flistxattr(int fd, char *names, size_t len) { int r; + char *p; + const char * end; + char *dest; + char *dest_end; if (!len) return sys_flistxattr(fd, names, len) * 2; @@ -403,12 +407,12 @@ int chain_flistxattr(int fd, char *names, size_t len) { r = sys_flistxattr(fd, full_buf, total_len); if (r < 0) - return r; + goto done; - char *p = full_buf; - const char *end = full_buf + r; - char *dest = names; - char *dest_end = names + len; + p = full_buf; + end = full_buf + r; + dest = names; + dest_end = names + len; while (p < end) { char name[CHAIN_XATTR_MAX_NAME_LEN * 2 + 16]; diff --git a/src/osd/ErasureCodePlugin.cc b/src/osd/ErasureCodePlugin.cc index 38ea56a174c25..5d0b6904e1ea2 100644 --- a/src/osd/ErasureCodePlugin.cc +++ b/src/osd/ErasureCodePlugin.cc @@ -45,7 +45,7 @@ ErasureCodePluginRegistry::~ErasureCodePluginRegistry() { for (std::map::iterator i = plugins.begin(); i != plugins.end(); - i++) { + ++i) { void *library = i->second->library; delete i->second; dlclose(library); diff --git a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc index f2be1ed06e711..fe656e58ee00f 100644 --- a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc +++ b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc @@ -54,7 +54,7 @@ int ErasureCodeJerasure::minimum_to_decode(const set &want_to_read, return -EIO; set::iterator i; unsigned j; - for (i = available_chunks.begin(), j = 0; j < (unsigned)k; i++, j++) + for (i = available_chunks.begin(), j = 0; j < (unsigned)k; ++i, j++) minimum->insert(*i); } return 0; @@ -67,7 +67,7 @@ int ErasureCodeJerasure::minimum_to_decode_with_cost(const set &want_to_rea set available_chunks; for (map::const_iterator i = available.begin(); i != available.end(); - i++) + ++i) available_chunks.insert(i->first); return minimum_to_decode(want_to_read, available_chunks, minimum); } diff --git a/src/osd/ErasureCodePluginJerasure/galois.c b/src/osd/ErasureCodePluginJerasure/galois.c index be8be59affa0c..0de6fbd334cfe 100755 --- a/src/osd/ErasureCodePluginJerasure/galois.c +++ b/src/osd/ErasureCodePluginJerasure/galois.c @@ -693,7 +693,7 @@ void galois_w32_region_multiply(char *region, /* Region to multiply */ nbytes /= sizeof(int); if (galois_split_w8[0]== NULL) { - if (galois_create_split_w8_tables(8) < 0) { + if (galois_create_split_w8_tables() < 0) { fprintf(stderr, "galois_32_region_multiply -- couldn't make split multiplication tables\n"); exit(1); } diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 0baeb5717806c..d63a0a1c11578 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -2201,9 +2201,10 @@ void OSD::handle_pg_peering_evt( int role = osdmap->calc_pg_role(whoami, acting, acting.size()); pg_history_t history = info.history; - project_pg_history(info.pgid, history, epoch, up, acting); + bool valid_history = project_pg_history( + info.pgid, history, epoch, up, acting); - if (epoch < history.same_interval_since) { + if (!valid_history || epoch < history.same_interval_since) { dout(10) << "get_or_create_pg " << info.pgid << " acting changed in " << history.same_interval_since << " (msg from " << epoch << ")" << dendl; return; @@ -2388,7 +2389,7 @@ void OSD::calc_priors_during(pg_t pgid, epoch_t start, epoch_t end, set& ps * Fill in the passed history so you know same_interval_since, same_up_since, * and same_primary_since. */ -void OSD::project_pg_history(pg_t pgid, pg_history_t& h, epoch_t from, +bool OSD::project_pg_history(pg_t pgid, pg_history_t& h, epoch_t from, const vector& currentup, const vector& currentacting) { @@ -2402,7 +2403,11 @@ void OSD::project_pg_history(pg_t pgid, pg_history_t& h, epoch_t from, e > from; e--) { // verify during intermediate epoch (e-1) - OSDMapRef oldmap = get_map(e-1); + OSDMapRef oldmap = service.try_get_map(e-1); + if (!oldmap) { + dout(15) << __func__ << ": found map gap, returning false" << dendl; + return false; + } assert(oldmap->have_pg_pool(pgid.pool())); vector up, acting; @@ -2452,6 +2457,7 @@ void OSD::project_pg_history(pg_t pgid, pg_history_t& h, epoch_t from, } dout(15) << "project_pg_history end " << h << dendl; + return true; } // ------------------------------------- @@ -5441,22 +5447,6 @@ void OSD::advance_map(ObjectStore::Transaction& t, C_Contexts *tfin) waiting_for_pg.erase(p++); } } - map >::iterator q = - peering_wait_for_split.begin(); - while (q != peering_wait_for_split.end()) { - pg_t pgid = q->first; - - // am i still primary? - vector acting; - int nrep = osdmap->pg_to_acting_osds(pgid, acting); - int role = osdmap->calc_pg_role(whoami, acting, nrep); - if (role >= 0) { - ++q; // still me - } else { - dout(10) << " discarding waiting ops for " << pgid << dendl; - peering_wait_for_split.erase(q++); - } - } } void OSD::consume_map() @@ -5935,7 +5925,12 @@ void OSD::handle_pg_create(OpRequestRef op) utime_t now = ceph_clock_now(NULL); history.last_scrub_stamp = now; history.last_deep_scrub_stamp = now; - project_pg_history(pgid, history, created, up, acting); + bool valid_history = + project_pg_history(pgid, history, created, up, acting); + /* the pg creation message must have come from a mon and therefore + * cannot be on the other side of a map gap + */ + assert(valid_history); // register. creating_pgs[pgid].history = history; @@ -6547,9 +6542,11 @@ void OSD::handle_pg_query(OpRequestRef op) // same primary? pg_history_t history = it->second.history; - project_pg_history(pgid, history, it->second.epoch_sent, up, acting); + bool valid_history = + project_pg_history(pgid, history, it->second.epoch_sent, up, acting); - if (it->second.epoch_sent < history.same_interval_since) { + if (!valid_history || + it->second.epoch_sent < history.same_interval_since) { dout(10) << " pg " << pgid << " dne, and pg has changed in " << history.same_interval_since << " (msg from " << it->second.epoch_sent << ")" << dendl; @@ -6613,9 +6610,11 @@ void OSD::handle_pg_remove(OpRequestRef op) pg_history_t history = pg->info.history; vector up, acting; osdmap->pg_to_up_acting_osds(pgid, up, acting); - project_pg_history(pg->info.pgid, history, pg->get_osdmap()->get_epoch(), - up, acting); - if (history.same_interval_since <= m->get_epoch()) { + bool valid_history = + project_pg_history(pg->info.pgid, history, pg->get_osdmap()->get_epoch(), + up, acting); + if (valid_history && + history.same_interval_since <= m->get_epoch()) { assert(pg->get_primary() == m->get_source().num()); PGRef _pg(pg); _remove_pg(pg); diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 29615558fefc0..11ad2b89399be 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -1191,8 +1191,12 @@ class OSD : public Dispatcher, void build_past_intervals_parallel(); void calc_priors_during(pg_t pgid, epoch_t start, epoch_t end, set& pset); - void project_pg_history(pg_t pgid, pg_history_t& h, epoch_t from, - const vector& lastup, const vector& lastacting); + + /// project pg history from from to now + bool project_pg_history( + pg_t pgid, pg_history_t& h, epoch_t from, + const vector& lastup, const vector& lastacting + ); ///< @return false if there was a map gap between from and now void wake_pg_waiters(pg_t pgid) { if (waiting_for_pg.count(pgid)) { diff --git a/src/osd/PG.cc b/src/osd/PG.cc index e92013abdc733..8207a675bce4a 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -2399,13 +2399,7 @@ void PG::log_weirdness() << " != info.last_update " << info.last_update << "\n"; - if (pg_log.get_log().empty()) { - // shoudl it be? - if (pg_log.get_head() != pg_log.get_tail()) - osd->clog.error() << info.pgid - << " log bound mismatch, empty but (" << pg_log.get_tail() << "," - << pg_log.get_head() << "]\n"; - } else { + if (!pg_log.get_log().empty()) { // sloppy check if ((pg_log.get_log().log.begin()->version <= pg_log.get_tail())) osd->clog.error() << info.pgid @@ -4679,19 +4673,11 @@ ostream& operator<<(ostream& out, const PG& pg) pg.pg_log.get_head() != pg.info.last_update) out << " (info mismatch, " << pg.pg_log.get_log() << ")"; - if (pg.pg_log.get_log().empty()) { - // shoudl it be? - if (pg.pg_log.get_head().version - pg.pg_log.get_tail().version != 0) { - out << " (log bound mismatch, empty)"; - } - } else { - if ((pg.pg_log.get_log().log.begin()->version <= pg.pg_log.get_tail()) || // sloppy check - (pg.pg_log.get_log().log.rbegin()->version != pg.pg_log.get_head() && - !(pg.pg_log.get_head() == pg.pg_log.get_tail()))) { + if (!pg.pg_log.get_log().empty()) { + if ((pg.pg_log.get_log().log.begin()->version <= pg.pg_log.get_tail())) { out << " (log bound mismatch, actual=[" << pg.pg_log.get_log().log.begin()->version << "," << pg.pg_log.get_log().log.rbegin()->version << "]"; - //out << "len=" << pg.log.log.size(); out << ")"; } } diff --git a/src/osd/PGLog.cc b/src/osd/PGLog.cc index 526baecf1284a..9f6ca1f70c3bc 100644 --- a/src/osd/PGLog.cc +++ b/src/osd/PGLog.cc @@ -360,7 +360,7 @@ void PGLog::rewind_divergent_log(ObjectStore::Transaction& t, eversion_t newhead } --p; mark_dirty_from(p->version); - if (p->version == newhead) { + if (p->version <= newhead) { ++p; divergent.splice(divergent.begin(), log.log, p, log.log.end()); break; diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 500042d16e3a4..10ab6a13df6ed 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -655,19 +655,38 @@ void ReplicatedPG::do_pg_op(OpRequestRef op) map::const_iterator missing_iter = pg_log.get_missing().missing.lower_bound(current); vector::iterator ls_iter = sentries.begin(); + hobject_t _max = hobject_t::get_max(); while (1) { - if (ls_iter == sentries.end()) { - break; - } + const hobject_t &mcand = + missing_iter == pg_log.get_missing().missing.end() ? + _max : + missing_iter->first; + const hobject_t &lcand = + ls_iter == sentries.end() ? + _max : + *ls_iter; hobject_t candidate; - if (missing_iter == pg_log.get_missing().missing.end() || - *ls_iter < missing_iter->first) { - candidate = *(ls_iter++); + if (mcand == lcand) { + candidate = mcand; + if (!mcand.is_max()) { + ls_iter++; + missing_iter++; + } + } else if (mcand < lcand) { + candidate = mcand; + assert(!mcand.is_max()); + ++missing_iter; } else { - candidate = (missing_iter++)->first; + candidate = lcand; + assert(!lcand.is_max()); + ++ls_iter; } + if (candidate >= next) { + break; + } + if (response.entries.size() == list_size) { next = candidate; break; @@ -8110,7 +8129,6 @@ int ReplicatedPG::recover_backfill( } PGBackend::RecoveryHandle *h = pgbackend->open_recovery_op(); - map > pushes; for (map >::iterator i = to_push.begin(); @@ -8142,6 +8160,17 @@ int ReplicatedPG::recover_backfill( assert(i->first > new_last_backfill); new_last_backfill = i->first; } + + /* If last_backfill is snapdir, we know that head necessarily cannot exist, + * therefore it's safe to bump the snap up to NOSNAP. This is necessary + * since we need avoid having SNAPDIR backfilled and HEAD not backfilled + * since a transaction on HEAD might change SNAPDIR + */ + if (new_last_backfill.is_snapdir()) + new_last_backfill = new_last_backfill.get_head(); + if (last_backfill_started.is_snapdir()) + last_backfill_started = last_backfill_started.get_head(); + assert(!pending_backfill_updates.empty() || new_last_backfill == last_backfill_started); if (pending_backfill_updates.empty() && diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 05b83c4af21bd..0cb3c0c64897b 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -1062,7 +1062,7 @@ ostream& operator<<(ostream& out, const pg_pool_t& p) out << " max_bytes " << p.quota_max_bytes; if (p.quota_max_objects) out << " max_objects " << p.quota_max_objects; - if (p.tiers.size()) + if (!p.tiers.empty()) out << " tiers " << p.tiers; if (p.is_tier()) out << " tier_of " << p.tier_of; diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index d2c574d982e1e..734df5e9e6900 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -2406,7 +2406,6 @@ Objecter::RequestStateHook::RequestStateHook(Objecter *objecter) : bool Objecter::RequestStateHook::call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { - stringstream ss; Formatter *f = new_formatter(format); m_objecter->client_lock.Lock(); m_objecter->dump_requests(f); diff --git a/src/rbd.cc b/src/rbd.cc index 147eb2c5138e9..41cd243735520 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -1643,12 +1643,12 @@ static int do_kernel_add(const char *poolname, const char *imgname, } if (read_only) - oss << " ro"; + oss << " ro,"; else - oss << " rw"; + oss << " "; const char *user = g_conf->name.get_id().c_str(); - oss << ",name=" << user; + oss << "name=" << user; char key_name[strlen(user) + strlen("client.") + 1]; snprintf(key_name, sizeof(key_name), "client.%s", user); diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 314e80b9ef26c..1c6b6d4d71ba0 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -234,7 +234,7 @@ static int do_curl_wait(CephContext *cct, CURLM *handle) int RGWHTTPClient::process_request(void *handle, bool wait_for_data, bool *done) { - multi_req_data *req_data = (multi_req_data *)handle; + multi_req_data *req_data = static_cast(handle); int still_running; int mstatus; @@ -282,7 +282,7 @@ int RGWHTTPClient::complete_request(void *handle) do { ret = process_request(handle, true, &done); } while (!done && !ret); - multi_req_data *req_data = (multi_req_data *)handle; + multi_req_data *req_data = static_cast(handle); delete req_data; return ret; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index c750276596f83..bd73a239a4bf1 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -418,6 +418,11 @@ int RGWOp::verify_op_mask() return -EPERM; } + if (!s->system_request && (required_mask & RGW_OP_TYPE_MODIFY) && !store->zone.is_master) { + ldout(s->cct, 5) << "NOTICE: modify request to a non-master zone by a non-system user, permission denied" << dendl; + return -EPERM; + } + return 0; } diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc index 66609ca723c28..89611f5858769 100644 --- a/src/rgw/rgw_quota.cc +++ b/src/rgw/rgw_quota.cc @@ -126,7 +126,6 @@ class AsyncRefreshHandler : public RGWGetBucketStats_CB { int AsyncRefreshHandler::init_fetch() { ldout(store->ctx(), 20) << "initiating async quota refresh for bucket=" << bucket << dendl; - map bucket_stats; int r = store->get_bucket_stats_async(bucket, this); if (r < 0) { ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket.name << dendl; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 4d6f8ef45301a..55d4b92bcbdb0 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -362,6 +362,10 @@ int RGWZoneParams::init(CephContext *cct, RGWRados *store, RGWRegion& region) return -EIO; } + is_master = (name == region.master_zone) || (region.master_zone.empty() && name == "default"); + + ldout(cct, 2) << "zone " << name << " is " << (is_master ? "" : "NOT ") << "master" << dendl; + return 0; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 874492ffe692d..476572ce3f6c9 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -428,11 +428,14 @@ struct RGWZoneParams { rgw_bucket user_uid_pool; string name; + bool is_master; RGWAccessKey system_key; map placement_pools; + RGWZoneParams() : is_master(false) {} + static int get_pool_name(CephContext *cct, string *pool_name); void init_name(CephContext *cct, RGWRegion& region); int init(CephContext *cct, RGWRados *store, RGWRegion& region); diff --git a/src/rgw/rgw_rest_metadata.cc b/src/rgw/rgw_rest_metadata.cc index 5036235ebd2b6..afd5c7b6cc055 100644 --- a/src/rgw/rgw_rest_metadata.cc +++ b/src/rgw/rgw_rest_metadata.cc @@ -31,7 +31,6 @@ static inline void frame_metadata_key(req_state *s, string& out) { bool exists; string key = s->info.args.get("key", &exists); - string metadata_key; string section; if (!s->bucket_name_str.empty()) { section = s->bucket_name_str; diff --git a/src/rgw/rgw_rest_replica_log.cc b/src/rgw/rgw_rest_replica_log.cc index 600a8edb78c5b..2543f32fba6e8 100644 --- a/src/rgw/rgw_rest_replica_log.cc +++ b/src/rgw/rgw_rest_replica_log.cc @@ -171,7 +171,9 @@ static int bucket_instance_to_bucket(RGWRados *store, string& bucket_instance, r int r = store->get_bucket_instance_info(NULL, bucket_instance, bucket_info, &mtime, NULL); if (r < 0) { - dout(5) << "could not get bucket instance info for bucket=" << bucket_instance << dendl; + dout(5) << "could not get bucket instance info for bucket=" << bucket_instance << ": " << cpp_strerror(r) << dendl; + if (r == -ENOENT) + return r; return -EINVAL; } diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index dc529e3d48d4b..e4462ec11e05e 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -2358,7 +2358,7 @@ class RGWUserMetadataHandler : public RGWMetadataHandler { } int list_keys_next(void *handle, int max, list& keys, bool *truncated) { - list_keys_info *info = (list_keys_info *)handle; + list_keys_info *info = static_cast(handle); string no_filter; @@ -2387,7 +2387,7 @@ class RGWUserMetadataHandler : public RGWMetadataHandler { } void list_keys_complete(void *handle) { - list_keys_info *info = (list_keys_info *)handle; + list_keys_info *info = static_cast(handle); delete info; } }; diff --git a/src/test/cli/osdmaptool/clobber.t b/src/test/cli/osdmaptool/clobber.t index 9bbe4d4ceeb7f..bbec5f0de636a 100644 --- a/src/test/cli/osdmaptool/clobber.t +++ b/src/test/cli/osdmaptool/clobber.t @@ -3,6 +3,7 @@ osdmaptool: writing epoch 1 to myosdmap $ ORIG_FSID="$(osdmaptool --print myosdmap|grep ^fsid)" + osdmaptool: osdmap file 'myosdmap' $ osdmaptool --createsimple 3 myosdmap osdmaptool: osdmap file 'myosdmap' @@ -27,6 +28,7 @@ $ NEW_FSID="$(osdmaptool --print myosdmap|grep ^fsid)" + osdmaptool: osdmap file 'myosdmap' $ [ "$ORIG_FSID" = "$NEW_FSID" ] $ osdmaptool --createsimple 1 --clobber myosdmap @@ -49,6 +51,7 @@ $ NEW_FSID="$(osdmaptool --print myosdmap|grep ^fsid)" + osdmaptool: osdmap file 'myosdmap' #TODO --clobber should probably set new fsid, remove the [1] $ [ "$ORIG_FSID" != "$NEW_FSID" ] [1] diff --git a/src/test/cli/osdmaptool/create-racks.t b/src/test/cli/osdmaptool/create-racks.t index 92bc995a227c5..f686ef4c05131 100644 --- a/src/test/cli/osdmaptool/create-racks.t +++ b/src/test/cli/osdmaptool/create-racks.t @@ -1,4 +1,5 @@ $ osdmaptool --create-from-conf om -c $TESTDIR/ceph.conf.withracks > /dev/null + osdmaptool: osdmap file 'om' $ osdmaptool --test-map-pg 0.0 om osdmaptool: osdmap file 'om' parsed '0.0' -> 0.0 diff --git a/src/test/old/test_seek_read.c b/src/test/old/test_seek_read.c index aedb32a2ae0b5..1ea3b750b455f 100644 --- a/src/test/old/test_seek_read.c +++ b/src/test/old/test_seek_read.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) utime_t start = ceph_clock_now(g_ceph_context); for (int i=0; i > pool_obj_cont; set oid_in_use; set oid_not_in_use; - set snaps_in_use; + SharedPtrRegistry snaps_in_use; int current_snap; string pool_name; librados::IoCtx io_ctx; @@ -1321,6 +1322,7 @@ class RollbackOp : public TestOp { bool done; librados::ObjectWriteOperation op; librados::AioCompletion *comp; + std::tr1::shared_ptr in_use; RollbackOp(int n, RadosTestContext *context, @@ -1351,7 +1353,9 @@ class RollbackOp : public TestOp { context->oid_not_in_use.erase(oid); roll_back_to = rand_choose(context->snaps)->first; - context->snaps_in_use.insert(roll_back_to); + in_use = context->snaps_in_use.lookup_or_create( + roll_back_to, + roll_back_to); cout << "rollback oid " << oid << " to " << roll_back_to << std::endl; @@ -1382,7 +1386,7 @@ class RollbackOp : public TestOp { context->update_object_version(oid, comp->get_version64()); context->oid_in_use.erase(oid); context->oid_not_in_use.insert(oid); - context->snaps_in_use.erase(roll_back_to); + in_use = std::tr1::shared_ptr(); context->kick(); } diff --git a/src/test/osd/TestRados.cc b/src/test/osd/TestRados.cc index 0c1d55c7777e6..20a4f8209cc55 100644 --- a/src/test/osd/TestRados.cc +++ b/src/test/osd/TestRados.cc @@ -116,7 +116,7 @@ class WeightedTestGenerator : public TestOpGenerator } while (true) { int snap = rand_choose(context.snaps)->first; - if (context.snaps_in_use.count(snap)) + if (context.snaps_in_use.lookup(snap)) continue; // in use; try again! cout << "snap_remove snap " << snap << std::endl; return new SnapRemoveOp(m_op, &context, snap, m_stats); diff --git a/src/tools/osdmaptool.cc b/src/tools/osdmaptool.cc index 2e55026076c32..edd31284c4d4f 100644 --- a/src/tools/osdmaptool.cc +++ b/src/tools/osdmaptool.cc @@ -156,7 +156,7 @@ int main(int argc, const char **argv) OSDMap osdmap; bufferlist bl; - cout << me << ": osdmap file '" << fn << "'" << std::endl; + cerr << me << ": osdmap file '" << fn << "'" << std::endl; int r = 0; struct stat st;