static void provide(char *conf_name, int mvm_id, char c) { struct CONF *conf; unsigned long sz = PAGE_SIZE*NUM_PAGES*mr_count; int fd, i; void *mem; conf = config_parse(conf_name); assert(conf); mem = valloc(sz); assert(mem); memset(mem, c, sz); for_each_mr (i) mr_array[i].addr = mem + (i * mr_array[i].sz); printf("[0] initialize %d: ", mvm_id); notify(""); fd = init_mvm(sz, mem, conf, mvm_id); if (fd < 0) { fprintf(stderr, "can't open /dev/heca\n"); return; } notify("[3] dirty pages:"); c = (mvm_id % 2)? 'd' : 'e'; dirty_pages(NUM_PUSHBACK, c); notify("[6] dirty and print pages (2):"); dirty_pages(NUM_PUSHBACK, '2'); print_pages(NUM_PUSHBACK); notify("[.]disconnect:\n"); heca_close(fd); }
static void compute(char *conf_name) { int fd = -1, i; struct CONF *conf; conf = config_parse(conf_name); assert(conf); for_each_mr (i) { mr_array[i].addr = valloc(PAGE_SIZE*NUM_PAGES); mr_array[i].flags |= UD_SHARED; } notify("[0] initialize cvm:\n"); fd = init_cvm(0, conf, mr_array, mr_count, 1); if (fd < 0) { fprintf(stderr, "can't open /dev/heca\n"); goto out; } notify("[1] pull all pages: (read mode, should show '2')"); print_pages(NUM_PAGES); notify("[2] push back pages: (should just be discarded)"); push_pages(fd, NUM_PUSHBACK); notify("[4] re-pull pages: (read mode, should show 'e')"); print_pages(NUM_PUSHBACK); notify("[5] dirty and print pages: (acquiring write, writing '1', printing)"); dirty_pages(NUM_PUSHBACK, '1'); print_pages(NUM_PUSHBACK); notify("[8] print pages: (getting read from mvm, should show '2')"); print_pages(NUM_PUSHBACK); notify("[9] dirty and print pages: (acquiring write, writing '1', printing)"); dirty_pages(NUM_PUSHBACK, '1'); print_pages(NUM_PUSHBACK); notify("[11] dirty and print pages: (acquiring write, writing '1', printing)"); dirty_pages(NUM_PUSHBACK, '1'); print_pages(NUM_PUSHBACK); notify("[.] disconnect:\n"); heca_close(fd); out: config_clean(conf); for_each_mr (i) { free(mr_array[i].addr); mr_array[i].addr = 0; } }
int help() { char *s; int tmp; struct MyString *tmpstring1, *tmpstring2; s = malloc(sizeof(char)*8); s[0] = 'h'; s[1] = 'e'; s[2] = 'l'; s[3] = 'p'; s[4] = '.'; s[5] = 't'; s[6] = 'x'; s[7] = 't'; if (s == NULL) return exit_force(); tmpstring1 = my_strings_start; tmpstring2 = my_strings_end; tmp = N; my_strings_start = NULL; my_strings_end = NULL; N = 0; if(read_file(s, 8) == -3) return -3; print_pages(); free_my_memory(); my_strings_start = tmpstring1; my_strings_end = tmpstring2; N = tmp; return 0; }
int main(int argc, char *argv[]) { pm_kernel_t *ker; pm_process_t *proc; pid_t *pids; size_t num_procs; size_t i; pm_map_t **maps; size_t num_maps; char cmdline[256]; // this must be within the range of int int error; int rc = EXIT_SUCCESS; uint8_t pr_flags = 0; struct ksm_pages kp; memset(&kp, 0, sizeof(kp)); opterr = 0; do { int c = getopt(argc, argv, "hvsa"); if (c == -1) break; switch (c) { case 'a': pr_flags |= PR_ALL; break; case 's': pr_flags |= PR_SORTED; break; case 'v': pr_flags |= PR_VERBOSE; break; case 'h': usage(argv[0]); exit(EXIT_SUCCESS); case '?': fprintf(stderr, "unknown option: %c\n", optopt); usage(argv[0]); exit(EXIT_FAILURE); } } while (1); error = pm_kernel_create(&ker); if (error) { fprintf(stderr, "Error creating kernel interface -- " "does this kernel have pagemap?\n"); exit(EXIT_FAILURE); } if (pr_flags & PR_ALL) { error = pm_kernel_pids(ker, &pids, &num_procs); if (error) { fprintf(stderr, "Error listing processes.\n"); exit(EXIT_FAILURE); } } else { if (optind != argc - 1) { usage(argv[0]); exit(EXIT_FAILURE); } pids = malloc(sizeof(*pids)); if (pids == NULL) { fprintf(stderr, "Error allocating pid memory\n"); exit(EXIT_FAILURE); } *pids = strtoul(argv[optind], NULL, 10); if (*pids == 0) { fprintf(stderr, "Invalid PID\n"); rc = EXIT_FAILURE; goto exit; } num_procs = 1; if (getprocname(*pids, cmdline, sizeof(cmdline)) < 0) { cmdline[0] = '\0'; } printf("%s (%u):\n", cmdline, *pids); } printf("Warning: this tool only compares the KSM CRCs of pages, there is a chance of " "collisions\n"); for (i = 0; i < num_procs; i++) { error = pm_process_create(ker, pids[i], &proc); if (error) { fprintf(stderr, "warning: could not create process interface for %d\n", pids[i]); rc = EXIT_FAILURE; goto exit; } error = pm_process_maps(proc, &maps, &num_maps); if (error) { pm_process_destroy(proc); fprintf(stderr, "warning: could not read process map for %d\n", pids[i]); rc = EXIT_FAILURE; goto exit; } if (read_pages(&kp, maps, num_maps, pr_flags) < 0) { free(maps); pm_process_destroy(proc); rc = EXIT_FAILURE; goto exit; } free(maps); pm_process_destroy(proc); } if (pr_flags & PR_SORTED) { qsort(kp.pages, kp.len, sizeof(*kp.pages), cmp_pages); } print_pages(&kp, pr_flags); exit: free_pages(&kp, pr_flags); free(pids); return rc; }
static void compute(char *conf_name) { int fd = -1, i, lockfd = -1, rc; struct CONF *conf = NULL; pid_t child; const char *lockfn = "/tmp/tst.lock"; fprintf(stderr, "Parent (%d): started\n", getpid()); for_each_mr (i) { mr_array[i].addr = valloc(PAGE_SIZE*NUM_PAGES); #if 0 mr_array[i].flags |= UD_COPY_ON_ACCESS; #endif } if ((child = fork()) == -1) { perror("fork error"); goto failure; } else if (!child) { if ((lockfd = open(lockfn, O_RDWR|O_CREAT|O_APPEND, 0666)) < 0) { perror("open"); goto failure; } fprintf(stderr, "Child (%d): started\n", getpid()); sleep(2); if (flock(lockfd, LOCK_EX) < 0) { perror("flock"); goto failure; } notify("[1] pull all pages: "); print_pages(NUM_PAGES); if (flock(lockfd, LOCK_UN) < 0) { perror("flock"); goto failure; } sleep(1); if (flock(lockfd, LOCK_EX) < 0) { perror("flock"); goto failure; } notify("[4] re-pull pages:"); print_pages(NUM_PUSHBACK); notify("[5] dirty and print pages (1):"); dirty_pages(NUM_PUSHBACK, '1'); print_pages(NUM_PUSHBACK); notify("[7] dirty and print pages (3):"); dirty_pages(NUM_PUSHBACK, '3'); print_pages(NUM_PUSHBACK); if (flock(lockfd, LOCK_UN) < 0) { perror("flock"); goto failure; } sleep(1); if (flock(lockfd, LOCK_EX) < 0) { perror("flock"); goto failure; } notify("[.] disconnect:\n"); fprintf(stderr, "Child (%d): ended\n", getpid()); if (flock(lockfd, LOCK_UN) < 0) { perror("flock"); goto failure; } goto done; } sleep(1); if ((lockfd = open(lockfn, O_RDWR|O_CREAT|O_APPEND, 0666)) < 0) { perror("open"); goto failure; } if (flock(lockfd, LOCK_EX) < 0) { perror("flock"); goto failure; } fprintf(stderr, "[0] initialize:\n"); conf = config_parse(conf_name); assert(conf); fd = init_cvm(child, conf, mr_array, mr_count, 1); if (fd < 0) { fprintf(stderr, "can't open /dev/heca\n"); goto failure; } fprintf(stderr, "Parent: completed HECA setup...\n"); if (flock(lockfd, LOCK_UN) < 0) { perror("flock"); goto failure; } sleep(1); if (flock(lockfd, LOCK_EX) < 0) { perror("flock"); goto failure; } notify("[2] push back pages:"); push_pages(child, fd, NUM_PUSHBACK); if (flock(lockfd, LOCK_UN) < 0) { perror("flock"); goto failure; } /* parent */ while (1) { int status; pid_t end; end = waitpid(child, &status, WNOHANG|WUNTRACED); if (end == -1) { perror("waitpid error"); goto failure; } else if (!end) { /* child still running */ sleep(1); } else if (end == child) { if (WIFEXITED(status)) printf("Child ended normally\n"); else if (WIFSIGNALED(status)) printf("Child ended because of an uncaught signal\n"); else if (WIFSTOPPED(status)) printf("Child process has stopped\n"); break; } } fprintf(stderr, "Parent (%d): is back\n", getpid()); notify("[X] parent will now close /dev/heca"); heca_close(fd); fd = -1; fprintf(stderr, "Parent (%d): ended\n", getpid()); rc = 0; goto done; /* child/parent cleanup */ failure: rc = 1; done: if (conf) config_clean(conf); for_each_mr (i) { free(mr_array[i].addr); mr_array[i].addr = 0; } if (lockfd != -1) close(lockfd); exit(rc); }