Add support for a separate filesystem tag, and in the process improve the support...
authorDaniel Hokka Zakrisson <daniel@hozac.com>
Thu, 16 Aug 2007 03:06:50 +0000 (03:06 +0000)
committerDaniel Hokka Zakrisson <daniel@hozac.com>
Thu, 16 Aug 2007 03:06:50 +0000 (03:06 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2589 94cd875c-1c1d-0410-91d2-eb244daf1a30

34 files changed:
compat.h
configure.ac
contrib/manifest.dat.pathsubst
ensc_wrappers/wrappers-vserver.hc
kernel/switch.h
kernel/tag_cmd.h [new file with mode: 0644]
lib/Makefile-files
lib/getvserverbyctx-compat.hc
lib/getvserverbyctx-v13.hc
lib/getvserverctx.c
lib/issupported.c
lib/issupportedstring.c
lib/nidopt2nid.c
lib/syscall_getvci-v21.hc
lib/syscall_getvci.c
lib/syscall_tagcreate.c [new file with mode: 0644]
lib/syscall_tagmigrate-v23.hc [new file with mode: 0644]
lib/syscall_tagmigrate.c [new file with mode: 0644]
lib/syscall_tasktag-v23.hc [new file with mode: 0644]
lib/syscall_tasktag.c [new file with mode: 0644]
lib/tagopt2tag.c [new file with mode: 0644]
lib/virtual.h
lib/vserver-internal.h
lib/vserver.h
lib/xidopt2xid.c
scripts/chcontext
scripts/util-vserver-vars.pathsubst
scripts/vserver.functions
scripts/vserver.start
scripts/vserver.suexec
src/Makefile-files
src/vserver-info.c
src/vtag.c [new file with mode: 0644]
vserver-start/main.c

index 43d920c..b4315c4 100644 (file)
--- a/compat.h
+++ b/compat.h
@@ -87,6 +87,11 @@ typedef uint32_t             xid_t;
 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)                               \
index 5caea3a..bb30072 100644 (file)
@@ -295,6 +295,7 @@ AC_CHECK_FUNCS([vserver])
 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])
 
index 08eca55..ab8e256 100644 (file)
@@ -121,6 +121,7 @@ legacy @SBINDIR@/vserver-copy
 core   @SBINDIR@/vserver-info
 base   @SBINDIR@/vserver-stat
 base   @SBINDIR@/vsomething
+core   @SBINDIR@/vtag
 base   @SBINDIR@/vtop
 core   @SBINDIR@/vuname
 build  @SBINDIR@/vupdateworld
index a1e1e0a..d86dbcf 100644 (file)
@@ -64,6 +64,14 @@ Evc_net_create(nid_t nid)
   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)
 {
@@ -77,6 +85,12 @@ Evc_net_migrate(nid_t nid)
 }
 
 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()");
@@ -180,3 +194,15 @@ Evc_nidopt2nid(char const *id, bool honor_static)
   }
   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;
+}
index 95eb6b4..ee6defc 100644 (file)
@@ -8,7 +8,7 @@
 #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))
 
 /*
@@ -31,7 +31,7 @@
   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  |       |
@@ -65,6 +65,7 @@
 #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)
diff --git a/kernel/tag_cmd.h b/kernel/tag_cmd.h
new file mode 100644 (file)
index 0000000..27ef60b
--- /dev/null
@@ -0,0 +1,14 @@
+#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 */
index 670e56b..e33f1d5 100644 (file)
@@ -34,7 +34,8 @@ lib_management_SRCS =         lib/comparevserverbyid.c \
                                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  \
@@ -145,6 +146,12 @@ lib_v22_SRCS =                     lib/syscall_setsched-v22.hc \
 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 \
@@ -192,6 +199,7 @@ lib_SRCS =                          lib/syscall.c \
                                $(lib_v21_SRCS) \
                                $(lib_v22_SRCS) \
                                $(lib_netv2_SRCS) \
+                               $(lib_v23_SRCS) \
                                $(ensc_fmt_SRCS)
 
 include_HEADERS +=             lib/vserver.h
