running ruby on solaris (rubykaigi 2015, 12/dec/2015)

42
BioRuby Running Ruby on Solaris Naohisa Goto / 後後後後 Genome Information Research Center, Research Institute for Microbial Diseases, Osaka Univ. 後後後後後後後後後後後後後後後後後後後後後後後 Email: [email protected] Twitter: @ngotogenome GitHub: ngoto

Upload: ngotogenome

Post on 09-Jan-2017

10.847 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Running Ruby on SolarisNaohisa Goto / 後藤直久

Genome Information Research Center, Research Institute for Microbial Diseases, Osaka Univ.大阪大学微生物病研究所附属遺伝情報実験センターEmail: [email protected]: @ngotogenomeGitHub: ngoto

Page 2: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Who am I ? / 自己紹介

Name: Naohisa Goto / 名前 : 後藤 直久

Affiliation: Genome Information Research Center, Research Institute for Microbial Diseases, Osaka University所属 : 大阪大学微生物病研究所附属遺伝情報実験センター

Position: Assistant Professor / 役職 : 助教

Twitter: @ngotogenomeGitHub: ngotoEmail: [email protected]

First Ruby experience: 1.2.6 (compiled in 22/Jun/1999)

Page 3: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Who am I ? / 自己紹介

First Ruby experience: 1.2.6compiled in 22/Jun/1999

Using Ruby for genome data analysisBioRuby developer since 2001

CRuby committer since July/2011as a platform maintainer of Solaris

RubySpec committer since Oct/2015.

Page 4: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

My Activities: BioRubyBioinformatics software library and tools

written in the Ruby LanguageRuby で書かれた生物情報科学(バイオインフォマティクス)用ライブラリとツール集

Free software (Ruby License)http://bioruby.org/https://github.com/bioruby/bioruby% gem install bio

Page 5: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Next-Generation DNA Sequencers

Performance: > 50Gb/day!

次世代シークエンサー

Page 6: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Our Servers for Genome Data Analysis

Fujitsu PRIMEQUEST1800E2CPU: Xeon E7-8870 x 8 (80 cores)Memory: 2TBOS: RedHat Enterprise Linux 6.5

Fujitsu SPARC Enterprise M5000CPU: SPARC64VII 2.66GHz x 4Memory: 512GBOS: Solaris10

Fujitsu PRIMERGY RX200 x 18CPU: Xeon X5690 x2 (12 cores)Memory: 96GB OS: RedHat Enterprise Linux 6.5

DDN GridScaler3TB SATA HDD x 600 = 1.8PB(Actual capacity 1.2PB)

Page 7: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

What is Solaris?"Solaris is a Unix operating system originally

developed by Sun Microsystems."「 Solaris (ソラリス)はサン・マイクロシステムズ(サン)によって開発され、 UNIX として認証を受けたオペレーティングシステム (OS) である。」

"Oracle Solaris, as it is named as of 2010, has been owned by Oracle Corporation since the Sun acquisition by Oracle in January 2010."「 2010 年 1 月 27 日のオラクルによるサン買収に伴い、現在の開発は同社が担っている。」

Proprietary, closed source / 商用、ソース非公開https://en.wikipedia.org/wiki/Solaris_%28operating_system%29https://ja.wikipedia.org/wiki/Solaris

Page 8: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

History of Solaris 1983SunOS 1.0

…1988/12 SunOS 4.01992/6 Solaris 2.0 (= SunOS 5.0)

…1997/7 Solaris 2.61998/11 Solaris 7 (= Solaris 2.7 = SunOS

5.7)…

2005/1 Solaris 102011/11 Solaris 11

Page 9: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Features of Solaris / 特徴

Cutting-edge features / 先端機能Solaris Container (Zone)ZFSDTraceRBAC (Role-Based Access Control)…

Backward compatibility / 後方互換性Old binary can be run without changes古いバイナリがそのまま動く

