From 5ee5e9157572fe9047a12be75af60fa32f0a60a8 Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Sat, 13 Oct 2007 12:13:30 +0000 Subject: [PATCH] Add support for the OOM bias, and vmemctrl to control it. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2619 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- kernel/context_cmd.h | 13 +++- kernel/switch.h | 2 + lib/Makefile-files | 6 +- lib/syscall_getbadness-v23.hc | 33 ++++++++ lib/syscall_getbadness.c | 39 ++++++++++ lib/syscall_setbadness-v23.hc | 30 +++++++ lib/syscall_setbadness.c | 39 ++++++++++ lib/vserver.h | 3 + src/Makefile-files | 14 +++- src/vmemctrl.c | 177 ++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 350 insertions(+), 6 deletions(-) create mode 100644 lib/syscall_getbadness-v23.hc create mode 100644 lib/syscall_getbadness.c create mode 100644 lib/syscall_setbadness-v23.hc create mode 100644 lib/syscall_setbadness.c create mode 100644 src/vmemctrl.c diff --git a/kernel/context_cmd.h b/kernel/context_cmd.h index 354b29d..d1ec86b 100644 --- a/kernel/context_cmd.h +++ b/kernel/context_cmd.h @@ -79,11 +79,22 @@ struct vcmd_ctx_caps_v1 { /* bcaps commands */ #define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0) -#define VCMD_set_bcaps VC_CMD(FLAGS,10, 0) +#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0) struct vcmd_bcaps { uint64_t bcaps; uint64_t bmask; }; + + +/* OOM badness */ + +#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0) +#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0) + +struct vcmd_badness_v0 { + int64_t bias; +}; + #endif /* _VX_CONTEXT_CMD_H */ diff --git a/kernel/switch.h b/kernel/switch.h index ee6defc..6836c27 100644 --- a/kernel/switch.h +++ b/kernel/switch.h @@ -60,6 +60,8 @@ #define VC_CAT_SCHED 14 +#define VC_CAT_MEMCTRL 20 + #define VC_CAT_VNET 25 #define VC_CAT_NETALT 26 #define VC_CAT_NETMIG 27 diff --git a/lib/Makefile-files b/lib/Makefile-files index de7dfe6..57b182a 100644 --- a/lib/Makefile-files +++ b/lib/Makefile-files @@ -152,7 +152,11 @@ lib_v23_SRCS = lib/syscall_tagmigrate-v23.hc \ lib/syscall_tagmigrate.c \ lib/syscall_tagcreate.c \ lib/syscall_tasktag-v23.hc \ - lib/syscall_tasktag.c + lib/syscall_tasktag.c \ + lib/syscall_getbadness.c \ + lib/syscall_getbadness-v23.hc \ + lib/syscall_setbadness.c \ + lib/syscall_setbadness-v23.hc if ENSC_HAVE_C99_COMPILER lib_v13_SRCS += lib/syscall_adddlimit-v13.hc \ diff --git a/lib/syscall_getbadness-v23.hc b/lib/syscall_getbadness-v23.hc new file mode 100644 index 0000000..acb8712 --- /dev/null +++ b/lib/syscall_getbadness-v23.hc @@ -0,0 +1,33 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_get_badness_v23(xid_t xid, int64_t *badness) +{ + struct vcmd_badness_v0 data; + int ret; + ret = vserver(VCMD_get_badness, xid, &data); + if (ret) + return ret; + *badness = data.bias; + return 0; +} diff --git a/lib/syscall_getbadness.c b/lib/syscall_getbadness.c new file mode 100644 index 0000000..6054151 --- /dev/null +++ b/lib/syscall_getbadness.c @@ -0,0 +1,39 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "virtual.h" +#include "vserver-internal.h" + +#if defined(VC_ENABLE_API_V23) +# include "syscall_getbadness-v23.hc" +#endif + +#if defined(VC_ENABLE_API_V23) + +int +vc_get_badness(xid_t xid, int64_t *badness) +{ + CALL_VC(CALL_VC_V23(vc_get_badness, xid, badness)); +} + +#endif diff --git a/lib/syscall_setbadness-v23.hc b/lib/syscall_setbadness-v23.hc new file mode 100644 index 0000000..7fc5736 --- /dev/null +++ b/lib/syscall_setbadness-v23.hc @@ -0,0 +1,30 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_set_badness_v23(xid_t xid, int64_t badness) +{ + struct vcmd_badness_v0 data = { + .bias = badness, + }; + return vserver(VCMD_set_badness, xid, &data); +} diff --git a/lib/syscall_setbadness.c b/lib/syscall_setbadness.c new file mode 100644 index 0000000..539f938 --- /dev/null +++ b/lib/syscall_setbadness.c @@ -0,0 +1,39 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "virtual.h" +#include "vserver-internal.h" + +#if defined(VC_ENABLE_API_V23) +# include "syscall_setbadness-v23.hc" +#endif + +#if defined(VC_ENABLE_API_V23) + +int +vc_set_badness(xid_t xid, int64_t badness) +{ + CALL_VC(CALL_VC_V23(vc_set_badness, xid, badness)); +} + +#endif diff --git a/lib/vserver.h b/lib/vserver.h index 890bd1a..82642e2 100644 --- a/lib/vserver.h +++ b/lib/vserver.h @@ -823,6 +823,9 @@ extern "C" { int vc_set_mapping(xid_t xid, const char *device, const char *target, uint32_t flags); int vc_unset_mapping(xid_t xid, const char *device, const char *target, uint32_t flags); + int vc_get_badness(xid_t xid, int64_t *badness); + int vc_set_badness(xid_t xid, int64_t badness); + /** \brief Information about parsing errors * \ingroup helper diff --git a/src/Makefile-files b/src/Makefile-files index c374c11..34a5be1 100644 --- a/src/Makefile-files +++ b/src/Makefile-files @@ -83,7 +83,8 @@ DIETPROGS += src/chcontext-compat \ src/vclone \ src/h2ext \ src/vtag \ - src/vspace + src/vspace \ + src/vmemctrl if ENSC_CAN_BEECRYPT_WITH_DIETLIBC DIETPROGS += src/vhashify @@ -165,6 +166,7 @@ sbin_PROGRAMS += src/exec-cd \ src/vdevmap \ src/vtag \ src/vspace \ + src/vmemctrl \ $(src_sbin_CXX_X_PROGS) if ENSC_HAVE_C99_COMPILER @@ -350,9 +352,13 @@ src_vtag_SOURCES = src/vtag.c src_vtag_LDADD = $(VSERVER_LDADDS) src_vtag_LDFLAGS = $(VSERVER_LDADDS) -src_vspace_SOURCES = src/vspace.c -src_vspace_LDADD = $(VSERVER_LDADDS) $(LIBINTERNAL) -src_vspace_LDFLAGS = $(VSERVER_LDFLGS) +src_vspace_SOURCES = src/vspace.c +src_vspace_LDADD = $(VSERVER_LDADDS) $(LIBINTERNAL) +src_vspace_LDFLAGS = $(VSERVER_LDFLGS) + +src_vmemctrl_SOURCES = src/vmemctrl.c +src_vmemctrl_LDADD = $(VSERVER_LDADDS) $(LIBINTERNAL) +src_vmemctrl_LDFLAGS = $(VSERVER_LDFLGS) EXTRA_PROGRAMS += $(src_sbin_CXX_PROGS) $(src_pkglib_CXX_PROGS) diff --git a/src/vmemctrl.c b/src/vmemctrl.c new file mode 100644 index 0000000..46a5e63 --- /dev/null +++ b/src/vmemctrl.c @@ -0,0 +1,177 @@ +// $Id$ + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "util.h" + +#include + +#include +#include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_PREFIX "vmemctrl: " +#define ENSC_WRAPPERS_VSERVER 1 +#define ENSC_WRAPPERS_UNISTD 1 +#include "wrappers.h" + +#define CMD_HELP 0x1000 +#define CMD_VERSION 0x1001 + +#define CMD_SET 0x2000 +#define CMD_GET 0x2001 + +#define CMD_XID 0x4000 +#define CMD_BADNESS 0x4001 + +int wrapper_exit_code = 255; + + +static struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "set", no_argument, 0, CMD_SET }, + { "get", no_argument, 0, CMD_GET }, + { "xid", required_argument, 0, CMD_XID }, + { "badness", required_argument, 0, CMD_BADNESS }, + { 0,0,0,0 } +}; + +struct Arguments { + xid_t xid; + int64_t badness; + bool do_set; + bool do_get; +}; + +static void +showHelp(int fd, char const *cmd, int res) +{ + WRITE_MSG(fd, "Usage:\n "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " (--set|--get) [--xid ] [--badness ]\n" + " [--] [ *]\n\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + + exit(res); +} + +static void +showVersion() +{ + WRITE_MSG(1, + "vmemctrl " VERSION " -- \n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2007 Daniel Hokka Zakrisson\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} + +static inline void +doset(struct Arguments *args) +{ + if (vc_set_badness(args->xid, args->badness) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_set_badness()"); + exit(wrapper_exit_code); + } +} + +static inline void +doget(struct Arguments *args) +{ + int64_t badness; + char buf[32]; + size_t l; + if (vc_get_badness(args->xid, &badness) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_get_badness()"); + exit(wrapper_exit_code); + } + l = utilvserver_fmt_int64(buf, badness); + buf[l] = '\0'; + WRITE_STR(1, buf); + WRITE_MSG(1, "\n"); +} + +int main (int argc, char *argv[]) +{ + struct Arguments args = { + .do_set = false, + .do_get = false, + .xid = VC_NOCTX, + .badness = 0, + }; + + while (1) { + int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0); + if (c==-1) break; + + switch (c) { + case CMD_HELP : showHelp(1, argv[0], 0); + case CMD_VERSION : showVersion(); + case CMD_XID : args.xid = Evc_xidopt2xid(optarg,true); break; + case CMD_SET : args.do_set = true; break; + case CMD_GET : args.do_get = true; break; + case CMD_BADNESS : { + char *endptr; + args.badness = strtoll(optarg, &endptr, 0); + if (*endptr) { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Badness '"); + WRITE_STR(2, optarg); + WRITE_MSG(2, "' is not an integer\n"); + exit(wrapper_exit_code); + } + break; + } + default : + WRITE_MSG(2, "Try '"); + WRITE_STR(2, argv[0]); + WRITE_MSG(2, " --help' for more information.\n"); + exit(wrapper_exit_code); + break; + } + } + + if (args.xid == VC_NOCTX) args.xid = Evc_get_task_xid(0); + + if (!args.do_set && !args.do_get) { + WRITE_MSG(2, "No operation specified; try '--help' for more information\n"); + exit(wrapper_exit_code); + } + else if (((args.do_set ? 1 : 0) + (args.do_get ? 1 : 0)) > 1) { + WRITE_MSG(2, "Multiple operations specified; try '--help' for more information\n"); + exit(wrapper_exit_code); + } + + if (args.do_set) + doset(&args); + else if (args.do_get) + doget(&args); + + if (optind != argc) + Eexecvp (argv[optind],argv+optind); + return EXIT_SUCCESS; +} -- 1.8.1.5