diff options
author | Sage Weil <sage@inktank.com> | 2013-08-02 11:54:53 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-02 11:54:53 -0700 |
commit | 9797986697622217cb03b3420a70a49eddb6b02d (patch) | |
tree | b0e96a13827ff6bd825dbbc45546707cf408c28f | |
parent | ea1243a1122bd48c9f514b92f6c5d83391e814e5 (diff) | |
parent | ef036bd4bc0e79bff8a5805800fbdeb0cc2db6ae (diff) | |
download | ceph-9797986697622217cb03b3420a70a49eddb6b02d.tar.gz |
Merge remote-tracking branch 'gh/next'
32 files changed, 383 insertions, 255 deletions
diff --git a/ceph.spec.in b/ceph.spec.in index 696d9ad3332..1a22b12f5c4 100644 --- a/ceph.spec.in +++ b/ceph.spec.in @@ -42,6 +42,9 @@ BuildRequires: libcurl-devel BuildRequires: libxml2-devel BuildRequires: libuuid-devel BuildRequires: leveldb-devel > 1.2 +%if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora} +BuildRequires: snappy-devel +%endif ################################################################################# # specific @@ -235,6 +238,14 @@ License: LGPL-2.0 Requires: java Requires: libcephfs_jni1 = %{version}-%{release} BuildRequires: java-devel +%if 0%{?suse_version} > 1220 +Requires: junit4 +BuildRequires: junit4 +%else +Requires: junit +BuildRequires: junit +%endif +BuildRequires: junit %description -n cephfs-java This package contains the Java libraries for the Ceph File System. diff --git a/debian/changelog b/debian/changelog index 7b814f0da90..aaf202293d1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ceph (0.67-rc3-1) precise; urgency=low + + * New upstream release + + -- Gary Lowell <gary.lowell@inktank.com> Tue, 30 Jul 2013 14:37:40 -0700 + ceph (0.67-rc2-1) precise; urgency=low * New upstream release diff --git a/qa/workunits/cephtool/test_daemon.sh b/qa/workunits/cephtool/test_daemon.sh new file mode 100755 index 00000000000..8d2bd27f700 --- /dev/null +++ b/qa/workunits/cephtool/test_daemon.sh @@ -0,0 +1,27 @@ +#!/bin/bash -x + +set -e + +expect_false() +{ + set -x + if "$@"; then return 1; else return 0; fi +} + +echo note: assuming mon.a is on the currenet host + +sudo ceph daemon mon.a version | grep version + +# get debug_ms setting and strip it, painfully for reuse +old_ms=$(sudo ceph daemon mon.a config get debug_ms | grep debug_ms | \ + sed -e 's/.*: //' -e 's/["\}\\]//g') +sudo ceph daemon mon.a config set debug_ms 13 +new_ms=$(sudo ceph daemon mon.a config get debug_ms | grep debug_ms | \ + sed -e 's/.*: //' -e 's/["\}\\]//g') +[ "$new_ms" = "13/13" ] +sudo ceph daemon mon.a config set debug_ms $old_ms +new_ms=$(sudo ceph daemon mon.a config get debug_ms | grep debug_ms | \ + sed -e 's/.*: //' -e 's/["\}\\]//g') +[ "$new_ms" = "$old_ms" ] + +echo OK diff --git a/qa/workunits/rados/test_hang.sh b/qa/workunits/rados/test_hang.sh new file mode 100755 index 00000000000..724e0bb82a5 --- /dev/null +++ b/qa/workunits/rados/test_hang.sh @@ -0,0 +1,8 @@ +#!/bin/sh -ex + +# Hang forever for manual testing using the thrasher +while(true) +do + sleep 300 +done +exit 0 diff --git a/qa/workunits/rest/test.py b/qa/workunits/rest/test.py index f0cf1f2c761..3fcf3fd75fb 100755 --- a/qa/workunits/rest/test.py +++ b/qa/workunits/rest/test.py @@ -11,9 +11,6 @@ import xml.etree.ElementTree BASEURL = os.environ.get('BASEURL', 'http://localhost:5000/api/v0.1') -class MyException(Exception): - pass - def fail(r, msg): print >> sys.stderr, 'FAILURE: url ', r.url print >> sys.stderr, msg @@ -22,6 +19,14 @@ def fail(r, msg): sys.exit(1) def expect(url, method, respcode, contenttype, extra_hdrs=None, data=None): + failmsg, r = expect_nofail(url, method, respcode, contenttype, extra_hdrs, + data) + if failmsg: + fail(r, failmsg) + return r + +def expect_nofail(url, method, respcode, contenttype, extra_hdrs=None, + data=None): fdict = {'get':requests.get, 'put':requests.put} f = fdict[method.lower()] @@ -30,7 +35,8 @@ def expect(url, method, respcode, contenttype, extra_hdrs=None, data=None): print '{0}: {1} {2}'.format(url, contenttype, r.status_code) if r.status_code != respcode: - fail(r, 'expected {0}, got {1}'.format(respcode, r.status_code)) + return 'expected {0}, got {1}'.format(respcode, r.status_code), r + r_contenttype = r.headers['content-type'] if contenttype in ['json', 'xml']: @@ -39,7 +45,7 @@ def expect(url, method, respcode, contenttype, extra_hdrs=None, data=None): contenttype = 'text/' + contenttype if contenttype and r_contenttype != contenttype: - fail(r, 'expected {0}, got "{1}"'.format(contenttype, r_contenttype)) + return 'expected {0}, got "{1}"'.format(contenttype, r_contenttype), r if contenttype.startswith('application'): if r_contenttype == 'application/json': @@ -48,23 +54,22 @@ def expect(url, method, respcode, contenttype, extra_hdrs=None, data=None): r.myjson = json.loads(r.content) assert(r.myjson != None) except Exception as e: - fail(r, 'Invalid JSON returned: "{0}"'.format(str(e))) + return 'Invalid JSON returned: "{0}"'.format(str(e)), r if r_contenttype == 'application/xml': try: # if it's there, squirrel it away for use in the caller r.tree = xml.etree.ElementTree.fromstring(r.content) except Exception as e: - fail(r, 'Invalid XML returned: "{0}"'.format(str(e))) + return 'Invalid XML returned: "{0}"'.format(str(e)), r - return r + return '', r JSONHDR={'accept':'application/json'} XMLHDR={'accept':'application/xml'} if __name__ == '__main__': - expect('auth/export', 'GET', 200, 'plain') expect('auth/export.json', 'GET', 200, 'json') expect('auth/export.xml', 'GET', 200, 'xml') @@ -157,17 +162,29 @@ if __name__ == '__main__': # EEXIST from CLI expect('mds/deactivate?who=2', 'PUT', 400, '') - r = expect('mds/dump.json', 'GET', 200, 'json') - assert('created' in r.myjson['output']) - current_epoch = r.myjson['output']['epoch'] r = expect('mds/dump.xml', 'GET', 200, 'xml') assert(r.tree.find('output/mdsmap/created') is not None) - r = expect('mds/getmap', 'GET', 200, '') - assert(len(r.content) != 0) - expect('mds/setmap?epoch={0}'.format(current_epoch + 1), 'PUT', 200, - 'plain', {'Content-Type':'text/plain'}, - data=r.content) + failresps = [] + while len(failresps) < 10: + r = expect('mds/dump.json', 'GET', 200, 'json') + assert('created' in r.myjson['output']) + current_epoch = r.myjson['output']['epoch'] + + map = expect('mds/getmap', 'GET', 200, '') + assert(len(map.content) != 0) + msg, r = expect_nofail( + 'mds/setmap?epoch={0}'.format(current_epoch + 1), 'PUT', 200, + 'plain', {'Content-Type':'text/plain'}, data=map.content + ) + if msg: + failresps.append(msg + r.content) + else: + break + + if len(failresps) == 10: + fail(r, 'Could not mds setmap in 10 tries; responses:' + + '\n'.join(failresps)) expect('mds/newfs?metadata=0&data=1&sure=--yes-i-really-mean-it', 'PUT', 200, '') expect('osd/pool/create?pool=data2&pg_num=10', 'PUT', 200, '') diff --git a/src/ceph.in b/src/ceph.in index 22c54a48689..0ae8df77cd7 100755 --- a/src/ceph.in +++ b/src/ceph.in @@ -26,7 +26,7 @@ import sys MYPATH = os.path.abspath(__file__) MYDIR = os.path.dirname(MYPATH) -DEVMODEMSG = '*** DEVELOPER MODE: setting PYTHONPATH and LD_LIBRARY_PATH' +DEVMODEMSG = '*** DEVELOPER MODE: setting PATH, PYTHONPATH and LD_LIBRARY_PATH ***' if MYDIR.endswith('src') and \ os.path.exists(os.path.join(MYDIR, '.libs')) and \ @@ -35,6 +35,7 @@ if MYDIR.endswith('src') and \ if 'LD_LIBRARY_PATH' in os.environ: if MYLIBPATH not in os.environ['LD_LIBRARY_PATH']: os.environ['LD_LIBRARY_PATH'] += ':' + MYLIBPATH + os.environ['PATH'] += ':' + MYDIR print >> sys.stderr, DEVMODEMSG os.execvp('python', ['python'] + sys.argv) else: diff --git a/src/client/Client.cc b/src/client/Client.cc index 5a9c5fdafcc..af465cb78bc 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -102,7 +102,7 @@ Client::CommandHook::CommandHook(Client *client) : { } -bool Client::CommandHook::call(std::string command, std::string args, +bool Client::CommandHook::call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { stringstream ss; diff --git a/src/client/Client.h b/src/client/Client.h index bc1fbc0401b..1117ff3b0af 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -45,6 +45,7 @@ using namespace __gnu_cxx; #include "common/Finisher.h" #include "common/compiler_extensions.h" +#include "common/cmdparse.h" #include "osdc/ObjectCacher.h" @@ -196,7 +197,7 @@ class Client : public Dispatcher { Client *m_client; public: CommandHook(Client *client); - bool call(std::string command, std::string args, std::string format, + bool call(std::string command, cmdmap_t &cmdmap, std::string format, bufferlist& out); }; CommandHook m_command_hook; diff --git a/src/common/admin_socket.cc b/src/common/admin_socket.cc index e73f3ce0a0c..1a507e606bf 100644 --- a/src/common/admin_socket.cc +++ b/src/common/admin_socket.cc @@ -353,7 +353,7 @@ bool AdminSocket::do_accept() string args; if (match != c) args = c.substr(match.length() + 1); - bool success = p->second->call(match, args, format, out); + bool success = p->second->call(match, cmdmap, format, out); if (!success) { ldout(m_cct, 0) << "AdminSocket: request '" << match << "' args '" << args << "' to " << p->second << " failed" << dendl; @@ -417,7 +417,7 @@ int AdminSocket::unregister_command(std::string command) class VersionHook : public AdminSocketHook { public: - virtual bool call(std::string command, std::string args, std::string format, + virtual bool call(std::string command, cmdmap_t &cmdmap, std::string format, bufferlist& out) { if (command == "0") { out.append(CEPH_ADMIN_SOCK_VERSION); @@ -441,7 +441,7 @@ class HelpHook : public AdminSocketHook { AdminSocket *m_as; public: HelpHook(AdminSocket *as) : m_as(as) {} - bool call(string command, string args, string format, bufferlist& out) { + bool call(string command, cmdmap_t &cmdmap, string format, bufferlist& out) { Formatter *f = new_formatter(format); f->open_object_section("help"); for (map<string,string>::iterator p = m_as->m_help.begin(); @@ -463,7 +463,7 @@ class GetdescsHook : public AdminSocketHook { AdminSocket *m_as; public: GetdescsHook(AdminSocket *as) : m_as(as) {} - bool call(string command, string args, string format, bufferlist& out) { + bool call(string command, cmdmap_t &cmdmap, string format, bufferlist& out) { int cmdnum = 0; JSONFormatter jf(false); jf.open_object_section("command_descriptions"); diff --git a/src/common/admin_socket.h b/src/common/admin_socket.h index 30c5eb96ab8..3bc84834348 100644 --- a/src/common/admin_socket.h +++ b/src/common/admin_socket.h @@ -21,6 +21,7 @@ #include <string> #include <map> #include "include/buffer.h" +#include "common/cmdparse.h" class AdminSocket; class CephContext; @@ -29,7 +30,7 @@ class CephContext; class AdminSocketHook { public: - virtual bool call(std::string command, std::string args, std::string format, + virtual bool call(std::string command, cmdmap_t &cmdmap, std::string format, bufferlist& out) = 0; virtual ~AdminSocketHook() {}; }; diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc index 6b227d8689e..9602fdf2e40 100644 --- a/src/common/ceph_context.cc +++ b/src/common/ceph_context.cc @@ -156,18 +156,25 @@ class CephContextHook : public AdminSocketHook { public: CephContextHook(CephContext *cct) : m_cct(cct) {} - bool call(std::string command, std::string args, std::string format, + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { - m_cct->do_command(command, args, format, &out); + m_cct->do_command(command, cmdmap, format, &out); return true; } }; -void CephContext::do_command(std::string command, std::string args, +void CephContext::do_command(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist *out) { Formatter *f = new_formatter(format); - lgeneric_dout(this, 1) << "do_command '" << command << "' '" << args << "'" << dendl; + stringstream ss; + for (cmdmap_t::iterator it = cmdmap.begin(); it != cmdmap.end(); ++it) { + if (it->first != "prefix") { + ss << it->first << ":" << cmd_vartype_stringify(it->second) << " "; + } + } + lgeneric_dout(this, 1) << "do_command '" << command << "' '" + << ss.str() << dendl; if (command == "perfcounters_dump" || command == "1" || command == "perf dump") { _perf_counters_collection->dump_formatted(f, false); @@ -182,14 +189,17 @@ void CephContext::do_command(std::string command, std::string args, _conf->show_config(f); } else if (command == "config set") { - std::string var = args; - size_t pos = var.find(' '); - if (pos == string::npos) { + std::string var; + std::vector<std::string> val; + + if (!(cmd_getval(this, cmdmap, "var", var)) || + !(cmd_getval(this, cmdmap, "val", val))) { f->dump_string("error", "syntax error: 'config set <var> <value>'"); } else { - std::string val = var.substr(pos+1); - var.resize(pos); - int r = _conf->set_val(var.c_str(), val.c_str()); + // val may be multiple words + ostringstream argss; + std::copy(val.begin(), val.end(), ostream_iterator<string>(argss, " ")); + int r = _conf->set_val(var.c_str(), argss.str().c_str()); if (r < 0) { f->dump_stream("error") << "error setting '" << var << "' to '" << val << "': " << cpp_strerror(r); } else { @@ -199,15 +209,20 @@ void CephContext::do_command(std::string command, std::string args, } } } else if (command == "config get") { - char buf[4096]; - memset(buf, 0, sizeof(buf)); - char *tmp = buf; - int r = _conf->get_val(args.c_str(), &tmp, sizeof(buf)); - if (r < 0) { - f->dump_stream("error") << "error getting '" << args << "': " << cpp_strerror(r); - } else { - f->dump_string(args.c_str(), buf); - } + std::string var; + if (!cmd_getval(this, cmdmap, "var", var)) { + f->dump_string("error", "syntax error: 'config get <var>'"); + } else { + char buf[4096]; + memset(buf, 0, sizeof(buf)); + char *tmp = buf; + int r = _conf->get_val(var.c_str(), &tmp, sizeof(buf)); + if (r < 0) { + f->dump_stream("error") << "error getting '" << var << "': " << cpp_strerror(r); + } else { + f->dump_string(var.c_str(), buf); + } + } } else if (command == "log flush") { _log->flush(); } @@ -224,7 +239,8 @@ void CephContext::do_command(std::string command, std::string args, } f->flush(*out); delete f; - lgeneric_dout(this, 1) << "do_command '" << command << "' '" << args << "' result is " << out->length() << " bytes" << dendl; + lgeneric_dout(this, 1) << "do_command '" << command << "' '" << ss.str() + << "result is " << out->length() << " bytes" << dendl; }; @@ -262,7 +278,7 @@ CephContext::CephContext(uint32_t module_type_) _admin_socket->register_command("2", "2", _admin_hook, ""); _admin_socket->register_command("perf schema", "perf schema", _admin_hook, "dump perfcounters schema"); _admin_socket->register_command("config show", "config show", _admin_hook, "dump current config settings"); - _admin_socket->register_command("config set", "config set name=var,type=CephString name=val,type=CephString", _admin_hook, "config set <field> <val>: set a config variable"); + _admin_socket->register_command("config set", "config set name=var,type=CephString name=val,type=CephString,n=N", _admin_hook, "config set <field> <val> [<val> ...]: set a config variable"); _admin_socket->register_command("config get", "config get name=var,type=CephString", _admin_hook, "config get <field>: get the config value"); _admin_socket->register_command("log flush", "log flush", _admin_hook, "flush log entries to log file"); _admin_socket->register_command("log dump", "log dump", _admin_hook, "dump recent log entries to log file"); diff --git a/src/common/ceph_context.h b/src/common/ceph_context.h index 85618e35219..08efeceaa67 100644 --- a/src/common/ceph_context.h +++ b/src/common/ceph_context.h @@ -20,6 +20,7 @@ #include "include/buffer.h" #include "include/atomic.h" +#include "common/cmdparse.h" class AdminSocket; class CephContextServiceThread; @@ -97,7 +98,7 @@ public: /** * process an admin socket command */ - void do_command(std::string command, std::string args, std::string foramt, + void do_command(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist *out); /** diff --git a/src/common/cmdparse.h b/src/common/cmdparse.h index f258969fb68..58c66b46052 100644 --- a/src/common/cmdparse.h +++ b/src/common/cmdparse.h @@ -11,7 +11,8 @@ #include <stdexcept> #include "common/Formatter.h" #include "common/BackTrace.h" -#include "common/ceph_context.h" + +class CephContext; /* this is handy; can't believe it's not standard */ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index f0fb4ae8332..d89cc412912 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -960,9 +960,9 @@ bool MDSMonitor::prepare_command(MMonCommand *m) wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs, get_last_committed())); return true; } - } - if (r == -EINVAL) + } else { ss << "unrecognized command"; + } out: string rs; getline(ss, rs); diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 2c21e6eac69..118cf6f4a1e 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -225,16 +225,16 @@ class AdminHook : public AdminSocketHook { Monitor *mon; public: AdminHook(Monitor *m) : mon(m) {} - bool call(std::string command, std::string args, std::string format, + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { stringstream ss; - mon->do_admin_command(command, args, format, ss); + mon->do_admin_command(command, cmdmap, format, ss); out.append(ss); return true; } }; -void Monitor::do_admin_command(string command, string args, string format, +void Monitor::do_admin_command(string command, cmdmap_t& cmdmap, string format, ostream& ss) { Mutex::Locker l(lock); @@ -246,7 +246,9 @@ void Monitor::do_admin_command(string command, string args, string format, else if (command == "quorum_status") _quorum_status(f.get(), ss); else if (command == "sync_force") { - if (args != "--yes-i-really-mean-it") { + string validate; + if ((!cmd_getval(g_ceph_context, cmdmap, "validate", validate)) || + (validate != "--yes-i-really-mean-it")) { ss << "are you SURE? this will mean the monitor store will be erased " "the next time the monitor is restarted. pass " "'--yes-i-really-mean-it' if you really do."; @@ -254,7 +256,7 @@ void Monitor::do_admin_command(string command, string args, string format, } sync_force(f.get(), ss); } else if (command.find("add_bootstrap_peer_hint") == 0) - _add_bootstrap_peer_hint(command, args, ss); + _add_bootstrap_peer_hint(command, cmdmap, ss); else assert(0 == "bad AdminSocket command binding"); } @@ -485,10 +487,19 @@ int Monitor::preinit() r = admin_socket->register_command("quorum_status", "quorum_status", admin_hook, "show current quorum status"); assert(r == 0); + r = admin_socket->register_command("sync_force", + "sync_force name=validate," + "type=CephChoices," + "strings=--yes-i-really-mean-it", + admin_hook, + "force sync of and clear monitor store"); + assert(r == 0); r = admin_socket->register_command("add_bootstrap_peer_hint", - "add_bootstrap_peer_hint name=addr,type=CephIPAddr", + "add_bootstrap_peer_hint name=addr," + "type=CephIPAddr", admin_hook, - "add peer address as potential bootstrap peer for cluster bringup"); + "add peer address as potential bootstrap" + " peer for cluster bringup"); assert(r == 0); lock.Lock(); @@ -577,6 +588,7 @@ void Monitor::shutdown() AdminSocket* admin_socket = cct->get_admin_socket(); admin_socket->unregister_command("mon_status"); admin_socket->unregister_command("quorum_status"); + admin_socket->unregister_command("sync_force"); admin_socket->unregister_command("add_bootstrap_peer_hint"); delete admin_hook; admin_hook = NULL; @@ -684,14 +696,17 @@ void Monitor::bootstrap() } } -void Monitor::_add_bootstrap_peer_hint(string cmd, string args, ostream& ss) +void Monitor::_add_bootstrap_peer_hint(string cmd, cmdmap_t& cmdmap, ostream& ss) { - dout(10) << "_add_bootstrap_peer_hint '" << cmd << "' '" << args << "'" << dendl; + string addrstr; + cmd_getval(g_ceph_context, cmdmap, "addr", addrstr); + dout(10) << "_add_bootstrap_peer_hint '" << cmd << "' '" + << addrstr << "'" << dendl; entity_addr_t addr; const char *end = 0; - if (!addr.parse(args.c_str(), &end)) { - ss << "failed to parse addr '" << args << "'; syntax is 'add_bootstrap_peer_hint ip[:port]'"; + if (!addr.parse(addrstr.c_str(), &end)) { + ss << "failed to parse addr '" << addrstr << "'; syntax is 'add_bootstrap_peer_hint ip[:port]'"; return; } diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 69dfefe144a..cb1f4138a25 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -586,7 +586,7 @@ public: bool _allowed_command(MonSession *s, map<std::string, cmd_vartype>& cmd); void _mon_status(Formatter *f, ostream& ss); void _quorum_status(Formatter *f, ostream& ss); - void _add_bootstrap_peer_hint(string cmd, string args, ostream& ss); + void _add_bootstrap_peer_hint(string cmd, cmdmap_t& cmdmap, ostream& ss); void handle_command(class MMonCommand *m); void handle_route(MRoute *m); @@ -750,7 +750,7 @@ public: int write_fsid(); int write_fsid(MonitorDBStore::Transaction &t); - void do_admin_command(std::string command, std::string args, + void do_admin_command(std::string command, cmdmap_t& cmdmap, std::string format, ostream& ss); private: diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 89aa1db34eb..69c181862cc 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -997,16 +997,17 @@ class OSDSocketHook : public AdminSocketHook { OSD *osd; public: OSDSocketHook(OSD *o) : osd(o) {} - bool call(std::string command, std::string args, std::string format, + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { stringstream ss; - bool r = osd->asok_command(command, args, format, ss); + bool r = osd->asok_command(command, cmdmap, format, ss); out.append(ss); return r; } }; -bool OSD::asok_command(string command, string args, string format, ostream& ss) +bool OSD::asok_command(string command, cmdmap_t& cmdmap, string format, + ostream& ss) { if (format == "") format = "json-pretty"; @@ -1089,15 +1090,15 @@ class TestOpsSocketHook : public AdminSocketHook { ObjectStore *store; public: TestOpsSocketHook(OSDService *s, ObjectStore *st) : service(s), store(st) {} - bool call(std::string command, std::string args, std::string format, + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { stringstream ss; - test_ops(service, store, command, args, ss); + test_ops(service, store, command, cmdmap, ss); out.append(ss); return true; } void test_ops(OSDService *service, ObjectStore *store, std::string command, - std::string args, ostream &ss); + cmdmap_t& cmdmap, ostream &ss); }; @@ -1249,10 +1250,12 @@ int OSD::init() assert(r == 0); test_ops_hook = new TestOpsSocketHook(&(this->service), this->store); + // Note: pools are CephString instead of CephPoolname because + // these commands traditionally support both pool names and numbers r = admin_socket->register_command( "setomapval", "setomapval " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname " \ "name=key,type=CephString "\ "name=val,type=CephString", @@ -1262,7 +1265,7 @@ int OSD::init() r = admin_socket->register_command( "rmomapkey", "rmomapkey " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname " \ "name=key,type=CephString", test_ops_hook, @@ -1271,7 +1274,7 @@ int OSD::init() r = admin_socket->register_command( "setomapheader", "setomapheader " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname " \ "name=header,type=CephString", test_ops_hook, @@ -1281,7 +1284,7 @@ int OSD::init() r = admin_socket->register_command( "getomap", "getomap " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname", test_ops_hook, "output entire object map"); @@ -1290,7 +1293,7 @@ int OSD::init() r = admin_socket->register_command( "truncobj", "truncobj " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname " \ "name=len,type=CephInt", test_ops_hook, @@ -1300,7 +1303,7 @@ int OSD::init() r = admin_socket->register_command( "injectdataerr", "injectdataerr " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname", test_ops_hook, "inject data error into omap"); @@ -1309,7 +1312,7 @@ int OSD::init() r = admin_socket->register_command( "injectmdataerr", "injectmdataerr " \ - "name=pool,type=CephPoolname " \ + "name=pool,type=CephString " \ "name=objname,type=CephObjectname", test_ops_hook, "inject metadata error"); @@ -3111,7 +3114,7 @@ void OSD::check_ops_in_flight() // injectmdataerr [namespace/]<obj-name> // injectdataerr [namespace/]<obj-name> void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, - std::string command, std::string args, ostream &ss) + std::string command, cmdmap_t& cmdmap, ostream &ss) { //Test support //Support changing the omap on a single osd by using the Admin Socket to @@ -3121,40 +3124,36 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, command == "truncobj" || command == "injectmdataerr" || command == "injectdataerr" ) { - std::vector<std::string> argv; pg_t rawpg, pgid; int64_t pool; OSDMapRef curmap = service->get_osdmap(); int r; - argv.push_back(command); - string_to_vec(argv, args); - int argc = argv.size(); + string poolstr; - if (argc < 3) { - ss << "Illegal request"; + cmd_getval(g_ceph_context, cmdmap, "pool", poolstr); + pool = curmap->const_lookup_pg_pool_name(poolstr.c_str()); + //If we can't find it by name then maybe id specified + if (pool < 0 && isdigit(poolstr[0])) + pool = atoll(poolstr.c_str()); + if (pool < 0) { + ss << "Invalid pool" << poolstr; return; } - - pool = curmap->const_lookup_pg_pool_name(argv[1].c_str()); - //If we can't find it my name then maybe id specified - if (pool < 0 && isdigit(argv[1].c_str()[0])) - pool = atoll(argv[1].c_str()); r = -1; string objname, nspace; - objname = string(argv[2]); - if (pool >= 0) { - std::size_t found = argv[2].find_first_of('/'); - if (found != string::npos) { - nspace = argv[2].substr(0, found); - objname = argv[2].substr(found+1); - } - object_locator_t oloc(pool, nspace); - r = curmap->object_locator_to_pg(object_t(objname), oloc, rawpg); + cmd_getval(g_ceph_context, cmdmap, "objname", objname); + std::size_t found = objname.find_first_of('/'); + if (found != string::npos) { + nspace = objname.substr(0, found); + objname = objname.substr(found+1); } + object_locator_t oloc(pool, nspace); + r = curmap->object_locator_to_pg(object_t(objname), oloc, rawpg); + if (r < 0) { - ss << "Invalid pool " << argv[1]; - return; + ss << "Invalid namespace/objname"; + return; } pgid = curmap->raw_pg_to_pg(rawpg); @@ -3162,15 +3161,13 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, ObjectStore::Transaction t; if (command == "setomapval") { - if (argc != 5) { - ss << "usage: setomapval <pool> [namespace/]<obj-name> <key> <val>"; - return; - } map<string, bufferlist> newattrs; bufferlist val; - string key(argv[3]); - - val.append(argv[4]); + string key, valstr; + cmd_getval(g_ceph_context, cmdmap, "key", key); + cmd_getval(g_ceph_context, cmdmap, "val", valstr); + + val.append(valstr); newattrs[key] = val; t.omap_setkeys(coll_t(pgid), obj, newattrs); r = store->apply_transaction(t); @@ -3179,13 +3176,11 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, else ss << "ok"; } else if (command == "rmomapkey") { - if (argc != 4) { - ss << "usage: rmomapkey <pool> [namespace/]<obj-name> <key>"; - return; - } + string key; set<string> keys; + cmd_getval(g_ceph_context, cmdmap, "key", key); - keys.insert(string(argv[3])); + keys.insert(key); t.omap_rmkeys(coll_t(pgid), obj, keys); r = store->apply_transaction(t); if (r < 0) @@ -3193,13 +3188,11 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, else ss << "ok"; } else if (command == "setomapheader") { - if (argc != 4) { - ss << "usage: setomapheader <pool> [namespace/]<obj-name> <header>"; - return; - } bufferlist newheader; + string headerstr; - newheader.append(argv[3]); + cmd_getval(g_ceph_context, cmdmap, "header", headerstr); + newheader.append(headerstr); t.omap_setheader(coll_t(pgid), obj, newheader); r = store->apply_transaction(t); if (r < 0) @@ -3207,10 +3200,6 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, else ss << "ok"; } else if (command == "getomap") { - if (argc != 3) { - ss << "usage: getomap <pool> [namespace/]<obj-name>"; - return; - } //Debug: Output entire omap bufferlist hdrbl; map<string, bufferlist> keyvals; @@ -3225,11 +3214,9 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, ss << "error=" << r; } } else if (command == "truncobj") { - if (argc != 4) { - ss << "usage: truncobj <pool> [namespace/]<obj-name> <val>"; - return; - } - t.truncate(coll_t(pgid), obj, atoi(argv[3].c_str())); + int64_t trunclen; + cmd_getval(g_ceph_context, cmdmap, "len", trunclen); + t.truncate(coll_t(pgid), obj, trunclen); r = store->apply_transaction(t); if (r < 0) ss << "error=" << r; diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 478f766d145..5196a1dc1f3 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -622,7 +622,7 @@ protected: // asok friend class OSDSocketHook; class OSDSocketHook *asok_hook; - bool asok_command(string command, string args, string format, ostream& ss); + bool asok_command(string command, cmdmap_t& cmdmap, string format, ostream& ss); public: ClassHandler *class_handler; diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 70d296a3ab3..fc54daa3f27 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -295,6 +295,7 @@ void Objecter::send_linger(LingerOp *info) // repeat send. cancel old registeration op, if any. if (ops.count(info->register_tid)) { Op *o = ops[info->register_tid]; + op_cancel_map_check(o); cancel_op(o); } info->register_tid = _op_submit(o); @@ -746,6 +747,7 @@ void Objecter::check_op_pool_dne(Op *op) void Objecter::_send_op_map_check(Op *op) { + assert(client_lock.is_locked()); // ask the monitor if (check_latest_map_ops.count(op->tid) == 0) { check_latest_map_ops[op->tid] = op; @@ -756,6 +758,7 @@ void Objecter::_send_op_map_check(Op *op) void Objecter::op_cancel_map_check(Op *op) { + assert(client_lock.is_locked()); map<tid_t, Op*>::iterator iter = check_latest_map_ops.find(op->tid); if (iter != check_latest_map_ops.end()) { @@ -1098,6 +1101,7 @@ void Objecter::tick() void Objecter::resend_mon_ops() { + assert(client_lock.is_locked()); ldout(cct, 10) << "resend_mon_ops" << dendl; for (map<tid_t,PoolStatOp*>::iterator p = poolstat_ops.begin(); p!=poolstat_ops.end(); ++p) { @@ -1397,6 +1401,7 @@ void Objecter::finish_op(Op *op) ops.erase(op->tid); logger->set(l_osdc_op_active, ops.size()); + assert(check_latest_map_ops.find(op->tid) == check_latest_map_ops.end()); delete op; } @@ -2321,7 +2326,7 @@ Objecter::RequestStateHook::RequestStateHook(Objecter *objecter) : { } -bool Objecter::RequestStateHook::call(std::string command, std::string args, +bool Objecter::RequestStateHook::call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out) { stringstream ss; diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index da5487f3a84..a321c409c9b 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -726,7 +726,7 @@ class Objecter { Objecter *m_objecter; public: RequestStateHook(Objecter *objecter); - bool call(std::string command, std::string args, std::string format, + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& out); }; diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index e938b031bc7..1e523f332cf 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -1417,7 +1417,8 @@ public: return ret; // are we actually going to perform this put, or is it too old? - if (!check_versions(old_ot.read_version, orig_mtime, + if (ret != -ENOENT && + !check_versions(old_ot.read_version, orig_mtime, objv_tracker.write_version, mtime, sync_type)) { return STATUS_NO_APPLY; } @@ -1560,10 +1561,12 @@ public: time_t orig_mtime; int ret = store->get_bucket_instance_info(NULL, oid, old_bci.info, &orig_mtime, &old_bci.attrs); - if (ret < 0 && ret != -ENOENT) + bool exists = (ret != -ENOENT); + if (ret < 0 && exists) return ret; - if (ret == -ENOENT || old_bci.info.bucket.bucket_id != bci.info.bucket.bucket_id) { + + if (!exists || old_bci.info.bucket.bucket_id != bci.info.bucket.bucket_id) { /* a new bucket, we need to select a new bucket placement for it */ rgw_bucket bucket; ret = store->set_bucket_location_by_rule(bci.info.placement_rule, oid, bucket); @@ -1580,7 +1583,8 @@ public: } // are we actually going to perform this put, or is it too old? - if (!check_versions(old_bci.info.objv_tracker.read_version, orig_mtime, + if (exists && + !check_versions(old_bci.info.objv_tracker.read_version, orig_mtime, objv_tracker.write_version, mtime, sync_type)) { objv_tracker.read_version = old_bci.info.objv_tracker.read_version; return STATUS_NO_APPLY; diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index ec62d670cea..6c383d822c1 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -352,9 +352,6 @@ void RGWProcess::handle_request(RGWRequest *req) goto done; } - req->log(s, "reading the cors attr"); - handler->read_cors_config(); - req->log(s, "verifying op mask"); ret = op->verify_op_mask(); if (ret < 0) { diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index e672de154ab..d34e18bc4ba 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -297,6 +297,7 @@ static int read_policy(RGWRados *store, struct req_state *s, ret = -EACCES; else ret = -ENOENT; + } else if (ret == -ENOENT) { ret = -ERR_NO_SUCH_BUCKET; } @@ -946,7 +947,7 @@ void RGWCreateBucket::execute() { RGWAccessControlPolicy old_policy(s->cct); map<string, bufferlist> attrs; - bufferlist aclbl, corsbl; + bufferlist aclbl; bool existed; int r; rgw_obj obj(store->zone.domain_root, s->bucket_name_str); @@ -1834,6 +1835,37 @@ void RGWPutACLs::execute() } } +static int read_bucket_cors(RGWRados *store, struct req_state *s, RGWCORSConfiguration *bucket_cors, bool *exist) +{ + bufferlist bl; + + map<string, bufferlist>::iterator aiter = s->bucket_attrs.find(RGW_ATTR_CORS); + if (aiter == s->bucket_attrs.end()) { + ldout(s->cct, 20) << "no CORS configuration attr found" << dendl; + *exist = false; + return 0; /* no CORS configuration found */ + } + + *exist = true; + + bl = aiter->second; + + bufferlist::iterator iter = bl.begin(); + try { + bucket_cors->decode(iter); + } catch (buffer::error& err) { + ldout(s->cct, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl; + return -EIO; + } + if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) { + RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(bucket_cors); + ldout(s->cct, 15) << "Read RGWCORSConfiguration"; + s3cors->to_xml(*_dout); + *_dout << dendl; + } + return 0; +} + int RGWGetCORS::verify_permission() { if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0) @@ -1844,15 +1876,17 @@ int RGWGetCORS::verify_permission() void RGWGetCORS::execute() { - stringstream ss; - if (!s->bucket_cors) { + bool cors_exist; + + ret = read_bucket_cors(store, s, &bucket_cors, &cors_exist); + if (ret < 0) + return ; + + if (!cors_exist) { dout(2) << "No CORS configuration set yet for this bucket" << dendl; ret = -ENOENT; return; } - RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(s->bucket_cors); - s3cors->to_xml(ss); - cors = ss.str(); } int RGWPutCORS::verify_permission() @@ -1865,45 +1899,17 @@ int RGWPutCORS::verify_permission() void RGWPutCORS::execute() { - bufferlist bl; - - RGWCORSConfiguration_S3 *cors_config; - RGWCORSXMLParser_S3 parser(s->cct); rgw_obj obj; - ret = 0; - - if (!parser.init()) { - ret = -EINVAL; - return; - } ret = get_params(); if (ret < 0) return; - ldout(s->cct, 15) << "read len=" << len << " data=" << (data ? data : "") << dendl; - if (!parser.parse(data, len, 1)) { - ret = -EINVAL; - return; - } - cors_config = static_cast<RGWCORSConfiguration_S3 *>(parser.find_first("CORSConfiguration")); - if (!cors_config) { - ret = -EINVAL; - return; - } - - if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) { - ldout(s->cct, 15) << "CORSConfiguration"; - cors_config->to_xml(*_dout); - *_dout << dendl; - } - RGWObjVersionTracker *ptracker = (s->object ? NULL : &s->bucket_info.objv_tracker); - cors_config->encode(bl); store->get_bucket_instance_obj(s->bucket, obj); store->set_atomic(s->obj_ctx, obj); - ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_CORS, bl, ptracker); + ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_CORS, cors_bl, ptracker); } int RGWDeleteCORS::verify_permission() @@ -1916,9 +1922,15 @@ int RGWDeleteCORS::verify_permission() void RGWDeleteCORS::execute() { + bool cors_exist; + RGWCORSConfiguration bucket_cors; + ret = read_bucket_cors(store, s, &bucket_cors, &cors_exist); + if (ret < 0) + return; + bufferlist bl; rgw_obj obj; - if (!s->bucket_cors) { + if (!cors_exist) { dout(2) << "No CORS configuration set yet for this bucket" << dendl; ret = -ENOENT; return; @@ -2510,40 +2522,6 @@ int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket) return ret; } -int RGWHandler::read_cors_config(void) -{ - int ret = 0; - bufferlist bl; - - dout(10) << "Going to read cors from attrs" << dendl; - rgw_obj obj; - store->get_bucket_instance_obj(s->bucket, obj); - if (obj.bucket.name.size()) { - ret = store->get_attr(s->obj_ctx, obj, RGW_ATTR_CORS, bl); - if (ret >= 0) { - bufferlist::iterator iter = bl.begin(); - s->bucket_cors = new RGWCORSConfiguration(); - try { - s->bucket_cors->decode(iter); - } catch (buffer::error& err) { - ldout(s->cct, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl; - return -EIO; - } - if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) { - RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(s->bucket_cors); - ldout(s->cct, 15) << "Read RGWCORSConfiguration"; - s3cors->to_xml(*_dout); - *_dout << dendl; - } - } else { - /*Not a serious error*/ - dout(2) << "Warning: There is no content for CORS xattr," - " cors may not be set yet" << dendl; - } - } - return ret; -} - RGWOp *RGWHandler::get_op(RGWRados *store) { diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 5da2e4f472c..d158f831cc7 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -526,7 +526,7 @@ public: class RGWGetCORS : public RGWOp { protected: int ret; - string cors; + RGWCORSConfiguration bucket_cors; public: RGWGetCORS() : ret(0) {} @@ -542,18 +542,13 @@ public: class RGWPutCORS : public RGWOp { protected: int ret; - size_t len; - char *data; + bufferlist cors_bl; public: RGWPutCORS() { ret = 0; - len = 0; - data = NULL; - } - virtual ~RGWPutCORS() { - free(data); } + virtual ~RGWPutCORS() { } int verify_permission(); void execute(); @@ -849,7 +844,6 @@ protected: virtual RGWOp *op_options() { return NULL; } public: RGWHandler() : store(NULL), s(NULL) {} - int read_cors_config(); virtual ~RGWHandler(); virtual int init(RGWRados *store, struct req_state *_s, RGWClientIO *cio); diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index e4933a67a39..a0870708c44 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -745,30 +745,6 @@ int RGWPutACLs_ObjStore::get_params() return ret; } -int RGWPutCORS_ObjStore::get_params() -{ - size_t cl = 0; - if (s->length) - cl = atoll(s->length); - if (cl) { - data = (char *)malloc(cl + 1); - if (!data) { - ret = -ENOMEM; - return ret; - } - int read_len; - int r = s->cio->read(data, cl, &read_len); - len = read_len; - if (r < 0) - return r; - data[len] = '\0'; - } else { - len = 0; - } - - return ret; -} - static int read_all_chunked_input(req_state *s, char **pdata, int *plen, int max_read) { #define READ_CHUNK 4096 diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 0b7204fe9cb..ded5b88366a 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -162,8 +162,6 @@ class RGWPutCORS_ObjStore : public RGWPutCORS { public: RGWPutCORS_ObjStore() {} ~RGWPutCORS_ObjStore() {} - - int get_params(); }; class RGWDeleteCORS_ObjStore : public RGWDeleteCORS { diff --git a/src/rgw/rgw_rest_metadata.cc b/src/rgw/rgw_rest_metadata.cc index 0705a46ed6c..de33df17446 100644 --- a/src/rgw/rgw_rest_metadata.cc +++ b/src/rgw/rgw_rest_metadata.cc @@ -164,7 +164,7 @@ void RGWOp_Metadata_Put::execute() { RGWMetadataHandler::sync_type_t sync_type = RGWMetadataHandler::APPLY_ALWAYS; bool mode_exists = false; - string mode_string = s->info.args.get("sync-type", &mode_exists); + string mode_string = s->info.args.get("update-type", &mode_exists); if (mode_exists) { bool parsed = RGWMetadataHandler::string_to_sync_type(mode_string, sync_type); diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 6c1738218e6..bbf363804bd 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -13,6 +13,7 @@ #include "rgw_policy_s3.h" #include "rgw_user.h" #include "rgw_cors.h" +#include "rgw_cors_s3.h" #include "rgw_client_io.h" @@ -1391,10 +1392,73 @@ void RGWGetCORS_ObjStore_S3::send_response() end_header(s, "application/xml"); dump_start(s); if (!ret) { + string cors; + RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(&bucket_cors); + stringstream ss; + + s3cors->to_xml(ss); + cors = ss.str(); s->cio->write(cors.c_str(), cors.size()); } } +int RGWPutCORS_ObjStore_S3::get_params() +{ + int r; + char *data = NULL; + int len = 0; + size_t cl = 0; + RGWCORSXMLParser_S3 parser(s->cct); + RGWCORSConfiguration_S3 *cors_config; + + if (s->length) + cl = atoll(s->length); + if (cl) { + data = (char *)malloc(cl + 1); + if (!data) { + r = -ENOMEM; + goto done_err; + } + int read_len; + r = s->cio->read(data, cl, &read_len); + len = read_len; + if (r < 0) + goto done_err; + data[len] = '\0'; + } else { + len = 0; + } + + if (!parser.init()) { + r = -EINVAL; + goto done_err; + } + + if (!parser.parse(data, len, 1)) { + r = -EINVAL; + goto done_err; + } + cors_config = static_cast<RGWCORSConfiguration_S3 *>(parser.find_first("CORSConfiguration")); + if (!cors_config) { + r = -EINVAL; + goto done_err; + } + + if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) { + ldout(s->cct, 15) << "CORSConfiguration"; + cors_config->to_xml(*_dout); + *_dout << dendl; + } + + cors_config->encode(cors_bl); + + free(data); + return 0; +done_err: + free(data); + return r; +} + void RGWPutCORS_ObjStore_S3::send_response() { if (ret) diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index a0af4eac9fd..b0d3c30384a 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -184,6 +184,7 @@ public: RGWPutCORS_ObjStore_S3() {} ~RGWPutCORS_ObjStore_S3() {} + int get_params(); void send_response(); }; diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 6fcecd4a98d..5e5b5c564bb 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -2308,7 +2308,8 @@ public: return ret; // are we actually going to perform this put, or is it too old? - if (!check_versions(objv_tracker.read_version, orig_mtime, + if (ret != -ENOENT && + !check_versions(objv_tracker.read_version, orig_mtime, objv_tracker.write_version, mtime, sync_mode)) { return STATUS_NO_APPLY; } diff --git a/src/test/admin_socket.cc b/src/test/admin_socket.cc index 8f67918e644..6f2a215b565 100644 --- a/src/test/admin_socket.cc +++ b/src/test/admin_socket.cc @@ -70,10 +70,19 @@ TEST(AdminSocket, SendNoOp) { } class MyTest : public AdminSocketHook { - bool call(std::string command, std::string args, std::string format, bufferlist& result) { + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& result) { + std::vector<std::string> args; + cmd_getval(g_ceph_context, cmdmap, "args", args); result.append(command); result.append("|"); - result.append(args); + string resultstr; + for (std::vector<std::string>::iterator it = args.begin(); + it != args.end(); ++it) { + if (it != args.begin()) + resultstr += ' '; + resultstr += *it; + } + result.append(resultstr); return true; } }; @@ -93,10 +102,19 @@ TEST(AdminSocket, RegisterCommand) { } class MyTest2 : public AdminSocketHook { - bool call(std::string command, std::string args, std::string format, bufferlist& result) { + bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& result) { + std::vector<std::string> args; + cmd_getval(g_ceph_context, cmdmap, "args", args); result.append(command); result.append("|"); - result.append(args); + string resultstr; + for (std::vector<std::string>::iterator it = args.begin(); + it != args.end(); ++it) { + if (it != args.begin()) + resultstr += ' '; + resultstr += *it; + } + result.append(resultstr); return true; } }; @@ -108,23 +126,23 @@ TEST(AdminSocket, RegisterCommandPrefixes) { ASSERT_EQ(true, asoct.shutdown()); ASSERT_EQ(true, asoct.init(get_rand_socket_path())); AdminSocketClient client(get_rand_socket_path()); - ASSERT_EQ(0, asoct.m_asokc->register_command("test", "test", new MyTest(), "")); - ASSERT_EQ(0, asoct.m_asokc->register_command("test command", "test command", new MyTest2(), "")); + ASSERT_EQ(0, asoct.m_asokc->register_command("test", "test name=args,type=CephString,n=N", new MyTest(), "")); + ASSERT_EQ(0, asoct.m_asokc->register_command("test command", "test command name=args,type=CephString,n=N", new MyTest2(), "")); string result; ASSERT_EQ("", client.do_request("{\"prefix\":\"test\"}", &result)); ASSERT_EQ("test|", result); ASSERT_EQ("", client.do_request("{\"prefix\":\"test command\"}", &result)); ASSERT_EQ("test command|", result); - ASSERT_EQ("", client.do_request("{\"prefix\":\"test command post\"}", &result)); + ASSERT_EQ("", client.do_request("{\"prefix\":\"test command\",\"args\":[\"post\"]}", &result)); ASSERT_EQ("test command|post", result); - ASSERT_EQ("", client.do_request("{\"prefix\":\"test command post\"}", &result)); + ASSERT_EQ("", client.do_request("{\"prefix\":\"test command\",\"args\":[\" post\"]}", &result)); ASSERT_EQ("test command| post", result); - ASSERT_EQ("", client.do_request("{\"prefix\":\"test this thing\"}", &result)); + ASSERT_EQ("", client.do_request("{\"prefix\":\"test\",\"args\":[\"this thing\"]}", &result)); ASSERT_EQ("test|this thing", result); - ASSERT_EQ("", client.do_request("{\"prefix\":\"test command post\"}", &result)); + ASSERT_EQ("", client.do_request("{\"prefix\":\"test\",\"args\":[\" command post\"]}", &result)); ASSERT_EQ("test| command post", result); - ASSERT_EQ("", client.do_request("{\"prefix\":\"test this thing\"}", &result)); + ASSERT_EQ("", client.do_request("{\"prefix\":\"test\",\"args\":[\" this thing\"]}", &result)); ASSERT_EQ("test| this thing", result); ASSERT_EQ(true, asoct.shutdown()); } diff --git a/src/test/system/systest_runnable.cc b/src/test/system/systest_runnable.cc index c0bc977618f..ec9b823db14 100644 --- a/src/test/system/systest_runnable.cc +++ b/src/test/system/systest_runnable.cc @@ -229,9 +229,9 @@ set_argv(int argc, const char **argv) if (m_argv_orig != NULL) { for (int i = 0; i < m_argc; ++i) free((void*)(m_argv_orig[i])); - delete m_argv_orig; + delete[] m_argv_orig; m_argv_orig = NULL; - delete m_argv; + delete[] m_argv; m_argv = NULL; m_argc = 0; } |