diff options
author | Sangho Park <sangho.p@samsung.com> | 2016-01-27 18:09:37 +0900 |
---|---|---|
committer | Sangho Park <sangho.p@samsung.com> | 2016-01-28 11:23:49 +0900 |
commit | 727988de8499458c0fb1a18231e1dcfbc5cb7c75 (patch) | |
tree | 4c7755419a16e99cd9d025d79004e70e31aa2d75 | |
parent | 51d56721e5de6c0f22533348ab27b92c3313c14d (diff) | |
download | qemu-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.c | 103 |
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); |