diff options
author | Greg Farnum <greg@inktank.com> | 2013-06-14 16:27:14 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-20 14:10:26 -0700 |
commit | d1c95943d8d7889d1dbcc5887d7598ceae9b546a (patch) | |
tree | bc8faddb052a44aca49d4ed98f8994f2a76272cb | |
parent | 008bdc5e647068fc8efa4fb68093a93bc1369d67 (diff) | |
download | ceph-d1c95943d8d7889d1dbcc5887d7598ceae9b546a.tar.gz |
cls_replica_log: add types for new class
Signed-off-by: Greg Farnum <greg@inktank.com>
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rw-r--r-- | src/cls/replica_log/cls_replica_log_types.cc | 80 | ||||
-rw-r--r-- | src/cls/replica_log/cls_replica_log_types.h | 189 | ||||
-rw-r--r-- | src/test/encoding/types.h | 5 |
4 files changed, 282 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 9c261645002..cda590e9e83 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -158,7 +158,9 @@ rgw_dencoder_src = rgw/rgw_dencoder.cc \ ceph_dencoder_SOURCES = test/encoding/ceph_dencoder.cc ${rgw_dencoder_src} perfglue/disabled_heap_profiler.cc ceph_dencoder_CXXFLAGS = ${AM_CXXFLAGS} -ceph_dencoder_LDADD = $(LIBGLOBAL_LDA) libcls_lock_client.a libcls_rgw_client.a libosd.a libmds.a libosdc.la $(LIBOS_LDA) libmon.a +ceph_dencoder_LDADD = $(LIBGLOBAL_LDA) libcls_lock_client.a \ + libcls_rgw_client.a libcls_replica_log_client.a \ + libosd.a libmds.a libosdc.la $(LIBOS_LDA) libmon.a bin_PROGRAMS += ceph-dencoder mount_ceph_SOURCES = mount/mount.ceph.c common/armor.c common/safe_io.c common/secret.c include/addr_parsing.c @@ -579,6 +581,7 @@ libcls_statelog_la_LDFLAGS = ${AM_LDFLAGS} -version-info 1:0:0 -export-symbols-r radoslib_LTLIBRARIES += libcls_statelog.la + if WITH_RADOSGW # rgw: rados gateway libcls_rgw_la_SOURCES = cls/rgw/cls_rgw.cc @@ -613,6 +616,10 @@ libcls_statelog_client_a_SOURCES = \ cls/statelog/cls_statelog_client.cc noinst_LIBRARIES += libcls_statelog_client.a +libcls_replica_log_client_a_SOURCES = \ + cls/replica_log/cls_replica_log_types.cc +noinst_LIBRARIES += libcls_replica_log_client.a + libcls_rgw_client_a_SOURCES = \ cls/rgw/cls_rgw_client.cc \ cls/rgw/cls_rgw_types.cc \ diff --git a/src/cls/replica_log/cls_replica_log_types.cc b/src/cls/replica_log/cls_replica_log_types.cc new file mode 100644 index 00000000000..ba89fd42ae3 --- /dev/null +++ b/src/cls/replica_log/cls_replica_log_types.cc @@ -0,0 +1,80 @@ +/* + * Ceph - scalable distributed file system + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "cls_replica_log_types.h" + +#include "common/Formatter.h" +#include "common/ceph_json.h" + +void cls_replica_log_item_marker::dump(Formatter *f) const +{ + f->dump_string("item name", item_name); + f->dump_stream("item timestamp") << item_timestamp; +} + +void cls_replica_log_item_marker:: +generate_test_instances(std::list<cls_replica_log_item_marker*>& ls) +{ + ls.push_back(new cls_replica_log_item_marker); + ls.back()->item_name = "test_item_1"; + ls.back()->item_timestamp.set_from_double(0); + ls.push_back(new cls_replica_log_item_marker); + ls.back()->item_name = "test_item_2"; + ls.back()->item_timestamp.set_from_double(20); +} + +void cls_replica_log_progress_marker::dump(Formatter *f) const +{ + f->dump_string("entity", entity_id); + f->dump_string("position_marker", position_marker); + position_time.gmtime(f->dump_stream("position_time")); + encode_json("items_in_progress", items, f); +} + +void cls_replica_log_progress_marker:: +generate_test_instances(std::list<cls_replica_log_progress_marker*>& ls) +{ + ls.push_back(new cls_replica_log_progress_marker); + ls.push_back(new cls_replica_log_progress_marker); + ls.back()->entity_id = "entity1"; + ls.back()->position_marker = "pos1"; + ls.back()->position_time.set_from_double(20); + + std::list<cls_replica_log_item_marker*> test_items; + cls_replica_log_item_marker::generate_test_instances(test_items); + std::list<cls_replica_log_item_marker*>::iterator i = test_items.begin(); + for ( ; i != test_items.end(); ++i) { + ls.back()->items.push_back(*(*i)); + } +} + +void cls_replica_log_bound::dump(Formatter *f) const +{ + f->dump_string("position_marker", position_marker); + position_time.gmtime(f->dump_stream("position_time")); + f->dump_string("marker_exists", marker_exists ? "yes" : "no"); + if (marker_exists) { + encode_json("marker", marker, f); //progress marker + } +} + +void cls_replica_log_bound:: +generate_test_instances(std::list<cls_replica_log_bound*>& ls) +{ + ls.push_back(new cls_replica_log_bound); + std::list<cls_replica_log_progress_marker*> marker_objects; + cls_replica_log_progress_marker::generate_test_instances(marker_objects); + std::list<cls_replica_log_progress_marker*>::iterator i = + marker_objects.begin(); + ls.back()->update_marker(*(*i)); + ls.push_back(new cls_replica_log_bound); + ++i; + ls.back()->update_marker(*(*i)); +} diff --git a/src/cls/replica_log/cls_replica_log_types.h b/src/cls/replica_log/cls_replica_log_types.h new file mode 100644 index 00000000000..39dc22e4456 --- /dev/null +++ b/src/cls/replica_log/cls_replica_log_types.h @@ -0,0 +1,189 @@ +/* + * Ceph - scalable distributed file system + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + * Copyright 2013 Inktank + */ + +#ifndef CLS_REPLICA_LOG_TYPES_H_ +#define CLS_REPLICA_LOG_TYPES_H_ + +#include "include/utime.h" +#include "include/encoding.h" +#include "include/types.h" +#include <errno.h> + +struct cls_replica_log_item_marker { + string item_name; // the name of the item we're marking + utime_t item_timestamp; // the time stamp at which the item was outdated + + cls_replica_log_item_marker() {} + cls_replica_log_item_marker(const string& name, const utime_t& time) : + item_name(name), item_timestamp(time) {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(item_name, bl); + ::encode(item_timestamp, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(item_name, bl); + ::decode(item_timestamp, bl); + DECODE_FINISH(bl); + } + + void dump(Formatter *f) const; + static void generate_test_instances(std::list<cls_replica_log_item_marker*>& ls); +}; +WRITE_CLASS_ENCODER(cls_replica_log_item_marker) + +struct cls_replica_log_progress_marker { + string entity_id; // the name of the entity setting the progress marker + string position_marker; // represents a log listing position on the master + utime_t position_time; // the timestamp associated with the position marker + std::list<cls_replica_log_item_marker> items; /* any items not caught up + to the position marker*/ + + cls_replica_log_progress_marker() {} + cls_replica_log_progress_marker(const string& entity, const string& marker, + const utime_t& time ) : + entity_id(entity), position_marker(marker), + position_time(time) {} + cls_replica_log_progress_marker(const string& entity, const string& marker, + const utime_t& time, + const std::list<cls_replica_log_item_marker> b) : + entity_id(entity), position_marker(marker), + position_time(time), + items(b) {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(entity_id, bl); + ::encode(position_marker, bl); + ::encode(position_time, bl); + ::encode(items, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(entity_id, bl); + ::decode(position_marker, bl); + ::decode(position_time, bl); + ::decode(items, bl); + DECODE_FINISH(bl); + } + + void dump(Formatter *f) const; + static void generate_test_instances(std::list<cls_replica_log_progress_marker*>& ls); +}; +WRITE_CLASS_ENCODER(cls_replica_log_progress_marker) + +class cls_replica_log_bound { + /** + * Right now, we are lazy and only support a single marker at a time. In the + * future, we might support more than one, so the interface is designed to + * let that work. + */ + string position_marker; // represents a log listing position on the master + utime_t position_time; // the timestamp associated with the position marker + bool marker_exists; // has the marker been set? + cls_replica_log_progress_marker marker; // the status of the current locker + +public: + cls_replica_log_bound() : marker_exists(false) {} + + int update_marker(const cls_replica_log_progress_marker& new_mark) { + // only one marker at a time right now + if (marker_exists && (marker.entity_id != new_mark.entity_id)) { + return -EEXIST; + } + // can't go backwards with our one marker! + if (marker_exists && (marker.position_time > new_mark.position_time)) { + return -EINVAL; + } + + marker = new_mark; + position_marker = new_mark.position_marker; + position_time = new_mark.position_time; + marker_exists = true; + // hey look, updating is idempotent; did you notice that? + return 0; + } + + int delete_marker(const string& entity_id) { + if (marker_exists) { + // ENOENT if our marker doesn't match the passed ID + if (marker.entity_id != entity_id) { + return -ENOENT; + } + // you can't delete it if there are unclean entries + if (!marker.items.empty()) { + return -ENOTEMPTY; + } + } + + marker_exists = false; + marker = cls_replica_log_progress_marker(); + // hey look, deletion is idempotent! Hurray. + return 0; + } + + std::string get_lowest_marker_bound() { + return position_marker; + } + + utime_t get_lowest_time_bound() { + return position_time; + } + + utime_t get_oldest_time() { + utime_t oldest = position_time; + list<cls_replica_log_item_marker>::const_iterator i; + for ( i = marker.items.begin(); i != marker.items.end(); ++i) { + if (i->item_timestamp < oldest) + oldest = i->item_timestamp; + } + return oldest; + } + + void get_markers(list<cls_replica_log_progress_marker>& ls) { + if (marker_exists) { + ls.push_back(marker); + } + } + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(position_marker, bl); + ::encode(position_time, bl); + ::encode(marker_exists, bl); + if (marker_exists) { + ::encode(marker, bl); + } + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(position_marker, bl); + ::decode(position_time, bl); + ::decode(marker_exists, bl); + if (marker_exists) { + ::decode(marker, bl); + } + DECODE_FINISH(bl); + } + + void dump(Formatter *f) const; + static void generate_test_instances(std::list<cls_replica_log_bound*>& ls); +}; +WRITE_CLASS_ENCODER(cls_replica_log_bound); + +#endif /* CLS_REPLICA_LOG_TYPES_H_ */ diff --git a/src/test/encoding/types.h b/src/test/encoding/types.h index a1d2773a946..263c774addc 100644 --- a/src/test/encoding/types.h +++ b/src/test/encoding/types.h @@ -236,6 +236,11 @@ TYPE(cls_lock_get_info_op) TYPE(cls_lock_get_info_reply) TYPE(cls_lock_list_locks_reply) +#include "cls/replica_log/cls_replica_log_types.h" +TYPE(cls_replica_log_item_marker) +TYPE(cls_replica_log_progress_marker) +TYPE(cls_replica_log_bound) + // --- messages --- #include "messages/MAuth.h" |