/* routines used by monitor publishers (containers) */ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path_sz, int do_mkdirp) { int ret; char *rundir; rundir = get_rundir(); if (!rundir) return -1; if (do_mkdirp) { ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath); if (ret < 0 || ret >= fifo_path_sz) { ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath); free(rundir); return -1; } ret = mkdir_p(fifo_path, 0755); if (ret < 0) { ERROR("unable to create monitor fifo dir %s", fifo_path); free(rundir); return ret; } } ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath); if (ret < 0 || ret >= fifo_path_sz) { ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath); free(rundir); return -1; } free(rundir); return 0; }
static char *lxclock_name(const char *p, const char *n) { int ret; int len; char *dest; const char *rundir; /* lockfile will be: * "/run" + "/lock/lxc/$lxcpath/$lxcname + '\0' if root * or * $XDG_RUNTIME_DIR + "/lock/lxc/$lxcpath/$lxcname + '\0' if non-root */ /* length of "/lock/lxc/" + $lxcpath + "/" + $lxcname + '\0' */ len = strlen("/lock/lxc/") + strlen(n) + strlen(p) + 2; rundir = get_rundir(); len += strlen(rundir); if ((dest = malloc(len)) == NULL) return NULL; ret = snprintf(dest, len, "%s/lock/lxc/%s", rundir, p); if (ret < 0 || ret >= len) { free(dest); return NULL; } ret = mkdir_p(dest, 0755); if (ret < 0) { /* fall back to "/tmp/" $(id -u) "/lxc/" $lxcpath / $lxcname + '\0' */ int l2 = 33 + strlen(n) + strlen(p); if (l2 > len) { char *d; d = realloc(dest, l2); if (!d) { free(dest); return NULL; } len = l2; dest = d; } ret = snprintf(dest, len, "/tmp/%d/lxc/%s", geteuid(), p); if (ret < 0 || ret >= len) { free(dest); return NULL; } ret = snprintf(dest, len, "/tmp/%d/lxc/%s/%s", geteuid(), p, n); } else ret = snprintf(dest, len, "%s/lock/lxc/%s/%s", rundir, p, n); if (ret < 0 || ret >= len) { free(dest); return NULL; } return dest; }
static char *lxclock_name(const char *p, const char *n) { int ret; int len; char *dest; const char *rundir; /* lockfile will be: * "/run" + "/lock/lxc/$lxcpath/$lxcname + '\0' if root * or * $XDG_RUNTIME_DIR + "/lock/lxc/$lxcpath/$lxcname + '\0' if non-root */ /* length of "/lock/lxc/" + $lxcpath + "/" + $lxcname + '\0' */ len = strlen("/lock/lxc/") + strlen(n) + strlen(p) + 2; rundir = get_rundir(); len += strlen(rundir); if ((dest = malloc(len)) == NULL) return NULL; ret = snprintf(dest, len, "%s/lock/lxc/%s", rundir, p); if (ret < 0 || ret >= len) { free(dest); return NULL; } process_lock(); ret = mkdir_p(dest, 0755); process_unlock(); if (ret < 0) { free(dest); return NULL; } ret = snprintf(dest, len, "%s/lock/lxc/%s/%s", rundir, p, n); if (ret < 0 || ret >= len) { free(dest); return NULL; } return dest; }
int main (int argc, char **argv) { struct ev_loop *loop; struct timeval tv[2]; char dirname[10]; char *shmdata; int rundir, rundirs[NUM_PROCS], sharedir; int pagesize; int i, j; // use the default event loop unless you have special needs loop = ev_default_loop (EVBACKEND_EPOLL); //EVFLAG_AUTO); rundir = get_rundir(); pagesize = getpagesize(); // Prepare shared data directory if ((mkdirat(rundir, SHARE_DIR_NAME, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0) { fprintf(stderr, "could not make share directory: %s\n", strerror(errno)); return -1; } if ((sharedir = openat(rundir, SHARE_DIR_NAME, O_DIRECTORY)) < 0) { fprintf(stderr, "could not open share directory: %s\n", strerror(errno)); return -1; } // Prepare worker rundirs for (i=0; i<NUM_PROCS; ++i) { sprintf(dirname, "%d", i); if ((mkdirat(rundir, dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0) { fprintf(stderr, "worker %d: could not make runtime directory: %s\n", i, strerror(errno)); return -1; } if ((rundirs[i] = openat(rundir, dirname, O_DIRECTORY)) < 0) { fprintf(stderr, "worker %d: could not open runtime directory: %s\n", i, strerror(errno)); return -1; } if ((mkfifoat(rundirs[i], "inputfile", S_IRUSR | S_IWUSR)) != 0) { fprintf(stderr, "%s: could not create FIFO: %s\n", "inputfile", strerror(errno)); } } // Memory map some data; for (j=0; j<NUM_SHMS; ++j) { // Maybe just use ids for shared SHM names shms[j] = openat(sharedir, "dbfile", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); ftruncate(shms[j], pagesize); shmdata = mmap((caddr_t)0, pagesize, PROT_WRITE, MAP_SHARED, shms[j], 0); strcpy(shmdata, "Very important DB data."); // Now "share" it for (i=0; i<NUM_PROCS; ++i) { linkat(sharedir, "dbfile", rundirs[i], "dbfile", 0); } } //ev_set_timeout_collect_interval (loop, 0.0001); //ev_set_io_collect_interval (loop, 0.0001); // Start children for (i=0; i<NUM_PROCS; ++i) { pid_t pid = fork(); if (pid == 0) { // Child fchdir(rundirs[i]); if (execle(argv[1], gnu_basename(argv[1]), "outputfile", "dbfile", "inputfile", NULL, NULL)) { fputs("Could not exec: ", stderr); fputs(strerror(errno), stderr); fputc('\n', stderr); exit(EXIT_FAILURE); } } else if (pid > 0) { // Parent } } // Initialize watchers for (i=0; i<NUM_PROCS; ++i) { ev_io *wio = &input_watcher[i]; fifos[i] = openat(rundirs[i], "inputfile", O_WRONLY); wio->data = (void*)i; ev_io_init(wio, input_cb, fifos[i], EV_WRITE); ev_io_start(loop, wio); } ev_child *wchld = &child_watcher; ev_child_init(wchld, child_cb, 0, 1); ev_child_start(loop, wchld); // now wait for events to arrive gettimeofday(tv+0, NULL); ev_loop (loop, 0); gettimeofday(tv+1, NULL); // unloop was called, so exit long t = (tv[1].tv_sec - tv[0].tv_sec) * 1000000 + (tv[1].tv_usec - tv[0].tv_usec); printf("\nTime taken: %lfs (%lfms average)\n\n", ((double)t) / 1000000.0, ((double)t) * NUM_PROCS / NUM_JOBS); // Hang up /* puts("Closing pipes..."); for (i=0; i<NUM_PROCS; ++i) { close(fifos[i]); } */ puts("Waiting for children processes to terminate..."); pid_t pid; do { pid = wait(NULL); if(pid == -1 && errno != ECHILD) { perror("Error during wait()"); abort(); } } while (pid > 0); // Cleanup shms puts("Cleaning SHMs..."); for (j=0; j<NUM_SHMS; ++j) { ftruncate(shms[j], 0); close(shms[i]); } // Finally... puts("Done."); return 0; }
static char *lxclock_name(const char *p, const char *n) { int ret; int len; char *dest; char *rundir; /* lockfile will be: * "/run" + "/lock/lxc/$lxcpath/$lxcname + '\0' if root * or * $XDG_RUNTIME_DIR + "/lock/lxc/$lxcpath/$lxcname + '\0' if non-root */ /* length of "/lock/lxc/" + $lxcpath + "/" + "." + $lxcname + '\0' */ len = strlen("/lock/lxc/") + strlen(n) + strlen(p) + 3; rundir = get_rundir(); if (!rundir) return NULL; len += strlen(rundir); if ((dest = malloc(len)) == NULL) { free(rundir); return NULL; } ret = snprintf(dest, len, "%s/lock/lxc/%s", rundir, p); if (ret < 0 || ret >= len) { free(dest); free(rundir); return NULL; } ret = mkdir_p(dest, 0755); if (ret < 0) { /* fall back to "/tmp/" + $(id -u) + "/lxc" + $lxcpath + "/" + "." + $lxcname + '\0' * * maximum length of $(id -u) is 10 calculated by (log (2 ** (sizeof(uid_t) * 8) - 1) / log 10 + 1) * * lxcpath always starts with '/' */ int l2 = 22 + strlen(n) + strlen(p); if (l2 > len) { char *d; d = realloc(dest, l2); if (!d) { free(dest); free(rundir); return NULL; } len = l2; dest = d; } ret = snprintf(dest, len, "/tmp/%d/lxc%s", geteuid(), p); if (ret < 0 || ret >= len) { free(dest); free(rundir); return NULL; } ret = mkdir_p(dest, 0755); if (ret < 0) { free(dest); free(rundir); return NULL; } ret = snprintf(dest, len, "/tmp/%d/lxc%s/.%s", geteuid(), p, n); } else ret = snprintf(dest, len, "%s/lock/lxc/%s/.%s", rundir, p, n); free(rundir); if (ret < 0 || ret >= len) { free(dest); return NULL; } return dest; }