]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/dbstore: Lifecycle support
authorSoumya Koduri <skoduri@redhat.com>
Mon, 27 Jun 2022 08:43:19 +0000 (14:13 +0530)
committerSoumya Koduri <skoduri@redhat.com>
Tue, 5 Jul 2022 12:12:19 +0000 (17:42 +0530)
Fixed issues with LC rule processing in dbstore. Also wrt object
transition, for now just the target storage class is updated for that
object in the object table without any other special action taken.

TODO: Once zonegroup, zone and storage-classes can be configured for
dbstore, need to validate target storage-class/placement rules and also
perform any other actions necessary (for eg., moving objects to another
table etc., if in case each storage class needs to have separate object table)

Signed-off-by: Soumya Koduri <skoduri@redhat.com>
src/rgw/rgw_lc.cc
src/rgw/rgw_sal_dbstore.cc
src/rgw/store/dbstore/common/dbstore.cc
src/rgw/store/dbstore/common/dbstore.h

index c4604d3e4fecec838bfce6460db7b558b3dc2539..57f412559bc1e3230440387ee96eae9c9f884ba9 100644 (file)
@@ -27,8 +27,7 @@
 #include "rgw_zone.h"
 #include "rgw_string.h"
 #include "rgw_multi.h"
-#include "rgw_sal_rados.h"
-#include "rgw_rados.h"
+#include "rgw_sal.h"
 #include "rgw_lc_tier.h"
 #include "rgw_notify.h"
 
