lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20211008144819.GA4045@fuller.cnet>
Date:   Fri, 8 Oct 2021 11:48:19 -0300
From:   Marcelo Tosatti <mtosatti@...hat.com>
To:     linux-kernel@...r.kernel.org
Cc:     Nitesh Lal <nilal@...hat.com>,
        Nicolas Saenz Julienne <nsaenzju@...hat.com>,
        Frederic Weisbecker <frederic@...nel.org>,
        Christoph Lameter <cl@...ux.com>,
        Juri Lelli <juri.lelli@...hat.com>,
        Peter Zijlstra <peterz@...radead.org>,
        Alex Belits <abelits@...its.com>, Peter Xu <peterx@...hat.com>
Subject: [patch v4] util-linux: add chisol tool to configure task isolation


Add chisol tool to configure task isolation. See chisol -h 
for details.

For example, to launch a version of oslat that activates 
task isolation:

chisol -q vmstat_sync -I conf ./oslat -f 1 -c 5 -D 5m

-q vmstat_sync: enable quiescing of per-CPU vmstats 
-I conf: inherit task isolation configuration.

To launch an unmodified application:

./chisol -q vmstat_sync -a -I active command args

Signed-off-by: Marcelo Tosatti <mtosatti@...hat.com>

diff -Nur util-linux.orig/configure.ac util-linux/configure.ac
--- util-linux.orig/configure.ac	2021-10-07 14:15:15.334935842 -0300
+++ util-linux/configure.ac	2021-10-05 15:11:54.197269076 -0300
@@ -2272,6 +2272,9 @@
 	[UL_CHECK_SYSCALL([sched_setattr])], [sched_setattr])
 AM_CONDITIONAL([BUILD_UCLAMPSET], [test "x$build_uclampset" = xyes])
 
