irqbalance/bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch

124 lines
3.1 KiB
Diff
Raw Normal View History

2019-09-30 10:53:30 -04:00
From d57caa98c082fb3bf746b0877aa368544e8e62dc Mon Sep 17 00:00:00 2001
From: Zengruan Ye <yezengruan@huawei.com>
Date: Mon, 15 Jul 2019 21:37:39 +0800
Subject: [PATCH 4/6] bugfix: irqbalance: fix wrong pid value in pid file
If irqbalance is killed by SIGKILL or SIGTERM,
after restarting irqbalance, the pid in pid file is
wrong, that's because the way we forbid starting
multiple irqbalance instances is wrong.
Here we use fcntl to lock pid file to forbid another instance
been launched.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
irqbalance.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 40ec65c..27cf2eb 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -584,6 +584,77 @@ int init_socket()
return 0;
}
+static int create_lock_pidfile(const char *lockfile)
+{
+ struct flock lock = { 0 };
+ char pid_s[16] = { 0 };
+ int lf = 0;
+ int err = -1;
+
+ lf = open(lockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ if (lf == -1) {
+ err = -errno;
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't create lock file.\n",
+ getpid());
+ return err;
+ }
+
+retry_fcntl:
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+ if (fcntl (lf, F_SETLK, &lock) == -1) {
+ err = -errno;
+ switch (errno) {
+ case EINTR:
+ goto retry_fcntl;
+ case EAGAIN:
+ case EACCES:
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Another instance is"
+ " already running, errno:%d.\n", getpid(), errno);
+ goto error_close;
+ default:
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't aquire lock."
+ " errno %d.\n", getpid(), errno);
+ goto error_close;
+ }
+ }
+
+ if (ftruncate(lf, 0) == -1) {
+ err = -errno;
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't truncate lock file."
+ " errno: %d.\n", getpid(), errno);
+ goto error_close_unlink;
+ }
+ if (snprintf(pid_s, sizeof(pid_s), "%u\n", getpid()) < 0) {
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't printf pid string.\n", getpid());
+ err = -1;
+ goto error_close_unlink;
+ }
+
+retry_write:
+ if ((size_t)write(lf, pid_s, strlen (pid_s)) != strlen (pid_s)) {
+ err = -errno;
+ if (errno == EINTR) {
+ goto retry_write;
+ } else {
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't write pid to lock"
+ " file. errno %d\n", getpid(), errno);
+ goto error_close_unlink;
+ }
+ }
+
+ return 0;
+
+error_close_unlink:
+ (void) unlink(lockfile);
+
+error_close:
+ close(lf);
+ return err;
+}
+
int main(int argc, char** argv)
{
struct sigaction action, hupaction;
@@ -676,17 +747,11 @@ int main(int argc, char** argv)
}
if (!foreground_mode) {
- int pidfd = -1;
if (daemon(0,0))
exit(EXIT_FAILURE);
/* Write pidfile */
- if (pidfile && (pidfd = open(pidfile,
- O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) {
- char str[16];
- snprintf(str, sizeof(str), "%u\n", getpid());
- write(pidfd, str, strlen(str));
- close(pidfd);
+ if (pidfile && create_lock_pidfile(pidfile) < 0) {
+ exit(EXIT_FAILURE);
}
}
--
1.8.3.1