set_bin_path_os(exec_argv);
}
-static void check_vm_lock(void)
-{
- check_vm_lock_os();
-}
-
-static void make_vm_lock(void)
-{
- make_vm_lock_os();
-}
-
-static void remove_vm_lock(void)
-{
- remove_vm_lock_os();
-}
-
static void emulator_notify_exit(Notifier *notifier, void *data)
{
- remove_vm_lock();
-
int i;
for (i = 0; i < _qemu_argc; ++i) {
g_free(_qemu_argv[i]);
void prepare_maru_after_device_init(void)
{
- check_vm_lock();
- make_vm_lock();
+ make_vm_lock_os();
maru_device_hotplug_init();
qemu_add_opts(&qemu_ecs_opts);
start_ecs();
strcat(log_path, LOGFILE);
}
-static void remove_vm_lock(void)
-{
- remove_vm_lock_os();
-}
-
-static void emulator_notify_exit(Notifier *notifier, void *data)
-{
- remove_vm_lock();
-
- INFO("Exit emulator...\n");
-}
-
-static Notifier emulator_exit = { .notify = emulator_notify_exit };
-
static void redir_output(void)
{
FILE *fp;
INFO("Emulator start !!!\n");
atexit(maru_atexit);
- emulator_add_exit_notifier(&emulator_exit);
extract_skin_info(_skin_argc, _skin_argv);
/*
- * Emulator
+ * ostuil
*
- * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2012 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* SeokYeon Hwang <syeon.hwang@samsung.com>
* MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@brief Collection of utilities for darwin
*/
-#include "emulator_common.h"
#include "osutil.h"
-#include "emulator.h"
#include "emul_state.h"
#include "debug_ch.h"
#include "maru_err_table.h"
#error
#endif
-#include <string.h>
-#include <unistd.h>
-#include <sys/shm.h>
#include <sys/sysctl.h>
#include <SystemConfiguration/SystemConfiguration.h>
MULTI_DEBUG_CHANNEL(qemu, osutil);
-static int g_shmid;
+void make_vm_lock_os(void) {
+ make_vm_lock_posix();
+}
+
static CFDictionaryRef proxySettings;
static char *cfstring_to_cstring(CFStringRef str) {
return value;
}
-void check_vm_lock_os(void)
-{
- /* TODO: */
-}
-
-void make_vm_lock_os(void)
-{
- char *shared_memory;
- int base_port;
- base_port = get_emul_vm_base_port();
- g_shmid = shmget((key_t)base_port, getpagesize(), 0666|IPC_CREAT);
- if (g_shmid == -1) {
- ERR("shmget failed\n");
- perror("osutil-darwin: ");
- return;
- }
-
- shared_memory = shmat(g_shmid, (char *)0x00, 0);
- if (shared_memory == (void *)-1) {
- ERR("shmat failed\n");
- perror("osutil-darwin: ");
- return;
- }
- g_sprintf(shared_memory, "%s", get_drive_image_file());
- INFO("shared memory key: %d, value: %s\n", base_port, (char *)shared_memory);
-
- if (shmdt(shared_memory) == -1) {
- ERR("shmdt failed\n");
- perror("osutil-darwin: ");
- }
-
-}
-
-void remove_vm_lock_os(void)
-{
- if (shmctl(g_shmid, IPC_RMID, 0) == -1) {
- ERR("shmctl failed\n");
- perror("osutil-linux: ");
- }
-}
-
void set_bin_path_os(char const *const exec_argv)
{
gchar *file_name = NULL;
/*
- * Emulator
+ * osutil
*
- * Copyright (C) 2012 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2012 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* SeokYeon Hwang <syeon.hwang@samsung.com>
* MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@brief Collection of utilities for linux
*/
-#include <png.h>
+#include "png.h"
#include "osutil.h"
-#include "emulator.h"
#include "emul_state.h"
#include "debug_ch.h"
-#include "maru_err_table.h"
#include "sdb.h"
#ifndef CONFIG_LINUX
#error
#endif
-#include <string.h>
-#include <unistd.h>
-#include <sys/shm.h>
-#include <sys/ipc.h>
#include <linux/version.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
MULTI_DEBUG_CHANNEL(emulator, osutil);
-static int g_shmid;
-static char *g_shared_memory;
static int gproxytool = GSETTINGS;
/* Getting proxy commands */
{ "gconftool-2 -g /system/proxy/socks_port", "gsettings get org.gnome.system.proxy.socks port" },
};
-void check_vm_lock_os(void)
-{
- int shm_id;
- void *shm_addr;
- uint32_t port;
- int val;
- struct shmid_ds shm_info;
-
- for (port = 26100; port < 26200; port += 10) {
- shm_id = shmget((key_t)port, 0, 0);
- if (shm_id != -1) {
- shm_addr = shmat(shm_id, (void *)0, 0);
- if ((void *)-1 == shm_addr) {
- ERR("error occured at shmat()\n");
- break;
- }
-
- val = shmctl(shm_id, IPC_STAT, &shm_info);
- if (val != -1) {
- INFO("count of process that use shared memory : %d\n",
- shm_info.shm_nattch);
- if ((shm_info.shm_nattch > 0) &&
- g_strcmp0(get_drive_image_file(), (char *)shm_addr) == 0) {
- if (check_port_bind_listen(port + 1) > 0) {
- shmdt(shm_addr);
- continue;
- }
- shmdt(shm_addr);
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "Can not execute this VM.\n"
- "The same name is running now.");
- exit(0);
- } else {
- shmdt(shm_addr);
- }
- }
- }
- }
-}
-
void make_vm_lock_os(void)
{
- int base_port;
-
- base_port = get_emul_vm_base_port();
-
- g_shmid = shmget((key_t)base_port, getpagesize(), 0666|IPC_CREAT);
- if (g_shmid == -1) {
- ERR("shmget failed\n");
- perror("osutil-linux: ");
- return;
- }
-
- g_shared_memory = shmat(g_shmid, (char *)0x00, 0);
- if (g_shared_memory == (void *)-1) {
- ERR("shmat failed\n");
- perror("osutil-linux: ");
- return;
- }
-
- g_sprintf(g_shared_memory, "%s", get_drive_image_file());
- INFO("shared memory key: %d value: %s\n",
- base_port, (char *)g_shared_memory);
-
- if (shmdt(g_shared_memory) == -1) {
- ERR("shmdt failed\n");
- perror("osutil-linux: ");
- }
-}
-
-void remove_vm_lock_os(void)
-{
- if (shmctl(g_shmid, IPC_RMID, 0) == -1) {
- ERR("shmctl failed\n");
- perror("osutil-linux: ");
- }
+ make_vm_lock_posix();
}
void set_bin_path_os(char const *const exec_argv)
/*
- * Emulator
+ * osutil
*
- * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2012 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* SeokYeon Hwang <syeon.hwang@samsung.com>
* MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@brief Collection of utilities for win32
*/
-#include <png.h>
+#include "png.h"
#include "emulator_common.h"
#include "osutil.h"
#include "emulator.h"
MULTI_DEBUG_CHANNEL (emulator, osutil);
-static HANDLE g_hMapFile;
-static char *g_pBuf;
+static HANDLE lock_file = INVALID_HANDLE_VALUE;
+static char *lock_filename = NULL;
static char g_sdcard[256] = {0,};
static sdcard_info info;
static const char *pactempfile = ".autoproxy";
-void check_vm_lock_os(void)
+static void remove_vm_lock_os(void)
{
- uint32_t port;
- char *base_port = NULL;
- char *pBuf;
- HANDLE hMapFile;
-
- for (port = 26100; port < 26200; port += 10) {
- base_port = g_strdup_printf("%d", port);
- hMapFile = OpenFileMapping(FILE_MAP_READ, TRUE, base_port);
- if (hMapFile == NULL) {
- INFO("port %s is not used.\n", base_port);
- continue;
- } else {
- pBuf = (char *)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 50);
- if (pBuf == NULL) {
- ERR("Could not map view of file (%d).\n", GetLastError());
- CloseHandle(hMapFile);
- }
+ g_free(lock_filename);
+ lock_filename = NULL;
- if (strcmp(pBuf, get_drive_image_file()) == 0) {
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "Can not execute this VM.\n"
- "The same name is running now.");
- UnmapViewOfFile(pBuf);
- CloseHandle(hMapFile);
- free(base_port);
- exit(0);
- } else {
- UnmapViewOfFile(pBuf);
- }
- }
-
- CloseHandle(hMapFile);
- free(base_port);
- }
-}
-
-void make_vm_lock_os(void)
-{
- char *port_in_use;
- char *shared_memory;
- int base_port;
-
- base_port = get_emul_vm_base_port();
- shared_memory = g_strdup_printf("%s", get_drive_image_file());
- port_in_use = g_strdup_printf("%d", base_port);
- g_hMapFile = CreateFileMapping(
- INVALID_HANDLE_VALUE, /* use paging file */
- NULL, /* default security */
- PAGE_READWRITE, /* read/write access */
- 0, /* maximum object size (high-order DWORD) */
- 50, /* maximum object size (low-order DWORD) */
- port_in_use); /* name of mapping object */
- if (g_hMapFile == NULL) {
- ERR("Could not create file mapping object (%d).\n", GetLastError());
+ if (lock_file == INVALID_HANDLE_VALUE) {
return;
}
- g_pBuf = MapViewOfFile(g_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 50);
- if (g_pBuf == NULL) {
- ERR("Could not map view of file (%d).\n", GetLastError());
- CloseHandle(g_hMapFile);
- return;
- }
+ CloseHandle(lock_file);
+ lock_file = INVALID_HANDLE_VALUE;
+}
- CopyMemory((PVOID)g_pBuf, shared_memory, strlen(shared_memory));
- free(port_in_use);
- free(shared_memory);
+static void notify_remove_lock(Notifier *notifier, void *data)
+{
+ remove_vm_lock_os();
}
-void remove_vm_lock_os(void)
+static Notifier remove_lock = { .notify = notify_remove_lock };
+
+/*
+On Windows, emulator will stop before checking lock because platform
+image file and kernel log file are aleady opened with exclusive write
+lock by pre-executed emulator. But it is still useful for
+emulator-manager.
+*/
+void make_vm_lock_os(void)
{
- if (g_pBuf != NULL) {
- UnmapViewOfFile(g_pBuf);
+ g_assert(lock_file == INVALID_HANDLE_VALUE);
+ g_assert(lock_filename == NULL);
+
+ lock_filename = g_strdup_printf("%s.lock", get_drive_image_file());
+
+ if (g_mkdir_with_parents(g_path_get_dirname(lock_filename), 0777)) {
+ ERR("Can not create directory for lock file: %ld\n",
+ GetLastError());
}
- if (g_hMapFile != NULL) {
- CloseHandle(g_hMapFile);
+ lock_file = CreateFile(lock_filename,
+ GENERIC_READ | GENERIC_WRITE,
+ 0, // No share
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
+ if (lock_file == INVALID_HANDLE_VALUE) {
+ DWORD error = GetLastError();
+ // On Windows, the file opened by CreateFile has exclusive lock
+ // naturally unless FILE_SHARE_* attribute is set.
+ if (error == ERROR_SHARING_VIOLATION) {
+ maru_register_exit_msg(MARU_EXIT_UNKNOWN,
+ "Can not execute this VM.\n"
+ "The same VM may be running now.");
+ exit(1);
+ }
+
+ ERR("Failed to create lock file: %0xlx\n", error);
}
-}
+ emulator_add_exit_notifier(&remove_lock);
+}
void set_bin_path_os(char const *const exec_argv)
{
/*
- * Emulator
+ * osutil
*
- * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2012-2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* SeokYeon Hwang <syeon.hwang@samsung.com>
* MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
MULTI_DEBUG_CHANNEL(emulator, osutil);
#ifndef CONFIG_WIN32
+
+#include "emulator.h"
+#include "emul_state.h"
+#include "maru_err_table.h"
+
+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;
#endif
const char *pac_tempfile = ".autoproxy";
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) {
+ 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 {
+ 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)
+{
+ if (lock_file == -1) {
+ return;
+ }
+
+ if (fd_unlock(lock_file)) {
+ INFO("Failed to remove lock from lock file");
+ }
+ close(lock_file);
+
+ lock_file = -1;
+}
+
+static void notify_remove_lock(Notifier *notifier, void *data)
+{
+ remove_vm_lock_posix();
+}
+
+static Notifier remove_lock = { .notify = notify_remove_lock };
+
+void make_vm_lock_posix(void)
+{
+ const char *image_file = get_drive_image_file();
+ int error = 0;
+
+ g_assert(lock_file == -1);
+ g_assert(image_file != NULL);
+
+retry:
+ lock_file = open(image_file, O_RDWR);
+ if (lock_file == -1) {
+ error = errno;
+ ERR("Failed to open image file for lock: %s\n",
+ strerror(error));
+ return;
+ }
+
+ 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);
+ INFO("Try to lock again after sleep\n");
+ g_usleep(10000); /* 10 msec */
+ goto retry;
+ }
+ maru_register_exit_msg(MARU_EXIT_UNKNOWN,
+ "Can not execute this VM.\n"
+ "The same name is running now.");
+ exit(1);
+ }
+
+ ERR("Failed to lock image file: %s\n", strerror(error));
+ close(lock_file);
+ lock_file = -1;
+ return;
+ }
+
+ emulator_add_exit_notifier(&remove_lock);
+}
+
inline bool make_sdcard_lock_posix(char *sdcard)
{
char *lock_file = g_strdup_printf("%s.lck", sdcard);
/*
- * Emulator
+ * osutil
*
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2012-2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* SeokYeon Hwang <syeon.hwang@samsung.com>
* MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#include "qemu-common.h"
+#ifdef CONFIG_WIN32
+#include "sysemu/os-win32.h"
+#else
+#include "sysemu/os-posix.h"
+#endif
+
#define HTTP_PROTOCOL "http="
#define HTTP_PREFIX "http://"
#define HTTPS_PROTOCOL "https="
extern const char *pac_tempfile;
-void check_vm_lock_os(void);
void make_vm_lock_os(void);
-void remove_vm_lock_os(void);
bool make_sdcard_lock_os(char *sdcard);
int remove_sdcard_lock_os(char *sdcard);
#ifndef CONFIG_WIN32
+void make_vm_lock_posix(void);
+
bool make_sdcard_lock_posix(char *sdcard);
int remove_sdcard_lock_posix(char *sdcard);
#endif