SNMP sysObjectID not translated when using Python3 easysnmp module - python-3.x

When I query SNMP sysObjectID using easysnmp module, then returned value is in numerical notation:
$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from easysnmp import Session
>>> session = Session(hostname="r1", community='public', version=2)
>>> session.get('sysObjectID.0')
<SNMPVariable value='.1.3.6.1.4.1.2636.1.1.1.2.21' (oid='sysObjectID', oid_index='0', snmp_type='OBJECTID')>
>>>
However, this does not seem to be because easysnmp is not able to find the correct MIB file. When I put the commands above into a file and execute it with strace, then correct MIB is accessed:
$ strace 2>&1 -f -e open python3 snmp_test.py | grep mib-jnx-chas-defines.txt
open("/usr/share/snmp/mibs/JuniperMibs_from_Juniper/mib-jnx-chas-defines.txt", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOTDIR (Not a directory)
open("/usr/share/snmp/mibs/JuniperMibs_from_Juniper/mib-jnx-chas-defines.txt", O_RDONLY) = 4
open("/usr/share/snmp/mibs/JuniperMibs_from_Juniper/mib-jnx-chas-defines.txt", O_RDONLY) = 3
$
I can double-check this using snmpget:
$ snmpget -v 2c -c public r1 sysObjectID.0
SNMPv2-MIB::sysObjectID.0 = OID: JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameMX960
$ strace 2>&1 -f -e open snmpget -v 2c -c public r1 sysObjectID.0 | grep mib-jnx-chas-defines.txt
open("/usr/share/snmp/mibs/JuniperMibs_from_Juniper/mib-jnx-chas-defines.txt", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOTDIR (Not a directory)
open("/usr/share/snmp/mibs/JuniperMibs_from_Juniper/mib-jnx-chas-defines.txt", O_RDONLY) = 4
open("/usr/share/snmp/mibs/JuniperMibs_from_Juniper/mib-jnx-chas-defines.txt", O_RDONLY) = 3
$
Still, just to be sure, I set the os.environ['MIBDIRS'], os.environ['MIBS'] and os.environ['PREFIX'] to same values as I see when I execute the snmpget -Dinit_mib -m ALL -v 2c -c public r1 sysObjectID.0 command, but this does not help either.
What might cause this?

This is because the value at the OID sysObjectID.0 is just being treated as a value. It looks like the use_sprint_value option enables the extra formatting on the return value:
>>> session = Session(hostname="abc", community='public', version=2, use_long_names=True, use_sprint_value=True)
>>> session.get('sysObjectID.0')
<SNMPVariable value='.iso.org.dod.internet.private.enterprises.2435.2.3.9.1' (oid='.iso.org.dod.internet.mgmt.mib-2.system.sysObjectID', oid_index='0', snmp_type='OBJECTID')>
Clearly the use_long_names option is also helpful to show the expanded name, though I don't have all the MIBs required to decode this example.

Related

Check cuda version in bash scripts

Basically, I want to achieve a version control on CUDA, similar to this:
if python3 -c 'import sys; assert sys.version_info == (3,8)' > /dev/null
then
exit;
fi
In my case, the CUDA version shown by ncvv -V must be >=11.3
according to this answer we could get cuda version via:
CUDA_VERSION=$(nvcc --version | sed -n 's/^.*release \([0-9]\+\.[0-9]\+\).*$/\1/p')
from the output of nvcc -V, in which the version is given after the key word "release":
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Sun_Mar_21_19:15:46_PDT_2021
Cuda compilation tools, release 11.3, V11.3.58
Build cuda_11.3.r11.3/compiler.29745058_0
But I am having trouble on further comparing the version with 11.3
I figured out a solution via python:
import os,re
b = os.popen('nvcc -V').readlines()
>>> b
['nvcc: NVIDIA (R) Cuda compiler driver\n', 'Copyright (c) 2005-2021 NVIDIA Corporation\n', 'Built on Sun_Mar_21_19:15:46_PDT_2021\n', 'Cuda compilation tools, release 11.3, V11.3.58\n', 'Build cuda_11.3.r11.3/compiler.29745058_0\n']
b = str(b)
c = re.findall(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}",b)
>>> c[0]
'11.3.58'
cc = c[0].split(".")
>>> cc
['11', '3', '58']
>>> [int(x) for x in cc] >[11,3,0]
True
>>> [int(x) for x in cc] >[11,4,0]
False
>>> [int(x) for x in cc] >[8,4,0]
True
>>> [int(x) for x in cc] >[8,314,0]
True
to sum up:
#!/usr/bin/env bash
if python3 -c 'import os,re; assert [int(x) for x in re.findall(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", str(os.popen("nvcc -V").readlines()))[0].split(".")] >[11,3,0]'> /dev/null
then
echo '11'
else
echo '22'
fi
Awk will allow you to deal with the decimal places:
nvcc --version | awk '/V([0-9]+.){2}.[0-9]+$/ { sub("V","",$NF);if ($NF>11.3) { exit 0 } else { exit 1 } }'
Run the output of the nvcc command into awk and then process lines with V followed by any number of digits, a full stop (2 times) and then any number of digits followed by an end of line (this regular expression may need amending for your use case)
Processing the resulting line, we take the last field and remove the "V" using awk's sub function. We then compare the new field to see whether it is greater than 11.3. If it is exit with 0, otherwise exit with 1.
Finally, within your script, you can utilise the command result with:
if $(nvcc --version | awk '/V([0-9]+.){2}.[0-9]+$/ { sub("V","",$NF);if ($NF>11.3) { exit 0 } else { exit 1 } }')
then
exit
fi
nvcc --version | mawk 'NF*=/ release /' OFS='\f' FS='^.+[Vv]|[.]'
11
3
58
and this solution is very adaptable to other version number scenarios too - say i wanna extract out the xnu version (i.e. very-core-macos) out :
# this is one single line, re-formatted for readability
Darwin 21.6.0 Darwin Kernel Version 21.6.0: Sat Jun 18 17:07:22 PDT 2022;
root:xnu-8020.140.41~1/RELEASE_ARM64_T6000 arm64 arm
uname -mprsv |
mawk 'NF*=/[:]xnu[-]/' OFS='\f' FS='^.+[:]xnu[-]|[.~]|[/].+$'
8020
140
41
1

fortran: Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2))

