int Psyscall_copyinargs(struct ps_prochandle *P, int nargs, argdes_t *argp, uintptr_t ap) { if (P->status.pr_dmodel == PR_MODEL_ILP32) { int32_t arglist[MAXARGS+2]; int i; argdes_t *adp; for (i = 0, adp = argp; i < nargs; i++, adp++) arglist[1 + i] = (int32_t)adp->arg_value; arglist[0] = P->status.pr_lwp.pr_reg[REG_RIP]; if (Pwrite(P, &arglist[0], sizeof (int) * (nargs+1), (uintptr_t)ap) != sizeof (int) * (nargs+1)) return (-1); } else { int64_t arglist[MAXARGS+2]; int i; argdes_t *adp; int pusharg = (nargs > 6) ? nargs - 6: 0; for (i = 0, adp = argp; i < nargs; i++, adp++) { switch (i) { case 0: (void) Pputareg(P, REG_RDI, adp->arg_value); break; case 1: (void) Pputareg(P, REG_RSI, adp->arg_value); break; case 2: (void) Pputareg(P, REG_RDX, adp->arg_value); break; case 3: (void) Pputareg(P, REG_RCX, adp->arg_value); break; case 4: (void) Pputareg(P, REG_R8, adp->arg_value); break; case 5: (void) Pputareg(P, REG_R9, adp->arg_value); break; default: arglist[i - 5] = (uint64_t)adp->arg_value; break; } } arglist[0] = P->status.pr_lwp.pr_reg[REG_RIP]; if (Pwrite(P, &arglist[0], sizeof (int64_t) * (pusharg + 1), ap) != sizeof (int64_t) * (pusharg + 1)) return (-1); } return (0); }
int Psyscall_copyinargs(struct ps_prochandle *P, int nargs, argdes_t *argp, uintptr_t ap) { uint32_t arglist[MAXARGS+2]; int i; argdes_t *adp; for (i = 0, adp = argp; i < nargs; i++, adp++) { arglist[i] = adp->arg_value; if (i < 6) (void) Pputareg(P, R_O0+i, adp->arg_value); } if (nargs > 6 && Pwrite(P, &arglist[0], sizeof (int32_t) * nargs, (uintptr_t)ap) != sizeof (int32_t) * nargs) return (-1); return (0); }
static void read_dumphdr(void) { if (filemode) dumpfd = Open(dumpfile, O_RDONLY, 0644); else dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); endoff = llseek(dumpfd, -DUMP_OFFSET, SEEK_END) & -DUMP_OFFSET; Pread(dumpfd, &dumphdr, sizeof (dumphdr), endoff); Pread(dumpfd, &datahdr, sizeof (datahdr), endoff + sizeof (dumphdr)); pagesize = dumphdr.dump_pagesize; if (dumphdr.dump_magic != DUMP_MAGIC) logprint(SC_SL_NONE | SC_EXIT_PEND, "bad magic number %x", dumphdr.dump_magic); if ((dumphdr.dump_flags & DF_VALID) == 0 && !disregard_valid_flag) logprint(SC_SL_NONE | SC_IF_VERBOSE | SC_EXIT_OK, "dump already processed"); if (dumphdr.dump_version != DUMP_VERSION) logprint(SC_SL_NONE | SC_IF_VERBOSE | SC_EXIT_PEND, "dump version (%d) != %s version (%d)", dumphdr.dump_version, progname, DUMP_VERSION); if (dumphdr.dump_wordsize != DUMP_WORDSIZE) logprint(SC_SL_NONE | SC_EXIT_PEND, "dump is from %u-bit kernel - cannot save on %u-bit kernel", dumphdr.dump_wordsize, DUMP_WORDSIZE); if (datahdr.dump_datahdr_magic == DUMP_DATAHDR_MAGIC) { if (datahdr.dump_datahdr_version != DUMP_DATAHDR_VERSION) logprint(SC_SL_NONE | SC_IF_VERBOSE | SC_EXIT_PEND, "dump data version (%d) != %s data version (%d)", datahdr.dump_datahdr_version, progname, DUMP_DATAHDR_VERSION); } else { (void) memset(&datahdr, 0, sizeof (datahdr)); datahdr.dump_maxcsize = pagesize; } /* * Read the initial header, clear the valid bits, and compare headers. * The main header may have been overwritten by swapping if we're * using a swap partition as the dump device, in which case we bail. */ Pread(dumpfd, &corehdr, sizeof (dumphdr_t), dumphdr.dump_start); corehdr.dump_flags &= ~DF_VALID; dumphdr.dump_flags &= ~DF_VALID; if (memcmp(&corehdr, &dumphdr, sizeof (dumphdr_t)) != 0) { /* * Clear valid bit so we don't complain on every invocation. */ if (!filemode) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); logprint(SC_SL_ERR | SC_EXIT_ERR, "initial dump header corrupt"); } }
int main(int argc, char **argv) { bool walk = false, randsize = false, verbose = false, csum = false, rtest = false, wtest = false; int fd1, fd2 = 0, direct = 0, nbytes = 4096, j, o; unsigned long size, i, offset = 0, done = 0, unique = 0, benchmark = 0; void *buf1 = NULL, *buf2 = NULL; struct pagestuff *pages, *p; unsigned char c[16]; time_t last_printed = 0; extern char *optarg; RC4_KEY writedata; RC4_set_key(&writedata, 16, bcache_magic); while ((o = getopt(argc, argv, "dnwvscwlb:")) != EOF) switch (o) { case 'd': direct = O_DIRECT; break; case 'n': walk = true; break; case 'v': verbose = true; break; case 's': randsize = true; break; case 'c': csum = true; break; case 'w': wtest = true; break; case 'r': rtest = true; break; case 'l': klog = true; break; case 'b': benchmark = atol(optarg); break; default: usage(); } argv += optind; argc -= optind; if (!rtest && !wtest) rtest = true; if (argc < 1) { printf("Please enter a device to test\n"); exit(EXIT_FAILURE); } if (!csum && !benchmark && argc < 2) { printf("Please enter a device to compare against\n"); exit(EXIT_FAILURE); } fd1 = open(argv[0], (wtest ? O_RDWR : O_RDONLY)|direct); if (!csum && !benchmark) fd2 = open(argv[1], (wtest ? O_RDWR : O_RDONLY)|direct); if (fd1 == -1 || fd2 == -1) { perror("Error opening device"); exit(EXIT_FAILURE); } size = getblocks(fd1); if (!csum && !benchmark) size = MIN(size, getblocks(fd2)); size = size / 8 - 16; pages = calloc(size + 16, sizeof(*pages)); printf("size %li\n", size); if (posix_memalign(&buf1, 4096, 4096 * 16) || posix_memalign(&buf2, 4096, 4096 * 16)) { printf("Could not allocate buffers\n"); exit(EXIT_FAILURE); } //setvbuf(stdout, NULL, _IONBF, 0); for (i = 0; !benchmark || i < benchmark; i++) { bool writing = (wtest && (i & 1)) || !rtest; nbytes = randsize ? drand48() * 16 + 1 : 1; nbytes <<= 12; offset >>= 12; offset += walk ? normal() * 20 : random(); offset %= size; offset <<= 12; if (!(i % 200)) flushlog(); if (!verbose) { time_t now = time(NULL); if (now - last_printed >= 2) { last_printed = now; goto print; } } else print: printf("Loop %6li offset %9li sectors %3i, %6lu mb done, %6lu mb unique\n", i, offset >> 9, nbytes >> 9, done >> 11, unique >> 11); done += nbytes >> 9; if (!writing) Pread(fd1, buf1, nbytes, offset); if (!writing && !csum && !benchmark) Pread(fd2, buf2, nbytes, offset); for (j = 0; j < nbytes; j += 4096) { p = &pages[(offset + j) / 4096]; if (writing) RC4(&writedata, 4096, zero, buf1 + j); if (csum) { MD4(buf1 + j, 4096, &c[0]); if (writing || (!p->readcount && !p->writecount)) { memcpy(&p->oldcsum[0], &p->csum[0], 16); memcpy(&p->csum[0], c, 16); } else if (memcmp(&p->csum[0], c, 16)) goto bad; } else if (!writing && !benchmark && memcmp(buf1 + j, buf2 + j, 4096)) goto bad; if (!p->writecount && !p->readcount) unique += 8; writing ? p->writecount++ : p->readcount++; } if (writing) Pwrite(fd1, buf1, nbytes, offset); if (writing && !csum && !benchmark) Pwrite(fd2, buf2, nbytes, offset); } printf("Loop %6li offset %9li sectors %3i, %6lu mb done, %6lu mb unique\n", i, offset >> 9, nbytes >> 9, done >> 11, unique >> 11); exit(EXIT_SUCCESS); err: perror("IO error"); flushlog(); exit(EXIT_FAILURE); bad: printf("Bad read! loop %li offset %li readcount %i writecount %i\n", i, (offset + j) >> 9, p->readcount, p->writecount); if (!memcmp(&p->oldcsum[0], c, 16)) printf("Matches previous csum\n"); flushlog(); exit(EXIT_FAILURE); }
void geFilePool::Writer::PwriteCRC(void *buffer, size_t size, off64_t offset) { size_t data_len = size - sizeof(uint32); ToLittleEndianBuffer(static_cast<char*>(buffer) + data_len, Crc32(buffer, data_len)); Pwrite(buffer, size, offset); }