Skip to content
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

Merged
merged 5 commits into from
Sep 25, 2024

Conversation

Okabe-Rintarou-0
Copy link
Member

@Okabe-Rintarou-0 Okabe-Rintarou-0 commented Sep 8, 2024

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:
image

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, but ut-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?:


@hzxuzhonghu
Copy link
Member

i've met some problem in developing, seems to be related to the deserialization problem talked about before:

How to reproduce? And the proto gen seems outdated, you can re run make gen

@Okabe-Rintarou-0
Copy link
Member Author

Okabe-Rintarou-0 commented Sep 9, 2024

i've met some problem in developing, seems to be related to the deserialization problem talked about before:

How to reproduce? And the proto gen seems outdated, you can re run make gen

For the 1st question: you can checkout to my branch and run the newly added unit test TestClusterLookupAll.
For the 2nd question: It's because i did not format the c code.

@Okabe-Rintarou-0
Copy link
Member Author

Okabe-Rintarou-0 commented Sep 9, 2024

FYI:
In this pr, i mainly add a new function to lookup all elements. it will return a linked list(since the length can be dynamic)

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;
}


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")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return nil, fmt.Errorf("ClusterLookupAll deserial_lookup_all_elems failed")
return nil, fmt.Error("ClusterLookupAll deserial_lookup_all_elems failed")

@@ -76,6 +76,35 @@ func ClusterLookup(key string, value *cluster_v2.Cluster) error {
return err
}

func ClusterLookupAll() ([]*cluster_v2.Cluster, error) {
var (
err error
Copy link
Collaborator

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

@kmesh-bot kmesh-bot added size/L and removed size/XXL labels Sep 9, 2024
Copy link

codecov bot commented Sep 9, 2024

Codecov Report

Attention: Patch coverage is 38.29787% with 58 lines in your changes missing coverage. Please review.

Project coverage is 53.67%. Comparing base (d5a4c00) to head (e3c37f8).
Report is 59 commits behind head on main.

Files with missing lines Patch % Lines
pkg/cache/v2/maps/authz.go 0.00% 20 Missing ⚠️
pkg/cache/v2/maps/route.go 0.00% 20 Missing ⚠️
pkg/status/status_server.go 33.33% 5 Missing and 3 partials ⚠️
pkg/cache/v2/maps/cluster.go 80.00% 2 Missing and 2 partials ⚠️
pkg/cache/v2/maps/listener.go 80.00% 2 Missing and 2 partials ⚠️
pkg/bpf/bpf_kmesh_l4.go 0.00% 2 Missing ⚠️
Files with missing lines Coverage Δ
pkg/cache/v2/cluster.go 38.88% <ø> (+4.57%) ⬆️
pkg/cache/v2/listener.go 58.73% <ø> (+9.39%) ⬆️
pkg/cache/v2/route.go 61.11% <ø> (+11.11%) ⬆️
pkg/bpf/bpf_kmesh_l4.go 0.00% <0.00%> (ø)
pkg/cache/v2/maps/cluster.go 60.52% <80.00%> (+6.95%) ⬆️
pkg/cache/v2/maps/listener.go 45.65% <80.00%> (+9.54%) ⬆️
pkg/status/status_server.go 42.30% <33.33%> (+4.11%) ⬆️
pkg/cache/v2/maps/authz.go 0.00% <0.00%> (ø)
pkg/cache/v2/maps/route.go 30.26% <0.00%> (-10.81%) ⬇️

... and 6 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ad3d9cd...e3c37f8. Read the comment docs.

@Okabe-Rintarou-0 Okabe-Rintarou-0 changed the title [WIP]support cluster lookup all [WIP]support ads bpf map lookup all Sep 10, 2024
@hzxuzhonghu
Copy link
Member

We can implement for the workload map first, which is simpler

@Okabe-Rintarou-0
Copy link
Member Author

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 LookupAll function for all ads bpf map.

@kmesh-bot kmesh-bot added size/XXL and removed size/L labels Sep 19, 2024
@Okabe-Rintarou-0 Okabe-Rintarou-0 changed the title [WIP]support ads bpf map lookup all Support ads bpf map lookup all Sep 20, 2024
@Okabe-Rintarou-0
Copy link
Member Author

FInished all, cc @hzxuzhonghu @YaoZengzeng

#define PRINTF(fmt, args...) \
do { \
printf(fmt, ##args); \
fflush(stdout); \
Copy link
Member

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

Copy link
Member Author

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.

Copy link
Member

@hzxuzhonghu hzxuzhonghu left a 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

@Okabe-Rintarou-0
Copy link
Member Author

Generally lg, what does the output look like

will add a ut

@kmesh-bot kmesh-bot added size/XL and removed size/L labels Sep 20, 2024
while (!bpf_map_get_next_key(ctx->curr_fd, prev_key, ctx->key)) {
prev_key = ctx->key;

value = create_struct(ctx, err);
Copy link
Contributor

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);
Copy link
Contributor

@nlgwcy nlgwcy Sep 22, 2024

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;
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will modify it.

@nlgwcy
Copy link
Contributor

nlgwcy commented Sep 25, 2024

/lgtm

Copy link
Member

@hzxuzhonghu hzxuzhonghu left a 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

@kmesh-bot
Copy link
Collaborator

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kmesh-bot kmesh-bot merged commit 48d3608 into kmesh-net:main Sep 25, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants