summaryrefslogtreecommitdiffstats
path: root/src/cls/log/cls_log_client.cc
blob: 182bb9fec47e9e74a7c7595c685486db68a8fda8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <errno.h>

#include "cls/log/cls_log_ops.h"
#include "include/rados/librados.hpp"
#include "include/compat.h"


using std::list;
using std::string;

using ceph::bufferlist;

using namespace librados;



void cls_log_add(librados::ObjectWriteOperation& op, list<cls_log_entry>& entries, bool monotonic_inc)
{
  bufferlist in;
  cls_log_add_op call;
  call.entries = entries;
  encode(call, in);
  op.exec("log", "add", in);
}

void cls_log_add(librados::ObjectWriteOperation& op, cls_log_entry& entry)
{
  bufferlist in;
  cls_log_add_op call;
  call.entries.push_back(entry);
  encode(call, in);
  op.exec("log", "add", in);
}

void cls_log_add_prepare_entry(cls_log_entry& entry, const utime_t& timestamp,
                 const string& section, const string& name, bufferlist& bl)
{
  entry.timestamp = timestamp;
  entry.section = section;
  entry.name = name;
  entry.data = bl;
}

void cls_log_add(librados::ObjectWriteOperation& op, const utime_t& timestamp,
                 const string& section, const string& name, bufferlist& bl)
{
  cls_log_entry entry;

  cls_log_add_prepare_entry(entry, timestamp, section, name, bl);
  cls_log_add(op, entry);
}

void cls_log_trim(librados::ObjectWriteOperation& op, const utime_t& from_time, const utime_t& to_time,
                  const string& from_marker, const string& to_marker)
{
  bufferlist in;
  cls_log_trim_op call;
  call.from_time = from_time;
  call.to_time = to_time;
  call.from_marker = from_marker;
  call.to_marker = to_marker;
  encode(call, in);
  op.exec("log", "trim", in);
}

int cls_log_trim(librados::IoCtx& io_ctx, const string& oid, const utime_t& from_time, const utime_t& to_time,
                 const string& from_marker, const string& to_marker)
{
  bool done = false;

  do {
    ObjectWriteOperation op;

    cls_log_trim(op, from_time, to_time, from_marker, to_marker);

    int r = io_ctx.operate(oid, &op);
    if (r == -ENODATA)
      done = true;
    else if (r < 0)
      return r;

  } while (!done);


  return 0;
}

class LogListCtx : public ObjectOperationCompletion {
  list<cls_log_entry> *entries;
  string *marker;
  bool *truncated;
public:
  LogListCtx(list<cls_log_entry> *_entries, string *_marker, bool *_truncated) :
                                      entries(_entries), marker(_marker), truncated(_truncated) {}
  void handle_completion(int r, bufferlist& outbl) override {
    if (r >= 0) {
      cls_log_list_ret ret;
      try {
        auto iter = outbl.cbegin();
        decode(ret, iter);
        if (entries)
          *entries = std::move(ret.entries);
        if (truncated)
          *truncated = ret.truncated;
        if (marker)
          *marker = std::move(ret.marker);
      } catch (ceph::buffer::error& err) {
        // nothing we can do about it atm
      }
    }
  }
};

void cls_log_list(librados::ObjectReadOperation& op, const utime_t& from,
		  const utime_t& to, const string& in_marker, int max_entries,
		  list<cls_log_entry>& entries,
                  string *out_marker, bool *truncated)
{
  bufferlist inbl;
  cls_log_list_op call;
  call.from_time = from;
  call.to_time = to;
  call.marker = in_marker;
  call.max_entries = max_entries;

  encode(call, inbl);

  op.exec("log", "list", inbl, new LogListCtx(&entries, out_marker, truncated));
}

class LogInfoCtx : public ObjectOperationCompletion {
  cls_log_header *header;
public:
  explicit LogInfoCtx(cls_log_header *_header) : header(_header) {}
  void handle_completion(int r, bufferlist& outbl) override {
    if (r >= 0) {
      cls_log_info_ret ret;
      try {
        auto iter = outbl.cbegin();
        decode(ret, iter);
        if (header)
	  *header = ret.header;
      } catch (ceph::buffer::error& err) {
        // nothing we can do about it atm
      }
    }
  }
};

void cls_log_info(librados::ObjectReadOperation& op, cls_log_header *header)
{
  bufferlist inbl;
  cls_log_info_op call;

  encode(call, inbl);

  op.exec("log", "info", inbl, new LogInfoCtx(header));
}