X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Flib%2Fgetvserverctx.c;h=6a0e2c12f38fca0281bd6ffe109ad1459d684a1f;hb=6a9feaf50079e7f15288c52a27ab0d381482e388;hp=3052c7a1e71e6052d2915f0583b863d1537a6ed3;hpb=d0ae91f088249a5c126ad170b82a8fc6e669b95f;p=util-vserver.git diff --git a/util-vserver/lib/getvserverctx.c b/util-vserver/lib/getvserverctx.c index 3052c7a..6a0e2c1 100644 --- a/util-vserver/lib/getvserverctx.c +++ b/util-vserver/lib/getvserverctx.c @@ -23,6 +23,7 @@ #include "vserver.h" #include "pathconfig.h" #include "compat-c99.h" +#include "lib_internal/util.h" #include #include @@ -31,7 +32,59 @@ #include #include -static ctx_t +#ifdef VC_ENABLE_API_COMPAT +#include + +static xid_t +extractLegacyXID(char const *dir, char const *basename) +{ + size_t l1 = strlen(dir); + size_t l2 = strlen(basename); + char path[l1 + l2 + sizeof("/.ctx")]; + char * ptr = path; + int fd; + ssize_t len; + xid_t result = VC_NOXID; + + ptr = Xmemcpy(ptr, dir, l1); + *ptr++ = '/'; + ptr = Xmemcpy(ptr, basename, l2); + ptr = Xmemcpy(ptr, ".ctx", 5); + + fd = open(path, O_RDONLY); + if (fd==-1) return VC_NOXID; + + len = lseek(fd, 0, SEEK_END); + + if (len!=-1 && lseek(fd, 0, SEEK_SET)!=-1) { + char buf[len+2]; + char const *pos = 0; + + buf[0] = '\n'; + + if (read(fd, buf+1, len+1)==len) { + buf[len+1] = '\0'; + pos = strstr(buf, "\nS_CONTEXT="); + } + + if (pos) pos += 11; + if (*pos>='1' && *pos<='9') + result = atoi(pos); + } + + close(fd); + return result; +} +#else +static xid_t +extractLegacyXID(char const UNUSED *dir, char const UNUSED *basename) +{ + return VC_NOXID; +} +#endif + + +static xid_t getCtxFromFile(char const *pathname) { int fd; @@ -39,52 +92,93 @@ getCtxFromFile(char const *pathname) fd = open(pathname, O_RDONLY); - if (fd==-1 || - (len=lseek(fd, 0, SEEK_END))==-1 || + if (fd==-1) return VC_NOCTX; + if ((len=lseek(fd, 0, SEEK_END))==-1 || (len>50) || - (lseek(fd, 0, SEEK_SET)==-1)) + (lseek(fd, 0, SEEK_SET)==-1)) { + close(fd); return VC_NOCTX; + } - BS; + { char buf[len+1]; char *errptr; - ctx_t res; + xid_t res; - if (TEMP_FAILURE_RETRY(read(fd, buf, len+1))!=len) - return VC_NOCTX; + if (TEMP_FAILURE_RETRY(read(fd, buf, len+1))!=len) res = VC_NOCTX; + else { + buf[len] = '\0'; - res = strtol(buf, &errptr, 10); - if (*errptr!='\0' && *errptr!='\n') return VC_NOCTX; + res = strtol(buf, &errptr, 10); + if (*errptr!='\0' && *errptr!='\n') res = VC_NOCTX; + } + close(fd); return res; - BE; + } } -ctx_t -vc_getVserverCtx(char const *id, vcCfgStyle style) +xid_t +vc_getVserverCtx(char const *id, vcCfgStyle style, bool honor_static, bool *is_running) { size_t l1 = strlen(id); - char buf[sizeof(CONFDIR "//") + l1 + sizeof("/run")]; + char buf[sizeof(CONFDIR "//") + l1 + sizeof("/context")]; if (style==vcCFG_NONE || style==vcCFG_AUTO) style = vc_getVserverCfgStyle(id); - + + if (is_running) *is_running = false; + switch (style) { case vcCFG_NONE : return VC_NOCTX; - case vcCFG_LEGACY : return VC_NOCTX; // todo + case vcCFG_LEGACY : + return extractLegacyXID(DEFAULT_PKGSTATEDIR, id); case vcCFG_RECENT_SHORT : case vcCFG_RECENT_FULL : { size_t idx = 0; + xid_t res = 0; + if (style==vcCFG_RECENT_SHORT) { memcpy(buf, CONFDIR "/", sizeof(CONFDIR "/")-1); idx = sizeof(CONFDIR "/") - 1; } memcpy(buf+idx, id, l1); idx += l1; - memcpy(buf+idx, "/run", 4); idx += 4; - buf[idx] = '\0'; + memcpy(buf+idx, "/run", 5); // appends '\0' too + res = getCtxFromFile(buf); - return getCtxFromFile(buf); + // 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) { + char *cur_name; + struct vc_vx_info info; + + // determine the vserver which is associated with the xid + // resp. skip this step when the context does not exist + cur_name = (vc_get_vx_info(res, &info)!=-1 ? + vc_getVserverByCtx_Internal(res, &style, 0, false) : 0); + + buf[idx] = '\0'; // cut off the '/run' from the vserver name + res = ((cur_name!=0 && + vc_compareVserverById(buf, vcCFG_RECENT_FULL, + cur_name, vcCFG_RECENT_FULL)==0) + ? res + : VC_NOCTX); // correct the value of 'res' + + free(cur_name); + } + + if (is_running) // fill 'is_running' information... + *is_running = res!=VC_NOCTX; + + if (res==VC_NOCTX && honor_static) { + memcpy(buf+idx, "/context", 9); // appends '\0' too + + res = getCtxFromFile(buf); + } + + return res; } default : return VC_NOCTX; }