/* 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 "android.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];

	if (in_android()) {
		char *tmpdir;

		tmpdir = android_tmpdir_path();
		if (!tmpdir)
			return -1;

		if (snprintf(path, sizeof(path), "%s/%s",
				tmpdir, lock->filename) < 0) {
			return -1;
		}
	} else {
		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;
}
