X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Frpm-fake.c;h=302c2941f2549d411ad39d16e2168e9c61bc5151;hb=54dca8e1902c0329b2a070098ea93b001a22cc5b;hp=f06361681f872796e762c339f5bcc3ae10a59f89;hpb=5ea081fe6ad6968fdab74f248d50c18907b79955;p=util-vserver.git diff --git a/util-vserver/src/rpm-fake.c b/util-vserver/src/rpm-fake.c index f063616..302c294 100644 --- a/util-vserver/src/rpm-fake.c +++ b/util-vserver/src/rpm-fake.c @@ -19,6 +19,9 @@ #ifdef HAVE_CONFIG_H # include #endif +#include "compat.h" + +#include #include #include @@ -28,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -48,62 +50,10 @@ static bool is_initialized = false; DECLARE(execv); //DECLARE(open); -static int def_NR_new_s_context = 259; -#undef __NR_new_s_context -static int __NR_new_s_context_rev0; -static int __NR_new_s_context_rev1; - -static int new_s_context_rev0(int, int, int); -static int new_s_context_rev1(int, int *, int, int); - -_syscall3(int, new_s_context_rev0, int, newctx, int, remove_cap, int, flags) -_syscall4(int, new_s_context_rev1, int, nbctx, int *, ctxs, int, remove_cap, int, flags) - -static int -new_s_context(int rev, - int nbctx, int *ctxs, int remove_cap, int flags) -{ - int ret; - - switch (rev) { - case 0 : - { - int ctx; - - switch (nbctx) { - case 0 : ctx = -1; break; - case 1 : ctx = ctxs[0]; break; - default : errno = EINVAL; return -1; - } - - ret = new_s_context_rev0(ctx, remove_cap, flags); - - break; - } - - case 1 : - ret = new_s_context_rev1(nbctx, ctxs, remove_cap, flags); - break; - - default : - errno = EINVAL; return -1; - } - - return ret; -} - -static void -initVserverSyscalls(int s_context_NR) -{ - int nr = (s_context_NR!=-1) ? s_context_NR : def_NR_new_s_context; - - __NR_new_s_context_rev0 = __NR_new_s_context_rev1 = nr; -} - static int getAndClearEnv(char const *key, int dflt) { - char *env = getenv(key); + char *env = getenv(key); int res; if (env==0 || env[0]=='\0') res = dflt; @@ -120,7 +70,19 @@ initLib() { if (is_initialized) return; - initVserverSyscalls(getAndClearEnv("RPM_FAKE_S_CONTEXT_NR", -1)); +#ifdef VC_ENABLE_API_LEGACY + { + extern void vc_init_internal_legacy(int ctx_rev, int ctx_number, + int ipv4_rev, int ipv4_number); + + vc_init_internal_legacy(getAndClearEnv("RPM_FAKE_S_CONTEXT_REV", 0), + getAndClearEnv("RPM_FAKE_S_CONTEXT_NR", 280), + 3, 281); + } +#else + (void)getAndClearEnv("RPM_FAKE_S_CONTEXT_REV", 0); + (void)getAndClearEnv("RPM_FAKE_S_CONTEXT_NR", 280); +#endif INIT(RTLD_NEXT, execv); //INIT(RTLD_NEXT, open); @@ -142,7 +104,7 @@ fixPreloadEnv() char *end_pos = pos + sizeof(LIBNAME); bool is_end = (end_pos[-1]=='\0'); char *start_pos; - + end_pos[-1] = '\0'; start_pos = strrchr(env, ':'); if (start_pos==0) start_pos = env; @@ -166,11 +128,9 @@ execvWorker(char const *path, char * const argv[]) int ctx; ctx = getAndClearEnv("RPM_FAKE_CTX", -1); - if ( (res=new_s_context(getAndClearEnv("RPM_FAKE_S_CONTEXT_REV", 0), - ctx==-1 ? 0 : 1, - &ctx, - getAndClearEnv("RPM_FAKE_CAP", ~0x3404040f), - getAndClearEnv("RPM_FAKE_FLAGS", 0)))!=-1 && + if ( (res=vc_new_s_context(ctx, + getAndClearEnv("RPM_FAKE_CAP", ~0x3404040f), + getAndClearEnv("RPM_FAKE_FLAGS", 0)))!=-1 && (res=execv_func(path, argv)!=-1) ) {} return res; @@ -223,13 +183,18 @@ removeNamespaceMounts(char const *path, char * const argv[]) .argv = argv, .mnts = mnts, }; - + + // the rpmlib signal-handler is still active; use the default one to + // make wait4() working... + signal(SIGCHLD, SIG_DFL); + pid_t pid = clone(removeNamespaceMountsChild, buf+sizeof(buf)/2, CLONE_NEWNS|SIGCHLD|CLONE_VFORK, ¶ms); if (pid==-1) return -1; - while ((p=waitpid(pid, &status, 0))==-1 && + while ((p=wait4(pid, &status, 0,0))==-1 && (errno==EINTR || errno==EAGAIN)) ; + if (p==-1) return -1; if (WIFEXITED(status)) exit(WEXITSTATUS(status));