@@ -1057,6 +1057,84 @@ int get_osdmap(ObjectStore *store, epoch_t e, OSDMap &osdmap, bufferlist& bl)
10571057 return 0 ;
10581058}
10591059
1060+ int expand_log (
1061+ CephContext *cct,
1062+ ObjectStore *fs,
1063+ spg_t pgid,
1064+ pg_info_t &info,
1065+ eversion_t target_version)
1066+ {
1067+ try {
1068+ bufferlist bl;
1069+ OSDMap osdmap;
1070+ int ret = get_osdmap (fs, info.last_update .epoch , osdmap, bl);
1071+ if (ret < 0 ) {
1072+ std::cerr << " Can't find latest local OSDMap " << info.last_update .epoch << std::endl;
1073+ return ret;
1074+ }
1075+ ceph_assert (osdmap.have_pg_pool (info.pgid .pool ()));
1076+ auto pool_info = osdmap.get_pg_pool (info.pgid .pool ());
1077+ if (!pool_info->is_erasure ()) {
1078+ std::cerr << " extend-log-with-fake-entries can only apply to pgs of ec pools" << std::endl;
1079+ return -EINVAL;
1080+ }
1081+
1082+ PGLog log (cct);
1083+ pg_missing_t missing;
1084+ auto ch = fs->open_collection (coll_t (pgid));
1085+ if (!ch) {
1086+ return -ENOENT;
1087+ }
1088+ ostringstream oss;
1089+ log.read_log_and_missing (
1090+ fs, ch,
1091+ pgid.make_pgmeta_oid (),
1092+ info,
1093+ oss,
1094+ cct->_conf ->osd_ignore_stale_divergent_priors ,
1095+ cct->_conf ->osd_debug_verify_missing_on_start );
1096+ if (debug && oss.str ().size ())
1097+ cerr << oss.str () << std::endl;
1098+
1099+ auto e = target_version;
1100+ e.version = log.get_head ().version + 1 ;
1101+ auto entry = *log.get_log ().log .rbegin ();
1102+ for (; e <= target_version; e.version ++) {
1103+ entry.version = e;
1104+ std::cout << " adding " << e << std::endl;
1105+ log.add (entry, true );
1106+ }
1107+ info.last_complete = target_version;
1108+ info.last_update = target_version;
1109+ info.last_user_version = target_version.version + 1 ;
1110+
1111+ std::map<string, bufferlist> km;
1112+ ObjectStore::Transaction t;
1113+
1114+ pg_fast_info_t fast;
1115+ fast.populate_from (info);
1116+ encode (fast, km[string (fastinfo_key)]);
1117+ encode (info, km[string (info_key)]);
1118+ log.write_log_and_missing (
1119+ t,
1120+ &km,
1121+ coll_t (pgid),
1122+ pgid.make_pgmeta_oid (),
1123+ pool_info->require_rollback ());
1124+
1125+ for (auto &ent : km) {
1126+ std::cout << " km key: " << ent.first << std::endl;
1127+ }
1128+
1129+ t.omap_setkeys (coll_t (pgid), pgid.make_pgmeta_oid (), km);
1130+ fs->queue_transaction (ch, std::move (t));
1131+ return 0 ;
1132+ } catch (const buffer::error &e) {
1133+ cerr << " read_log_and_missing threw exception error " << e.what () << std::endl;
1134+ return -EFAULT;
1135+ }
1136+ }
1137+
10601138int get_pg_num_history (ObjectStore *store, pool_pg_num_history_t *h)
10611139{
10621140 ObjectStore::CollectionHandle ch = store->open_collection (coll_t::meta ());
@@ -3350,7 +3428,7 @@ bool ends_with(const string& check, const string& ending)
33503428int main (int argc, char **argv)
33513429{
33523430 string dpath, jpath, pgidstr, op, file, mountpoint, mon_store_path, object;
3353- string target_data_path, fsid;
3431+ string target_data_path, fsid, target_version_str ;
33543432 string objcmd, arg1, arg2, type, format, argnspace, pool, rmtypestr, dump_data_dir;
33553433 boost::optional<std::string> nspace;
33563434 spg_t pgid;
@@ -3368,6 +3446,8 @@ int main(int argc, char **argv)
33683446 " Arg is one of [bluestore (default), memstore]" )
33693447 (" data-path" , po::value<string>(&dpath),
33703448 " path to object store, mandatory" )
3449+ (" target-version" , po::value<string>(&target_version_str),
3450+ " the target version that log is expected to be expanded to" )
33713451 (" journal-path" , po::value<string>(&jpath),
33723452 " path to journal, use if tool can't find it" )
33733453 (" pgid" , po::value<string>(&pgidstr),
@@ -3627,6 +3707,18 @@ int main(int argc, char **argv)
36273707 return 1 ;
36283708 }
36293709
3710+ eversion_t target_version;
3711+ if (op == " extend-log-with-fake-entries" ) {
3712+ if (target_version_str.empty ()) {
3713+ std::cerr << " target-version needed" << std::endl;
3714+ return 1 ;
3715+ }
3716+ std::string epoch_str = target_version_str.substr (0 , target_version_str.find (" ." ));
3717+ std::string version_str = target_version_str.substr (target_version_str.find (" ." ) + 1 );
3718+ target_version.epoch = std::stoi (epoch_str);
3719+ target_version.version = std::stoll (version_str);
3720+ }
3721+
36303722 std::unique_ptr<ObjectStore> fs = ObjectStore::create (g_ceph_context, type, dpath, jpath, flags);
36313723 if (!fs) {
36323724 cerr << " Unable to create store of type " << type << std::endl;
@@ -4147,7 +4239,7 @@ int main(int argc, char **argv)
41474239
41484240 // If not an object command nor any of the ops handled below, then output this usage
41494241 // before complaining about a bad pgid
4150- if (!vm.count (" objcmd" ) && op != " export" && op != " export-remove" && op != " info" && op != " log" && op != " mark-complete" && op != " trim-pg-log" && op != " trim-pg-log-dups" && op != " pg-log-inject-dups" ) {
4242+ if (!vm.count (" objcmd" ) && op != " export" && op != " export-remove" && op != " info" && op != " log" && op != " mark-complete" && op != " trim-pg-log" && op != " trim-pg-log-dups" && op != " pg-log-inject-dups" && op != " extend-log-with-fake-entries " ) {
41514243 cerr << " Must provide --op (info, log, remove, mkfs, fsck, repair, export, export-remove, import, list, fix-lost, list-pgs, dump-super, meta-list, "
41524244 " get-osdmap, set-osdmap, get-superblock, set-superblock, get-inc-osdmap, set-inc-osdmap, mark-complete, reset-last-complete, dump-export, trim-pg-log, "
41534245 " trim-pg-log-dups statfs)"
@@ -4464,6 +4556,10 @@ int main(int argc, char **argv)
44644556 goto out;
44654557
44664558 dump_log (formatter, cout, log, missing);
4559+ } else if (op == " extend-log-with-fake-entries" ) {
4560+ ret = expand_log (cct.get (), fs.get (), pgid, info, target_version);
4561+ if (ret < 0 )
4562+ goto out;
44674563 } else if (op == " mark-complete" ) {
44684564 ObjectStore::Transaction tran;
44694565 ObjectStore::Transaction *t = &tran;
0 commit comments