index 79ceef6..3e7fde2 100644 (file)
@@ -96,7 +96,7 @@ vc_getVserverByCtx_compat(xid_t ctx, vcCfgStyle *style, char const *revdir,
        // 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);
index d9f601b..4d2e09b 100644 (file)
@@ -28,7 +28,7 @@ vc_getVserverByCtx_v13(xid_t ctx, vcCfgStyle *style, char const UNUSED *revdir,
 
   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);
   }
index 59c3963..fda8d73 100644 (file)
@@ -120,10 +120,11 @@ getCtxFromFile(char const *pathname)
 }
 
 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);
@@ -151,7 +152,7 @@ vc_getVserverCtx(char const *id, vcCfgStyle style, bool honor_static, bool *is_r
        // 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;
 
@@ -180,7 +181,17 @@ vc_getVserverCtx(char const *id, vcCfgStyle style, bool honor_static, bool *is_r
        *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);
       }
index 73bf813..45b1c24 100644 (file)
 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;
@@ -44,6 +46,7 @@ vc_isSupported(vcFeatureSet feature)
     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); 
   }
 
index a4ef2f9..e9526f9 100644 (file)
@@ -34,7 +34,7 @@ static struct {
   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
index d3fd8c6..2f6388a 100644 (file)
 #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)
 {
@@ -32,7 +39,16 @@ 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;
 
index b7794f1..74a629f 100644 (file)
@@ -20,7 +20,7 @@
 #  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);
index e9b28dc..42875f0 100644 (file)
@@ -30,7 +30,7 @@
 
 #if defined(VC_ENABLE_API_V21)
 
-int
+vc_vci_t
 vc_get_vci()
 {
   CALL_VC(CALL_VC_V21(vc_get_vci, 0));
diff --git a/lib/syscall_tagcreate.c b/lib/syscall_tagcreate.c
new file mode 100644 (file)
index 0000000..752731a
--- /dev/null
@@ -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 <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
diff --git a/lib/syscall_tagmigrate-v23.hc b/lib/syscall_tagmigrate-v23.hc
new file mode 100644 (file)
index 0000000..bb718c8
--- /dev/null
@@ -0,0 +1,27 @@
+// $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);
+}
diff --git a/lib/syscall_tagmigrate.c b/lib/syscall_tagmigrate.c
new file mode 100644 (file)
index 0000000..d5a9e46
--- /dev/null
@@ -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 <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
diff --git a/lib/syscall_tasktag-v23.hc b/lib/syscall_tasktag-v23.hc
new file mode 100644 (file)
index 0000000..e01b35a
--- /dev/null
@@ -0,0 +1,27 @@
+// $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);
+}
diff --git a/lib/syscall_tasktag.c b/lib/syscall_tasktag.c
new file mode 100644 (file)
index 0000000..f5d6c35
--- /dev/null
@@ -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 <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
diff --git a/lib/tagopt2tag.c b/lib/tagopt2tag.c
new file mode 100644 (file)
index 0000000..7f4b6aa
--- /dev/null
@@ -0,0 +1,57 @@
+// $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;
+}
index aadf2fa..857be66 100644 (file)
@@ -31,6 +31,7 @@
 #include <kernel/sched_cmd.h>
 #include <kernel/signal_cmd.h>
 #include <kernel/device_cmd.h>
+#include <kernel/tag_cmd.h>
 
 #include <kernel/legacy.h>
 
index 4e71afd..e1cd60c 100644 (file)
@@ -50,7 +50,7 @@ inline static ALWAYSINLINE void vc_noop0() {}
 #  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;                                    \
@@ -120,6 +120,12 @@ inline static ALWAYSINLINE void vc_noop0() {}
 #  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
@@ -179,6 +185,19 @@ inline static ALWAYSINLINE void vc_noop0() {}
 #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))
index ee53775..d403677 100644 (file)
 #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