@@ -523,6 +522,7 @@ static int remove_expired_obj(
   auto& meta = o.meta;
   int ret;
   std::string version_id;
+  std::unique_ptr<rgw::sal::Notification> notify;
 
   if (!remove_indeed) {
     obj_key.instance.clear();
@@ -560,30 +560,34 @@ static int remove_expired_obj(
   del_op->params.unmod_since = meta.mtime;
   del_op->params.marker_version_id = version_id;
 
-  std::unique_ptr<rgw::sal::Notification> notify
-    = store->get_notification(dpp, obj.get(), nullptr, event_type,
+  rgw::sal::RadosStore *rados = dynamic_cast<rgw::sal::RadosStore*>(oc.store);
+  if (rados) {
+    // notification supported only for RADOS store for now
+    notify
+      = store->get_notification(dpp, obj.get(), nullptr, event_type,
                              bucket.get(), lc_id,
                              const_cast<std::string&>(oc.bucket->get_tenant()),
                              lc_req_id, null_yield);
 
-  /* can eliminate cast when reservation is lifted into Notification */
-  auto notify_res = static_cast<rgw::sal::RadosNotification*>(notify.get())->get_reservation();
+    /* can eliminate cast when reservation is lifted into Notification */
+    auto notify_res = static_cast<rgw::sal::RadosNotification*>(notify.get())->get_reservation();
 
-  ret = rgw::notify::publish_reserve(dpp, event_type, notify_res, nullptr);
-  if (ret < 0) {
-    ldpp_dout(dpp, 1)
-      << "ERROR: notify reservation failed, deferring delete of object k="
-      << o.key
-      << dendl;
-    return ret;
+    ret = rgw::notify::publish_reserve(dpp, event_type, notify_res, nullptr);
+    if ( ret < 0) {
+      ldpp_dout(dpp, 1)
+        << "ERROR: notify reservation failed, deferring delete of object k="
+        << o.key
+        << dendl;
+      return ret;
+    }
   }
-
   ret =  del_op->delete_obj(dpp, null_yield);
   if (ret < 0) {
     ldpp_dout(dpp, 1) <<
       "ERROR: publishing notification failed, with error: " << ret << dendl;
-  } else {
-      // send request to notification manager
+  } else if (rados) {
+    // send request to notification manager
+    auto notify_res = static_cast<rgw::sal::RadosNotification*>(notify.get())->get_reservation();
     (void) rgw::notify::publish_commit(
       obj.get(), obj->get_obj_size(), ceph::real_clock::now(),
       obj->get_attrs()[RGW_ATTR_ETAG].to_str(), version_id, event_type,
index c06fc814d0c35299ed4d34879eedf9ed5a20db18..dbf0f812920c8af3c9521ad7e65f7f2d74a88460 100644 (file)
@@ -734,7 +734,9 @@ namespace rgw::sal {
       const DoutPrefixProvider* dpp,
       optional_yield y)
   {
-    return 0;
+    DB::Object op_target(store->getDB(),
+        get_bucket()->get_info(), get_obj());
+    return op_target.transition(dpp, placement_rule, mtime, olh_epoch);
   }
 
   int DBObject::transition_to_cloud(Bucket* bucket,
@@ -1609,7 +1611,9 @@ namespace rgw::sal {
 
   bool DBStore::valid_placement(const rgw_placement_rule& rule)
   {
-    return zone.get_rgw_params().valid_placement(rule);
+    // XXX: Till zonegroup, zone and storage-classes can be configured
+    // for dbstore return true
+    return true; //zone.get_rgw_params().valid_placement(rule);
   }
 
   std::unique_ptr<User> DBStore::get_user(const rgw_user &u)
index ecd8b5a9e874d1a33351376ab77e5be886b259d4..ad71cd0bcbd99f89aaa5db71581c34a531646cf1 100644 (file)
@@ -1133,6 +1133,60 @@ out:
   return ret;
 }
 
+int DB::Object::transition(const DoutPrefixProvider *dpp,
+                           const rgw_placement_rule& rule,
+                           const real_time& mtime,
+                           uint64_t olh_epoch)
+{
+  int ret = 0;
+
+  DBOpParams params = {};
+  map<string, bufferlist> *attrset;
+
+  store->InitializeParams(dpp, &params);
+  InitializeParamsfromObject(dpp, &params);
+
+  ret = store->ProcessOp(dpp, "GetObject", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0) <<"In GetObject failed err:(" <<ret<<")" << dendl;
+    goto out;
+  }
+
+  /* pick one field check if object exists */
+  if (!params.op.obj.state.exists) {
+    ldpp_dout(dpp, 0)<<"Object(bucket:" << bucket_info.bucket.name << ", Object:"<< obj.key.name << ") doesn't exist" << dendl;
+    return -1;
+  }
+
+  params.op.query_str = "meta";
+  params.op.obj.state.mtime = real_clock::now();
+  params.op.obj.storage_class = rule.storage_class;
+  attrset = &params.op.obj.state.attrset;
+  if (!rule.storage_class.empty()) {
+    bufferlist bl;
+    bl.append(rule.storage_class);
+    (*attrset)[RGW_ATTR_STORAGE_CLASS] = bl;
+  }
+  params.op.obj.versioned_epoch = olh_epoch; // XXX: not sure if needed
+
+  /* Unlike Rados, in dbstore for now, both head and tail objects
+   * refer to same storage class
+   */
+  params.op.obj.head_placement_rule = rule;
+  params.op.obj.tail_placement.placement_rule = rule;
+
+  ret = store->ProcessOp(dpp, "UpdateObject", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In UpdateObject failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+out:
+  return ret;
+}
+
 int DB::raw_obj::read(const DoutPrefixProvider *dpp, int64_t ofs,
                       uint64_t len, bufferlist& bl)
 {
index d105dc2ac0814a82cf1c7ea3f5310e33832ad93d..5f84689134f6571f3aa62b5d038264e8b620e4c3 100644 (file)
@@ -625,9 +625,7 @@ class DBOp {
       BucketName TEXT NOT NULL , \
       StartTime  INTEGER , \
       Status     INTEGER , \
-      PRIMARY KEY (LCIndex, BucketName), \
-      FOREIGN KEY (BucketName) \
-      REFERENCES '{}' (BucketName) ON DELETE CASCADE ON UPDATE CASCADE \n);";
+      PRIMARY KEY (LCIndex, BucketName) \n);";
 
     static constexpr std::string_view CreateLCHeadTableQ =
       "CREATE TABLE IF NOT EXISTS '{}' ( \
@@ -1910,6 +1908,9 @@ class DB {
       int InitializeParamsfromObject(const DoutPrefixProvider *dpp, DBOpParams* params);
       int set_attrs(const DoutPrefixProvider *dpp, std::map<std::string, bufferlist>& setattrs,
           std::map<std::string, bufferlist>* rmattrs);
+      int transition(const DoutPrefixProvider *dpp,
+                     const rgw_placement_rule& rule, const real_time& mtime,
+                     uint64_t olh_epoch);
       int obj_omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, bool must_exist);
       int obj_omap_get_vals_by_keys(const DoutPrefixProvider *dpp, const std::string& oid,
           const std::set<std::string>& keys,