Bug 1624879 - The libvirtMib_subagent sends SNMP traps without sysUptime.0
Summary: The libvirtMib_subagent sends SNMP traps without sysUptime.0
Status: VERIFIED
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: libvirt-snmp
Version: 7.5
Hardware: Unspecified
OS: Unspecified
high
medium
Target Milestone: rc
: ---
Assignee: Michal Privoznik
QA Contact: jiyan
URL:
Whiteboard:
Keywords: Upstream, ZStream
Depends On:
Blocks: 1653591
TreeView+ depends on / blocked
 
Reported: 2018-09-03 13:33 UTC by Miguel Martin
Modified: 2019-01-29 09:59 UTC (History)
11 users (show)

(edit)
Prior to this update, the variables sent in the SNMP trap by libvirt-snmp did not conform to the RFC 1905 protocol operations standard. This update fixes the problem.
Clone Of:
: 1653591 (view as bug list)
(edit)
Last Closed:


Attachments (Terms of Use)

Description Miguel Martin 2018-09-03 13:33:00 UTC
Description of problem:

libvirtMib_subagent does not conform RFC1905:
According to [1]:
"The first two variable bindings in the variable binding list of an
 SNMPv2-Trap-PDU are sysUpTime.0 [9] and snmpTrapOID.0 [9]
 respectively."

snmpTrapOID.0 is the first variable binding in src/libvirtNotifications.c code and no sysUptime.0 is sent 

Version-Release number of selected component (if applicable):
libvirt-snmp-0.0.3

Additional info:
[1] https://tools.ietf.org/html/rfc1905#section-4.2.6

A possible patch would be:

diff --git a/src/libvirtNotifications.c b/src/libvirtNotifications.c
index 135f177..29419b7 100644
--- a/src/libvirtNotifications.c
+++ b/src/libvirtNotifications.c
@@ -28,6 +28,7 @@
 #include "libvirtGuestTable_enums.h"
 #include "libvirtSnmpError.h"
 
+static const oid sysuptime_oid[] = { 1, 3, 6, 2, 1, 1, 3, 0 };
 static const oid snmptrap_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
 
 int
@@ -49,6 +50,7 @@ send_libvirtGuestNotif_trap(virDomainPtr dom)
     unsigned char domUUID[VIR_UUID_BUFLEN];
     virDomainInfo info;
     int rowstatus = ROWSTATUS_ACTIVE;
+    u_long uptime = netsnmp_get_agent_uptime();
 
     if (virDomainGetUUID(dom, domUUID) < 0) {
         printLibvirtError("Failed to get domain UUID");
@@ -76,6 +78,15 @@ send_libvirtGuestNotif_trap(virDomainPtr dom)
             break;
     };
 
+    /*
+     * Set the sysUptime.0 value
+     */
+    snmp_varlist_add_variable(&var_list,
+                              sysuptime_oid, OID_LENGTH(sysuptime_oid),
+                              ASN_TIMETICKS,
+                              (u_char*)&uptime,
+                              sizeof(uptime));
+
     /*
      * Set the snmpTrapOid.0 value
      */

Comment 2 Michal Privoznik 2018-09-10 13:41:49 UTC
Pushed upstream:

commit 0ca48c8abe6e29ee0a61f95f67cfc1da0e486b70
Author:     Michal Privoznik <mprivozn@redhat.com>
AuthorDate: Mon Sep 10 15:36:05 2018 +0200
Commit:     Michal Privoznik <mprivozn@redhat.com>
CommitDate: Mon Sep 10 15:36:05 2018 +0200

    Send sysUpTime in traps
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1624879
    
    According to RFC 1905:
    
      The first two variable bindings in the variable binding list of
      an SNMPv2-Trap-PDU are sysUpTime.0 and snmpTrapOID.0
      respectively.
    
    We are setting the snmpTrapOID.0 variable but not sysUpTime.0.
    
    Based on work of: Miguel Martin <mmartinv@redhat.com>
    
    Signed-off-by: Michal Privoznik <mprivozn@redhat.com>

v0.0.3-15-g0ca48c8

