-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support ads bpf map lookup all #827
Conversation
How to reproduce? And the proto gen seems outdated, you can re run |
For the 1st question: you can checkout to my branch and run the newly added unit test |
FYI: struct element_list_node* deserial_lookup_all_elems(const void* msg_desciptor) {
int ret, err;
struct element_list_node* value_list_head = NULL;
const char* map_name = NULL;
struct op_context context = {.inner_map_object = NULL};
const ProtobufCMessageDescriptor* desc;
struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0};
int map_fd, outter_fd = 0, inner_fd = 0;
unsigned int id, outter_id = 0, inner_id = 0;
if (msg_desciptor == NULL)
return NULL;
desc = (ProtobufCMessageDescriptor*)msg_desciptor;
if (desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC)
return NULL;
map_name = desc->short_name;
ret = get_map_ids(map_name, &id, &outter_id, &inner_id);
if (ret)
return NULL;
ret = get_map_fd_info(id, &map_fd, &info);
if (ret < 0) {
LOG_ERR("invalid MAP_ID: %d\n", id);
return NULL;
}
ret = get_map_fd_info(inner_id, &inner_fd, &inner_info);
ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info);
if (ret < 0 || map_info_check(&outter_info, &inner_info))
goto end;
init_op_context(context, NULL, NULL, desc, outter_fd, map_fd, &outter_info,
&inner_info, &info);
value_list_head = create_struct_list(&context, &err);
if (err != 0) {
LOG_ERR("create_struct_list failed, err = %d", err);
deserial_free_elem_list(value_list_head);
value_list_head = NULL;
}
end:
if (context.key != NULL)
free(context.key);
if (map_fd > 0)
close(map_fd);
if (outter_fd > 0)
close(outter_fd);
if (inner_fd > 0)
close(inner_fd);
return value_list_head;
} |
pkg/cache/v2/maps/cluster.go
Outdated
|
||
cMsg := C.deserial_lookup_all_elems(unsafe.Pointer(&C.cluster__cluster__descriptor)) | ||
if cMsg == nil { | ||
return nil, fmt.Errorf("ClusterLookupAll deserial_lookup_all_elems failed") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return nil, fmt.Errorf("ClusterLookupAll deserial_lookup_all_elems failed") | |
return nil, fmt.Error("ClusterLookupAll deserial_lookup_all_elems failed") |
pkg/cache/v2/maps/cluster.go
Outdated
@@ -76,6 +76,35 @@ func ClusterLookup(key string, value *cluster_v2.Cluster) error { | |||
return err | |||
} | |||
|
|||
func ClusterLookupAll() ([]*cluster_v2.Cluster, error) { | |||
var ( | |||
err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:No need to define variables in advance
We can implement for the workload map first, which is simpler |
yes, that can be done by using the bpf go user space method. for the ads map, i've implement a common method for looking up all keys of a given bpf map, which will return a linked list. We can then use it to implement |
Signed-off-by: [email protected] <[email protected]>
Signed-off-by: [email protected] <[email protected]>
197164a
to
e50a459
Compare
FInished all, cc @hzxuzhonghu @YaoZengzeng |
a3db1a0
to
e8c4aa2
Compare
Signed-off-by: [email protected] <[email protected]>
e8c4aa2
to
2a341ae
Compare
#define PRINTF(fmt, args...) \ | ||
do { \ | ||
printf(fmt, ##args); \ | ||
fflush(stdout); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without fflush we cannot see the log.
the c printf uses a buffer.
I met this when i am debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally lg, what does the output look like
will add a ut |
Signed-off-by: [email protected] <[email protected]>
22db770
to
a531634
Compare
while (!bpf_map_get_next_key(ctx->curr_fd, prev_key, ctx->key)) { | ||
prev_key = ctx->key; | ||
|
||
value = create_struct(ctx, err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When create_struct
returns error, value may not be NULL. create_struct
needs to be optimized. When an error is returned, the value is released in the function instead of depending on the caller. Currently, leakage may occur in create_struct_list
.
value = create_struct(ctx, err); | ||
if (*err != 0) { | ||
LOG_ERR("create_struct failed, err = %d\n", err); | ||
deserial_free_elem_list(elem_list_head); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an error occurs, resources must be reclaimed and returned in a unified manner. The recommended format is as follows:
while (!bpf_map_get_next_key(ctx->curr_fd, prev_key, ctx->key)) {
value = create_struct(ctx, err);
if (*err != 0)
break;
......
struct element_list_node *new_node = (struct element_list_node *)calloc(1, sizeof(struct element_list_node));
if (!new_node) {
*err = -1;
break;
}
.......
}
if (*err) {
deserial_free_elem_list(elem_list_head);
return NULL;
}
return elem_list_head;
deserial_free_elem_list(elem_list_head); | ||
return NULL; | ||
} | ||
new_node->elem = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are basic operations for updating list. It is recommended that you encapsulate them into independent functions or macros or call existing libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, will modify it.
/lgtm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should support dump this from kmeshctl now
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: hzxuzhonghu The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
feature
What this PR does / why we need it:
support cluster lookup all for dump all the kv of bpf map.
It's for #820
i've met some problem in developing, seems to be related to the deserialization problem(#702 ) talked about before:
i update cluster 1 here, but the lookup and the newly written lookupall both got empty cluster name.
the output is:
lookup: cluster: api_status:UPDATE connect_timeout:1, api_status:UPDATE name:"ut-cluster-2" connect_timeout:1
ut-cluster-2
is shown, butut-cluster-1
does not work.If we only define
Name
field, the test will even panic.Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?: