]>
git.proxmox.com Git - ceph.git/blob - ceph/src/global/pidfile.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "common/debug.h"
16 #include "common/errno.h"
17 #include "common/safe_io.h"
18 #include "global/pidfile.h"
23 #include <sys/types.h>
26 #if defined(__FreeBSD__)
27 #include <sys/param.h>
30 #include "include/compat.h"
33 // derr can be used for functions exclusively called from pidfile_write
35 // cerr must be used for functions called by pidfile_remove because
36 // logging is not functional when it is called. cerr output is lost
37 // when the caller is daemonized but it will show if not (-f)
39 #define dout_context g_ceph_context
40 #define dout_prefix *_dout
41 #define dout_subsys ceph_subsys_
45 char pf_path
[PATH_MAX
+ 1];
57 return pf_path
[0] != '\0' && pf_fd
!= -1;
61 memset(pf_path
, 0, sizeof(pf_path
));
67 int open(const ConfigProxy
& conf
);
71 static pidfh
*pfh
= nullptr;
74 // check that the file we opened still is the same
78 if (stat(pf_path
, &st
) == -1)
80 if (st
.st_dev
!= pf_dev
|| st
.st_ino
!= pf_ino
)
91 if ((ret
= verify()) < 0) {
99 // seek to the beginning of the file before reading
100 ret
= ::lseek(pf_fd
, 0, SEEK_SET
);
102 std::cerr
<< __func__
<< " lseek failed "
103 << cpp_strerror(errno
) << std::endl
;
107 // check that the pid file still has our pid in it
109 memset(buf
, 0, sizeof(buf
));
110 ssize_t res
= safe_read(pf_fd
, buf
, sizeof(buf
));
113 std::cerr
<< __func__
<< " safe_read failed "
114 << cpp_strerror(-res
) << std::endl
;
120 std::cerr
<< __func__
<< " the pid found in the file is "
121 << a
<< " which is different from getpid() "
122 << getpid() << std::endl
;
125 ret
= ::unlink(pf_path
);
127 std::cerr
<< __func__
<< " unlink " << pf_path
<< " failed "
128 << cpp_strerror(errno
) << std::endl
;
135 int pidfh::open(const ConfigProxy
& conf
)
137 int len
= snprintf(pf_path
, sizeof(pf_path
),
138 "%s", conf
->pid_file
.c_str());
140 if (len
>= (int)sizeof(pf_path
))
141 return -ENAMETOOLONG
;
144 fd
= ::open(pf_path
, O_CREAT
|O_RDWR
|O_CLOEXEC
, 0644);
147 derr
<< __func__
<< ": failed to open pid file '"
148 << pf_path
<< "': " << cpp_strerror(err
) << dendl
;
153 if (fstat(fd
, &st
) == -1) {
155 derr
<< __func__
<< ": failed to fstat pid file '"
156 << pf_path
<< "': " << cpp_strerror(err
) << dendl
;
168 .l_whence
= SEEK_SET
,
172 int r
= ::fcntl(pf_fd
, F_SETLK
, &l
);
174 if (errno
== EAGAIN
|| errno
== EACCES
) {
175 derr
<< __func__
<< ": failed to lock pidfile "
176 << pf_path
<< " because another process locked it"
177 << "': " << cpp_strerror(errno
) << dendl
;
179 derr
<< __func__
<< ": failed to lock pidfile "
180 << pf_path
<< "': " << cpp_strerror(errno
) << dendl
;
195 int len
= snprintf(buf
, sizeof(buf
), "%d\n", getpid());
196 if (::ftruncate(pf_fd
, 0) < 0) {
198 derr
<< __func__
<< ": failed to ftruncate the pid file '"
199 << pf_path
<< "': " << cpp_strerror(err
) << dendl
;
202 ssize_t res
= safe_write(pf_fd
, buf
, len
);
204 derr
<< __func__
<< ": failed to write to pid file '"
205 << pf_path
<< "': " << cpp_strerror(-res
) << dendl
;
211 void pidfile_remove()
218 int pidfile_write(const ConfigProxy
& conf
)
220 if (conf
->pid_file
.empty()) {
221 dout(0) << __func__
<< ": ignore empty --pid-file" << dendl
;
225 ceph_assert(pfh
== nullptr);
228 if (atexit(pidfile_remove
)) {
229 derr
<< __func__
<< ": failed to set pidfile_remove function "
230 << "to run at exit." << dendl
;
234 int r
= pfh
->open(conf
);