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

new(scap, sinsp)!: linux_hostinfo platform for use with non-syscall source plugins #1969

Merged
merged 2 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion userspace/libscap/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
add_library(scap_platform STATIC scap_linux_platform.c scap_procs.c scap_fds.c scap_userlist.c scap_iflist.c scap_cgroup.c scap_machine_info.c)
add_library(scap_platform
STATIC
scap_linux_platform.c
scap_linux_hostinfo_platform.c
scap_procs.c
scap_fds.c
scap_userlist.c
scap_iflist.c
scap_cgroup.c
scap_machine_info.c)
target_include_directories(scap_platform PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
target_link_libraries(scap_platform PRIVATE scap_error scap_platform_util)
add_dependencies(scap_platform uthash)
73 changes: 73 additions & 0 deletions userspace/libscap/linux/scap_linux_hostinfo_platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
Copyright (C) 2024 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

#include <libscap/linux/scap_linux_platform.h>

#include <libscap/scap.h>
#include <libscap/scap-int.h>
#include <libscap/scap_machine_info.h>
#include <libscap/linux/scap_linux_int.h>

#include <stdlib.h>
#include <unistd.h>

static void scap_linux_hostinfo_free_platform(struct scap_platform* platform)
{
free(platform);
}

int32_t scap_linux_hostinfo_init_platform(struct scap_platform* platform, char* lasterr, struct scap_engine_handle engine, struct scap_open_args* oargs)
{
int rc;

if(scap_os_get_machine_info(&platform->m_machine_info, lasterr) != SCAP_SUCCESS)
{
return SCAP_FAILURE;
}

scap_os_get_agent_info(&platform->m_agent_info);

rc = scap_linux_create_iflist(platform);
if(rc != SCAP_SUCCESS)
{
scap_linux_hostinfo_free_platform(platform);
return rc;

Check warning on line 48 in userspace/libscap/linux/scap_linux_hostinfo_platform.c

View check run for this annotation

Codecov / codecov/patch

userspace/libscap/linux/scap_linux_hostinfo_platform.c#L47-L48

Added lines #L47 - L48 were not covered by tests
}

return SCAP_SUCCESS;
}

static const struct scap_platform_vtable scap_linux_hostinfo_platform_vtable = {
.init_platform = scap_linux_hostinfo_init_platform,
.refresh_addr_list = scap_linux_create_iflist,
.free_platform = scap_linux_hostinfo_free_platform,
};

struct scap_platform* scap_linux_hostinfo_alloc_platform()
{
struct scap_linux_platform* platform = calloc(1, sizeof(*platform));

if(platform == NULL)
{
return NULL;
}

struct scap_platform* generic = &platform->m_generic;
generic->m_vtable = &scap_linux_hostinfo_platform_vtable;

return generic;
}
16 changes: 16 additions & 0 deletions userspace/libscap/linux/scap_linux_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ struct scap_linux_platform

struct scap_platform* scap_linux_alloc_platform(proc_entry_callback proc_callback, void* proc_callback_context);

/**
* @brief A lightweight Linux platform that only collects static host information
*
* This is useful with source plugins that do not handle syscall data but still want access
* to some info about the machine they're running on. Currently collected data includes:
* - machine info
* - agent info
* - interface list
*/
struct scap_linux_hostinfo_platform
{
struct scap_platform m_generic;
};

struct scap_platform* scap_linux_hostinfo_alloc_platform();

#ifdef __cplusplus
};
#endif
8 changes: 6 additions & 2 deletions userspace/libscap/scap.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,16 @@ limitations under the License.
// The test_input and source_plugin engines can optionally use a linux_platform
// but only on an actual Linux system.
//
// Still, to compile properly on non-Linux, provide an implementation
// of scap_linux_alloc_platform() that always fails at runtime.
// Still, to compile properly on non-Linux, provide implementations
// of scap_linux_alloc_platform() and scap_linux_hostinfo_alloc_platform() that always fail at runtime.
struct scap_platform* scap_linux_alloc_platform(proc_entry_callback proc_callback, void* proc_callback_context)
{
return NULL;
}
struct scap_platform* scap_linux_hostinfo_alloc_platform()
{
return NULL;
}
#endif

const char* scap_getlasterr(scap_t* handle)
Expand Down
28 changes: 18 additions & 10 deletions userspace/libsinsp/sinsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,8 @@
#endif
}

