From: Daniel Hokka Zakrisson Date: Fri, 8 Dec 2006 13:24:49 +0000 (+0000) Subject: Work better on 2.6.19. X-Git-Tag: release-0.30.212~8 X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60eb97440f168c25135c63ef3ce06cf6c0babdda;p=util-vserver.git Work better on 2.6.19. This includes adding a new kind of API that depends on the VCI-bits, to detect the presence of spaces. vnamespace now only enters the filesystem related namespaces (CLONE_NEWNS|CLONE_FS). vc_ctx_migrate_spaces enters the others. Fix dynamic context detection by using the VCI-bits. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2415 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- diff --git a/lib/Makefile-files b/lib/Makefile-files index 7d2c3bf..1ea2848 100644 --- a/lib/Makefile-files +++ b/lib/Makefile-files @@ -121,7 +121,12 @@ lib_v21_SRCS = lib/syscall_setccaps-v21.hc \ lib/syscall_virtstat.c \ lib/syscall_virtstat-v21.hc \ lib/syscall_ctxstat.c \ - lib/syscall_ctxstat-v21.hc + lib/syscall_ctxstat-v21.hc \ + lib/syscall_getspacemask.c \ + lib/syscall_getspacemask-v21.hc \ + lib/syscall_enternamespace-v21.hc \ + lib/syscall_setnamespace-v21.hc \ + lib/syscall_ctxmigrate-v21.hc if ENSC_HAVE_C99_COMPILER lib_v13_SRCS += lib/syscall_adddlimit-v13.hc \ @@ -138,6 +143,7 @@ PKGCONFIG_FILES = lib/util-vserver lib_SRCS = lib/syscall.c \ lib/checkversion.c \ + lib/checkconfig.c \ lib/isdirectory.c \ lib/isfile.c \ lib/islink.c \ diff --git a/lib/checkconfig.c b/lib/checkconfig.c new file mode 100644 index 0000000..8c3f696 --- /dev/null +++ b/lib/checkconfig.c @@ -0,0 +1,45 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2003 Enrico Scholz +// Copyright (C) 2006 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 "vserver-internal.h" + +uint_least32_t +utilvserver_checkCompatConfig() +{ +#ifdef VC_ENABLE_API_V21 + static uint32_t res=0; + static int v_errno; + + if (res==0) { + res = vc_get_vci(); + v_errno = errno; + if (res==(uint32_t)-1 && (errno==ENOSYS || errno==EINVAL)) res=0; + } + + errno = v_errno; + return res; +#else + return 0; +#endif +} diff --git a/lib/getxidtype.c b/lib/getxidtype.c index 5e44da6..74a9d94 100644 --- a/lib/getxidtype.c +++ b/lib/getxidtype.c @@ -21,14 +21,21 @@ #endif #include "vserver.h" -#include "virtual.h" +#include "internal.h" vcXidType vc_getXIDType(xid_t xid) { - if (xid==0) return vcTYPE_MAIN; - if (xid==1) return vcTYPE_WATCH; - if (xid>1 && xid=MIN_D_CONTEXT && xid1 && xid=MIN_D_CONTEXT && xid=MIN_D_CONTEXT; + return vc_getXIDType(xid) == vcTYPE_DYNAMIC; } diff --git a/lib/syscall_ctxmigrate-v21.hc b/lib/syscall_ctxmigrate-v21.hc new file mode 100644 index 0000000..ca6666f --- /dev/null +++ b/lib/syscall_ctxmigrate-v21.hc @@ -0,0 +1,34 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// Copyright (C) 2006 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_ctx_migrate_spaces(xid_t xid) +{ + int ret; + + ret = vc_enter_namespace(xid, vc_get_space_mask() & ~(CLONE_NEWNS|CLONE_FS)); + if (ret) + return ret; + + return vserver(VCMD_ctx_migrate_v0, CTX_USER2KERNEL(xid), NULL); +} diff --git a/lib/syscall_ctxmigrate.c b/lib/syscall_ctxmigrate.c index 30ddffa..38db308 100644 --- a/lib/syscall_ctxmigrate.c +++ b/lib/syscall_ctxmigrate.c @@ -21,17 +21,26 @@ #endif #include "vserver.h" -#include "vserver-internal.h" #include "virtual.h" +#if defined(VC_ENABLE_API_V13) && defined(VC_ENABLE_API_V21) +# define VC_MULTIVERSION_SYSCALL 1 +#endif +#include "vserver-internal.h" + #if defined(VC_ENABLE_API_V13) # include "syscall_ctxmigrate-v13.hc" #endif -#if defined(VC_ENABLE_API_V13) +#if defined(VC_ENABLE_API_V21) +# include "syscall_ctxmigrate-v21.hc" +#endif + +#if defined(VC_ENABLE_API_V13) || defined(VC_ENABLE_API_V21) int vc_ctx_migrate(xid_t xid) { - CALL_VC(CALL_VC_V13A(vc_ctx_migrate, xid)); + CALL_VC(CALL_VC_SPACES(vc_ctx_migrate, xid), + CALL_VC_V13A (vc_ctx_migrate, xid)); } #endif diff --git a/lib/syscall_enternamespace-v13.hc b/lib/syscall_enternamespace-v13.hc index 7b40b14..e4dc1cf 100644 --- a/lib/syscall_enternamespace-v13.hc +++ b/lib/syscall_enternamespace-v13.hc @@ -23,7 +23,9 @@ #include "vserver.h" static inline ALWAYSINLINE int -vc_enter_namespace_v13(xid_t xid) +vc_enter_namespace_v13(xid_t xid, uint_least64_t mask) { - return vserver(VCMD_enter_namespace, CTX_USER2KERNEL(xid), 0); + if ((mask & (CLONE_NEWNS|CLONE_FS)) == 0) + return 0; + return vserver(VCMD_enter_space_v0, CTX_USER2KERNEL(xid), 0); } diff --git a/lib/syscall_enternamespace-v21.hc b/lib/syscall_enternamespace-v21.hc new file mode 100644 index 0000000..0106984 --- /dev/null +++ b/lib/syscall_enternamespace-v21.hc @@ -0,0 +1,31 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// Copyright (C) 2006 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" + +static inline ALWAYSINLINE int +vc_enter_namespace_spaces(xid_t xid, uint_least64_t mask) +{ + struct vcmd_space_mask data = { .mask = mask }; + return vserver(VCMD_enter_space, CTX_USER2KERNEL(xid), &data); +} diff --git a/lib/syscall_enternamespace.c b/lib/syscall_enternamespace.c index 25ea4da..4eaeae1 100644 --- a/lib/syscall_enternamespace.c +++ b/lib/syscall_enternamespace.c @@ -23,14 +23,24 @@ #include "vserver.h" #include "virtual.h" +#if defined(VC_ENABLE_API_V13) && defined(VC_ENABLE_API_V21) +# define VC_MULTIVERSION_SYSCALL 1 +#endif #include "vserver-internal.h" #ifdef VC_ENABLE_API_V13 # include "syscall_enternamespace-v13.hc" #endif +#ifdef VC_ENABLE_API_V21 +# include "syscall_enternamespace-v21.hc" +#endif + +#if defined(VC_ENABLE_API_V13) || defined(VC_ENABLE_API_V21) int -vc_enter_namespace(xid_t xid) +vc_enter_namespace(xid_t xid, uint_least64_t mask) { - CALL_VC(CALL_VC_V13(vc_enter_namespace, xid)); + CALL_VC(CALL_VC_SPACES(vc_enter_namespace, xid, mask), + CALL_VC_V13 (vc_enter_namespace, xid, mask)); } +#endif diff --git a/lib/syscall_getspacemask-v21.hc b/lib/syscall_getspacemask-v21.hc new file mode 100644 index 0000000..e4caa7c --- /dev/null +++ b/lib/syscall_getspacemask-v21.hc @@ -0,0 +1,32 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// Copyright (C) 2006 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 uint_least64_t +vc_get_space_mask_spaces(int UNUSED tmp) +{ + struct vcmd_space_mask data = { .mask = 0 }; + int ret = vserver(VCMD_get_space_mask, 0, &data); + if (ret) + return ret; + return data.mask; +} diff --git a/lib/syscall_getspacemask.c b/lib/syscall_getspacemask.c new file mode 100644 index 0000000..55fac58 --- /dev/null +++ b/lib/syscall_getspacemask.c @@ -0,0 +1,38 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// Copyright (C) 2006 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 "vserver-internal.h" +#include "virtual.h" + +#if defined(VC_ENABLE_API_V21) +# include "syscall_getspacemask-v21.hc" +#endif + +#if defined(VC_ENABLE_API_V21) +uint_least64_t +vc_get_space_mask() +{ + CALL_VC(CALL_VC_SPACES(vc_get_space_mask, 0)); +} +#endif diff --git a/lib/syscall_getvci-v21.hc b/lib/syscall_getvci-v21.hc index ac96358..b7794f1 100644 --- a/lib/syscall_getvci-v21.hc +++ b/lib/syscall_getvci-v21.hc @@ -21,7 +21,7 @@ #endif static inline ALWAYSINLINE int -vc_get_vci_v21() +vc_get_vci_v21(int UNUSED tmp) { return vserver(VCMD_get_vci, 0, 0); } diff --git a/lib/syscall_getvci.c b/lib/syscall_getvci.c index 94dbc96..e9b28dc 100644 --- a/lib/syscall_getvci.c +++ b/lib/syscall_getvci.c @@ -33,7 +33,7 @@ int vc_get_vci() { - CALL_VC(CALL_VC_V21(vc_get_vci)); + CALL_VC(CALL_VC_V21(vc_get_vci, 0)); } #endif diff --git a/lib/syscall_setnamespace-v13.hc b/lib/syscall_setnamespace-v13.hc index cda4c1a..915d67d 100644 --- a/lib/syscall_setnamespace-v13.hc +++ b/lib/syscall_setnamespace-v13.hc @@ -23,7 +23,9 @@ #include "vserver.h" static inline ALWAYSINLINE int -vc_set_namespace_v13(int UNUSED tmp) +vc_set_namespace_v13(xid_t xid, uint_least64_t mask) { - return vserver(VCMD_set_namespace_v0, -1, 0); + if ((mask & (CLONE_NEWNS|CLONE_FS)) == 0) + return 0; + return vserver(VCMD_set_space_v0, CTX_USER2KERNEL(xid), 0); } diff --git a/lib/syscall_setnamespace-v21.hc b/lib/syscall_setnamespace-v21.hc new file mode 100644 index 0000000..160a124 --- /dev/null +++ b/lib/syscall_setnamespace-v21.hc @@ -0,0 +1,31 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// Copyright (C) 2006 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" + +static inline ALWAYSINLINE int +vc_set_namespace_spaces(xid_t xid, uint_least64_t mask) +{ + struct vcmd_space_mask data = { .mask = mask }; + return vserver(VCMD_set_space, CTX_USER2KERNEL(xid), &data); +} diff --git a/lib/syscall_setnamespace.c b/lib/syscall_setnamespace.c index a03998e..0e4d4a2 100644 --- a/lib/syscall_setnamespace.c +++ b/lib/syscall_setnamespace.c @@ -23,14 +23,24 @@ #include "vserver.h" #include "virtual.h" +#if defined(VC_ENABLE_API_V13) && defined(VC_ENABLE_API_V21) +# define VC_MULTIVERSION_SYSCALL 1 +#endif #include "vserver-internal.h" #ifdef VC_ENABLE_API_V13 # include "syscall_setnamespace-v13.hc" #endif +#ifdef VC_ENABLE_API_V21 +# include "syscall_setnamespace-v21.hc" +#endif + +#if defined(VC_ENABLE_API_V13) || defined(VC_ENABLE_API_V21) int -vc_set_namespace() +vc_set_namespace(xid_t xid, uint_least64_t mask) { - CALL_VC(CALL_VC_V13(vc_set_namespace,0)); + CALL_VC(CALL_VC_SPACES(vc_set_namespace, xid, mask), + CALL_VC_V13 (vc_set_namespace, xid, mask)); } +#endif diff --git a/lib/virtual.h b/lib/virtual.h index a3f9fa5..828183a 100644 --- a/lib/virtual.h +++ b/lib/virtual.h @@ -19,20 +19,18 @@ #ifndef H_UTIL_VSERVER_LIB_VIRTUAL_H #define H_UTIL_VSERVER_LIB_VIRTUAL_H -#include #include #include #include -#include #include #include #include -#include +#include +#include #include #include #include -#include #include #endif // H_UTIL_VSERVER_LIB_VIRTUAL_H diff --git a/lib/vserver-internal.h b/lib/vserver-internal.h index 56a0338..055dd07 100644 --- a/lib/vserver-internal.h +++ b/lib/vserver-internal.h @@ -41,12 +41,16 @@ inline static ALWAYSINLINE void vc_noop0() {} #define CALL_VC_NOOP vc_noop0() #define CALL_VC_GENERAL(ID, SUFFIX, FUNC, ...) \ VC_PREFIX; VC_SELECT(ID) return FUNC ## _ ## SUFFIX(__VA_ARGS__); VC_SUFFIX +#define CALL_VC_GENERAL_CONFIG(BIT, SUFFIX, FUNC, ...) \ + VC_PREFIX; VC_CBIT(BIT) return FUNC ## _ ## SUFFIX(__VA_ARGS__); VC_SUFFIX #ifdef VC_MULTIVERSION_SYSCALL # define VC_SELECT(ID) if (ver>=(ID)) +# define VC_CBIT(BIT) if ((conf&BIT) == BIT) # define CALL_VC(...) \ do { \ int ver = utilvserver_checkCompatVersion(); \ + int UNUSED conf = utilvserver_checkCompatConfig(); \ if (ver==-1) return -1; \ VC_SUFFIX, __VA_ARGS__, VC_PREFIX; \ errno = ENOSYS; \ @@ -54,6 +58,7 @@ inline static ALWAYSINLINE void vc_noop0() {} } while (0) #else # define VC_SELECT(ID) if (1) +# define VC_CBIT(BIT) if (1) # define CALL_VC(...) \ do { \ if (1) {} VC_SUFFIX, __VA_ARGS__, VC_PREFIX; \ @@ -103,13 +108,17 @@ inline static ALWAYSINLINE void vc_noop0() {} # define CALL_VC_V13OBS(F,...) CALL_VC_NOOP #endif - #ifdef VC_ENABLE_API_V21 # define CALL_VC_V21(F,...) CALL_VC_GENERAL(0x00020100, v21, F, __VA_ARGS__) #else # define CALL_VC_V21(F,...) CALL_VC_NOOP #endif +#ifdef VC_ENABLE_API_V21 +# define CALL_VC_SPACES(F,...) CALL_VC_GENERAL_CONFIG(VC_VCI_SPACES, spaces, F, __VA_ARGS__) +#else +# define CALL_VC_SPACES(F,...) CALL_VC_NOOP +#endif #ifdef VC_ENABLE_API_NET # define CALL_VC_NET(F,...) CALL_VC_GENERAL(0x00010016, net, F, __VA_ARGS__) diff --git a/lib/vserver.h b/lib/vserver.h index 2f9c62a..bb0b93a 100644 --- a/lib/vserver.h +++ b/lib/vserver.h @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef IS_DOXYGEN #if defined(__GNUC__) @@ -254,6 +255,22 @@ #define VC_VLIMIT_MAPPED 23 +// the VCI bit values +#define VC_VCI_NO_DYNAMIC (1 << 0) +#define VC_VCI_SPACES (1 << 10) + + +#ifndef CLONE_NEWNS +# define CLONE_NEWNS 0x00020000 +#endif +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +# define CLONE_NEWIPC 0x08000000 +#endif + + #define VC_BAD_PERSONALITY ((uint_least32_t)(-1)) @@ -608,9 +625,10 @@ extern "C" { /** Returns true iff \a xid is a dynamic xid */ bool vc_is_dynamic_xid(xid_t xid); - int vc_enter_namespace(xid_t xid); - int vc_set_namespace(); + int vc_enter_namespace(xid_t xid, uint_least64_t mask); + int vc_set_namespace(xid_t xid, uint_least64_t mask); int vc_cleanup_namespace(); + uint_least64_t vc_get_space_mask(); /** \brief Flags of process-contexts diff --git a/src/vcontext.c b/src/vcontext.c index 6cb76ef..0557a30 100644 --- a/src/vcontext.c +++ b/src/vcontext.c @@ -274,8 +274,8 @@ doit(struct Arguments const *args, int argc, char *argv[]) if (args->do_chroot) { Echroot("."); if (args->set_namespace) { - if (args->do_migrateself) Evc_set_namespace(); - else if (args->do_migrate) Evc_enter_namespace(xid); + if (args->do_migrateself) Evc_set_namespace(xid, 0); + else if (args->do_migrate) Evc_enter_namespace(xid, 0); } } diff --git a/src/vnamespace.c b/src/vnamespace.c index 366b967..c71cc9f 100644 --- a/src/vnamespace.c +++ b/src/vnamespace.c @@ -36,13 +36,6 @@ #define ENSC_WRAPPERS_VSERVER 1 #include -#ifndef CLONE_NEWUTS -# define CLONE_NEWUTS 0x04000000 -#endif -#ifndef CLONE_NEWIPC -# define CLONE_NEWIPC 0x08000000 -#endif - #define CMD_HELP 0x1000 #define CMD_VERSION 0x1001 @@ -102,9 +95,9 @@ newNamespace(char const *cmd) signal(SIGCHLD, SIG_DFL); #ifdef NDEBUG - pid = sys_clone(CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_VFORK|SIGCHLD, 0); + pid = sys_clone(CLONE_NEWNS|CLONE_VFORK|SIGCHLD, 0); #else - pid = sys_clone(CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD, 0); + pid = sys_clone(CLONE_NEWNS|SIGCHLD, 0); #endif switch (pid) { @@ -119,18 +112,18 @@ newNamespace(char const *cmd) } static void -enterNamespace(xid_t xid) +enterNamespace(xid_t xid, uint_least64_t mask) { - if (vc_enter_namespace(xid)==-1) { + if (vc_enter_namespace(xid, mask)==-1) { perror("vnamespace: vc_enter_namespace()"); exit(255); } } static void -setNamespace() +setNamespace(xid_t xid, uint_least64_t mask) { - if (vc_set_namespace()==-1) { + if (vc_set_namespace(xid, mask)==-1) { perror("vnamespace: vc_set_namespace()"); exit(255); } @@ -189,9 +182,9 @@ int main(int argc, char *argv[]) WRITE_MSG(2, "No command specified; try '--help' for more information\n"); else { if (do_new) newNamespace(argv[optind]); - else if (do_set) setNamespace(); + else if (do_set) setNamespace(VC_SAMECTX, CLONE_NEWNS|CLONE_FS); else if (do_cleanup) cleanupNamespace(); - else if (do_enter) enterNamespace(xid); + else if (do_enter) enterNamespace(xid, CLONE_NEWNS|CLONE_FS); if (optind