Skip to content

Commit fe047fe

Browse files
geraldcombspoiana
authored andcommitted
update(userspace): Make offset extraction per-value instead of per-field
Add support for extracting offsets for each value instead of just the first one. Signed-off-by: Gerald Combs <[email protected]>
1 parent 747bd9d commit fe047fe

File tree

10 files changed

+67
-46
lines changed

10 files changed

+67
-46
lines changed

userspace/libsinsp/filter_cache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class sinsp_filter_extract_cache {
8383

8484
inline bool result() const { return m_result; }
8585

86-
inline const std::vector<extract_offset_t>& offsets() const { return m_offsets; }
86+
inline const std::vector<extract_offset_t>& offsets() const { return m_value_offsets; }
8787

8888
private:
8989
template<typename T>
@@ -97,7 +97,7 @@ class sinsp_filter_extract_cache {
9797
bool m_result = false;
9898
std::vector<extract_value_t> m_values;
9999
std::vector<std::vector<uint8_t>> m_storage;
100-
std::vector<extract_offset_t> m_offsets;
100+
std::vector<extract_offset_t> m_value_offsets;
101101
};
102102

103103
/**

userspace/libsinsp/plugin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ std::unique_ptr<sinsp_filter_check> sinsp_plugin::new_filtercheck(
985985
bool sinsp_plugin::extract_fields_and_offsets(sinsp_evt* evt,
986986
uint32_t num_fields,
987987
ss_plugin_extract_field* fields,
988-
ss_plugin_extract_field_offsets* field_offsets) {
988+
ss_plugin_extract_value_offsets* value_offsets) {
989989
if(!m_inited) {
990990
throw sinsp_exception(std::string(s_not_init_err) + ": " + m_name);
991991
}
@@ -1002,7 +1002,7 @@ bool sinsp_plugin::extract_fields_and_offsets(sinsp_evt* evt,
10021002
in.owner = (ss_plugin_owner_t*)this;
10031003
in.get_owner_last_error = sinsp_plugin::get_owner_last_error;
10041004
in.table_reader_ext = &table_reader_ext;
1005-
in.field_offsets = field_offsets;
1005+
in.value_offsets = value_offsets;
10061006
sinsp_plugin::table_read_api(in.table_reader, table_reader_ext);
10071007
auto res = m_handle->api.extract_fields(m_state, &ev, &in) == SS_PLUGIN_SUCCESS;
10081008

userspace/libsinsp/plugin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class sinsp_plugin : public libsinsp::state::sinsp_table_owner {
187187
bool extract_fields_and_offsets(sinsp_evt* evt,
188188
uint32_t num_fields,
189189
ss_plugin_extract_field* fields,
190-
ss_plugin_extract_field_offsets* field_offsets);
190+
ss_plugin_extract_value_offsets* value_offsets);
191191

192192
/** Event Parsing **/
193193
inline const std::unordered_set<std::string>& parse_event_sources() const {

userspace/libsinsp/plugin_filtercheck.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,9 @@ bool sinsp_filter_check_plugin::extract_nocache(sinsp_evt* evt,
170170
efield.arg_present = m_arg_present;
171171
efield.ftype = type;
172172
efield.flist = m_info->m_fields[m_field_id].m_flags & EPF_IS_LIST;
173-
ss_plugin_extract_field_offsets eoffset;
174-
ss_plugin_extract_field_offsets* eoptr = nullptr;
173+
ss_plugin_extract_value_offsets eoffset = {nullptr, nullptr};
174+
ss_plugin_extract_value_offsets* eoptr = nullptr;
175175
if(offsets) {
176-
eoffset.start = UINT32_MAX;
177-
eoffset.length = UINT32_MAX;
178176
eoptr = &eoffset;
179177
}
180178
if(!m_eplugin->extract_fields_and_offsets(evt, num_fields, &efield, eoptr) ||
@@ -216,11 +214,10 @@ bool sinsp_filter_check_plugin::extract_nocache(sinsp_evt* evt,
216214
break;
217215
}
218216
values.push_back(res);
219-
}
220217

221-
if(offsets) {
222-
extract_offset_t res_offset = {eoffset.start, eoffset.length};
223-
offsets->push_back(res_offset);
218+
if(offsets && eoffset.start && eoffset.length) {
219+
offsets->emplace_back(extract_offset_t{eoffset.start[i], eoffset.length[i]});
220+
}
224221
}
225222

226223
return true;

userspace/libsinsp/test/plugins.ut.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,8 @@ TEST_F(sinsp_with_test_input, plugin_custom_source) {
376376
ASSERT_FALSE(field_has_value(evt, "fd.name", filterlist));
377377
ASSERT_EQ(get_field_as_string(evt, "evt.pluginname", filterlist), src_pl->name());
378378
ASSERT_EQ(get_field_as_string(evt, "sample.hello", filterlist), "hello world");
379-
ASSERT_EQ(get_field_offset_start(evt, "sample.hello", filterlist), 0);
380-
ASSERT_EQ(get_field_offset_length(evt, "sample.hello", filterlist), 11);
379+
ASSERT_EQ(get_value_offset_start(evt, "sample.hello", filterlist, 0), 0);
380+
ASSERT_EQ(get_value_offset_length(evt, "sample.hello", filterlist, 0), 11);
381381
ASSERT_EQ(next_event(), nullptr); // EOF is expected
382382
}
383383

userspace/libsinsp/test/plugins/plugin_extract.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,18 @@ ss_plugin_rc plugin_extract_fields(ss_plugin_t* s,
133133
for(uint32_t i = 0; i < in->num_fields; i++) {
134134
switch(in->fields[i].field_id) {
135135
case 0: // test.hello
136+
{
136137
ps->strstorage = "hello world";
137138
ps->strptr = ps->strstorage.c_str();
139+
static uint32_t res_start = 0;
140+
static uint32_t res_length = ps->strstorage.size();
138141
in->fields[i].res.str = &ps->strptr;
139142
in->fields[i].res_len = 1;
140-
if(in->field_offsets) {
141-
in->field_offsets[i].start = 0;
142-
in->field_offsets[i].length = ps->strstorage.size();
143+
if(in->value_offsets) {
144+
in->value_offsets[i].start = &res_start;
145+
in->value_offsets[i].length = &res_length;
143146
}
144-
break;
147+
} break;
145148
default:
146149
in->fields[i].res_len = 0;
147150
return SS_PLUGIN_FAILURE;

userspace/libsinsp/test/sinsp_with_test_input.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -667,9 +667,10 @@ std::string sinsp_with_test_input::get_field_as_string(sinsp_evt* evt,
667667
return result;
668668
}
669669

670-
extract_offset_t sinsp_with_test_input::get_field_offsets(sinsp_evt* evt,
670+
extract_offset_t sinsp_with_test_input::get_value_offsets(sinsp_evt* evt,
671671
std::string_view field_name,
672-
filter_check_list& flist) {
672+
filter_check_list& flist,
673+
size_t val_idx) {
673674
if(evt == nullptr) {
674675
throw sinsp_exception("The event class is NULL");
675676
}
@@ -688,19 +689,26 @@ extract_offset_t sinsp_with_test_input::get_field_offsets(sinsp_evt* evt,
688689
if(offsets.size() == 0) {
689690
throw sinsp_exception("Unable to extract offsets for " + std::string(field_name));
690691
}
691-
return offsets.at(0);
692+
if(val_idx >= values.size()) {
693+
throw sinsp_exception("Offset index " + std::to_string(val_idx) + " out of range for " +
694+
std::string(field_name));
695+
}
696+
697+
return offsets.at(val_idx);
692698
}
693699

694-
uint32_t sinsp_with_test_input::get_field_offset_start(sinsp_evt* evt,
700+
uint32_t sinsp_with_test_input::get_value_offset_start(sinsp_evt* evt,
695701
std::string_view field_name,
696-
filter_check_list& flist) {
697-
return get_field_offsets(evt, field_name, flist).start;
702+
filter_check_list& flist,
703+
size_t val_idx) {
704+
return get_value_offsets(evt, field_name, flist, val_idx).start;
698705
}
699706

700-
uint32_t sinsp_with_test_input::get_field_offset_length(sinsp_evt* evt,
707+
uint32_t sinsp_with_test_input::get_value_offset_length(sinsp_evt* evt,
701708
std::string_view field_name,
702-
filter_check_list& flist) {
703-
return get_field_offsets(evt, field_name, flist).length;
709+
filter_check_list& flist,
710+
size_t val_idx) {
711+
return get_value_offsets(evt, field_name, flist, val_idx).length;
704712
}
705713

706714
bool sinsp_with_test_input::eval_filter(sinsp_evt* evt,

userspace/libsinsp/test/sinsp_with_test_input.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,18 @@ class sinsp_with_test_input : public ::testing::Test {
300300
bool field_has_value(sinsp_evt*, std::string_view field_name, filter_check_list&);
301301
std::string get_field_as_string(sinsp_evt*, std::string_view field_name);
302302
std::string get_field_as_string(sinsp_evt*, std::string_view field_name, filter_check_list&);
303-
extract_offset_t get_field_offsets(sinsp_evt*, std::string_view field_name, filter_check_list&);
304-
uint32_t get_field_offset_start(sinsp_evt*, std::string_view field_name, filter_check_list&);
305-
uint32_t get_field_offset_length(sinsp_evt*, std::string_view field_name, filter_check_list&);
303+
extract_offset_t get_value_offsets(sinsp_evt*,
304+
std::string_view field_name,
305+
filter_check_list&,
306+
size_t val_idx);
307+
uint32_t get_value_offset_start(sinsp_evt*,
308+
std::string_view field_name,
309+
filter_check_list&,
310+
size_t val_idx);
311+
uint32_t get_value_offset_length(sinsp_evt*,
312+
std::string_view field_name,
313+
filter_check_list&,
314+
size_t val_idx);
306315
bool eval_filter(sinsp_evt* evt,
307316
std::string_view filter_str,
308317
std::shared_ptr<sinsp_filter_cache_factory> cachef = nullptr);

userspace/plugin/plugin_api.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,13 @@ typedef struct ss_plugin_field_extract_input {
371371
// Vtable for controlling a state table for read operations.
372372
ss_plugin_table_reader_vtable_ext* table_reader_ext;
373373

374-
// An array of ss_plugin_extract_field_offsets structs. This member
375-
// is optional, and might be ignored by extractors.
376-
ss_plugin_extract_field_offsets* field_offsets;
374+
// An array of ss_plugin_extract_value_offsets structs. The start
375+
// and length in each entry should be set to nullptr, and as with
376+
// the "fields" member, memory pointers set as output must be
377+
// allocated by the plugin and must not be deallocated or modified
378+
// until the next extract_fields() call.
379+
// This member is optional, and might be ignored by extractors.
380+
ss_plugin_extract_value_offsets* value_offsets;
377381
} ss_plugin_field_extract_input;
378382

379383
// Input passed to the plugin when parsing an event for the event parsing

userspace/plugin/plugin_types.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,19 @@ typedef struct ss_plugin_byte_buffer {
128128
const void* ptr;
129129
} ss_plugin_byte_buffer;
130130

131-
// Used in extract_fields_and_offsets to receive field offsets along
132-
// with field data.
133-
// Extraction functions might not support offsets. In order to detect
134-
// this, callers can initialize this to an invalid pair, such as
135-
// {UINT32_MAX, UINT32_MAX}. Extraction functions that support offsets
136-
// should be set these to the zero-indexed start offset and length of
137-
// the field in the event or log data. {0, 0} can be used to indicate
138-
// that there are no valid offsets, e.g. if the field was generated or
131+
// Used in extract_fields_and_offsets to receive field value offsets
132+
// along with field data.
133+
// Extraction functions that support offsets should be set these to an
134+
// array of zero-indexed start offsets and lengths of each returned
135+
// value in the event or log data. {0, 0} can be used to indicate that
136+
// there are no valid offsets, e.g. if the value was generated or
139137
// computed from other data.
140-
typedef struct ss_plugin_extract_field_offsets {
141-
uint32_t start;
142-
uint32_t length;
143-
} ss_plugin_extract_field_offsets;
138+
// Extraction functions might not support offsets. In order to detect
139+
// this, callers should initialize the start and length to nullptr.
140+
typedef struct ss_plugin_extract_value_offsets {
141+
uint32_t* start;
142+
uint32_t* length;
143+
} ss_plugin_extract_value_offsets;
144144

145145
// Used in extract_fields functions below to receive a field/arg
146146
// pair and return an extracted value.

0 commit comments

Comments
 (0)