summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSangho Park <sangho.p@samsung.com>2016-01-27 18:09:37 +0900
committerSangho Park <sangho.p@samsung.com>2016-01-28 11:23:49 +0900
commit727988de8499458c0fb1a18231e1dcfbc5cb7c75 (patch)
tree4c7755419a16e99cd9d025d79004e70e31aa2d75
parent51d56721e5de6c0f22533348ab27b92c3313c14d (diff)
downloadqemu-727988de8499458c0fb1a18231e1dcfbc5cb7c75.tar.gz
qemu-727988de8499458c0fb1a18231e1dcfbc5cb7c75.tar.bz2
qemu-727988de8499458c0fb1a18231e1dcfbc5cb7c75.zip
osutil: modified posix lock mechanism
After failing to lock file, check the lock whether other emulator locks the file or not. If other emulator does not lock the file, try again to lock file after sleep. Change-Id: I9cfc3c4af395eb0d9e113eefb83d3953b431a19c Signed-off-by: Sangho Park <sangho.p@samsung.com>
-rw-r--r--tizen/src/util/osutil.c103
1 files changed, 63 insertions, 40 deletions
diff --git a/tizen/src/util/osutil.c b/tizen/src/util/osutil.c
index 2c13652940..442d123a3a 100644
--- a/tizen/src/util/osutil.c
+++ b/tizen/src/util/osutil.c
@@ -46,35 +46,56 @@ DECLARE_DEBUG_CHANNEL(osutil)
static int lock_file = -1;
+static struct flock _lock = {
+ .l_type = F_WRLCK,
+ .l_start = 0,
+ .l_whence = SEEK_SET,
+ .l_len = 0,
+};
static sdcard_info info;
static int fd_lock(int fd)
{
- struct flock lock;
-
- lock.l_type = F_WRLCK;
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
- lock.l_pid = getpid();
-
- return fcntl(fd, F_SETLK, &lock);
+ return fcntl(fd, F_SETLK, &_lock);
}
static int fd_unlock(int fd)
{
- struct flock lock;
-
- lock.l_type = F_UNLCK;
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
- lock.l_pid = getpid();
-
+ struct flock lock = {
+ .l_type = F_UNLCK,
+ .l_start = _lock.l_start,
+ .l_whence = _lock.l_whence,
+ .l_len = _lock.l_len,
+ };
return fcntl(fd, F_SETLK, &lock);
}
+/*
+ * Check the file lock.
+ * Emulator locks the whole file exclusively. If one of the current lock's
+ * l_type, l_start, l_whence, and l_len is different from my own, other
+ * but emulator locks the file and then we will try to lock the file.
+ */
+static bool fd_checklock(int fd)
+{
+ struct flock lock = _lock;
+
+ if (fcntl(fd, F_GETLK, &lock) < 0) {
+ LOG_INFO("Failed to get lock information: %s\n", strerror(errno));
+ } else if (lock.l_type == _lock.l_type &&
+ lock.l_start == _lock.l_start &&
+ lock.l_whence == _lock.l_whence &&
+ lock.l_len == _lock.l_len) {
+ return true;
+ } else {
+ LOG_INFO("Lock: type=%d(%d), start=%d, whence=%d, len=%d, pid=%d\n",
+ lock.l_type, _lock.l_type, (int)lock.l_start, lock.l_whence,
+ (int)lock.l_len, lock.l_pid);
+ }
+ return false;
+}
+
static void remove_vm_lock_posix(void)
{
g_assert(lock_file != -1);
@@ -94,40 +115,42 @@ static void notify_remove_lock(Notifier *notifier, void *data)
static Notifier remove_lock = { .notify = notify_remove_lock };
-#define RETRY_COUNT 10
void make_vm_lock_posix(void)
{
const char *image_file = get_drive_image_file();
- int error = 0, i;
+ int error = 0;
g_assert(lock_file == -1);
g_assert(image_file != NULL);
- for (i = 0; i < RETRY_COUNT; ++i) {
- lock_file = open(image_file, O_RDWR);
- if (lock_file == -1) {
- error = errno;
- LOG_WARNING("Failed to open image file for lock: %s\n",
+retry:
+ lock_file = open(image_file, O_RDWR);
+ if (lock_file == -1) {
+ error = errno;
+ LOG_WARNING("Failed to open image file for lock: %s\n",
strerror(error));
- return;
- }
+ return;
+ }
- if (fd_lock(lock_file) == -1) {
- error = errno;
- if (error == EAGAIN || error == EACCES) {
- if (i == RETRY_COUNT - 1) {
- error_report("Can not execute this VM. "
- "The same VM may be running now.");
- exit(1);
- }
- g_usleep(10000); /* 10 msec */
+ if (fd_lock(lock_file) == -1) {
+ error = errno;
+ if (error == EAGAIN || error == EACCES) {
+ /* Check whether other except emulator locks the file */
+ if (fd_checklock(lock_file) == false) {
+ close(lock_file);
+ LOG_INFO("Try to lock again after sleep\n");
+ g_usleep(10000); /* 10 msec */
+ goto retry;
}
-
- LOG_WARNING("Failed to lock image file: %s\n", strerror(error));
- close(lock_file);
- lock_file = -1;
- return;
+ error_report("Can not execute this VM. "
+ "The same VM may be running now.");
+ exit(1);
}
+
+ LOG_WARNING("Failed to lock image file: %s\n", strerror(error));
+ close(lock_file);
+ lock_file = -1;
+ return;
}
emulator_add_exit_notifier(&remove_lock);