int LiveCDFS::doStat(const char *name, struct lufs_fattr *attr) { FUNC_START("name='%s', attr=%p", name, attr); if (!whiteout->isVisible(name)) { FUNC_RET("%d", -1, -1); } string fullpath = path->mkpath(name); struct stat buf; if (lstat(fullpath.c_str(), &buf) < 0) { WARN("Could not perform lstat on file='%s'", fullpath.c_str()); FUNC_RET("%d", -1, -1); } TRACE("name='%s', buf.st_uid=%u, buf.st_gid=%u, buf.st_size=%u", name, buf.st_uid, buf.st_gid, buf.st_size); attr->f_mode = buf.st_mode; attr->f_nlink = buf.st_nlink; attr->f_uid = buf.st_uid; //2; // This makes us default to the specified -o uid attr->f_gid = buf.st_gid; //2; // This makes us default to the specified -o gid attr->f_size = buf.st_size; attr->f_atime = buf.st_atime; attr->f_mtime = buf.st_mtime; attr->f_ctime = buf.st_ctime; FUNC_RET("%d", 0, 0); }
int LiveCDFS::doWrite(const char *file, long long offset, unsigned long count, char *buf) { FUNC_START("file='%s', offset=%l, count=%ul, buf=%p", file, offset, count, buf); int fd = open(path->mkpath(file).c_str(), O_WRONLY); if (fd <= 0) { WARN("Cannot open file='%s' O_WRONLY", file); FUNC_RET("%d", fd, fd); } if (lseek(fd, offset, SEEK_SET) < 0) { WARN("Seek for file='%s', fd=%d failed", file, fd); close(fd); FUNC_RET("%d", -1, -1); } int res = write(fd, buf, count); close(fd); TRACE("Write count=%ul, res=%d", count, res); FUNC_RET("%d", res, res); }
int sandbox_init(sandbox_t * psbox, const char * argv[]) { FUNC_BEGIN("sandbox_init(%p,%p)", psbox, argv); assert(psbox); if (psbox == NULL) { WARNING("psbox: bad pointer"); FUNC_RET(-1, "sandbox_init()"); } pthread_mutex_init(&psbox->mutex, NULL); P(&psbox->mutex); pthread_cond_init(&psbox->update, NULL); __sandbox_task_init(&psbox->task, argv); __sandbox_stat_init(&psbox->stat); __sandbox_ctrl_init(&psbox->ctrl, (thread_func_t)__sandbox_tracer, #ifdef WITH_CUSTOM_MONITOR (thread_func_t)__sandbox_monitor #else (thread_func_t)(NULL) #endif /* WITH_CUSTOM_MONITOR */ ); V(&psbox->mutex); P(&psbox->mutex); psbox->result = S_RESULT_PD; psbox->status = S_STATUS_PRE; pthread_cond_broadcast(&psbox->update); V(&psbox->mutex); FUNC_RET(0, "sandbox_init()"); }
int sandbox_fini(sandbox_t * psbox) { FUNC_BEGIN("sandbox_fini(%p)", psbox); assert(psbox); if (psbox == NULL) { WARNING("psbox: bad pointer"); FUNC_RET(-1, "sandbox_fini()"); } P(&psbox->mutex); psbox->result = S_RESULT_PD; psbox->status = S_STATUS_FIN; pthread_cond_broadcast(&psbox->update); V(&psbox->mutex); P(&psbox->mutex); __sandbox_task_fini(&psbox->task); __sandbox_stat_fini(&psbox->stat); __sandbox_ctrl_fini(&psbox->ctrl); pthread_cond_destroy(&psbox->update); V(&psbox->mutex); pthread_mutex_destroy(&psbox->mutex); FUNC_RET(0, "sandbox_fini()"); }
LiveCDFS * LiveCDFS::create(struct list_head *cfg, struct dir_cache *cache, struct credentials *cred) { FUNC_START("cfg=%p, cache=%p, cred=%p", cfg, cache, cred); const char *opt = lu_opt_getchar(cfg, "MOUNT", "ro_root"); if (opt == NULL) { ERROR("FATAL: Please specify '-o ro_root=<point>', defining the ro root (underlay) as a mount option"); FUNC_RET("%p", NULL, NULL); } string root = string(opt); opt = lu_opt_getchar(cfg, "MOUNT", "rw_tmp"); if (opt == NULL) { ERROR("FATAL: Please specify '-o rw_tmp=<point>', defining the temporary rw workspace, as a mount option"); FUNC_RET("%p", NULL, NULL); } string tmp = string(opt); opt = lu_opt_getchar(cfg, "MOUNT", "mount"); if (opt == NULL) { ERROR("FATAL: Please specify '-o mount=<point>', defining the final mountpoint, as a mount option"); FUNC_RET("%p", NULL, NULL); } string mount = string(opt); t_active_livecdfs *active = findActive(root, tmp); LiveCDFS *fs = NULL; if (active == NULL) { Path *path = NULL; Whiteout *wo = NULL; if (((path = Path::create(root, tmp)) != NULL) && ((wo = Whiteout::create(tmp)) != NULL)) { fs = new LiveCDFS(cfg, cache, cred, mount, path, wo); } if (fs == NULL) { if (path != NULL) { delete path; } if (wo != NULL) { delete wo; } ERROR("Could not create new LiveCDFS instance"); } else { activefs.push_back((t_active_livecdfs){mount,root,tmp,1,fs}); TRACE("Created new LiveCDFS instance, fs=%p", fs); } } else { fs = active->fs; active->count++; } FUNC_RET("%p", fs, fs); }
bool proc_dump(const proc_t * const pproc, const void * const addr, long * const pword) { FUNC_BEGIN("proc_dump(%p,%p,%p)", pproc, addr, pword); assert(pproc); assert(addr); assert(pword); #ifdef __linux__ /* Current instruction */ *pword = ptrace(PTRACE_PEEKDATA, pproc->pid, addr, NULL); if (errno != 0) { WARNING("ptrace:PTRACE_PEEKDATA"); FUNC_RET(false, "proc_dump()"); } #else #warning "proc_dump is not implemented for this platform" #endif #ifdef DELETED /* Access the memory of targeted process via procfs */ char buffer[4096]; sprintf(buffer, PROCFS "/%d/mem", pproc->pid); if (access(buffer, R_OK | F_OK) < 0) { WARNING("procfs entries missing or invalid"); FUNC_RET(false, "proc_dump()"); } /* Copy a word from targeted address */ int fd = open(buffer, O_RDONLY); if (lseek(fd, (off_t)addr, SEEK_SET) < 0) { extern int errno; WARNING("lseek(%d, %p, SEEK_SET) failes, ERRNO %d", fd, addr, errno); FUNC_RET(false, "proc_dump()"); } if (read(fd, (void *)pword, sizeof(unsigned long)) < 0) { WARNING("read"); FUNC_RET(false, "proc_dump()"); } close(fd); #endif /* DELETED */ DBG("data.%p 0x%08lx", addr, *pword); FUNC_RET(true, "proc_dump()"); }
int LiveCDFS::doLinkAll(const char *target, const char *newlink, bool issymlink = false) { FUNC_START("target='%s', link='%s'", target, newlink); if (!whiteout->isVisible(target)) { FUNC_RET("%d", -1, -1); } string dir = path->getDir(newlink); string slink = path->mktmp(newlink); string starget = string(target); if ((dir.length() != 0) && !path->isTmp(dir)) { TRACE("Creating directory dir='%s' (link)", dir.c_str()); path->recurseMkdir(dir); } if (path->exists(path->mkpath(target), 0)) { if (!path->isDir(target)) { dir = path->getDir(target); if ((dir.length() != 0) && !path->isTmp(dir)) { TRACE("Creating directory dir='%s' (target)", dir.c_str()); path->recurseMkdir(dir); } } if (!path->exists(path->mktmp(target), 0)) { if (path->exists(path->mkroot(target), 0)) { path->copyTmp(target); } } if (*target == '/') { starget = path->mkpath(target); } } else { // target is hopefully pointing at our root, ignore } TRACE("Creating link, target='%s', link='%s'", starget.c_str(), slink.c_str()); int ret = issymlink ? symlink(starget.c_str(), slink.c_str()) : link(starget.c_str(), slink.c_str()); if (ret < 0) { ERROR("strerror(errno)='%s' on link(target='%s', link='%s')", strerror(errno), starget.c_str(), slink.c_str()); } else { whiteout->setVisible(newlink, true); } FUNC_RET("%d", ret, ret); }
bool proc_bind(const void * const dummy, proc_t * const pproc) { FUNC_BEGIN("%p,%p", dummy, pproc); assert(dummy && pproc); if ((dummy == NULL) || (pproc == NULL)) { FUNC_RET("%d", false); } pproc->tflags.trace_id = ((sandbox_t *)dummy)->ctrl.tid; FUNC_RET("%d", true); }
t_active_livecdfs * LiveCDFS::findActive(const LiveCDFS* fs) { FUNC_START("fs=%p", fs); for (vector<t_active_livecdfs>::iterator i = activefs.begin(); i != activefs.end(); ) { TRACE("Testing LiveCDFS instance, i=%p, fs=%p", &*i, i->fs); if (i->fs == fs) { TRACE("Found existing LiveCDFS at i=%p, fs=%p", &*i, i->fs); FUNC_RET("%p", &*i, &*i); } i++; } TRACE("Existing LiveCDFS instance not found"); FUNC_RET("%p", NULL, NULL); }
int livecdfs_mount(void *fs) { FUNC_START("fs=%p", fs); int ret = ((LiveCDFS*)fs)->doMount(); FUNC_RET("%d", ret, ret); }
int LiveCDFS::doSymlink(const char *target, const char *link) { FUNC_START("target='%s', link='%s'", target, link); int ret = doLinkAll(target, link, true); FUNC_RET("%d", ret, ret); }
t_active_livecdfs * LiveCDFS::findActive(const string &root, const string &tmp) { FUNC_START("root='%s', tmp='%s'", root.c_str(), tmp.c_str()); for (vector<t_active_livecdfs>::iterator i = activefs.begin(); i != activefs.end(); ) { TRACE("Testing LiveCDFS instance, i=%p, root='%s', tmp='%s'", &*i, i->root.c_str(), i->tmp.c_str()); if ((i->root == root) && (i->tmp == tmp)) { TRACE("Found existing LiveCDFS at i=%p, fs=%p, root='%s', tmp='%s'", &*i, i->fs, root.c_str(), tmp.c_str()); FUNC_RET("%p", &*i, &*i); } i++; } TRACE("Existing LiveCDFS instance not found"); FUNC_RET("%p", NULL, NULL); }
int livecdfs_rmdir(void *fs, char *dir) { FUNC_START("fs=%p, dir='%s'", fs, dir); int ret = ((LiveCDFS*)fs)->doRmdir(dir); FUNC_RET("%d", ret, ret); }
int livecdfs_release(void *fs, char *file) { FUNC_START("fs=%p, file='%s'", fs, file); int ret = ((LiveCDFS*)fs)->doRelease(file); FUNC_RET("%d", ret, ret); }
int livecdfs_setattr(void *fs, char *file, struct lufs_fattr *attr) { FUNC_START("fs=%p, file='%s', attr=%p", fs, file, attr); int ret = ((LiveCDFS*)fs)->doSetattr(file, attr); FUNC_RET("%d", ret, ret); }
int livecdfs_symlink(void *fs, char *target, char *link) { FUNC_START("fs=%p, target='%s', link='%s'", fs, target, link); int ret = ((LiveCDFS*)fs)->doSymlink(target, link); FUNC_RET("%d", ret, ret); }
int livecdfs_readdir(void *fs, char *name, struct directory *dir) { FUNC_START("fs=%p, name='%s', dir=%p", fs, name, dir); int ret = ((LiveCDFS*)fs)->doReaddir(name, dir); FUNC_RET("%d", ret, ret); }
int livecdfs_stat(void *fs, char *name, struct lufs_fattr *attr) { FUNC_START("fs=%p, name='%s', attr=%p", fs, name, attr); int ret = ((LiveCDFS*)fs)->doStat(name, attr); FUNC_RET("%d", ret, ret); }
int livecdfs_open(void *fs, char *file, unsigned mode) { FUNC_START("fs=%p, file='%s', mode=%u", fs, file, mode); int ret = ((LiveCDFS*)fs)->doOpen(file, mode); FUNC_RET("%d", ret, ret); }
int livecdfs_rename(void *fs, char *oldname, char *newname) { FUNC_START("fs=%p, old='%s', new='%s'", fs, oldname, newname); int ret = ((LiveCDFS*)fs)->doRename(oldname, newname); FUNC_RET("%d", ret, ret); }
int livecdfs_create(void *fs, char *file, int mode) { FUNC_START("fs=%p, file='%s', mode=%u", fs, file, mode); int ret = ((LiveCDFS*)fs)->doCreate(file, mode); FUNC_RET("%d", ret, ret); }
int livecdfs_mkdir(void *fs, char *dir, int mode) { FUNC_START("fs=%p, dir='%s', mode=%u", fs, dir, mode); int ret = ((LiveCDFS*)fs)->doMkdir(dir, mode); FUNC_RET("%d", ret, ret); }
void * livecdfs_init(struct list_head *cfg, struct dir_cache *cache, struct credentials *cred, void **global_ctx) { FUNC_START("cfg=%p, cache=%p, cred=%p, global_ctx=%p", cfg, cache, cred, global_ctx); void *fs = (void *)LiveCDFS::create(cfg, cache, cred); FUNC_RET("%p", fs, fs); }
int livecdfs_readlink(void *fs, char *link, char *buf, int buflen) { FUNC_START("fs=%p, link='%s', buf=%p, buflen=%u", fs, link, buf, buflen); int ret = ((LiveCDFS*)fs)->doReadlink(link, buf, buflen); FUNC_RET("%d", ret, ret); }
int LiveCDFS::doSetattr(const char *file, struct lufs_fattr *attr) { FUNC_START("file='%s', attr=%p", file, attr); if (!whiteout->isVisible(file)) { FUNC_RET("%d", -1, -1); } if (!path->isTmp(file)) { path->copyTmp(file); } string tmppath = path->mktmp(file); struct stat buf; int res; if ((res = lstat(tmppath.c_str(), &buf)) < 0) { ERROR("Could not perform lstat, strerror(errno)='%s'", file, strerror(errno)); FUNC_RET("%d", res, res); } if ((buf.st_uid != attr->f_uid) || (buf.st_gid != attr->f_gid)) { TRACE("Setting uid=%d, gid=%d", attr->f_uid, attr->f_gid); if ((res = chown(tmppath.c_str(), attr->f_uid, attr->f_gid)) < 0) { ERROR("Unable to chown, strerror(errno)='%s'", strerror(errno)); FUNC_RET("%d", res, res); } } if (buf.st_size > attr->f_size) { TRACE("Truncating to %u bytes", attr->f_size); if ((res = truncate(tmppath.c_str(), attr->f_size)) < 0) { ERROR("Unable to truncate, strerror(errno)='%s'", strerror(errno)); FUNC_RET("%d", res, res); } } if (buf.st_mode != attr->f_mode) { TRACE("Set mode=%u, old=%u", attr->f_mode, buf.st_mode); if ((res = chmod(tmppath.c_str(), attr->f_mode)) < 0) { ERROR("Unable to chmod, strerror(errno)='%s'", strerror(errno)); FUNC_RET("%d", res, res); } } if ((buf.st_atime != (time_t)attr->f_atime) || (buf.st_mtime != (time_t)attr->f_mtime)) { struct utimbuf utim = {attr->f_atime, attr->f_mtime}; if ((res = utime(tmppath.c_str(), &utim)) < 0) { ERROR("Unable to utime, strerror(errno)='%s'", strerror(errno)); FUNC_RET("%d", res, res); } } FUNC_RET("%d", 0, 0); }
static long __trace_req(act_t action, long * const pdata, proc_t * const pproc) { FUNC_BEGIN("%d,%p,%p", action, pdata, pproc); assert(!NO_ACTION(action)); assert(pproc); long res = 0; P(&trace_mutex); /* Wait while an existing action is being performed */ while (trace_info.action != T_NOP) { DBG("waiting for slot"); pthread_cond_wait(&trace_notice, &trace_mutex); } DBG("obtained slot"); /* Propose the request */ trace_info.action = action; trace_info.pproc = pproc; trace_info.data = ((pdata != NULL)?(*pdata):(0)); trace_info.result = 0; /* Wait while the action is being performed */ while (trace_info.action != T_ACK) { DBG("requesting action %s", trace_act_name(trace_info.action)); pthread_cond_broadcast(&trace_notice); pthread_cond_wait(&trace_notice, &trace_mutex); } if (pdata != NULL) { *pdata = trace_info.data; } res = trace_info.result; DBG("collected results"); /* Release slot */ trace_info.action = T_NOP; trace_info.pproc = NULL; trace_info.data = 0; trace_info.result = 0; pthread_cond_broadcast(&trace_notice); DBG("released slot"); V(&trace_mutex); FUNC_RET("%ld", res); }
int livecdfs_write(void *fs, char *file, long long offset, unsigned long count, char *buf) { FUNC_START("fs=%p, file='%s', offset=%l, count=%ul, buf=%p", fs, file, offset, count, buf); int ret = ((LiveCDFS*)fs)->doWrite(file, offset, count, buf); FUNC_RET("%d", ret, ret); }
bool trace_end(const proc_t * const pproc) { FUNC_BEGIN("%p", pproc); assert(pproc); trace_proxy_t __trace = TRACE_PROXY(pproc); bool res = (__trace(T_END, NULL, (proc_t *)pproc) == 0); FUNC_RET("%d", res); }
int LiveCDFS::doReadlink(const char *link, char *buf, int buflen) { FUNC_START("link='%s', buf=%p, buflen=%u", link, buf, buflen); if (!whiteout->isVisible(link)) { FUNC_RET("%d", -1, -1); } string linkpath = path->mkpath(link); TRACE("Reading linkpath='%s'", linkpath.c_str()); int ret = readlink(linkpath.c_str(), buf, buflen); if (ret < 0) { ERROR("strerror(errno)='%s' on readlink(link='%s', &buf, buflen=%d)", strerror(errno), linkpath.c_str(), buflen); } else { buf[ret] = '\0'; TRACE("After readlink, ret=%d, buf='%s'", ret, buf); /*if (buf[0] == '/') { string relpath = string("../"); int pos = 0; while ((pos = string(link).find("/", pos+1)) > 0) { relpath = path->join(relpath, "../"); } pos = 0; while ((pos = mount.find("/", pos+1)) > 0) { relpath = path->join(relpath, "../"); } relpath = path->join(relpath, string(buf)); memset(buf, 0, 256); strncpy(buf, relpath.c_str(), 255); ret = strlen(buf); TRACE("Translated relpath='%s'", buf); }*/ } FUNC_RET("%d", ret, ret); }
bool trace_self(void) { FUNC_BEGIN("trace_self()"); bool res = false; #ifdef __linux__ res = (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == 0); #else #warning "trace_self is not implemented for this platform" #endif /* __linux__ */ FUNC_RET(res, "trace_self()"); }