天天看點

移植opendaylight到powerpc平台

今天介紹一下将ODL移植到powerpc平台上遇到的一些問題。

1、啟動karaf時提示找不到hostname,無法進行tcp連接配接。

可以通過hostname指令進行設定,例如hostname localhost

2、啟動過程中出現異常,提示檔案句柄不足。

一個程序打開檔案句柄數目是有限制(也可以設定成無限),不同作業系統是不同的。我們可以通過ulimit進行設定,例如:ulimit -n 65535

3、啟動過程出現異常,提示找不到類名(最惡心的問題),百度+谷歌都不好使。

[email protected]>Uncaught error from thread [opendaylight-cluster-data-
akka.persistence.dispatchers.default-plugin-dispatcher-18] shutting down JVM since 'akka.jvm-exit-on
-fatal-error' is enabled for ActorSystem[opendaylight-cluster-data]
java.lang.NoClassDefFoundError: org/iq80/leveldb/DBFactory
        at akka.persistence.journal.leveldb.LeveldbJournal.<init>(LeveldbJournal.scala:22)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.lang.Class.newInstance(Class.java:442)
        at akka.util.Reflect$.instantiate(Reflect.scala:44)
        at akka.actor.NoArgsReflectConstructor.produce(IndirectActorProducer.scala:105)
        at akka.actor.Props.newActor(Props.scala:213)
        at akka.actor.ActorCell.newActor(ActorCell.scala:562)
        at akka.actor.ActorCell.create(ActorCell.scala:588)
        at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:461)
        at akka.actor.ActorCell.systemInvoke(ActorCell.scala:483)
        at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:282)
        at akka.dispatch.Mailbox.run(Mailbox.scala:223)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.iq80.leveldb.DBFactory
        at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
        at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 18 more
#
#
           

【定位過程-第一階段】

定位過程1:提示找不到類,那麼就看一下類是否存在,經過确認類檔案是存在且路徑也是對的,類檔案在leveldbjni-all-1.8-odl.jar包中。

定位過程2:檢視leveldbjni-all-1.8-odl.jar中META-INF/MANIFEST.MF檔案,其中有一段内容如下(整理格式後):

Bundle-NativeCode:
META-INF/native/windows32/leveldbjni.dll;osname=Win32;processor=x86,
META-INF/native/windows64/leveldbjni.dll;osname=Win32;processor=x86-64,
META-INF/native/osx/libleveldbjni.jnilib;osname=macosx;processor=x86,
META-INF/native/osx/libleveldbjni.jnilib;osname=macosx;processor=x86-64,
META-INF/native/linux32/libleveldbjni.so;osname=Linux;processor=x86,
META-INF/native/linux64/libleveldbjni.so;osname=Linux;processor=x86-64,
META-INF/native/sunos64/amd64/libleveldbjni.so;osname=SunOS;processor=x86-64,
META-INF/native/sunos64/sparcv9/libleveldbjni.so;osname=SunOS;processor=sparcv9
           

因為我們是linux系統(紅色字段),然而我們是powerpc平台并非x86平台。基本可以确定so動态庫以及processor這個地方是有問題的,那麼就先解決這個問題。

【解決問題-第一階段】

解決1:libleveldbjni.so必須是powerpc平台上,需要下載下傳如下三個軟體:

軟體名稱 下載下傳方式 備注
snappy wget http://snappy.googlecode.com/files/snappy-1.0.5.tar.gz
leveldb git clone git://github.com/chirino/leveldb.git 非谷歌官方倉庫位址
leveldbjni git clone git://github.com/fusesource/leveldbjni.git

具體編譯方式可參考leveldbjni中readme.md檔案,提醒一下必須是交叉編譯啊!!将編譯好的libleveldbjni.so替換到jar包中。

解決2:processor應該設定成什麼呢?

通過走查代碼,發現processor的擷取是通過System.getProperty("os.arch"),在我們的環境中os.arch傳回的是ppc64。是以我們對MANIFEST.MF檔案修改,将對應的processor修改成ppc64。

【驗證-第一階段】

 替換so以及MANIFEST.MF檔案之後,再次啟動karaf,仍然報相同錯誤,沒有任何進展。

【定位過程-第二階段】

定位過程1:為了驗證替換檔案之後的jar是否正确,下載下傳原生的karaf,并且手動安裝這個jar包,發現bundle的狀态一直都是Installed(正常應該Active狀态)。說明jar包還是有問題。

定位過程2:針對這種問題,我們隻能調試,調試方法有:日志、debug調試。對于一個不太了解軟體,debug調試是最佳方式。針對這個問題,我們應該将斷點設定在什麼地方呢?由于我們是通過bundle:install -s bundle名稱,那麼好我們就設定在指令行入口的地方。

【解決問題-第二階段】

通過上面debug過程中,最終發現指令行在安裝bundle的時候,比對arch名字是powerpc,而非是ppc64。是以我們可以得出我們需要将processor設定成powerpc。(這部分代碼進行了适配,把ppc64是配成powerpc)

【驗證-第二階段】

通過上面将processor設定powerpc,将jar包放到原生的karaf中,發現安裝這個bundle之後,狀态是active。非常的興奮!!!然後把該jar包放到odl中,啟動karaf,不幸的事情發生了,還是報錯且錯誤一樣。簡直是在做過山車一般,倍兒爽!!

【定位過程-第三階段】

既然原生的karaf能運作起來,證明這樣配置問題不大且so庫應該也是正常的。那麼就隻能調試debug調試odl。

定位過程1:我們在調試odl的時候一般都是系統啟動ok,調試我們業務邏輯,但是針對這種啟動過程中抛出了異常,我們應該如何調試呢?我們面臨的是必須在抛異常之前就把斷點斷住,我們應該怎麼做呢?原來jvm提供了一個參數suspend,我們需要将這個參數設定.即可。這個參數含義是程序啟動之後隻配置設定基本資源,不執行任何業務邏輯,當用戶端連上jvm之後,才開始執行業務邏輯。說白點大白話,就設定這個參數之後進行先挂起。

定位過程2:bundle:install  [bundle名稱] 與 bundle:install -s [bundle名稱] 差別是s表示start,安裝并激活。通過分步調試,隻調試install過程,發現install過程沒有問題,processor校驗過程對os.arch進行了适配,适配成powerpc。

 【解決問題-第三階段】

解決方法1:修改start過程對processor校驗。

解決方法2:修改配置MANIFEST.MF檔案,增加對processor是ppc64。

【驗證-第三階段】

META-INF/native/linux64/libleveldbjni.so;osname=Linux;processor=ppc64,
META-INF/native/linux64/libleveldbjni.so;osname=Linux;processor=powerpc,
           

采用解決方法2,驗證通過,karaf可以在powerpc平台正常啟動。

【特别說明】

1、在解決過程還需要編一個libjansi.so,在jline-2.12.jar,是以需要單獨再編譯一下libjansi.so

2、我們的odl代碼其實包含了兩套osgi架構Apache Felix和Equinox(原生karaf隻有Felix),由于存在兩個osgi架構,才導緻上面對于processor的處理出現不一緻。       

繼續閱讀