Exemplo n.º 1
0
int
lock_mtab (void) {
	int i;
	struct timespec waittime;
	struct timeval maxtime;
	char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];

	if (!signals_have_been_setup) {
		int sig = 0;
		struct sigaction sa;

		sa.sa_handler = handler;
		sa.sa_flags = 0;
		sigfillset (&sa.sa_mask);

		while (sigismember (&sa.sa_mask, ++sig) != -1
		       && sig != SIGCHLD) {
			if (sig == SIGALRM)
				sa.sa_handler = setlkw_timeout;
			else
				sa.sa_handler = handler;
			sigaction (sig, &sa, (struct sigaction *) 0);
		}
		signals_have_been_setup = 1;
	}

	sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());

	i = open (linktargetfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
	if (i < 0) {
		/* linktargetfile does not exist (as a file)
		   and we cannot create it. Read-only filesystem?
		   Too many files open in the system?
		   Filesystem full? */
		return EX_FILEIO;
	}
	close(i);

	maxtime = mono_time();
	maxtime.tv_sec += MOUNTLOCK_MAXTIME;

	waittime.tv_sec = 0;
	waittime.tv_nsec = (1000 * MOUNTLOCK_WAITTIME);

	/* Repeat until it was us who made the link */
	while (!we_created_lockfile) {
		struct timeval now;
		struct flock flock;
		int errsv, j;

		j = link(linktargetfile, _PATH_MOUNTED_LOCK);
		errsv = errno;

		if (j == 0)
			we_created_lockfile = 1;

		if (j < 0 && errsv != EEXIST) {
			(void) unlink(linktargetfile);
			return EX_FILEIO;
		}

		lockfile_fd = open (_PATH_MOUNTED_LOCK, O_WRONLY);

		if (lockfile_fd < 0) {
			/* Strange... Maybe the file was just deleted? */
			now = mono_time();
			if (errno == ENOENT && now.tv_sec < maxtime.tv_sec) {
				we_created_lockfile = 0;
				continue;
			}
			(void) unlink(linktargetfile);
			return EX_FILEIO;
		}

		flock.l_type = F_WRLCK;
		flock.l_whence = SEEK_SET;
		flock.l_start = 0;
		flock.l_len = 0;

		if (j == 0) {
			/* We made the link. Now claim the lock. If we can't
			 * get it, continue anyway
			 */
			fcntl (lockfile_fd, F_SETLK, &flock);
			(void) unlink(linktargetfile);
		} else {
			/* Someone else made the link. Wait. */
			now = mono_time();
			if (now.tv_sec < maxtime.tv_sec) {
				alarm(maxtime.tv_sec - now.tv_sec);
				if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) {
					(void) unlink(linktargetfile);
					return EX_FILEIO;
				}
				alarm(0);
				nanosleep(&waittime, NULL);
			} else {
				(void) unlink(linktargetfile);
				return EX_FILEIO;
			}
			close(lockfile_fd);
		}
	}
	return 0;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	double t0, t1;
	if (argc != 5) {
		puts("Usage: syncbench file write_size write_qty (d|s)");
		return 1;
	}
	if (strlen(argv[4]) != 1) {
		puts("You're a bad person.");
		return 1;
	}
	int d;
	if (argv[4][0] == 'd') {
		d = 1;
	} else if (argv[4][0] == 's') {
		d = 0;
	} else {
		puts("That last parameter should have been either 'd' or 's'.");
		return 1;
	}
	int write_size = atoi(argv[2]);
	int no_of_writes = atoi(argv[3]);
	if ((write_size <= 0) || (no_of_writes <= 0)) {
		puts("You want me to write no bytes?");
		return 1;
	}
	int fd = open(argv[1], O_CREAT | O_WRONLY | O_EXCL);
	if (fd == -1) {
		if (errno == EEXIST) {
			printf("Refusing to nuke existing file %s.\n", argv[1]);
		} else {
			printf("Can't open %s for write.\n", argv[1]);
		}
		return 1;
	}
	char *bytes = malloc(write_size);
	if (bytes == NULL) {
		puts("malloc() failed, FML.");
		return 1;
	}
	int i;
	for (i = 0; i < write_size; i++) {
		bytes[i] = '0' + (i % 10);
	}
	if (mono_time(&t0)) {
		puts("can't consult a clock.");
		return 1;
	}
	for (i = 0; i < no_of_writes; i++) {
		ssize_t r = write(fd, bytes, write_size);
		if (r != write_size) {
			puts("write() failed.");
			return 1;
		}
		if (d) {
			if (fdatasync(fd)) {
				puts("fdatasync() failed.");
				return 1;
			}
		} else {
			if (fsync(fd)) {
				puts("fsync() failed.");
				return 1;
			}
		}
	}
	if (mono_time(&t1)) {
		puts("really, can't consult the clock?");
		return 1;
	}
	char *c = d ? "fdatasync" : "fsync";
	printf("Performed %d %s()s in %f seconds.\n", no_of_writes, c, t1 - t0);
	double rate = no_of_writes / (t1 - t0);
	printf("That's %f calls/second, or %f seconds/call.\n", rate, 1 / rate);
	return 0;
}