Comment 3 jiyan 2018-10-17 05:54:57 UTC
Verifying steps can be checked in https://bugzilla.redhat.com/show_bug.cgi?id=1624839#c7

Comment 4 Michal Privoznik 2018-10-23 10:28:33 UTC
Moving to POST per comment 2.

Comment 6 jiyan 2018-11-12 11:00:07 UTC
Configuration:
1. Install libvirt-snmp, libvirt-snmp-debuginfo, net-snmp net-snmp-libs, net-snmp-utils components
2. Modify "/etc/snmp/snmpd.conf" as following: 
   # cat /etc/snmp/snmpd.conf
   rwcommunity public
   master agentx
   trapcommunity public
   trap2sink localhost
3. Modify "/etc/snmp/snmptrapd.conf" as following: 
   # cat /etc/snmp/snmptrapd.conf 
   authCommunity log,execute,net public 
   logOption f /var/log/snmptraps.log
4. Modify "/etc/sysconfig/snmptrapd" as following: 
   # cat /etc/sysconfig/snmptrapd 
   OPTIONS="-m ALL -p /var/run/snmptrapd.pid"
5. Restart related service
   # systemctl restart snmpd
   # systemctl restart snmptrapd
   # systemctl restart libvirtd

**Host1:**
Version:
**********libvirt-snmp-0.0.3-6.el7.x86_64
kernel-3.10.0-957.el7.x86_64
qemu-kvm-rhev-2.12.0-19.el7_6.2.x86_64
libvirt-4.5.0-10.virtcov.el7_6.3.x86_64

Steps:
1. Run libvirt snmp agent daemon through the following cmd on "Terminal 1"
# LIBVIRT_DEFAULT_URI="qemu:///system" libvirtMib_subagent -f -L -D ALL

