[hackers] [skvm] No two instances of skvm can be executed simultaneously. Explicit locking || Dimitrios Papastamos

From: <hg_AT_suckless.org>
Date: Tue, 28 Apr 2009 19:49:36 +0000 (UTC)

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