I am a beginner of Fortran and running a model written by Fortran. When I tried to compile it, I got an error message like:
libtool: link: (cd ".libs" && rm -f "libgrib_api_f77.so" && ln -s "libgrib_api_f77.so.1.0.0" "libgrib_api_f77.so")
libtool: link: ar cru .libs/libgrib_api_f77.a grib_fortran.o grib_f77.o
libtool: link: ranlib .libs/libgrib_api_f77.a
libtool: link: ( cd ".libs" && rm -f "libgrib_api_f77.la" && ln -s "../libgrib_api_f77.la" "libgrib_api_f77.la" )
gfortran -c -o same_int_long.o same_int_long.f90
same_int_long.f90:23:18:
17 | call check_long(x2(1),x2(2),ret)
| 2
......
23 | call check_long(x4(1),x4(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/INTEGER(2)).
same_int_long.f90:29:18:
17 | call check_long(x2(1),x2(2),ret)
| 2
......
29 | call check_long(x8(1),x8(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)).
same_int_long.f90:51:17:
45 | call check_int(x2(1),x2(2),ret)
| 2
......
51 | call check_int(x4(1),x4(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/INTEGER(2)).
same_int_long.f90:57:17:
45 | call check_int(x2(1),x2(2),ret)
| 2
......
57 | call check_int(x8(1),x8(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)).
make[2]: *** [Makefile:546: same_int_long.o] Error 1
make[2]: Leaving directory '/gpfs/home3/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source/fortran'
make[1]: *** [Makefile:604: all-recursive] Error 1
make[1]: Leaving directory '/gpfs/home3/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source'
make: *** [Makefile:398: /home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source-LXgfortran/include/grib_api.mod] Error 2
What I did is basically following the installation of the model:
Step1
(base) [eccei339#int3 ~]$ mkdir snellius_surfex
(base) [eccei339#int3 ~]$ cp open_surfex_v8_1_20200107.tar-2.gz snellius_surfex/
(base) [eccei339#int3 ~]$ cd snellius_surfex/
(base) [eccei339#int3 snellius_surfex]$ tar zxvf open_surfex_v8_1_20200107.tar-2.gz
…(omit the tar zxvf logging information)
Step 2: some essential env variable
(base) [eccei339#int3 snellius_surfex]$ export VER_MPI="NOMPI"
(base) [eccei339#int3 snellius_surfex]$ export OMP_NUM_THREADS=1
(base) [eccei339#int3 snellius_surfex]$ module load 2021
(base) [eccei339#int3 snellius_surfex]$ module load GCC/10.3.0
(base) [eccei339#int3 snellius_surfex]$ ls
open_SURFEX_V8_1 open_surfex_v8_1_20200107.tar-2.gz
(here I exported some necessary envi var following the instructions of installation of the software)
Step 3: configure
(base) [eccei339#int3 snellius_surfex]$ cd open_SURFEX_V8_1/src/
(base) [eccei339#int3 src]$ ls
ASSIM Makefile Rules.bullXI15.mk Rules.MCgfortran.mk SURFEX
configure Makefile.SURFEX.mk Rules.bullXI16.mk Rules.SX8.mk
FORC OFFLIN Rules.LXgfortran.mk Rules.zgfortran.mk
include Rules.AIX64.mk Rules.LXifort.mk Rules.zifort.mk
LIB Rules.bgfortran.mk Rules.LXpgi.mk scripts
(base) [eccei339#int3 src]$ ./configure
(omit the long logging info of the “configure” command)
(base) [eccei339#int3 src]$ . ../conf/profile_surfex-LXgfortran-SFX-V8-1-1-NOMPI-OMP-O2-X0
(an essential step following the instructions of installation of the software)
Step 4: make the master
(base) [eccei339#int3 src]$ make
find: ‘/home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/dir_obj-LXgfortran-SFX-V8-1-1-NOMPI-OMP-O2-X0/MASTER’: No such file or directory
cd /home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source && LDFLAGS= FCFLAGS= CPPFLAGS="" \
./configure --disable-jpeg --prefix=/home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source-LXgfortran FC="gfortran" && \
make -j 1 clean && \
make -j 1 && \
make -j 1 install && \
make -j 1 clean
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking how to print strings... printf
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
(omit the long logging information, and the final lines are the error message shown in the beginning of this question description.)
I searched the Internet that this could be due to the GCC 10 is more strict than older GCC (I compiled this model last year with older GCC and made it, but failed this time because our server is transferred to a new system, thus the GCC is upgraded from older version to a new version). Some information from Google said that I could add something like this:
export FCFLAGS="-w -fallow-argument-mismatch -O2"
export FFLAGS="-w -fallow-argument-mismatch -O2"
But I tried it in the step 2 where I export some essential environmental variables, it still does not work. So I am wondering is there anybody who can help me? Thanks a lot!
Updates: the source code of grib_api-1.17.0-Source/fortran/same_int_long.f90 from http://distfiles.macports.org/grib_api/ is as following:
! Copyright 2005-2016 ECMWF.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
!
! In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
! virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
integer function kind_of_long()
integer(2), dimension(2) :: x2 = (/1, 2/)
integer(4), dimension(2) :: x4 = (/1, 2/)
integer(8), dimension(2) :: x8 = (/1, 2/)
character(len=1) :: ret
kind_of_long=-1
call check_long(x2(1),x2(2),ret)
if (ret == 't') then
kind_of_long=2
return
endif
call check_long(x4(1),x4(2),ret)
if (ret == 't') then
kind_of_long=4
return
endif
call check_long(x8(1),x8(2),ret)
if (ret == 't') then
kind_of_long=8
return
endif
end function kind_of_long
integer function kind_of_int()
integer(2), dimension(2) :: x2 = (/1, 2/)
integer(4), dimension(2) :: x4 = (/1, 2/)
integer(8), dimension(2) :: x8 = (/1, 2/)
character(len=1) :: ret
kind_of_int=-1
call check_int(x2(1),x2(2),ret)
if (ret == 't') then
kind_of_int=2
return
endif
call check_int(x4(1),x4(2),ret)
if (ret == 't') then
kind_of_int=4
return
endif
call check_int(x8(1),x8(2),ret)
if (ret == 't') then
kind_of_int=8
return
endif
end function kind_of_int
program same_int_long
integer ki,kl
ki=kind_of_int()
kl=kind_of_long()
if (ki /= kl) then
write (*,'(i1)') 0
else
write (*,'(i1)') 1
endif
end program same_int_long
Here is the full log information of make: https://drive.google.com/file/d/14rkj2ay39Rv84QBL6UDiSdlIAfhuEt_z/view?usp=sharing
This appened to me with a MPI fortran code. The cause is a decision from gcc developpers on what should be «good interfaces» see here.
Two solutions in my case :
Tells gfortran to ignore this concerns with option -fallow-argument-mismatch.
Use modern fortran interface (use mpi instead of include mpif.h)
I chose the latter.
What you are instantiating as an INTEGER is getting its value assigned by another (variable or declaration) integer of a different "byte" memory storage size.
e.g. in other languages int is 4 bytes and long is 8 bytes. (note) Fortran also has pointers alike C/C++
https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vna5/index.html
nb: You did not show the code that has the problem , somewhere around line 29 char 18 in source file same_int_long.f90 ??

A function declared with __attribute__((constructor)) is invoked more than once with LD_PRELOAD

Define a shared library as follows:
#include <unistd.h>
#include <stdio.h>
static void init(void) __attribute__((constructor));
static void init(void)
{
fprintf(stderr, "pid=%u\n", (unsigned) getpid());
}
Build using GCC 10 on an AMD64 machine:
gcc -shared -fPIC lib.c
Run a trivial process to validate:
$ LD_PRELOAD=`realpath a.out` ls
pid=15771
a.out lib.c
The line pid=15771 is printed by init() as expected.
Now, repeat with a complex process that spawns children and threads:
$ LD_PRELOAD=`realpath a.out` python3
pid=15835
pid=15835
pid=15835
pid=15835
pid=15839
pid=15844
pid=15835
pid=15835
pid=15846
pid=15846
pid=15847
pid=15847
pid=15849
pid=15849
pid=15851
pid=15852
pid=15853
pid=15853
pid=15856
pid=15857
pid=15857
pid=15858
pid=15858
pid=15861
pid=15862
pid=15862
pid=15865
pid=15868
pid=15835
Python 3.8.2 (default, Apr 19 2020, 18:33:14)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Observe that there are repeated entries like pid=15835, which indicates that init() has been executed more than once for some of the processes.
Why?
Your Python installation executes some programs when the Python interpreter is launched. If a process image is replaced using execve, the process ID does not change, but constructors run for the new process image.
A simpler example looks like this:
$ LD_PRELOAD=`realpath a.out` bash -c 'exec /bin/true'
You can see more details by invoking strace:
$ strace -f -E LD_PRELOAD=`realpath a.out` -eexecve bash -c 'exec /bin/true'
execve("/usr/bin/bash", ["bash", "-c", "exec /bin/true"], 0x55b275d8b830 /* 29 vars */) = 0
pid=801315
execve("/bin/true", ["/bin/true"], 0x5564dedbeb80 /* 29 vars */) = 0
pid=801315
+++ exited with 0 +++

Computing offset of a function in memory

I am reading documentation for a uprobe tracer and there is a instruction how to compute offset of a function in memory. I am quoting it here.
Following example shows how to dump the instruction pointer and %ax
register at the probed text address. Probe zfree function in /bin/zsh:
# cd /sys/kernel/debug/tracing/
# cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
# objdump -T /bin/zsh | grep -w zfree
0000000000446420 g DF .text 0000000000000012 Base zfree
0x46420 is the offset of zfree in object /bin/zsh that is loaded at
0x00400000.
I do not know why, but they took output 0x446420 and subtracted 0x400000 to get 0x46420. It seamed as an error to me. Why 0x400000?
I have tried to do the same on my Fedora 23 with 4.5.6-200 kernel.
First I turned off memory address randomization
echo 0 > /proc/sys/kernel/randomize_va_space
Then I figured out where binary is in memory
$ cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
555555554000-55555560f000 r-xp 00000000 fd:00 2387155 /usr/bin/zsh
Took the offset
marko#fedora:~ $ objdump -T /bin/zsh | grep -w zfree
000000000005dc90 g DF .text 0000000000000012 Base zfree
And figured out where zfree is via gdb
$ gdb -p 21067 --batch -ex 'p zfree'
$1 = {<text variable, no debug info>} 0x5555555b1c90 <zfree>
marko#fedora:~ $ python
Python 2.7.11 (default, Mar 31 2016, 20:46:51)
[GCC 5.3.1 20151207 (Red Hat 5.3.1-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hex(0x5555555b1c90-0x555555554000)
'0x5dc90'
You see, I've got the same result as in objdump without subtracting anything.
But then I tried the same on another machine with SLES and there it's the same as in uprobe documentation.
Why is there such a difference? How do I compute correct offset then?
As far as I see the difference may be caused only by the way how examined binary was built. Saying more precisely - if ELF has fixed load address or not. Lets do simple experiment. We have simple test code:
int main(void) { return 0; }
Then, build it in two ways:
$ gcc -o t1 t.c # create image with fixed load address
$ gcc -o t2 t.c -pie # create load-base independent image
Now, lets check load base addresses for these two images:
$ readelf -l --wide t1 | grep LOAD
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x00067c 0x00067c R E 0x200000
LOAD 0x000680 0x0000000000600680 0x0000000000600680 0x000228 0x000230 RW 0x200000
$ readelf -l --wide t2 | grep LOAD
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0008cc 0x0008cc R E 0x200000
LOAD 0x0008d0 0x00000000002008d0 0x00000000002008d0 0x000250 0x000258 RW 0x2000
Here you can see that first image requires fixed load address - 0x400000, and the second one has no address requirements at all.
And now we can compare addresses that objdump tells about main:
$ objdump -t t1 | grep ' main'
00000000004004b6 g F .text 000000000000000b main
$ objdump -t t2 | grep ' main'
0000000000000710 g F .text 000000000000000b main
As we see, the address is a complete virtual address that first byte of main will occupy if image is loaded at address, stored in program header. And of course the second image never won't be loaded at 0x0 but instead at another, randomly chosen location, that will offset real function position.

node.js filesystem mangles Cygwin drive name

I recently installed Cygwin64 after using Cygwin32 for quite some time and I'm now having problems with one of our production scripts. Node.js's 'readFileSync' seems to be prepending the windows drive letter to the path and then failing to resolve - e.g. /cygdrive/c/foo becomes c:/cygdrive/c/foo.
I've found various mentions of similar issues online but so far I've been unable to resolve this problem. My co-worker has a seemingly identical setup and does not experience the problem.
Here it is in a nutshell -
$ cat filetest.js
var fs = require('fs');
function main(argv) {
console.log("fileName => ", argv[2]);
var data = fs.readFileSync(argv[2], 'utf8');
console.log("success");
}
main(process.argv);
$ s/node filetest.js filetest.js
fileName => filetest.js
success
$ ls -l /cygdrive/c/temp/Test.txt
----rwx---+ 1 bdodd Domain Users 14 Jun 3 14:12 /cygdrive/c/temp/Test.txt
$ s/node filetest.js /cygdrive/c/temp/Test.txt
fileName => /cygdrive/c/temp/Test.txt
fs.js:338
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
^
Error: ENOENT, no such file or directory 'C:\cygdrive\c\temp\Test.txt'
and just for completeness...
$ cat /etc/fstab
# /etc/fstab
#
# This file is read once by the first process in a Cygwin process tree.
# To pick up changes, restart all Cygwin processes. For a description
# see https://cygwin.com/cygwin-ug-net/using.html#mount-table
# This is default anyway:
none /cygdrive cygdrive binary,posix=0,user 0 0
$ cd /cygdrive/
$ ls -l
total 40
d---rwx---+ 1 NT SERVICE+TrustedInstaller NT SERVICE+TrustedInstaller 0 Jun 3 14:09 c
dr-xrwxr-x 1 Unknown+User Unix_Group+33 0 Apr 29 2014 u
Insight would be greatly appreciated. Thanks!

Resources