diff options
-rw-r--r-- | grpc.def | 1 | ||||
-rw-r--r-- | include/grpc/grpc.h | 4 | ||||
-rw-r--r-- | src/core/ext/filters/client_channel/client_channel_channelz.h | 7 | ||||
-rw-r--r-- | src/core/ext/transport/chttp2/server/chttp2_server.cc | 5 | ||||
-rw-r--r-- | src/core/lib/channel/channelz.cc | 39 | ||||
-rw-r--r-- | src/core/lib/channel/channelz.h | 20 | ||||
-rw-r--r-- | src/core/lib/channel/channelz_registry.cc | 12 | ||||
-rw-r--r-- | src/core/lib/surface/server.cc | 31 | ||||
-rw-r--r-- | src/core/lib/surface/server.h | 9 | ||||
-rw-r--r-- | src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 | ||||
-rw-r--r-- | src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 | ||||
-rw-r--r-- | test/core/end2end/tests/channelz.cc | 4 | ||||
-rw-r--r-- | test/core/surface/public_headers_must_be_c89.c | 1 |
13 files changed, 122 insertions, 16 deletions
@@ -75,6 +75,7 @@ EXPORTS grpc_resource_quota_arg_vtable grpc_channelz_get_top_channels grpc_channelz_get_servers + grpc_channelz_get_server_sockets grpc_channelz_get_channel grpc_channelz_get_subchannel grpc_channelz_get_socket diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index a9beee1c9e..02ab6e8ba4 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -503,6 +503,10 @@ GRPCAPI char* grpc_channelz_get_top_channels(intptr_t start_channel_id); /* Gets all servers that exist in the process. */ GRPCAPI char* grpc_channelz_get_servers(intptr_t start_server_id); +/* Gets all server sockets that exist in the server. */ +GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id, + intptr_t start_socket_id); + /* Returns a single Channel, or else a NOT_FOUND code. The returned string is allocated and must be freed by the application. */ GRPCAPI char* grpc_channelz_get_channel(intptr_t channel_id); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 8ce331e529..8a5c3e7e5e 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -25,17 +25,10 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/gprpp/inlined_vector.h" typedef struct grpc_subchannel grpc_subchannel; namespace grpc_core { - -// TODO(ncteisen), this only contains the uuids of the children for now, -// since that is all that is strictly needed. In a future enhancement we will -// add human readable names as in the channelz.proto -typedef InlinedVector<intptr_t, 10> ChildRefsList; - namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index b95baa9191..1147ad1485 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -135,9 +135,10 @@ static void on_handshake_done(void* arg, grpc_error* error) { if (args->endpoint != nullptr) { grpc_transport* transport = grpc_create_chttp2_transport(args->args, args->endpoint, false); - grpc_server_setup_transport( + grpc_server_setup_transport_with_socket_uuid( connection_state->svr_state->server, transport, - connection_state->accepting_pollset, args->args); + connection_state->accepting_pollset, args->args, + grpc_chttp2_transport_get_socket_uuid(transport)); // Use notify_on_receive_settings callback to enforce the // handshake deadline. connection_state->transport = diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 339c827525..c384f99833 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -36,6 +36,7 @@ #include "src/core/lib/iomgr/error.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" #include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -149,11 +150,45 @@ RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } -ServerNode::ServerNode(size_t channel_tracer_max_nodes) - : BaseNode(EntityType::kServer), trace_(channel_tracer_max_nodes) {} +ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) + : BaseNode(EntityType::kServer), + server_(server), + trace_(channel_tracer_max_nodes) {} ServerNode::~ServerNode() {} +char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + ChildRefsList socket_refs; + // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is + // reserved). However, we want to support requests coming in with + // start_server_id=0, which signifies "give me everything." + size_t start_idx = start_socket_id == 0 ? 0 : start_socket_id - 1; + grpc_server_populate_server_sockets(server_, &socket_refs, start_idx); + if (!socket_refs.empty()) { + // create list of socket refs + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); + for (size_t i = 0; i < socket_refs.size(); ++i) { + json_iterator = + grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", + socket_refs[i]); + } + } + // For now we do not have any pagination rules. In the future we could + // pick a constant for max_channels_sent for a GetServers request. + // Tracking: https://github.com/grpc/grpc/issues/16019. + json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, + GRPC_JSON_TRUE, false); + char* json_str = grpc_json_dump_to_string(top_level_json, 0); + grpc_json_destroy(top_level_json); + return json_str; +} + grpc_json* ServerNode::RenderJson() { // We need to track these three json objects to build our object grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index d949e1b449..4b9040c0f1 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -24,6 +24,7 @@ #include <grpc/grpc.h> #include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -49,6 +50,12 @@ #define GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT 0 namespace grpc_core { + +// TODO(ncteisen), this only contains the uuids of the children for now, +// since that is all that is strictly needed. In a future enhancement we will +// add human readable names as in the channelz.proto +typedef InlinedVector<intptr_t, 10> ChildRefsList; + namespace channelz { namespace testing { @@ -76,6 +83,12 @@ class BaseNode : public RefCounted<BaseNode> { // All children must implement this function. virtual grpc_json* RenderJson() GRPC_ABSTRACT; + // Fat interface for functionality that will only ever be called on Servers. + // All other channelz entities will assert false. + virtual char* RenderServerSockets(intptr_t start_socket_id) { + GPR_ASSERT(false); + } + // Renders the json and returns allocated string that must be freed by the // caller. char* RenderJsonString(); @@ -181,11 +194,15 @@ class ChannelNode : public BaseNode { // Handles channelz bookkeeping for servers class ServerNode : public BaseNode { public: - explicit ServerNode(size_t channel_tracer_max_nodes); + explicit ServerNode(grpc_server* server, size_t channel_tracer_max_nodes); ~ServerNode() override; grpc_json* RenderJson() override; + // Server overrides this functionality to populate the JSON with + // the sockets it owns. + char* RenderServerSockets(intptr_t start_socket_id) override; + // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { trace_.AddTraceEvent(severity, data); @@ -201,6 +218,7 @@ class ServerNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: + grpc_server* server_; CallCountingHelper call_counter_; ChannelTrace trace_; }; diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 841f1c6104..820ed7bf8d 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -160,6 +160,18 @@ char* grpc_channelz_get_servers(intptr_t start_server_id) { return grpc_core::channelz::ChannelzRegistry::GetServers(start_server_id); } +char* grpc_channelz_get_server_sockets(intptr_t server_id, + intptr_t start_socket_id) { + grpc_core::channelz::BaseNode* server_node = + grpc_core::channelz::ChannelzRegistry::Get(server_id); + if (server_node == nullptr || + server_node->type() != + grpc_core::channelz::BaseNode::EntityType::kServer) { + return nullptr; + } + return server_node->RenderServerSockets(start_socket_id); +} + char* grpc_channelz_get_channel(intptr_t channel_id) { grpc_core::channelz::BaseNode* channel_node = grpc_core::channelz::ChannelzRegistry::Get(channel_id); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 1dd583c3f7..5482319f79 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -104,6 +104,7 @@ struct channel_data { uint32_t registered_method_max_probes; grpc_closure finish_destroy_channel_closure; grpc_closure channel_connectivity_changed; + uint32_t socket_uuid; }; typedef struct shutdown_tag { @@ -1015,7 +1016,7 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { arg, {GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT, 0, INT_MAX}); server->channelz_server = grpc_core::MakeRefCounted<grpc_core::channelz::ServerNode>( - trace_events_per_node); + server, trace_events_per_node); server->channelz_server->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Server created")); @@ -1116,9 +1117,9 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, *pollsets = server->pollsets; } -void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, - grpc_pollset* accepting_pollset, - const grpc_channel_args* args) { +void grpc_server_setup_transport_with_socket_uuid( + grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset, + const grpc_channel_args* args, intptr_t socket_uuid) { size_t num_registered_methods; size_t alloc; registered_method* rm; @@ -1138,6 +1139,7 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, chand->server = s; server_ref(s); chand->channel = channel; + chand->socket_uuid = socket_uuid; size_t cq_idx; for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) { @@ -1212,6 +1214,27 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, grpc_transport_perform_op(transport, op); } +void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, + grpc_pollset* accepting_pollset, + const grpc_channel_args* args) { + grpc_server_setup_transport_with_socket_uuid(s, transport, accepting_pollset, + args, 0); +} + +void grpc_server_populate_server_sockets( + grpc_server* s, grpc_core::ChildRefsList* server_sockets, + intptr_t start_idx) { + gpr_mu_lock(&s->mu_global); + channel_data* c = nullptr; + for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { + intptr_t socket_uuid = c->socket_uuid; + if (socket_uuid >= start_idx) { + server_sockets->push_back(socket_uuid); + } + } + gpr_mu_unlock(&s->mu_global); +} + void done_published_shutdown(void* done_arg, grpc_cq_completion* storage) { (void)done_arg; gpr_free(storage); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 0196743ff9..62d444e57e 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -47,6 +47,15 @@ void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args); +void grpc_server_setup_transport_with_socket_uuid( + grpc_server* server, grpc_transport* transport, + grpc_pollset* accepting_pollset, const grpc_channel_args* args, + intptr_t socket_uuid); + +void grpc_server_populate_server_sockets( + grpc_server* server, grpc_core::ChildRefsList* server_sockets, + intptr_t start_idx); + grpc_core::channelz::ServerNode* grpc_server_get_channelz_node( grpc_server* server); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 1e7d7f687f..5dd4386888 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -98,6 +98,7 @@ grpc_resource_quota_set_max_threads_type grpc_resource_quota_set_max_threads_imp grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import; grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; grpc_channelz_get_servers_type grpc_channelz_get_servers_import; +grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import; grpc_channelz_get_channel_type grpc_channelz_get_channel_import; grpc_channelz_get_subchannel_type grpc_channelz_get_subchannel_import; grpc_channelz_get_socket_type grpc_channelz_get_socket_import; @@ -355,6 +356,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_resource_quota_arg_vtable_import = (grpc_resource_quota_arg_vtable_type) GetProcAddress(library, "grpc_resource_quota_arg_vtable"); grpc_channelz_get_top_channels_import = (grpc_channelz_get_top_channels_type) GetProcAddress(library, "grpc_channelz_get_top_channels"); grpc_channelz_get_servers_import = (grpc_channelz_get_servers_type) GetProcAddress(library, "grpc_channelz_get_servers"); + grpc_channelz_get_server_sockets_import = (grpc_channelz_get_server_sockets_type) GetProcAddress(library, "grpc_channelz_get_server_sockets"); grpc_channelz_get_channel_import = (grpc_channelz_get_channel_type) GetProcAddress(library, "grpc_channelz_get_channel"); grpc_channelz_get_subchannel_import = (grpc_channelz_get_subchannel_type) GetProcAddress(library, "grpc_channelz_get_subchannel"); grpc_channelz_get_socket_import = (grpc_channelz_get_socket_type) GetProcAddress(library, "grpc_channelz_get_socket"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index ed4b6264b0..ec6e400089 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -269,6 +269,9 @@ extern grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import typedef char*(*grpc_channelz_get_servers_type)(intptr_t start_server_id); extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import; #define grpc_channelz_get_servers grpc_channelz_get_servers_import +typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id); +extern grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import; +#define grpc_channelz_get_server_sockets grpc_channelz_get_server_sockets_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); extern grpc_channelz_get_channel_type grpc_channelz_get_channel_import; #define grpc_channelz_get_channel grpc_channelz_get_channel_import diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 40a0370f0e..2711d87f17 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -258,6 +258,10 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); + json = channelz_server->RenderServerSockets(0); + GPR_ASSERT(nullptr != strstr(json, "\"socketRef\":")); + gpr_free(json); + end_test(&f); config.tear_down_data(&f); } diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 3ebdb88a08..4640b8e4ca 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -137,6 +137,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable); printf("%lx", (unsigned long) grpc_channelz_get_top_channels); printf("%lx", (unsigned long) grpc_channelz_get_servers); + printf("%lx", (unsigned long) grpc_channelz_get_server_sockets); printf("%lx", (unsigned long) grpc_channelz_get_channel); printf("%lx", (unsigned long) grpc_channelz_get_subchannel); printf("%lx", (unsigned long) grpc_channelz_get_socket); |