From dfc09a2d9ed4b16cef0227bd63ce2b82a3cb28b3 Mon Sep 17 00:00:00 2001 From: Jan Radon Date: Sat, 26 Nov 2022 23:12:35 +0100 Subject: [PATCH] #349 validate object --- CHANGELOG.md | 3 +++ configure.ac | 2 +- rpm/dovecot-ceph-plugin.spec | 2 +- src/librmb/rados-storage-impl.cpp | 7 +++++++ src/librmb/rados-storage-impl.h | 1 + src/librmb/rados-storage.h | 4 ++++ src/librmb/tools/rmb/rmb-commands.cpp | 17 +++++++++++++---- src/librmb/tools/rmb/rmb-commands.h | 2 +- src/storage-rbox/doveadm-rbox-plugin.cpp | 13 +++++-------- src/storage-rbox/rbox-save.cpp | 5 +++++ src/storage-rbox/rbox-sync.cpp | 3 +++ src/tests/mocks/mock_test.h | 1 + 12 files changed, 45 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ada64cdb..285093ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # Change Log +## [0.0.46](https://github.com/ceph-dovecot/dovecot-ceph-plugin/tree/0.0.45) (2022-11-22) +- #349 bugfix doveadm rmb create ceph index validate object metadata + ## [0.0.45](https://github.com/ceph-dovecot/dovecot-ceph-plugin/tree/0.0.45) (2022-11-22) - #349 bugfix doveadm rmb return code not set diff --git a/configure.ac b/configure.ac index 9c451fac..c7dac368 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ AC_PREREQ([2.59]) -AC_INIT([dovecot-ceph-plugin], [0.0.45], [https://github.com/ceph-dovecot/dovecot-ceph-plugin/issues/new], ,[https://github.com/ceph-dovecot/dovecot-ceph-plugin]) +AC_INIT([dovecot-ceph-plugin], [0.0.46], [https://github.com/ceph-dovecot/dovecot-ceph-plugin/issues/new], ,[https://github.com/ceph-dovecot/dovecot-ceph-plugin]) AC_CONFIG_AUX_DIR([.]) diff --git a/rpm/dovecot-ceph-plugin.spec b/rpm/dovecot-ceph-plugin.spec index 2d426132..7b7a04c4 100644 --- a/rpm/dovecot-ceph-plugin.spec +++ b/rpm/dovecot-ceph-plugin.spec @@ -14,7 +14,7 @@ Name: dovecot-ceph-plugin Summary: Dovecot Ceph RADOS plugins -Version: 0.0.45 +Version: 0.0.46 Release: 0%{?dist} URL: https://github.com/ceph-dovecot/dovecot-ceph-plugin diff --git a/src/librmb/rados-storage-impl.cpp b/src/librmb/rados-storage-impl.cpp index 37e57274..f2b38993 100644 --- a/src/librmb/rados-storage-impl.cpp +++ b/src/librmb/rados-storage-impl.cpp @@ -576,6 +576,13 @@ void RadosStorageImpl::free_rados_mail(librmb::RadosMail *mail) { } } +uint64_t RadosStorageImpl::ceph_index_size(){ + uint64_t psize; + time_t pmtime; + get_recovery_io_ctx().stat(get_namespace(), &psize, &pmtime); + return psize; +} + int RadosStorageImpl::ceph_index_append(const std::string &oid) { librados::bufferlist bl; bl.append(RadosUtils::convert_to_ceph_index(oid)); diff --git a/src/librmb/rados-storage-impl.h b/src/librmb/rados-storage-impl.h index 11ab2856..c4320859 100644 --- a/src/librmb/rados-storage-impl.h +++ b/src/librmb/rados-storage-impl.h @@ -85,6 +85,7 @@ class RadosStorageImpl : public RadosStorage { void free_rados_mail(librmb::RadosMail *mail) override; + uint64_t ceph_index_size() override; int ceph_index_append(const std::string &oid) override; int ceph_index_append(const std::set &oids) override; int ceph_index_overwrite(const std::set &oids) override; diff --git a/src/librmb/rados-storage.h b/src/librmb/rados-storage.h index c3d36fe9..fcc0690d 100644 --- a/src/librmb/rados-storage.h +++ b/src/librmb/rados-storage.h @@ -220,6 +220,10 @@ underTest.ceph_index_add("dkfkjdf") */ virtual int ceph_index_delete() = 0; + /** + * returns the ceph index size + */ + virtual uint64_t ceph_index_size() = 0; /*! read the complete mail object into bufferlist * diff --git a/src/librmb/tools/rmb/rmb-commands.cpp b/src/librmb/tools/rmb/rmb-commands.cpp index 4bfb3def..58c1dd15 100644 --- a/src/librmb/tools/rmb/rmb-commands.cpp +++ b/src/librmb/tools/rmb/rmb-commands.cpp @@ -427,12 +427,21 @@ static void aio_cb(rados_completion_t cb, void *arg) { int RmbCommands::overwrite_ceph_object_index(std::set &mail_oids){ return storage->ceph_index_overwrite(mail_oids); } -std::set RmbCommands::load_objects(){ +std::set RmbCommands::load_objects(librmb::RadosStorageMetadataModule *ms){ std::set mail_list; - librados::NObjectIterator iter_guid =storage->find_mails(nullptr); + librados::NObjectIterator iter_guid = storage->find_mails(nullptr); while (iter_guid != librados::NObjectIterator::__EndObjectIterator) { - mail_list.insert((*iter_guid).get_oid()); - iter_guid++; + librmb::RadosMail mail; + mail.set_oid((*iter_guid).get_oid()); + + int load_metadata_ret = ms->load_metadata(&mail); + if (load_metadata_ret < 0 || !librmb::RadosUtils::validate_metadata(mail.get_metadata())) { + std::cerr << "metadata for object : " << mail.get_oid()->c_str() << " is not valid, skipping object " << std::endl; + iter_guid++; + continue; + } + mail_list.insert((*iter_guid).get_oid()); + iter_guid++; } return mail_list; } diff --git a/src/librmb/tools/rmb/rmb-commands.h b/src/librmb/tools/rmb/rmb-commands.h index 85bdcff1..d33c9b2f 100644 --- a/src/librmb/tools/rmb/rmb-commands.h +++ b/src/librmb/tools/rmb/rmb-commands.h @@ -66,7 +66,7 @@ class RmbCommands { void set_output_path(librmb::CmdLineParser *parser); int overwrite_ceph_object_index(std::set &mail_oids); - std::set load_objects(); + std::set load_objects(librmb::RadosStorageMetadataModule *ms); int remove_ceph_object_index(); int append_ceph_object_index(const std::set &mail_oids); private: diff --git a/src/storage-rbox/doveadm-rbox-plugin.cpp b/src/storage-rbox/doveadm-rbox-plugin.cpp index fa716669..e9d585c7 100644 --- a/src/storage-rbox/doveadm-rbox-plugin.cpp +++ b/src/storage-rbox/doveadm-rbox-plugin.cpp @@ -805,10 +805,7 @@ static int cmd_rmb_create_ceph_index_run(struct doveadm_mail_cmd_context *_ctx, return -1; } if(rmb_cmds.remove_ceph_object_index() < 0){ - i_error(" Error overwriting ceph object index"); - delete ms; - _ctx->exit_code = -1; - return -1; + i_debug(" Error overwriting ceph object index"); } if (user->namespaces != NULL) { @@ -832,7 +829,7 @@ static int cmd_rmb_create_ceph_index_run(struct doveadm_mail_cmd_context *_ctx, } //append to index. - i_info("found %d mails in namespace",mail_objects.size()); + i_info("found %s mails in namespace %d",info->vname, mail_objects.size()); if(rmb_cmds.append_ceph_object_index(mail_objects) < 0){ i_error(" Error overwriting ceph object index"); delete ms; @@ -842,9 +839,10 @@ static int cmd_rmb_create_ceph_index_run(struct doveadm_mail_cmd_context *_ctx, mail_objects.clear(); } } - } // end of for + } // end of for + }else{ - mail_objects = rmb_cmds.load_objects(); + mail_objects = rmb_cmds.load_objects(ms); if(rmb_cmds.overwrite_ceph_object_index(mail_objects) < 0){ i_error(" Error overwriting ceph object index"); delete ms; @@ -900,7 +898,6 @@ static int iterate_list_objects(struct mail_namespace* ns, const struct mailbox_ continue; } std::string oid = guid_128_to_string(obox_rec->oid); - //TODO: add the oid to the ceph index!!!! object_list.insert(oid); } if (mailbox_search_deinit(&search_ctx) < 0) { diff --git a/src/storage-rbox/rbox-save.cpp b/src/storage-rbox/rbox-save.cpp index 7826bb03..3f002e12 100644 --- a/src/storage-rbox/rbox-save.cpp +++ b/src/storage-rbox/rbox-save.cpp @@ -899,6 +899,11 @@ int rbox_save_finish(struct mail_save_context *_ctx) { if( r_storage->config->get_object_search_method() == 2){ // ceph config schalter an oder aus! r_storage->s->ceph_index_append(*r_ctx->rados_mail->get_oid()); + uint64_t index_size = r_storage->s->ceph_index_size(); + // WARN if index reaches 80% of max object size + if((r_storage->s->get_max_object_size() / index_size) > 80) { + i_warning("ceph_index file(%d) close to exceed max_object size(%d), recalc index !",r_storage->s->get_max_object_size(), index_size ); + } } } if (r_storage->save_log->is_open()) { diff --git a/src/storage-rbox/rbox-sync.cpp b/src/storage-rbox/rbox-sync.cpp index f4ab9736..8758acaa 100644 --- a/src/storage-rbox/rbox-sync.cpp +++ b/src/storage-rbox/rbox-sync.cpp @@ -367,6 +367,9 @@ int rbox_sync_begin(struct rbox_mailbox *rbox, struct rbox_sync_context **ctx_r, rebuild = (hdr->flags & MAIL_INDEX_HDR_FLAG_FSCKD) != 0; #endif + //TODO: check ceph index size, if threshold size has been reached, stat mails + // and repair mailbox + ctx = i_new(struct rbox_sync_context, 1); ctx->rbox = rbox; i_array_init(&ctx->expunged_items, 32); diff --git a/src/tests/mocks/mock_test.h b/src/tests/mocks/mock_test.h index e465f636..0e3f5f0a 100644 --- a/src/tests/mocks/mock_test.h +++ b/src/tests/mocks/mock_test.h @@ -83,6 +83,7 @@ class RadosStorageMock : public RadosStorage { MOCK_METHOD0(create_anker, int()); + MOCK_METHOD0(ceph_index_size,uint64_t()); MOCK_METHOD1(ceph_index_append,int(const std::string &oid)); MOCK_METHOD1(ceph_index_append,int(const std::set &oids));