diff -Naur ceph-13.2.5-orig/src/rgw/.rgw_sync_log_trim.cc.swp ceph-13.2.5/src/rgw/.rgw_sync_log_trim.cc.swp
--- ceph-13.2.5-orig/src/rgw/.rgw_sync_log_trim.cc.swp	1970-01-01 01:00:00.000000000 +0100
+++ ceph-13.2.5/src/rgw/.rgw_sync_log_trim.cc.swp	2019-04-19 12:08:23.000000000 +0200
@@ -0,0 +1,100 @@
+b0VIM 8.1E”¹\mºÓgrootrpi3b-build2~root/ceph-13.2.5/src/rgw/rgw_sync_log_trim.ccutf-8
3210#"! Utp
+ÿƒŠ„ujƒní}[^Ø	g6
+j�<ad ƒ¹ž›pmJGÞ fD@?.	á
à
¸
ž

e
L
1


êéÉ­¬ˆ‡tKJ-ìë®‘��D.þ
+û
+Ø
+×
+¼
+’
+‘
+E
+B
+A
+ô	£	k	U	3		áÏÎ¯wON'ýøËÊ”�76åàß±��€Y/*)õãÂÁzLGF1êß¯®c^[ÕÓÒ“‘{ZD/-ëéÓ¾ª¨vu<:   ENCODE_START(1, 1, bl);{void TrimCounters::Request::encode(bufferlist& bl) constWRITE_CLASS_ENCODER(TrimCounters::BucketCounter);}  decode(count, p);  decode(bucket, p);  using ceph::decode;{void TrimCounters::BucketCounter::decode(bufferlist::iterator& p)}  encode(count, bl);  encode(bucket, bl);  // no versioning to save space  using ceph::encode;{void TrimCounters::BucketCounter::encode(bufferlist& bl) const}  return out << rhs.bucket << ":" << rhs.count;{std::ostream& operator<<(std::ostream& out, const TrimCounters::BucketCounter& rhs)};  };    void handle(bufferlist::iterator& input, bufferlist& output) override;    Handler(Server *server) : server(server) {}   public:    Server *const server;  class Handler : public TrimNotifyHandler {  /// notify handler  };    virtual void reset_bucket_counters() = 0;    virtual void get_bucket_counters(int count, Vector& counters) = 0;    virtual ~Server() = default;  struct Server {  /// server interface to query the hottest buckets  };    void decode(bufferlist::iterator& p);    void encode(bufferlist& bl) const;    Vector bucket_counters;  struct Response {  /// return the current bucket trim counters  };    void decode(bufferlist::iterator& p);    void encode(bufferlist& bl) const;    uint16_t max_buckets; //< maximum number of bucket counters to return  struct Request {  /// request bucket trim counters from peer gateways  using Vector = std::vector<BucketCounter>;  };    void decode(bufferlist::iterator& p);    void encode(bufferlist& bl) const;      : bucket(bucket), count(count) {}    BucketCounter(const std::string& bucket, int count)    BucketCounter() = default;    int count{0};    std::string bucket; //< bucket instance metadata key  struct BucketCounter {  /// counter for a single bucketstruct TrimCounters {/// the trim process needs to accumulate their counters/// each gateway will process different datalog shards, so the gateway that runs/// api to share the bucket trim counters between gateways in the same zone.};  virtual void handle(bufferlist::iterator& input, bufferlist& output) = 0;  virtual ~TrimNotifyHandler() = default;struct TrimNotifyHandler {WRITE_RAW_ENCODER(TrimNotifyType);};  NotifyTrimComplete,  NotifyTrimCounters = 0,enum TrimNotifyType {// watch/notify api for gateways to coordinate about which buckets to trimusing rgw::BucketTrimStatus;const std::string rgw::BucketTrimStatus::oid = "bilog.trim";using BucketChangeCounter = BoundedKeyCounter<std::string, int>;using rgw::BucketTrimConfig;#define dout_prefix (*_dout << "trim: ")#undef dout_prefix#define dout_subsys ceph_subsys_rgw#include "include/assert.h"#include <boost/asio/yield.hpp>#include "rgw_sync.h"#include "rgw_rados.h"#include "rgw_metadata.h"#include "rgw_data_sync.h"#include "rgw_cr_rest.h"#include "rgw_cr_rados.h"#include "rgw_sync_log_trim.h"#include "common/errno.h"#include "common/bounded_key_counter.h"#include <boost/container/flat_map.hpp>#include <boost/circular_buffer.hpp>#include <mutex> */ * Foundation.  See file COPYING. * License version 2.1, as published by the Free Software * modify it under the terms of the GNU Lesser General Public * This is free software; you can redistribute it and/or * * Author: Casey Bodley <cbodley@redhat.com> * * Copyright (C) 2017 Red Hat, Inc * * Ceph - scalable distributed file system/*// vim: ts=8 sw=2 smarttab// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-ad�…<ä˜”“i(ûæ»·¶j'Ð
£
`
\
[


à´°­¬v1
Ø×¹·—•”HFÊ
+¤
+˜
+”
+h
+f
+e
+
+
+×	š	˜	—	D	B		Ô›™˜…„} // namespace rgw}                          impl.get(), impl->status_obj);  return new BucketTrimCR(impl->store, http, impl->config,  // return the trim coroutine without any polling{RGWCoroutine* BucketTrimManager::create_admin_bucket_trim_cr(RGWHTTPManager *http)}                              impl.get(), impl->status_obj);  return new BucketTrimPollCR(impl->store, http, impl->config,{RGWCoroutine* BucketTrimManager::create_bucket_trim_cr(RGWHTTPManager *http)}  impl->counter.insert(bucket.to_string());  }    return;  if (impl->trimmed.lookup(bucket)) {  // filter recently trimmed bucket instances out of bucket change counter  std::lock_guard<std::mutex> lock(impl->mutex);{void BucketTrimManager::on_bucket_changed(const boost::string_view& bucket)}  return impl->watcher.start();{int BucketTrimManager::init()BucketTrimManager::~BucketTrimManager() = default;}{  : impl(new Impl(store, config))                                     const BucketTrimConfig& config)BucketTrimManager::BucketTrimManager(RGWRados *store,};  }    return trimmed.lookup(bucket_instance);    std::lock_guard<std::mutex> lock(mutex);  bool trimmed_recently(const boost::string_view& bucket_instance) override {  }    trimmed.insert(std::move(bucket_instance), clock_type::now());    std::lock_guard<std::mutex> lock(mutex);    ldout(store->ctx(), 20) << "trimmed bucket instance " << bucket_instance << dendl;  void on_bucket_trimmed(std::string&& bucket_instance) override {  /// BucketTrimObserver interface to remember successfully-trimmed buckets  }    trimmed.expire_old(clock_type::now());    counter.clear();    std::lock_guard<std::mutex> lock(mutex);    ldout(store->ctx(), 20) << "bucket trim completed" << dendl;  void reset_bucket_counters() override {  }    ldout(store->ctx(), 20) << "get_bucket_counters: " << buckets << dendl;                        });adðuÌ³£�œ\NJI7þ¾Š„RAû
Ç
®
¨
š
–
•
…
s
Q
8
2
.
-

È‚fXR<2üåäº“hY
+Û
+†
+€
+C
+?
+>
+
+
+Ñ	µ	§	¡	…	7	&	 					É­‚�<ìéè£ŠM¼™PñÚº—j4úÚ¿�B0(Þ�f^XTHFEùá¥rY5ð  const   const std::vector<std::string>& markers; //< shard markers to trim  const RGWBucketInfo& bucket_info;  RGWRados *const store;  static constexpr int MAX_CONCURRENT_SHARDS = 16;class BucketTrimShardCollectCR : public RGWShardCollectCR {/// concurrent requests/// trim each bilog shard to the given marker, while limiting the number of}  return 0;  }    }      }        marker = std::move(shard.inc_marker.position);      if (peer == first || marker > shard.inc_marker.position) {      // always take the first marker, or any later marker that's smaller      }        continue;      if (shard.state != rgw_bucket_shard_sync_info::StateIncrementalSync) {      // only consider incremental sync markers      auto& marker = *m++;    for (auto& shard : *peer) {    auto m = status->begin();    }      return -EINVAL;      // all peers must agree on the number of shards    } else if (*num_shards != peer_shards) {      status->resize(*num_shards);      num_shards = peer_shards;    if (!num_shards) {    const size_t peer_shards = peer->size();  for (auto peer = first; peer != last; ++peer) {  boost::optional<size_t> num_shards = boost::make_optional(false, 0UL);  // -Wmaybe-uninitialized warning  // The initialisation below is required to silence a false positive  status->clear();{                    std::vector<std::string> *status)int take_min_status(CephContext *cct, Iter first, Iter last,template <typename Iter>/// populate the status with the minimum stable marker of each shard};  virtual bool trimmed_recently(const boost::string_view& bucket_instance) = 0;  virtual void on_bucket_trimmed(std::string&& bucket_instance) = 0;  virtual ~BucketTrimObserver() = default;struct BucketTrimObserver {/// Interface to communicate with the trim manager about completed operations};  }    }      restart();      ldout(store->ctx(), 4) << "Disconnected watch on " << ref.oid << dendl;    if (err == -ENOTCONN) {    }      return;    if (cookie != handle) {  void handle_error(uint64_t cookie, int err) override {  /// reestablish the watch if it gets disconnected  }    ref.ioctx.notify_ack(ref.oid, notify_id, cookie, reply);    }      lderr(store->ctx()) << "Failed to decode notification: " << e.what() << dendl;    } catch (const buffer::error& e) {      }        lderr(store->ctx()) << "no handler for notify type " << type << dendl;      } else {        handler->second->handle(p, reply);      if (handler != handlers.end()) {      auto handler = handlers.find(type);      decode(type, p);      TrimNotifyType type;      auto p = bl.begin();    try {    bufferlist reply;    }      return;    if (cookie != handle) {                     uint64_t notifier_id, bufferlist& bl) override {  void handle_notify(uint64_t notify_id, uint64_t cookie,  /// respond to bucket trim notifications  }    }      ref.ioctx.close();      ref.ioctx.unwatch2(handle);    if (handle) {  void stop() {  }    return r;    }      ref.ioctx.close();          << " with " << cpp_strerror(-r) << dendl;      lderr(store->ctx()) << "Failed to restart watch on " << ref.oid    if (r < 0) {    r = ref.ioctx.watch2(ref.oid, &handle, this);    }          << " with " << cpp_strerror(-r) << dendl;      lderr(store->ctx()) << "Failed to unwatch on " << ref.oid    if (r < 0) {    int r = ref.ioctx.unwatch2(handle);  int restart() {  }    return 0;    ldout(store->ctx(), 10) << "Watching " << ref.oid << dendl;    }      return r;      ref.ioctx.close();          << " with " << cpp_strerror(-r) << dendl;ad	ÅjÏÆx4ö·²”‘�dbCÿ
þ
ä
É
�
>
üÀ¬™“�}|<	ðÒ¬�`ü
+û
+»
+t
+3
+2
+)
+ë	¶	{	K	%	ýØ©¤£‰†…a_MÿÜ©�iBÿÐ¤‡~}Y,î¡‹~v<ð¥‘‹?#áÆ±‰�{zGüÏ¸c?98ÅÄ    ldout(cct, 10) << "trimming bilogs for bucket=" << bucket_info.bucket    // trim shards with a ShardCollectCR    }      return set_cr_error(retcode);      ldout(cct, 4) << "failed to correlate bucket sync status from peers" << dendl;    if (retcode < 0) {                              &min_markers);    retcode = take_min_status(cct, peer_status.begin(), peer_status.end(),    // determine the minimum marker for each shard    }      }        return set_cr_error(child_ret);        drain_all();      if (child_ret < 0) {      collect(&child_ret, nullptr);      yield wait_for_child();    while (num_spawned()) {    // wait for a response from each peer. all must respond to attempt trim    }            false);                                           bucket_instance, &bucket_info),      spawn(new RGWGetBucketInstanceInfoCR(store->get_async_rados(), store,      // in parallel, read the local bucket instance info      }        ++p;              false);        spawn(new StatusCR(cct, c.second, http, "/admin/log/", params, &*p),        using StatusCR = RGWReadRESTResourceCR<StatusShards>;      for (auto& c : store->zone_conn_map) {      auto p = peer_status.begin();      };        { nullptr, nullptr }        { "source-zone", zone_id.c_str() },        { "bucket", bucket_instance.c_str() },        { "status", nullptr },        { "type", "bucket-index" },      rgw_http_param_pair params[] = {      // query data sync status from each sync peer    yield {    set_status("fetching sync status from peers");    // query peers for sync status    ldout(cct, 4) << "starting trim on bucket=" << bucket_instance << dendl;  reenter(this) {{int BucketTrimInstanceCR::operate()};  int operate() override;  {}      peer_status(store->zone_conn_map.size())      zone_id(store->get_zone().id),      bucket_instance(bucket_instance),      http(http), observer(observer),    : RGWCoroutine(store->ctx()), store(store),                       const std::string& bucket_instance)                       BucketTrimObserver *observer,  BucketTrimInstanceCR(RGWRados *store, RGWHTTPManager *http, public:  std::vector<std::string> min_markers; //< min marker per shard  std::vector<StatusShards> peer_status; //< sync status for each peer  using StatusShards = std::vector<rgw_bucket_shard_sync_info>;  int child_ret = 0;  RGWBucketInfo bucket_info; //< bucket instance info to locate bucket indices  const std::string& zone_id; //< my zone id  std::string bucket_instance;  BucketTrimObserver *const observer;  RGWHTTPManager *const http;  RGWRados *const store;class BucketTrimInstanceCR : public RGWCoroutine {/// trim the bilog of all of the given bucket instance's shards}  return false;  }    }      return true;            false);                                    std::string{}, marker),      spawn(new RGWRadosBILogTrimCR(store, bucket_info, shard_id,          << " of " << bucket_info.bucket << " at marker " << marker << dendl;      ldout(cct, 10) << "trimming bilog shard " << shard_id    if (!marker.empty()) {    // skip empty markers    const auto shard_id = i++;    const auto& marker = markers[i];  while (i < markers.size()) {{bool BucketTrimShardCollectCR::spawn_next()};  bool spawn_next() override;  {}      store(store), bucket_info(bucket_info), markers(markers)    : RGWShardCollectCR(store->ctx(), MAX_CONCURRENT_SHARDS),                           const std::vector<std::string>& markers)  BucketTrimShardCollectCR(RGWRados *store, const RGWBucketInfo& bucket_info, public:  size_t i{0}; //< index of current shard markerad:n¬ƒ4ÿàÍÇ°yL("!ä
Ê
Æ
º
¸
·
f
'

