int mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
		       int lock_type, unsigned int timeout_secs,
		       struct file_lock **lock_r)
{
	if (fd == -1) {
		i_assert(MAIL_INDEX_IS_IN_MEMORY(index));
		return 1;
	}

	return file_wait_lock(fd, path, lock_type, index->lock_method,
			      timeout_secs, lock_r);
}
示例#2
0
static int squat_uidlist_lock(struct squat_uidlist *uidlist)
{
	int ret;

	for (;;) {
		i_assert(uidlist->fd != -1);
		i_assert(uidlist->file_lock == NULL);
		i_assert(uidlist->dotlock == NULL);

		if (uidlist->trie->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
			ret = file_wait_lock(uidlist->fd, uidlist->path,
					     F_WRLCK,
					     uidlist->trie->lock_method,
					     SQUAT_TRIE_LOCK_TIMEOUT,
					     &uidlist->file_lock);
		} else {
			ret = file_dotlock_create(&uidlist->trie->dotlock_set,
						  uidlist->path, 0,
						  &uidlist->dotlock);
		}
		if (ret == 0) {
			i_error("squat uidlist %s: Locking timed out",
				uidlist->path);
			return 0;
		}
		if (ret < 0)
			return -1;

		ret = squat_uidlist_is_file_stale(uidlist);
		if (ret == 0)
			break;

		if (uidlist->file_lock != NULL)
			file_unlock(&uidlist->file_lock);
		else
			file_dotlock_delete(&uidlist->dotlock);
		if (ret < 0)
			return -1;

		squat_uidlist_close(uidlist);
		uidlist->fd = squat_trie_create_fd(uidlist->trie,
						   uidlist->path, 0);
		if (uidlist->fd == -1)
			return -1;
	}
	return 1;
}
示例#3
0
文件: file-lock.c 项目: aosm/dovecot
int file_try_lock(int fd, const char *path, int lock_type,
		  enum file_lock_method lock_method,
		  struct file_lock **lock_r)
{
	return file_wait_lock(fd, path, lock_type, lock_method, 0, lock_r);
}
示例#4
0
static void
ssl_params_if_unchanged(const char *path, time_t mtime,
			unsigned int ssl_dh_parameters_length ATTR_UNUSED)
{
	const char *temp_path, *error;
	struct file_lock *lock;
	struct stat st, st2;
	mode_t old_mask;
	int fd, ret;
	buffer_t *buf;

#ifdef HAVE_SETPRIORITY
	if (setpriority(PRIO_PROCESS, 0, SSL_PARAMS_PRIORITY) < 0)
		i_error("setpriority(%d) failed: %m", SSL_PARAMS_PRIORITY);
#endif

	temp_path = t_strconcat(path, ".tmp", NULL);

	old_mask = umask(0);
	fd = open(temp_path, O_WRONLY | O_CREAT, 0644);
	umask(old_mask);

	if (fd == -1)
		i_fatal("creat(%s) failed: %m", temp_path);

	/* If multiple dovecot instances are running, only one of them needs
	   to regenerate this file. */
	ret = file_wait_lock(fd, temp_path, F_WRLCK,
			     FILE_LOCK_METHOD_FCNTL,
			     SSL_BUILD_PARAM_TIMEOUT_SECS, &lock);
	if (ret < 0)
		i_fatal("file_try_lock(%s) failed: %m", temp_path);
	if (ret == 0) {
		/* someone else is writing this */
		i_fatal("Timeout while waiting for %s generation to complete",
			path);
	}

	/* make sure the .tmp file is still the one we created */
	if (fstat(fd, &st) < 0)
		i_fatal("fstat(%s) failed: %m", temp_path);
	if (stat(temp_path, &st2) < 0) {
		if (errno != ENOENT)
			i_fatal("stat(%s) failed: %m", temp_path);
		st2.st_ino = st.st_ino+1;
	}
	if (st.st_ino != st2.st_ino) {
		/* nope. so someone else just generated the file. */
		i_close_fd(&fd);
		return;
	}

	/* check that the parameters file is still the same */
	if (stat(path, &st) == 0) {
		if (st.st_mtime != mtime) {
			i_close_fd(&fd);
			return;
		}
	} else if (errno != ENOENT)
		i_fatal("stat(%s) failed: %m", path);

	/* ok, we really want to generate it. */
	if (ftruncate(fd, 0) < 0)
		i_fatal("ftruncate(%s) failed: %m", temp_path);

	i_info("Generating SSL parameters");

	buf = buffer_create_dynamic(pool_datastack_create(), 1024);
	if (ssl_iostream_generate_params(buf, ssl_dh_parameters_length,
					 &error) < 0) {
		i_fatal("ssl_iostream_generate_params(%u) failed: %s",
			ssl_dh_parameters_length, error);
	}
	if (write_full(fd, buf->data, buf->used) < 0)
		i_fatal("write(%s) failed: %m", temp_path);

	if (rename(temp_path, path) < 0)
		i_fatal("rename(%s, %s) failed: %m", temp_path, path);
	if (close(fd) < 0)
		i_fatal("close(%s) failed: %m", temp_path);
	file_lock_free(&lock);

	i_info("SSL parameters regeneration completed");
}