@@ -349,11 +351,12 @@ extern "C" {
      */
   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
@@ -769,6 +772,15 @@ extern "C" {
                              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;
@@ -931,7 +943,7 @@ extern "C" {
                 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;
@@ -962,6 +974,8 @@ extern "C" {
   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);
   
@@ -984,6 +998,11 @@ extern "C" {
    *  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
@@ -992,7 +1011,8 @@ extern "C" {
    *  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
index 80a51e5..3bef404 100644 (file)
@@ -28,7 +28,7 @@ static xid_t
 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
index 93b0959..2caa42c 100755 (executable)
@@ -134,7 +134,8 @@ while true; do
     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"} )
 
@@ -157,7 +158,9 @@ chain_cmd=( "${chain_cmd[@]}"
                ${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 )
index 3803564..2e6afbb 100644 (file)
@@ -99,6 +99,7 @@ _VSHELPER="$__PKGLIBDIR/vshelper"
 _VSHELPER_SYNC="$__PKGLIBDIR/vshelper-sync"
 _VSOMETHING="$__SBINDIR/vsomething"
 _VSYSCTL="$__PKGLIBDIR/vsysctl"
+_VTAG="$__SBINDIR/vtag"
 _VWAIT="$__SBINDIR/vwait"
 _VUNAME="$__SBINDIR/vuname"
 _VUNIFY="$__PKGLIBDIR/vunify"
index 5bfda35..30e82f0 100644 (file)
@@ -43,6 +43,8 @@ declare -a OPTS_VCONTEXT_ENTER=()
 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=()
 
@@ -599,6 +601,17 @@ function _generateInterfaceOptions
     _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
@@ -712,6 +725,7 @@ function generateOptions
     _generateChcontextOptions   "$1"
     _generateScheduleOptions    "$1"
     _generatePersonalityOptions "$1"
+    _generateTagOptions         "$1"
 
     if test -n "$_IS_FAKEINIT"; then
        CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
index 1ade946..63b02a9 100644 (file)
@@ -132,6 +132,7 @@ if $_VSERVER_INFO - FEATURE migrate; then
     ${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 -- } \
index b91f7f3..8b19f53 100644 (file)
@@ -37,6 +37,7 @@ if $_VSERVER_INFO - FEATURE migrate; then
         $_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[@]}" -- \
        "$@"
@@ -44,6 +45,7 @@ if $_VSERVER_INFO - FEATURE migrate; then
        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" -- \
index dad36c1..5b4a6ad 100644 (file)
@@ -81,7 +81,8 @@ DIETPROGS +=          src/chcontext-compat \
                        src/vdevmap \
                        src/vsysctl \
                        src/vclone \
-                       src/h2ext
+                       src/h2ext \
+                       src/vtag
 
 if ENSC_CAN_BEECRYPT_WITH_DIETLIBC
 DIETPROGS +=           src/vhashify
@@ -161,6 +162,7 @@ sbin_PROGRAMS +=    src/exec-cd \
                        src/nattribute \
                        src/naddress \
                        src/vdevmap \
+                       src/vtag \
                        $(src_sbin_CXX_X_PROGS)
 
 if ENSC_HAVE_C99_COMPILER
@@ -342,6 +344,10 @@ src_h2ext_SOURCES          = src/h2ext.c
 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
index 36465fd..d28bf28 100644 (file)
@@ -53,6 +53,7 @@ typedef enum { tgNONE,tgCONTEXT, tgID, tgRUNNING,
               tgXID, tgUTS, tgSYSINFO,
               tgFEATURE, tgCANONIFY,
               tgVERIFYCAP, tgXIDTYPE, tgVERIFYPROC,
+              tgNID, tgTAG,
 }      VserverTag;
 
 static struct {
@@ -82,6 +83,8 @@ 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;
@@ -230,13 +233,13 @@ getAPIVer(char *buf)
   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;
@@ -246,6 +249,24 @@ getXid(char *buf, char const *pid_str)
 }
 
 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
@@ -434,7 +455,7 @@ static char *
 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);
@@ -502,7 +523,7 @@ execQuery(char const *vserver, VserverTag tag, int argc, char *argv[])
       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;
     }
@@ -522,6 +543,8 @@ execQuery(char const *vserver, VserverTag tag, int argc, char *argv[])
     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            : {
diff --git a/src/vtag.c b/src/vtag.c
new file mode 100644 (file)
index 0000000..3aa6cc4
--- /dev/null
@@ -0,0 +1,172 @@
+// $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;
+}
index 953daf2..634a734 100644 (file)
@@ -115,7 +115,7 @@ checkConstraints()
   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 '");