Skip to content

Commit 2b29682

Browse files
erthalionMolter73
andcommitted
Split user info
sinsp_threadinfo contains two fields with user and login_user information. Since those fields are of scap_userinfo type and statically allocated, they take a lot of space: scap_userinfo m_user; /* 368 2312 */ scap_userinfo m_loginuser; /* 2680 2312 */ which is 4624 bytes out of 5728 for the whole sinsp_threadinfo: /* size: 5728, cachelines: 90, members: 64 */ Most of this memory is coming from the fields name (MAX_CREDENTIALS_STR_LEN), homedir and shell (both SCAP_MAX_PATH_SIZE). For a process-heavy workload this can mean a lot of memory taken for these purposes. To make memory management more flexible, split m_user/m_loginuser into two set of fields: * one containing uid/gid, which are ubiquitous and generally used everywhere * one for the rest of heavy details, which are needed less often The new sinsp_userinfo class is not supposed to use separately from sinsp_threadinfo, thus it's defined inside the class. Co-authored-by: Mauro Ezequiel Moltrasio <[email protected]>
1 parent fecec54 commit 2b29682

File tree

8 files changed

+163
-55
lines changed

8 files changed

+163
-55
lines changed

userspace/libsinsp/filterchecks.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6177,22 +6177,27 @@ uint8_t* sinsp_filter_check_user::extract(sinsp_evt *evt, OUT uint32_t* len, boo
61776177
switch(m_field_id)
61786178
{
61796179
case TYPE_UID:
6180-
RETURN_EXTRACT_VAR(tinfo->m_user.uid);
6180+
m_uid = tinfo->m_user.uid();
6181+
RETURN_EXTRACT_VAR(m_uid);
61816182
case TYPE_NAME:
6182-
RETURN_EXTRACT_CSTR(tinfo->m_user.name);
6183+
m_strval = tinfo->m_user.name();
6184+
RETURN_EXTRACT_STRING(m_strval);
61836185
case TYPE_HOMEDIR:
6184-
RETURN_EXTRACT_CSTR(tinfo->m_user.homedir);
6186+
m_strval = tinfo->m_user.homedir();
6187+
RETURN_EXTRACT_STRING(m_strval);
61856188
case TYPE_SHELL:
6186-
RETURN_EXTRACT_CSTR(tinfo->m_user.shell);
6189+
m_strval = tinfo->m_user.shell();
6190+
RETURN_EXTRACT_STRING(m_strval);
61876191
case TYPE_LOGINUID:
61886192
m_s64val = (int64_t)-1;
6189-
if(tinfo->m_loginuser.uid < UINT32_MAX)
6193+
if(tinfo->m_loginuser.uid() < UINT32_MAX)
61906194
{
6191-
m_s64val = (int64_t)tinfo->m_loginuser.uid;
6195+
m_s64val = (int64_t)tinfo->m_loginuser.uid();
61926196
}
61936197
RETURN_EXTRACT_VAR(m_s64val);
61946198
case TYPE_LOGINNAME:
6195-
RETURN_EXTRACT_CSTR(tinfo->m_loginuser.name);
6199+
m_strval = tinfo->m_loginuser.name();
6200+
RETURN_EXTRACT_STRING(m_strval);
61966201
default:
61976202
ASSERT(false);
61986203
break;
@@ -6237,9 +6242,11 @@ uint8_t* sinsp_filter_check_group::extract(sinsp_evt *evt, OUT uint32_t* len, bo
62376242
switch(m_field_id)
62386243
{
62396244
case TYPE_GID:
6240-
RETURN_EXTRACT_VAR(tinfo->m_group.gid);
6245+
m_gid = tinfo->m_group.gid();
6246+
RETURN_EXTRACT_VAR(m_gid);
62416247
case TYPE_NAME:
6242-
RETURN_EXTRACT_CSTR(tinfo->m_group.name);
6248+
m_name = tinfo->m_group.name();
6249+
RETURN_EXTRACT_STRING(m_name);
62436250
default:
62446251
ASSERT(false);
62456252
break;

userspace/libsinsp/parsers.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,9 +1611,9 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid)
16111611
/* Refresh user / loginuser / group */
16121612
if(child_tinfo->m_container_id.empty() == false)
16131613
{
1614-
child_tinfo->set_user(child_tinfo->m_user.uid);
1615-
child_tinfo->set_loginuser(child_tinfo->m_loginuser.uid);
1616-
child_tinfo->set_group(child_tinfo->m_group.gid);
1614+
child_tinfo->set_user(child_tinfo->m_user.uid());
1615+
child_tinfo->set_loginuser(child_tinfo->m_loginuser.uid());
1616+
child_tinfo->set_group(child_tinfo->m_group.gid());
16171617
}
16181618

16191619
/* If there's a listener, invoke it */
@@ -2159,9 +2159,9 @@ void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt)
21592159
/* Refresh user / loginuser / group */
21602160
if(child_tinfo->m_container_id.empty() == false)
21612161
{
2162-
child_tinfo->set_user(child_tinfo->m_user.uid);
2163-
child_tinfo->set_loginuser(child_tinfo->m_loginuser.uid);
2164-
child_tinfo->set_group(child_tinfo->m_group.gid);
2162+
child_tinfo->set_user(child_tinfo->m_user.uid());
2163+
child_tinfo->set_loginuser(child_tinfo->m_loginuser.uid());
2164+
child_tinfo->set_group(child_tinfo->m_group.gid());
21652165
}
21662166

21672167
//
@@ -2705,7 +2705,7 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt)
27052705
if(evt->get_num_params() > 26)
27062706
{
27072707
parinfo = evt->get_param(26);
2708-
evt->m_tinfo->m_user.uid = *(uint32_t *)parinfo->m_val;
2708+
evt->m_tinfo->m_user.set_uid(*(uint32_t *)parinfo->m_val);
27092709
}
27102710

27112711
//
@@ -2747,9 +2747,9 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt)
27472747
//
27482748
if(container_id != evt->m_tinfo->m_container_id)
27492749
{
2750-
evt->m_tinfo->set_user(evt->m_tinfo->m_user.uid);
2751-
evt->m_tinfo->set_loginuser(evt->m_tinfo->m_loginuser.uid);
2752-
evt->m_tinfo->set_group(evt->m_tinfo->m_group.gid);
2750+
evt->m_tinfo->set_user(evt->m_tinfo->m_user.uid());
2751+
evt->m_tinfo->set_loginuser(evt->m_tinfo->m_loginuser.uid());
2752+
evt->m_tinfo->set_group(evt->m_tinfo->m_group.gid());
27532753
}
27542754

