daemon_listener.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright [2021] JD.com, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. #include <sys/socket.h>
  18. #include <sys/un.h>
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include <stdio.h>
  22. #include "daemon_listener.h"
  23. #include "helper.h"
  24. #include "config/dbconfig.h"
  25. #include "log/log.h"
  26. WatchDogListener::WatchDogListener(WatchDog *watchdog, int sec) : owner_(watchdog), peerfd_(-1), delay_(sec){};
  27. WatchDogListener::~WatchDogListener()
  28. {
  29. if (peerfd_ > 0) {
  30. log4cplus_debug("daemons listener fd: %d closed", peerfd_);
  31. close(peerfd_);
  32. }
  33. };
  34. /* 建socket */
  35. int WatchDogListener::attach_watch_dog()
  36. {
  37. int fd[2];
  38. socketpair(AF_UNIX, SOCK_DGRAM, 0, fd);
  39. netfd = fd[0];
  40. peerfd_ = fd[1];
  41. char buf[30];
  42. snprintf(buf, sizeof(buf), "%d", peerfd_);
  43. setenv(ENV_WATCHDOG_SOCKET_FD, buf, 1);
  44. int no;
  45. setsockopt(netfd, SOL_SOCKET, SO_PASSCRED, (no = 1, &no), sizeof(int));
  46. fcntl(netfd, F_SETFD, FD_CLOEXEC);
  47. enable_input();
  48. owner_->set_listener(this);
  49. return 0;
  50. }
  51. void WatchDogListener::input_notify()
  52. {
  53. char buf[16];
  54. int n;
  55. struct msghdr msg = {0};
  56. char ucbuf[CMSG_SPACE(sizeof(struct ucred))];
  57. struct iovec iov[1];
  58. iov[0].iov_base = (void *)&buf;
  59. iov[0].iov_len = sizeof(buf);
  60. msg.msg_control = ucbuf;
  61. msg.msg_controllen = sizeof ucbuf;
  62. msg.msg_iov = iov;
  63. msg.msg_iovlen = 1;
  64. msg.msg_flags = 0;
  65. while ((n = recvmsg(netfd, &msg, MSG_TRUNC | MSG_DONTWAIT)) > 0) {
  66. struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
  67. struct ucred *uc;
  68. if (msg.msg_controllen < sizeof(ucbuf) ||
  69. cmsg->cmsg_level != SOL_SOCKET ||
  70. cmsg->cmsg_type != SCM_CREDENTIALS ||
  71. cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)) ||
  72. msg.msg_controllen < cmsg->cmsg_len)
  73. continue;
  74. uc = (struct ucred *)CMSG_DATA(cmsg);
  75. if (n != sizeof(buf))
  76. continue;
  77. log4cplus_debug("new daemons object: %p, %d, %d, %s", owner_, buf[0], uc->pid, buf + 1);
  78. WatchDogObject *obj = NULL;
  79. if (buf[0] == WATCHDOG_INPUT_OBJECT) {
  80. obj = new WatchDogObject(owner_, buf, uc->pid);
  81. if (obj == NULL) {
  82. log4cplus_error("new WatchDogObject error");
  83. return;
  84. }
  85. } else if (buf[0] == WATCHDOG_INPUT_HELPER) {
  86. StartHelperPara *para = (StartHelperPara *)(buf + 1);
  87. char path[32];
  88. if (!DbConfig::build_path(path, 32, getpid(), para->mach, para->role, para->type)) {
  89. log4cplus_error("build helper listen path error");
  90. return;
  91. }
  92. NEW(WatchDogHelper(owner_, delay_, path, para->mach, para->role, para->backlog, para->type, para->conf, para->num), obj);
  93. if (obj == NULL) {
  94. log4cplus_error("new daemons helper error");
  95. return;
  96. }
  97. WatchDogHelper *helper = (WatchDogHelper *)obj;
  98. if (helper->new_proc_fork() < 0 || helper->verify() < 0) {
  99. log4cplus_error("fork helper error");
  100. return;
  101. }
  102. } else {
  103. log4cplus_error("unknown daemons input type: %d, %s", buf[0], buf + 1);
  104. return;
  105. }
  106. obj->attach_watch_dog();
  107. }
  108. }