summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/lock/build.mk2
-rw-r--r--util/lock/csem.c275
-rw-r--r--util/lock/csem.h154
-rw-r--r--util/lock/file_lock.c251
-rw-r--r--util/lock/gec_lock.c2
-rw-r--r--util/lock/ipc_lock.c105
-rw-r--r--util/lock/ipc_lock.h16
-rw-r--r--util/lock/locks.h15
8 files changed, 263 insertions, 557 deletions
diff --git a/util/lock/build.mk b/util/lock/build.mk
index 6cf595b995..48c152d830 100644
--- a/util/lock/build.mk
+++ b/util/lock/build.mk
@@ -6,5 +6,5 @@
# Lock library
#
-util-lock-objs=csem.o ipc_lock.o gec_lock.o
+util-lock-objs=file_lock.o gec_lock.o
util-lock-objs+=android.o
diff --git a/util/lock/csem.c b/util/lock/csem.c
deleted file mode 100644
index 2ad3d5d873..0000000000
--- a/util/lock/csem.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2003 Sun Microsystems, Inc.
- * Copyright 2010 Google, Inc.
- *
- * 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.
- *
- * Developer's note: This was open sourced by Sun Microsystems, which got it
- * via Cobalt Networks. It has been fairly extensively modified since then.
- */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <errno.h>
-#include <sched.h>
-
-#include "csem.h"
-
-#if (defined(__BIONIC__) || defined(__GNU_LIBRARY__)) && !defined(_SEM_SEMUN_UNDEFINED)
-/* union semun is defined by including <sys/sem.h> */
-#else
-/* according to X/OPEN we have to define it ourselves */
-union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
- unsigned short int *array; /* array for GETALL, SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
-};
-#endif
-
-/*
- * On some platforms semctl(SETVAL) sets sem_otime, on other platforms it
- * does not. Figure out what this platform does.
- *
- * Returns 0 if semctl(SETVAL) does not set sem_otime
- * Returns 1 if semctl(SETVAL) does set sem_otime
- * Returns -1 on error
- */
-static int does_semctl_set_otime(void)
-{
- int sem_id;
- int ret;
-
- /* create a test semaphore */
- sem_id = semget(IPC_PRIVATE, 1, S_IRUSR|S_IWUSR);
- if (sem_id < 0)
- return -1;
-
- /* set the value */
- if (csem_setval(sem_id, 1) < 0) {
- csem_destroy(sem_id);
- return -1;
- }
-
- /* read sem_otime */
- ret = (csem_get_otime(sem_id) > 0) ? 1 : 0;
-
- /* clean up */
- csem_destroy(sem_id);
-
- return ret;
-}
-
-int csem_create(key_t key, unsigned val)
-{
- static int need_otime_hack = -1;
- int sem_id;
-
- /* see if we need to trigger a semop to set sem_otime */
- if (need_otime_hack < 0) {
- int ret = does_semctl_set_otime();
- if (ret < 0)
- return -1;
-
- need_otime_hack = !ret;
- }
-
- /* create it or fail */
- sem_id = semget(key, 1, IPC_CREAT|IPC_EXCL | S_IRUSR|S_IWUSR);
- if (sem_id < 0)
- return -1;
-
- /* initalize the value */
- if (need_otime_hack)
- val++;
-
- if (csem_setval(sem_id, val) < 0) {
- csem_destroy(sem_id);
- return -1;
- }
-
- if (need_otime_hack) {
- /* force sem_otime to change */
- csem_down(sem_id);
- }
-
- return sem_id;
-}
-
-/* how many times to loop, waiting for sem_otime */
-#define MAX_OTIME_LOOPS 1000
-
-int csem_get(key_t key)
-{
- int sem_id;
- int i;
-
- /* CSEM_PRIVATE needs to go through csem_create() to get an
- * initial value */
- if (key == CSEM_PRIVATE) {
- errno = EINVAL;
- return -1;
- }
-
- /* get the (assumed existing) semaphore */
- sem_id = semget(key, 1, S_IRUSR|S_IWUSR);
- if (sem_id < 0)
- return -1;
-
- /* loop until sem_otime != 0, which means it has been initialized */
- for (i = 0; i < MAX_OTIME_LOOPS; i++) {
- time_t otime = csem_get_otime(sem_id);
- if (otime < 0) {
- /* error */
- return -1;
- }
- if (otime > 0) {
- /* success */
- return sem_id;
- }
- /* retry */
- sched_yield();
- }
-
- /* fell through - error */
- return -1;
-}
-
-int csem_get_or_create(key_t key, unsigned val)
-{
- int sem_id;
-
- /* try to create the semaphore */
- sem_id = csem_create(key, val);
- if (sem_id >= 0 || errno != EEXIST) {
- /* it either succeeded or got an error */
- return sem_id;
- }
-
- /* it must exist already - get it */
- sem_id = csem_get(key);
- if (sem_id < 0)
- return -1;
-
- return sem_id;
-}
-
-int csem_destroy(int sem_id)
-{
- return semctl(sem_id, 0, IPC_RMID);
-}
-
-int csem_getval(int sem_id)
-{
- return semctl(sem_id, 0, GETVAL);
-}
-
-int csem_setval(int sem_id, unsigned val)
-{
- union semun arg;
- arg.val = val;
- if (semctl(sem_id, 0, SETVAL, arg) < 0)
- return -1;
-
- return 0;
-}
-
-static int csem_up_undoflag(int sem_id, int undoflag)
-{
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = 1;
- sops.sem_flg = undoflag;
- return semop(sem_id, &sops, 1);
-}
-
-int csem_up(int sem_id)
-{
- return csem_up_undoflag(sem_id, 0);
-}
-
-int csem_up_undo(int sem_id)
-{
- return csem_up_undoflag(sem_id, SEM_UNDO);
-}
-
-static int csem_down_undoflag(int sem_id, int undoflag)
-{
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = undoflag;
- return semop(sem_id, &sops, 1);
-}
-
-int csem_down(int sem_id)
-{
- return csem_down_undoflag(sem_id, 0);
-}
-
-int csem_down_undo(int sem_id)
-{
- return csem_down_undoflag(sem_id, SEM_UNDO);
-}
-
-static int csem_down_timeout_undoflag(int sem_id,
- struct timespec *timeout,
- int undoflag)
-{
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = undoflag;
- return semtimedop(sem_id, &sops, 1, timeout);
-}
-
-int csem_down_timeout(int sem_id, struct timespec *timeout)
-{
- return csem_down_timeout_undoflag(sem_id, timeout, 0);
-}
-
-int csem_down_timeout_undo(int sem_id, struct timespec *timeout)
-{
- return csem_down_timeout_undoflag(sem_id, timeout, SEM_UNDO);
-}
-
-time_t csem_get_otime(int sem_id)
-{
- union semun arg;
- struct semid_ds ds;
- arg.buf = &ds;
- if (semctl(sem_id, 0, IPC_STAT, arg) < 0)
- return -1;
-
- return ds.sem_otime;
-}
diff --git a/util/lock/csem.h b/util/lock/csem.h
deleted file mode 100644
index 469a824259..0000000000
--- a/util/lock/csem.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2003 Sun Microsystems, Inc.
- * Copyright 2010 Google, Inc.
- *
- * 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.
- *
- * Developer's note: This was open sourced by Sun Microsystems, which got it
- * via Cobalt Networks. It has been fairly extensively modified since then.
- */
-
-#ifndef __UTIL_CSEM_H
-#define __UTIL_CSEM_H
-
-#include <sys/ipc.h>
-#include <time.h>
-
-/* create a private key */
-#define CSEM_PRIVATE IPC_PRIVATE
-
-/*
- * Create a new semaphore with the specified key, initialized to the
- * specified value. If the key is CSEM_PRIVATE, a new private semaphore
- * is allocated.
- *
- * Returns the sempahore ID (>= 0) on success.
- * Returns < 0 on error, or if the key already exists.
- */
-extern int csem_create(key_t key, unsigned val);
-
-/*
- * Fetch an existing semaphore with the specified key.
- *
- * Returns the sempahore ID (>= 0) on success.
- * Returns < 0 on error, or if the key does not exist.
- */
-extern int csem_get(key_t key);
-
-/*
- * Fetch or create a semaphore with the specified key. If the semaphore
- * did not exist, it will be created with the specified value.
- *
- * Returns the sempahore ID (>= 0) on success.
- * Returns < 0 on error.
- */
-extern int csem_get_or_create(key_t key, unsigned val);
-
-/*
- * Destroy the semaphore.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_destroy(int sem_id);
-
-/*
- * Get the value of the semaphore.
- *
- * Returns the value (>= 0) on success.
- * Returns < 0 on error.
- */
-extern int csem_getval(int sem_id);
-
-/*
- * Set the value of the semaphore.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_setval(int sem_id, unsigned val);
-
-/*
- * Increment the semaphore.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_up(int sem_id);
-
-/*
- * Increment the semaphore. This operation will be undone when the
- * process terminates.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_up_undo(int sem_id);
-
-/*
- * Decrement the semaphore, or block if sem == 0.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_down(int sem_id);
-
-/*
- * Decrement the semaphore, or block if sem == 0. This operation will be
- * undone when the process terminates.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_down_undo(int sem_id);
-
-/*
- * Decrement the semaphore, or block with a timeout if sem == 0.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_down_timeout(int sem_id, struct timespec *timeout);
-
-/*
- * Decrement the semaphore, or block with a timeout if sem == 0. This
- * operation will be undone when the process terminates.
- *
- * Returns 0 on success.
- * Returns < 0 on error.
- */
-extern int csem_down_timeout_undo(int sem_id, struct timespec *timeout);
-
-/*
- * Get the timestamp of the last csem_up()/csem_down() call.
- *
- * Returns sem_otime on success.
- * Returns < 0 on error
- */
-extern time_t csem_get_otime(int sem_id);
-
-#endif /* __UTIL_CSEM_H */
diff --git a/util/lock/file_lock.c b/util/lock/file_lock.c
new file mode 100644
index 0000000000..94f5991172
--- /dev/null
+++ b/util/lock/file_lock.c
@@ -0,0 +1,251 @@
+/* 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 "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 file_lock_open_or_create(struct ipc_lock *lock)
+{
+ struct stat s;
+ 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 {
+ if (snprintf(path, sizeof(path), "%s", SYSTEM_LOCKFILE_DIR) < 0)
+ return -1;
+
+ if (lstat(path, &s) < 0) {
+ fprintf(stderr, "Cannot stat %s", path);
+ return -1;
+ }
+
+ if (!S_ISDIR(s.st_mode)) {
+ fprintf(stderr, "%s is not a directory.\n", path);
+ return -1;
+ }
+
+ if (strlen(path) + strlen(lock->filename) + 2 > PATH_MAX) {
+ fprintf(stderr, "Lockfile path too long.\n");
+ return -1;
+ }
+ strcat(path, "/");
+ strcat(path, lock->filename);
+ }
+
+ lock->fd = open(path, O_RDWR | O_CREAT, 0600);
+ if (lock->fd < 0) {
+ fprintf(stderr, "Cannot open lockfile %s", path);
+ return -1;
+ }
+
+ 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) {
+ fprintf(stderr, "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 {
+ fprintf(stderr, "nanosleep() failed");
+ return ret;
+ }
+ }
+
+ if (timeout_msecs < 0)
+ continue;
+
+ msecs_remaining -= SLEEP_INTERVAL_MS;
+ if (msecs_remaining < 0)
+ break;
+ }
+
+ if (ret != 0) {
+ fprintf(stderr, "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) {
+ fprintf(stderr, "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) {
+ fprintf(stderr, "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)
+ fprintf(stderr, "Cannot release lock");
+
+ if (close(lock->fd) < 0)
+ fprintf(stderr, "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;
+ }
+
+ return -1;
+}
diff --git a/util/lock/gec_lock.c b/util/lock/gec_lock.c
index 4df231af3e..d354ea08f3 100644
--- a/util/lock/gec_lock.c
+++ b/util/lock/gec_lock.c
@@ -32,7 +32,7 @@
#include "ipc_lock.h"
#include "locks.h"
-static struct ipc_lock gec_lock = IPC_LOCK_INIT(GECLOCK);
+static struct ipc_lock gec_lock = LOCKFILE_INIT(CROS_EC_LOCKFILE_NAME);
int acquire_gec_lock(int timeout_secs)
{
diff --git a/util/lock/ipc_lock.c b/util/lock/ipc_lock.c
deleted file mode 100644
index 790014e67b..0000000000
--- a/util/lock/ipc_lock.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright 2012, 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.
- */
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "csem.h"
-#include "ipc_lock.h"
-
-static int lock_init(struct ipc_lock *lock)
-{
- if (lock->sem < 0) {
- /* get or create the semaphore, init to 1 if needed */
- int sem = csem_get_or_create(lock->key, 1);
- if (sem < 0)
- return -1;
-
- lock->sem = sem;
- }
- return 0;
-}
-
-static void msecs_to_timespec(int msecs, struct timespec *tmspec)
-{
- tmspec->tv_sec = msecs / 1000;
- tmspec->tv_nsec = (msecs % 1000) * 1000 * 1000;
-}
-
-int acquire_lock(struct ipc_lock *lock, int timeout_msecs)
-{
- int ret;
- struct timespec timeout;
- struct timespec *timeout_ptr;
-
- /* initialize the lock */
- if (lock_init(lock) < 0) {
- fprintf(stderr, "%s(): failed to init lock 0x%08x\n",
- __func__, (uint32_t)lock->key);
- return -1;
- }
-
- /* check if it is already held */
- if (lock->is_held)
- return 1;
-
- /* calculate the timeout */
- if (timeout_msecs >= 0) {
- timeout_ptr = &timeout;
- msecs_to_timespec(timeout_msecs, timeout_ptr);
- } else {
- timeout_ptr = NULL;
- }
-
- /* try to get the lock */
- ret = csem_down_timeout_undo(lock->sem, timeout_ptr);
- if (ret < 0) {
- fprintf(stderr, "%s(): failed to acquire lock 0x%08x\n",
- __func__, (uint32_t)lock->key);
- return -1;
- }
-
- /* success */
- lock->is_held = 1;
- return 0;
-}
-
-int release_lock(struct ipc_lock *lock)
-{
- if (lock->is_held) {
- lock->is_held = 0;
- csem_up_undo(lock->sem);
- /* NOTE: do not destroy the semaphore, we want it to persist */
- return 0;
- }
- /* did not hold the lock */
- return -1;
-}
diff --git a/util/lock/ipc_lock.h b/util/lock/ipc_lock.h
index 39ae277a7e..ca739ac04e 100644
--- a/util/lock/ipc_lock.h
+++ b/util/lock/ipc_lock.h
@@ -31,20 +31,18 @@
#ifndef __UTIL_IPC_LOCK_H
#define __UTIL_IPC_LOCK_H
-#include <sys/ipc.h>
-
struct ipc_lock {
- key_t key; /* provided by the developer */
- int sem; /* internal */
- int is_held; /* internal */
+ int is_held; /* internal */
+ char *filename; /* provided by the developer */
+ int fd; /* internal */
};
/* don't use C99 initializers here, so this can be used in C++ code */
-#define IPC_LOCK_INIT(key) \
+#define LOCKFILE_INIT(lockfile) \
{ \
- key, /* name */ \
- -1, /* sem */ \
- 0, /* is_held */ \
+ 0, /* is_held */ \
+ lockfile, /* filename */ \
+ -1, /* fd */ \
}
/*
diff --git a/util/lock/locks.h b/util/lock/locks.h
index 74360883fd..e87c36d73b 100644
--- a/util/lock/locks.h
+++ b/util/lock/locks.h
@@ -31,17 +31,8 @@
#ifndef __UTIL_LOCKS_H
#define __UTIL_LOCKS_H
-/* this is the base key, since we have to pick something global */
-#define IPC_LOCK_KEY (0x67736c00 & 0xfffffc00) /* 22 bits "gsl" */
-
-/* The ordering of the following keys matters a lot. We don't want to reorder
- * keys and have a new binary dependent on deployed/used because it will break
- * atomicity of existing users and binaries. In other words, DO NOT REORDER. */
-
-/* this is the "big lock". */
-#define BIGLOCK (IPC_LOCK_KEY + 0)
-
-/* for Google EC */
-#define GECLOCK (IPC_LOCK_KEY + 1)
+#define SYSTEM_LOCKFILE_DIR "/var/run/lock"
+#define LOCKFILE_NAME "firmware_utility_lock"
+#define CROS_EC_LOCKFILE_NAME "cros_ec_lock"
#endif /* __UTIL_LOCKS_H */