ONOS port on Ubuntu16.10 - levivic/zEcoTest GitHub Wiki

Building ONOS

ONOS (Open Network Operating System) is a software defined networking (SDN) OS for service providers that has scalability, high availability, high performance and abstractions to make it easy to create apps and services. The instructions provided below specify the steps to build ONOS 1.9.0 on IBM Z for Ubuntu 16.10, RHEL 7 and SLES 12 SP 2:

General Note:

  • A directory <source root> will be referred to in these instructions, this is a temporary writable directory anywhere you'd like to place it

Building ONOS 1.9.0

Step 1: Install the dependencies

Install Java 8

Ubuntu:

apt-get update
apt-get install wget openjdk-8-jdk git

RHEL:

yum update
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel wget git

SLES:

zypper update
zypper install -y java-1_8_0-openjdk java-1_8_0-openjdk-devel wget git

Install Maven

Ubuntu:

apt-get install maven

RHEL and SLES: Following https://github.com/linux-on-ibm-z/docs/wiki/Building-Maven, note that you should replace ibm-java with openjdk 8

Install Karaf

cd /<source_root>/
git clone https://github.com/apache/karaf.git
cd karaf
git checkout karaf-3.0.8
export MAVEN_OPTS="-Xms1024m -Xmx4096m -Xss4m"
mvn clean install -DskipTests
cd ..
cp karaf/assemblies/apache-karaf/target/apache-karaf-3.0.8.tar.gz .
tar xzvf apache-karaf-3.0.8.tar.gz

Make changes to the configuration of Karaf

cd apache-,karaf-3.0.8
vim etc/org.apache.karaf.features.cfg

Locate the featuresRepositories and append the following line (will need a comma before appending the text to separate from the previous value)

mvn:org.onosproject/onos-features/1.5.0-SNAPSHOT/xml/features

Build Pre-compiled Protoc artifact of Protobuf

Install dependencies:

Ubuntu:

apt-get install -y autoconf automake libtool curl make g++ unzip

REHL:

yum install -y autoconf automake libtool curl make g++ unzip

SLES:

zypper install -y autoconf automake libtool curl make g++ unzip
Build from source
cd /<source_root>/
git clone https://github.com/google/protobuf.git
cd protobuf
git checkout v3.0.0

Make changes to autogen.sh

@@ -31,7 +31,8 @@ fi
# directory is set up as an SVN external.
if test ! -e gmock; then
   echo "Google Mock not present.  Fetching gmock-1.7.0 from the web..."
-  curl $curlopts -O https://googlemock.googlecode.com/files/gmock-1.7.0.zip
+#  curl $curlopts -O https://googlemock.googlecode.com/files/gmock-1.7.0.zip
+  curl $curlopts -O http://pkgs.fedoraproject.org/repo/pkgs/gmock/gmock-1.7.0.zip/073b984d8798ea1594f5e44d85b20d66/gmock-1.7.0.zip
   unzip -q gmock-1.7.0.zip
   rm gmock-1.7.0.zip
   mv gmock-1.7.0 gmock

Prepare s390x patch file, i.e., /<source_root>/protobuf/s390x.patch, as following:

Description: Add support for s390x architecture.
Based on port of Google V8 JavaScript engine to z Systems
Origin: https://github.com/ibmruntimes/v8z

--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -76,6 +76,13 @@
 #elif defined(__PPC__)
 #define GOOGLE_PROTOBUF_ARCH_PPC 1
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__s390__) || defined(__s390x__)
+#define GOOGLE_PROTOBUF_ARCH_S390 1
+#if defined(__s390x__)
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#else
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#endif
 #elif defined(__GNUC__)
 # if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
 // We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