Page 10: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Demo: Binary in 1999 works!

The old binary "ruby_1.2.6" build in Jun 22 1999 works on Solaris 10 today without modification!

Page 11: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Supported ArchitectureSPARC

Original hardware sold by Oracle, Fujitsu, etc."SPARC Solaris"

x64 (x86-64, AMD64, Intel 64)PC (IBM PC/AT compatible architecture)

"Intel Solaris"

Page 12: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

SPARC ProcessorRISC instruction set architectureBig-endian

Developed by Sun Microsystems since 1987SPARC is a registered trademark of SPARC

International, Inc. since 1989The SPARC architecture is fully open, non-

proprietary and royalty free.Current versions:

SPARC V8 (32-bit) and SPARC V9 (64-bit)

Page 13: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Why I started using Solaris?I've been using Solaris on SPARC since

1999, simply because they have been available in our institute. / 所属組織にあったから、 1999 年から使用。

In 1990's, Solaris and SPARC was the best choice of scientific computing.1990 年代、 Solaris と SPARC は科学技術演算に最適だった。De-facto standard / 事実上の標準Availability of software was good / ソフトの入手

が容易

Page 14: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Why do I still use Solaris?Today, our main machines are Linux.We still maintain a SPARC Solaris server

For the past software / 昔のソフトを使うためFor reproducibility of science / 科学の再現性のた

Page 15: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

How I became a Ruby Committer1. Report a bug on Solaris / バグを報告• Including build failure, test failure/error

2. Report patch for the bug / パッチを書いて送る

3. Repeat 1..2 several times / 1,2 を数回繰り返す

Page 16: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

How to build Ruby on SolarisRecommended requirements

GNU TarGNU BashGNU MakeGNU BinutilsOpenSSL

Requirements to build from SVN headGNU AutoconfGNU BisonLibffiRuby

Page 17: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

PATH is importantTwo or more variants for a command may

exist in different directoriese.g. make

/usr/ccs/bin/make/usr/xpg4/bin/make/usr/sfw/bin/gmake/usr/local/bin/make (installed by system admin)…

Setting appropriate PATH is important!The order of directories in PATH is also

important

Page 18: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

C/C++ Compilers on SolarisOracle Solaris Studio

Latest version: 12.4 (Nov/2014)Former names: Sun Studio, Sun Workshop/opt/SolarisStudio12.4/bin/cc

GCC/usr/sfw/bin/gcc (version 3.4.3)/opt/csw/bin/gcc, /usr/local/bin/gcc, …

Fujitsu C Compiler (fcc)Latest version: ??? (I'm using 5.6 (Nov/2006))/opt/FSUNf90/bin/fcc

Page 19: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

StandardsSolaris supports multiple standards, including:

System V Interface Definition Edition 3 (SVID) X/Open ANSI C (C90) POSIX.1-2001 (SUSv3) ISO C (C99)

Compile-time options for selecting some standardse.g. -D_XOPEN_SOURCE=500 for SUSv2.

Since Ruby 2.3, -D_XOPEN_SOURCE=xxx is automatically added.

Behaviors may be changed with the selected standards.See "man standards"For libm (Math) functions, see

http://docs.oracle.com/cd/E37069_01/html/E39019/z4000ac610479.html

Page 20: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

64-bit compileSolaris is 64-bit OS, but most binaries are

32-bitFor keeping backward compatibility?

Compiler's default: 32-bit compile

64-bit compile option in CFLAGSGCC: -m64Oracle Solaris Studio (Sun Studio) 12.x: -m64Sun Studio (Sun Workshop) 11 or earlier:

SPARC: -xarch=v9x86 (Intel): -xarch=generic64

Fujitsu C Compiler (fcc): -KV9

Page 21: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

64-bit compile: 64-bit LibrarySolaris is 64-bit OS, but most binaries are

32-bitAll major compiler's defaults are 32-bit

64-bit libraries are often forgotten to be installed, especially for installation by hand without using package management system. パッケージ管理システムを使わない手動インストールの場合、 64 ビットのライブラリはインスールされ忘れている事が多い。

Page 22: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Default Library Search Path"crle" shows default library search path

Equivalent of "ldconfig" in Linux and *BSD."crle" for 32-bit, "crle -64" for 64-bit

% crle

Default configuration file (/var/ld/ld.config) not found Platform: 32-bit MSB SPARC Default Library Path (ELF): /lib:/usr/lib (system default) Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default)

% crle -64

Default configuration file (/var/ld/64/ld.config) not found Platform: 64-bit MSB SPARCV9 Default Library Path (ELF): /lib/64:/usr/lib/64 (system default) Trusted Directories (ELF): /lib/secure/64:/usr/lib/secure/64 (system default)

Page 23: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Extra LibrariesLibrary locations (not in the default search

path) should be specified in LDFLAGS-L for static libraries, -R for shared libraries.Example for GCC and Oracle Solaris Studio 12:

LDFLAGS="-m64 -L/usr/local/64/lib -R/usr/local/64/lib"

C header file locations should also be specified in CPPFLAGSe.g. CPPFLAGS="-I/usr/local/64/include"

Page 24: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

LD_LIBRARY_PATH considered harmfulLD_LIBRARY_PATH and derivatives for

runtime shared library path. LD_LIBRARY_PATH for both 32- and 64-bitLD_LIBRARY_PATH_32 for 32-bitLD_LIBRARY_PATH_64 for 64-bit

They should only be used for temporary use.

Don't set LD_LIBRARY_PATH globallyDon't set in .cshrc, .login, .profile, etc.

Page 25: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

64-bit build nameEven when setting 64-bit compile option, build

name guessed by ./configure would be the same as that of 32-bit compile.(32-bit) SPARC Solaris 10: sparc-sun-solaris2.10(32-bit) Intel Solaris 10: i386-pc-solaris2.10

Setting build name for 64-bit compile is recommended.SPARC Solaris 10: --build=sparc64-sun-

solaris2.10Intel Solaris 10: --build=x86_64-pc-solaris2.10

% ./configure --help(snip)System types: --build=BUILD configure for building on BUILD [guessed]

Page 26: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Example of ./configureCompiler: Oracle Solaris Studio 12.464-bit compile

% setenv PATH /opt/SolarisStudio12.4/bin:/usr/local/64/bin:/usr/local/bin:/usr/ccs/bin:/usr/xpg4/bin:/usr/bin:/bin:/usr/open-win/bin:/usr/dt/bin:/usr/X11/bin:/usr/sbin

% unsetenv LD_LIBRARY_PATH% unsetenv LD_LIBRARY_PATH_32% unsetenv LD_LIBRARY_PATH_64% setenv CC "cc"% setenv CXX "CC"% setenv CPPFLAGS "-I/usr/local/64/include"% setenv CFLAGS "-xO3 -m64"% setenv CXXFLAGS $CFLAGS% setenv LDFLAGS "-m64 -L/usr/local/64/lib -R/usr/local/64/lib"% setenv DLDFLAGS $LDFLAGS% ./configure --prefix=/home/xxxx/testruby/2.3.0

--build=sparc64-sun-solaris2.10 --with-tclConfig-dir=/usr/local/64/lib --with-tkConfig-dir=/usr/local/64/lib

Page 27: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

makechecking if make is GNU make... yeschecking for nroff... /usr/bin/nroff.ext/include/sparc64-solaris2.10/ruby/config.h updatedconfigure: ruby library version = 2.3.0configure: creating ./config.statusconfig.status: creating GNUmakefileconfig.status: creating Makefileconfig.status: creating ruby-2.3.pc% make V=1

