4 * Lock file managing functions.
8 * Copyright (C) 2000-2006 Kern Sibbald
9 * Copyright (C) 1998-99 Brian Schau <bsc@fleggaard.dk>
10 * Copyright (C) 1998-99-2000 Riccardo Facchetti <riccardo@master.oasi.gpa.it>
11 * Copyright (C) 1996-99 Andre M. Hedrick <andre@suse.com>
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of version 2 of the GNU General
15 * Public License as published by the Free Software Foundation.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public
23 * License along with this program; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
31 * For Windows, we do NOT create a lock file. Even if we did
32 * no other program would respect it since this is not a
36 /* Check to see if a serial port lockfile exists.
37 * If so, and the process is no longer running,
38 * blow away the lockfile.
40 #if !defined(HAVE_WIN32)
41 static int check_stale_lockfile(UPSINFO
*ups
)
49 * If the daemon is talking with APC_NET, the lock file is not
52 if (ups
->cable
.type
== APC_NET
)
55 if (ups
->lockpath
[0] == '\0') {
57 * If there's no lockfile configured, return error.
58 * This is a _must_. See my comment in apcconfig.c
60 log_event(ups
, LOG_ERR
, "No lock path configured.\n");
65 if ((ups
->lockfile
= open(ups
->lockpath
, O_RDONLY
)) < 0) {
67 * Cannot open the file (may be it doesn't exist and that's okay
68 * for us so return success).
73 /* On any other error, return error. */
74 log_event(ups
, LOG_ERR
, "Lock file open error. ERR=%s\n", strerror(errno
));
78 if ((size
= read(ups
->lockfile
, &pidbuffer
, 11)) == -1) {
80 * If we can not read from file, close it and return error:
81 * the file exist but we can not check for stale.
84 log_event(ups
, LOG_ERR
, "Lock file read error. ERR=%s\n", strerror(errno
));
88 if (size
== 0 || (sscanf(pidbuffer
, "%d", &stalepid
) != 1)) {
90 * If there's no data in the file or the data written is wrong
91 * we have a process that:
92 * 1 - running but failed to write the lock file
93 * 2 - not running and failed to write the lock file
95 * Anyway we assume the worst case (1) and return error.
98 log_event(ups
, LOG_ERR
, "Lock file data error: %s\n", pidbuffer
);
102 /* Check if it is our current pid or the pid of our parent */
103 if (stalepid
== getpid() || stalepid
== getppid()) {
105 * We are us (may be a crash of the machine ... same pid
106 * because same boot sequence ... leave it alone and go run)
113 * Okay, now we have a stalepid to check.
114 * kill(pid,0) checks to see if the process is still running.
116 if (kill(stalepid
, 0) == -1 && errno
== ESRCH
) {
118 * Okay this is a stale lock:
119 * we can unlink even before closing it.
121 if (unlink(ups
->lockpath
) < 0) {
122 log_event(ups
, LOG_ERR
,
123 "Unable to unlink old lock file %s because %s\n",
124 ups
->lockpath
, strerror(errno
));
133 * We have unfortunately found a perfectly valid lock file.
136 log_event(ups
, LOG_ERR
, "Valid lock file for pid=%d, but not ours pid=%d\n",
142 close(ups
->lockfile
);
150 * Create serial port lock file
152 int hibernate_ups
= FALSE
;
153 int shutdown_ups
= FALSE
;
154 int create_lockfile(UPSINFO
*ups
)
156 #if !defined(HAVE_WIN32)
161 * If this is a hibernate or shutdown execution, we are
162 * probably running with the filesystems read-only, so
163 * don't try to create the lock file.
165 if (hibernate_ups
|| shutdown_ups
)
168 switch (error
= check_stale_lockfile(ups
)) {
170 /* Lockfile not needed: return success. */
172 /* Lockfile exists and contains our pid. */
176 /* Lockfile exists and is not stale. */
180 /* Lockfile does not exist _now_. */
186 * Now the file does not exist any more.
187 * Open it for creation and don't accept any kind of error.
190 if ((ups
->lockfile
= open(ups
->lockpath
, O_CREAT
| O_EXCL
| O_RDWR
, 0644)) < 0) {
192 * Okay there is some problem with the lock path or
193 * something like that.
195 log_event(ups
, LOG_ERR
,
196 "Cannot create %s serial port lock file: ERR=%s\n",
197 ups
->lockpath
, strerror(errno
));
201 if (asnprintf(pidbuffer
, sizeof(pidbuffer
), "%010ld", (long)getpid()) <= 0) {
202 /* Problems with sprintf */
204 log_event(ups
, LOG_ERR
, "Lock file sprintf error.\n");
208 if (write(ups
->lockfile
, pidbuffer
,
209 strlen(pidbuffer
) + 1) != (int)strlen(pidbuffer
) + 1) {
210 /* Problems with write. */
212 log_event(ups
, LOG_ERR
, "Lock file %s write failure. ERR=%s\n",
213 ups
->lockpath
, strerror(errno
));
222 close(ups
->lockfile
);
231 void delete_lockfile(UPSINFO
*ups
)
233 #if !defined(HAVE_WIN32)
234 if (ups
->lockpath
[0] != '\0') {
236 * If lockfile is ours, close it and delete it,
237 * otherwise do nothing.
239 if (check_stale_lockfile(ups
) == LCKEXIST
) {
240 if (ups
->lockfile
!= -1) {
241 close(ups
->lockfile
);
244 unlink(ups
->lockpath
);
247 * Now ups->lockfile is == -1 so there's no need to
248 * blank ups->lockfile too.