--- a/src/google/protobuf/stubs/atomicops.h
+++ b/src/google/protobuf/stubs/atomicops.h
@@ -216,6 +216,8 @@ Atomic64 Release_Load(volatile const Ato
 #include <google/protobuf/stubs/atomicops_internals_pnacl.h>
 #elif defined(GOOGLE_PROTOBUF_ARCH_PPC)
 #include <google/protobuf/stubs/atomicops_internals_ppc_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_S390)
+#include <google/protobuf/stubs/atomicops_internals_s390_gcc.h>
 #elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
 #include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
 #elif defined(__clang__)
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_s390_gcc.h
@@ -0,0 +1,148 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_S390_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_S390_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  return (__sync_val_compare_and_swap(ptr, old_value, new_value));
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  Atomic32 old_value;
+  do {
+    old_value = *ptr;
+  } while (__sync_bool_compare_and_swap(ptr, old_value, new_value) == false);
+  return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  return __sync_add_and_fetch(ptr, increment);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value, Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value, Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void MemoryBarrier() { __sync_synchronize(); }
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { return *ptr; }
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  return (__sync_val_compare_and_swap(ptr, old_value, new_value));
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                         Atomic64 new_value) {
+  Atomic64 old_value;
+  do {
+    old_value = *ptr;
+  } while (__sync_bool_compare_and_swap(ptr, old_value, new_value) == false);
+  return old_value;
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                        Atomic64 increment) {
+  return __sync_add_and_fetch(ptr, increment);
+}
+
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value, Atomic64 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value, Atomic64 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { return *ptr; }
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#endif
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_S390_H_
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,6 +70,7 @@ nobase_include_HEADERS =
   google/protobuf/stubs/atomicops_internals_macosx.h            \
   google/protobuf/stubs/atomicops_internals_mips_gcc.h          \
   google/protobuf/stubs/atomicops_internals_pnacl.h             \
+  google/protobuf/stubs/atomicops_internals_s390_gcc.h          \
   google/protobuf/stubs/atomicops_internals_solaris.h           \
   google/protobuf/stubs/atomicops_internals_tsan.h              \
   google/protobuf/stubs/atomicops_internals_x86_gcc.h           \

For RHEL, you need first to

yum install libstdc++-static

and note that this package is from the rhel-s390x-server-7-optional repo on RHEL, so you need to get the repo configured first.

Then,

git apply s390x.patch
./autogen.sh
./configure
make
make install
ldconfig

Then make the following changes to ./protoc-artifacts/build-protoc.sh

@@ -73,6 +73,8 @@ checkArch ()
         assertEq $format "elf32-i386" $LINENO
       elif [ "$ARCH" == x86_64 ](/levivic/zEcoTest/wiki/-"$ARCH"-==-x86_64-); then
         assertEq $format "elf64-x86-64" $LINENO
+      elif [ "$ARCH" == s390x ](/levivic/zEcoTest/wiki/-"$ARCH"-==-s390x-); then
+        assertEq $format "elf64-s390" $LINENO
       else
         fail "Unsupported arch: $ARCH"
       fi
@@ -116,6 +118,8 @@ checkDependencies ()
       white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2"
     elif [ "$ARCH" == x86_64 ](/levivic/zEcoTest/wiki/-"$ARCH"-==-x86_64-); then
       white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2"
+    elif [ "$ARCH" == s390x ](/levivic/zEcoTest/wiki/-"$ARCH"-==-s390x-); then
+      white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld64\.so\.1"
     fi
   elif [ "$OS" == osx ](/levivic/zEcoTest/wiki/-"$OS"-==-osx-); then
     dump_cmd='otool -L '"$1"' | fgrep dylib'
@@ -179,6 +183,8 @@ elif [ "$(uname)" == Linux* ](/levivic/zEcoTest/wiki/-"$(uname)"-==-Linux*-); then
       CXXFLAGS="$CXXFLAGS -m64"
     elif [ "$ARCH" == x86_32 ](/levivic/zEcoTest/wiki/-"$ARCH"-==-x86_32-); then
       CXXFLAGS="$CXXFLAGS -m32"
+    elif [ "$ARCH" == s390x ](/levivic/zEcoTest/wiki/-"$ARCH"-==-s390x-); then
+      CXXFLAGS="$CXXFLAGS -m64"
     else
       fail "Unsupported arch: $ARCH"
     fi

Then

cd protoc-artifacts
./build-protoc.sh linux s390x protoc
cd target
mvn install:install-file -DgroupId=com.google.protobuf -DartifactId=protoc -Dversion=3.0.0 -Dclassifier=linux-s390_64 -Dpackaging=exe -Dfile=./protoc.exe

Build protoc-gen-grpc-java

cd /<source_root>/
git clone https://github.com/grpc/grpc-java.git
cd grpc-java
git checkout v1.0.0

Make changes to ./compiler/build.gradle

@@ -47,6 +47,7 @@ model {
       }
     }
     gcc(Gcc) {
+      target("unknown")
     }
     clang(Clang) {
     }
