typedef uint32_t nid_t;
#endif
+#ifndef HAVE_TAG_T
+#include <stdint.h>
+typedef uint32_t tag_t;
+#endif
+
#if defined(__dietlibc__)
#define TEMP_FAILURE_RETRY(expression) \
AC_CHECK_DECLS(MS_MOVE,,,[#include <linux/fs.h>])
AC_CHECK_TYPES(xid_t,,,[#include <sys/types.h>])
AC_CHECK_TYPES(nid_t,,,[#include <sys/types.h>])
+AC_CHECK_TYPES(tag_t,,,[#include <sys/types.h>])
AC_CHECK_HEADERS([sys/capability.h])
core @SBINDIR@/vserver-info
base @SBINDIR@/vserver-stat
base @SBINDIR@/vsomething
+core @SBINDIR@/vtag
base @SBINDIR@/vtop
core @SBINDIR@/vuname
build @SBINDIR@/vupdateworld
return res;
}
+inline static WRAPPER_DECL tag_t
+Evc_tag_create(tag_t tag)
+{
+ register tag_t res = vc_tag_create(tag);
+ FatalErrnoError(res==VC_NOCTX, "vc_tag_create()");
+ return res;
+}
+
inline static WRAPPER_DECL void
Evc_ctx_migrate(xid_t xid, uint_least64_t flags)
{
}
inline static WRAPPER_DECL void
+Evc_tag_migrate(tag_t tag)
+{
+ FatalErrnoError(vc_tag_migrate(tag)==-1, "vc_tag_migrate()");
+}
+
+inline static WRAPPER_DECL void
Evc_get_cflags(xid_t xid, struct vc_ctx_flags *flags)
{
FatalErrnoError(vc_get_cflags(xid, flags)==-1, "vc_get_cflags()");
}
return rc;
}
+
+inline static WRAPPER_DECL tag_t
+Evc_tagopt2tag(char const *id, bool honor_static)
+{
+ char const * err;
+ tag_t rc = vc_tagopt2tag(id, honor_static, &err);
+ if (__builtin_expect(rc==VC_NOCTX,0)) {
+ ENSC_DETAIL1(msg, "vc_tagopt2tag", id, 1);
+ FatalErrnoErrorFail(msg);
+ }
+ return rc;
+}
#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
#define VC_VERSION(c) ((c) & 0xFFF)
-#define VC_CMD(c,i,v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
+#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
| (((i) & 0xFF) << 16) | ((v) & 0xFFF))
/*
NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
| 24| 25| 26| 27| 28| 29| | 30| 31|
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+
- DISK | | | | |DLIMIT | | |INODE | |
+ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+
OTHER |VSTAT | | | | | | |VINFO | |
#define VC_CAT_NETMIG 27
#define VC_CAT_NETCTRL 28
+#define VC_CAT_TAGMIG 35
#define VC_CAT_DLIMIT 36
#define VC_CAT_INODE 38
#define VC_CAT_SYSTEST 61
#define VC_CAT_COMPAT 63
-/* interface version */
-
-#define VCI_VERSION 0x00020102
-#define VCI_LEGACY_VERSION 0x000100FF
-
/* query version */
#define VCMD_get_version VC_CMD(VERSION, 0, 0)
--- /dev/null
+#ifndef _VX_TAG_CMD_H
+#define _VX_TAG_CMD_H
+
+
+/* vinfo commands */
+
+#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
+
+
+/* context commands */
+
+#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
+
+#endif /* _VX_TAG_CMD_H */
lib/getvservername.c \
lib/getvservervdir.c \
lib/xidopt2xid.c \
- lib/nidopt2nid.c
+ lib/nidopt2nid.c \
+ lib/tagopt2tag.c
lib_v11_SRCS = lib/syscall_rlimit.c \
lib/syscall_rlimit-v11.hc \
lib/syscall_kill.c \
lib_netv2_SRCS = lib/syscall_netadd-netv2.hc \
lib/syscall_netremove-netv2.hc
+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
+
if ENSC_HAVE_C99_COMPILER
lib_v13_SRCS += lib/syscall_adddlimit-v13.hc \
lib/syscall_adddlimit.c \
$(lib_v21_SRCS) \
$(lib_v22_SRCS) \
$(lib_netv2_SRCS) \
+ $(lib_v23_SRCS) \
$(ensc_fmt_SRCS)
include_HEADERS += lib/vserver.h
// check if expected ctx == actual ctx (but only when this check is
// request)
if (validate_result &&
- vc_getVserverCtx(path, vcCFG_RECENT_FULL, false, 0)!=ctx) return 0;
+ vc_getVserverCtx(path, vcCFG_RECENT_FULL, false, 0, vcCTX_XID)!=ctx) return 0;
if (style) *style = vcCFG_RECENT_FULL;
return strdup(path);
if (vc_get_vhi_name(ctx, vcVHI_CONTEXT, buf, sizeof buf)!=-1 &&
(!validate_result ||
- vc_getVserverCtx(buf, vcCFG_RECENT_FULL, false, 0)==ctx)) {
+ vc_getVserverCtx(buf, vcCFG_RECENT_FULL, false, 0, vcCTX_XID)==ctx)) {
if (style) *style = vcCFG_RECENT_FULL;
return strdup(buf);
}
}
xid_t
-vc_getVserverCtx(char const *id, vcCfgStyle style, bool honor_static, bool *is_running)
+vc_getVserverCtx(char const *id, vcCfgStyle style, bool honor_static, bool *is_running,
+ vcCtxType type)
{
size_t l1 = strlen(id);
- char buf[sizeof(CONFDIR "//") + l1 + sizeof("/context")];
+ char buf[sizeof(CONFDIR "//") + l1 + sizeof("/ncontext")];
if (style==vcCFG_NONE || style==vcCFG_AUTO)
style = vc_getVserverCfgStyle(id);
// when context information could be read, we have to verify that
// it belongs to a running vserver and the both vservers are
// identically
- if (res!=VC_NOCTX) {
+ if (res!=VC_NOCTX && type == vcCTX_XID) {
char *cur_name;
struct vc_vx_info info;
*is_running = res!=VC_NOCTX;
if (res==VC_NOCTX && honor_static) {
- memcpy(buf+idx, "/context", 9); // appends '\0' too
+ switch (type) {
+ case vcCTX_XID:
+ memcpy(buf+idx, "/context", 9); // appends '\0' too
+ break;
+ case vcCTX_NID:
+ memcpy(buf+idx, "/ncontext", 10);
+ break;
+ case vcCTX_TAG:
+ memcpy(buf+idx, "/tag", 5);
+ break;
+ }
res = getCtxFromFile(buf);
}
bool
vc_isSupported(vcFeatureSet feature)
{
- int ver = vc_get_version();
+ int ver = vc_get_version();
+ vc_vci_t conf = vc_get_vci();
if (ver==-1) return false;
+ if (conf==(vc_vci_t)-1) conf = 0;
switch (feature) {
case vcFEATURE_COMPAT : return true;
case vcFEATURE_SCHED : return ver >= 0x00020000; // todo
case vcFEATURE_VNET : return ver >= 0x00020001;
case vcFEATURE_VSTAT : return ver >= 0x00020103;
+ case vcFEATURE_PPTAG : return conf & VC_VCI_PPTAG;
default : assert(false);
}
DECL(VKILL), DECL(IATTR), DECL(RLIMIT), DECL(COMPAT),
DECL(MIGRATE), DECL(NAMESPACE), DECL(SCHED), DECL(VINFO),
DECL(VHI), DECL(VSHELPER0), DECL(VSHELPER), DECL(VWAIT),
- DECL(VNET), DECL(VSTAT),
+ DECL(VNET), DECL(VSTAT), DECL(PPTAG),
};
bool
#include <string.h>
#include <stdlib.h>
+static nid_t
+getVserverNid(char const *id, bool honor_static, char const **err)
+{
+ *err = "vc_getVserverCtx";
+ return vc_getVserverCtx(id, vcCFG_AUTO, honor_static, 0, vcCTX_NID);
+}
+
nid_t
vc_nidopt2nid(char const *str, bool honor_static, char const **err_info)
{
err = "vc_get_task_nid()";
if (strcmp(str,"self")==0) res = vc_get_task_nid(0);
- else res = vc_xidopt2xid(str, honor_static, &err);
+ else if (str[0]==':') res = getVserverNid(str+1, honor_static, &err);
+ else {
+ char * endptr;
+ nid_t nid = strtol(str, &endptr, 10);
+
+ if (endptr!=str && (*endptr=='\0' || *endptr=='\n'))
+ res = nid;
+ else
+ res = getVserverNid(str, honor_static, &err);
+ }
if (res==VC_NOCTX && err_info) *err_info = err;
# include <config.h>
#endif
-static inline ALWAYSINLINE int
+static inline ALWAYSINLINE vc_vci_t
vc_get_vci_v21(int UNUSED tmp)
{
return vserver(VCMD_get_vci, 0, 0);
#if defined(VC_ENABLE_API_V21)
-int
+vc_vci_t
vc_get_vci()
{
CALL_VC(CALL_VC_V21(vc_get_vci, 0));
--- /dev/null
+// $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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "virtual.h"
+#include "vserver-internal.h"
+
+#if defined(VC_ENABLE_API_V23)
+# include "syscall_tagmigrate-v23.hc"
+#endif
+
+#if defined(VC_ENABLE_API_V23)
+
+int
+vc_tag_create(tag_t tag)
+{
+ CALL_VC(CALL_VC_TAG(vc_tag_migrate, tag));
+}
+
+#endif
--- /dev/null
+// $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 <config.h>
+#endif
+
+static inline ALWAYSINLINE int
+vc_tag_migrate_tag(tag_t tag)
+{
+ return vserver(VCMD_tag_migrate, TAG_USER2KERNEL(tag), NULL);
+}
--- /dev/null
+// $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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "virtual.h"
+#include "vserver-internal.h"
+
+#if defined(VC_ENABLE_API_V23)
+# include "syscall_tagmigrate-v23.hc"
+#endif
+
+#if defined(VC_ENABLE_API_V23)
+
+int
+vc_tag_migrate(tag_t tag)
+{
+ CALL_VC(CALL_VC_TAG(vc_tag_migrate, tag));
+}
+
+#endif
--- /dev/null
+// $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 <config.h>
+#endif
+
+static inline ALWAYSINLINE tag_t
+vc_get_task_tag_tag(pid_t pid)
+{
+ return vserver(VCMD_task_tag, pid, NULL);
+}
--- /dev/null
+// $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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "virtual.h"
+#include "vserver-internal.h"
+
+#if defined(VC_ENABLE_API_V23)
+# include "syscall_tasktag-v23.hc"
+#endif
+
+#if defined(VC_ENABLE_API_V23)
+
+tag_t
+vc_get_task_tag(pid_t pid)
+{
+ CALL_VC(CALL_VC_TAG(vc_get_task_tag, pid));
+}
+
+#endif
--- /dev/null
+// $Id$ --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include <string.h>
+#include <stdlib.h>
+
+static tag_t
+getVserverTag(char const *id, bool honor_static, char const **err)
+{
+ *err = "vc_getVserverCtx";
+ return vc_getVserverCtx(id, vcCFG_AUTO, honor_static, 0, vcCTX_TAG);
+}
+
+tag_t
+vc_tagopt2tag(char const *str, bool honor_static, char const **err_info)
+{
+ char const * err;
+ tag_t res = VC_NOCTX;
+
+ err = "vc_task_tag()";
+ if (strcmp(str,"self")==0) res = vc_get_task_tag(0);
+ else if (str[0]==':') res = getVserverTag(str+1, honor_static, &err);
+ else {
+ char * endptr;
+ tag_t tag = strtol(str, &endptr, 10);
+
+ if (endptr!=str && (*endptr=='\0' || *endptr=='\n'))
+ res = tag;
+ else
+ res = getVserverTag(str, honor_static, &err);
+ }
+
+ if (res==VC_NOCTX && err_info) *err_info = err;
+
+ return res;
+}
#include <kernel/sched_cmd.h>
#include <kernel/signal_cmd.h>
#include <kernel/device_cmd.h>
+#include <kernel/tag_cmd.h>
#include <kernel/legacy.h>
# define CALL_VC(...) \
do { \
int ver = utilvserver_checkCompatVersion(); \
- uint_least32_t UNUSED conf = utilvserver_checkCompatConfig(); \
+ vc_vci_t UNUSED conf = utilvserver_checkCompatConfig(); \
if (ver==-1) return -1; \
VC_SUFFIX, __VA_ARGS__, VC_PREFIX; \
errno = ENOSYS; \
# define CALL_VC_SPACES(F,...) CALL_VC_NOOP
#endif
+#if defined(VC_ENABLE_API_V23)
+# define CALL_VC_TAG(F,...) CALL_VC_GENERAL_CONFIG(VC_VCI_PPTAG, tag, F, __VA_ARGS__)
+#else
+# define CALL_VC_TAG(F,...) CALL_VC_NOOP
+#endif
+
#ifdef VC_ENABLE_API_V22
# define CALL_VC_V22(F,...) CALL_VC_GENERAL(0x00020200, v22, F, __VA_ARGS__)
#else
#endif
#if 1
+# define TAG_KERNEL2USER(X) (((X)==(uint32_t)(-1)) ? VC_NOCTX : \
+ ((X)==(uint32_t)(-2)) ? VC_SAMECTX : \
+ (tag_t)(X))
+
+# define TAG_USER2KERNEL(X) (((X)==VC_DYNAMIC_XID) ? (uint32_t)(-1) : \
+ ((X)==VC_SAMECTX) ? (uint32_t)(-2) : \
+ (uint32_t)(X))
+#else
+# define TAG_USER2KERNEL(X) (X)
+# define TAG_KERNEL2USER(X) (X)
+#endif
+
+#if 1
# define EXT2FLAGS_USER2KERNEL(X) (((X) & ~(VC_IMMUTABLE_FILE_FL|VC_IMMUTABLE_LINK_FL)) | \
((X) & VC_IMMUTABLE_FILE_FL ? EXT2_IMMUTABLE_FILE_FL : 0) | \
((X) & VC_IMMUTABLE_LINK_FL ? EXT2_IMMUTABLE_LINK_FL : 0))
#define VC_VCI_NO_DYNAMIC (1 << 0)
#define VC_VCI_SPACES (1 << 10)
#define VC_VCI_NETV2 (1 << 11)
+#define VC_VCI_PPTAG (1 << 28)
// the device mapping flags
#ifdef IS_DOXYGEN
typedef an_unsigned_integer_type xid_t;
typedef an_unsigned_integer_type nid_t;
+typedef an_unsigned_integer_type tag_t;
#endif
#ifdef __cplusplus
*/
int vc_get_version();
+ typedef uint64_t vc_vci_t;
/** \brief Returns the kernel configuration bits
* \ingroup syscalls
* \returns The kernel configuration bits
*/
- int vc_get_vci();
+ vc_vci_t vc_get_vci();
/** \brief Moves current process into a context
* \ingroup syscalls
uint_least32_t flags,
struct vc_ctx_dlimit *limits) VC_ATTR_NONNULL((1));
+ /** Get the filesystem tag for a process. */
+ tag_t vc_get_task_tag(pid_t pid);
+
+ /** Create a new filesystem tag space. */
+ int vc_tag_create(tag_t tag);
+
+ /** Migrate to an existing filesystem tag space. */
+ int vc_tag_migrate(tag_t tag);
+
/* scheduler related syscalls */
struct vc_set_sched {
uint_least32_t set_mask;
vcFEATURE_COMPAT, vcFEATURE_MIGRATE, vcFEATURE_NAMESPACE,
vcFEATURE_SCHED, vcFEATURE_VINFO, vcFEATURE_VHI,
vcFEATURE_VSHELPER0, vcFEATURE_VSHELPER, vcFEATURE_VWAIT,
- vcFEATURE_VNET, vcFEATURE_VSTAT }
+ vcFEATURE_VNET, vcFEATURE_VSTAT, vcFEATURE_PPTAG, }
vcFeatureSet;
bool vc_isSupported(vcFeatureSet) VC_ATTR_CONST;
xid_t vc_xidopt2xid(char const *, bool honor_static, char const **err_info);
/** Maps a nid given at '--nid' options to a nid_t */
nid_t vc_nidopt2nid(char const *, bool honor_static, char const **err_info);
+ /** Maps a tag given at '--tag' options to a tag_t */
+ tag_t vc_tagopt2tag(char const *, bool honor_static, char const **err_info);
vcCfgStyle vc_getVserverCfgStyle(char const *id);
* allocated and must be freed by the caller. */
char * vc_getVserverVdir(char const *id, vcCfgStyle style, bool physical);
+ typedef enum { vcCTX_XID = 1,
+ vcCTX_NID,
+ vcCTX_TAG,
+ } vcCtxType;
+
/** Returns the ctx of the given vserver. When vserver is not running and
* 'honor_static' is false, VC_NOCTX will be returned. Else, when
* 'honor_static' is true and a static assignment exists, those value will
* When 'is_running' is not null, the status of the vserver will be
* assigned to this variable. */
xid_t vc_getVserverCtx(char const *id, vcCfgStyle style,
- bool honor_static, bool /*@null@*/ *is_running);
+ bool honor_static, bool /*@null@*/ *is_running,
+ vcCtxType type);
/** Resolves the cfg-path of the vserver owning the given ctx. 'revdir' will
be used as the directory holding the mapping-links; when NULL, the
getVserverXid(char const *id, bool honor_static, char const **err)
{
*err = "vc_getVserverCtx";
- return vc_getVserverCtx(id, vcCFG_AUTO, honor_static, 0);
+ return vc_getVserverCtx(id, vcCFG_AUTO, honor_static, 0, vcCTX_XID);
}
xid_t
shift
done
-create_cmd=( $_VCONTEXT --create --silentexist
+create_cmd=( ${OPT_CTX:+$_VTAG --create --tag "$OPT_CTX" --silentexist --}
+ $_VCONTEXT --create --silentexist
${OPT_SILENT:+--silent}
${OPT_CTX:+--xid "$OPT_CTX"} )
${OPT_CAPS:+--bcap "${OPT_CAPS[*]}"}
${OPT_FLAGS:+--flag "${OPT_FLAGS[*]}"} )
-migrate_cmd=( $_VCONTEXT
+migrate_cmd=( $_VTAG --migrate --tag "$OPT_CTX"
+ --
+ $_VCONTEXT
${OPT_SILENT:+--silent}
${OPT_DISCONNECT:+--disconnect}
$OPT_INITPID )
_VSHELPER_SYNC="$__PKGLIBDIR/vshelper-sync"
_VSOMETHING="$__SBINDIR/vsomething"
_VSYSCTL="$__PKGLIBDIR/vsysctl"
+_VTAG="$__SBINDIR/vtag"
_VWAIT="$__SBINDIR/vwait"
_VUNAME="$__SBINDIR/vuname"
_VUNIFY="$__PKGLIBDIR/vunify"
declare -a OPTS_VATTRIBUTE=( --flag fakeinit )
declare -a OPTS_VSCHED=()
declare -a OPTS_ENV=()
+declare -a OPTS_VTAG_CREATE=()
+declare -a OPTS_VTAG_ENTER=()
declare -a STOPCMD_PREPARE=()
_HAVE_INTERFACE_OPTIONS=1
}
+function _generateTagOptions
+{
+ local vdir="$1"
+ local tag
+
+ getFileValue tag "$vdir/tag" "$vdir/context" || return 0
+
+ OPTS_VTAG_CREATE=( --tag "$tag" )
+ OPTS_VTAG_ENTER=( --tag "$tag" )
+}
+
function enableInterfaces
{
local i=0
_generateChcontextOptions "$1"
_generateScheduleOptions "$1"
_generatePersonalityOptions "$1"
+ _generateTagOptions "$1"
if test -n "$_IS_FAKEINIT"; then
CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
${NICE_CMD[@]} \
$_CHBIND "${CHBIND_OPTS[@]}" -- \
$_EXEC_ULIMIT "$VSERVER_DIR"/ulimits \
+ $_VTAG --create "${OPTS_VTAG_CREATE[@]}" -- \
$_VCONTEXT --create "${OPTS_VCONTEXT_CREATE[@]}" -- \
${OPTION_STRACE:+$_STRACE -fF -o /tmp/vserver-start.$$} \
${USE_VNAMESPACE:+$_VNAMESPACE --set -- } \
$_CHBIND "${CHBIND_OPTS[@]}" \
$_EXEC_ULIMIT "$VSERVER_DIR/ulimits" \
${USE_VNAMESPACE:+$_VNAMESPACE --enter "$S_CONTEXT" -- } \
+ $_VTAG --migrate "${OPTS_VTAG_ENTER[@]}" -- \
$_VCONTEXT $SILENT_OPT --migrate --chroot \
--xid "$S_CONTEXT" --uid "$user" "${OPTS_VCONTEXT_ENTER[@]}" -- \
"$@"
exec \
$_CHBIND "${CHBIND_OPTS[@]}" \
$_EXEC_ULIMIT "$VSERVER_DIR/ulimits" \
+ $_VTAG --migrate "${OPTS_VTAG_ENTER[@]}" -- \
$_VCONTEXT --create "${OPTS_VCONTEXT_CREATE[@]}" -- \
$_VUNAME --xid self --dir "$VSERVER_DIR"/uts --missingok -- \
$_VUNAME --xid self --set -t context="$VSERVER_DIR" -- \
src/vdevmap \
src/vsysctl \
src/vclone \
- src/h2ext
+ src/h2ext \
+ src/vtag
if ENSC_CAN_BEECRYPT_WITH_DIETLIBC
DIETPROGS += src/vhashify
src/nattribute \
src/naddress \
src/vdevmap \
+ src/vtag \
$(src_sbin_CXX_X_PROGS)
if ENSC_HAVE_C99_COMPILER
src_h2ext_LDADD = $(LIBINTERNAL) $(VSERVER_LDADDS)
src_h2ext_LDFLAGS = $(VSERVER_LDFLGS)
+src_vtag_SOURCES = src/vtag.c
+src_vtag_LDADD = $(VSERVER_LDADDS)
+src_vtag_LDFLAGS = $(VSERVER_LDADDS)
+
EXTRA_PROGRAMS += $(src_sbin_CXX_PROGS) $(src_pkglib_CXX_PROGS)
TESTS_ENVIRONMENT += srctestsuitedir=$(top_builddir)/src/testsuite
tgXID, tgUTS, tgSYSINFO,
tgFEATURE, tgCANONIFY,
tgVERIFYCAP, tgXIDTYPE, tgVERIFYPROC,
+ tgNID, tgTAG,
} VserverTag;
static struct {
{ "VERIFYCAP", tgVERIFYCAP, "test if the kernel supports linux capabilities" },
{ "VERIFYPROC", tgVERIFYPROC, "test if /proc can be read by contexts!=0" },
{ "XIDTYPE", tgXIDTYPE, "returns the type of the given XID" },
+ { "NID", tgNID, "outputs the network context-id of the given pid" },
+ { "TAG", tgTAG, "outputs the filesystem tag of the given pid" },
};
int wrapper_exit_code = 1;
return buf;
}
-static char *
-getXid(char *buf, char const *pid_str)
+static inline char *
+getCtxId(char *buf, const char *pid_str, xid_t (*get_id)(pid_t pid), const char *err_str)
{
pid_t pid = atoi(pid_str);
- xid_t xid = vc_get_task_xid(pid);
+ xid_t xid = get_id(pid);
- if (xid==VC_NOCTX) perror("vc_get_task_xid()");
+ if (xid==VC_NOCTX) perror(err_str);
else {
utilvserver_fmt_long(buf, xid);
return buf;
}
static char *
+getXid(char *buf, char const *pid_str)
+{
+ return getCtxId(buf, pid_str, vc_get_task_xid, "vc_get_task_xid()");
+}
+
+static char *
+getNid(char *buf, const char *pid_str)
+{
+ return getCtxId(buf, pid_str, vc_get_task_nid, "vc_get_task_nid()");
+}
+
+static char *
+getTag(char *buf, const char *pid_str)
+{
+ return getCtxId(buf, pid_str, vc_get_task_tag, "vc_get_task_tag()");
+}
+
+static char *
getPXid(char UNUSED *buf, char const UNUSED *vserver)
{
// TODO: implement me when available
getContext(char *buf, char const *vserver, bool allow_only_static)
{
xid_t xid = vc_getVserverCtx(vserver, vcCFG_AUTO,
- allow_only_static, 0);
+ allow_only_static, 0, vcCTX_XID);
if (xid==VC_NOCTX) return 0;
utilvserver_fmt_long(buf, xid);
if (isNumber(vserver, &xid, true) && xid>=0)
res = (vc_get_vx_info(xid, &info)==-1) ? 0 : "1";
else
- res = (vc_getVserverCtx(vserver, vcCFG_AUTO, false, 0)==VC_NOCTX) ? 0 : "1";
+ res = (vc_getVserverCtx(vserver, vcCFG_AUTO, false, 0, vcCTX_XID)==VC_NOCTX) ? 0 : "1";
break;
}
case tgFEATURE : return testFeature(argc,argv); break;
case tgVERIFYCAP : return verifyCap() ? 0 : 1; break;
case tgVERIFYPROC : return verifyProc() ? 0 : 1; break;
+ case tgNID : res = getNid(buf, vserver); break;
+ case tgTAG : res = getTag(buf, vserver); break;
default : {
--- /dev/null
+// $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 <config.h>
+#endif
+
+#include "util.h"
+
+#include <vserver.h>
+#include <getopt.h>
+#include <errno.h>
+#include <sys/types.h>
+
+
+#define ENSC_WRAPPERS_PREFIX "vtag: "
+#define ENSC_WRAPPERS_VSERVER 1
+#include <wrappers.h>
+
+#define CMD_HELP 0x1000
+#define CMD_VERSION 0x1001
+#define CMD_TAG 0x4000
+#define CMD_CREATE 0x4001
+#define CMD_MIGRATE 0x4002
+#define CMD_SILENTEXIST 0x4003
+
+
+struct option const
+CMDLINE_OPTIONS[] = {
+ { "help", no_argument, 0, CMD_HELP },
+ { "version", no_argument, 0, CMD_VERSION },
+ { "tag", required_argument, 0, CMD_TAG },
+ { "create", no_argument, 0, CMD_CREATE },
+ { "migrate", no_argument, 0, CMD_MIGRATE },
+ { "silentexist", no_argument, 0, CMD_SILENTEXIST },
+ { 0,0,0,0 },
+};
+
+struct Arguments {
+ bool do_create;
+ bool do_migrate;
+ bool is_silentexist;
+ int verbosity;
+ tag_t tag;
+};
+
+int wrapper_exit_code = 255;
+
+static void
+showHelp(int fd, char const *cmd, int res)
+{
+ WRITE_MSG(fd, "Usage:\n ");
+ WRITE_STR(fd, cmd);
+ WRITE_MSG(fd,
+ " (--create|--migrate) --tag <tag> <opts>* [--] <program> <args>*\n "
+ "\n"
+ "<opts> can be:\n"
+ " --silentexist ... be silent when context exists already; useful\n"
+ " for '--create' only\n"
+ "\n"
+ "'vtag --create' exits with code 254 iff the context exists already.\n"
+ "\n"
+ "Please report bugs to " PACKAGE_BUGREPORT "\n");
+
+ exit(res);
+}
+
+static void
+showVersion()
+{
+ WRITE_MSG(1,
+ "vtag " VERSION " -- sets the process's filesystem tag\n"
+ "This program is part of " PACKAGE_STRING "\n\n"
+ "Copyright (C) 2007 Daniel Hokka Zakrisson\n"
+ VERSION_COPYRIGHT_DISCLAIMER);
+ exit(0);
+}
+
+static inline ALWAYSINLINE int
+doit(struct Arguments const *args, char *argv[])
+{
+ tag_t tag;
+
+ if (!vc_isSupported(vcFEATURE_PPTAG))
+ goto exec;
+
+ if (args->do_create) {
+ tag = vc_tag_create(args->tag);
+ if (tag==VC_NOCTX) {
+ switch (errno) {
+ case EEXIST :
+ if (!args->is_silentexist)
+ perror(ENSC_WRAPPERS_PREFIX "vc_tag_create()");
+ return 254;
+ default :
+ perror(ENSC_WRAPPERS_PREFIX "vc_tag_create()");
+ return wrapper_exit_code;
+ }
+ }
+ }
+ else
+ tag = args->tag;
+
+ if (args->do_migrate)
+ Evc_tag_migrate(tag);
+
+exec:
+ execvp(argv[optind], argv+optind);
+
+ PERROR_Q(ENSC_WRAPPERS_PREFIX "execvp", argv[optind]);
+ return wrapper_exit_code;
+}
+
+int main (int argc, char *argv[])
+{
+ struct Arguments args = {
+ .tag = VC_NOCTX,
+ .do_create = false,
+ .do_migrate = false,
+ .is_silentexist = false,
+ .verbosity = 1,
+ };
+
+ 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_CREATE : args.do_create = true; break;
+ case CMD_MIGRATE : args.do_migrate = true; break;
+ case CMD_SILENTEXIST : args.is_silentexist = true; break;
+ case CMD_TAG : args.tag = Evc_tagopt2tag(optarg,true); break;
+
+ default :
+ WRITE_MSG(2, "Try '");
+ WRITE_STR(2, argv[0]);
+ WRITE_MSG(2, " --help' for more information.\n");
+ return wrapper_exit_code;
+ break;
+ }
+ }
+
+ if (!args.do_create && !args.do_migrate)
+ WRITE_MSG(2, "Neither '--create' nor '--migrate' specified; try '--help' for more information\n");
+ else if (args.do_create && args.do_migrate)
+ WRITE_MSG(2, "Can not specify '--create' and '--migrate' at the same time; try '--help' for more information\n");
+ else if (args.tag==VC_NOCTX)
+ WRITE_MSG(2, "You must specify the tag with '--tag'; try '--help' for more information\n");
+ else if (optind>=argc)
+ WRITE_MSG(2, "No command given; use '--help' for more information.\n");
+ else
+ return doit(&args, argv);
+
+ return wrapper_exit_code;
+}
struct vc_vx_info info;
xid = vc_getVserverCtx(opts.VSERVER_DIR, vcCFG_RECENT_FULL,
- true, &is_running);
+ true, &is_running, vcCTX_XID);
if (xid!=VC_NOCTX && vc_get_vx_info(xid, &info)!=-1) {
WRITE_MSG(2, "vserver.start: vserver '");