From mboxrd@z Thu Jan 1 00:00:00 1970 From: xuyang2018.jy@fujitsu.com Date: Wed, 23 Jun 2021 09:28:58 +0000 Subject: [LTP] [PATCH 1/2] syscalls/msgstress03: fix fork failure on small memory systems In-Reply-To: <20210622111440.74722-1-krzysztof.kozlowski@canonical.com> References: <20210622111440.74722-1-krzysztof.kozlowski@canonical.com> Message-ID: <60D2FEFC.8030706@fujitsu.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: ltp@lists.linux.it Hi Krzysztof > Running syscalls/msgstress03 on a system with less than ~4 GB of RAM fails: > > msgstress03 1 TFAIL : msgstress03.c:155: Fork failed (may be OK if under stress) > > In dmesg: > > LTP: starting msgstress03 > cgroup: fork rejected by pids controller in /user.slice/user-1000.slice/session-1.scope > > The reason is cgroups pid limit set by systemd user.slice. The limit is > set for login session, also for root user. For example on 2 GB RAM > machine it is set as: > /sys/fs/cgroup/pids/user.slice/user-0.slice/pids.max:5207 This file only exists on cgroupv1 and cgroupv2 should use /sys/fs/cgroup/user.slice/user-0.slice/pids.max. Also if some embedded system doesn't have systemd, do we have a generic way or fallback way to calculate the pid max? For this problem, I have a calculate way in my patch[1] at this time last year. [1]https://patchwork.ozlabs.org/project/ltp/patch/1592298082-21792-2-git-send-email-xuyang2018.jy@cn.fujitsu.com/ Best Regards Yang Xu > > Read the maximum number of pids and adjust the test limit. For 2 GB RAM > machine with systemd this will result in: > > msgstress03 0 TINFO : Found limit of processes 5056 (from /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max) > msgstress03 0 TINFO : Requested number of processes higher than user session limit (10000> 4556), setting to 4556 > > Signed-off-by: Krzysztof Kozlowski > --- > include/ipcmsg.h | 2 + > libs/libltpipc/libipc.c | 58 +++++++++++++++++++ > .../syscalls/ipc/msgstress/msgstress03.c | 15 ++++- > 3 files changed, 74 insertions(+), 1 deletion(-) > > diff --git a/include/ipcmsg.h b/include/ipcmsg.h > index d89894b726cf..b73b72d6d172 100644 > --- a/include/ipcmsg.h > +++ b/include/ipcmsg.h > @@ -61,8 +61,10 @@ void rm_queue(int); > > key_t getipckey(); > int getuserid(char *); > +int get_session_uid(void); > > int get_max_msgqueues(void); > int get_used_msgqueues(void); > +int get_pids_limit(void); > > #endif /* ipcmsg.h */ > diff --git a/libs/libltpipc/libipc.c b/libs/libltpipc/libipc.c > index d94880f54b64..cd3480ed9f21 100644 > --- a/libs/libltpipc/libipc.c > +++ b/libs/libltpipc/libipc.c > @@ -151,6 +151,31 @@ int getuserid(char *user) > return (ent->pw_uid); > } > > +/* > + * Get the effective session UID - either one invoking current test via sudo > + * or the real UID. > + */ > +int get_session_uid(void) > +{ > + const char *sudo_uid; > + > + sudo_uid = getenv("SUDO_UID"); > + if (sudo_uid) { > + int real_uid; > + > + TEST(sscanf(sudo_uid, "%u",&real_uid)); > + if (TEST_RETURN != 1) { > +#ifdef DEBUG > + tst_resm(TINFO, "No SUDO_UID from env"); > +#endif > + } else { > + return real_uid; > + } > + } > + > + return getuid(); > +} > + > /* > * rm_shm() - removes a shared memory segment. > */ > @@ -218,3 +243,36 @@ int get_max_msgqueues(void) > fclose(f); > return atoi(buff); > } > + > +/* > + * Get the limit of processes for current session configured by systemd user.slice. > + * This also applies to root user. > + */ > +int get_pids_limit(void) > +{ > + int real_uid, ret; > + char path[PATH_MAX]; > + long unsigned int max_pids; > + > + real_uid = get_session_uid(); > + if (TEST_RETURN != 1) { > + tst_resm(TINFO, "Cannot get UID"); > + return -1; > + } > + > + ret = snprintf(path, sizeof(path), > + "/sys/fs/cgroup/pids/user.slice/user-%d.slice/pids.max", > + real_uid); > + if (ret< 0 || (size_t)ret>= sizeof(path)) > + return -1; > + > + if (access(path, R_OK) != 0) { > + tst_resm(TINFO, "Cannot read session user limits from '%s'", path); > + return -1; > + } > + > + SAFE_FILE_SCANF(cleanup, path, "%lu",&max_pids); > + tst_resm(TINFO, "Found limit of processes %lu (from %s)", max_pids, path); > + > + return max_pids; > +} > diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c > index 294b401b1b38..9cf96db7956e 100644 > --- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c > +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c > @@ -78,7 +78,7 @@ static void usage(void) > > int main(int argc, char **argv) > { > - int i, j, ok, pid; > + int i, j, ok, pid, max_session_pids; > int count, status; > struct sigaction act; > > @@ -109,6 +109,19 @@ int main(int argc, char **argv) > } > } > > + max_session_pids = get_pids_limit(); > + if (max_session_pids> 0) { > + /* Clamp number of processes to session limit with some buffer for OS */ > + max_session_pids = (max_session_pids> 500 ? max_session_pids - 500 : 0); > + if (nprocs>= max_session_pids) { > + tst_resm(TINFO, > + "Requested number of processes higher than user session limit (%d> %d), " > + "setting to %d", nprocs, max_session_pids, > + max_session_pids); > + nprocs = max_session_pids; > + } > + } > + > srand(getpid()); > tid = -1; >