Commit ef9d4b8d authored by Teng Qin's avatar Teng Qin

Use ProcMountNSGuard in C API

This commit adds helper method in C API using `ProcMountNSGuard` to enter
and exit mount namespace, and use it in `libbpf.h`
parent 3bfc877a
...@@ -39,8 +39,8 @@ add_library(bcc-shared SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c ...@@ -39,8 +39,8 @@ add_library(bcc-shared SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c
set_target_properties(bcc-shared PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0) set_target_properties(bcc-shared PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0)
set_target_properties(bcc-shared PROPERTIES OUTPUT_NAME bcc) set_target_properties(bcc-shared PROPERTIES OUTPUT_NAME bcc)
add_library(bcc-loader-static STATIC libbpf.c perf_reader.c bcc_elf.c bcc_perf_map.c bcc_proc.c) add_library(bcc-loader-static STATIC libbpf.c perf_reader.c bcc_elf.c bcc_perf_map.c bcc_proc.c bcc_syms.cc)
add_library(bcc-static STATIC bpf_common.cc bpf_module.cc shared_table.cc bpffs_table.cc json_map_decl_visitor.cc table_storage.cc exported_files.cc bcc_syms.cc usdt_args.cc usdt.cc common.cc BPF.cc BPFTable.cc) add_library(bcc-static STATIC bpf_common.cc bpf_module.cc shared_table.cc bpffs_table.cc json_map_decl_visitor.cc table_storage.cc exported_files.cc usdt_args.cc usdt.cc common.cc BPF.cc BPFTable.cc)
set_target_properties(bcc-static PROPERTIES OUTPUT_NAME bcc) set_target_properties(bcc-static PROPERTIES OUTPUT_NAME bcc)
set(llvm_raw_libs bitwriter bpfcodegen irreader linker set(llvm_raw_libs bitwriter bpfcodegen irreader linker
......
...@@ -13,15 +13,11 @@ ...@@ -13,15 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <fcntl.h> #include <fcntl.h>
#include <sched.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
...@@ -393,97 +389,6 @@ void bcc_procutils_free(const char *ptr) { ...@@ -393,97 +389,6 @@ void bcc_procutils_free(const char *ptr) {
free((void *)ptr); free((void *)ptr);
} }
bool bcc_procutils_enter_mountns(int pid, struct ns_cookie *nc) {
char curnspath[4096];
char newnspath[4096];
int oldns = -1;
int newns = -1;
struct stat ons_stat;
struct stat nns_stat;
if (nc == NULL)
return false;
nc->nsc_oldns = -1;
nc->nsc_newns = -1;
if (snprintf(curnspath, 4096, "/proc/self/ns/mnt") == 4096) {
return false;
}
if (snprintf(newnspath, 4096, "/proc/%d/ns/mnt", pid) == 4096) {
return false;
}
if ((oldns = open(curnspath, O_RDONLY)) < 0) {
return false;
}
if ((newns = open(newnspath, O_RDONLY)) < 0) {
goto errout;
}
if (fstat(oldns, &ons_stat) < 0) {
goto errout;
}
if (fstat(newns, &nns_stat) < 0) {
goto errout;
}
/*
* Only switch to the new namespace if it doesn't match the existing
* namespace. This prevents us from getting an EPERM when trying to enter an
* identical namespace.
*/
if (ons_stat.st_ino == nns_stat.st_ino) {
goto errout;
}
if (setns(newns, CLONE_NEWNS) < 0) {
goto errout;
}
nc->nsc_oldns = oldns;
nc->nsc_newns = newns;
return true;
errout:
if (oldns > -1) {
(void) close(oldns);
}
if (newns > -1) {
(void) close(newns);
}
return false;
}
bool bcc_procutils_exit_mountns(struct ns_cookie *nc) {
bool rc = false;
if (nc == NULL)
return rc;
if (nc->nsc_oldns == -1 || nc->nsc_newns == -1)
return rc;
if (setns(nc->nsc_oldns, CLONE_NEWNS) == 0) {
rc = true;
}
if (nc->nsc_oldns > -1) {
(void) close(nc->nsc_oldns);
nc->nsc_oldns = -1;
}
if (nc->nsc_newns > -1) {
(void) close(nc->nsc_newns);
nc->nsc_newns = -1;
}
return rc;
}
/* Detects the following languages + C. */ /* Detects the following languages + C. */
const char *languages[] = {"java", "python", "ruby", "php", "node"}; const char *languages[] = {"java", "python", "ruby", "php", "node"};
const char *language_c = "c"; const char *language_c = "c";
......
...@@ -24,11 +24,6 @@ extern "C" { ...@@ -24,11 +24,6 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
struct ns_cookie {
int nsc_oldns;
int nsc_newns;
};
// Module name, start address, end address, whether to check mount namespace, payload // Module name, start address, end address, whether to check mount namespace, payload
typedef int (*bcc_procutils_modulecb)(const char *, uint64_t, uint64_t, bool, void *); typedef int (*bcc_procutils_modulecb)(const char *, uint64_t, uint64_t, bool, void *);
// Symbol name, address, payload // Symbol name, address, payload
...@@ -41,8 +36,6 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback, ...@@ -41,8 +36,6 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
void *payload); void *payload);
int bcc_procutils_each_ksym(bcc_procutils_ksymcb callback, void *payload); int bcc_procutils_each_ksym(bcc_procutils_ksymcb callback, void *payload);
void bcc_procutils_free(const char *ptr); void bcc_procutils_free(const char *ptr);
bool bcc_procutils_enter_mountns(int pid, struct ns_cookie *nc);
bool bcc_procutils_exit_mountns(struct ns_cookie *nc);
const char *bcc_procutils_language(int pid); const char *bcc_procutils_language(int pid);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -517,4 +517,15 @@ int bcc_resolve_symname(const char *module, const char *symname, ...@@ -517,4 +517,15 @@ int bcc_resolve_symname(const char *module, const char *symname,
sym->offset = (sym->offset - load_addr); sym->offset = (sym->offset - load_addr);
return 0; return 0;
} }
void *bcc_enter_mount_ns(int pid) {
return static_cast<void *>(new ProcMountNSGuard(pid));
}
void bcc_exit_mount_ns(void **guard) {
if (guard && *guard) {
delete static_cast<ProcMountNSGuard *>(*guard);
*guard = NULL;
}
}
} }
...@@ -52,6 +52,10 @@ int bcc_foreach_symbol(const char *module, SYM_CB cb); ...@@ -52,6 +52,10 @@ int bcc_foreach_symbol(const char *module, SYM_CB cb);
int bcc_find_symbol_addr(struct bcc_symbol *sym); int bcc_find_symbol_addr(struct bcc_symbol *sym);
int bcc_resolve_symname(const char *module, const char *symname, int bcc_resolve_symname(const char *module, const char *symname,
const uint64_t addr, int pid, struct bcc_symbol *sym); const uint64_t addr, int pid, struct bcc_symbol *sym);
void *bcc_enter_mount_ns(int pid);
void bcc_exit_mount_ns(void **guard);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include "bcc_proc.h" #include "bcc_syms.h"
#include "libbpf.h" #include "libbpf.h"
#include "perf_reader.h" #include "perf_reader.h"
...@@ -413,8 +413,8 @@ void * bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, con ...@@ -413,8 +413,8 @@ void * bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, con
char new_name[128]; char new_name[128];
struct perf_reader *reader = NULL; struct perf_reader *reader = NULL;
static char *event_type = "uprobe"; static char *event_type = "uprobe";
struct ns_cookie nsc = {-1, -1};
int n; int n;
void* mount_ns_guard = NULL;
snprintf(new_name, sizeof(new_name), "%s_bcc_%d", ev_name, getpid()); snprintf(new_name, sizeof(new_name), "%s_bcc_%d", ev_name, getpid());
reader = perf_reader_new(cb, NULL, NULL, cb_cookie, probe_perf_reader_page_cnt); reader = perf_reader_new(cb, NULL, NULL, cb_cookie, probe_perf_reader_page_cnt);
...@@ -435,15 +435,15 @@ void * bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, con ...@@ -435,15 +435,15 @@ void * bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, con
goto error; goto error;
} }
bcc_procutils_enter_mountns(pid, &nsc); mount_ns_guard = bcc_enter_mount_ns(pid);
if (write(kfd, buf, strlen(buf)) < 0) { if (write(kfd, buf, strlen(buf)) < 0) {
if (errno == EINVAL) if (errno == EINVAL)
fprintf(stderr, "check dmesg output for possible cause\n"); fprintf(stderr, "check dmesg output for possible cause\n");
close(kfd); close(kfd);
goto error; goto error;
} }
bcc_procutils_exit_mountns(&nsc);
close(kfd); close(kfd);
bcc_exit_mount_ns(&mount_ns_guard);
snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%ss/%s", event_type, new_name); snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%ss/%s", event_type, new_name);
if (bpf_attach_tracing_event(progfd, buf, reader, pid, cpu, group_fd) < 0) if (bpf_attach_tracing_event(progfd, buf, reader, pid, cpu, group_fd) < 0)
...@@ -452,7 +452,7 @@ void * bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, con ...@@ -452,7 +452,7 @@ void * bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, con
return reader; return reader;
error: error:
bcc_procutils_exit_mountns(&nsc); bcc_exit_mount_ns(&mount_ns_guard);
perf_reader_free(reader); perf_reader_free(reader);
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment