Hi,

I've encountered some problems with running ipmievd under systemd - it does not
understand the way how ipmievd forks and times out when starting the service.
This patch adds 'Type=notify' support to ipmievd and systemd can start
ipmievd with full error detection.

See http://0pointer.de/public/systemd-man/sd_notify.html for details,
how description, how ipmievd communicates with systemd. I copied appropriate
Lennart's code to helper.c, it has very tolerant license.
---

 configure.in              |    7 +++
 include/ipmitool/helper.h |    2 +
 lib/helper.c              |   99 +++++++++++++++++++++++++++++++++++++++++++++
 src/ipmievd.c             |    1 
 4 files changed, 109 insertions(+)

diff --git a/configure.in b/configure.in
index 680619c..fdb58e6 100644
--- a/configure.in
+++ b/configure.in
@@ -496,6 +496,13 @@ AC_ARG_ENABLE([file-security],
            AC_DEFINE(ENABLE_FILE_SECURITY, [1], [Define to 1 for extra file 
security.])
        fi], [])
 
+dnl Enable systemd integration
+AC_ARG_ENABLE([systemd],
+       [AC_HELP_STRING([--enable-systemd],
+                       [enable systemd service type=notify support in ipmievd. 
])],
+       [if test "x$enable_systemd" != "xno"; then
+           AC_DEFINE(ENABLE_SYSTEMD, [1], [Define to 1 if building for 
systemd.])
+       fi], [])
 
 AC_TRY_RUN([
        #include <stdio.h>
diff --git a/include/ipmitool/helper.h b/include/ipmitool/helper.h
index bc2bc02..9c6de72 100644
--- a/include/ipmitool/helper.h
+++ b/include/ipmitool/helper.h
@@ -85,6 +85,8 @@ void printbuf(const uint8_t * buf, int len, const char * 
desc);
 uint8_t ipmi_csum(uint8_t * d, int s);
 FILE * ipmi_open_file(const char * file, int rw);
 void ipmi_start_daemon(struct ipmi_intf *intf);
+void ipmi_notify_sd(char *state);
+
 
 #define ipmi_open_file_read(file)      ipmi_open_file(file, 0)
 #define ipmi_open_file_write(file)     ipmi_open_file(file, 1)
diff --git a/lib/helper.c b/lib/helper.c
index fb10770..6809342 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -604,3 +604,102 @@ ipmi_start_daemon(struct ipmi_intf *intf)
        dup(0);
        dup(0);
 }
+
+/***
+  Copyright 2010 Lennart Poettering
+                
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+        
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+***/
+#ifdef ENABLE_SYSTEMD
+#include <sys/un.h>
+#include <stddef.h>
+#endif
+
+void
+ipmi_notify_sd(char *state)
+{
+#if ENABLE_SYSTEMD
+       int unset_environment = 0;
+
+        int fd = -1, r;
+        struct msghdr msghdr;
+        struct iovec iovec;
+        const char *e;
+       struct sockaddr_un un;
+
+        if (!state) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (!(e = getenv("NOTIFY_SOCKET")))
+                return;
+
+        /* Must be an abstract socket, or an absolute path */
+        if ((e[0] != '@' && e[0] != '/') || e[1] == 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        memset(&un, 0, sizeof(un));
+        un.sun_family = AF_UNIX;
+        strncpy(un.sun_path, e, sizeof(un.sun_path));
+
+        if (un.sun_path[0] == '@')
+                un.sun_path[0] = 0;
+
+        memset(&iovec, 0, sizeof(iovec));
+        iovec.iov_base = (char *)state;
+        iovec.iov_len = strlen(state);
+
+        memset(&msghdr, 0, sizeof(msghdr));
+        msghdr.msg_name = &un;
+        msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + 
strlen(e);
+
+        if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
+                msghdr.msg_namelen = sizeof(struct sockaddr_un);
+
+        msghdr.msg_iov = &iovec;
+        msghdr.msg_iovlen = 1;
+
+        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        r = 1;
+
+finish:
+        if (unset_environment)
+                unsetenv("NOTIFY_SOCKET");
+
+        if (fd >= 0)
+                close(fd);
+
+        return;
+#endif
+}
+
diff --git a/src/ipmievd.c b/src/ipmievd.c
index 19cdea6..136cc77 100644
--- a/src/ipmievd.c
+++ b/src/ipmievd.c
@@ -766,6 +766,7 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char 
** argv)
                fprintf(fp, "%d\n", (int)getpid());
                fclose(fp);
        }
+       ipmi_notify_sd("READY=1");
 
        /* register signal handler for cleanup */
        act.sa_handler = ipmievd_cleanup;


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

Reply via email to