Esempio n. 1
0
int
main(int argc, char *argv[])
{
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	WT_RAND_STATE rnd;
	uint64_t key;
	uint32_t absent, count, timeout;
	int ch, status, ret;
	pid_t pid;
	char *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	working_dir = NULL;
	timeout = 10;
	while ((ch = __wt_getopt(progname, argc, argv, "h:t:")) != EOF)
		switch (ch) {
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 't':
			timeout = (uint32_t)atoi(__wt_optarg);
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, 512, working_dir);
	testutil_make_work_dir(home);

	/*
	 * Fork a child to insert as many items.  We will then randomly
	 * kill the child, run recovery and make sure all items we wrote
	 * exist after recovery runs.
	 */
	if ((pid = fork()) < 0)
		testutil_die(errno, "fork");

	if (pid == 0) { /* child */
		fill_db();
		return (EXIT_SUCCESS);
	}

	/* parent */
	__wt_random_init(&rnd);
	/* Sleep for the configured amount of time before killing the child. */
	printf("Parent: sleep %" PRIu32 " seconds, then kill child\n", timeout);
	sleep(timeout);

	/*
	 * !!! It should be plenty long enough to make sure more than one
	 * log file exists.  If wanted, that check would be added here.
	 */
	printf("Kill child\n");
	if (kill(pid, SIGKILL) != 0)
		testutil_die(errno, "kill");
	waitpid(pid, &status, 0);

	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it.
	 */
	chdir(home);
	printf("Open database, run recovery and verify content\n");
	if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	if ((fp = fopen(RECORDS_FILE, "r")) == NULL)
		testutil_die(errno, "fopen");

	/*
	 * For every key in the saved file, verify that the key exists
	 * in the table after recovery.  Since we did write-no-sync, we
	 * expect every key to have been recovered.
	 */
	for (absent = count = 0;; ++count) {
		ret = fscanf(fp, "%" SCNu64 "\n", &key);
		if (ret != EOF && ret != 1)
			testutil_die(errno, "fscanf");
		if (ret == EOF)
			break;
		cursor->set_key(cursor, key);
		if ((ret = cursor->search(cursor)) != 0) {
			if (ret != WT_NOTFOUND)
				testutil_die(ret, "search");
			printf("no record with key %" PRIu64 "\n", key);
			++absent;
		}
	}
	fclose(fp);
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if (absent) {
		printf("%u record(s) absent from %u\n", absent, count);
		return (EXIT_FAILURE);
	}
	printf("%u records verified\n", count);
	return (EXIT_SUCCESS);
}
Esempio n. 2
0
File: main.c Progetto: ajdavis/mongo
int
main(int argc, char *argv[])
{
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	pid_t pid;
	uint64_t new_offset, offset;
	uint32_t count, max_key;
	int ch, ret, status;
	const char *working_dir;

	(void)testutil_set_progname(argv);

	working_dir = "WT_TEST.truncated-log";
	while ((ch = __wt_getopt(progname, argc, argv, "h:")) != EOF)
		switch (ch) {
		case 'h':
			working_dir = __wt_optarg;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, sizeof(home), working_dir);
	testutil_make_work_dir(home);

	/*
	 * Fork a child to do its work.  Wait for it to exit.
	 */
	if ((pid = fork()) < 0)
		testutil_die(errno, "fork");

	if (pid == 0) { /* child */
		fill_db();
		return (EXIT_SUCCESS);
	}

	/* parent */
	/* Wait for child to kill itself. */
	if (waitpid(pid, &status, 0) == -1)
		testutil_die(errno, "waitpid");

	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it.
	 */
	if (chdir(home) != 0)
		testutil_die(errno, "chdir: %s", home);

	printf("Open database, run recovery and verify content\n");
	if ((fp = fopen(RECORDS_FILE, "r")) == NULL)
		testutil_die(errno, "fopen");
	ret = fscanf(fp, "%" SCNu64 " %" SCNu32 "\n", &offset, &max_key);
	if (ret != 2)
		testutil_die(errno, "fscanf");
	if (fclose(fp) != 0)
		testutil_die(errno, "fclose");
	/*
	 * The offset is the beginning of the last record.  Truncate to
	 * the middle of that last record (i.e. ahead of that offset).
	 */
	if (offset > UINT64_MAX - V_SIZE)
		testutil_die(ERANGE, "offset");
	new_offset = offset + V_SIZE;
	printf("Parent: Log file 1: Key %" PRIu32 " at %" PRIu64 "\n",
	     max_key, offset);
	printf("Parent: Truncate mid-record to %" PRIu64 "\n", new_offset);
	if (truncate(LOG_FILE_1, (wt_off_t)new_offset) != 0)
		testutil_die(errno, "truncate");

	testutil_check(wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn));
	testutil_check(conn->open_session(conn, NULL, NULL, &session));
	testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));

	/*
	 * For every key in the saved file, verify that the key exists
	 * in the table after recovery.  Since we did write-no-sync, we
	 * expect every key to have been recovered.
	 */
	count = 0;
	while (cursor->next(cursor) == 0)
		++count;
	/*
	 * The max key in the saved file is the key we truncated, but the
	 * key space starts at 0 and we're counting the records here, so we
	 * expect the max key number of records.  Add one for the system
	 * record for the previous LSN that the cursor will see too.
	 */
	if (count > (max_key + 1)) {
		printf("expected %" PRIu32 " records found %" PRIu32 "\n",
		    max_key, count);
		return (EXIT_FAILURE);
	}
	printf("%" PRIu32 " records verified\n", count);

	/*
	 * Write a log record and then walk the log to make sure we can
	 * read that log record that is beyond the truncated record.
	 */
	write_and_read_new(session);
	testutil_check(conn->close(conn, NULL));
	return (EXIT_SUCCESS);
}
Esempio n. 3
0
int
main(int argc, char *argv[])
{
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	uint64_t new_offset, offset;
	uint32_t count, max_key;
	int ch, status, ret;
	pid_t pid;
	const char *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	working_dir = "WT_TEST.truncated-log";
	while ((ch = __wt_getopt(progname, argc, argv, "h:")) != EOF)
		switch (ch) {
		case 'h':
			working_dir = __wt_optarg;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, 512, working_dir);
	testutil_make_work_dir(home);

	/*
	 * Fork a child to insert as many items.  We will then randomly
	 * kill the child, run recovery and make sure all items we wrote
	 * exist after recovery runs.
	 */
	if ((pid = fork()) < 0)
		testutil_die(errno, "fork");

	if (pid == 0) { /* child */
		fill_db();
		return (EXIT_SUCCESS);
	}

	/* parent */
	/* Wait for child to kill itself. */
	if (waitpid(pid, &status, 0) == -1)
		testutil_die(errno, "waitpid");

	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it.
	 */
	if (chdir(home) != 0)
		testutil_die(errno, "chdir: %s", home);

	printf("Open database, run recovery and verify content\n");
	if ((fp = fopen(RECORDS_FILE, "r")) == NULL)
		testutil_die(errno, "fopen");
	ret = fscanf(fp, "%" SCNu64 " %" SCNu32 "\n", &offset, &max_key);
	if (ret != 2)
		testutil_die(errno, "fscanf");
	if (fclose(fp) != 0)
		testutil_die(errno, "fclose");
	/*
	 * The offset is the beginning of the last record.  Truncate to
	 * the middle of that last record (i.e. ahead of that offset).
	 */
	if (offset > UINT64_MAX - V_SIZE)
		testutil_die(ERANGE, "offset");
	new_offset = offset + V_SIZE;
	printf("Parent: Truncate to %" PRIu64 "\n", new_offset);
	if ((ret = truncate(LOG_FILE_1, (wt_off_t)new_offset)) != 0)
		testutil_die(errno, "truncate");

	if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	/*
	 * For every key in the saved file, verify that the key exists
	 * in the table after recovery.  Since we did write-no-sync, we
	 * expect every key to have been recovered.
	 */
	count = 0;
	while ((ret = cursor->next(cursor)) == 0)
		++count;
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if (count > max_key) {
		printf("expected %" PRIu32 " records found %" PRIu32 "\n",
		    max_key, count);
		return (EXIT_FAILURE);
	}
	printf("%" PRIu32 " records verified\n", count);
	return (EXIT_SUCCESS);
}
Esempio n. 4
0
int main(int argc, char **argv)
{
  int fdfifo, fdfifowrite;
  char *x;
  unsigned long id;

  VERSIONINFO;

  x = env_get("WORKDIR");
  if (!x)
    strerr_die2x(111, FATAL, "$WORKDIR not set");
  if (chdir(x) == -1)
    strerr_die4sys(111, FATAL, "unable to chdir to ", x, ": ");

  x = env_get("GID");
  if (!x)
    strerr_die2x(111, FATAL, "$GID not set");
  scan_ulong(x,&id);
  if (prot_gid((int) id) == -1)
    strerr_die2sys(111, FATAL, "unable to setgid: ");

  x = env_get("UID");
  if (!x)
    strerr_die2x(111, FATAL, "$UID not set");
  scan_ulong(x,&id);

  /* undocumented feature */
  if(id == 0)
    if(!env_get("IWANTTORUNASROOTANDKNOWWHATIDO"))
      strerr_die2x(111, FATAL, "unable to run under uid 0: please change $UID");

  if (prot_uid((int) id) == -1)
    strerr_die2sys(111, FATAL, "unable to setuid: ");

  buffer_putsflush(buffer_2, ARGV0 "starting\n");

  if(fifo_make(FIFONAME, 0620) == -1)
    strerr_warn4(ARGV0, "unable to create fifo ", FIFONAME, " ", &strerr_sys);

  fdfifo = open_read(FIFONAME);
  if(fdfifo == -1)
    strerr_die4sys(111, FATAL, "unable to open for read ", FIFONAME, " ");
  coe(fdfifo);
  ndelay_on(fdfifo); /* DJB says: shouldn't be necessary */

  /* we need this to keep the fifo from beeing closed */
  fdfifowrite = open_write(FIFONAME);
  if (fdfifowrite == -1)
    strerr_die4sys(111, FATAL, "unable to open for write ", FIFONAME, " ");
  coe(fdfifowrite);

  /* init a buffer for nonblocking reading */
  buffer_init(&wr, waitread, fdfifo, waitreadspace, sizeof waitreadspace);

  t = dAVLAllocTree();

  /* read snapshot of dnsdatatree */ 
  fill_db();

  /* SIGALRM can be used to check if dumping the database is needed */
  sig_catch(sig_alarm, sigalrm);

  /* SIGHUP can be used to force dumping the database */
  sig_catch(sig_hangup, sighup);  

  /* check if out child is done */
  sig_catch(sig_child, sigchld);  

  // XXX SIGINT, SIGTERM,

  /* do our normal workloop */
  doit();

  /* we shouldn't get here */
  return 1;
}