Kea 2.7.5
interprocess_sync_file.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7// This file requires LOCKFILE_DIR to be defined. It points to the default
8// directory where lockfile will be created.
9
10#include <config.h>
11
13
14#include <string>
15#include <cerrno>
16#include <cstring>
17#include <sstream>
18#include <iostream>
19
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26
27namespace isc {
28namespace log {
29namespace interprocess {
30
32 if (fd_ != -1) {
33 // This will also release any applied locks.
34 close(fd_);
35 // The lockfile will continue to exist, and we must not delete
36 // it.
37 }
38}
39
40bool
41InterprocessSyncFile::do_lock(int cmd, short l_type) {
42 // Open lock file only when necessary (i.e., here). This is so that
43 // if a default InterprocessSync object is replaced with another
44 // implementation, it doesn't attempt any opens.
45 if (fd_ == -1) {
46 std::string lockfile_path = LOCKFILE_DIR;
47
48 const char* const env = getenv("KEA_LOCKFILE_DIR");
49 if (env != NULL) {
50 lockfile_path = env;
51 }
52
53 lockfile_path += "/" + task_name_ + "_lockfile";
54
55 // Open the lockfile in the constructor so it doesn't do the access
56 // checks every time a message is logged.
57 const mode_t mode = umask(S_IXUSR | S_IXGRP | S_IXOTH); // 0111
58 fd_ = open(lockfile_path.c_str(), O_CREAT | O_RDWR,
59 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); // 0660
60 umask(mode);
61
62 if (fd_ == -1) {
63 std::stringstream tmp;
64
65 // We failed to create a lockfile. This means that the logging
66 // system is unusable. We need to report the issue using plain
67 // print to stderr.
68 tmp << "Unable to use interprocess sync lockfile ("
69 << std::strerror(errno) << "): " << lockfile_path;
70 std::cerr << tmp.str() << std::endl;
71
72 // And then throw exception as usual.
73 isc_throw(InterprocessSyncFileError, tmp.str());
74 }
75 }
76
77 struct flock lock;
78
79 memset(&lock, 0, sizeof (lock));
80 lock.l_type = l_type;
81 lock.l_whence = SEEK_SET;
82 lock.l_start = 0;
83 lock.l_len = 1;
84
85 return (fcntl(fd_, cmd, &lock) == 0);
86}
87
88bool
90 if (is_locked_) {
91 return (true);
92 }
93
94 if (do_lock(F_SETLKW, F_WRLCK)) {
95 is_locked_ = true;
96 return (true);
97 }
98
99 return (false);
100}
101
102bool
104 if (is_locked_) {
105 return (true);
106 }
107
108 if (do_lock(F_SETLK, F_WRLCK)) {
109 is_locked_ = true;
110 return (true);
111 }
112
113 return (false);
114}
115
116bool
118 if (!is_locked_) {
119 return (true);
120 }
121
122 if (do_lock(F_SETLKW, F_UNLCK)) {
123 is_locked_ = false;
124 return (true);
125 }
126
127 return (false);
128}
129
130} // namespace interprocess
131} // namespace log
132} // namespace isc
bool lock()
Acquire the lock (blocks if something else has acquired a lock on the same task name)
bool tryLock()
Try to acquire a lock (doesn't block)
const std::string task_name_
The task name.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Defines the logger used by the top-level component of kea-lfc.