void sinsp::open_plugin(const std::string& plugin_name, const std::string& plugin_open_params, sinsp_mode_t mode)
void sinsp::open_plugin(const std::string& plugin_name, const std::string& plugin_open_params,
FedeDP marked this conversation as resolved.
Show resolved Hide resolved
sinsp_plugin_platform platform_type)
{
#ifdef HAS_ENGINE_SOURCE_PLUGIN
scap_open_args oargs {};
Expand All @@ -564,16 +565,23 @@
oargs.engine_params = &params;

scap_platform* platform;
switch(mode)
sinsp_mode_t mode;
switch(platform_type)
{
case SINSP_MODE_PLUGIN:
platform = scap_generic_alloc_platform(::on_new_entry_from_proc, this);
break;
case SINSP_MODE_LIVE:
platform = scap_linux_alloc_platform(::on_new_entry_from_proc, this);
break;
default:
throw sinsp_exception("Unsupported mode for SOURCE_PLUGIN engine");
case sinsp_plugin_platform::SINSP_PLATFORM_GENERIC:
mode = SINSP_MODE_PLUGIN;
platform = scap_generic_alloc_platform(::on_new_entry_from_proc, this);
break;
case sinsp_plugin_platform::SINSP_PLATFORM_HOSTINFO:
mode = SINSP_MODE_PLUGIN;
platform = scap_linux_hostinfo_alloc_platform();
break;
case sinsp_plugin_platform::SINSP_PLATFORM_FULL:
mode = SINSP_MODE_LIVE;
platform = scap_linux_alloc_platform(::on_new_entry_from_proc, this);

Check warning on line 581 in userspace/libsinsp/sinsp.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/sinsp.cpp#L579-L581

Added lines #L579 - L581 were not covered by tests
break;
default:

Check warning on line 583 in userspace/libsinsp/sinsp.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/sinsp.cpp#L583

Added line #L583 was not covered by tests
throw sinsp_exception("Unsupported mode for SOURCE_PLUGIN engine");
}
open_common(&oargs, &scap_source_plugin_engine, platform, mode);
#else
Expand Down
12 changes: 11 additions & 1 deletion userspace/libsinsp/sinsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ enum sinsp_mode_t
SINSP_MODE_TEST,
};

/**
* @brief Possible platforms to use with plugins
*/
enum class sinsp_plugin_platform
{
SINSP_PLATFORM_GENERIC, //!< generic platform, no system information collected
SINSP_PLATFORM_HOSTINFO, //!< basic host information collected, for non-syscall source plugins
SINSP_PLATFORM_FULL, //!< full system information collected, for syscall source plugins
};

/** @defgroup inspector Main library
@{
*/
Expand Down Expand Up @@ -168,7 +178,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source
virtual void open_nodriver(bool full_proc_scan = false);
virtual void open_savefile(const std::string &filename, int fd = 0);
virtual void open_plugin(const std::string& plugin_name, const std::string& plugin_open_params,
sinsp_mode_t mode = SINSP_MODE_PLUGIN);
sinsp_plugin_platform platform_type);
virtual void open_gvisor(const std::string &config_path, const std::string &root_path, bool no_events = false, int epoll_timeout = -1);
/*[EXPERIMENTAL] This API could change between releases, we are trying to find the right configuration to deploy the modern bpf probe:
* `cpus_for_each_buffer` and `online_only` are the 2 experimental params. The first one allows associating more than one CPU to a single ring buffer.
Expand Down
13 changes: 11 additions & 2 deletions userspace/libsinsp/test/plugins.ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,13 @@ TEST_F(sinsp_with_test_input, plugin_syscall_source)

// we will not use the test scap engine here, but open the src plugin instead
// note: we configure the plugin to just emit 1 event through its open params
m_inspector.open_plugin(src_pl->name(), "1");
m_inspector.open_plugin(src_pl->name(), "1", sinsp_plugin_platform::SINSP_PLATFORM_HOSTINFO);

#ifdef __linux__
// The LINUX_HOSTINFO platform type fills in machine_info, but only on Linux
// (non-Linux platforms have a stub implementation in scap.c)
ASSERT_GT(m_inspector.get_machine_info()->num_cpus, 0);
#endif

auto evt = next_event();
ASSERT_NE(evt, nullptr);
Expand Down Expand Up @@ -310,7 +316,10 @@ TEST_F(sinsp_with_test_input, plugin_custom_source)

// we will not use the test scap engine here, but open the src plugin instead
// note: we configure the plugin to just emit 1 event through its open params
m_inspector.open_plugin(src_pl->name(), "1");
m_inspector.open_plugin(src_pl->name(), "1", sinsp_plugin_platform::SINSP_PLATFORM_GENERIC);

// the GENERIC platform type does not fill in machine_info
ASSERT_EQ(m_inspector.get_machine_info()->num_cpus, 0);

auto evt = next_event();
ASSERT_NE(evt, nullptr);
Expand Down
Loading