2. Run snmpwalk to query domain status on "Terminal 2"
# snmpwalk -m ALL -v 2c -c public -OX localhost libvirtMIB
LIBVIRT-MIB::libvirtGuestName[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = STRING: "test1"
LIBVIRT-MIB::libvirtGuestState[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = INTEGER: running(1)
LIBVIRT-MIB::libvirtGuestCpuCount[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = Gauge32: 1
LIBVIRT-MIB::libvirtGuestMemoryCurrent[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = Gauge32: 1024
LIBVIRT-MIB::libvirtGuestMemoryLimit[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = Gauge32: 1024
LIBVIRT-MIB::libvirtGuestCpuTime[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = Counter64: 19100000000
LIBVIRT-MIB::libvirtGuestRowStatus[STRING: 15966392-65dc-4306-9dfe-3bd92e641436] = INTEGER: active(1)

which is identical with the output of 'virsh' cmd:
# virsh domstate test1
running

3. Open ths third terminal to check the log
# tail -f  /var/log/messages | grep --line-buffered "localhost [UDP: [127.0.0.1]"

4. Set the status of the domain through 'snmpset' cmd
# snmpset -m ALL -v 2c -c public localhost libvirtGuestState.\'15966392-65dc-4306-9dfe-3bd92e641436\' = paused
LIBVIRT-MIB::libvirtGuestState.'..c.e.C...;..d.6' = INTEGER: paused(3)

Verify the status of domain through 'virsh' cmd:
# virsh list --all
 Id    Name                           State
----------------------------------------------------
 3     test1                          paused

5. Check the log
# tail -f  /var/log/messages | grep --line-buffered "localhost [UDP: [127.0.0.1]"
Nov 12 05:50:22 ibm-x3250m6-05 snmptrapd[16211]: localhost [UDP: [127.0.0.1]:37508->[127.0.0.1]:162]: Trap , DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (6733) 0:01:07.33, SNMPv2-MIB::snmpTrapOID.0 = OID: LIBVIRT-MIB::libvirtGuestNotif, LIBVIRT-MIB::libvirtGuestName.0 = STRING: "test1", LIBVIRT-MIB::libvirtGuestUUID.0 = STRING: 15966392-65dc-4306-9dfe-3bd92e641436, LIBVIRT-MIB::libvirtGuestState.0 = INTEGER: paused(3), LIBVIRT-MIB::libvirtGuestRowStatus.0 = INTEGER: active(1)
Nov 12 05:50:22 ibm-x3250m6-05 snmptrapd[16211]: localhost [UDP: [127.0.0.1]:37508->[127.0.0.1]:162]: Trap , DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (6733) 0:01:07.33, SNMPv2-MIB::snmpTrapOID.0 = OID: LIBVIRT-MIB::libvirtGuestNotif, LIBVIRT-MIB::libvirtGuestName.0 = STRING: "test1", LIBVIRT-MIB::libvirtGuestUUID.0 = STRING: 15966392-65dc-4306-9dfe-3bd92e641436, LIBVIRT-MIB::libvirtGuestState.0 = INTEGER: paused(3), LIBVIRT-MIB::libvirtGuestRowStatus.0 = INTEGER: active(1)


**Host2:**
Version:
**********libvirt-snmp-0.0.3-5.el7.x86_64
libvirt-4.5.0-10.virtcov.el7_6.3.x86_64
qemu-kvm-rhev-2.12.0-19.el7_6.2.x86_64
kernel-3.10.0-957.el7.x86_64

Steps:
1. Run libvirt snmp agent daemon through the following cmd on "Terminal 1"
# LIBVIRT_DEFAULT_URI="qemu:///system" libvirtMib_subagent -f -L -D ALL

2. Run snmpwalk to query domain status on "Terminal 2"
# snmpwalk -m ALL -v 2c -c public -OX localhost libvirtMIB
LIBVIRT-MIB::libvirtGuestName[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = STRING: "test1"
LIBVIRT-MIB::libvirtGuestState[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = INTEGER: running(1)
LIBVIRT-MIB::libvirtGuestCpuCount[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = Gauge32: 1
LIBVIRT-MIB::libvirtGuestMemoryCurrent[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = Gauge32: 1024
LIBVIRT-MIB::libvirtGuestMemoryLimit[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = Gauge32: 1024
LIBVIRT-MIB::libvirtGuestCpuTime[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = Counter64: 7430000000
LIBVIRT-MIB::libvirtGuestRowStatus[STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360] = INTEGER: active(1)

which is identical with the output of 'virsh' cmd:
# virsh domstate test1
running

3. Open ths third terminal to check the log
# tail -f  /var/log/messages | grep --line-buffered "localhost [UDP: [127.0.0.1]"

4. Set the status of the domain through 'snmpset' cmd
# snmpset -m ALL -v 2c -c public localhost libvirtGuestState.\'20ae5bfa-a34c-4246-8f3e-f80096771360\' = paused
LIBVIRT-MIB::libvirtGuestState.' .[..LBF.>...w.`' = INTEGER: paused(3)

Verify the status of domain through 'virsh' cmd:
# virsh list --all
 Id    Name                           State
----------------------------------------------------
 3     test1                          paused

5. Check the log
# tail -f  /var/log/messages | grep --line-buffered "localhost [UDP: [127.0.0.1]"
Nov 12 05:52:42 ibm-x3850x6-03 snmptrapd[24582]: localhost [UDP: [127.0.0.1]:33611->[127.0.0.1]:162]: Trap , DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (8766) 0:01:27.66, SNMPv2-MIB::snmpTrapOID.0 = OID: LIBVIRT-MIB::libvirtGuestNotif, LIBVIRT-MIB::libvirtGuestName.0 = STRING: "test1", LIBVIRT-MIB::libvirtGuestUUID.1 = STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360, LIBVIRT-MIB::libvirtGuestState.2 = INTEGER: paused(3), LIBVIRT-MIB::libvirtGuestRowStatus.3 = INTEGER: active(1)
Nov 12 05:52:42 ibm-x3850x6-03 snmptrapd[24582]: localhost [UDP: [127.0.0.1]:33611->[127.0.0.1]:162]: Trap , DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (8767) 0:01:27.67, SNMPv2-MIB::snmpTrapOID.0 = OID: LIBVIRT-MIB::libvirtGuestNotif, LIBVIRT-MIB::libvirtGuestName.0 = STRING: "test1", LIBVIRT-MIB::libvirtGuestUUID.1 = STRING: 20ae5bfa-a34c-4246-8f3e-f80096771360, LIBVIRT-MIB::libvirtGuestState.2 = INTEGER: paused(3), LIBVIRT-MIB::libvirtGuestRowStatus.3 = INTEGER: active(1)

Hi Michal.
As we have discussed several days ago, in both old version and new version of 'libvirt-snmp', I can see the 'sysUpTimeInstance' info through the log.

But in the new version, the code about the 'sysuptime' is truly added, so I can not distinguish whether 'sysUpTimeInstance' info is generated by the new code.

Comment 7 Michal Privoznik 2018-11-12 13:25:25 UTC
(In reply to jiyan from comment #6)

> Hi Michal.
> As we have discussed several days ago, in both old version and new version
> of 'libvirt-snmp', I can see the 'sysUpTimeInstance' info through the log.
> 
> But in the new version, the code about the 'sysuptime' is truly added, so I
> can not distinguish whether 'sysUpTimeInstance' info is generated by the new
> code.

What we could do is run the agent in stand alone mode and see if it sends the instance uptime. Or maybe previously it was net-snmp code adding it if not found? Jan, you originally wrote this code, any ideas please?

Comment 8 Miguel Martin 2018-11-26 08:32:44 UTC
It looks like the net-snmp code prepends the sysUptime.0 varbind if not present:
~~~
       /*
         * Check the varbind list we've been given.
         * If it starts with a 'sysUptime.0' varbind, then use that.
         * Otherwise, prepend a suitable 'sysUptime.0' varbind.
         */
        if (!snmp_oid_compare( vblist->name,    vblist->name_length,
                               sysuptime_oid, sysuptime_oid_len )) {
            template_v2pdu->variables = vblist;
            trap_vb  = vblist->next_variable;
        } else {
            uptime   = netsnmp_get_agent_uptime();
            var = NULL;
            snmp_varlist_add_variable( &var,
                           sysuptime_oid, sysuptime_oid_len,
                           ASN_TIMETICKS, (u_char*)&uptime, sizeof(uptime));
            if (!var) {
                snmp_log(LOG_WARNING,
                     "send_trap: failed to insert sysUptime varbind\n");
                snmp_free_pdu(template_v2pdu);
                snmp_free_varbind(vblist);
                return -1;
            }
            template_v2pdu->variables = var;
            var->next_variable        = vblist;
            trap_vb  = vblist;
        }
~~~

So it seems the patch is not necessary. :(

Comment 10 jiyan 2018-11-28 07:05:19 UTC
Hi Miguel
So how should we deal with this bug? Should we close this bug OR other solutions?

Comment 12 Miguel Martin 2018-12-03 17:08:27 UTC
(In reply to jiyan from comment #10)
> Hi Miguel
> So how should we deal with this bug? Should we close this bug OR other
> solutions?

Not sure TBH, the bug has all the flags granted and it's not harmful although is not needed.

Michal what do you think?

Comment 13 Michal Privoznik 2018-12-04 07:39:33 UTC
(In reply to Miguel Martin from comment #12)
> (In reply to jiyan from comment #10)
> > Hi Miguel
> > So how should we deal with this bug? Should we close this bug OR other
> > solutions?
> 
> Not sure TBH, the bug has all the flags granted and it's not harmful
> although is not needed.
> 
> Michal what do you think?

Yeah, I think it makes sense to have the patch in. Moreover, if there is a way to run agentx in a standalone mode (it looks like it should be possible but I'm unable to come up with some usable config file for it), then the trapd doesn't add sysUptime right? In that case the agent should do that itself.

Comment 14 jiyan 2018-12-04 07:57:20 UTC
Hi Michal
So Do you think whether the steps in comment 6 are enough to verify this bug?
Or should I do something else?

https://bugzilla.redhat.com/show_bug.cgi?id=1624879#c6

Comment 15 Michal Privoznik 2018-12-04 09:42:01 UTC
(In reply to jiyan from comment #14)
> Hi Michal
> So Do you think whether the steps in comment 6 are enough to verify this bug?
> Or should I do something else?

Yes, they are enough. Thanks.

Comment 16 jiyan 2018-12-05 01:56:19 UTC
According to comment 15, move this bug to be verified.


Note You need to log in before you can comment on or make changes to this bug.