1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2    	// vim: ts=8 sw=2 smarttab
3    	
4    	#include <errno.h>
5    	
6    	#include "cls/user/cls_user_client.h"
7    	#include "include/rados/librados.hpp"
8    	
9    	
10   	using namespace librados;
11   	
12   	
13   	void cls_user_set_buckets(librados::ObjectWriteOperation& op, list<cls_user_bucket_entry>& entries, bool add)
14   	{
15   	  bufferlist in;
16   	  cls_user_set_buckets_op call;
17   	  call.entries = entries;
18   	  call.add = add;
19   	  call.time = real_clock::now();
20   	  encode(call, in);
21   	  op.exec("user", "set_buckets_info", in);
22   	}
23   	
24   	void cls_user_complete_stats_sync(librados::ObjectWriteOperation& op)
25   	{
26   	  bufferlist in;
27   	  cls_user_complete_stats_sync_op call;
28   	  call.time = real_clock::now();
29   	  encode(call, in);
30   	  op.exec("user", "complete_stats_sync", in);
31   	}
32   	
33   	void cls_user_remove_bucket(librados::ObjectWriteOperation& op, const cls_user_bucket& bucket)
34   	{
35   	  bufferlist in;
36   	  cls_user_remove_bucket_op call;
37   	  call.bucket = bucket;
38   	  encode(call, in);
39   	  op.exec("user", "remove_bucket", in);
40   	}
41   	
42   	class ClsUserListCtx : public ObjectOperationCompletion {
43   	  list<cls_user_bucket_entry> *entries;
44   	  string *marker;
45   	  bool *truncated;
46   	  int *pret;
47   	public:
48   	  ClsUserListCtx(list<cls_user_bucket_entry> *_entries, string *_marker, bool *_truncated, int *_pret) :
49   	                                      entries(_entries), marker(_marker), truncated(_truncated), pret(_pret) {}
50   	  void handle_completion(int r, bufferlist& outbl) override {
51   	    if (r >= 0) {
52   	      cls_user_list_buckets_ret ret;
53   	      try {
54   	        auto iter = outbl.cbegin();
55   	        decode(ret, iter);
56   	        if (entries)
57   		  *entries = ret.entries;
58   	        if (truncated)
59   	          *truncated = ret.truncated;
60   	        if (marker)
61   	          *marker = ret.marker;
62   	      } catch (buffer::error& err) {
63   	        r = -EIO;
64   	      }
65   	    }
66   	    if (pret) {
67   	      *pret = r;
68   	    }
69   	  }
70   	};
71   	
72   	void cls_user_bucket_list(librados::ObjectReadOperation& op,
73   	                          const string& in_marker,
74   	                          const string& end_marker,
75   	                          int max_entries,
76   	                          list<cls_user_bucket_entry>& entries,
77   	                          string *out_marker,
78   	                          bool *truncated,
79   	                          int *pret)
80   	{
81   	  bufferlist inbl;
82   	  cls_user_list_buckets_op call;
83   	  call.marker = in_marker;
84   	  call.end_marker = end_marker;
85   	  call.max_entries = max_entries;
86   	
87   	  encode(call, inbl);
88   	
89   	  op.exec("user", "list_buckets", inbl, new ClsUserListCtx(&entries, out_marker, truncated, pret));
90   	}
91   	
92   	class ClsUserGetHeaderCtx : public ObjectOperationCompletion {
93   	  cls_user_header *header;
94   	  RGWGetUserHeader_CB *ret_ctx;
95   	  int *pret;
96   	public:
97   	  ClsUserGetHeaderCtx(cls_user_header *_h, RGWGetUserHeader_CB *_ctx, int *_pret) : header(_h), ret_ctx(_ctx), pret(_pret) {}
(1) Event exn_spec_violation: An exception of type "std::length_error" is thrown but the throw list "throw()" doesn't allow it to be thrown. This will cause a call to unexpected() which usually calls terminate().
Also see events: [fun_call_w_exception]
98   	  ~ClsUserGetHeaderCtx() override {
99   	    if (ret_ctx) {
(2) Event fun_call_w_exception: Called function throws an exception of type "std::length_error". [details]
Also see events: [exn_spec_violation]
100  	      ret_ctx->put();
101  	    }
102  	  }
103  	  void handle_completion(int r, bufferlist& outbl) override {
104  	    if (r >= 0) {
105  	      cls_user_get_header_ret ret;
106  	      try {
107  	        auto iter = outbl.cbegin();
108  	        decode(ret, iter);
109  	        if (header)
110  		  *header = ret.header;
111  	      } catch (buffer::error& err) {
112  	        r = -EIO;
113  	      }
114  	      if (ret_ctx) {
115  	        ret_ctx->handle_response(r, ret.header);
116  	      }
117  	    }
118  	    if (pret) {
119  	      *pret = r;
120  	    }
121  	  }
122  	};
123  	
124  	void cls_user_get_header(librados::ObjectReadOperation& op,
125  	                       cls_user_header *header, int *pret)
126  	{
127  	  bufferlist inbl;
128  	  cls_user_get_header_op call;
129  	
130  	  encode(call, inbl);
131  	
132  	  op.exec("user", "get_header", inbl, new ClsUserGetHeaderCtx(header, NULL, pret));
133  	}
134  	
135  	void cls_user_reset_stats(librados::ObjectWriteOperation &op)
136  	{
137  	  bufferlist inbl;
138  	  cls_user_reset_stats_op call;
139  	  call.time = real_clock::now();
140  	  encode(call, inbl);
141  	  op.exec("user", "reset_user_stats", inbl);
142  	}
143  	
144  	int cls_user_get_header_async(IoCtx& io_ctx, string& oid, RGWGetUserHeader_CB *ctx)
145  	{
146  	  bufferlist in, out;
147  	  cls_user_get_header_op call;
148  	  encode(call, in);
149  	  ObjectReadOperation op;
150  	  op.exec("user", "get_header", in, new ClsUserGetHeaderCtx(NULL, ctx, NULL)); /* no need to pass pret, as we'll call ctx->handle_response() with correct error */
151  	  AioCompletion *c = librados::Rados::aio_create_completion(NULL, NULL, NULL);
152  	  int r = io_ctx.aio_operate(oid, c, &op, NULL);
153  	  c->release();
154  	  if (r < 0)
155  	    return r;
156  	
157  	  return 0;
158  	}
159