annotate common/linuxlockfile.c @ 1332:8362e30f7b55

(issue139) Check that pid is not running if the lock can be aquired If the lock on the lockfile can be aquired it might still be possible that another process is running. So we read the pid from the lockfile and check if another process with the same installation prefix as us is running.
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 15 Oct 2014 14:19:46 +0200
parents 7ea3a4c0e2ae
children 5d7b1650de1f
rev   line source
1160
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
2 * Software engineering by Intevation GmbH
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
3 *
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
4 * This file is Free Software under the GNU GPL (v>=2)
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
5 * and comes with ABSOLUTELY NO WARRANTY!
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
6 * See LICENSE.txt for details.
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
7 */
a974b61a5cce (issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 782
diff changeset
8
782
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
9 #ifndef WIN32
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
10
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
11 #include <fcntl.h>
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
12 #include <stdio.h>
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
13 #include <sys/types.h>
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
14 #include <unistd.h>
1332
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
15 #include <string.h>
782
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
16
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
17 #include "logging.h"
1332
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
18 #include "util.h"
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
19 #include "strhelp.h"
782
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
20
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
21 int
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
22 open_lockfile(char *path)
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
23 {
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
24 int fd;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
25 char pidstr[20];
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
26 size_t pidstrlen;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
27 struct flock lk;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
28 fd = open(path, O_RDWR | O_CREAT, 0600);
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
29 if (fd != -1)
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
30 {
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
31 /* Get an exclusive lock on the whole file. */
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
32 lk.l_type = F_WRLCK;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
33 lk.l_whence = SEEK_SET;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
34 lk.l_start = 0;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
35 lk.l_len = 0;
1332
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
36 fcntl(fd, F_SETLK, &lk);
782
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
37 if (fcntl(fd, F_SETLK, &lk) != -1)
1332
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
38 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
39 char oldpid[20];
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
40 FILE *f = fopen(path, "r");
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
41 size_t bytes_read;
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
42 if (f)
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
43 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
44 bytes_read = fread(oldpid, 1, sizeof(oldpid), f);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
45 if (bytes_read)
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
46 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
47 char *oldPath,
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
48 *newPath;
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
49 if (bytes_read == sizeof(oldpid))
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
50 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
51 ERRORPRINTF ("Bad information in pidfile\n");
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
52 }
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
53 else
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
54 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
55 oldpid[bytes_read] = '\0';
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
56 oldPath = get_proc_install_dir(oldpid);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
57 newPath = get_install_dir();
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
58 if (oldPath && newPath && strcmp(oldPath, newPath) == 0)
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
59 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
60 DEBUGPRINTF("Got lock but process from %s is still"
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
61 "running.\n", oldPath);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
62 xfree(oldPath);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
63 xfree(newPath);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
64 return -1;
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
65 }
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
66 xfree(oldPath);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
67 xfree(newPath);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
68 }
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
69 }
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
70 fclose(f);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
71 }
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
72
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
73 ftruncate(fd, 0);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
74 pidstrlen = (size_t)snprintf(pidstr, sizeof(pidstr), "%d",
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
75 getpid());
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
76 write(fd, pidstr, pidstrlen);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
77 }
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
78 else
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
79 {
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
80 /* Lock can not be acquired. Bail out... */
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
81 close(fd);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
82 DEBUGPRINTF("Could not get an exclusive lock on %s.\n", path);
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
83 return -1;
8362e30f7b55 (issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1250
diff changeset
84 }
782
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
85 }
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
86 else
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
87 {
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
88 DEBUGPRINTF("Failed to open lock file: %s.\n", path);
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
89 }
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
90 return fd;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
91 }
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
92
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
93 void
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
94 close_lockfile(int fd)
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
95 {
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
96 struct flock lk;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
97
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
98 /* Delete the PID from file. */
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
99 /* We do this instead of trying to unlink the file. */
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
100 ftruncate(fd, 0);
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
101
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
102 /* Remove lock from the file. */
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
103 lk.l_type = F_UNLCK;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
104 lk.l_whence = SEEK_SET;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
105 lk.l_start = 0;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
106 lk.l_len = 0;
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
107 if (fcntl(fd, F_SETLK, &lk) == -1)
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
108 {
1250
7ea3a4c0e2ae This should be serious software.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1162
diff changeset
109 /* Lock can not be removed */
7ea3a4c0e2ae This should be serious software.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 1162
diff changeset
110 DEBUGPRINTF("Could not remove lock from pid file.\n");
782
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
111 }
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
112 close(fd);
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
113 }
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
114
20ca94680003 Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff changeset
115 #endif /* Not WIN32 */

http://wald.intevation.org/projects/trustbridge/