27552755
//
@@ -6388,9 +6388,9 @@ void sinsp_parser::parse_chroot_exit(sinsp_evt *evt)
63886388
//
63896389
if(container_id != evt->m_tinfo->m_container_id)
63906390
{
6391-
evt->m_tinfo->set_user(evt->m_tinfo->m_user.uid);
6392-
evt->m_tinfo->set_loginuser(evt->m_tinfo->m_loginuser.uid);
6393-
evt->m_tinfo->set_group(evt->m_tinfo->m_group.gid);
6391+
evt->m_tinfo->set_user(evt->m_tinfo->m_user.uid());
6392+
evt->m_tinfo->set_loginuser(evt->m_tinfo->m_loginuser.uid());
6393+
evt->m_tinfo->set_group(evt->m_tinfo->m_group.gid());
63946394
}
63956395
}
63966396
}

userspace/libsinsp/sinsp.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,10 @@ void sinsp::init()
449449
m_inited = true;
450450
}
451451

452-
void sinsp::set_import_users(bool import_users)
452+
void sinsp::set_import_users(bool import_users, bool user_details)
453453
{
454454
m_usergroup_manager.m_import_users = import_users;
455+
m_usergroup_manager.m_user_details_enabled = user_details;
455456
}
456457

457458
/*=============================== OPEN METHODS ===============================*/

