Skip to content

report hung radostrace ops on interrupt#92

Open
zhhuabj wants to merge 1 commit into
taodd:mainfrom
zhhuabj:detect_hang_ops_with_radostrace
Open

report hung radostrace ops on interrupt#92
zhhuabj wants to merge 1 commit into
taodd:mainfrom
zhhuabj:detect_hang_ops_with_radostrace

Conversation

@zhhuabj
Copy link
Copy Markdown
Contributor

@zhhuabj zhhuabj commented May 13, 2026

Handle SIGINT without exiting immediately so radostrace can dump operations still pending in the BPF ops map before cleanup.

  • add SIGINT state tracking in radostrace
  • iterate the ops BPF map and print unfinished operations
  • include stuck duration, client, tid, target osd, object, and rw mode
  • return cleanly after interrupt/timeout-triggered shutdown

@zhhuabj
Copy link
Copy Markdown
Contributor Author

zhhuabj commented May 13, 2026

test result - https://paste.ubuntu.com/p/FvpMC8XsCX/

Comment thread src/radostrace.cc Outdated
clog << "process killed" << endl;
got_sigint = 1;
} else {
exit(signum);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

exit(3) isn't a async-signal-safe function: https://www.man7.org/linux/man-pages/man7/signal-safety.7.html

better to use _exit() instead.

The same concern is applicable for clog too. We need to review "signal safety" across the codease. But that can be done separately later.

Comment thread src/radostrace.cc Outdated
int found = 0;

memset(&key, 0, sizeof(key));
while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

To get the first key that's not in the map, bpf_map_get_next_key needs to be called with NULL as key. But a valid "key" is passed now (key is zero-initalized but it's not NULL), so this is likely to miss the correct first key.

struct client_op_k *cur = NULL;
while (bpf_map_get_next_key(map_fd, cur, &next_key) == 0) {
    if (bpf_map_lookup_elem(map_fd, &next_key, &val) == 0) {
        ...
    }
    key = next_key;
    cur = &key;
}

would fix it.

@pponnuvel
Copy link
Copy Markdown
Collaborator

I also think "hung ops" better describes than "hang ops", so suggest name changes as such.

@zhhuabj zhhuabj force-pushed the detect_hang_ops_with_radostrace branch 2 times, most recently from aa20743 to b05de17 Compare May 14, 2026 14:16
Copy link
Copy Markdown
Owner

@taodd taodd left a comment

Choose a reason for hiding this comment

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

We also need to add a test to deliberately cause a hang Op

Comment thread src/radostrace.bpf.c Outdated
}
if (name_len > 0) {
bpf_probe_read_user(val->object_name, name_len, (void *)name_base);
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Let's keep the original code here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

Comment thread src/radostrace.cc
@zhhuabj zhhuabj force-pushed the detect_hang_ops_with_radostrace branch from b05de17 to 762503a Compare May 19, 2026 04:10
@zhhuabj
Copy link
Copy Markdown
Contributor Author

zhhuabj commented May 19, 2026

test result in microceph - https://paste.ubuntu.com/p/9NqMgrcz4K/
test result in openstack - https://paste.ubuntu.com/p/Dtg36rVNx8/

@taodd
Copy link
Copy Markdown
Owner

taodd commented May 19, 2026

Thanks @zhhuabj

  1. The incomplete operations are missing the pid value, we can get the pid value from the send_op function instead of the finish_op function.
  2. To simplify the output, instead of naming the new column as "status" and filled with words "complete" and "incomplete", we can name the column to "Complete" with value of "1" or "0" to indicate whether the operation is complete or not.
  3. Another suggestion is that we don't need to separate the output between complete and incomplete ops. Put all of them together would be fine and easy to process by the analyzer

@taodd
Copy link
Copy Markdown
Owner

taodd commented May 19, 2026

Also, the patch needs to be rebased

@zhhuabj zhhuabj force-pushed the detect_hang_ops_with_radostrace branch from 762503a to f67ffe2 Compare May 22, 2026 10:49
@zhhuabj
Copy link
Copy Markdown
Contributor Author

zhhuabj commented May 22, 2026

Thanks @zhhuabj

  1. The incomplete operations are missing the pid value, we can get the pid value from the send_op function instead of the finish_op function.
  2. To simplify the output, instead of naming the new column as "status" and filled with words "complete" and "incomplete", we can name the column to "Complete" with value of "1" or "0" to indicate whether the operation is complete or not.
  3. Another suggestion is that we don't need to separate the output between complete and incomplete ops. Put all of them together would be fine and easy to process by the analyzer

Hi @dongdong, Thank you for the feedback! I've addressed all three suggestions:

1, pid from send_op: Moved val->pid = get_pid() to uprobe_send_op so incomplete ops also have a valid pid.
2, Complete column with 0/1: Renamed the status column to Complete and replaced "complete"/"incomplete" strings with "1"/"0" for easier filtering.
3, Unified output: Merged complete and incomplete ops into a single output stream — completed ops print with Complete=1 as they arrive, incomplete ops print with Complete=0 at flush time.

and here is the latest test result - https://paste.ubuntu.com/p/3sSGqb3WGv/

Previously, radostrace silently discarded any ops that were in-flight
(tracked in the BPF ops map via _send_op) but had not yet completed
(_finish_op not yet fired) when the session ended.  This made it
impossible for users to identify hung or slow operations when
interrupting a trace or when a timeout expired.

This commit adds a report_hung_ops() function that iterates the BPF
ops hash map at exit and prints any remaining entries as "incomplete"
rows, using the same tabular format as the normal "complete" output.

Signed-off-by: Zhang Hua <joshua.zhang@canonical.com>
@zhhuabj zhhuabj force-pushed the detect_hang_ops_with_radostrace branch from f67ffe2 to cf846e9 Compare May 22, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants