diff options
author | Sage Weil <sage@inktank.com> | 2013-09-23 09:50:10 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-09-23 09:50:10 -0700 |
commit | 10363daddb5101a21f77fc67dfe502700ecf0737 (patch) | |
tree | 678347f06a3520dab7585c2fafb25de2c7e8c714 | |
parent | 991139bc0de1147171a08c21cfffd0dc57cd2b81 (diff) | |
parent | 3c64784e3fcbd0530acf14c7e3b37cae4cd54a91 (diff) | |
download | ceph-10363daddb5101a21f77fc67dfe502700ecf0737.tar.gz |
Merge remote-tracking branch 'gh/next'
-rwxr-xr-x | qa/workunits/cephtool/test.sh | 7 | ||||
-rw-r--r-- | src/common/buffer.cc | 9 | ||||
-rw-r--r-- | src/common/lru_map.h | 48 | ||||
-rw-r--r-- | src/mds/MDS.cc | 4 | ||||
-rw-r--r-- | src/osd/OSD.cc | 4 | ||||
-rw-r--r-- | src/perfglue/heap_profiler.cc | 10 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 30 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 2 |
8 files changed, 73 insertions, 41 deletions
diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index d92c2709dfd..51420a2f134 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -334,4 +334,11 @@ ceph pg set_full_ratio 95 2>$TMPFILE; check_response $? 22 'not in range' # expect "not in range" for invalid overload percentage ceph osd reweight-by-utilization 80 2>$TMPFILE; check_response $? 22 'not in range' +# expect 'heap' commands to be correctly parsed +ceph heap stats +ceph heap start_profiler +ceph heap dump +ceph heap stop_profiler +ceph heap release + echo OK diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 0424887139e..24a61724c8e 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -990,11 +990,14 @@ void buffer::list::rebuild_page_aligned() */ char *buffer::list::c_str() { - if (_buffers.size() == 0) + if (_buffers.empty()) return 0; // no buffers - if (_buffers.size() > 1) + + std::list<ptr>::const_iterator iter = _buffers.begin(); + iter++; + + if (iter != _buffers.end()) rebuild(); - assert(_buffers.size() == 1); return _buffers.front().c_str(); // good, we're already contiguous. } diff --git a/src/common/lru_map.h b/src/common/lru_map.h index fb637478884..6e7f7b3786f 100644 --- a/src/common/lru_map.h +++ b/src/common/lru_map.h @@ -13,8 +13,8 @@ class lru_map { typename std::list<K>::iterator lru_iter; }; - std::map<K, entry> tokens; - std::list<K> tokens_lru; + std::map<K, entry> entries; + std::list<K> entries_lru; Mutex lock; @@ -33,19 +33,19 @@ template <class K, class V> bool lru_map<K, V>::find(const K& key, V& value) { lock.Lock(); - typename std::map<K, entry>::iterator iter = tokens.find(key); - if (iter == tokens.end()) { + typename std::map<K, entry>::iterator iter = entries.find(key); + if (iter == entries.end()) { lock.Unlock(); return false; } entry& e = iter->second; - tokens_lru.erase(e.lru_iter); + entries_lru.erase(e.lru_iter); value = e.value; - tokens_lru.push_front(key); - e.lru_iter = tokens_lru.begin(); + entries_lru.push_front(key); + e.lru_iter = entries_lru.begin(); lock.Unlock(); @@ -56,23 +56,23 @@ template <class K, class V> void lru_map<K, V>::add(const K& key, V& value) { lock.Lock(); - typename std::map<K, entry>::iterator iter = tokens.find(key); - if (iter != tokens.end()) { + typename std::map<K, entry>::iterator iter = entries.find(key); + if (iter != entries.end()) { entry& e = iter->second; - tokens_lru.erase(e.lru_iter); + entries_lru.erase(e.lru_iter); } - tokens_lru.push_front(key); - entry& e = tokens[key]; + entries_lru.push_front(key); + entry& e = entries[key]; e.value = value; - e.lru_iter = tokens_lru.begin(); - - while (tokens_lru.size() > max) { - typename std::list<K>::reverse_iterator riter = tokens_lru.rbegin(); - iter = tokens.find(*riter); - // assert(iter != tokens.end()); - tokens.erase(iter); - tokens_lru.pop_back(); + e.lru_iter = entries_lru.begin(); + + while (entries.size() > max) { + typename std::list<K>::reverse_iterator riter = entries_lru.rbegin(); + iter = entries.find(*riter); + // assert(iter != entries.end()); + entries.erase(iter); + entries_lru.pop_back(); } lock.Unlock(); @@ -82,13 +82,13 @@ template <class K, class V> void lru_map<K, V>::erase(const K& key) { Mutex::Locker l(lock); - typename std::map<K, entry>::iterator iter = tokens.find(key); - if (iter == tokens.end()) + typename std::map<K, entry>::iterator iter = entries.find(key); + if (iter == entries.end()) return; entry& e = iter->second; - tokens_lru.erase(e.lru_iter); - tokens.erase(iter); + entries_lru.erase(e.lru_iter); + entries.erase(iter); } #endif diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index fc05ca0ecb7..c2e0bbbe369 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -800,7 +800,9 @@ void MDS::handle_command(MMonCommand *m) clog.info() << "tcmalloc not enabled, can't use heap profiler commands\n"; else { ostringstream ss; - ceph_heap_profiler_handle_command(m->cmd, ss); + vector<std::string> cmdargs; + cmdargs.insert(cmdargs.begin(), m->cmd.begin()+1, m->cmd.end()); + ceph_heap_profiler_handle_command(cmdargs, ss); clog.info() << ss.str(); } } else dout(0) << "unrecognized command! " << m->cmd << dendl; diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index ff1276969d8..1cdc232b064 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -3966,6 +3966,10 @@ COMMAND("bench " \ "(default 1G size 4MB). Results in log.", "osd", "rw", "cli,rest") COMMAND("flush_pg_stats", "flush pg stats", "osd", "rw", "cli,rest") +COMMAND("heap " \ + "name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \ + "show heap usage info (available only if compiled with tcmalloc)", \ + "osd", "rw", "cli,rest") COMMAND("debug_dump_missing " \ "name=filename,type=CephFilepath", "dump missing objects to a named file", "osd", "r", "cli,rest") diff --git a/src/perfglue/heap_profiler.cc b/src/perfglue/heap_profiler.cc index 550f7f924c6..6b079b865fa 100644 --- a/src/perfglue/heap_profiler.cc +++ b/src/perfglue/heap_profiler.cc @@ -88,7 +88,7 @@ void ceph_heap_profiler_dump(const char *reason) void ceph_heap_profiler_handle_command(const std::vector<std::string>& cmd, ostream& out) { - if (cmd.size() == 2 && cmd[1] == "dump") { + if (cmd.size() == 1 && cmd[0] == "dump") { if (!ceph_heap_profiler_running()) { out << "heap profiler not running; can't dump"; return; @@ -98,16 +98,16 @@ void ceph_heap_profiler_handle_command(const std::vector<std::string>& cmd, out << g_conf->name << "dumping heap profile now.\n" << heap_stats; ceph_heap_profiler_dump("admin request"); - } else if (cmd.size() == 2 && cmd[1] == "start_profiler") { + } else if (cmd.size() == 1 && cmd[0] == "start_profiler") { ceph_heap_profiler_start(); out << g_conf->name << " started profiler"; - } else if (cmd.size() == 2 && cmd[1] == "stop_profiler") { + } else if (cmd.size() == 1 && cmd[0] == "stop_profiler") { ceph_heap_profiler_stop(); out << g_conf->name << " stopped profiler"; - } else if (cmd.size() == 2 && cmd[1] == "release") { + } else if (cmd.size() == 1 && cmd[0] == "release") { ceph_heap_release_free_memory(); out << g_conf->name << " releasing free RAM back to system."; - } else if (cmd.size() == 2 && cmd[1] == "stats") { + } else if (cmd.size() == 1 && cmd[0] == "stats") { char *heap_stats = new char[1024]; ceph_heap_profiler_stats(heap_stats, 1024); out << g_conf->name << "tcmalloc heap stats:" diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index bada7d22d1b..3db7c719a82 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2493,6 +2493,22 @@ static void set_copy_attrs(map<string, bufferlist>& src_attrs, map<string, buffe } } +class GetObjHandleDestructor { + RGWRados *store; + void **handle; + +public: + GetObjHandleDestructor(RGWRados *_store) : store(_store), handle(NULL) {} + ~GetObjHandleDestructor() { + if (handle) { + store->finish_get_obj(handle); + } + } + void set_handle(void **_h) { + handle = _h; + } +}; + /** * Copy an object. * dest_obj: the object to copy into @@ -2547,6 +2563,7 @@ int RGWRados::copy_obj(void *ctx, ldout(cct, 5) << "Copy object " << src_obj.bucket << ":" << src_obj.object << " => " << dest_obj.bucket << ":" << dest_obj.object << dendl; void *handle = NULL; + GetObjHandleDestructor handle_destructor(this); map<string, bufferlist> src_attrs; off_t ofs = 0; @@ -2556,6 +2573,8 @@ int RGWRados::copy_obj(void *ctx, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &obj_size, NULL, &handle, err); if (ret < 0) return ret; + + handle_destructor.set_handle(&handle); } else { /* source is in a different region, copy it there */ @@ -2616,7 +2635,7 @@ int RGWRados::copy_obj(void *ctx, { /* opening scope so that we can do goto, sorry */ bufferlist& extra_data_bl = processor.get_extra_data(); if (extra_data_bl.length()) { - extra_data_bl.push_back((char)0); + extra_data_bl.append((char)0); JSONParser jp; if (!jp.parse(extra_data_bl.c_str(), extra_data_bl.length())) { ldout(cct, 0) << "failed to parse response extra data. len=" << extra_data_bl.length() << " data=" << extra_data_bl.c_str() << dendl; @@ -2699,7 +2718,7 @@ set_err_state: return 0; } else if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */ - return copy_obj_data(ctx, handle, end, dest_obj, src_obj, mtime, src_attrs, category, ptag, err); + return copy_obj_data(ctx, &handle, end, dest_obj, src_obj, mtime, src_attrs, category, ptag, err); } map<uint64_t, RGWObjManifestPart>::iterator miter = astate->manifest.objs.begin(); @@ -2804,7 +2823,7 @@ done_ret: int RGWRados::copy_obj_data(void *ctx, - void *handle, off_t end, + void **handle, off_t end, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, @@ -2830,7 +2849,7 @@ int RGWRados::copy_obj_data(void *ctx, do { bufferlist bl; - ret = get_obj(ctx, NULL, &handle, src_obj, bl, ofs, end); + ret = get_obj(ctx, NULL, handle, src_obj, bl, ofs, end); if (ret < 0) return ret; @@ -2877,12 +2896,9 @@ int RGWRados::copy_obj_data(void *ctx, if (mtime) obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL, NULL); - finish_get_obj(&handle); - return ret; done_err: delete_obj(ctx, shadow_obj); - finish_get_obj(&handle); return r; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index a55f1c1f94c..65765c414aa 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1130,7 +1130,7 @@ public: void *progress_data); int copy_obj_data(void *ctx, - void *handle, off_t end, + void **handle, off_t end, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, |