Fedora 28 support (#1820)
authorBrenden Blanco <bblanco@gmail.com>
Mon, 23 Jul 2018 15:15:56 +0000 (08:15 -0700)
committeryonghong-song <ys114321@gmail.com>
Mon, 23 Jul 2018 15:15:56 +0000 (08:15 -0700)
* tools: use printb for more python3 compat

Switch to printb in killsnoop and wakeuptime

* tests: use subproceess sleep to trigger test

In some python implementations, time.sleep uses select instead of
nanosleep and hence won't trigger the bpf kprobe.

* tools: remove explicit python3 shebang

Use an ambiguous python invocation in the shebang line. Instead, rely on
packaging stage to mangle the line to specify a python version.

* cmake: add ENABLE_LLVM_SHARED option

This adds an option to specify that only the dynamic libraries should be
used to link bcc. This is most likely to be used in systems that don't
build/provide the llvm-static and clang-static package options
(fedora-based).

* rpm: enable llvm_shared and python3 build options

Enable rpm packaging with two new features:
 - shared-only packaging (no static linking)
 - python3
To enable these build features (off by default), run:
 RPM_WITH_OPTS="--with llvm_shared --with python3" ./scripts/build-rpm.sh

* rpm: protect python3-bcc package declaration

Don't define python3-bcc if --with python3 isn't explicitly specified.

* specs: only build python3 if requested

* man: compress man pages

* specs: enable python3 by default in fc28+/rh8+

- Enable llvm_shared and python3 --with options by default in new fedora
- Fix string quoting
- Update spec changelog

CMakeLists.txt
SPECS/bcc.spec
cmake/clang_libs.cmake
man/man8/CMakeLists.txt
scripts/build-rpm.sh
tests/python/test_array.py
tools/inject.py
tools/killsnoop.py
tools/wakeuptime.py

index 9bc2441..f9e38f7 100644 (file)
@@ -16,6 +16,7 @@ include(GNUInstallDirs)
 include(CheckCXXCompilerFlag)
 include(cmake/FindCompilerFlag.cmake)
 
+option(ENABLE_LLVM_SHARED "Enable linking LLVM as a shared library" OFF)
 option(ENABLE_CLANG_JIT "Enable Loading BPF through Clang Frontend" ON)
 option(ENABLE_USDT "Enable User-level Statically Defined Tracing" ON)
 CMAKE_DEPENDENT_OPTION(ENABLE_CPP_API "Enable C++ API" ON "ENABLE_USDT" OFF)
index 0155041..f74bb61 100644 (file)
@@ -5,6 +5,31 @@
 %else
 %{!?with_lua: %global with_lua 1}
 %endif
+
+# use --with shared to only link against libLLVM.so
+%if 0%{?fedora} >= 28 || 0%{?rhel} > 7
+%bcond_without llvm_shared
+%else
+%bcond_with llvm_shared
+%endif
+
+# Build python3 support for distributions that have it
+%if 0%{?fedora} >= 28 || 0%{?rhel} > 7
+%bcond_without python3
+%else
+%bcond_with python3
+%endif
+
+%if %{with python3}
+%global __python %{__python3}
+%global python_bcc python3-bcc
+%global python_cmds python2;python3
+%else
+%global __python %{__python2}
+%global python_bcc python2-bcc
+%global python_cmds python2
+%endif
+
 %define debug_package %{nil}
 
 Name:           bcc
@@ -20,12 +45,18 @@ Source0:        bcc.tar.gz
 ExclusiveArch: x86_64 ppc64 aarch64 ppc64le
 BuildRequires: bison cmake >= 2.8.7 flex make
 BuildRequires: gcc gcc-c++ python2-devel elfutils-libelf-devel-static
+%if %{with python3}
+BuildRequires: python3-devel
+%endif
 %if %{with_lua}
 BuildRequires: luajit luajit-devel
 %endif
 %if %{without local_clang_static}
-BuildRequires: llvm-devel llvm-static
+BuildRequires: llvm-devel
 BuildRequires: clang-devel
+%if %{without llvm_shared}
+BuildRequires: llvm-static
+%endif
 %endif
 BuildRequires: pkgconfig ncurses-devel
 
@@ -48,13 +79,19 @@ mkdir build
 pushd build
 cmake .. -DREVISION_LAST=%{version} -DREVISION=%{version} \
       -DCMAKE_INSTALL_PREFIX=/usr \
-      %{?lua_config}
+      %{?lua_config} \
+      -DPYTHON_CMD="%{python_cmds}" \
+      %{?with_llvm_shared:-DENABLE_LLVM_SHARED=1}
 make %{?_smp_mflags}
 popd
 
 %install
 pushd build
 make install/strip DESTDIR=%{buildroot}
+# mangle shebangs
+find %{buildroot}/usr/share/bcc/{tools,examples} -type f -exec \
+    sed -i -e '1 s|^#!/usr/bin/python$|#!'%{__python}'|' \
+           -e '1 s|^#!/usr/bin/env python$|#!'%{__python}'|' {} \;
 
 %package -n libbcc
 Summary: Shared Library for BPF Compiler Collection (BCC)
@@ -62,12 +99,22 @@ Requires: elfutils-libelf
 %description -n libbcc
 Shared Library for BPF Compiler Collection (BCC)
 
-%package -n python-bcc
-Summary: Python bindings for BPF Compiler Collection (BCC)
+%package -n python2-bcc
+Summary: Python2 bindings for BPF Compiler Collection (BCC)
 Requires: libbcc = %{version}-%{release}
-%description -n python-bcc
+%{?python_provide:%python_provide python2-bcc}
+%description -n python2-bcc
 Python bindings for BPF Compiler Collection (BCC)
 
+%if %{with python3}
+%package -n python3-bcc
+Summary: Python3 bindings for BPF Compiler Collection (BCC)
+Requires: libbcc = %{version}-%{release}
+%{?python_provide:%python_provide python3-bcc}
+%description -n python3-bcc
+Python bindings for BPF Compiler Collection (BCC)
+%endif
+
 %if %{with_lua}
 %package -n bcc-lua
 Summary: Standalone tool to run BCC tracers written in Lua
@@ -78,7 +125,7 @@ Standalone tool to run BCC tracers written in Lua
 
 %package -n libbcc-examples
 Summary: Examples for BPF Compiler Collection (BCC)
-Requires: python-bcc = %{version}-%{release}
+Requires: %{python_bcc} = %{version}-%{release}
 %if %{with_lua}
 Requires: bcc-lua = %{version}-%{release}
 %endif
@@ -87,7 +134,7 @@ Examples for BPF Compiler Collection (BCC)
 
 %package -n bcc-tools
 Summary: Command line tools for BPF Compiler Collection (BCC)
-Requires: python-bcc = %{version}-%{release}
+Requires: %{python_bcc} = %{version}-%{release}
 %description -n bcc-tools
 Command line tools for BPF Compiler Collection (BCC)
 
@@ -95,8 +142,13 @@ Command line tools for BPF Compiler Collection (BCC)
 /usr/lib64/*
 /usr/include/bcc/*
 
-%files -n python-bcc
-%{python_sitelib}/bcc*
+%files -n python2-bcc
+%{python2_sitelib}/bcc*
+
+%if %{with python3}
+%files -n python3-bcc
+%{python3_sitelib}/bcc*
+%endif
 
 %if %{with_lua}
 %files -n bcc-lua
@@ -122,6 +174,11 @@ Command line tools for BPF Compiler Collection (BCC)
 %postun -n libbcc -p /sbin/ldconfig
 
 %changelog
+* Wed Jul 18 2018 Brenden Blanco <bblanco@gmail.com> - 0.6.0-1
+- Make python3 the default when possible
+- Add with llvm_shared conditional
+- Add python2/python3 package targets
+
 * Mon Nov 21 2016 William Cohen <wcohen@redhat.com> - 0.2.0-1
 - Revise bcc.spec to address rpmlint issues and build properly in Fedora koji.
 
index cf1b10f..af6604f 100644 (file)
@@ -1,3 +1,6 @@
+if(ENABLE_LLVM_SHARED)
+set(llvm_libs "LLVM")
+else()
 set(llvm_raw_libs bitwriter bpfcodegen debuginfodwarf irreader linker
   mcjit objcarcopts option passes nativecodegen lto)
 list(FIND LLVM_AVAILABLE_LIBS "LLVMCoverage" _llvm_coverage)
@@ -14,6 +17,7 @@ if (${LLVM_PACKAGE_VERSION} VERSION_EQUAL 6 OR ${LLVM_PACKAGE_VERSION} VERSION_G
 endif()
 llvm_map_components_to_libnames(_llvm_libs ${llvm_raw_libs})
 llvm_expand_dependencies(llvm_libs ${_llvm_libs})
+endif()
 
 # order is important
 set(clang_libs
index ce74859..718c700 100644 (file)
@@ -1,2 +1,12 @@
+find_program(GZIP gzip)
 file(GLOB FILES *.8)
-install(FILES ${FILES} DESTINATION share/bcc/man/man8)
+set(GZFILES "")
+foreach(FIL ${FILES})
+  get_filename_component(NAME ${FIL} NAME)
+  add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.gz
+    COMMAND ${GZIP} -c ${FIL} > ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.gz
+    DEPENDS ${FIL})
+  list(APPEND GZFILES "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.gz")
+endforeach()
+add_custom_target(man ALL DEPENDS ${GZFILES})
+install(FILES ${GZFILES} DESTINATION share/bcc/man/man8)
index 23002dc..0616501 100755 (executable)
@@ -24,7 +24,7 @@ sed \
   SPECS/bcc.spec > $TMP/SPECS/bcc.spec
 
 pushd $TMP
-rpmbuild --define "_topdir `pwd`" -ba SPECS/bcc.spec
+rpmbuild $RPM_WITH_OPTS --define "_topdir `pwd`" -ba SPECS/bcc.spec
 popd
 
 cp $TMP/RPMS/*/*.rpm .
index eb8712b..d5e1aee 100755 (executable)
@@ -66,7 +66,7 @@ int do_sys_nanosleep(void *ctx) {
         b.attach_kprobe(event=b.get_syscall_fnname("nanosleep"),
                         fn_name="do_sys_nanosleep")
         b["events"].open_perf_buffer(cb, lost_cb=lost_cb)
-        time.sleep(0.1)
+        subprocess.call(['sleep', '0.1'])
         b.perf_buffer_poll()
         self.assertGreater(self.counter, 0)
         b.cleanup()
index 2f7d2f1..031679b 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # This script generates a BPF program with structure inspired by trace.py. The
 # generated program operates on PID-indexed stacks. Generally speaking,
index 6022cd0..89ea5cd 100755 (executable)
@@ -14,6 +14,7 @@
 
 from __future__ import print_function
 from bcc import BPF
+from bcc.utils import ArgString, printb
 import argparse
 from time import strftime
 import ctypes as ct
@@ -138,8 +139,8 @@ def print_event(cpu, data, size):
     if (args.failed and (event.ret >= 0)):
         return
 
-    print("%-9s %-6d %-16s %-4d %-6d %d" % (strftime("%H:%M:%S"),
-        event.pid, event.comm.decode(), event.sig, event.tpid, event.ret))
+    printb(b"%-9s %-6d %-16s %-4d %-6d %d" % (strftime("%H:%M:%S"),
+        event.pid, event.comm, event.sig, event.tpid, event.ret))
 
 # loop with callback to print_event
 b["events"].open_perf_buffer(print_event)
index cf0ca7d..7254594 100755 (executable)
@@ -12,6 +12,7 @@
 
 from __future__ import print_function
 from bcc import BPF
+from bcc.utils import printb
 from time import sleep, strftime
 import argparse
 import signal
@@ -206,17 +207,17 @@ while (1):
         if folded:
             # print folded stack output
             line = \
-                [k.waker.decode()] + \
+                [k.waker] + \
                 [b.ksym(addr)
                     for addr in reversed(list(waker_kernel_stack))] + \
-                [k.target.decode()]
-            print("%s %d" % (";".join(line), v.value))
+                [k.target]
+            printb(b"%s %d" % (b";".join(line), v.value))
         else:
             # print default multi-line stack output
-            print("    %-16s %s" % ("target:", k.target.decode()))
+            printb(b"    %-16s %s" % (b"target:", k.target))
             for addr in waker_kernel_stack:
-                print("    %-16x %s" % (addr, b.ksym(addr)))
-            print("    %-16s %s" % ("waker:", k.waker.decode()))
+                printb(b"    %-16x %s" % (addr, b.ksym(addr)))
+            printb(b"    %-16s %s" % (b"waker:", k.waker))
             print("        %d\n" % v.value)
     counts.clear()