changeset: 1:22990e73c952
tag: tip
user: Dimitrios Papastamos <stateless [at] archlinux.us>
date: Tue Apr 28 20:49:09 2009 -0700
files: init/skvm skvm.c
description:
No two instances of skvm can be executed simultaneously. Explicit locking
using flock on a pid file (/var/run/skvm.pid) has been implemented.
diff -r cd5dd6134ab9 -r 22990e73c952 init/skvm
--- a/init/skvm Tue Apr 28 12:58:45 2009 -0700
+++ b/init/skvm Tue Apr 28 20:49:09 2009 -0700
@@ -21,6 +21,7 @@
if [ $? -gt 0 ]; then
stat_fail
else
+ rm -f /var/run/skvm.pid
rm_daemon skvm
stat_done
fi
diff -r cd5dd6134ab9 -r 22990e73c952 skvm.c
--- a/skvm.c Tue Apr 28 12:58:45 2009 -0700
+++ b/skvm.c Tue Apr 28 20:49:09 2009 -0700
@@ -5,6 +5,7 @@
#include <string.h>
#include <errno.h>
#include <signal.h>
+#include <stdint.h>
#include <mntent.h>
#include <getopt.h>
@@ -12,8 +13,10 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <dirent.h>
#include <syslog.h>
+#include <fcntl.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
@@ -32,6 +35,9 @@
#define DEFAULT_MNT_OPTIONS "noexec,nosuid"
#define BASE_MNT_DIR "/media/"
+/* not user controlled */
+#define LOCKFILE "/var/run/skvm.pid"
+#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
#define FREE_WRAP(ptr) do { free(ptr); ptr = NULL; } while (0)
#define INIT_NODE(p1, p2) \
do { \
@@ -77,6 +83,8 @@
static struct device_t *tail = NULL;
/* the main loop handler */
static GMainLoop *loop = NULL;
+/* file descriptor for LOCKFILE */
+static int pid_fd = -1;
/* flag used for debugging */
static int debug_mode_flag = 0;
@@ -111,11 +119,12 @@
static int do_mount(struct device_t *device);
static int file_exists(const char *path);
static void cleanup(int sig);
+static int is_running(void);
+static void deinit(void);
static void debug_dump_device(const struct device_t *device);
int
main(int argc, char *argv[]) {
- struct device_t *iter, *tmp;
int c;
static struct option long_options[] = {
@@ -143,6 +152,10 @@
if (!debug_mode_flag) {
if (daemon(0, 0) < 0)
return EXIT_FAILURE;
+ if (is_running()) {
+ deinit();
+ return EXIT_FAILURE;
+ }
}
if (debug_mode_flag) {
@@ -153,19 +166,7 @@
loop = g_main_loop_new((GMainContext *)NULL, FALSE);
g_main_run(loop);
- closelog();
- libhal_ctx_shutdown(hal_ctx, (DBusError *)NULL);
- libhal_ctx_free(hal_ctx);
- dbus_connection_unref(dbus_conn);
-
- iter = head;
-
- while (iter) {
- tmp = iter;
- iter = iter->next;
- free_device(tmp);
- }
-
+ deinit();
return EXIT_SUCCESS;
}
@@ -580,6 +581,56 @@
g_main_loop_quit(loop);
}
+/*
+ * Check if skvm is already running, make sure the log
+ * file has been opened and the new instance has been daemonized.
+ */
+static int
+is_running(void) {
+ char buf[16];
+
+ pid_fd = open(LOCKFILE, O_RDWR | O_CREAT, LOCKMODE);
+ if (pid_fd < 0) {
+ syslog(LOG_ERR, "%s:%d %s", __FILE__, __LINE__,
+ strerror(errno));
+ return 1;
+ }
+
+ if (flock(pid_fd, LOCK_EX | LOCK_NB) < 0) {
+ close(pid_fd);
+ pid_fd = -1;
+ syslog(LOG_ERR, "%s:%d can't lock %s: %s", __FILE__, __LINE__,
+ LOCKFILE, strerror(errno));
+ return 1;
+ }
+
+ ftruncate(pid_fd, 0);
+ snprintf(buf, sizeof(buf), "%jd\n", (intmax_t)getpid());
+ write(pid_fd, buf, strlen(buf));
+ return 0;
+}
+
+static void
+deinit(void) {
+ struct device_t *iter, *tmp;
+
+ closelog();
+ libhal_ctx_shutdown(hal_ctx, (DBusError *)NULL);
+ libhal_ctx_free(hal_ctx);
+ dbus_connection_unref(dbus_conn);
+
+ iter = head;
+
+ while (iter) {
+ tmp = iter;
+ iter = iter->next;
+ free_device(tmp);
+ }
+
+ if (pid_fd != -1)
+ close(pid_fd); /* releases lock */
+}
+
static void
debug_dump_device(const struct device_t *device) {
printf("~~~ Device dump ~~~\n");
Received on Tue Apr 28 2009 - 19:49:36 UTC
This archive was generated by hypermail 2.2.0 : Tue Apr 28 2009 - 20:00:08 UTC