summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-02 11:54:53 -0700
committerSage Weil <sage@inktank.com>2013-08-02 11:54:53 -0700
commit9797986697622217cb03b3420a70a49eddb6b02d (patch)
treeb0e96a13827ff6bd825dbbc45546707cf408c28f
parentea1243a1122bd48c9f514b92f6c5d83391e814e5 (diff)
parentef036bd4bc0e79bff8a5805800fbdeb0cc2db6ae (diff)
downloadceph-9797986697622217cb03b3420a70a49eddb6b02d.tar.gz
Merge remote-tracking branch 'gh/next'
-rw-r--r--ceph.spec.in11
-rw-r--r--debian/changelog6
-rwxr-xr-xqa/workunits/cephtool/test_daemon.sh27
-rwxr-xr-xqa/workunits/rados/test_hang.sh8
-rwxr-xr-xqa/workunits/rest/test.py51
-rwxr-xr-xsrc/ceph.in3
-rw-r--r--src/client/Client.cc2
-rw-r--r--src/client/Client.h3
-rw-r--r--src/common/admin_socket.cc8
-rw-r--r--src/common/admin_socket.h3
-rw-r--r--src/common/ceph_context.cc58
-rw-r--r--src/common/ceph_context.h3
-rw-r--r--src/common/cmdparse.h3
-rw-r--r--src/mon/MDSMonitor.cc4
-rw-r--r--src/mon/Monitor.cc37
-rw-r--r--src/mon/Monitor.h4
-rw-r--r--src/osd/OSD.cc111
-rw-r--r--src/osd/OSD.h2
-rw-r--r--src/osdc/Objecter.cc7
-rw-r--r--src/osdc/Objecter.h2
-rw-r--r--src/rgw/rgw_bucket.cc12
-rw-r--r--src/rgw/rgw_main.cc3
-rw-r--r--src/rgw/rgw_op.cc118
-rw-r--r--src/rgw/rgw_op.h12
-rw-r--r--src/rgw/rgw_rest.cc24
-rw-r--r--src/rgw/rgw_rest.h2
-rw-r--r--src/rgw/rgw_rest_metadata.cc2
-rw-r--r--src/rgw/rgw_rest_s3.cc64
-rw-r--r--src/rgw/rgw_rest_s3.h1
-rw-r--r--src/rgw/rgw_user.cc3
-rw-r--r--src/test/admin_socket.cc40
-rw-r--r--src/test/system/systest_runnable.cc4
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;
}