ðÊ—g^Ý–d-ù
+Ç
+Â
+¤
+¡
+ 
+q
+o
+X
+F
+B
+ø	ì	Ý	Û	Ú	’	G	E	2	1	)	
+	ñ°zbIH'ÜÁŠ_WQ,	¼lkÒ¿‡mL/
ìÓÒ²©m"Ñ—[íÛ´®ª§¦}T  if (r < 0) {  int r = mgr->list_keys_init(section, start_marker, &handle);  // start a listing at the given marker{int AsyncMetadataList::_send_request()};  }    }      mgr->list_keys_complete(handle);    if (handle) {  ~AsyncMetadataList() override {  {}      section(section), start_marker(start_marker), callback(callback)    : RGWAsyncRadosRequest(caller, cn), cct(cct), mgr(mgr),                    const MetadataListCallback& callback)                    const std::string& section, const std::string& start_marker,                    RGWAioCompletionNotifier *cn, RGWMetadataManager *mgr,  AsyncMetadataList(CephContext *cct, RGWCoroutine *caller, public:  int _send_request() override;  void *handle{nullptr};  MetadataListCallback callback;  const std::string start_marker;  const std::string section;  RGWMetadataManager *const mgr;  CephContext *const cct;class AsyncMetadataList : public RGWAsyncRadosRequest {/// initial marker/// on reaching the end, it will restart at the beginning and list up to the/// lists metadata keys, passing each to a callback until it returns false.using MetadataListCallback = std::function<bool(std::string&&, std::string&&)>;/// metadata callback has the signature bool(string&& key, string&& marker)}  return 0;  }    return -EIO;  } catch (const buffer::error& e) {    }      }        counter.insert(b.bucket, b.count);      for (const auto& b : response.bucket_counters) {      decode(response, q);      TrimCounters::Response response;      auto q = peer.second.begin();    for (auto& peer : replies) {    decode(timeouts, p);    decode(replies, p);    std::set<std::pair<uint64_t, uint64_t>> timeouts;    std::map<std::pair<uint64_t, uint64_t>, bufferlist> replies;    auto p = bl.begin();    // decode notify responses  try {  counter.clear();{int accumulate_peer_counters(bufferlist& bl, BucketChangeCounter& counter)/// correlate the replies from each peer gateway into the given counter}  return true;  ++bucket;  spawn(new BucketTrimInstanceCR(store, http, observer, *bucket), false);  }    return false;  if (bucket == end) {{bool BucketTrimInstanceCollectCR::spawn_next()};  bool spawn_next() override;  {}      bucket(buckets.begin()), end(buckets.end())      store(store), http(http), observer(observer),    : RGWShardCollectCR(store->ctx(), max_concurrent),                              int max_concurrent)                              const std::vector<std::string>& buckets,                              BucketTrimObserver *observer,  BucketTrimInstanceCollectCR(RGWRados *store, RGWHTTPManager *http, public:  std::vector<std::string>::const_iterator end;  std::vector<std::string>::const_iterator bucket;  BucketTrimObserver *const observer;  RGWHTTPManager *const http;  RGWRados *const store;class BucketTrimInstanceCollectCR : public RGWShardCollectCR {/// trim each bucket instance while limiting the number of concurrent operations}  return 0;  }    return set_cr_done();    observer->on_bucket_trimmed(std::move(bucket_instance));    }      return set_cr_error(retcode);          << cpp_strerror(retcode) << dendl;      ldout(cct, 4) << "failed to trim bilog shards: "    if (retcode < 0) {    }      retcode = 0;    if (retcode == -ENODATA) {    // ENODATA just means there were no keys to trim    yield call(new BucketTrimShardCollectCR(store, bucket_info, min_markers));    set_status("trimming bilog shards");       << " markers=" << min_markers << ", shards=" << min_markers.size() << dendl;ad (}Æ¡“�A@!òñêÇ�|H!å
ä
Ë
«
‹
Q
?
7
1


