]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: parse ceph.*.layout vxattr key/value content
authorSage Weil <sage@inktank.com>
Mon, 21 Jan 2013 05:53:37 +0000 (21:53 -0800)
committerGreg Farnum <greg@inktank.com>
Thu, 21 Feb 2013 21:44:01 +0000 (13:44 -0800)
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)

qa/workunits/misc/layout_vxattrs.sh
src/mds/Server.cc

index d181e03212c3dc893c5ec95026169482e15324b4..e6c7c65212a868ba6402cfef4ecf0f0965c50f93 100755 (executable)
@@ -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
index ac51e60d0a989d4133e68cc682fd80fce273afca..20372947f5f3025bad4b0affe977e11b80755df2 100644 (file)
 #include <boost/lexical_cast.hpp>
 #include "include/assert.h"  // lexical_cast includes system assert.h
 
+#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"
@@ -3512,12 +3516,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") {