From: Cyril Hrubis <chrubis@suse.cz>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH 1/2] lib: Add library functions to check specified cgroup subsystem
Date: Mon, 28 Jan 2019 17:12:12 +0100 [thread overview]
Message-ID: <20190128161211.GA11600@rei.lan> (raw)
In-Reply-To: <1548654851-19112-1-git-send-email-yangx.jy@cn.fujitsu.com>
Hi!
> 1) Check if specified cgroup subsystem is supported.
> 2) Check if specified cgroup subsystem is mounted by default, and use
> custom mountpoint as the cgroup subsystem's mountpoint properly.
> 3) Add doc for these library functions.
>
> Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
> ---
> doc/test-writing-guidelines.txt | 45 +++++++++++++++++
> include/tst_cgroups.h | 13 +++++
> lib/tst_cgroups.c | 107 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 165 insertions(+)
> create mode 100644 include/tst_cgroups.h
> create mode 100644 lib/tst_cgroups.c
>
> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
> index 731be76..57ae6aa 100644
> --- a/doc/test-writing-guidelines.txt
> +++ b/doc/test-writing-guidelines.txt
> @@ -1539,6 +1539,51 @@ static struct tst_test test = {
> };
> -------------------------------------------------------------------------------
>
> +2.2.29 Parsing specified cgroup subsystem
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +void tst_set_cgroup_mntpoint(char *subsys_name, char *spec_mntpoint);
This function name is a bit misleading as it actually mounts the cgroup.
> +void tst_umount_cgroup(char *spec_mntpoint);
> +
> +The 'tst_set_cgroup_mntpoint()' function checks if 'subsys_name' (i.e. specified
> +cgroup subsystem) is supported and mounted by default, and uses 'spec_mntpoint'
> +(custom mountpoint) as 'subsys_name' mountpoint to test. For details:
> +1) It exits with TCONF if 'subsys_name' is not supported.
> +2) If 'subsys_name' is already mounted to a mountpoint, it creates a symlink
> + named by 'spec_mntpoint' to the pre-existent mountpoint.
> +3) If 'subsys_name' is not mounted, it mounts 'subsys_name' to 'spec_mntpoint'.
> +
> +The 'tst_umount_cgroup()' function unmounts and removes 'spec_mntpoint'.
> +
> +Note:
> +We should set .needs_tmpdir flag because we create 'spec_mntpoint' in tmpdir.
Generally this is a great step forward but what this is missing:
* Automatic cleanup, if tests creates any subdirectories in the cgroup
filesystem these will stay there until the machine is rebooted
I guess that it will be much easier to create the interface so that it
returns a path to a newly created subdirectory in the cgroup
filesystem tree so that we can remove it recursively later on
* Interface in tst_test structure. I suppose that we may add something
as const char *needs_cgroup; to the tst_test structure which would
be set to subsystem name such as:
static struct tst_test test = {
...
.needs_cgroup = "memory",
...
};
And the test will then set const char *tst_cgroup_path pointer to the
actuall path to the cgroup.
* I do wonder if we will nedd support for more than one cgroup type
later on, but so far I do not see that need so keeping it as an
interface for a single subsytem type will suffice.
> +[source,c]
> +-------------------------------------------------------------------------------
> +#include "tst_test.h"
> +#include "tst_cgroups.h"
> +
> +static void setup(void)
> +{
> + ...
> + tst_set_cgroups_mntpoint("memory", "mntpoint");
> + ...
> +}
> +
> +static void cleanup(void)
> +{
> + ...
> + tst_umount_cgroup("mntpoint");
> + ...
> +}
> +
> +sturct tst_test test = {
> + ...
> + .setup = setup,
> + .cleanup = cleanup,
> + ...
> +};
> +-------------------------------------------------------------------------------
>
> 2.3 Writing a testcase in shell
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> diff --git a/include/tst_cgroups.h b/include/tst_cgroups.h
> new file mode 100644
> index 0000000..70f5d18
> --- /dev/null
> +++ b/include/tst_cgroups.h
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
> + * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
> + */
> +
> +#ifndef TST_CGROUPS_H__
> +#define TST_CGROUPS_H__
> +
> +void tst_set_cgroup_mntpoint(char *subsys_name, char *spec_mntpoint);
> +void tst_umount_cgroup(char *spec_mntpoint);
> +
> +#endif /* TST_CGROUPS_H__ */
> diff --git a/lib/tst_cgroups.c b/lib/tst_cgroups.c
> new file mode 100644
> index 0000000..dd027c5
> --- /dev/null
> +++ b/lib/tst_cgroups.c
> @@ -0,0 +1,107 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
> + * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
> + */
> +
> +#include <errno.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <mntent.h>
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_safe_stdio.h"
> +
> +#define CGROUPS_PATH "/proc/cgroups"
> +#define MOUNTS_PATH "/proc/mounts"
> +
> +static char *cgroup_mntpoint;
> +static int cgroup_mounted;
> +
> +void tst_umount_cgroup(char *spec_mntpoint)
> +{
> + char buf[1024];
> +
> + if (cgroup_mntpoint) {
> + if (!access(spec_mntpoint, F_OK))
> + SAFE_UNLINK(spec_mntpoint);
> + return;
> + }
> +
> + if (cgroup_mounted) {
> + /* 'spec_mntpoint' may be treated as source instead
> + * of target, so append '/' to 'spec_mntpoint'. See
> + * ltp commit 4617249 for details.
> + */
> + sprintf(buf, "%s/", spec_mntpoint);
> + SAFE_UMOUNT(buf);
> + cgroup_mounted = 0;
> + }
> +
> + if (!access(spec_mntpoint, F_OK))
> + SAFE_RMDIR(spec_mntpoint);
> +}
> +
> +void tst_set_cgroup_mntpoint(char *subsys_name, char *spec_mntpoint)
> +{
> + FILE *fp = NULL, *mp = NULL;
> + struct mntent *mnt;
> + char buf[1024], name[64];
> + int enabled = 0, supported = 0;
> +
> + if (access(CGROUPS_PATH, F_OK))
> + tst_brk(TCONF, "Kernel didn't support for control groups");
> +
> + fp = SAFE_FOPEN(CGROUPS_PATH, "r");
> +
> + while (fgets(buf, 1024, fp)) {
> + if (sscanf(buf, "%s %*d %*d %d", name, &enabled) == -1) {
> + SAFE_FCLOSE(fp);
> + tst_brk(TBROK | TERRNO,
> + "sscanf() failed to read %s info",
> + subsys_name);
> + }
> +
> + if (!strcmp(name, subsys_name)) {
> + supported++;
> + break;
> + }
> + }
> +
> + SAFE_FCLOSE(fp);
> +
> + if (!supported || !enabled) {
> + tst_brk(TCONF,
> + "%s wasn't supported by kernel or it wasn't enabled",
> + subsys_name);
> + }
> +
> + mp = setmntent(MOUNTS_PATH, "r");
> + if (mp == NULL) {
> + tst_brk(TBROK | TERRNO,
> + "setmntent() failed to open /proc/mounts");
> + }
> +
> + while ((mnt = getmntent(mp))) {
> + if (hasmntopt(mnt, subsys_name)) {
> + cgroup_mntpoint = mnt->mnt_dir;
> + break;
> + }
> + }
> +
> + endmntent(mp);
> +
> + if (cgroup_mntpoint) {
> + /* Use pre-existent subsys mountpoint and creat a symlink
> + * named by spec_mntpoint to it.
> + */
> + SAFE_SYMLINK(cgroup_mntpoint, spec_mntpoint);
> + } else {
> + /* Mount subsys to spec_mntpoint. */
> + SAFE_MKDIR(spec_mntpoint, 0777);
> + SAFE_MOUNT("none", spec_mntpoint, "cgroup", 0, subsys_name);
> + cgroup_mounted = 1;
> + }
> +}
> --
> 1.8.3.1
>
>
>
--
Cyril Hrubis
chrubis@suse.cz
prev parent reply other threads:[~2019-01-28 16:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-28 5:54 [LTP] [PATCH 1/2] lib: Add library functions to check specified cgroup subsystem Xiao Yang
2019-01-28 5:54 ` [LTP] [PATCH 2/2] syscalls/madvise09.c: Use " Xiao Yang
2019-01-28 16:12 ` Cyril Hrubis [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190128161211.GA11600@rei.lan \
--to=chrubis@suse.cz \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox