aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--grpc.def1
-rw-r--r--include/grpc/grpc.h4
-rw-r--r--src/core/ext/filters/client_channel/client_channel_channelz.h7
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.cc5
-rw-r--r--src/core/lib/channel/channelz.cc39
-rw-r--r--src/core/lib/channel/channelz.h20
-rw-r--r--src/core/lib/channel/channelz_registry.cc12
-rw-r--r--src/core/lib/surface/server.cc31
-rw-r--r--src/core/lib/surface/server.h9
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h3
-rw-r--r--test/core/end2end/tests/channelz.cc4
-rw-r--r--test/core/surface/public_headers_must_be_c89.c1
13 files changed, 122 insertions, 16 deletions
diff --git a/grpc.def b/grpc.def
index 345c0a786c..4f22d077c8 100644
--- a/grpc.def
+++ b/grpc.def
@@ -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);