ûÜÎÊÉŽkWV%Ù´¦¢fe^;ð
+¼
+•
+…
+
+Y
+X
+?
+
+ÿ	Þ	º	¨	 	f	T	L	F	/	.	"	 		óÀ“rT1êá™S!ê§`[<%! °iL>:ôðÌ½¨“�‰†…ZA#ÛÁ£†g%
+Â€1(' public:  static const std::string section; //< metadata section for bucket instances  std::string last_cold_marker; //< position for next trim marker  RGWObjVersionTracker objv; //< version tracker for trim status object  BucketTrimStatus status;  std::vector<std::string> buckets; //< buckets selected for trim  BucketChangeCounter counter;  bufferlist notify_replies;  ceph::mono_time start_time;  const rgw_raw_obj& obj;  BucketTrimObserver *const observer;  const BucketTrimConfig& config;  RGWHTTPManager *const http;  RGWRados *const store;class BucketTrimCR : public RGWCoroutine {};  }    }      req = nullptr;      req->finish();    if (req) {  void request_cleanup() override {  }    return req->get_ret_status();  int request_complete() override {  }    return 0;    async_rados->queue(req);                                mgr, section, start_marker, callback);    req = new AsyncMetadataList(cct, this, stack->create_completion_notifier(),  int send_request() override {  }    request_cleanup();  ~MetadataListCR() override {  {}      section(section), start_marker(start_marker), callback(callback)    : RGWSimpleCoroutine(cct), async_rados(async_rados), mgr(mgr),                 const MetadataListCallback& callback)                 const std::string& start_marker,                 RGWMetadataManager *mgr, const std::string& section,  MetadataListCR(CephContext *cct, RGWAsyncRadosProcessor *async_rados, public:  RGWAsyncRadosRequest *req{nullptr};  MetadataListCallback callback;  const std::string& start_marker;  const std::string& section;  RGWMetadataManager *const mgr;  RGWAsyncRadosProcessor *const async_rados;class MetadataListCR : public RGWSimpleCoroutine {/// coroutine wrapper for AsyncMetadataList}  return 0;  } while (truncated);    }      }        return 0;      if (!callback(std::move(key), std::move(marker))) {      }        return 0;      if (marker >= start_marker) {      // stop at original marker      auto& key = keys.front();      assert(keys.size() == 1);    if (!keys.empty()) {    marker = mgr->get_marker(handle);    }      return r;          << cpp_strerror(r) << dendl;      ldout(cct, 10) << "failed to list metadata: "    if (r < 0) {    r = mgr->list_keys_next(handle, 1, keys, &truncated);    // get the next key and marker  do {  ldout(cct, 20) << "restarting metadata listing" << dendl;  }    return r;        << cpp_strerror(r) << dendl;    ldout(cct, 10) << "failed to restart metadata listing: "  if (r < 0) {  r = mgr->list_keys_init(section, "", &handle);  handle = nullptr;  mgr->list_keys_complete(handle);  // restart the listing from the beginning (empty marker)  }    return 0;    // already listed all keys  if (start_marker.empty()) {  } while (truncated);    }      }        return 0;      if (!callback(std::move(key), std::move(marker))) {      auto& key = keys.front();      assert(keys.size() == 1);    if (!keys.empty()) {    marker = mgr->get_marker(handle);    }      return r;          << cpp_strerror(r) << dendl;      ldout(cct, 10) << "failed to list metadata: "    if (r < 0) {    r = mgr->list_keys_next(handle, 1, keys, &truncated);    // get the next key and marker  do {  std::string marker;  bool truncated{false};  std::list<std::string> keys;  ldout(cct, 20) << "starting metadata listing at " << start_marker << dendl;  }    return r;        << cpp_strerror(r) << dendl;    ldout(cct, 10) << "failed to init metadata listing: "ad§^Ê}V
+ÉÄÃ²¯®rqUSAï
Ã

J
<
úÂ—€fIýÈÀ§\6.-½
+¤
+V
+0
+(
+ô	ó	¹	w	R		õéãâªwN
Ç�v7âÚ¶{s7ÞÐ‰LÍ—cJ>ûµ‘xl9êºˆI>=í¯§¦      }                                section, status.marker, cb));        call(new MetadataListCR(cct, store->get_async_rados(), store->meta_mgr,        };          return buckets.size() < config.buckets_per_interval;          // return true if there's room for more          last_cold_marker = std::move(marker);          // remember the last cold bucket spawned to update the status marker          buckets.emplace_back(std::move(bucket));          }            return true;          if (i != buckets.end()) {          auto i = std::find(buckets.begin(), buckets.end(), bucket);          // filter out active buckets that we've already selected          }            return true;          if (observer->trimmed_recently(bucket)) {          // filter out keys that we trimmed recently        auto cb = [this, ref] (std::string&& bucket, std::string&& marker) {        // list cold buckets to consider for trim        auto ref = boost::intrusive_ptr<RGWCoroutine>{this};        // capture a reference so 'this' remains valid in the callback      yield {      set_status("listing cold buckets for trim");          << status.marker << dendl;      ldout(cct, 10) << "listing cold buckets from marker="      }        status.marker.clear(); // restart at the beginning      if (status.marker == "MAX") {      }        return set_cr_error(retcode);            << cpp_strerror(retcode) << dendl;        ldout(cct, 10) << "failed to read bilog trim status: "      if (retcode < 0) {                                &status, true, &objv));      yield call(new ReadStatus(store->get_async_rados(), store, obj,      using ReadStatus = RGWSimpleRadosReadCR<BucketTrimStatus>;      set_status("reading trim status");      // read BucketTrimStatus for marker position    if (buckets.size() < config.buckets_per_interval) {    }        });          buckets.push_back(bucket);        [this] (const std::string& bucket, int count) {      counter.get_highest(max_count,                            config.min_cold_buckets_per_interval;      const int max_count = config.buckets_per_interval -      buckets.reserve(config.buckets_per_interval);      }        return set_cr_error(retcode);        ldout(cct, 4) << "failed to correlate peer bucket counters" << dendl;      if (retcode < 0) {      retcode = accumulate_peer_counters(notify_replies, counter);      // select the hottest buckets for trim      }        return set_cr_error(retcode);        ldout(cct, 10) << "failed to fetch peer bucket counters" << dendl;      if (retcode < 0) {      }                                  &notify_replies));        call(new RGWRadosNotifyCR(store, obj, bl, config.notify_timeout_ms,        encode(request, bl);        encode(type, bl);        bufferlist bl;        TrimCounters::Request request{32};        const TrimNotifyType type = NotifyTrimCounters;        // request the top bucket counters from each peer gateway      yield {      set_status("fetching active bucket counters");      ldout(cct, 10) << "fetching active bucket counters" << dendl;      // query watch/notify for hot buckets    if (config.buckets_per_interval) {    start_time = ceph::mono_clock::now();  reenter(this) {{int BucketTrimCR::operate()const std::string BucketTrimCR::section{"bucket.instance"};};  int operate();  {}      observer(observer), obj(obj), counter(config.counter_size)    : RGWCoroutine(store->ctx()), store(store), http(http), config(config),               const rgw_raw_obj& obj)               const BucketTrimConfig& config, BucketTrimObserver *observer,  BucketTrimCR(RGWRados *store, RGWHTTPManager *http,adFögç¢sME?>ä�@ô
Ç
Æ
¥
[
*
÷¦cêÑ�a;3-,â
+Ö
+ 
+{
+f
+N
+3
+é	¾	¸	¡	S	/	)	(	ç­“�ƒ�€Q8øÒ¸ˆlkb(õ¬p<üûêçæÆÄ²£…>=úÑ†Iê›‰�€bÊ©Z	ù÷öõ}  return 0;  }    }      }                                              obj, name, cookie));        yield call(new RGWSimpleRadosUnlockCR(store->get_async_rados(), store,        set_status("unlocking");        // on errors, unlock so other gateways can try      if (retcode < 0) {      yield call(new BucketTrimCR(store, http, config, observer, obj));      set_status("trimming");      }        continue;        ldout(cct, 4) << "failed to lock: " << cpp_strerror(retcode) << dendl;      if (retcode < 0) {                                          config.trim_interval_sec));                                          obj, name, cookie,      yield call(new RGWSimpleRadosLockCR(store->get_async_rados(), store,      set_status("acquiring trim lock");      // prevent others from trimming for our entire wait interval      wait(utime_t{static_cast<time_t>(config.trim_interval_sec), 0});      set_status("sleeping");    for (;;) {  reenter(this) {{int BucketTrimPollCR::operate()};  int operate();  {}      cookie(RGWSimpleRadosLockCR::gen_random_cookie(cct))      config(config), observer(observer), obj(obj),    : RGWCoroutine(store->ctx()), store(store), http(http),                   BucketTrimObserver *observer, const rgw_raw_obj& obj)                   const BucketTrimConfig& config,  BucketTrimPollCR(RGWRados *store, RGWHTTPManager *http, public:  const std::string cookie;  const std::string name{"trim"}; //< lock name  const rgw_raw_obj& obj;  BucketTrimObserver *const observer;  const BucketTrimConfig& config;  RGWHTTPManager *const http;  RGWRados *const store;class BucketTrimPollCR : public RGWCoroutine {}  return 0;  }    return set_cr_done();        << ceph::mono_clock::now() - start_time << dendl;    ldout(cct, 4) << "bucket index log processing completed in "    }      return set_cr_error(retcode);      ldout(cct, 10) << "failed to notify peers of trim completion" << dendl;    if (retcode < 0) {    }                                nullptr));      call(new RGWRadosNotifyCR(store, obj, bl, config.notify_timeout_ms,      encode(request, bl);      encode(type, bl);      bufferlist bl;      TrimComplete::Request request;      const TrimNotifyType type = NotifyTrimComplete;    yield {    set_status("trim completed");    // notify peers that trim completed    }      }        return set_cr_error(retcode);            << cpp_strerror(retcode) << dendl;        ldout(cct, 4) << "failed to write updated trim status: "      if (retcode < 0) {                                 status, &objv));      yield call(new WriteStatus(store->get_async_rados(), store, obj,      using WriteStatus = RGWSimpleRadosWriteCR<BucketTrimStatus>;      ldout(cct, 20) << "writing bucket trim marker=" << status.marker << dendl;      status.marker = std::move(last_cold_marker);      set_status("writing updated trim status");    if (!last_cold_marker.empty() && status.marker != last_cold_marker) {    // write updated trim status    // ignore errors from individual buckets                                               config.concurrent_buckets));    yield call(new BucketTrimInstanceCollectCR(store, http, observer, buckets,    ldout(cct, 4) << "collected " << buckets.size() << " buckets for trim" << dendl;    set_status("trimming buckets");    // trim bucket instances with limited concurrency    }      }        return set_cr_error(retcode);            << cpp_strerror(retcode) << dendl;        ldout(cct, 4) << "failed to list bucket instance metadata: "      if (retcode < 0) {adÖj°_@èßÃ�ŒE
¼
”
b
'
óïîŸmU1
+êÕÍÇµ±°^3ÿ
+¹
+Ÿ
+™
+•
+”
+Š
+y
+l
+W
+R
+*
+
+
+
+ñ	ð	¼	u	s	Y	X	;	ÿâÂƒZø²Žr@>=Ä»¢�€`_÷ö´x2
ßÂÁua`(¸”Y2-,ò«�bÖÕ                          buckets.emplace_back(key, count);    counter.get_highest(count, [&buckets] (const std::string& key, int count) {    std::lock_guard<std::mutex> lock(mutex);    buckets.reserve(count);  void get_bucket_counters(int count, TrimCounters::Vector& buckets) {  /// TrimCounters::Server interface for watch/notify api  {}      watcher(store, status_obj, this)      trimmed(config.recent_size, config.recent_duration),      counter(config.counter_size),      status_obj(store->get_zone_params().log_pool, BucketTrimStatus::oid),    : store(store), config(config),  Impl(RGWRados *store, const BucketTrimConfig& config)  std::mutex mutex;  /// protect data shared between data sync, trim, and watch/notify threads  BucketTrimWatcher watcher;  /// serve the bucket trim watch/notify api  RecentlyTrimmedBucketList trimmed;  /// track recently trimmed buckets to focus trim activity elsewhere  using clock_type = RecentlyTrimmedBucketList::clock_type;  using RecentlyTrimmedBucketList = RecentEventList<std::string>;  BucketChangeCounter counter;  /// count frequency of bucket instance entries in the data changes log  const rgw_raw_obj status_obj;  const BucketTrimConfig config;  RGWRados *const store; public:                                public BucketTrimObserver {class BucketTrimManager::Impl : public TrimCounters::Server,}  config.recent_duration = std::chrono::hours(2);  config.recent_size = 128;  config.notify_timeout_ms = 10000;      conf->get_val<int64_t>("rgw_sync_log_trim_concurrent_buckets");  config.concurrent_buckets =      conf->get_val<int64_t>("rgw_sync_log_trim_min_cold_buckets");  config.min_cold_buckets_per_interval =      conf->get_val<int64_t>("rgw_sync_log_trim_max_buckets");  config.buckets_per_interval =  config.counter_size = 512;      conf->get_val<int64_t>("rgw_sync_log_trim_interval");  config.trim_interval_sec =  auto conf = cct->_conf;{void configure_bucket_trim(CephContext *cct, BucketTrimConfig& config)// read bucket trim configuration from ceph contextnamespace rgw {};  const ceph::timespan max_duration;  boost::circular_buffer<Event> events;  };    time_point time;    T value;  struct Event { private:  }    }      events.pop_front();    while (!events.empty() && events.front().time < expired_before) {    const auto expired_before = now - max_duration;  void expire_old(const time_point& now) {  /// remove events that are no longer recent compared to the given point in time  }    return false;    }      }        return true;      if (key == event.value) {    for (const auto& event : events) {  bool lookup(const U& key) const {  template <typename U>  /// U can be any that provides operator==(U, T)  /// performs a linear search for an event matching the given key, whose type  }    events.push_back(Event{std::move(value), now});    // assert(events.empty() || now >= events.back().time)  void insert(T&& value, const time_point& now) {  /// recent as the last inserted event  /// insert an event at the given point in time. this time must be at least as  {}    : events(max_size), max_duration(max_duration)  RecentEventList(size_t max_size, const ceph::timespan& max_duration)  using time_point = typename clock_type::time_point;  using clock_type = Clock; public:class RecentEventList {template <typename T, typename Clock = ceph::coarse_mono_clock>/// inserted in temporal order/// and recent events can be searched by key. expiration depends on events being/// tracks a bounded list of events with timestamps. old events can be expired,ad
+FŠåÐÎ’�z`LJãáÇ¨“‘TR<
+Û
Ú
š
c
a
N
4
÷öá¡…ƒ‚2ïÈž™…^4/.þ
+×
+Ö
+Á
+”
+z
+o
+?
+>
+ó	î	ë	ê	±	¯	•	€	~	B	@	*			èç­«‘|z=;%âá¡jhU;:åãâá±zaG2âŸž•X$¶gcbI=98(ùèØÒÑ›iQ*úÖ ˜’�FE      lderr(store->ctx()) << "Failed to watch " << ref.oid    if (r < 0) {    }      }        r = ref.ioctx.watch2(ref.oid, &handle, this);      if (r == -EEXIST || r == 0) {      r = ref.ioctx.create(ref.oid, exclusive);      constexpr bool exclusive = true;    if (r == -ENOENT) {    r = ref.ioctx.watch2(ref.oid, &handle, this);    // register a watch on the realm's control object    }      return r;    if (r < 0) {    int r = store->get_raw_obj_ref(obj, &ref);  int start() {  }    stop();  ~BucketTrimWatcher() {  }    handlers.emplace(NotifyTrimComplete, new TrimComplete::Handler(counters));    handlers.emplace(NotifyTrimCounters, new TrimCounters::Handler(counters));    : store(store), obj(obj) {                    TrimCounters::Server *counters)  BucketTrimWatcher(RGWRados *store, const rgw_raw_obj& obj, public:  boost::container::flat_map<TrimNotifyType, HandlerPtr> handlers;  using HandlerPtr = std::unique_ptr<TrimNotifyHandler>;  uint64_t handle{0};  rgw_rados_ref ref;  const rgw_raw_obj& obj;  RGWRados *const store;class BucketTrimWatcher : public librados::WatchCtx2 {/// rados watcher for bucket trim notifications}  encode(response, output);  Response response;  server->reset_bucket_counters();  decode(request, input);  Request request;{                                   bufferlist& output)void TrimComplete::Handler::handle(bufferlist::iterator& input,WRITE_CLASS_ENCODER(TrimComplete::Response);}  DECODE_FINISH(p);  DECODE_START(1, p);{void TrimComplete::Response::decode(bufferlist::iterator& p)}  ENCODE_FINISH(bl);  ENCODE_START(1, 1, bl);{void TrimComplete::Response::encode(bufferlist& bl) constWRITE_CLASS_ENCODER(TrimComplete::Request);}  DECODE_FINISH(p);  DECODE_START(1, p);{void TrimComplete::Request::decode(bufferlist::iterator& p)}  ENCODE_FINISH(bl);  ENCODE_START(1, 1, bl);{void TrimComplete::Request::encode(bufferlist& bl) const};  };    void handle(bufferlist::iterator& input, bufferlist& output) override;    Handler(Server *server) : server(server) {}   public:    Server *const server;  class Handler : public TrimNotifyHandler {  /// notify handler  using Server = TrimCounters::Server;  /// server interface to reset bucket counters  };    void decode(bufferlist::iterator& p);    void encode(bufferlist& bl) const;  struct Response {  };    void decode(bufferlist::iterator& p);    void encode(bufferlist& bl) const;  struct Request {struct TrimComplete {/// counters can be reset/// api to notify peer gateways that trim has completed and their bucket change}  encode(response, output);  server->get_bucket_counters(count, response.bucket_counters);  Response response;  auto count = std::min<uint16_t>(request.max_buckets, 128);  decode(request, input);  Request request;{                                   bufferlist& output)void TrimCounters::Handler::handle(bufferlist::iterator& input,WRITE_CLASS_ENCODER(TrimCounters::Response);}  DECODE_FINISH(p);  decode(bucket_counters, p);  DECODE_START(1, p);{void TrimCounters::Response::decode(bufferlist::iterator& p)}  ENCODE_FINISH(bl);  encode(bucket_counters, bl);  ENCODE_START(1, 1, bl);{void TrimCounters::Response::encode(bufferlist& bl) constWRITE_CLASS_ENCODER(TrimCounters::Request);}  DECODE_FINISH(p);  decode(max_buckets, p);  DECODE_START(1, p);{void TrimCounters::Request::decode(bufferlist::iterator& p)}  ENCODE_FINISH(bl);  encode(max_buckets, bl);
\ No newline at end of file
diff -Naur ceph-13.2.5-orig/src/rgw/librgw.cc ceph-13.2.5/src/rgw/librgw.cc
--- ceph-13.2.5-orig/src/rgw/librgw.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/librgw.cc	2019-04-19 17:09:53.000000000 +0200
@@ -11,6 +11,9 @@
  * Foundation.  See file COPYING.
  *
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "include/compat.h"
 #include <sys/types.h>
 #include <string.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_admin.cc ceph-13.2.5/src/rgw/rgw_admin.cc
--- ceph-13.2.5-orig/src/rgw/rgw_admin.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_admin.cc	2019-04-19 17:31:24.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <errno.h>
 #include <iostream>
 #include <sstream>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_asio_frontend.cc ceph-13.2.5/src/rgw/rgw_asio_frontend.cc
--- ceph-13.2.5-orig/src/rgw/rgw_asio_frontend.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_asio_frontend.cc	2019-04-19 17:31:34.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <atomic>
 #include <condition_variable>
 #include <mutex>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_auth_keystone.cc ceph-13.2.5/src/rgw/rgw_auth_keystone.cc
--- ceph-13.2.5-orig/src/rgw/rgw_auth_keystone.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_auth_keystone.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <string>
 #include <vector>
 
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_auth_s3.cc ceph-13.2.5/src/rgw/rgw_auth_s3.cc
--- ceph-13.2.5-orig/src/rgw/rgw_auth_s3.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_auth_s3.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <algorithm>
 #include <map>
 #include <iterator>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_civetweb_frontend.cc ceph-13.2.5/src/rgw/rgw_civetweb_frontend.cc
--- ceph-13.2.5-orig/src/rgw/rgw_civetweb_frontend.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_civetweb_frontend.cc	2019-04-19 17:31:29.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <set>
 #include <string>
 
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_client_io.cc ceph-13.2.5/src/rgw/rgw_client_io.cc
--- ceph-13.2.5-orig/src/rgw/rgw_client_io.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_client_io.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_common.cc ceph-13.2.5/src/rgw/rgw_common.cc
--- ceph-13.2.5-orig/src/rgw/rgw_common.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_common.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <errno.h>
 #include <vector>
 #include <algorithm>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_compression.cc ceph-13.2.5/src/rgw/rgw_compression.cc
--- ceph-13.2.5-orig/src/rgw/rgw_compression.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_compression.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,7 +1,8 @@
-
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_compression.h"
 
 #define dout_subsys ceph_subsys_rgw
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_crypt.cc ceph-13.2.5/src/rgw/rgw_crypt.cc
--- ceph-13.2.5-orig/src/rgw/rgw_crypt.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_crypt.cc	2019-04-19 16:51:38.000000000 +0200
@@ -3,6 +3,9 @@
 /**
  * Crypto filters for Put/Post/Get operations.
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <rgw/rgw_op.h>
 #include <rgw/rgw_crypt.h>
 #include <auth/Crypto.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_file.cc ceph-13.2.5/src/rgw/rgw_file.cc
--- ceph-13.2.5-orig/src/rgw/rgw_file.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_file.cc	2019-04-19 17:09:43.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "include/compat.h"
 #include "include/rados/rgw_file.h"
 
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_formats.cc ceph-13.2.5/src/rgw/rgw_formats.cc
--- ceph-13.2.5-orig/src/rgw/rgw_formats.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_formats.cc	2019-04-19 12:08:23.000000000 +0200
@@ -12,6 +12,8 @@
  *
  */
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <boost/format.hpp>
 
 #include "common/escape.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_frontend.cc ceph-13.2.5/src/rgw/rgw_frontend.cc
--- ceph-13.2.5-orig/src/rgw/rgw_frontend.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_frontend.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <signal.h>
 
 #include "rgw_frontend.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_http_client_curl.cc ceph-13.2.5/src/rgw/rgw_http_client_curl.cc
--- ceph-13.2.5-orig/src/rgw/rgw_http_client_curl.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_http_client_curl.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_http_client_curl.h"
 #include <mutex>
 #include <vector>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_json_enc.cc ceph-13.2.5/src/rgw/rgw_json_enc.cc
--- ceph-13.2.5-orig/src/rgw/rgw_json_enc.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_json_enc.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_common.h"
 #include "rgw_rados.h"
 #include "rgw_log.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_loadgen.cc ceph-13.2.5/src/rgw/rgw_loadgen.cc
--- ceph-13.2.5-orig/src/rgw/rgw_loadgen.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_loadgen.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <algorithm>
 #include <sstream>
 #include <string.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_loadgen_process.cc ceph-13.2.5/src/rgw/rgw_loadgen_process.cc
--- ceph-13.2.5-orig/src/rgw/rgw_loadgen_process.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_loadgen_process.cc	2019-04-19 17:09:58.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/errno.h"
 #include "common/Throttle.h"
 #include "common/WorkQueue.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_log.cc ceph-13.2.5/src/rgw/rgw_log.cc
--- ceph-13.2.5-orig/src/rgw/rgw_log.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_log.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/Clock.h"
 #include "common/Timer.h"
 #include "common/utf8.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_main.cc ceph-13.2.5/src/rgw/rgw_main.cc
--- ceph-13.2.5-orig/src/rgw/rgw_main.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_main.cc	2019-04-19 17:49:05.000000000 +0200
@@ -1,5 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/ceph_argparse.h"
 #include "global/global_init.h"
 #include "global/signal_handler.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_multi.cc ceph-13.2.5/src/rgw/rgw_multi.cc
--- ceph-13.2.5-orig/src/rgw/rgw_multi.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_multi.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <string.h>
 
 #include <iostream>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_op.cc ceph-13.2.5/src/rgw/rgw_op.cc
--- ceph-13.2.5-orig/src/rgw/rgw_op.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_op.cc	2019-04-19 12:32:46.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <errno.h>
 #include <stdlib.h>
 #include <system_error>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_os_lib.cc ceph-13.2.5/src/rgw/rgw_os_lib.cc
--- ceph-13.2.5-orig/src/rgw/rgw_os_lib.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_os_lib.cc	2019-04-19 12:32:51.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_rest.h"
 #include "rgw_rest_s3.h"
 #include "rgw_rest_user.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_process.cc ceph-13.2.5/src/rgw/rgw_process.cc
--- ceph-13.2.5-orig/src/rgw/rgw_process.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_process.cc	2019-04-19 12:32:41.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/errno.h"
 #include "common/Throttle.h"
 #include "common/WorkQueue.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rados.cc ceph-13.2.5/src/rgw/rgw_rados.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rados.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rados.cc	2019-04-19 12:48:43.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "include/compat.h"
 #include <errno.h>
 #include <stdlib.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_realm_reloader.cc ceph-13.2.5/src/rgw/rgw_realm_reloader.cc
--- ceph-13.2.5-orig/src/rgw/rgw_realm_reloader.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_realm_reloader.cc	2019-04-19 12:09:30.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_realm_reloader.h"
 #include "rgw_rados.h"
 
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_request.cc ceph-13.2.5/src/rgw/rgw_request.cc
--- ceph-13.2.5-orig/src/rgw/rgw_request.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_request.cc	2019-04-19 12:48:48.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_op.h"
 #include "rgw_request.h"
 
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest.cc ceph-13.2.5/src/rgw/rgw_rest.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest.cc	2019-04-19 13:02:25.000000000 +0200
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
 
 #include <errno.h>
 #include <limits.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_bucket.cc ceph-13.2.5/src/rgw/rgw_rest_bucket.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_bucket.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_bucket.cc	2019-04-19 13:02:12.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_op.h"
 #include "rgw_bucket.h"
 #include "rgw_rest_bucket.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_client.cc ceph-13.2.5/src/rgw/rgw_rest_client.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_client.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_client.cc	2019-04-19 13:02:29.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_common.h"
 #include "rgw_rest_client.h"
 #include "rgw_auth_s3.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_config.cc ceph-13.2.5/src/rgw/rgw_rest_config.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_config.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_config.cc	2019-04-19 13:29:10.000000000 +0200
@@ -11,6 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/ceph_json.h"
 #include "common/strtol.h"
 #include "rgw_rest.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_log.cc ceph-13.2.5/src/rgw/rgw_rest_log.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_log.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_log.cc	2019-04-19 13:39:20.000000000 +0200
@@ -11,6 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/ceph_json.h"
 #include "common/strtol.h"
 #include "rgw_rest.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_metadata.cc ceph-13.2.5/src/rgw/rgw_rest_metadata.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_metadata.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_metadata.cc	2019-04-19 13:39:03.000000000 +0200
@@ -11,6 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "include/page.h"
 
 #include "rgw_rest.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_opstate.cc ceph-13.2.5/src/rgw/rgw_rest_opstate.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_opstate.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_opstate.cc	2019-04-19 13:59:16.000000000 +0200
@@ -11,6 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/ceph_json.h"
 #include "common/strtol.h"
 #include "rgw_rest.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_realm.cc ceph-13.2.5/src/rgw/rgw_rest_realm.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_realm.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_realm.cc	2019-04-19 13:59:24.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/errno.h"
 #include "rgw_rest_realm.h"
 #include "rgw_rest_s3.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_replica_log.cc ceph-13.2.5/src/rgw/rgw_rest_replica_log.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_replica_log.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_replica_log.cc	2019-04-19 14:08:59.000000000 +0200
@@ -11,6 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/ceph_json.h"
 #include "common/strtol.h"
 #include "rgw_rest.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_role.cc ceph-13.2.5/src/rgw/rgw_rest_role.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_role.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_role.cc	2019-04-19 14:08:53.000000000 +0200
@@ -1,5 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
+
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <errno.h>
 
 #include "common/errno.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_s3.cc ceph-13.2.5/src/rgw/rgw_rest_s3.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_s3.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_s3.cc	2019-04-19 15:27:09.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <errno.h>
 #include <array>
 #include <string.h>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_swift.cc ceph-13.2.5/src/rgw/rgw_rest_swift.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_swift.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_swift.cc	2019-04-19 15:26:59.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/format.hpp>
 #include <boost/optional.hpp>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_usage.cc ceph-13.2.5/src/rgw/rgw_rest_usage.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_usage.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_usage.cc	2019-04-19 15:26:54.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_op.h"
 #include "rgw_usage.h"
 #include "rgw_rest_usage.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_rest_user.cc ceph-13.2.5/src/rgw/rgw_rest_user.cc
--- ceph-13.2.5-orig/src/rgw/rgw_rest_user.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_rest_user.cc	2019-04-19 16:17:16.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "common/ceph_json.h"
 
 #include "rgw_op.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_swift_auth.cc ceph-13.2.5/src/rgw/rgw_swift_auth.cc
--- ceph-13.2.5-orig/src/rgw/rgw_swift_auth.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_swift_auth.cc	2019-04-19 16:28:36.000000000 +0200
@@ -1,6 +1,8 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include <array>
 
 #include <boost/utility/string_view.hpp>
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_sync_module_es.cc ceph-13.2.5/src/rgw/rgw_sync_module_es.cc
--- ceph-13.2.5-orig/src/rgw/rgw_sync_module_es.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_sync_module_es.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,3 +1,5 @@
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_common.h"
 #include "rgw_coroutine.h"
 #include "rgw_sync_module.h"
diff -Naur ceph-13.2.5-orig/src/rgw/rgw_sync_module_es_rest.cc ceph-13.2.5/src/rgw/rgw_sync_module_es_rest.cc
--- ceph-13.2.5-orig/src/rgw/rgw_sync_module_es_rest.cc	2019-03-12 17:48:03.000000000 +0100
+++ ceph-13.2.5/src/rgw/rgw_sync_module_es_rest.cc	2019-04-19 12:08:23.000000000 +0200
@@ -1,3 +1,5 @@
+#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
+
 #include "rgw_sync_module_es.h"
 #include "rgw_sync_module_es_rest.h"
 #include "rgw_es_query.h"
