- add command line option to override is running check. - don't use proc fs for is running check. - fix fail on included browse map not found. - fix incorrect multi source messages. - clear stale flag on map read. - fix proximity other rpc ping timeout. - refactor mount request vars code. - make handle_mounts startup condition distinct. - fix submount shutdown handling. - try not to block on expire. - add configuration paramter UMOUNT_WAIT. - fix multi mount race. - fix nfs4 colon escape handling. - check replicated list after probe. - add replicated server selection debug logging. - update replicated server selection documentation. - use /dev/urandom instead of /dev/random. - check for mtab pointing to /proc/mounts. - fix interface config buffer size. - fix percent hack heap corruption.
620 lines
15 KiB
Diff
620 lines
15 KiB
Diff
autofs-5.0.3 - don't use proc for is running check
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Using /proc/<pid>/cmdline to check if the daemon is running allows
|
|
any user to create a trivial program called "automount" and prevent
|
|
the system automounter from running simply by executing it and
|
|
leaving it running. This patch makes autofs use a flag file for this
|
|
check instead.
|
|
---
|
|
|
|
CHANGELOG | 1
|
|
Makefile.conf.in | 3 +
|
|
aclocal.m4 | 16 ++++
|
|
configure | 35 +++++++++
|
|
configure.in | 17 +++++
|
|
daemon/Makefile | 5 +
|
|
daemon/automount.c | 95 ++++++++------------------
|
|
daemon/flag.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
8 files changed, 294 insertions(+), 70 deletions(-)
|
|
create mode 100644 daemon/flag.c
|
|
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index f40a941..3921552 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -24,6 +24,7 @@
|
|
- fix incorrect if check in get user info.
|
|
- fix couple of memory leaks.
|
|
- add command line option to override check for daemon already running.
|
|
+- don't use proc file system when checking if the daemon is running.
|
|
|
|
14/01/2008 autofs-5.0.3
|
|
-----------------------
|
|
diff --git a/Makefile.conf.in b/Makefile.conf.in
|
|
index 09c3129..d88f5ee 100644
|
|
--- a/Makefile.conf.in
|
|
+++ b/Makefile.conf.in
|
|
@@ -74,6 +74,9 @@ autofsmapdir = @mapdir@
|
|
# Location for autofs fifos
|
|
autofsfifodir = @fifodir@
|
|
|
|
+# Location for autofs flag file
|
|
+autofsflagdir = @flagdir@
|
|
+
|
|
# Where to install the automount program
|
|
sbindir = @sbindir@
|
|
|
|
diff --git a/aclocal.m4 b/aclocal.m4
|
|
index a1105ae..9ef4050 100644
|
|
--- a/aclocal.m4
|
|
+++ b/aclocal.m4
|
|
@@ -136,6 +136,22 @@ AC_DEFUN(AF_FIFO_D,
|
|
done
|
|
fi])
|
|
|
|
+dnl --------------------------------------------------------------------------
|
|
+dnl AF_FLAG_D
|
|
+dnl
|
|
+dnl Check the location of the autofs flag file directory
|
|
+dnl --------------------------------------------------------------------------
|
|
+AC_DEFUN(AF_FLAG_D,
|
|
+[if test -z "$flagdir"; then
|
|
+ for flag_d in /var/run /tmp; do
|
|
+ if test -z "$flagdir"; then
|
|
+ if test -d "$flag_d"; then
|
|
+ flagdir="$flag_d"
|
|
+ fi
|
|
+ fi
|
|
+ done
|
|
+fi])
|
|
+
|
|
dnl ----------------------------------- ## -*- Autoconf -*-
|
|
dnl Check if --with-dmalloc was given. ##
|
|
dnl From Franc,ois Pinard ##
|
|
diff --git a/configure b/configure
|
|
index 0d3268c..9278196 100755
|
|
--- a/configure
|
|
+++ b/configure
|
|
@@ -655,6 +655,7 @@ initdir
|
|
confdir
|
|
mapdir
|
|
fifodir
|
|
+flagdir
|
|
DMALLOCLIB
|
|
MOUNT
|
|
HAVE_MOUNT
|
|
@@ -1295,6 +1296,7 @@ Optional Packages:
|
|
--with-confdir=DIR use DIR for autofs configuration files
|
|
--with-mapdir=PATH look in PATH for mount maps used by the automounter
|
|
--with-fifodir=PATH use PATH as the directory for fifos used by the automounter
|
|
+ --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter
|
|
--with-dmalloc use dmalloc, as in
|
|
http://www.dmalloc.com/dmalloc.tar.gz
|
|
--with-hesiod=DIR enable Hesiod support (libs and includes in DIR)
|
|
@@ -1876,6 +1878,36 @@ echo "${ECHO_T}$fifodir" >&6; }
|
|
|
|
|
|
#
|
|
+# The user can specify --with-flagdir=PATH to specify where autofs flag file goes
|
|
+#
|
|
+if test -z "$flagdir"; then
|
|
+ for flag_d in /var/run /tmp; do
|
|
+ if test -z "$flagdir"; then
|
|
+ if test -d "$flag_d"; then
|
|
+ flagdir="$flag_d"
|
|
+ fi
|
|
+ fi
|
|
+ done
|
|
+fi
|
|
+
|
|
+# Check whether --with-flagdir was given.
|
|
+if test "${with_flagdir+set}" = set; then
|
|
+ withval=$with_flagdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no"
|
|
+ then
|
|
+ :
|
|
+ else
|
|
+ filagdir="${withval}"
|
|
+ fi
|
|
+
|
|
+fi
|
|
+
|
|
+{ echo "$as_me:$LINENO: checking for autofs flag file directory" >&5
|
|
+echo $ECHO_N "checking for autofs flag file directory... $ECHO_C" >&6; }
|
|
+{ echo "$as_me:$LINENO: result: $flagdir" >&5
|
|
+echo "${ECHO_T}$flagdir" >&6; }
|
|
+
|
|
+
|
|
+#
|
|
# Optional include dmalloc
|
|
#
|
|
{ echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
|
|
@@ -6247,6 +6279,7 @@ initdir!$initdir$ac_delim
|
|
confdir!$confdir$ac_delim
|
|
mapdir!$mapdir$ac_delim
|
|
fifodir!$fifodir$ac_delim
|
|
+flagdir!$flagdir$ac_delim
|
|
DMALLOCLIB!$DMALLOCLIB$ac_delim
|
|
MOUNT!$MOUNT$ac_delim
|
|
HAVE_MOUNT!$HAVE_MOUNT$ac_delim
|
|
@@ -6297,7 +6330,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
|
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
|
_ACEOF
|
|
|
|
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then
|
|
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
|
|
break
|
|
elif $ac_last_try; then
|
|
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
|
diff --git a/configure.in b/configure.in
|
|
index 27b9bec..5ba3a49 100644
|
|
--- a/configure.in
|
|
+++ b/configure.in
|
|
@@ -96,6 +96,23 @@ AC_MSG_RESULT([$fifodir])
|
|
AC_SUBST(fifodir)
|
|
|
|
#
|
|
+# The user can specify --with-flagdir=PATH to specify where autofs flag file goes
|
|
+#
|
|
+AF_FLAG_D()
|
|
+AC_ARG_WITH(flagdir,
|
|
+[ --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter],
|
|
+ if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no"
|
|
+ then
|
|
+ :
|
|
+ else
|
|
+ filagdir="${withval}"
|
|
+ fi
|
|
+)
|
|
+AC_MSG_CHECKING([for autofs flag file directory])
|
|
+AC_MSG_RESULT([$flagdir])
|
|
+AC_SUBST(flagdir)
|
|
+
|
|
+#
|
|
# Optional include dmalloc
|
|
#
|
|
AM_WITH_DMALLOC()
|
|
diff --git a/daemon/Makefile b/daemon/Makefile
|
|
index 528a684..9c2d858 100644
|
|
--- a/daemon/Makefile
|
|
+++ b/daemon/Makefile
|
|
@@ -6,9 +6,9 @@
|
|
include ../Makefile.rules
|
|
|
|
SRCS = automount.c indirect.c direct.c spawn.c module.c mount.c \
|
|
- lookup.c state.c
|
|
+ lookup.c state.c flag.c
|
|
OBJS = automount.o indirect.o direct.o spawn.o module.o mount.o \
|
|
- lookup.o state.o
|
|
+ lookup.o state.o flag.o
|
|
|
|
version := $(shell cat ../.version)
|
|
|
|
@@ -17,6 +17,7 @@ CFLAGS += -DAUTOFS_LIB_DIR=\"$(autofslibdir)\"
|
|
CFLAGS += -DAUTOFS_MAP_DIR=\"$(autofsmapdir)\"
|
|
CFLAGS += -DAUTOFS_CONF_DIR=\"$(autofsconfdir)\"
|
|
CFLAGS += -DAUTOFS_FIFO_DIR=\"$(autofsfifodir)\"
|
|
+CFLAGS += -DAUTOFS_FLAG_DIR=\"$(autofsflagdir)\"
|
|
CFLAGS += -DVERSION_STRING=\"$(version)\"
|
|
LDFLAGS += -rdynamic
|
|
LIBS = -ldl
|
|
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
index 48ac30a..dbf267c 100644
|
|
--- a/daemon/automount.c
|
|
+++ b/daemon/automount.c
|
|
@@ -81,6 +81,8 @@ pthread_key_t key_thread_stdenv_vars;
|
|
|
|
#define MAX_OPEN_FILES 10240
|
|
|
|
+int aquire_flag_file(void);
|
|
+void release_flag_file(void);
|
|
static int umount_all(struct autofs_point *ap, int force);
|
|
|
|
extern pthread_mutex_t master_mutex;
|
|
@@ -1098,7 +1100,7 @@ static int handle_packet(struct autofs_point *ap)
|
|
return -1;
|
|
}
|
|
|
|
-static void become_daemon(unsigned foreground)
|
|
+static void become_daemon(unsigned foreground, unsigned daemon_check)
|
|
{
|
|
FILE *pidfp;
|
|
char buf[MAX_ERR_BUF];
|
|
@@ -1118,9 +1120,14 @@ static void become_daemon(unsigned foreground)
|
|
}
|
|
|
|
/* Detach from foreground process */
|
|
- if (foreground)
|
|
+ if (foreground) {
|
|
+ if (daemon_check && !aquire_flag_file()) {
|
|
+ fprintf(stderr, "%s: program is already running.\n",
|
|
+ program);
|
|
+ exit(1);
|
|
+ }
|
|
log_to_stderr();
|
|
- else {
|
|
+ } else {
|
|
pid = fork();
|
|
if (pid > 0) {
|
|
int r;
|
|
@@ -1136,6 +1143,13 @@ static void become_daemon(unsigned foreground)
|
|
}
|
|
close(start_pipefd[0]);
|
|
|
|
+ if (daemon_check && !aquire_flag_file()) {
|
|
+ fprintf(stderr, "%s: program is already running.\n",
|
|
+ program);
|
|
+ close(start_pipefd[1]);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
/*
|
|
* Make our own process group for "magic" reason: processes that share
|
|
* our pgrp see the raw filesystem behind the magic.
|
|
@@ -1143,6 +1157,7 @@ static void become_daemon(unsigned foreground)
|
|
if (setsid() == -1) {
|
|
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
fprintf(stderr, "setsid: %s", estr);
|
|
+ close(start_pipefd[1]);
|
|
exit(1);
|
|
}
|
|
log_to_syslog();
|
|
@@ -1617,64 +1632,6 @@ static void key_thread_stdenv_vars_destroy(void *arg)
|
|
return;
|
|
}
|
|
|
|
-static int is_automount_running(void)
|
|
-{
|
|
- FILE *fp;
|
|
- DIR *dir;
|
|
- struct dirent entry;
|
|
- struct dirent *result;
|
|
- char path[PATH_MAX + 1], buf[PATH_MAX];
|
|
-
|
|
- if ((dir = opendir("/proc")) == NULL) {
|
|
- fprintf(stderr, "cannot opendir(/proc)\n");
|
|
- exit(1);
|
|
- }
|
|
-
|
|
- while (readdir_r(dir, &entry, &result) == 0) {
|
|
- int path_len, pid = 0;
|
|
-
|
|
- if (!result)
|
|
- break;
|
|
-
|
|
- if (*entry.d_name == '.')
|
|
- continue;
|
|
-
|
|
- if (!strcmp(entry.d_name, "self"))
|
|
- continue;
|
|
-
|
|
- if (!isdigit(*entry.d_name))
|
|
- continue;
|
|
-
|
|
- pid = atoi(entry.d_name);
|
|
- if (pid == getpid())
|
|
- continue;
|
|
-
|
|
- path_len = sprintf(path, "/proc/%s/cmdline", entry.d_name);
|
|
- if (path_len >= PATH_MAX) {
|
|
- fprintf(stderr,
|
|
- "buffer to small for /proc path\n");
|
|
- return -1;
|
|
- }
|
|
- path[path_len] = '\0';
|
|
-
|
|
- fp = fopen(path, "r");
|
|
- if (fp) {
|
|
- int c, len = 0;
|
|
-
|
|
- while (len < 127 && (c = fgetc(fp)) != EOF && c)
|
|
- buf[len++] = c;
|
|
- buf[len] = '\0';
|
|
-
|
|
- if (strstr(buf, "automount"))
|
|
- return pid;
|
|
- fclose(fp);
|
|
- }
|
|
- }
|
|
- closedir(dir);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static void usage(void)
|
|
{
|
|
fprintf(stderr,
|
|
@@ -1973,11 +1930,6 @@ int main(int argc, char *argv[])
|
|
exit(exit_code);
|
|
}
|
|
|
|
- if (daemon_check && is_automount_running() > 0) {
|
|
- fprintf(stderr, "%s: program is already running.\n",
|
|
- program);
|
|
- exit(1);
|
|
- }
|
|
#if 0
|
|
if (!load_autofs4_module()) {
|
|
fprintf(stderr, "%s: can't load %s filesystem module.\n",
|
|
@@ -2009,7 +1961,7 @@ int main(int argc, char *argv[])
|
|
"can't increase core file limit - continuing");
|
|
#endif
|
|
|
|
- become_daemon(foreground);
|
|
+ become_daemon(foreground, daemon_check);
|
|
|
|
if (argc == 0)
|
|
master_list = master_new(NULL, timeout, ghost);
|
|
@@ -2020,6 +1972,7 @@ int main(int argc, char *argv[])
|
|
logerr("%s: can't create master map %s",
|
|
program, argv[0]);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
|
|
@@ -2027,6 +1980,7 @@ int main(int argc, char *argv[])
|
|
logerr("%s: failed to init thread attribute struct!",
|
|
program);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
|
|
@@ -2035,6 +1989,7 @@ int main(int argc, char *argv[])
|
|
logerr("%s: failed to set detached thread attribute!",
|
|
program);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
|
|
@@ -2044,6 +1999,7 @@ int main(int argc, char *argv[])
|
|
logerr("%s: failed to set stack size thread attribute!",
|
|
program);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
#endif
|
|
@@ -2060,6 +2016,7 @@ int main(int argc, char *argv[])
|
|
program);
|
|
master_kill(master_list);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
|
|
@@ -2067,6 +2024,7 @@ int main(int argc, char *argv[])
|
|
logerr("%s: failed to create alarm handler thread!", program);
|
|
master_kill(master_list);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
|
|
@@ -2074,6 +2032,7 @@ int main(int argc, char *argv[])
|
|
logerr("%s: failed to create FSM handler thread!", program);
|
|
master_kill(master_list);
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(1);
|
|
}
|
|
|
|
@@ -2086,6 +2045,7 @@ int main(int argc, char *argv[])
|
|
*pst_stat = 3;
|
|
res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
|
|
close(start_pipefd[1]);
|
|
+ release_flag_file();
|
|
exit(3);
|
|
}
|
|
|
|
@@ -2102,6 +2062,7 @@ int main(int argc, char *argv[])
|
|
pid_file = NULL;
|
|
}
|
|
closelog();
|
|
+ release_flag_file();
|
|
|
|
#ifdef LIBXML2_WORKAROUND
|
|
if (dh)
|
|
diff --git a/daemon/flag.c b/daemon/flag.c
|
|
new file mode 100644
|
|
index 0000000..d8ca61b
|
|
--- /dev/null
|
|
+++ b/daemon/flag.c
|
|
@@ -0,0 +1,192 @@
|
|
+/* ----------------------------------------------------------------------- *
|
|
+ *
|
|
+ * flag.c - autofs flag file management
|
|
+ *
|
|
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
|
|
+ * Copyright 2008 Ian Kent <raven@themaw.net>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
+ * USA; either version 2 of the License, or (at your option) any later
|
|
+ * version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * ----------------------------------------------------------------------- */
|
|
+
|
|
+#include <sys/time.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+#include <time.h>
|
|
+#include <unistd.h>
|
|
+#include <string.h>
|
|
+#include <alloca.h>
|
|
+#include <stdio.h>
|
|
+#include <signal.h>
|
|
+#include <errno.h>
|
|
+
|
|
+#define MAX_PIDSIZE 20
|
|
+#define FLAG_FILE AUTOFS_FLAG_DIR "/autofs-running"
|
|
+
|
|
+/* Flag for already existing flag file. */
|
|
+static int we_created_flagfile = 0;
|
|
+
|
|
+/* file descriptor of flag file */
|
|
+static int fd = -1;
|
|
+
|
|
+static int flag_is_owned(int fd)
|
|
+{
|
|
+ int pid = 0, tries = 3;
|
|
+
|
|
+ while (tries--) {
|
|
+ char pidbuf[MAX_PIDSIZE + 1];
|
|
+ int got;
|
|
+
|
|
+ lseek(fd, 0, SEEK_SET);
|
|
+ got = read(fd, pidbuf, MAX_PIDSIZE);
|
|
+ /*
|
|
+ * We add a terminator to the pid to verify write complete.
|
|
+ * If the write isn't finished in 300 milliseconds then it's
|
|
+ * probably a stale lock file.
|
|
+ */
|
|
+ if (got > 0 && pidbuf[got - 1] == '\n') {
|
|
+ sscanf(pidbuf, "%d", &pid);
|
|
+ break;
|
|
+ } else {
|
|
+ struct timespec t = { 0, 100000000 };
|
|
+ struct timespec r;
|
|
+
|
|
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
|
|
+ memcpy(&t, &r, sizeof(struct timespec));
|
|
+
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* Stale flagfile */
|
|
+ if (!tries)
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+
|
|
+ if (pid) {
|
|
+ int ret;
|
|
+
|
|
+ ret = kill(pid, 0);
|
|
+ /*
|
|
+ * If lock file exists but is not owned by a process
|
|
+ * we return unowned status so we can get rid of it
|
|
+ * and continue.
|
|
+ */
|
|
+ if (ret == -1 && errno == ESRCH)
|
|
+ return 0;
|
|
+ } else {
|
|
+ /*
|
|
+ * Odd, no pid in file - so what should we do?
|
|
+ * Assume something bad happened to owner and
|
|
+ * return unowned status.
|
|
+ */
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+/* Remove flag file. */
|
|
+void release_flag_file(void)
|
|
+{
|
|
+ if (fd > 0) {
|
|
+ close(fd);
|
|
+ fd = -1;
|
|
+ }
|
|
+
|
|
+ if (we_created_flagfile) {
|
|
+ unlink(FLAG_FILE);
|
|
+ we_created_flagfile = 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* * Try to create flag file */
|
|
+int aquire_flag_file(void)
|
|
+{
|
|
+ char *linkf;
|
|
+ int len;
|
|
+
|
|
+ len = strlen(FLAG_FILE) + MAX_PIDSIZE;
|
|
+ linkf = alloca(len + 1);
|
|
+ snprintf(linkf, len, "%s.%d", FLAG_FILE, getpid());
|
|
+
|
|
+ /*
|
|
+ * Repeat until it was us who made the link or we find the
|
|
+ * flag file already exists. If an unexpected error occurs
|
|
+ * we return 0 claiming the flag file exists which may not
|
|
+ * really be the case.
|
|
+ */
|
|
+ while (!we_created_flagfile) {
|
|
+ int errsv, i, j;
|
|
+
|
|
+ i = open(linkf, O_WRONLY|O_CREAT, 0);
|
|
+ if (i < 0) {
|
|
+ release_flag_file();
|
|
+ return 0;
|
|
+ }
|
|
+ close(i);
|
|
+
|
|
+ j = link(linkf, FLAG_FILE);
|
|
+ errsv = errno;
|
|
+
|
|
+ (void) unlink(linkf);
|
|
+
|
|
+ if (j < 0 && errsv != EEXIST) {
|
|
+ release_flag_file();
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ fd = open(FLAG_FILE, O_RDWR);
|
|
+ if (fd < 0) {
|
|
+ /* Maybe the file was just deleted? */
|
|
+ if (errno == ENOENT)
|
|
+ continue;
|
|
+ release_flag_file();
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (j == 0) {
|
|
+ char pidbuf[MAX_PIDSIZE + 1];
|
|
+ int pidlen;
|
|
+
|
|
+ pidlen = sprintf(pidbuf, "%d\n", getpid());
|
|
+ if (write(fd, pidbuf, pidlen) != pidlen) {
|
|
+ release_flag_file();
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ we_created_flagfile = 1;
|
|
+ } else {
|
|
+ /*
|
|
+ * Someone else made the link.
|
|
+ * If the flag file is not owned by anyone clean
|
|
+ * it up and try again, otherwise return fail.
|
|
+ */
|
|
+ if (!flag_is_owned(fd)) {
|
|
+ close(fd);
|
|
+ fd = -1;
|
|
+ unlink(FLAG_FILE);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ release_flag_file();
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ close(fd);
|
|
+ fd = -1;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|