@@ -59,6 +60,7 @@ model {
     x86_64 {
       architecture "x86_64"
     }
+    unknown {}
   }

   components {
@@ -67,6 +69,8 @@ model {
         // If arch is not within the defined platforms, we do not specify the
         // targetPlatform so that Gradle will choose what is appropriate.
         targetPlatform arch
+      } else{
+        targetPlatform "unknown"
       }
       baseName "$protocPluginBaseName"
     }

Make changes to ./compiler/check-artifact.sh

@@ -59,6 +59,8 @@ checkArch ()
         assertEq $format "elf32-i386" $LINENO
       elif [ "$ARCH" == x86_64 ](/levivic/zEcoTest/wiki/-"$ARCH"-==-x86_64-); then
         assertEq $format "elf64-x86-64" $LINENO
+      elif [ "$ARCH" == s390x ](/levivic/zEcoTest/wiki/-"$ARCH"-==-s390x-); then
+        assertEq $format "elf64-s390" $LINENO
       else
         fail "Unsupported arch: $ARCH"
       fi
@@ -103,6 +105,8 @@ checkDependencies ()
       white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2"
     elif [ "$ARCH" == x86_64 ](/levivic/zEcoTest/wiki/-"$ARCH"-==-x86_64-); then
       white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2"
+    elif [ "$ARCH" == s390x ](/levivic/zEcoTest/wiki/-"$ARCH"-==-s390x-); then
+      white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld64\.so\.1"
     fi
   elif [ "$OS" == osx ](/levivic/zEcoTest/wiki/-"$OS"-==-osx-); then
     dump_cmd='otool -L '"$1"' | fgrep dylib'

Then

cd compiler
../gradlew java_pluginExecutable
mvn install:install-file -DgroupId=io.grpc -DartifactId=protoc-gen-grpc-java -Dversion=1.0.0 -Dclassifier=linux-s390_64 -Dpackaging=exe -Dfile=build/exe/java_plugin/protoc-gen-grpc-java

Build Thrift compiler

Install dependencies

Ubuntu:

apt-get install bison flex g++ libboost1.61-all-dev libevent-dev libssl-dev pkg-config

RHEL:

yum install bison flex gcc-c++ libevent-devel openssl pkgconfig

SLES:

zypper install bison flex gcc-c++ libevent-devel libopenssl-devel pkg-config
Build from source
cd /<source_root>/
git clone https://github.com/apache/thrift.git
cd thrift
git checkout 0.9.3
./bootstrap.sh
./configure
make
mkdir -p /<source_root>/onos/protocols/bmv2/thrift-api/target/thrift-compiler/
cp compiler/cpp/thrift /<source_root>/onos/protocols/bmv2/thrift-api/target/thrift-compiler/thrift-linux-s390_64.exe

Build Openjfx

Install dependencies

For RHEL

yum install -y mercurial gperf ksh libpng12-devel libjpeg-devel libxml2-devel libxslt-devel systemd-devel glib2-devel  gtk2-devel libXtst-devel pango-devel freetype-deve cmake ruby ant
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0/
export JDK_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0/

For SLES

zypper install -y mercurial gperf mksh libpng12-devel libjpeg62-devel libxml2-devel libxslt-devel systemd-devel glib2-devel gtk2-devel libXtst-devel pango-devel freetype-devel cmake ruby ant
export JAVA_HOME=/usr/lib64/jvm/java-1.8.0-openjdk-1.8.0/
export JDK_HOME=/usr/lib64/jvm/java-1.8.0-openjdk-1.8.0/

Install gradle-1.8 for java 8

cd /<source_root>
wget https://services.gradle.org/distributions/gradle-1.8-bin.zip
mkdir /opt/gradle
unzip -d /opt/gradle gradle-1.8-bin.zip
export PATH=$PATH:/opt/gradle/gradle-1.8/bin
Build from source
hg clone http://hg.openjdk.java.net/openjfx/8u-dev/rt
cd rt

Make changes to ./build.gradle

