diff options
author | Sage Weil <sage@inktank.com> | 2013-01-20 21:53:37 -0800 |
---|---|---|
committer | Greg Farnum <greg@inktank.com> | 2013-02-20 17:21:23 -0800 |
commit | b4fd196cae5ab76aeb8f82f0581d0a6a2133a3ed (patch) | |
tree | b76c07e1662e5c1b3484695f4ed9be2ceeff9c95 | |
parent | 5f92adca26b509aed5655e85ad53174fa7b574b9 (diff) | |
download | ceph-b4fd196cae5ab76aeb8f82f0581d0a6a2133a3ed.tar.gz |
mds: parse ceph.*.layout vxattr key/value content
Use qi to parse a strictly formatted set of key/value pairs. Be picky
about whitespace. Any subset of recognized keys is allowed. Parse the
same set of keys as the ceph.*.layout.* vxattrs.
Signed-off-by: Sage Weil <sage@inktank.com>
(cherry picked from commit 5551aa5b3b5c2e9e7006476b9cd8cc181d2c9a04)
-rwxr-xr-x | qa/workunits/misc/layout_vxattrs.sh | 17 | ||||
-rw-r--r-- | src/mds/Server.cc | 41 |
2 files changed, 57 insertions, 1 deletions
diff --git a/qa/workunits/misc/layout_vxattrs.sh b/qa/workunits/misc/layout_vxattrs.sh index d181e03212c..e6c7c65212a 100755 --- a/qa/workunits/misc/layout_vxattrs.sh +++ b/qa/workunits/misc/layout_vxattrs.sh @@ -32,6 +32,18 @@ getfattr -n ceph.file.layout.stripe_unit file2 | grep -q 1048576 getfattr -n ceph.file.layout.stripe_count file2 | grep -q 8 getfattr -n ceph.file.layout.object_size file2 | grep -q 10485760 +setfattr -n ceph.file.layout -v "stripe_unit=4194304 stripe_count=16 object_size=41943040 pool=data" file2 +getfattr -n ceph.file.layout.stripe_unit file2 | grep -q 4194304 +getfattr -n ceph.file.layout.stripe_count file2 | grep -q 16 +getfattr -n ceph.file.layout.object_size file2 | grep -q 41943040 +getfattr -n ceph.file.layout.pool file2 | grep -q data + +setfattr -n ceph.file.layout -v "stripe_unit=1048576" file2 +getfattr -n ceph.file.layout.stripe_unit file2 | grep -q 1048576 +getfattr -n ceph.file.layout.stripe_count file2 | grep -q 16 +getfattr -n ceph.file.layout.object_size file2 | grep -q 41943040 +getfattr -n ceph.file.layout.pool file2 | grep -q data + # dir rm -f dir/file || true rmdir dir || true @@ -55,6 +67,11 @@ getfattr -n ceph.dir.layout.stripe_unit dir | grep -q 1048576 getfattr -n ceph.dir.layout.stripe_count dir | grep -q 8 getfattr -n ceph.dir.layout.object_size dir | grep -q 10485760 +setfattr -n ceph.file.layout -v "stripe_count=16" file2 +getfattr -n ceph.file.layout.stripe_count file2 | grep -q 16 +setfattr -n ceph.file.layout -v "object_size=10485760 stripe_count=8 stripe_unit=1048576 pool=data" file2 +getfattr -n ceph.file.layout.stripe_count file2 | grep -q 8 + touch dir/file getfattr -n ceph.file.layout.pool dir/file | grep -q data getfattr -n ceph.file.layout.stripe_unit dir/file | grep -q 1048576 diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c17fc8d0050..1a2d2b47372 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -14,6 +14,10 @@ #include <boost/lexical_cast.hpp> +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/include/qi.hpp> +#include <boost/fusion/include/std_pair.hpp> + #include "MDS.h" #include "Server.h" #include "Locker.h" @@ -3381,12 +3385,47 @@ void Server::handle_client_setdirlayout(MDRequest *mdr) // XATTRS +// parse a map of keys/values. +namespace qi = boost::spirit::qi; + +template <typename Iterator> +struct keys_and_values + : qi::grammar<Iterator, std::map<string, string>()> +{ + keys_and_values() + : keys_and_values::base_type(query) + { + query = pair >> *(qi::lit(' ') >> pair); + pair = key >> '=' >> value; + key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9"); + value = +qi::char_("a-zA-Z_0-9"); + } + qi::rule<Iterator, std::map<string, string>()> query; + qi::rule<Iterator, std::pair<string, string>()> pair; + qi::rule<Iterator, string()> key, value; +}; + int Server::parse_layout_vxattr(string name, string value, ceph_file_layout *layout) { dout(20) << "parse_layout_vxattr name " << name << " value '" << value << "'" << dendl; try { if (name == "layout") { - // XXX implement me + string::iterator begin = value.begin(); + string::iterator end = value.end(); + keys_and_values<string::iterator> p; // create instance of parser + std::map<string, string> m; // map to receive results + if (!qi::parse(begin, end, p, m)) { // returns true if successful + return -EINVAL; + } + string left(begin, end); + dout(10) << " parsed " << m << " left '" << left << "'" << dendl; + if (begin != end) + return -EINVAL; + for (map<string,string>::iterator q = m.begin(); q != m.end(); ++q) { + int r = parse_layout_vxattr(string("layout.") + q->first, q->second, layout); + if (r < 0) + return r; + } } else if (name == "layout.object_size") { layout->fl_object_size = boost::lexical_cast<unsigned>(value); } else if (name == "layout.stripe_unit") { |