cc -xO3 -xtarget=sparc64viiplus -m64 -DRUBY_EXPORT -I/usr/local/64/include -I. -I.ext/include/sparc64-solaris2.10 -I./include -I. -o parse.o -c parse.c"parse.y", line 1256: operands have incompatible types: void ":" int(snip)cc: acomp failed for parse.cmake: *** [parse.o] Error 2

Page 28: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Reporting Bug via bugs.ruby-lang.org

Page 29: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Typical Bugs on Solaris, SPARCTypo inside #if .. #endif conditionsConflict of names

File name, function, macro, …

EndianWord alignment

Page 30: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Simple Bug Fix: Typo

(r36290) [Bug #6689][ruby-dev:45904]Only affected on Solaris, because it was inside #if.The person who wrote the original line (@nobu)

did not (and could not) test the code on 64-bit Solaris.

Even for the super programmer, it is difficult to check such code without building and running on the platform.

#elif defined(__sun) #include <atomic.h> # if SIZEOF_SIZE_T == SIZEOF_LONG # define ATOMIC_SIZE_ADD(var, val) atomic_add_long(&(var), (val)) # define ATOMIC_SIZE_SUB(var, val) atomic_add_long(&(var), -(val)) # define ATOMIC_SIZE_INC(var) atomic_inc_ulong(&(var)) # define ATOMIC_SIZE_DEC(var) atomic_dec_ulong(&(var))-# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_long(&(var), (val))+# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_ulong(&(var), (val))

Page 31: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Simple Fix: Conflict of names(r37604) [ruby-dev:46414] [Bug #7287]

Solaris has "atomic.h" in /usr/includeThere was "atomic.h" in Ruby source

Only the latter was loaded, but both were needed

Renamed "atomic.h" to "ruby_atomic.h" in Ruby source code

Page 32: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Big-Endian and Little-Endian

1A2B3C4D

4D3C2B1A

Big-Endian(SPARC, etc.)

Little-Endian(x86_64, etc.)

xx+1x+2x+3

(32-bit integer)1A 2B 3C 4D

xx+1x+2x+3

Page 33: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Big-Endian and Little-Endian

000000001A2B3C4D

4D3C2B1A00000000

Big-Endian(SPARC, etc.)

Little-Endian(x86_64, etc.)

xx+1x+2x+3x+4x+5x+6x+7

(64-bit integer)00 00 00 00 1A 2B 3C 4D

xx+1x+2x+3x+4x+5x+6x+7

Page 34: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Endian Bug Fix

(r37996) [ruby-core:50292] [Bug #7463]

--- a/ext/openssl/ossl_ssl.c+++ b/ext/openssl/ossl_ssl.c@@ -569,10 +569,12 @@ static VALUE ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded) { int len = RSTRING_LENINT(cur);+ char len_byte; if (len < 1 || len > 255) ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); /* Encode the length byte */- rb_str_buf_cat(encoded, (const char *) &len, 1);+ len_byte = len;+ rb_str_buf_cat(encoded, &len_byte, 1); rb_str_buf_cat(encoded, RSTRING_PTR(cur), len); return Qnil; }

Page 35: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Word AlignmentOn SPARC, n-byte (= n * 8 bit) integer or

float data must be put at a memory address equal to some multiple of the word size n.

1A 2B 3C 4DAddress: 0x100 0x101 0x102 0x103 0x104 0x105 0x106 0x107

1A 2B 3C 4D

1A 2B 3C 4D

1A 2B 3C 4D

1A 2B 3C 4D

OK

OK

Bus Error

Bus Error

Bus Error

Page 36: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Alignment Bug Fix+#if !defined(INFINITY) || !defined(NAN)+union bytesequence4_or_float {+ unsigned char bytesequence[4];+ float float_value;+};+#endif

#ifdef HAVE_INFINITY #elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */-const unsigned char rb_infinity[] = "\x00\x00\x80\x7f";+const union bytesequence4_or_float rb_infinity = { 0x00, 0x00, 0x80, 0x7f }; #else-const unsigned char rb_infinity[] = "\x7f\x80\x00\x00";+const union bytesequence4_or_float rb_infinity = { 0x7f, 0x80, 0x00, 0x00 }; #endif

-RUBY_EXTERN const unsigned char rb_infinity[];-# define INFINITY (*(float *)rb_infinity)+RUBY_EXTERN const union bytesequence4_or_float rb_infinity;+# define INFINITY (rb_infinity.float_value)

(r33502) [Bug #5469] [ruby-dev: 44657]

Page 37: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Most Bugs are non-specificMost bugs occurred on Solaris were NOT

specific to the platform but would affect all platforms.

Difference of platform can reveal hidden bugsDifferent OSDifferent memory managementDifferent CPU architecture

EndianAlignment

Different compiler

Page 38: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Integer Overflow(r32757) [ruby-dev:43284] [Bug #4456]

s+(n) overflows when n is very larges: pointer; n: value coming from user's Ruby

codeOn i386 Linux, it overflows with very large n such as

(2**31-1)On 32-bit SPARC Solaris, it overflows with relatively

smaller value, due to the different memory management.

Calculation order was changed to prevent overflow-#define NEEDS(n) do if (s + (n) >= endp - 1) goto err; while (0)+#define NEEDS(n) do if (s >= endp || (n) >= endp - s - 1) goto err; while (0) #define FILL_PADDING(i) do { \ if (!(flags & BIT_OF(LEFT)) && precision > (i)) { \ NEEDS(precision); \

Page 39: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

Forgotten "+1"(r48999) [ruby-dev:48779] [Bug #10646]

The allocated memory size of ptr includes the region to record its size, and thus "+1" must be needed.During make test-all, SEGV observed only on Solaris, but

apparently all platforms should be affected.

--- a/gc.c+++ b/gc.c@@ -7674,5 +7674,5 @@ wmap_final_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)if (j < i) {- ptr = ruby_sized_xrealloc2(ptr, j, sizeof(VALUE), i);+ ptr = ruby_sized_xrealloc2(ptr, j + 1, sizeof(VALUE), i); ptr[0] = j; *value = (st_data_t)ptr; }

Page 40: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

transcode.c: fix race condition(r51037) [ruby-dev:49106] [Bug #11277]https://bugs.ruby-lang.org/issues/11277Summary:The bug was first observed only on Solaris. I found that it also occurred on Linux, after

investigation. I found a simple reproduction code.

Fixed by @nobu

% ruby --disable=gems -e '(0..2).collect { |_| Thread.new { p "\u3042".encode("EUC-JP") }}.each { |t| t.join }' -e:1: warning: failed to load encoding (EUC-JP); use ASCII-8BIT instead-e:1:in `encode': code converter not found (UTF-8 to EUC-JP) (Encoding::ConverterNotFoundError) from -e:1:in `block (2 levels) in <main>'

Page 41: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

make test-all: 0 failures, 0 errors% make test-all TESTS=-v V=1(snip)XMLRPC::ClientTest#test_new2_ssl_custom_port = 0.00 s = .XMLRPC::ClientTest#test_new2_user_password = 0.00 s = .XMLRPC::ClientTest#test_request = 0.03 s = .

Finished tests in 1537.222241s, 10.3446 tests/s, 1451.5078 assertions/s.

15902 tests, 2231290 assertions, 0 failures, 0 errors, 49 skips

ruby -v: ruby 2.3.0dev (2015-12-01) [sparc64-solaris2.10]make: Nothing to be done for `test-all'.

Page 42: Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)

BioRuby

ConclusionsIt is very difficult to write code with no bugs

without building and running the code, even for super programmers.たとえ神プログラマであっても、ビルド・実行せずにバグの無いコードを書くのは難しい。

Running on different platforms would reveal hidden bugs. That's one of the reasons why it is good to maintain various platforms.異なる環境で実行したら、隠れたバグが見つかることがあるのが、多様な環境をサポートするのが良い理由の一つ。