userspace/libsinsp/sinsp.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,18 @@ class SINSP_PUBLIC sinsp : public capture_stats_source
317317
creating them can increase the startup time. Moreover, they contain
318318
information that could be privacy sensitive.
319319
320-
\note default behavior is import_users=true.
320+
\param user_details if set to false, no extended user information will be
321+
stored in sinsp_threadinfo, only user id/group id will be available. By
322+
default thread information is enriched with the full set of user
323+
information, i.e. name, homedir, shell, group name. The parameter
324+
controls this behavior, an can be used to reduce memory footprint.
325+
326+
\note default behavior is import_users=true, user_details=true
321327
322328
@throws a sinsp_exception containing the error string is thrown in case
323329
of failure.
324330
*/
325-
void set_import_users(bool import_users);
331+
void set_import_users(bool import_users, bool user_details = true);
326332

327333
/*!
328334
\brief temporarily pauses event capture.
@@ -790,6 +796,14 @@ class SINSP_PUBLIC sinsp : public capture_stats_source
790796
return m_isdebug_enabled;
791797
}
792798

799+
/*!
800+
\brief Returns true if extended user information is collected.
801+
*/
802+
inline bool is_user_details_enabled()
803+
{
804+
return m_usergroup_manager.m_user_details_enabled;
805+
}
806+
793807
/*!
794808
\brief Set a flag indicating if the command line requested to show container information.
795809

userspace/libsinsp/threadinfo.cpp

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ void sinsp_threadinfo::init()
154154
m_exe_ino_mtime = 0;
155155
m_exe_ino_ctime_duration_clone_ts = 0;
156156
m_exe_ino_ctime_duration_pidns_start = 0;
157-
158-
memset(&m_user, 0, sizeof(scap_userinfo));
159-
memset(&m_group, 0, sizeof(scap_groupinfo));
160-
memset(&m_loginuser, 0, sizeof(scap_userinfo));
161157
}
162158

163159
sinsp_threadinfo::~sinsp_threadinfo()
@@ -574,19 +570,27 @@ void sinsp_threadinfo::set_user(uint32_t uid)
574570
if (!user)
575571
{
576572
auto notify = m_inspector->is_live() || m_inspector->is_syscall_plugin();
577-
user = m_inspector->m_usergroup_manager.add_user(m_container_id, m_pid, uid, m_group.gid, NULL, NULL, NULL, notify);
573+
user = m_inspector->m_usergroup_manager.add_user(m_container_id, m_pid, uid, m_group.gid(), NULL, NULL, NULL, notify);
578574
}
575+
579576
if (user)
580577
{
581-
memcpy(&m_user, user, sizeof(scap_userinfo));
578+
m_user.set_uid(user->uid);
579+
m_user.set_gid(m_group.gid());
580+
581+
if (m_inspector->is_user_details_enabled())
582+
{
583+
m_user.set_name(user->name, sizeof(user->name));
584+
m_user.set_homedir(user->homedir, sizeof(user->homedir));
585+
m_user.set_shell(user->shell, sizeof(user->shell));
586+
}
582587
}
583588
else
584589
{
585-
m_user.uid = uid;
586-
m_user.gid = m_group.gid;
587-
strlcpy(m_user.name, (uid == 0) ? "root" : "<NA>", sizeof(m_user.name));
588-
strlcpy(m_user.homedir, (uid == 0) ? "/root" : "<NA>", sizeof(m_user.homedir));
589-
strlcpy(m_user.shell, "<NA>", sizeof(m_user.shell));
590+
// No need to set name/homedir/shell, the default values from
591+
// sinsp_userinfo are going to be used.
592+
m_user.set_uid(uid);
593+
m_user.set_gid(m_group.gid());
590594
}
591595
}
592596

@@ -600,30 +604,44 @@ void sinsp_threadinfo::set_group(uint32_t gid)
600604
}
601605
if (group)
602606
{
603-
memcpy(&m_group, group, sizeof(scap_groupinfo));
607+
m_group.set_gid(group->gid);
608+
609+
if (m_inspector->is_user_details_enabled())
610+
{
611+
m_group.set_name(group->name, sizeof(group->name));
612+
}
604613
}
605614
else
606615
{
607-
m_group.gid = gid;
608-
strlcpy(m_group.name, (gid == 0) ? "root" : "<NA>", sizeof(m_group.name));
616+
// No need to set name/homedir/shell, the default values from
617+
// sinsp_userinfo are going to be used.
618+
m_group.set_gid(gid);
609619
}
610-
m_user.gid = m_group.gid;
620+
m_user.set_gid(m_group.gid());
611621
}
612622

613623
void sinsp_threadinfo::set_loginuser(uint32_t loginuid)
614624
{
615625
scap_userinfo *login_user = m_inspector->m_usergroup_manager.get_user(m_container_id, loginuid);
626+
616627
if (login_user)
617628
{
618-
memcpy(&m_loginuser, login_user, sizeof(scap_userinfo));
629+
m_loginuser.set_uid(login_user->uid);
630+
m_loginuser.set_gid(m_group.gid());
631+
632+
if (m_inspector->is_user_details_enabled())
633+
{
634+
m_loginuser.set_name(login_user->name, sizeof(login_user->name));
635+
m_loginuser.set_homedir(login_user->homedir, sizeof(login_user->homedir));
636+
m_loginuser.set_shell(login_user->shell, sizeof(login_user->shell));
637+
}
619638
}
620639
else
621640
{
622-
m_loginuser.uid = loginuid;
623-
m_loginuser.gid = m_group.gid;
624-
strlcpy(m_loginuser.name, loginuid == 0 ? "root" : "<NA>", sizeof(m_loginuser.name));
625-
strlcpy(m_loginuser.homedir, loginuid == 0 ? "/root" : "<NA>", sizeof(m_loginuser.homedir));
626-
strlcpy(m_loginuser.shell, "<NA>", sizeof(m_loginuser.shell));
641+
// No need to set name/homedir/shell, the default values from
642+
// sinsp_userinfo are going to be used.
643+
m_loginuser.set_uid(loginuid);
644+
m_loginuser.set_gid(m_group.gid());
627645
}
628646
}
629647

@@ -1945,8 +1963,8 @@ void sinsp_thread_manager::thread_to_scap(sinsp_threadinfo& tinfo, scap_threadi
19451963

19461964
sctinfo->flags = tinfo.m_flags ;
19471965
sctinfo->fdlimit = tinfo.m_fdlimit;
1948-
sctinfo->uid = tinfo.m_user.uid;
1949-
sctinfo->gid = tinfo.m_group.gid;
1966+
sctinfo->uid = tinfo.m_user.uid();
1967+
sctinfo->gid = tinfo.m_group.gid();
19501968
sctinfo->vmsize_kb = tinfo.m_vmsize_kb;
19511969
sctinfo->vmrss_kb = tinfo.m_vmrss_kb;
19521970
sctinfo->vmswap_kb = tinfo.m_vmswap_kb;
@@ -1955,7 +1973,7 @@ void sinsp_thread_manager::thread_to_scap(sinsp_threadinfo& tinfo, scap_threadi
19551973
sctinfo->vtid = tinfo.m_vtid;
19561974
sctinfo->vpid = tinfo.m_vpid;
19571975
sctinfo->fdlist = NULL;
1958-
sctinfo->loginuid = tinfo.m_loginuser.uid;
1976+
sctinfo->loginuid = tinfo.m_loginuser.uid();
19591977
sctinfo->filtered_out = false;
19601978
}
19611979

@@ -2181,9 +2199,9 @@ threadinfo_map_t::ptr_t sinsp_thread_manager::get_thread_ref(int64_t tid, bool q
21812199
newti->m_not_expired_children = 0;
21822200
newti->m_comm = "<NA>";
21832201
newti->m_exe = "<NA>";
2184-
newti->m_user.uid = 0xffffffff;
2185-
newti->m_group.gid = 0xffffffff;
2186-
newti->m_loginuser.uid = 0xffffffff;
2202+
newti->m_user.set_uid(0xffffffff);
2203+
newti->m_group.set_gid(0xffffffff);
2204+
newti->m_loginuser.set_uid(0xffffffff);
21872205
}
21882206

21892207
//

userspace/libsinsp/threadinfo.h

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,71 @@ class SINSP_PUBLIC sinsp_threadinfo: public libsinsp::state::table_entry
7272
{
7373

7474
public:
75+
class sinsp_userinfo
76+
{
77+
public:
78+
uint32_t uid() { return m_uid; }
79+
uint32_t gid() { return m_gid; }
80+
std::string name() {
81+
if (m_name.empty())
82+
{
83+
return (m_uid == 0) ? "root" : "<NA>";
84+
}
85+
else
86+
{
87+
return m_name;
88+
}
89+
};
90+
std::string homedir() {
91+
if (m_homedir.empty())
92+
{
93+
return (m_uid == 0) ? "/root" : "<NA>";
94+
}
95+
else
96+
{
97+
return m_homedir;
98+
}
99+
};
100+
std::string shell() { return m_shell.empty() ? "<NA>" : m_shell; };
101+
102+
void set_uid(uint32_t uid) { m_uid = uid; };
103+
void set_gid(uint32_t gid) { m_gid = gid; };
104+
void set_name(char *name, size_t length) { m_name.assign(name, length); };
105+
void set_homedir(char *homedir, size_t length) { m_homedir.assign(homedir, length); };
106+
void set_shell(char *shell, size_t length) { m_shell.assign(shell, length); };
107+
108+
private:
109+
uint32_t m_uid; ///< User ID
110+
uint32_t m_gid; ///< Group ID
111+
std::string m_name; ///< Username
112+
std::string m_homedir; ///< Home directory
113+
std::string m_shell; ///< Shell program
114+
};
115+
116+
117+
class sinsp_groupinfo
118+
{
119+
public:
120+
uint32_t gid() { return m_gid; };
121+
std::string name() {
122+
if (m_name.empty())
123+
{
124+
return (m_gid == 0) ? "root" : "<NA>";
125+
}
126+
else
127+
{
128+
return m_name;
129+
}
130+
};
131+
132+
void set_gid(uint32_t gid) { m_gid = gid; };
133+
void set_name(char *name, size_t length) { m_name.assign(name, length); };
134+
private:
135+
uint32_t m_gid; ///< Group ID
136+
std::string m_name; ///< Group name
137+
};
138+
139+
75140
sinsp_threadinfo(
76141
sinsp *inspector = nullptr,
77142
std::shared_ptr<libsinsp::state::dynamic_struct::field_infos> dyn_fields = nullptr);
@@ -419,9 +484,9 @@ class SINSP_PUBLIC sinsp_threadinfo: public libsinsp::state::table_entry
419484
std::string m_container_id; ///< heuristic-based container id
420485
uint32_t m_flags; ///< The thread flags. See the PPM_CL_* declarations in ppm_events_public.h.
421486
int64_t m_fdlimit; ///< The maximum number of FDs this thread can open
422-
scap_userinfo m_user; ///< user infos
423-
scap_userinfo m_loginuser; ///< loginuser infos (auid)
424-
scap_groupinfo m_group; ///< group infos
487+
sinsp_userinfo m_user; ///< user infos
488+
sinsp_userinfo m_loginuser; ///< loginuser infos (auid)
489+
sinsp_groupinfo m_group; ///< group infos
425490
uint64_t m_cap_permitted; ///< permitted capabilities
426491
uint64_t m_cap_effective; ///< effective capabilities
427492
uint64_t m_cap_inheritable; ///< inheritable capabilities

userspace/libsinsp/user.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ using namespace std;
118118
// clang-format off
119119
sinsp_usergroup_manager::sinsp_usergroup_manager(sinsp* inspector)
120120
: m_import_users(true)
121+
, m_user_details_enabled(true)
121122
, m_last_flush_time_ns(0)
122123
, m_inspector(inspector)
123124
, m_host_root(m_inspector->get_host_root())

userspace/libsinsp/user.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class sinsp_usergroup_manager
133133
//
134134
bool m_import_users;
135135

136+
bool m_user_details_enabled;
137+
136138
private:
137139
scap_userinfo *add_host_user(uint32_t uid, uint32_t gid, const char *name, const char *home, const char *shell, bool notify);
138140
scap_userinfo *add_container_user(const std::string &container_id, int64_t pid, uint32_t uid, bool notify);

0 commit comments

Comments
 (0)