Browse code

Add snmpd and snmptrapd to systemd service (bug 1652065)

Change-Id: I83941d264fc8e0f4c373054224dccfec5eaf8490
Reviewed-on: http://photon-jenkins.eng.vmware.com/804
Tested-by: jenkins-photon <wangnan2015@hotmail.com>
Reviewed-by: suezzelur <anishs@vmware.com>

nickshize authored on 2016/05/04 15:56:12
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1650 @@
0
+718183 - Provide native systemd unit file
1
+
2
+Gathered from following upstream git commits and backported to 5.7.
3
+
4
+commit 19499c3c90bf9d7b2b9e5d08baa26cc6bba28a11
5
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
6
+Date:   Mon Aug 8 15:48:54 2011 +0200
7
+
8
+    CHANGES: snmpd: integrated with systemd, see README.systemd for details.
9
+    
10
+    It brings sd-daemon.c and .h directly downloaded from systemd. I've made very
11
+    few changes to it to match our NETSNMP_NO_SYSTEMD and include paths.
12
+
13
+commit fef6cddfdb94da1a6b1fb768af62918b80f11fd3
14
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
15
+Date:   Mon Aug 8 15:48:54 2011 +0200
16
+
17
+    CHANGES: snmptrapd: integrate systemd notification support.
18
+
19
+commit 0641e43c694c485cbbffef0556efc4641bd3ff50
20
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
21
+Date:   Mon Aug 8 15:48:54 2011 +0200
22
+
23
+    Add sd_find_inet_socket() and sd_find_inet_unisx() helpers into
24
+    system-specific code. This will help us to find various sockets
25
+    created by systemd much easier.
26
+
27
+commit 76530a89f1c8bbd0b63acce63e10d5d4812a1a16
28
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
29
+Date:   Mon Aug 8 15:48:54 2011 +0200
30
+
31
+    Check sockets created by systemd when opening new server sockets.
32
+    
33
+    systemd can pass sockets to our daemons during startup using LISTEN_FDS
34
+    environment variable. So check this variable when opening new listening
35
+    socket - maybe system has already opened the socket for us.
36
+
37
+commit bf108d7f1354f6276fc43c129963f2c49b9fc242
38
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
39
+Date:   Mon Aug 8 15:48:54 2011 +0200
40
+
41
+    Added sample systemd service files.
42
+
43
+commit 884ec488a6596380ba283d707827dd926a52e0b2
44
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
45
+Date:   Mon Aug 8 15:48:55 2011 +0200
46
+
47
+    Run autoheader+autoconf.
48
+
49
+commit 86132e3f1e6ef7b4e0b96d8fa24e37c81b71b0e0
50
+Author: Jan Safranek <jsafranek@users.sourceforge.net>
51
+Date:   Tue Aug 9 10:53:43 2011 +0200
52
+
53
+    Update systemd documentation and samples.
54
+    
55
+    - add socket unit for snmpd to paralelize boot
56
+    - update WantedBy in socket units as recommended by http://0pointer.de/blog/projects/socket-activation.html
57
+    - rephrase README.systemd
58
+
59
+diff -up net-snmp-5.7.3/agent/snmpd.c.MPGqYh net-snmp-5.7.3/agent/snmpd.c
60
+--- net-snmp-5.7.3/agent/snmpd.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
61
+@@ -164,6 +164,10 @@ typedef long    fd_mask;
62
+ 
63
+ #endif
64
+ 
65
++#ifndef NETSNMP_NO_SYSTEMD
66
++#include <net-snmp/library/sd-daemon.h>
67
++#endif
68
++
69
+ netsnmp_feature_want(logging_file)
70
+ netsnmp_feature_want(logging_stdio)
71
+ netsnmp_feature_want(logging_syslog)
72
+@@ -443,18 +447,26 @@ main(int argc, char *argv[])
73
+     int             agent_mode = -1;
74
+     char           *pid_file = NULL;
75
+     char            option_compatability[] = "-Le";
76
++    int             prepared_sockets = 0;
77
+ #if HAVE_GETPID
78
+     int fd;
79
+     FILE           *PID;
80
+ #endif
81
+ 
82
+ #ifndef WIN32
83
++#ifndef NETSNMP_NO_SYSYSTEMD
84
++    /* check if systemd has sockets for us and don't close them */
85
++    prepared_sockets = netsnmp_sd_listen_fds(0);
86
++#endif /* NETSNMP_NO_SYSYSTEMD */
87
++
88
+     /*
89
+      * close all non-standard file descriptors we may have
90
+      * inherited from the shell.
91
+      */
92
+-    for (i = getdtablesize() - 1; i > 2; --i) {
93
+-        (void) close(i);
94
++    if (!prepared_sockets) {
95
++        for (i = getdtablesize() - 1; i > 2; --i) {
96
++            (void) close(i);
97
++        }
98
+     }
99
+ #endif /* #WIN32 */
100
+     
101
+@@ -1107,6 +1119,19 @@ main(int argc, char *argv[])
102
+     netsnmp_addrcache_initialise();
103
+ 
104
+     /*
105
++     * Let systemd know we're up.
106
++     */
107
++#ifndef NETSNMP_NO_SYSTEMD
108
++    netsnmp_sd_notify(1, "READY=1\n");
109
++    if (prepared_sockets)
110
++        /*
111
++         * Clear the environment variable, we already processed all the sockets
112
++         * by now.
113
++         */
114
++        netsnmp_sd_listen_fds(1);
115
++#endif
116
++
117
++    /*
118
+      * Forever monitor the dest_port for incoming PDUs.  
119
+      */
120
+     DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
121
+diff -up net-snmp-5.7.3/apps/snmptrapd.c.MPGqYh net-snmp-5.7.3/apps/snmptrapd.c
122
+--- net-snmp-5.7.3/apps/snmptrapd.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
123
+@@ -125,6 +125,10 @@ SOFTWARE.
124
+ 
125
+ #include <net-snmp/net-snmp-features.h>
126
+ 
127
++#ifndef NETSNMP_NO_SYSTEMD
128
++#include <net-snmp/library/sd-daemon.h>
129
++#endif
130
++
131
+ #ifndef BSD4_3
132
+ #define BSD4_2
133
+ #endif
134
+@@ -657,15 +661,22 @@ main(int argc, char *argv[])
135
+     int             agentx_subagent = 1;
136
+ #endif
137
+     netsnmp_trapd_handler *traph;
138
++    int             prepared_sockets = 0;
139
+ 
140
+ 
141
+ #ifndef WIN32
142
++#ifndef NETSNMP_NO_SYSTEMD
143
++    /* check if systemd has sockets for us and don't close them */
144
++    prepared_sockets = netsnmp_sd_listen_fds(0);
145
++#endif
146
+     /*
147
+      * close all non-standard file descriptors we may have
148
+      * inherited from the shell.
149
+      */
150
+-    for (i = getdtablesize() - 1; i > 2; --i) {
151
+-        (void) close(i);
152
++    if (!prepared_sockets) {
153
++        for (i = getdtablesize() - 1; i > 2; --i) {
154
++            (void) close(i);
155
++        }
156
+     }
157
+ #endif /* #WIN32 */
158
+     
159
+@@ -1318,6 +1329,19 @@ main(int argc, char *argv[])
160
+ #endif
161
+ #endif
162
+ 
163
++    /*
164
++     * Let systemd know we're up.
165
++     */
166
++#ifndef NETSNMP_NO_SYSTEMD
167
++    netsnmp_sd_notify(1, "READY=1\n");
168
++    if (prepared_sockets)
169
++        /*
170
++         * Clear the environment variable, we already processed all the sockets
171
++         * by now.
172
++         */
173
++        netsnmp_sd_listen_fds(1);
174
++#endif
175
++
176
+ #ifdef WIN32SERVICE
177
+     trapd_status = SNMPTRAPD_RUNNING;
178
+ #endif
179
+diff -up net-snmp-5.7.3/configure.d/config_modules_lib.MPGqYh net-snmp-5.7.3/configure.d/config_modules_lib
180
+--- net-snmp-5.7.3/configure.d/config_modules_lib.MPGqYh	2014-12-08 21:23:22.000000000 +0100
181
+@@ -53,6 +53,14 @@ if test "x$PARTIALTARGETOS" = "xmingw32"
182
+   other_ftobjs_list="$other_ftobjs_list winpipe.ft"
183
+ fi
184
+ 
185
++# Linux systemd
186
++if test "x$with_systemd" == "xyes"; then
187
++  other_src_list="$other_src_list sd-daemon.c"
188
++  other_objs_list="$other_objs_list sd-daemon.o"
189
++  other_lobjs_list="$other_lobjs_list sd-daemon.lo"
190
++  other_ftobjs_list="$other_ftobjs_list sd-daemon.ft"
191
++fi
192
++
193
+ AC_SUBST(other_src_list)
194
+ AC_SUBST(other_objs_list)
195
+ AC_SUBST(other_lobjs_list)
196
+diff -up net-snmp-5.7.3/configure.d/config_project_with_enable.MPGqYh net-snmp-5.7.3/configure.d/config_project_with_enable
197
+--- net-snmp-5.7.3/configure.d/config_project_with_enable.MPGqYh	2014-12-08 21:23:22.000000000 +0100
198
+@@ -690,6 +690,15 @@ if test "x$with_dummy_values" != "xyes";
199
+      data for])
200
+ fi
201
+ 
202
++NETSNMP_ARG_WITH(systemd,
203
++[  --with-systemd                 Provide systemd support. See README.systemd
204
++                                  for details.])
205
++# Define unless specifically suppressed (i.e., option defaults to false).
206
++if test "x$with_systemd" != "xyes"; then
207
++  AC_DEFINE(NETSNMP_NO_SYSTEMD, 1,
208
++    [If you don't want to integrate with systemd.])
209
++fi
210
++
211
+ NETSNMP_ARG_ENABLE(set-support,
212
+ [  --disable-set-support           Do not allow SNMP set requests.])
213
+ if test "x$enable_set_support" = "xno"; then
214
+diff -up net-snmp-5.7.3/configure.MPGqYh net-snmp-5.7.3/configure
215
+--- net-snmp-5.7.3/configure.MPGqYh	2014-12-08 21:23:37.000000000 +0100
216
+@@ -951,6 +951,8 @@ with_kmem_usage
217
+ enable_kmem_usage
218
+ with_dummy_values
219
+ enable_dummy_values
220
++with_systemd
221
++enable_systemd
222
+ enable_set_support
223
+ with_set_support
224
+ with_sys_contact
225
+@@ -1867,6 +1869,8 @@ Configuring the agent:
226
+                                   This is technically not compliant with the
227
+                                   SNMP specifications, but was how the agent
228
+                                   operated for versions < 4.0.
229
++  --with-systemd                 Provide systemd support. See README.systemd
230
++                                  for details.
231
+   --with-sys-contact="who@where"  Default system contact.
232
+                                     (Default: LOGIN@DOMAINNAME)
233
+   --with-sys-location="location"  Default system location.
234
+@@ -4398,6 +4402,24 @@ $as_echo "#define NETSNMP_NO_DUMMY_VALUE
235
+ 
236
+ fi
237
+ 
238
++
239
++# Check whether --with-systemd was given.
240
++if test "${with_systemd+set}" = set; then :
241
++  withval=$with_systemd;
242
++fi
243
++
244
++   # Check whether --enable-systemd was given.
245
++if test "${enable_systemd+set}" = set; then :
246
++  enableval=$enable_systemd; as_fn_error $? "Invalid option. Use --with-systemd/--without-systemd instead" "$LINENO" 5
247
++fi
248
++
249
++# Define unless specifically suppressed (i.e., option defaults to false).
250
++if test "x$with_systemd" != "xyes"; then
251
++
252
++$as_echo "#define NETSNMP_NO_SYSTEMD 1" >>confdefs.h
253
++
254
++fi
255
++
256
+ # Check whether --enable-set-support was given.
257
+ if test "${enable_set_support+set}" = set; then :
258
+   enableval=$enable_set_support;
259
+@@ -18639,6 +18661,14 @@ if test "x$PARTIALTARGETOS" = "xmingw32"
260
+   other_ftobjs_list="$other_ftobjs_list winpipe.ft"
261
+ fi
262
+ 
263
++# Linux systemd
264
++if test "x$with_systemd" == "xyes"; then
265
++  other_src_list="$other_src_list sd-daemon.c"
266
++  other_objs_list="$other_objs_list sd-daemon.o"
267
++  other_lobjs_list="$other_lobjs_list sd-daemon.lo"
268
++  other_ftobjs_list="$other_ftobjs_list sd-daemon.ft"
269
++fi
270
++
271
+ 
272
+ 
273
+ 
274
+diff -up net-snmp-5.7.3/dist/snmpd.service.MPGqYh net-snmp-5.7.3/dist/snmpd.service
275
+--- net-snmp-5.7.3/dist/snmpd.service.MPGqYh	2015-02-17 13:34:05.745221844 +0100
276
+@@ -0,0 +1,18 @@
277
++#
278
++# SNMP agent service file for systemd
279
++#
280
++#
281
++# The service should be enabled, i.e. snmpd should start during machine boot.
282
++# Socket activation shall not be used. See README.systemd for details.
283
++
284
++[Unit]
285
++Description=Simple Network Management Protocol (SNMP) daemon.
286
++After=syslog.target network.target
287
++
288
++[Service]
289
++# Type=notify is also supported. It should be set when snmpd.socket is not used.
290
++Type=simple
291
++ExecStart=/usr/sbin/snmpd -f
292
++
293
++[Install]
294
++WantedBy=multi-user.target
295
+diff -up net-snmp-5.7.3/dist/snmpd.socket.MPGqYh net-snmp-5.7.3/dist/snmpd.socket
296
+--- net-snmp-5.7.3/dist/snmpd.socket.MPGqYh	2015-02-17 13:34:05.745221844 +0100
297
+@@ -0,0 +1,17 @@
298
++[Unit]
299
++Description=Socket listening for SNMP and AgentX messages
300
++
301
++[Socket]
302
++ListenDatagram=0.0.0.0:161
303
++# Uncomment other listening addresses as needed - TCP, UDP6, TCP6.
304
++# It must match listening addresses/ports defined in snmpd.service
305
++# or snmpd.conf.
306
++# ListenStream=0.0.0.0:161
307
++# ListenDatagram=[::]:161
308
++# ListenStream=[::]:161
309
++#
310
++# Uncomment AgentX socket if snmpd.conf enables AgentX protocol.
311
++# ListenStream=/var/agentx/master
312
++
313
++[Install]
314
++WantedBy=sockets.target
315
+diff -up net-snmp-5.7.3/dist/snmptrapd.service.MPGqYh net-snmp-5.7.3/dist/snmptrapd.service
316
+--- net-snmp-5.7.3/dist/snmptrapd.service.MPGqYh	2015-02-17 13:34:05.745221844 +0100
317
+@@ -0,0 +1,16 @@
318
++#
319
++# SNMP trap-processing service file for systemd
320
++#
321
++
322
++[Unit]
323
++Description=Simple Network Management Protocol (SNMP) Trap daemon.
324
++After=syslog.target network.target
325
++
326
++[Service]
327
++# Type=notify is also supported. It should be set when snmptrapd.socket is not
328
++# used.
329
++Type=simple
330
++ExecStart=/usr/sbin/snmptrapd -f
331
++
332
++[Install]
333
++WantedBy=multi-user.target
334
+diff -up net-snmp-5.7.3/dist/snmptrapd.socket.MPGqYh net-snmp-5.7.3/dist/snmptrapd.socket
335
+--- net-snmp-5.7.3/dist/snmptrapd.socket.MPGqYh	2015-02-17 13:34:05.745221844 +0100
336
+@@ -0,0 +1,14 @@
337
++[Unit]
338
++Description=Socket listening for SNMP trap messages
339
++
340
++[Socket]
341
++ListenDatagram=0.0.0.0:162
342
++# Uncomment other listening addresses as needed - TCP, UDP6, TCP6.
343
++# It must match listening addresses/ports defined in snmptrapd.service
344
++# or snmptrapd.conf.
345
++# ListenStream=0.0.0.0:162
346
++# ListenDatagram=[::]:162
347
++# ListenStream=[::]:162
348
++
349
++[Install]
350
++WantedBy=sockets.target
351
+diff -up net-snmp-5.7.3/include/net-snmp/library/sd-daemon.h.MPGqYh net-snmp-5.7.3/include/net-snmp/library/sd-daemon.h
352
+--- net-snmp-5.7.3/include/net-snmp/library/sd-daemon.h.MPGqYh	2015-02-17 13:34:05.746221843 +0100
353
+@@ -0,0 +1,286 @@
354
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
355
++
356
++#ifndef SNMPD_SD_DAEMON_H
357
++#define SNMPD_SD_DAEMON_H
358
++
359
++/***
360
++  Copyright 2010 Lennart Poettering
361
++
362
++  Permission is hereby granted, free of charge, to any person
363
++  obtaining a copy of this software and associated documentation files
364
++  (the "Software"), to deal in the Software without restriction,
365
++  including without limitation the rights to use, copy, modify, merge,
366
++  publish, distribute, sublicense, and/or sell copies of the Software,
367
++  and to permit persons to whom the Software is furnished to do so,
368
++  subject to the following conditions:
369
++
370
++  The above copyright notice and this permission notice shall be
371
++  included in all copies or substantial portions of the Software.
372
++
373
++  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
374
++  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
375
++  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
376
++  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
377
++  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
378
++  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
379
++  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
380
++  SOFTWARE.
381
++***/
382
++
383
++#include <sys/types.h>
384
++#include <inttypes.h>
385
++
386
++#ifdef __cplusplus
387
++extern "C" {
388
++#endif
389
++
390
++/*
391
++  Reference implementation of a few systemd related interfaces for
392
++  writing daemons. These interfaces are trivial to implement. To
393
++  simplify porting we provide this reference implementation.
394
++  Applications are welcome to reimplement the algorithms described
395
++  here if they do not want to include these two source files.
396
++
397
++  The following functionality is provided:
398
++
399
++  - Support for logging with log levels on stderr
400
++  - File descriptor passing for socket-based activation
401
++  - Daemon startup and status notification
402
++  - Detection of systemd boots
403
++
404
++  You may compile this with -DDISABLE_SYSTEMD to disable systemd
405
++  support. This makes all those calls NOPs that are directly related to
406
++  systemd (i.e. only sd_is_xxx() will stay useful).
407
++
408
++  Since this is drop-in code we don't want any of our symbols to be
409
++  exported in any case. Hence we declare hidden visibility for all of
410
++  them.
411
++
412
++  You may find an up-to-date version of these source files online:
413
++
414
++  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
415
++  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
416
++
417
++  This should compile on non-Linux systems, too, but with the
418
++  exception of the sd_is_xxx() calls all functions will become NOPs.
419
++
420
++  See sd-daemon(7) for more information.
421
++*/
422
++
423
++#ifndef _sd_printf_attr_
424
++#if __GNUC__ >= 4
425
++#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
426
++#else
427
++#define _sd_printf_attr_(a,b)
428
++#endif
429
++#endif
430
++
431
++/*
432
++  Log levels for usage on stderr:
433
++
434
++          fprintf(stderr, SD_NOTICE "Hello World!\n");
435
++
436
++  This is similar to printk() usage in the kernel.
437
++*/
438
++#define SD_EMERG   "<0>"  /* system is unusable */
439
++#define SD_ALERT   "<1>"  /* action must be taken immediately */
440
++#define SD_CRIT    "<2>"  /* critical conditions */
441
++#define SD_ERR     "<3>"  /* error conditions */
442
++#define SD_WARNING "<4>"  /* warning conditions */
443
++#define SD_NOTICE  "<5>"  /* normal but significant condition */
444
++#define SD_INFO    "<6>"  /* informational */
445
++#define SD_DEBUG   "<7>"  /* debug-level messages */
446
++
447
++/* The first passed file descriptor is fd 3 */
448
++#define SD_LISTEN_FDS_START 3
449
++
450
++/*
451
++  Returns how many file descriptors have been passed, or a negative
452
++  errno code on failure. Optionally, removes the $LISTEN_FDS and
453
++  $LISTEN_PID file descriptors from the environment (recommended, but
454
++  problematic in threaded environments). If r is the return value of
455
++  this function you'll find the file descriptors passed as fds
456
++  SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
457
++  errno style error code on failure. This function call ensures that
458
++  the FD_CLOEXEC flag is set for the passed file descriptors, to make
459
++  sure they are not passed on to child processes. If FD_CLOEXEC shall
460
++  not be set, the caller needs to unset it after this call for all file
461
++  descriptors that are used.
462
++
463
++  See sd_listen_fds(3) for more information.
464
++*/
465
++int netsnmp_sd_listen_fds(int unset_environment);
466
++
467
++/*
468
++  Helper call for identifying a passed file descriptor. Returns 1 if
469
++  the file descriptor is a FIFO in the file system stored under the
470
++  specified path, 0 otherwise. If path is NULL a path name check will
471
++  not be done and the call only verifies if the file descriptor
472
++  refers to a FIFO. Returns a negative errno style error code on
473
++  failure.
474
++
475
++  See sd_is_fifo(3) for more information.
476
++*/
477
++int netsnmp_sd_is_fifo(int fd, const char *path);
478
++
479
++/*
480
++  Helper call for identifying a passed file descriptor. Returns 1 if
481
++  the file descriptor is a special character device on the file
482
++  system stored under the specified path, 0 otherwise.
483
++  If path is NULL a path name check will not be done and the call
484
++  only verifies if the file descriptor refers to a special character.
485
++  Returns a negative errno style error code on failure.
486
++
487
++  See sd_is_special(3) for more information.
488
++*/
489
++int netsnmp_sd_is_special(int fd, const char *path);
490
++
491
++/*
492
++  Helper call for identifying a passed file descriptor. Returns 1 if
493
++  the file descriptor is a socket of the specified family (AF_INET,
494
++  ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
495
++  family is 0 a socket family check will not be done. If type is 0 a
496
++  socket type check will not be done and the call only verifies if
497
++  the file descriptor refers to a socket. If listening is > 0 it is
498
++  verified that the socket is in listening mode. (i.e. listen() has
499
++  been called) If listening is == 0 it is verified that the socket is
500
++  not in listening mode. If listening is < 0 no listening mode check
501
++  is done. Returns a negative errno style error code on failure.
502
++
503
++  See sd_is_socket(3) for more information.
504
++*/
505
++int netsnmp_sd_is_socket(int fd, int family, int type, int listening);
506
++
507
++/*
508
++  Helper call for identifying a passed file descriptor. Returns 1 if
509
++  the file descriptor is an Internet socket, of the specified family
510
++  (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
511
++  SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
512
++  check is not done. If type is 0 a socket type check will not be
513
++  done. If port is 0 a socket port check will not be done. The
514
++  listening flag is used the same way as in sd_is_socket(). Returns a
515
++  negative errno style error code on failure.
516
++
517
++  See sd_is_socket_inet(3) for more information.
518
++*/
519
++int netsnmp_sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
520
++
521
++/*
522
++  Helper call for identifying a passed file descriptor. Returns 1 if
523
++  the file descriptor is an AF_UNIX socket of the specified type
524
++  (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
525
++  a socket type check will not be done. If path is NULL a socket path
526
++  check will not be done. For normal AF_UNIX sockets set length to
527
++  0. For abstract namespace sockets set length to the length of the
528
++  socket name (including the initial 0 byte), and pass the full
529
++  socket path in path (including the initial 0 byte). The listening
530
++  flag is used the same way as in sd_is_socket(). Returns a negative
531
++  errno style error code on failure.
532
++
533
++  See sd_is_socket_unix(3) for more information.
534
++*/
535
++int netsnmp_sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length);
536
++
537
++/*
538
++  Informs systemd about changed daemon state. This takes a number of
539
++  newline separated environment-style variable assignments in a
540
++  string. The following variables are known:
541
++
542
++     READY=1      Tells systemd that daemon startup is finished (only
543
++                  relevant for services of Type=notify). The passed
544
++                  argument is a boolean "1" or "0". Since there is
545
++                  little value in signaling non-readiness the only
546
++                  value daemons should send is "READY=1".
547
++
548
++     STATUS=...   Passes a single-line status string back to systemd
549
++                  that describes the daemon state. This is free-from
550
++                  and can be used for various purposes: general state
551
++                  feedback, fsck-like programs could pass completion
552
++                  percentages and failing programs could pass a human
553
++                  readable error message. Example: "STATUS=Completed
554
++                  66% of file system check..."
555
++
556
++     ERRNO=...    If a daemon fails, the errno-style error code,
557
++                  formatted as string. Example: "ERRNO=2" for ENOENT.
558
++
559
++     BUSERROR=... If a daemon fails, the D-Bus error-style error
560
++                  code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
561
++
562
++     MAINPID=...  The main pid of a daemon, in case systemd did not
563
++                  fork off the process itself. Example: "MAINPID=4711"
564
++
565
++  Daemons can choose to send additional variables. However, it is
566
++  recommended to prefix variable names not listed above with X_.
567
++
568
++  Returns a negative errno-style error code on failure. Returns > 0
569
++  if systemd could be notified, 0 if it couldn't possibly because
570
++  systemd is not running.
571
++
572
++  Example: When a daemon finished starting up, it could issue this
573
++  call to notify systemd about it:
574
++
575
++     sd_notify(0, "READY=1");
576
++
577
++  See sd_notifyf() for more complete examples.
578
++
579
++  See sd_notify(3) for more information.
580
++*/
581
++int netsnmp_sd_notify(int unset_environment, const char *state);
582
++
583
++/*
584
++  Similar to sd_notify() but takes a format string.
585
++
586
++  Example 1: A daemon could send the following after initialization:
587
++
588
++     sd_notifyf(0, "READY=1\n"
589
++                   "STATUS=Processing requests...\n"
590
++                   "MAINPID=%lu",
591
++                   (unsigned long) getpid());
592
++
593
++  Example 2: A daemon could send the following shortly before
594
++  exiting, on failure:
595
++
596
++     sd_notifyf(0, "STATUS=Failed to start up: %s\n"
597
++                   "ERRNO=%i",
598
++                   strerror(errno),
599
++                   errno);
600
++
601
++  See sd_notifyf(3) for more information.
602
++*/
603
++int netsnmp_sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3);
604
++
605
++/*
606
++  Returns > 0 if the system was booted with systemd. Returns < 0 on
607
++  error. Returns 0 if the system was not booted with systemd. Note
608
++  that all of the functions above handle non-systemd boots just
609
++  fine. You should NOT protect them with a call to this function. Also
610
++  note that this function checks whether the system, not the user
611
++  session is controlled by systemd. However the functions above work
612
++  for both user and system services.
613
++
614
++  See sd_booted(3) for more information.
615
++*/
616
++int netsnmp_sd_booted(void);
617
++
618
++/**
619
++ * Find an socket with given parameters. See man sd_is_socket_inet for
620
++ * description of the arguments.
621
++ *
622
++ * Returns the file descriptor if it is found, 0 otherwise.
623
++ */
624
++int netsnmp_sd_find_inet_socket(int family, int type, int listening, int port);
625
++
626
++/**
627
++ * Find an unix socket with given parameters. See man sd_is_socket_unix for
628
++ * description of the arguments.
629
++ *
630
++ * Returns the file descriptor if it is found, 0 otherwise.
631
++ */
632
++int
633
++netsnmp_sd_find_unix_socket(int type, int listening, const char *path);
634
++
635
++#ifdef __cplusplus
636
++}
637
++#endif
638
++
639
++#endif /* SNMPD_SD_DAEMON_H */
640
+diff -up net-snmp-5.7.3/include/net-snmp/net-snmp-config.h.in.MPGqYh net-snmp-5.7.3/include/net-snmp/net-snmp-config.h.in
641
+--- net-snmp-5.7.3/include/net-snmp/net-snmp-config.h.in.MPGqYh	2014-12-08 21:23:22.000000000 +0100
642
+@@ -1410,6 +1410,9 @@
643
+ /* If you don't have root access don't exit upon kmem errors */
644
+ #undef NETSNMP_NO_ROOT_ACCESS
645
+ 
646
++/* If you don't want to integrate with systemd. */
647
++#undef NETSNMP_NO_SYSTEMD
648
++
649
+ /* Define if you want to remove all SET/write access from the code */
650
+ #undef NETSNMP_NO_WRITE_SUPPORT
651
+ 
652
+diff -up net-snmp-5.7.3/README.systemd.MPGqYh net-snmp-5.7.3/README.systemd
653
+--- net-snmp-5.7.3/README.systemd.MPGqYh	2015-02-17 13:34:05.747221843 +0100
654
+@@ -0,0 +1,41 @@
655
++README.systemd
656
++--------------
657
++Net-SNMP provides two daemons, which support systemd system manager. 
658
++See http://www.freedesktop.org/wiki/Software/systemd to learn how
659
++systemd works. Both socket activation and notification is supported by these
660
++daemons.
661
++
662
++To enable systemd support, the sources must be compiled with
663
++--with-systemd configure option.
664
++
665
++snmpd - The SNMP agent
666
++----------------------
667
++Socket activation od snmpd daemon is implemented, but it's discouraged.
668
++The reason is simple - snmpd not only listens and processes SNMP requests
669
++from network, but also gathers system statistics counters, sends traps and
670
++communicates with subagents. It even opens few netlink sockets.
671
++
672
++In other words, snmpd should run from system start to properly work.
673
++This can be done in two ways:
674
++1) either as snmpd service unit with 'Type=notification' and without a socket
675
++   unit
676
++2) or as snmpd service unit with 'Type=simple', appropriate socket socket unit
677
++   and the snmpd service enabled. This way systemd creates the snmpd listening
678
++   socket early during boot and passes the sockets to snmpd slightly later
679
++   (but still during machine boot). This way systemd can paralelize start of
680
++   services, which depend on snmpd. Admins must adjust the socket file manually,
681
++   depending if the snmpd support AgentX, IPv6, SMUX etc.
682
++
683
++snmpd should be started with '-f' command line parameter to disable forking -
684
++systemd does that for us automatically.
685
++
686
++
687
++snmptrapd - The trap processing daemon
688
++--------------------------------------
689
++snmptrapd supports full socket activation and also notification (if needed).
690
++Both 'Type=simple' (with appropriate socket unit) and 'Type=notify' services
691
++will work. Again, '-f' parameter should be provided on snmptrapd command line.
692
++
693
++If integration with SNMP agent using AgentX protocol is enabled, snmptrapd should
694
++start during boot and not after first SNMP trap arrives. Same rules as for snmpd
695
++applies then.
696
+\ No newline at end of file
697
+diff -up net-snmp-5.7.3/snmplib/sd-daemon.c.MPGqYh net-snmp-5.7.3/snmplib/sd-daemon.c
698
+--- net-snmp-5.7.3/snmplib/sd-daemon.c.MPGqYh	2015-02-17 13:34:05.747221843 +0100
699
+@@ -0,0 +1,532 @@
700
++/*
701
++ * Systemd integration parts.
702
++ *
703
++ * Most of this file is directly copied from systemd sources.
704
++ * Changes:
705
++ * - all functions were renamed to have netsnmp_ prefix
706
++ * - includes were  changed to match Net-SNMP style.
707
++ * - removed gcc export macros
708
++ * - removed POSIX message queues
709
++ */
710
++
711
++#include <net-snmp/net-snmp-config.h>
712
++#include <net-snmp/net-snmp-features.h>
713
++#include <net-snmp/types.h>
714
++#include <net-snmp/library/snmp_debug.h>
715
++
716
++#ifndef NETSNMP_NO_SYSTEMD
717
++
718
++/***
719
++  Copyright 2010 Lennart Poettering
720
++
721
++  Permission is hereby granted, free of charge, to any person
722
++  obtaining a copy of this software and associated documentation files
723
++  (the "Software"), to deal in the Software without restriction,
724
++  including without limitation the rights to use, copy, modify, merge,
725
++  publish, distribute, sublicense, and/or sell copies of the Software,
726
++  and to permit persons to whom the Software is furnished to do so,
727
++  subject to the following conditions:
728
++
729
++  The above copyright notice and this permission notice shall be
730
++  included in all copies or substantial portions of the Software.
731
++
732
++  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
733
++  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
734
++  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
735
++  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
736
++  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
737
++  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
738
++  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
739
++  SOFTWARE.
740
++***/
741
++
742
++#ifndef _GNU_SOURCE
743
++#define _GNU_SOURCE
744
++#endif
745
++
746
++#include <sys/types.h>
747
++#include <sys/stat.h>
748
++#include <sys/socket.h>
749
++#include <sys/un.h>
750
++#include <sys/fcntl.h>
751
++#include <netinet/in.h>
752
++#include <stdlib.h>
753
++#include <errno.h>
754
++#include <unistd.h>
755
++#include <string.h>
756
++#include <stdarg.h>
757
++#include <stdio.h>
758
++#include <stddef.h>
759
++#include <limits.h>
760
++
761
++#include <net-snmp/library/sd-daemon.h>
762
++
763
++int netsnmp_sd_listen_fds(int unset_environment) {
764
++
765
++        int r, fd;
766
++        const char *e;
767
++        char *p = NULL;
768
++        unsigned long l;
769
++
770
++        if (!(e = getenv("LISTEN_PID"))) {
771
++                r = 0;
772
++                goto finish;
773
++        }
774
++
775
++        errno = 0;
776
++        l = strtoul(e, &p, 10);
777
++
778
++        if (errno != 0) {
779
++                r = -errno;
780
++                goto finish;
781
++        }
782
++
783
++        if (!p || *p || l <= 0) {
784
++                r = -EINVAL;
785
++                goto finish;
786
++        }
787
++
788
++        /* Is this for us? */
789
++        if (getpid() != (pid_t) l) {
790
++                r = 0;
791
++                goto finish;
792
++        }
793
++
794
++        if (!(e = getenv("LISTEN_FDS"))) {
795
++                r = 0;
796
++                goto finish;
797
++        }
798
++
799
++        errno = 0;
800
++        l = strtoul(e, &p, 10);
801
++
802
++        if (errno != 0) {
803
++                r = -errno;
804
++                goto finish;
805
++        }
806
++
807
++        if (!p || *p) {
808
++                r = -EINVAL;
809
++                goto finish;
810
++        }
811
++
812
++        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
813
++                int flags;
814
++
815
++                if ((flags = fcntl(fd, F_GETFD)) < 0) {
816
++                        r = -errno;
817
++                        goto finish;
818
++                }
819
++
820
++                if (flags & FD_CLOEXEC)
821
++                        continue;
822
++
823
++                if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
824
++                        r = -errno;
825
++                        goto finish;
826
++                }
827
++        }
828
++
829
++        r = (int) l;
830
++
831
++finish:
832
++        if (unset_environment) {
833
++                unsetenv("LISTEN_PID");
834
++                unsetenv("LISTEN_FDS");
835
++        }
836
++
837
++        return r;
838
++}
839
++
840
++int netsnmp_sd_is_fifo(int fd, const char *path) {
841
++        struct stat st_fd;
842
++
843
++        if (fd < 0)
844
++                return -EINVAL;
845
++
846
++        memset(&st_fd, 0, sizeof(st_fd));
847
++        if (fstat(fd, &st_fd) < 0)
848
++                return -errno;
849
++
850
++        if (!S_ISFIFO(st_fd.st_mode))
851
++                return 0;
852
++
853
++        if (path) {
854
++                struct stat st_path;
855
++
856
++                memset(&st_path, 0, sizeof(st_path));
857
++                if (stat(path, &st_path) < 0) {
858
++
859
++                        if (errno == ENOENT || errno == ENOTDIR)
860
++                                return 0;
861
++
862
++                        return -errno;
863
++                }
864
++
865
++                return
866
++                        st_path.st_dev == st_fd.st_dev &&
867
++                        st_path.st_ino == st_fd.st_ino;
868
++        }
869
++
870
++        return 1;
871
++}
872
++
873
++int netsnmp_sd_is_special(int fd, const char *path) {
874
++        struct stat st_fd;
875
++
876
++        if (fd < 0)
877
++                return -EINVAL;
878
++
879
++        if (fstat(fd, &st_fd) < 0)
880
++                return -errno;
881
++
882
++        if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode))
883
++                return 0;
884
++
885
++        if (path) {
886
++                struct stat st_path;
887
++
888
++                if (stat(path, &st_path) < 0) {
889
++
890
++                        if (errno == ENOENT || errno == ENOTDIR)
891
++                                return 0;
892
++
893
++                        return -errno;
894
++                }
895
++
896
++                if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode))
897
++                        return
898
++                                st_path.st_dev == st_fd.st_dev &&
899
++                                st_path.st_ino == st_fd.st_ino;
900
++                else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode))
901
++                        return st_path.st_rdev == st_fd.st_rdev;
902
++                else
903
++                        return 0;
904
++        }
905
++
906
++        return 1;
907
++}
908
++
909
++static int sd_is_socket_internal(int fd, int type, int listening) {
910
++        struct stat st_fd;
911
++
912
++        if (fd < 0 || type < 0)
913
++                return -EINVAL;
914
++
915
++        if (fstat(fd, &st_fd) < 0)
916
++                return -errno;
917
++
918
++        if (!S_ISSOCK(st_fd.st_mode))
919
++                return 0;
920
++
921
++        if (type != 0) {
922
++                int other_type = 0;
923
++                socklen_t l = sizeof(other_type);
924
++
925
++                if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0)
926
++                        return -errno;
927
++
928
++                if (l != sizeof(other_type))
929
++                        return -EINVAL;
930
++
931
++                if (other_type != type)
932
++                        return 0;
933
++        }
934
++
935
++        if (listening >= 0) {
936
++                int accepting = 0;
937
++                socklen_t l = sizeof(accepting);
938
++
939
++                if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0)
940
++                        return -errno;
941
++
942
++                if (l != sizeof(accepting))
943
++                        return -EINVAL;
944
++
945
++                if (!accepting != !listening)
946
++                        return 0;
947
++        }
948
++
949
++        return 1;
950
++}
951
++
952
++union sockaddr_union {
953
++        struct sockaddr sa;
954
++        struct sockaddr_in in4;
955
++        struct sockaddr_in6 in6;
956
++        struct sockaddr_un un;
957
++        struct sockaddr_storage storage;
958
++};
959
++
960
++int netsnmp_sd_is_socket(int fd, int family, int type, int listening) {
961
++        int r;
962
++
963
++        if (family < 0)
964
++                return -EINVAL;
965
++
966
++        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
967
++                return r;
968
++
969
++        if (family > 0) {
970
++                union sockaddr_union sockaddr;
971
++                socklen_t l;
972
++
973
++                memset(&sockaddr, 0, sizeof(sockaddr));
974
++                l = sizeof(sockaddr);
975
++
976
++                if (getsockname(fd, &sockaddr.sa, &l) < 0)
977
++                        return -errno;
978
++
979
++                if (l < sizeof(sa_family_t))
980
++                        return -EINVAL;
981
++
982
++                return sockaddr.sa.sa_family == family;
983
++        }
984
++
985
++        return 1;
986
++}
987
++
988
++int netsnmp_sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
989
++        union sockaddr_union sockaddr;
990
++        socklen_t l;
991
++        int r;
992
++
993
++        if (family != 0 && family != AF_INET && family != AF_INET6)
994
++                return -EINVAL;
995
++
996
++        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
997
++                return r;
998
++
999
++        memset(&sockaddr, 0, sizeof(sockaddr));
1000
++        l = sizeof(sockaddr);
1001
++
1002
++        if (getsockname(fd, &sockaddr.sa, &l) < 0)
1003
++                return -errno;
1004
++
1005
++        if (l < sizeof(sa_family_t))
1006
++                return -EINVAL;
1007
++
1008
++        if (sockaddr.sa.sa_family != AF_INET &&
1009
++            sockaddr.sa.sa_family != AF_INET6)
1010
++                return 0;
1011
++
1012
++        if (family > 0)
1013
++                if (sockaddr.sa.sa_family != family)
1014
++                        return 0;
1015
++
1016
++        if (port > 0) {
1017
++                if (sockaddr.sa.sa_family == AF_INET) {
1018
++                        if (l < sizeof(struct sockaddr_in))
1019
++                                return -EINVAL;
1020
++
1021
++                        return htons(port) == sockaddr.in4.sin_port;
1022
++                } else {
1023
++                        if (l < sizeof(struct sockaddr_in6))
1024
++                                return -EINVAL;
1025
++
1026
++                        return htons(port) == sockaddr.in6.sin6_port;
1027
++                }
1028
++        }
1029
++
1030
++        return 1;
1031
++}
1032
++
1033
++int netsnmp_sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
1034
++        union sockaddr_union sockaddr;
1035
++        socklen_t l;
1036
++        int r;
1037
++
1038
++        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
1039
++                return r;
1040
++
1041
++        memset(&sockaddr, 0, sizeof(sockaddr));
1042
++        l = sizeof(sockaddr);
1043
++
1044
++        if (getsockname(fd, &sockaddr.sa, &l) < 0)
1045
++                return -errno;
1046
++
1047
++        if (l < sizeof(sa_family_t))
1048
++                return -EINVAL;
1049
++
1050
++        if (sockaddr.sa.sa_family != AF_UNIX)
1051
++                return 0;
1052
++
1053
++        if (path) {
1054
++                if (length <= 0)
1055
++                        length = strlen(path);
1056
++
1057
++                if (length <= 0)
1058
++                        /* Unnamed socket */
1059
++                        return l == offsetof(struct sockaddr_un, sun_path);
1060
++
1061
++                if (path[0])
1062
++                        /* Normal path socket */
1063
++                        return
1064
++                                (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) &&
1065
++                                memcmp(path, sockaddr.un.sun_path, length+1) == 0;
1066
++                else
1067
++                        /* Abstract namespace socket */
1068
++                        return
1069
++                                (l == offsetof(struct sockaddr_un, sun_path) + length) &&
1070
++                                memcmp(path, sockaddr.un.sun_path, length) == 0;
1071
++        }
1072
++
1073
++        return 1;
1074
++}
1075
++
1076
++int netsnmp_sd_notify(int unset_environment, const char *state) {
1077
++        int fd = -1, r;
1078
++        struct msghdr msghdr;
1079
++        struct iovec iovec;
1080
++        union sockaddr_union sockaddr;
1081
++        const char *e;
1082
++
1083
++        if (!state) {
1084
++                r = -EINVAL;
1085
++                goto finish;
1086
++        }
1087
++
1088
++        if (!(e = getenv("NOTIFY_SOCKET")))
1089
++                return 0;
1090
++
1091
++        /* Must be an abstract socket, or an absolute path */
1092
++        if ((e[0] != '@' && e[0] != '/') || e[1] == 0) {
1093
++                r = -EINVAL;
1094
++                goto finish;
1095
++        }
1096
++
1097
++        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
1098
++                r = -errno;
1099
++                goto finish;
1100
++        }
1101
++
1102
++        memset(&sockaddr, 0, sizeof(sockaddr));
1103
++        sockaddr.sa.sa_family = AF_UNIX;
1104
++        strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path));
1105
++
1106
++        if (sockaddr.un.sun_path[0] == '@')
1107
++                sockaddr.un.sun_path[0] = 0;
1108
++
1109
++        memset(&iovec, 0, sizeof(iovec));
1110
++        iovec.iov_base = (char *)state;
1111
++        iovec.iov_len = strlen(state);
1112
++
1113
++        memset(&msghdr, 0, sizeof(msghdr));
1114
++        msghdr.msg_name = &sockaddr;
1115
++        msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
1116
++
1117
++        if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
1118
++                msghdr.msg_namelen = sizeof(struct sockaddr_un);
1119
++
1120
++        msghdr.msg_iov = &iovec;
1121
++        msghdr.msg_iovlen = 1;
1122
++
1123
++        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
1124
++                r = -errno;
1125
++                goto finish;
1126
++        }
1127
++
1128
++        r = 1;
1129
++
1130
++finish:
1131
++        if (unset_environment)
1132
++                unsetenv("NOTIFY_SOCKET");
1133
++
1134
++        if (fd >= 0)
1135
++                close(fd);
1136
++
1137
++        return r;
1138
++}
1139
++
1140
++int netsnmp_sd_notifyf(int unset_environment, const char *format, ...) {
1141
++        va_list ap;
1142
++        char *p = NULL;
1143
++        int r;
1144
++
1145
++        va_start(ap, format);
1146
++        r = vasprintf(&p, format, ap);
1147
++        va_end(ap);
1148
++
1149
++        if (r < 0 || !p)
1150
++                return -ENOMEM;
1151
++
1152
++        r = netsnmp_sd_notify(unset_environment, p);
1153
++        free(p);
1154
++
1155
++        return r;
1156
++}
1157
++
1158
++int netsnmp_sd_booted(void) {
1159
++        struct stat a, b;
1160
++
1161
++        /* We simply test whether the systemd cgroup hierarchy is
1162
++         * mounted */
1163
++
1164
++        if (lstat("/sys/fs/cgroup", &a) < 0)
1165
++                return 0;
1166
++
1167
++        if (lstat("/sys/fs/cgroup/systemd", &b) < 0)
1168
++                return 0;
1169
++
1170
++        return a.st_dev != b.st_dev;
1171
++}
1172
++
1173
++/* End of original sd-daemon.c from systemd sources */
1174
++
1175
++int
1176
++netsnmp_sd_find_inet_socket(int family, int type, int listening, int port)
1177
++{
1178
++    int count, fd;
1179
++
1180
++    count = netsnmp_sd_listen_fds(0);
1181
++    if (count <= 0) {
1182
++        DEBUGMSGTL(("systemd:find_inet_socket", "No LISTEN_FDS found.\n"));
1183
++        return 0;
1184
++    }
1185
++    DEBUGMSGTL(("systemd:find_inet_socket", "LISTEN_FDS reports %d sockets.\n",
1186
++            count));
1187
++
1188
++    for (fd = 3; fd < 3+count; fd++) {
1189
++        int rc = netsnmp_sd_is_socket_inet(fd, family, type, listening, port);
1190
++        if (rc < 0)
1191
++            DEBUGMSGTL(("systemd:find_inet_socket",
1192
++                    "sd_is_socket_inet error: %d\n", rc));
1193
++        if (rc > 0) {
1194
++            DEBUGMSGTL(("systemd:find_inet_socket",
1195
++                    "Found the socket in LISTEN_FDS\n"));
1196
++            return fd;
1197
++        }
1198
++    }
1199
++    DEBUGMSGTL(("systemd:find_inet_socket", "Socket not found in LISTEN_FDS\n"));
1200
++    return 0;
1201
++}
1202
++
1203
++int
1204
++netsnmp_sd_find_unix_socket(int type, int listening, const char *path)
1205
++{
1206
++    int count, fd;
1207
++
1208
++    count = netsnmp_sd_listen_fds(0);
1209
++    if (count <= 0) {
1210
++        DEBUGMSGTL(("systemd:find_unix_socket", "No LISTEN_FDS found.\n"));
1211
++        return 0;
1212
++    }
1213
++    DEBUGMSGTL(("systemd:find_unix_socket", "LISTEN_FDS reports %d sockets.\n",
1214
++            count));
1215
++
1216
++    for (fd = 3; fd < 3+count; fd++) {
1217
++        int rc = netsnmp_sd_is_socket_unix(fd, type, listening, path, 0);
1218
++        if (rc < 0)
1219
++            DEBUGMSGTL(("systemd:find_unix_socket",
1220
++                    "netsnmp_sd_is_socket_unix error: %d\n", rc));
1221
++        if (rc > 0) {
1222
++            DEBUGMSGTL(("systemd:find_unix_socket",
1223
++                    "Found the socket in LISTEN_FDS\n"));
1224
++            return fd;
1225
++        }
1226
++    }
1227
++    DEBUGMSGTL(("systemd:find_unix_socket", "Socket not found in LISTEN_FDS\n"));
1228
++    return 0;
1229
++}
1230
++
1231
++#endif /* ! NETSNMP_NO_SYSTEMD */
1232
+diff -up net-snmp-5.7.3/snmplib/transports/snmpTCPDomain.c.MPGqYh net-snmp-5.7.3/snmplib/transports/snmpTCPDomain.c
1233
+--- net-snmp-5.7.3/snmplib/transports/snmpTCPDomain.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
1234
+@@ -43,6 +43,10 @@
1235
+ #include <net-snmp/library/snmpTCPBaseDomain.h>
1236
+ #include <net-snmp/library/tools.h>
1237
+ 
1238
++#ifndef NETSNMP_NO_SYSTEMD
1239
++#include <net-snmp/library/sd-daemon.h>
1240
++#endif
1241
++
1242
+ /*
1243
+  * needs to be in sync with the definitions in snmplib/snmpUDPDomain.c
1244
+  * and perl/agent/agent.xs
1245
+@@ -149,6 +153,7 @@ netsnmp_tcp_transport(struct sockaddr_in
1246
+     netsnmp_transport *t = NULL;
1247
+     netsnmp_udp_addr_pair *addr_pair = NULL;
1248
+     int rc = 0;
1249
++    int socket_initialized = 0;
1250
+ 
1251
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
1252
+     if (local)
1253
+@@ -178,7 +183,19 @@ netsnmp_tcp_transport(struct sockaddr_in
1254
+     t->domain_length =
1255
+         sizeof(netsnmp_snmpTCPDomain) / sizeof(netsnmp_snmpTCPDomain[0]);
1256
+ 
1257
+-    t->sock = socket(PF_INET, SOCK_STREAM, 0);
1258
++#ifndef NETSNMP_NO_SYSTEMD
1259
++    /*
1260
++     * Maybe the socket was already provided by systemd...
1261
++     */
1262
++    if (local) {
1263
++        t->sock = netsnmp_sd_find_inet_socket(PF_INET, SOCK_STREAM, 1,
1264
++                ntohs(addr->sin_port));
1265
++        if (t->sock)
1266
++            socket_initialized = 1;
1267
++    }
1268
++#endif
1269
++    if (!socket_initialized)
1270
++        t->sock = socket(PF_INET, SOCK_STREAM, 0);
1271
+     if (t->sock < 0) {
1272
+         netsnmp_transport_free(t);
1273
+         return NULL;
1274
+@@ -215,11 +232,13 @@ netsnmp_tcp_transport(struct sockaddr_in
1275
+         setsockopt(t->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt,
1276
+ 		   sizeof(opt));
1277
+ 
1278
+-        rc = bind(t->sock, (struct sockaddr *)addr, sizeof(struct sockaddr));
1279
+-        if (rc != 0) {
1280
+-            netsnmp_socketbase_close(t);
1281
+-            netsnmp_transport_free(t);
1282
+-            return NULL;
1283
++        if (!socket_initialized) {
1284
++            rc = bind(t->sock, (struct sockaddr *)addr, sizeof(struct sockaddr));
1285
++            if (rc != 0) {
1286
++                netsnmp_socketbase_close(t);
1287
++                netsnmp_transport_free(t);
1288
++                return NULL;
1289
++            }
1290
+         }
1291
+ 
1292
+         /*
1293
+@@ -235,12 +254,13 @@ netsnmp_tcp_transport(struct sockaddr_in
1294
+         /*
1295
+          * Now sit here and wait for connections to arrive.  
1296
+          */
1297
+-
1298
+-        rc = listen(t->sock, NETSNMP_STREAM_QUEUE_LEN);
1299
+-        if (rc != 0) {
1300
+-            netsnmp_socketbase_close(t);
1301
+-            netsnmp_transport_free(t);
1302
+-            return NULL;
1303
++        if (!socket_initialized) {
1304
++            rc = listen(t->sock, NETSNMP_STREAM_QUEUE_LEN);
1305
++            if (rc != 0) {
1306
++                netsnmp_socketbase_close(t);
1307
++                netsnmp_transport_free(t);
1308
++                return NULL;
1309
++            }
1310
+         }
1311
+         
1312
+         /*
1313
+diff -up net-snmp-5.7.3/snmplib/transports/snmpTCPIPv6Domain.c.MPGqYh net-snmp-5.7.3/snmplib/transports/snmpTCPIPv6Domain.c
1314
+--- net-snmp-5.7.3/snmplib/transports/snmpTCPIPv6Domain.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
1315
+@@ -49,6 +49,10 @@
1316
+ #include <net-snmp/library/snmpTCPBaseDomain.h>
1317
+ #include <net-snmp/library/tools.h>
1318
+ 
1319
++#ifndef NETSNMP_NO_SYSTEMD
1320
++#include <net-snmp/library/sd-daemon.h>
1321
++#endif
1322
++
1323
+ #include "inet_ntop.h"
1324
+ 
1325
+ oid netsnmp_TCPIPv6Domain[] = { TRANSPORT_DOMAIN_TCP_IPV6 };
1326
+@@ -140,6 +144,7 @@ netsnmp_tcp6_transport(struct sockaddr_i
1327
+ {
1328
+     netsnmp_transport *t = NULL;
1329
+     int             rc = 0;
1330
++    int             socket_initialized = 0;
1331
+ 
1332
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
1333
+     if (local)
1334
+@@ -174,7 +179,19 @@ netsnmp_tcp6_transport(struct sockaddr_i
1335
+     t->domain = netsnmp_TCPIPv6Domain;
1336
+     t->domain_length = sizeof(netsnmp_TCPIPv6Domain) / sizeof(oid);
1337
+ 
1338
+-    t->sock = socket(PF_INET6, SOCK_STREAM, 0);
1339
++#ifndef NETSNMP_NO_SYSTEMD
1340
++    /*
1341
++     * Maybe the socket was already provided by systemd...
1342
++     */
1343
++    if (local) {
1344
++        t->sock = netsnmp_sd_find_inet_socket(PF_INET6, SOCK_STREAM, 1,
1345
++                ntohs(addr->sin6_port));
1346
++        if (t->sock)
1347
++            socket_initialized = 1;
1348
++    }
1349
++#endif
1350
++    if (!socket_initialized)
1351
++        t->sock = socket(PF_INET6, SOCK_STREAM, 0);
1352
+     if (t->sock < 0) {
1353
+         netsnmp_transport_free(t);
1354
+         return NULL;
1355
+@@ -220,12 +237,14 @@ netsnmp_tcp6_transport(struct sockaddr_i
1356
+ 
1357
+         setsockopt(t->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));
1358
+ 
1359
+-        rc = bind(t->sock, (struct sockaddr *) addr,
1360
+-		  sizeof(struct sockaddr_in6));
1361
+-        if (rc != 0) {
1362
+-            netsnmp_socketbase_close(t);
1363
+-            netsnmp_transport_free(t);
1364
+-            return NULL;
1365
++        if (!socket_initialized) {
1366
++            rc = bind(t->sock, (struct sockaddr *) addr,
1367
++                    sizeof(struct sockaddr_in6));
1368
++            if (rc != 0) {
1369
++                netsnmp_socketbase_close(t);
1370
++                netsnmp_transport_free(t);
1371
++                return NULL;
1372
++            }
1373
+         }
1374
+ 
1375
+         /*
1376
+@@ -242,11 +261,13 @@ netsnmp_tcp6_transport(struct sockaddr_i
1377
+          * Now sit here and wait for connections to arrive.  
1378
+          */
1379
+ 
1380
+-        rc = listen(t->sock, NETSNMP_STREAM_QUEUE_LEN);
1381
+-        if (rc != 0) {
1382
+-            netsnmp_socketbase_close(t);
1383
+-            netsnmp_transport_free(t);
1384
+-            return NULL;
1385
++        if (!socket_initialized) {
1386
++            rc = listen(t->sock, NETSNMP_STREAM_QUEUE_LEN);
1387
++            if (rc != 0) {
1388
++                netsnmp_socketbase_close(t);
1389
++                netsnmp_transport_free(t);
1390
++                return NULL;
1391
++            }
1392
+         }
1393
+         
1394
+         /*
1395
+diff -up net-snmp-5.7.3/snmplib/transports/snmpUDPIPv4BaseDomain.c.MPGqYh net-snmp-5.7.3/snmplib/transports/snmpUDPIPv4BaseDomain.c
1396
+--- net-snmp-5.7.3/snmplib/transports/snmpUDPIPv4BaseDomain.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
1397
+@@ -40,6 +40,10 @@
1398
+ 
1399
+ #include <net-snmp/library/snmpSocketBaseDomain.h>
1400
+ 
1401
++#ifndef NETSNMP_NO_SYSTEMD
1402
++#include <net-snmp/library/sd-daemon.h>
1403
++#endif
1404
++
1405
+ #if defined(HAVE_IP_PKTINFO) || defined(HAVE_IP_RECVDSTADDR)
1406
+ int netsnmp_udpipv4_recvfrom(int s, void *buf, int len, struct sockaddr *from,
1407
+                              socklen_t *fromlen, struct sockaddr *dstip,
1408
+@@ -64,6 +68,7 @@ netsnmp_udpipv4base_transport(struct soc
1409
+     char           *client_socket = NULL;
1410
+     netsnmp_indexed_addr_pair addr_pair;
1411
+     socklen_t       local_addr_len;
1412
++    int             socket_initialized = 0;
1413
+ 
1414
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
1415
+     if (local)
1416
+@@ -88,7 +93,20 @@ netsnmp_udpipv4base_transport(struct soc
1417
+         free(str);
1418
+     }
1419
+ 
1420
+-    t->sock = socket(PF_INET, SOCK_DGRAM, 0);
1421
++#ifndef NETSNMP_NO_SYSTEMD
1422
++    /*
1423
++     * Maybe the socket was already provided by systemd...
1424
++     */
1425
++    if (local) {
1426
++        t->sock = netsnmp_sd_find_inet_socket(PF_INET, SOCK_DGRAM, -1,
1427
++                ntohs(addr->sin_port));
1428
++        if (t->sock)
1429
++            socket_initialized = 1;
1430
++    }
1431
++#endif
1432
++    if (!socket_initialized)
1433
++        t->sock = socket(PF_INET, SOCK_DGRAM, 0);
1434
++
1435
+     DEBUGMSGTL(("UDPBase", "openned socket %d as local=%d\n", t->sock, local)); 
1436
+     if (t->sock < 0) {
1437
+         netsnmp_transport_free(t);
1438
+@@ -151,12 +169,14 @@ netsnmp_udpipv4base_transport(struct soc
1439
+             }
1440
+         }
1441
+ #endif /* !defined(WIN32) */
1442
+-        rc = bind(t->sock, (struct sockaddr *) addr,
1443
+-                  sizeof(struct sockaddr));
1444
+-        if (rc != 0) {
1445
+-            netsnmp_socketbase_close(t);
1446
+-            netsnmp_transport_free(t);
1447
+-            return NULL;
1448
++        if (!socket_initialized) {
1449
++            rc = bind(t->sock, (struct sockaddr *) addr,
1450
++                    sizeof(struct sockaddr));
1451
++            if (rc != 0) {
1452
++                netsnmp_socketbase_close(t);
1453
++                netsnmp_transport_free(t);
1454
++                return NULL;
1455
++            }
1456
+         }
1457
+         t->data = NULL;
1458
+         t->data_length = 0;
1459
+diff -up net-snmp-5.7.3/snmplib/transports/snmpUDPIPv6Domain.c.MPGqYh net-snmp-5.7.3/snmplib/transports/snmpUDPIPv6Domain.c
1460
+--- net-snmp-5.7.3/snmplib/transports/snmpUDPIPv6Domain.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
1461
+@@ -67,6 +67,10 @@ static const struct in6_addr in6addr_any
1462
+ #include <net-snmp/library/snmpSocketBaseDomain.h>
1463
+ #include <net-snmp/library/tools.h>
1464
+ 
1465
++#ifndef NETSNMP_NO_SYSTEMD
1466
++#include <net-snmp/library/sd-daemon.h>
1467
++#endif
1468
++
1469
+ #include "inet_ntop.h"
1470
+ #include "inet_pton.h"
1471
+ 
1472
+@@ -190,6 +194,7 @@ netsnmp_udp6_transport(struct sockaddr_i
1473
+ {
1474
+     netsnmp_transport *t = NULL;
1475
+     int             rc = 0;
1476
++    int             socket_initialized = 0;
1477
+ 
1478
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
1479
+     if (local)
1480
+@@ -217,7 +222,19 @@ netsnmp_udp6_transport(struct sockaddr_i
1481
+     t->domain_length =
1482
+         sizeof(netsnmp_UDPIPv6Domain) / sizeof(netsnmp_UDPIPv6Domain[0]);
1483
+ 
1484
+-    t->sock = socket(PF_INET6, SOCK_DGRAM, 0);
1485
++#ifndef NETSNMP_NO_SYSTEMD
1486
++    /*
1487
++     * Maybe the socket was already provided by systemd...
1488
++     */
1489
++    if (local) {
1490
++        t->sock = netsnmp_sd_find_inet_socket(PF_INET6, SOCK_DGRAM, -1,
1491
++                ntohs(addr->sin6_port));
1492
++        if (t->sock)
1493
++            socket_initialized = 1;
1494
++    }
1495
++#endif
1496
++    if (!socket_initialized)
1497
++        t->sock = socket(PF_INET6, SOCK_DGRAM, 0);
1498
+     if (t->sock < 0) {
1499
+         netsnmp_transport_free(t);
1500
+         return NULL;
1501
+@@ -242,13 +259,14 @@ netsnmp_udp6_transport(struct sockaddr_i
1502
+             } 
1503
+         }
1504
+ #endif
1505
+-
1506
+-        rc = bind(t->sock, (struct sockaddr *) addr,
1507
+-		  sizeof(struct sockaddr_in6));
1508
+-        if (rc != 0) {
1509
+-            netsnmp_socketbase_close(t);
1510
+-            netsnmp_transport_free(t);
1511
+-            return NULL;
1512
++        if (!socket_initialized) {
1513
++            rc = bind(t->sock, (struct sockaddr *) addr,
1514
++                    sizeof(struct sockaddr_in6));
1515
++            if (rc != 0) {
1516
++                netsnmp_socketbase_close(t);
1517
++                netsnmp_transport_free(t);
1518
++                return NULL;
1519
++            }
1520
+         }
1521
+         t->local = (unsigned char*)malloc(18);
1522
+         if (t->local == NULL) {
1523
+diff -up net-snmp-5.7.3/snmplib/transports/snmpUnixDomain.c.MPGqYh net-snmp-5.7.3/snmplib/transports/snmpUnixDomain.c
1524
+--- net-snmp-5.7.3/snmplib/transports/snmpUnixDomain.c.MPGqYh	2014-12-08 21:23:22.000000000 +0100
1525
+@@ -37,6 +37,10 @@
1526
+ #include <net-snmp/library/system.h> /* mkdirhier */
1527
+ #include <net-snmp/library/tools.h>
1528
+ 
1529
++#ifndef NETSNMP_NO_SYSTEMD
1530
++#include <net-snmp/library/sd-daemon.h>
1531
++#endif
1532
++
1533
+ netsnmp_feature_child_of(transport_unix_socket_all, transport_all)
1534
+ netsnmp_feature_child_of(unix_socket_paths, transport_unix_socket_all)
1535
+ 
1536
+@@ -295,6 +299,7 @@ netsnmp_unix_transport(struct sockaddr_u
1537
+     netsnmp_transport *t = NULL;
1538
+     sockaddr_un_pair *sup = NULL;
1539
+     int             rc = 0;
1540
++    int             socket_initialized = 0;
1541
+ 
1542
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
1543
+     /* SPECIAL CIRCUMSTANCE: We still want AgentX to be able to operate,
1544
+@@ -333,7 +338,18 @@ netsnmp_unix_transport(struct sockaddr_u
1545
+     t->data_length = sizeof(sockaddr_un_pair);
1546
+     sup = (sockaddr_un_pair *) t->data;
1547
+ 
1548
+-    t->sock = socket(PF_UNIX, SOCK_STREAM, 0);
1549
++#ifndef NETSNMP_NO_SYSTEMD
1550
++    /*
1551
++     * Maybe the socket was already provided by systemd...
1552
++     */
1553
++    if (local) {
1554
++        t->sock = netsnmp_sd_find_unix_socket(SOCK_STREAM, 1, addr->sun_path);
1555
++        if (t->sock)
1556
++            socket_initialized = 1;
1557
++    }
1558
++#endif
1559
++    if (!socket_initialized)
1560
++        t->sock = socket(PF_UNIX, SOCK_STREAM, 0);
1561
+     if (t->sock < 0) {
1562
+         netsnmp_transport_free(t);
1563
+         return NULL;
1564
+@@ -357,25 +373,26 @@ netsnmp_unix_transport(struct sockaddr_u
1565
+ 
1566
+         t->flags |= NETSNMP_TRANSPORT_FLAG_LISTEN;
1567
+ 
1568
+-        unlink(addr->sun_path);
1569
+-        rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
1570
+-
1571
+-        if (rc != 0 && errno == ENOENT && create_path) {
1572
+-            rc = mkdirhier(addr->sun_path, create_mode, 1);
1573
++        if (!socket_initialized) {
1574
++            unlink(addr->sun_path);
1575
++            rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
1576
++            if (rc != 0 && errno == ENOENT && create_path) {
1577
++                rc = mkdirhier(addr->sun_path, create_mode, 1);
1578
++                if (rc != 0) {
1579
++                    netsnmp_unix_close(t);
1580
++                    netsnmp_transport_free(t);
1581
++                    return NULL;
1582
++                }
1583
++                rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
1584
++            }
1585
+             if (rc != 0) {
1586
++                DEBUGMSGTL(("netsnmp_unix_transport",
1587
++                        "couldn't bind \"%s\", errno %d (%s)\n",
1588
++                        addr->sun_path, errno, strerror(errno)));
1589
+                 netsnmp_unix_close(t);
1590
+                 netsnmp_transport_free(t);
1591
+                 return NULL;
1592
+             }
1593
+-            rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
1594
+-        }
1595
+-        if (rc != 0) {
1596
+-            DEBUGMSGTL(("netsnmp_unix_transport",
1597
+-                        "couldn't bind \"%s\", errno %d (%s)\n",
1598
+-                        addr->sun_path, errno, strerror(errno)));
1599
+-            netsnmp_unix_close(t);
1600
+-            netsnmp_transport_free(t);
1601
+-            return NULL;
1602
+         }
1603
+ 
1604
+         /*
1605
+@@ -391,16 +408,17 @@ netsnmp_unix_transport(struct sockaddr_u
1606
+          * Now sit here and listen for connections to arrive.
1607
+          */
1608
+ 
1609
+-        rc = listen(t->sock, NETSNMP_STREAM_QUEUE_LEN);
1610
+-        if (rc != 0) {
1611
+-            DEBUGMSGTL(("netsnmp_unix_transport",
1612
+-                        "couldn't listen to \"%s\", errno %d (%s)\n",
1613
+-                        addr->sun_path, errno, strerror(errno)));
1614
+-            netsnmp_unix_close(t);
1615
+-            netsnmp_transport_free(t);
1616
+-            return NULL;
1617
++        if (!socket_initialized) {
1618
++            rc = listen(t->sock, NETSNMP_STREAM_QUEUE_LEN);
1619
++            if (rc != 0) {
1620
++                DEBUGMSGTL(("netsnmp_unix_transport",
1621
++                            "couldn't listen to \"%s\", errno %d (%s)\n",
1622
++                            addr->sun_path, errno, strerror(errno)));
1623
++                netsnmp_unix_close(t);
1624
++                netsnmp_transport_free(t);
1625
++                return NULL;
1626
++            }
1627
+         }
1628
+-
1629
+     } else {
1630
+         t->remote = (u_char *)malloc(strlen(addr->sun_path));
1631
+         if (t->remote == NULL) {
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:	Net-SNMP is a suite of applications used to implement SNMP v1, SNMP v2c and SNMP v3 using both IPv4 and IPv6. 
3 3
 Name:		net-snmp   
4 4
 Version:	5.7.3
5
-Release:	1%{?dist}
5
+Release:	2%{?dist}
6 6
 License:	BSD (like)  
7 7
 URL:		http://net-snmp.sourceforge.net/
8 8
 Group:		Productivity/Networking/Other
... ...
@@ -10,8 +10,9 @@ Vendor:		VMware, Inc.
10 10
 Distribution:	Photon
11 11
 Source0:	http://sourceforge.net/projects/%{name}/files/%{name}/%{version}/%{name}-%{version}.tar.gz
12 12
 %define sha1 net-snmp=97dc25077257680815de44e34128d365c76bd839
13
-BuildRequires: openssl-devel perl
14
-Requires:	perl
13
+Patch1: 	net-snmp-5.7.2-systemd.patch
14
+BuildRequires:	openssl-devel perl systemd
15
+Requires:	perl systemd
15 16
 %description
16 17
  Net-SNMP is a suite of applications used to implement SNMP v1, SNMP v2c and SNMP v3 using both IPv4 and IPv6.
17 18
 
... ...
@@ -25,6 +26,7 @@ The net-snmp-devel package contains headers and libraries for building SNMP appl
25 25
 
26 26
 %prep
27 27
 %setup -q
28
+%patch1 -p1
28 29
 
29 30
 %build
30 31
 ./configure --prefix=%{_prefix} \
... ...
@@ -37,6 +39,7 @@ The net-snmp-devel package contains headers and libraries for building SNMP appl
37 37
 		--with-persistent-directory=/var/lib/net-snmp \
38 38
 		--with-sys-contact="root@localhost" \
39 39
 		--with-defaults \
40
+		--with-systemd \
40 41
 		--disable-static \
41 42
 		--with-x=no \
42 43
 		--enable-as-needed
... ...
@@ -44,6 +47,48 @@ make
44 44
 
45 45
 %install
46 46
 make install DESTDIR=%{buildroot}
47
+mkdir -p %{buildroot}/lib/systemd/system
48
+cat << EOF >> %{buildroot}/lib/systemd/system/snmpd.service
49
+[Unit]
50
+Description=Simple Network Management Protocol (SNMP) Daemon.
51
+After=syslog.target network.target
52
+
53
+[Service]
54
+Type=notify
55
+ExecStart=/usr/sbin/snmpd -LS0-6d -f
56
+ExecReload=/bin/kill -HUP $MAINPID
57
+
58
+[Install]
59
+WantedBy=multi-user.target
60
+EOF
61
+
62
+cat << EOF >> %{buildroot}/lib/systemd/system/snmptrapd.service
63
+[Unit]
64
+Description=Simple Network Management Protocol (SNMP) Trap Daemon.
65
+After=syslog.target network.target
66
+
67
+[Service]
68
+Type=notify
69
+ExecStart=/usr/sbin/snmptrapd -Lsd -f
70
+ExecReload=/bin/kill -HUP $MAINPID
71
+
72
+[Install]
73
+WantedBy=multi-user.target
74
+EOF
75
+
76
+%post
77
+/sbin/ldconfig
78
+%systemd_post snmpd.service
79
+%systemd_post snmptrapd.service
80
+
81
+%preun
82
+%systemd_preun snmpd.service
83
+%systemd_preun snmptrapd.service
84
+
85
+%postun
86
+/sbin/ldconfig
87
+%systemd_postun_with_restart snmpd.service
88
+%systemd_postun_with_restart snmptrapd.service
47 89
 
48 90
 %clean
49 91
 rm -rf %{buildroot}/*
... ...
@@ -51,6 +96,8 @@ rm -rf %{buildroot}/*
51 51
 %files
52 52
 %doc COPYING NEWS README ChangeLog
53 53
 %defattr(-,root,root)
54
+/lib/systemd/system/snmpd.service
55
+/lib/systemd/system/snmptrapd.service
54 56
 %{_bindir}
55 57
 %{_libdir}/*.so.*
56 58
 /sbin/* 
... ...
@@ -64,5 +111,7 @@ rm -rf %{buildroot}/*
64 64
 %{_datadir}
65 65
 
66 66
 %changelog
67
+*	Wed May 04 2016 Nick Shi <nshi@vmware.com> 5.7.3-2
68
+-	Add snmpd and snmptrapd to systemd service.
67 69
 *	Mon Nov 30 2015 Harish Udaiya Kumar <hudaiyakumar@vmware.com> 5.7.3-1
68 70
 -	Initial build.	First version