summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-09-23 09:50:10 -0700
committerSage Weil <sage@inktank.com>2013-09-23 09:50:10 -0700
commit10363daddb5101a21f77fc67dfe502700ecf0737 (patch)
tree678347f06a3520dab7585c2fafb25de2c7e8c714
parent991139bc0de1147171a08c21cfffd0dc57cd2b81 (diff)
parent3c64784e3fcbd0530acf14c7e3b37cae4cd54a91 (diff)
downloadceph-10363daddb5101a21f77fc67dfe502700ecf0737.tar.gz
Merge remote-tracking branch 'gh/next'
-rwxr-xr-xqa/workunits/cephtool/test.sh7
-rw-r--r--src/common/buffer.cc9
-rw-r--r--src/common/lru_map.h48
-rw-r--r--src/mds/MDS.cc4
-rw-r--r--src/osd/OSD.cc4
-rw-r--r--src/perfglue/heap_profiler.cc10
-rw-r--r--src/rgw/rgw_rados.cc30
-rw-r--r--src/rgw/rgw_rados.h2
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,