for f in \
api_aio api_io api_list api_lock api_misc \
api_tier api_pool api_snapshots api_stat api_watch_notify api_cmd \
+ api_service \
api_c_write_operations \
api_c_read_operations \
list_parallel \
CEPH_RADOS_API int rados_monitor_log2(rados_t cluster, const char *level,
rados_log_callback2_t cb, void *arg);
+
+/**
+ * register daemon instance for a service
+ *
+ * Register us as a daemon providing a particular service. We identify
+ * the service (e.g., 'rgw') and our instance name (e.g., 'rgw.$hostname').
+ * The metadata is a map of keys and values with arbitrary static metdata
+ * for this instance. The encoding is a series of NULL-terminated strings,
+ * alternating key names and values, terminating with an empty key name.
+ * For example, "foo\0bar\0this\0that\0\0" is the dict {foo=bar,this=that}.
+ *
+ * For the lifetime of the librados instance, regular beacons will be sent
+ * to the cluster to maintain our registration in the service map.
+ *
+ * @param cluster handle
+ * @param service service name
+ * @param daemon deamon instance name
+ * @param metadata_dict static daemon metadata dict
+ */
+CEPH_RADOS_API int rados_service_register(
+ rados_t cluster,
+ const char *service,
+ const char *daemon,
+ const char *metadata_dict);
+
+/**
+ * update daemon status
+ *
+ * Update our mutable status information in the service map.
+ *
+ * The status dict is encoded the same way the daemon metadata is encoded
+ * for rados_service_register. For example, "foo\0bar\0this\0that\0\0" is
+ * {foo=bar,this=that}.
+ *
+ * @param cluster rados cluster handle
+ * @param status_dict status dict
+ */
+CEPH_RADOS_API int rados_service_update_status(
+ rados_t cluster,
+ const char *status_dict);
+
/** @} Mon/OSD/PG commands */
/*
int conf_set(const char *option, const char *value);
int conf_get(const char *option, std::string &val);
+ int service_daemon_register(
+ const std::string& service, ///< service name (e.g., 'rgw')
+ const std::string& name, ///< daemon name (e.g., 'gwfoo')
+ const std::map<std::string,std::string>& metadata); ///< static metadata about daemon
+ int service_daemon_update_status(
+ const std::map<std::string,std::string>& status);
+
int pool_create(const char *name);
int pool_create(const char *name, uint64_t auid);
int pool_create(const char *name, uint64_t auid, uint8_t crush_rule);
monclient.sub_want("mgrmap", 0, 0);
monclient.renew_subs();
+ if (service_daemon) {
+ ldout(cct, 10) << __func__ << " registering as " << service_name << "."
+ << daemon_name << dendl;
+ mgrclient.service_daemon_register(service_name, daemon_name,
+ daemon_metadata);
+ }
mgrclient.init();
objecter->set_client_incarnation(0);
m->put();
}
+
+int librados::RadosClient::service_daemon_register(
+ const std::string& service, ///< service name (e.g., 'rgw')
+ const std::string& name, ///< daemon name (e.g., 'gwfoo')
+ const std::map<std::string,std::string>& metadata)
+{
+ if (service_daemon) {
+ return -EEXIST;
+ }
+ if (service == "osd" ||
+ service == "mds" ||
+ service == "client" ||
+ service == "mon" ||
+ service == "mgr") {
+ // normal ceph entity types are not allowed!
+ return -EINVAL;
+ }
+ if (service.empty() || name.empty()) {
+ return -EINVAL;
+ }
+
+ ldout(cct,10) << __func__ << " " << service << "." << name << dendl;
+ service_daemon = true;
+ service_name = service;
+ daemon_name = name;
+ daemon_metadata.insert(metadata.begin(), metadata.end());
+
+ if (state == DISCONNECTED) {
+ return 0;
+ }
+ if (state == CONNECTING) {
+ return -EBUSY;
+ }
+ mgrclient.service_daemon_register(service_name, daemon_name,
+ daemon_metadata);
+ return 0;
+}
+
+int librados::RadosClient::service_daemon_update_status(
+ const std::map<std::string,std::string>& status)
+{
+ if (state != CONNECTED) {
+ return -ENOTCONN;
+ }
+ return mgrclient.service_daemon_update_status(status);
+}
void *log_cb_arg;
string log_watch;
+ bool service_daemon = false;
+ string daemon_name, service_name;
+ map<string,string> daemon_metadata;
+
int wait_for_osdmap();
public:
void get();
bool put();
void blacklist_self(bool set);
+
+ int service_daemon_register(
+ const std::string& service, ///< service name (e.g., 'rgw')
+ const std::string& name, ///< daemon name (e.g., 'gwfoo')
+ const std::map<std::string,std::string>& metadata); ///< static metadata about daemon
+ int service_daemon_update_status(
+ const std::map<std::string,std::string>& status);
};
#endif
return 0;
}
+int librados::Rados::service_daemon_register(
+ const std::string& service, ///< service name (e.g., 'rgw')
+ const std::string& name, ///< daemon name (e.g., 'gwfoo')
+ const std::map<std::string,std::string>& metadata) ///< static metadata about daemon
+{
+ return client->service_daemon_register(service, name, metadata);
+}
+
+int librados::Rados::service_daemon_update_status(
+ const std::map<std::string,std::string>& status)
+{
+ return client->service_daemon_update_status(status);
+}
+
int librados::Rados::pool_create(const char *name)
{
string str(name);
target_link_libraries(ceph_test_rados_api_lock
rados_a ${UNITTEST_LIBS} radostest)
+# ceph_test_rados_api_service
+add_executable(ceph_test_rados_api_service
+ service.cc
+ )
+set_target_properties(ceph_test_rados_api_service PROPERTIES COMPILE_FLAGS
+ ${UNITTEST_CXX_FLAGS})
+target_link_libraries(ceph_test_rados_api_service
+ rados_a global ${UNITTEST_LIBS} radostest)
+
# ceph_test_rados_api_tier
add_executable(ceph_test_rados_api_tier
tier.cc
--- /dev/null
+#include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
+#include "test/librados/test.h"
+#include "test/librados/TestCase.h"
+#include "include/stringify.h"
+
+#include <algorithm>
+#include <errno.h>
+#include "gtest/gtest.h"
+#include "test/unit.cc"
+
+using namespace librados;
+
+TEST(LibRadosServicePP, RegisterEarly) {
+ Rados cluster;
+ cluster.init("admin");
+ ASSERT_EQ(0, cluster.conf_read_file(NULL));
+ cluster.conf_parse_env(NULL);
+ string name = string("pid") + stringify(getpid());
+ ASSERT_EQ(0, cluster.service_daemon_register(
+ "laundry", name, {{"foo", "bar"}, {"this", "that"}}));
+ ASSERT_EQ(-EEXIST, cluster.service_daemon_register(
+ "laundry", name, {{"foo", "bar"}, {"this", "that"}}));
+ ASSERT_EQ(0, cluster.connect());
+ sleep(5);
+ cluster.shutdown();
+}
+
+TEST(LibRadosServicePP, RegisterLate) {
+ Rados cluster;
+ cluster.init("admin");
+ ASSERT_EQ(0, cluster.conf_read_file(NULL));
+ cluster.conf_parse_env(NULL);
+ ASSERT_EQ("", connect_cluster_pp(cluster));
+ string name = string("pid") + stringify(getpid());
+ ASSERT_EQ(0, cluster.service_daemon_register(
+ "laundry", name, {{"foo", "bar"}, {"this", "that"}}));
+}
+
+TEST(LibRadosServicePP, Status) {
+ Rados cluster;
+ cluster.init("admin");
+ ASSERT_EQ(0, cluster.conf_read_file(NULL));
+ cluster.conf_parse_env(NULL);
+ string name = string("pid") + stringify(getpid());
+ ASSERT_EQ(-ENOTCONN, cluster.service_daemon_update_status(
+ {{"testing", "starting"}}));
+ ASSERT_EQ(0, cluster.connect());
+ ASSERT_EQ(0, cluster.service_daemon_register(
+ "laundry", name, {{"foo", "bar"}, {"this", "that"}}));
+ for (int i=0; i<20; ++i) {
+ ASSERT_EQ(0, cluster.service_daemon_update_status({
+ {"testing", "running"},
+ {"count", stringify(i)}
+ }));
+ sleep(1);
+ }
+ cluster.shutdown();
+}