Skip to content

Replace popen('uname -ap') with uname() syscall in bvar kernel_version - #3517

Open
weim0000 wants to merge 1 commit into
apache:masterfrom
weim0000:fix_uname
Open

Replace popen('uname -ap') with uname() syscall in bvar kernel_version#3517
weim0000 wants to merge 1 commit into
apache:masterfrom
weim0000:fix_uname

Conversation

@weim0000

@weim0000 weim0000 commented Sep 3, 2026

Copy link
Copy Markdown

What problem does this PR solve?

Problem Summary:

When a brpc server has allocated a large amount of memory, the first request to the /vars endpoint can cause a significant latency stall. This is because the kernel_version bvar variable is lazily initialized on first access, and its constructor calls popen("uname -ap") to read the kernel version.

Internally, popen() calls fork() to spawn a child process. On Linux, fork() needs to duplicate the parent process's page tables. For a server with a large memory footprint (e.g., tens of GBs), this can take hundreds of milliseconds or even longer, effectively blocking the bthread that handles the /vars request.

This caused a production incident in our environment, where the service appeared to hang when the monitoring system first scraped the /vars endpoint after the server had been running for a while with heavy memory usage.

What is changed and the side effects?

Changed:

Replace butil::read_command_output(oss, "uname -ap") (which shells out via popenforkexec) with the POSIX uname() syscall in src/bvar/default_variables.cpp. The uname() syscall reads the same kernel information directly via struct utsname, without creating any child process. The output format remains equivalent to uname -ap. A unit test is added in test/bvar_variable_unittest.cpp.

Side effects:

  • Performance effects: Eliminates the fork() overhead entirely. The uname() syscall completes in microseconds regardless of the process's memory usage, whereas the previous popen() approach could stall for 100ms+ on large-memory processes.

  • Breaking backward compatibility: No. The output format of the kernel_version bvar remains the same.

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.

1 participant