/* Copyright 2016, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *    * Neither the name of Google Inc. nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * file_lock.c: Implementation for a binary semaphore using a file lock.
 *
 * Warning: This relies on flock() which is known to be broken on NFS.
 *
 * The file will remain persistent once the lock has been used. Unfortunately,
 * unlinking the file can introduce a race condition so we leave the file
 * in place.
 *
 * The current process's PID will be written to the file for debug purposes.
 */

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "flash.h"
#include "ipc_lock.h"
#include "locks.h"

#define SLEEP_INTERVAL_MS	50

static void msecs_to_timespec(int msecs, struct timespec *tmspec)
{
	tmspec->tv_sec = msecs / 1000;
	tmspec->tv_nsec = (msecs % 1000) * 1000 * 1000;
}

static int lock_is_held(struct ipc_lock *lock)
{
	return lock->is_held;
}

static int test_dir(const char *path)
{
	struct stat s;

	if (lstat(path, &s) < 0) {
		msg_gerr("Cannot stat %s.\n", path);
		return -1;
	}

	if (!S_ISDIR(s.st_mode)) {
		msg_gerr("%s is not a directory.\n", path);
		return -1;
	}

	return 0;
}

static int file_lock_open_or_create(struct ipc_lock *lock)
{
	char path[PATH_MAX];
	const char *dir = SYSTEM_LOCKFILE_DIR;
	const char fallback[] = "/tmp";

	if (test_dir(dir)) {
		dir = fallback;
		msg_gerr("Trying fallback directory: %s\n", dir);
		if (test_dir(dir))
			return -1;
	}

	if (snprintf(path, sizeof(path), "%s/%s", dir, lock->filename) < 0)
		return -1;

	lock->fd = open(path, O_RDWR | O_CREAT, 0600);
	if (lock->fd < 0) {
		msg_gerr("Cannot open lockfile %s", path);
		return -1;
	}

	msg_gdbg("Opened file lock \"%s\"\n", path);
	return 0;
}

static int file_lock_get(struct ipc_lock *lock, int timeout_msecs)
{
	int msecs_remaining = timeout_msecs;
	struct timespec sleep_interval, rem;
	int ret = -1;

	if (timeout_msecs == 0)
		return flock(lock->fd, LOCK_EX | LOCK_NB);

	msecs_to_timespec(SLEEP_INTERVAL_MS, &sleep_interval);

	while ((ret = flock(lock->fd, LOCK_EX | LOCK_NB)) != 0) {
		if (errno != EWOULDBLOCK) {
			msg_gerr("Error obtaining lock");
			return -1;
		}

		if (msecs_remaining < SLEEP_INTERVAL_MS)
			msecs_to_timespec(msecs_remaining, &sleep_interval);

		while (nanosleep(&sleep_interval, &rem) != 0) {
			if (errno == EINTR) {
				sleep_interval = rem;
				continue;
			} else {
				msg_gerr("nanosleep() failed");
				return ret;
			}
		}

		if (timeout_msecs < 0)
			continue;

		msecs_remaining -= SLEEP_INTERVAL_MS;
		if (msecs_remaining < 0)
			break;
	}

	if (ret != 0) {
		msg_gerr("Timed out waiting for file lock.\n");
		return -1;
	}

	return 0;
}

static int file_lock_write_pid(struct ipc_lock *lock)
{
	ssize_t len;
	/* PIDs are usually 5 digits, but we'll reserve enough room for
	   a value of 2^32 (10 digits) out of paranoia. */
	char pid_str[11];

	if (ftruncate(lock->fd, 0) < 0) {
		msg_gerr("Cannot truncate lockfile");
		return -1;
	}

	snprintf(pid_str, sizeof(pid_str), "%lu", (unsigned long)getpid());
	len = write(lock->fd, pid_str, strlen(pid_str));
	if (len < 0) {
		msg_gerr("Cannot write PID to lockfile");
		return -1;
	}

	return 0;
}

static void file_lock_release(struct ipc_lock *lock)
{
	if (flock(lock->fd, LOCK_UN) < 0)
		msg_gerr("Cannot release lock");

	if (close(lock->fd) < 0)
		msg_gerr("Cannot close lockfile");
}

/*
 * timeout <0 = no timeout (try forever)
 * timeout 0  = do not wait (return immediately)
 * timeout >0 = wait up to $timeout milliseconds
 *
 * returns 0 to indicate lock acquired
 * returns >0 to indicate lock was already held
 * returns <0 to indicate failed to acquire lock
 */
int acquire_lock(struct ipc_lock *lock, int timeout_msecs)
{
	/* check if it is already held */
	if (lock_is_held(lock))
		return 1;

	if (file_lock_open_or_create(lock))
		return -1;

	if (file_lock_get(lock, timeout_msecs)) {
		lock->is_held = 0;
		close(lock->fd);
		return -1;
	} else {
		lock->is_held = 1;
	}

	/*
	 * Write PID to lockfile for debug purposes. Failure to write to
	 * the file should not be considered fatal. There might be something
	 * bad happening with the filesystem, but the lock has already been
	 * obtained and we may need our tools for diagnostics and repairs
	 * so we should continue anyway.
	 */
	file_lock_write_pid(lock);
	return 0;
}

/*
 * returns 0 if lock was released successfully
 * returns -1 if lock had not been held before the call
 */
int release_lock(struct ipc_lock *lock)
{
	if (lock_is_held(lock)) {
		file_lock_release(lock);
		lock->is_held = 0;
		return 0;
	}

	msg_ginfo("%s called but lock was not held on %s.\n",
			__func__, lock->filename);
	return -1;
}