+UL_ENABLE_ALIAS([chisol], [chisol])
+UL_BUILD_INIT([chisol])
+AM_CONDITIONAL([BUILD_CHISOL], [test "x$build_chisol" = xyes])
 
 AC_ARG_ENABLE([wall],
   AS_HELP_STRING([--disable-wall], [do not build wall]),
diff -Nur util-linux.orig/schedutils/chisol.c util-linux/schedutils/chisol.c
--- util-linux.orig/schedutils/chisol.c	1969-12-31 21:00:00.000000000 -0300
+++ util-linux/schedutils/chisol.c	2021-10-07 14:17:38.710937831 -0300
@@ -0,0 +1,304 @@
+/*
+ * chisol.c - change task isolation parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2021 Marcelo Tosatti <mtosatti@...hat.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+#include <sched.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+#include <errno.h>
+
+#include "nls.h"
+#include "strutils.h"
+#include "xalloc.h"
+#include "procutils.h"
+#include "c.h"
+#include "closestream.h"
+
+static void __attribute__((__noreturn__)) usage(void)
+{
+	FILE *out = stdout;
+	fprintf(out,
+		_("Usage: %s [options] cmd [args...]]\n\n"),
+		program_invocation_short_name);
+
+	fputs(USAGE_SEPARATOR, out);
+	fputs(_("Change task isolation parameters.\n"), out);
+	fputs(USAGE_SEPARATOR, out);
+
+	fprintf(out, _(
+		"Options:\n"
+		" -q, --quiesce      configure quiescing of particular activities\n"
+		"                    (to list supported activities see --info)\n"
+		" -i, --info         show supported task isolation features\n"
+		" -a, --activate     activate isolation before exec\n"
+		" -I, --inherit      set inheritance across fork/exec.\n"
+		" 		     Two modes are available: conf, where only task\n"
+		"		     isolation configuration is inherited, or active,\n"
+		"		     where configuration and activation are inherited.\n"
+		));
+	printf(USAGE_HELP_OPTIONS(20));
+
+	fputs(USAGE_SEPARATOR, out);
+	fprintf(out, _(
+		"Configure task isolation and run a new command:\n"
+		"    %1$s -q vmstat_sync cmd\n"
+		"Configure, activate task isolation and run a new command:\n"
+		"    %1$s -a -q vmstat_sync cmd\n"
+		"To query the supported task isolation features:\n"
+		"    %1$s -i\n"),
+		program_invocation_short_name);
+
+	printf(USAGE_MAN_TAIL("chisol(1)"));
+	exit(EXIT_SUCCESS);
+}
+
+struct isol_feat_name {
+	int val;
+	char *name;
+};
+
+struct isol_feat_name featnames[] = {
+	{ ISOL_F_QUIESCE, "quiesce" },
+};
+
+struct isol_feat_name qfeatnames[] = {
+	{ ISOL_F_QUIESCE_VMSTATS, "vmstat_sync" },
+};
+
+#define SSZ sizeof(struct isol_feat_name)
+
+static char *featname(int val, struct isol_feat_name *fnames,
+		      unsigned int nrentries)
+{
+	unsigned int i;
+	char *name;
+
+	for (i = 0; i < nrentries; i++) {
+		struct isol_feat_name *f = &fnames[i];
+
+		if (f->val == val)
+			return strdup(f->name);
+	}
+
+	name = malloc(100);
+	snprintf(name, 100, "0x%x\n", val);
+
+	return name;
+}
+
+static void __attribute__((__noreturn__)) task_isol_info(void)
+{
+	int ret;
+	unsigned int i, j;
+	unsigned long long feats = 0;
+
+	FILE *out = stdout;
+
+	/* Retrieve supported task isolation features */
+	ret = prctl(PR_ISOL_FEAT_GET, 0, &feats, 0, 0);
+	if (ret == -1) {
+		perror(_("prctl PR_ISOL_FEAT_GET"));
+		exit(EXIT_FAILURE);
+	}
+
+	for (i = 0; i < 16; i++) {
+		if (feats & (1<<i)) {
+			char *fn;
+			unsigned long long featmask;
+			struct task_isol_quiesce_extensions qext;
+
+			fn = featname(1<<i, featnames, sizeof(featnames)/SSZ);
+
+			fprintf(out, "%s: ", fn);
+			free(fn);
+
+			if (i != 0)
+				continue;
+
+			ret = prctl(PR_ISOL_FEAT_GET, (1<<i), &qext, 0, 0);
+			if (ret == -1) {
+				perror(_("prctl PR_ISOL_FEAT_GET"));
+				exit(EXIT_FAILURE);
+			}
+
+			featmask = qext.supported_quiesce_bits;
+			for (j = 0; j < 16; j++) {
+				if (featmask & (1<<j)) {
+					fn = featname(1<<j, qfeatnames,
+						      sizeof(qfeatnames)/SSZ);
+					fprintf(out, "%s ", fn);
+					free(fn);
+				}
+			}
+		}
+	}
+
+	fprintf(out, "\n");
+	exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+	int c, ret, activate = 0;
+	short int inherit_mask = 0;
+	unsigned long long quiesce_act_mask = 0;
+	char *subopts;
+	char *value;
+
+	static const struct option longopts[] = {
+		{ "quiesce",	required_argument, NULL, 'q' },
+		{ "info",	no_argument, 	   NULL, 'i' },
+		{ "inherit",	required_argument, NULL, 'I' },
+		{ "activate",	no_argument,	   NULL, 'a' },
+		{ "help",	no_argument,	   NULL, 'h' },
+		{ "version",	no_argument,	   NULL, 'V' },
+		{ NULL,		no_argument,       NULL,  0  }
+	};
+
+	enum {
+		VMSTAT_SYNC_OPT = 0,
+	};
+	char *const token[] = {
+		[VMSTAT_SYNC_OPT]   = "vmstat_sync",
+		NULL
+	};
+
+	enum {
+		INHERIT_CONF = 0,
+		INHERIT_ACTIVE,
+
+	};
+	char *const itoken[] = {
+		[INHERIT_CONF]   = "conf",
+		[INHERIT_ACTIVE] = "active",
+		NULL
+	};
+
+
+	setlocale(LC_ALL, "");
+	bindtextdomain(PACKAGE, LOCALEDIR);
+	textdomain(PACKAGE);
+	close_stdout_atexit();
+
+	while ((c = getopt_long(argc, argv, "+q:I:iahV", longopts, NULL)) != -1) {
+	switch (c) {
+		case 'q':
+			subopts = optarg;
+			while (*subopts != '\0') {
+				switch (getsubopt(&subopts, token, &value)) {
+					case VMSTAT_SYNC_OPT:
+						quiesce_act_mask |=
+							ISOL_F_QUIESCE_VMSTATS;
+						break;
+					default:
+						fprintf(stderr, "Unknown "
+							"quiesce activity "
+							"/%s/\n", value);
+						errtryhelp(EXIT_FAILURE);
+						break;
+				}
+			}
+			break;
+		case 'I':
+			subopts = optarg;
+			while (*subopts != '\0') {
+				switch (getsubopt(&subopts, itoken, &value)) {
+					case INHERIT_CONF:
+						inherit_mask |= ISOL_INHERIT_CONF;
+						break;
+					case INHERIT_ACTIVE:
+						inherit_mask |= ISOL_INHERIT_CONF;
+						inherit_mask |= ISOL_INHERIT_ACTIVE;
+						break;
+					default:
+						fprintf(stderr, "Unknown "
+							"inheritance "
+							"/%s/\n", value);
+						errtryhelp(EXIT_FAILURE);
+						break;
+				}
+			}
+			break;
+		case 'i':
+			task_isol_info();
+			break;
+		case 'a':
+			activate = 1;
+			break;
+		case 'V':
+			print_version(EXIT_SUCCESS);
+		case 'h':
+			usage();
+		default:
+			errtryhelp(EXIT_FAILURE);
+		}
+	}
+
+	if (argc - optind < 1) {
+		warnx(_("bad usage"));
+		errtryhelp(EXIT_FAILURE);
+	}
+
+	if (quiesce_act_mask) {
+		struct task_isol_quiesce_control qctrl;
+
+		qctrl.quiesce_mask = quiesce_act_mask;
+		ret = prctl(PR_ISOL_CFG_SET, I_CFG_FEAT, ISOL_F_QUIESCE, &qctrl, 0);
+		if (ret == -1) {
+			perror("prctl PR_ISOL_CFG_SET");
+			exit(EXIT_FAILURE);
+        	}
+	}
+
+	if (activate && quiesce_act_mask) {
+		unsigned long long activate_mask = ISOL_F_QUIESCE;
+
+		ret = prctl(PR_ISOL_ACTIVATE_SET, &activate_mask, 0, 0, 0);
+		if (ret == -1) {
+			perror("prctl PR_ISOL_ACTIVATE_SET (ISOL_F_QUIESCE)");
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	if (inherit_mask != 0) {
+		struct task_isol_inherit_control i_ctrl;
+
+		memset(&i_ctrl, 0, sizeof(i_ctrl));
+		i_ctrl.inherit_mask = inherit_mask;
+
+		ret = prctl(PR_ISOL_CFG_SET, I_CFG_INHERIT, &i_ctrl, 0, 0);
+		if (ret == -1) {
+			perror("prctl PR_ISOL_CFG_SET (I_CFG_INHERIT)");
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	argv += optind;
+	execvp(argv[0], argv);
+	errexec(argv[0]);
+
+	return EXIT_SUCCESS;
+}
+
diff -Nur util-linux.orig/schedutils/Makemodule.am util-linux/schedutils/Makemodule.am
--- util-linux.orig/schedutils/Makemodule.am	2021-10-07 14:15:15.334935842 -0300
+++ util-linux/schedutils/Makemodule.am	2021-10-05 15:11:54.199269088 -0300
@@ -29,3 +29,11 @@
 uclampset_SOURCES = schedutils/uclampset.c schedutils/sched_attr.h
 uclampset_LDADD = $(LDADD) libcommon.la
 endif
+
+if BUILD_CHISOL
+usrbin_exec_PROGRAMS += chisol
+#MANPAGES += schedutils/chisol.1
+#dist_noinst_DATA += schedutils/chisol.1.adoc
+chisol_SOURCES = schedutils/chisol.c
+chisol_LDADD = $(LDADD) libcommon.la
+endif

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