250c250
< ext.IS_64 = OS_ARCH.toLowerCase().contains("64")
---
> ext.IS_64 = OS_ARCH.toLowerCase().contains("64") || OS_ARCH.contains("s390x")
707c708
< } else if (IS_LINUX && OS_ARCH != "i386" && OS_ARCH != "amd64") {
---
> } else if (IS_LINUX && OS_ARCH != "i386" && OS_ARCH != "amd64" && OS_ARCH != "s390x") {

For SLES only, make changes to ./modules/swing/src/main/java/javafx/embed/swing/JFXPannel.java

83a84
> import sun.java2d.SurfaceData;
626a628,645
>     // FIXME: once we move to JDK 9 as the boot JDK we should remove the
>     // reflection code from this method, consider changing it to
>     // use double rather than int, and account for the possibility of
>     // a different scale factor in X and Y.
>     private int getDefaultScale(SurfaceData surfaceData) {
>         /*
>         double scale = surfaceData.getDefaultScaleX();
>         */
>         double scale = 1;
>         try {
>             Method meth = SurfaceData.class.getMethod("getDefaultScaleX");
>             scale = (Double)meth.invoke(surfaceData);
>         } catch (Exception ex) {
>         }
>
>         return (int)Math.round(scale);
>     }
>
723c742
<                 newScaleFactor = ((SunGraphics2D)g).surfaceData.getDefaultScaleX();
---
>                 newScaleFactor = getDefaultScale(((SunGraphics2D)g).surfaceData);

Then

gradle

After the building process is finished, for RHEL,

cp ./build/sdk/rt/lib/ext/jfxrt.jar /usr/lib/jvm/java/jre/lib/ext/
cp ./build/sdk/rt/lib/jfxswt.jar /usr/lib/jvm/java/jre/lib/

For SLES

cp ./build/sdk/rt/lib/ext/jfxrt.jar /usr/lib64/jvm/java/jre/lib/ext/
cp ./build/sdk/rt/lib/jfxswt.jar /usr/lib64/jvm/java/jre/lib/

Install JNA

For Ubuntu

apt-get install libjna-java

For SLES and RHEL, you have to build JNA from source. To install dependencies, for SLES

zypper install -y libX11-6 libX11-devel libXt6 libXt-devel ant-junit

and for RHEL

yum install -y libX11 libX11-devel libXt libXt-devel ant-junit

Then build from source

cd /<source_root>
git clone https://github.com/java-native-access/jna.git
cd jna
git checkout 4.2.2
ant
cp build/native-linux-s390x/libjnidispatch.so /usr/lib64/jvm/java/jre/lib/s390x/
cp build/jna.jar /usr/share/java

Step 2: Build ONOS

cd /<source_root>/
git clone https://gerrit.onosproject.org/onos
cd onos
git checkout 1.9.0

Make changes to ./tools/dev/bash_profile

@@ -11,15 +11,15 @@ if [ -z "${JAVA_HOME}" ]; then
         export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
     elif [ -d /usr/lib/jvm/java-8-oracle ]; then
         export JAVA_HOME="/usr/lib/jvm/java-8-oracle"
-    elif [ -d /usr/lib/jvm/java-8-openjdk-amd64 ]; then
-        export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
+    elif [ -d /usr/lib/jvm/java-8-openjdk-s390x ]; then
+        export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-s390x"
     fi
 fi

-export MAVEN=${MAVEN:-~/Applications/apache-maven-3.3.9}
+export MAVEN=${MAVEN:-/usr/share/maven}

 export KARAF_VERSION=${KARAF_VERSION:-3.0.8}
-export KARAF_ROOT=${KARAF_ROOT:-~/Applications/apache-karaf-$KARAF_VERSION}
+export KARAF_ROOT=${KARAF_ROOT:-/<source_root>/apache-karaf-3.0.8
 export KARAF_LOG=$KARAF_ROOT/data/log/karaf.log

Make changes to ./protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java

@@ -116,9 +116,9 @@ public class NetconfSessionImpl implements NetconfSession {
             int connectTimeout = NetconfControllerImpl.netconfConnectTimeout;

             try {
-                netconfConnection.connect(null, 1000 * connectTimeout, 1000 * connectTimeout);
+                netconfConnection.connect(null, 10000 * connectTimeout, 10000 * connectTimeout);
             } catch (IOException e) {

Then build ONOS

mvn clean
mkdir -p /<source_root>/onos/protocols/bmv2/thrift-api/target/thrift-compiler/
cp /<source_root>/thrift/compiler/cpp/thrift /<source_root>/onos/protocols/bmv2/thrift-api/target/thrift-compiler/thrift-linux-s390_64.exe
export MAVEN_OPTS="-Xms1024m -Xmx4096m -Xss4m"
ulimit -c unlimited
mvn install
export PATH=$PATH:/<source_root>/onos/tools/test/bin:/<source_root>/onos/tools/build