Python 3
CentOS 6ã®opensslã®ãã¼ã¸ã§ã³ï¼1.0.1eï¼ã®é¢ä¿ã§ãPython 3.7以ä¸ã¯ãã«ãã失æãã¾ãã
- https://docs.python.org/ja/3/whatsnew/3.7.html
The improved host name check requires a libssl implementation compatible with OpenSSL 1.0.2 or 1.1. Consequently, OpenSSL 0.9.8 and 1.0.1 are no longer supported
ä»åã¯3.7ã«ãã ããã¯ãªãã®ã§ãpyenvã§Python 3.6ã®ææ°ã®3.6.8ãã¤ã³ã¹ãã¼ã«ãã¦ãpipã§tensorflowãã¤ã³ã¹ãã¼ã«ãã¾ãã詳細ã¯å²æã°ã°ã£ã¦ãã
glibc, stdc++
ã¤ã³ã¹ãã¼ã«ã«æåãã¦ãã使ããã¨ããã¨ã¨ã©ã¼ãåºã¾ãã
$ python3.6 -c 'import tensorflow; print("hello")' Traceback (most recent call last): ... ImportError: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by /home/ore/.pyenv/versions/3.6.8/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so) ... $ ldd /home/ore/.pyenv/versions/3.6.8/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so |& grep 'not found' | awk '{print $4}' `GLIBC_2.16' `GLIBC_2.14' `GLIBC_2.17' `GLIBC_2.15' `GLIBCXX_3.4.15' `GLIBCXX_3.4.19' `GLIBCXX_3.4.14' `CXXABI_1.3.7' `GLIBCXX_3.4.17' `GLIBCXX_3.4.18' `CXXABI_1.3.5' `GLIBC_2.14' `GLIBC_2.16' `GLIBC_2.17' `GLIBCXX_3.4.14' `GLIBCXX_3.4.18' `CXXABI_1.3.5' `GLIBCXX_3.4.15' `GLIBCXX_3.4.19' `GLIBCXX_3.4.17' `CXXABI_1.3.7'
ã©ããããglibc 2.17ã¨libstdc++ 3.4.19ãå¿ è¦ããã§ãã
ãããã«ã·ã¹ãã ã®glibcãç½®ãæããã®ã¯æãã®ã§ãå¥ã®ãã£ã¬ã¯ããªã«å±éãã¦ä»åã®python3.6ã¯ããã®shared objectã使ãããã«ãã¾ãã
glibcã¨libstdc++ã¯ãhttps://pkgs.org/ ã§æ¢ãã¦CentOS 7ã®ãæåãã¾ãã
$ cd ~/tmp/ $ wget \ http://mirror.centos.org/centos/7/updates/x86_64/Packages/glibc-2.17-260.el7_6.5.x86_64.rpm \ http://mirror.centos.org/centos/7/updates/x86_64/Packages/glibc-devel-2.17-260.el7_6.5.x86_64.rpm \ http://mirror.centos.org/centos/7/os/x86_64/Packages/libstdc++-4.8.5-36.el7.x86_64.rpm \ http://mirror.centos.org/centos/7/os/x86_64/Packages/libstdc++-devel-4.8.5-36.el7.x86_64.rpm \ ;
~/lib/
ã®ä¸ã«å±éãã¾ãã
$ cd ~/lib/ $ for p in ~/tmp/*.rpm; do echo $p; rpm2cpio $p | cpio -idv; done $ ls -F etc/ lib64/ sbin/ usr/ var/
以ä¸ããã¹æå®ãé·ããªãã®ã§ç°¡ç¥åã®ããå¤æ°ã«å ¥ãã¨ãã¾ãã
py36="$HOME/.pyenv/versions/3.6.8/bin/python3.6" pywrap_tensorflow_internal="$HOME/.pyenv/versions/3.6.8/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so" my_ld="$HOME/lib/lib64/ld-linux-x86-64.so.2" my_libs="$HOME/lib/usr/lib64:$HOME/lib/lib64"
ld-linux.so
ã¯ã³ãã³ãã¨ãã¦ãå®è¡ã§ãã¦ã --library-path
ã§dynamic loadããshared objectã®ãã¹ãæå®ã§ãã¾ããç°å¢å¤æ° LD_LIBRARY_PATH
ã§ãåæ§ã®ãã¨ãã§ãã¾ãããä½ç¨ç¯å²ãåããã»ã¹ã¾ã§åã¶ãã©ããã¨ããéããããã¾ãã
ld-linux.so
çµç±ã§ python3.6
ãèµ·åãã¦ãå
ç¨ã¨ã©ã¼ã«ãªã£ãã³ã¼ããå®è¡ãã¦ã¿ã¾ãã
$ $my_ld --library-path $my_libs $py36 -c 'import tensorflow; print("hello")' hello
ä»åº¦ã¯æ£å¸¸çµäºãã¾ããï¼ãã£ããï¼ï¼
child process
æ©éãæçµçã«èµ°ããããã¹ã¯ãªãããå®è¡ãã¦ã¿ãã¨â¦
$ $my_ld --library-path $my_libs $py36 oreno.py * Serving Flask app "server" (lazy loading) * Environment: production ... Traceback (most recent call last): ... ImportError: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by /home/ore/.pyenv/versions/3.6.8/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so) ...
失æãã¾ããã
ã¨ã©ã¼ã¡ãã»ã¼ã¸ããããã¨ãã·ã¹ãã ã®glibcããã¼ããã¦ãã¾ã£ã¦ããããã§ããstrace -f -s 1000 $my_ld ...
ã§ç¢ºèªãã¦ã¿ãã¨ãå¾å㧠$my_ld
ãä»ããªã㧠$py36
ã execve
ãã¦ç°å¸¸çµäºãã¦ãã¾ããã詳細ã¯ç¢ºèªãã¦ã¾ããããã©ã£ã㧠fork
ãã¦ãããããªããã¨æãã¾ãã
åããã»ã¹ã«ãæ°ããglibcã®å ´æãæãã¦ãããã°ããã®ã§ã試ãã« LD_LIBRARY_PATH
ãã»ãããã¦å®è¡ãã¦ã¿ãã¨â¦
$ env LD_LIBRARY_PATH=$my_libs $my_ld --library-path $my_libs $py36 oreno.py ... /home/ore/.pyenv/versions/3.6.8/bin/python3.6: relocation error: /home/ore/lib/lib64/libc.so.6: symbol _dl_starting_up, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
失æãã¾ããã
ãã¶ããã·ã¹ãã ã® /lib64/ld-linux-x86-64.so.2
ã§æ°ããglibcããã¼ããããã¨ãã¦å¤±æãã¦ãããã ã¨æãã¾ãã
ãããæåããã¨ãã¦ããLD_LIBRARY_PATH
ã¯ä½ç¨ç¯å²ã大ããã®ã§ãä»ã®æ¹æ³ãããã°é¿ãããæ段ã§ãã
patchelf
Linuxã®å®è¡ãã¡ã¤ã«å½¢å¼ã®ELFã«ã¯ãdynamic linker (interpreter) ã¨ã©ã¤ãã©ãªã®ãµã¼ããã¹ï¼runpathï¼ãåãè¾¼ããã¨ãã§ãã¾ããããã㯠readelf
ã patchelf
ã§ç¢ºèªãããã¨ãã§ãã¾ãã
CentOS 6ç¨ã® patchelf
ã¯EPELã«ããã¾ãã
$ readelf -a /usr/bin/mailq | grep -e interpreter -e runpath [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 0x000000000000001d (RUNPATH) Library runpath: [/usr/lib/postfix] $ patchelf --print-interpreter --print-rpath /usr/bin/mailq /lib64/ld-linux-x86-64.so.2 /usr/lib/postfix
patchelf
ã¯ãããã®æ
å ±ãå¤æ´ãããã¨ãã§ããã®ã§ã$py36
ã®interpreterã¨runpathãå¤æ´ãã¦ãã¾ãã°ã $my_ld --library-path $my_libs
ã®åç½®ãä¸è¦ã«ãªãã¨ããããã§ãã
ãã£ã¦ã¿ã¾ãããã
$ cp -p $py36 ${py36}.bak $ patchelf --set-interpreter $my_ld --set-rpath $my_libs $py36
ãã£ããã$my_ld
ã®åç½®ãªãã§å®è¡ãã¦ã¿ãã¨â¦
$ $py36 -c 'import tensorflow; print("hello")' Traceback (most recent call last): ... ImportError: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by /home/ore/.pyenv/versions/3.6.8/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so)
ã¨ã©ã¼ãåºã¾ãããããããã¯æ³å®å ã§ãã
$py36
ã¯æå¾
ããã¨ããæ°ããglibcããã¼ãã§ããã®ã§ããã_pywrap_tensorflow_internal.so
ãlibstdc++ããã¼ããããã¨ãã¦æ°ããã®ãè¦ã¤ããããã¨ã©ã¼ã«ãªã£ã¦ããããã§ããï¼glibcã¯æ¢ã« $py36
ãæ°ããã®ããã¼ãæ¸ã¿ãªã®ã§å¤§ä¸å¤«ï¼
ãªã®ã§ã_pywrap_tensorflow_internal.so
ãrunpathãæ¸ãæãã¦ãã¾ãã¾ãããã
_pywrap_tensorflow_internal.so
ã¯æ¢ã«runpathãè¨å®ããã¦ããã®ã§ãããã«è¿½å ããæãã§ã»ãããã¾ããï¼ç´ç²ãªshared objectãªã®ã§interpreterã®å¤æ´ã®å¿
è¦ã¯ããã¾ããï¼
$ORIGIN
ãå±éãããªãããã«ã·ã³ã°ã«ã¯ã©ã¼ãããã®ãå¿ããªãã§ãã ããã
$ patchelf --print-rpath $pywrap_tensorflow_internal $ORIGIN/../../_solib_k8/_U_S_Stensorflow_Spython_C_Upywrap_Utensorflow_Uinternal.so___Utensorflow:$ORIGIN/:$ORIGIN/.. $ cp -p $pywrap_tensorflow_internal ${pywrap_tensorflow_internal}.bak $ patchelf --set-rpath '$ORIGIN/../../_solib_k8/_U_S_Stensorflow_Spython_C_Upywrap_Utensorflow_Uinternal.so___Utensorflow:$ORIGIN/:$ORIGIN/..'":$my_libs" $pywrap_tensorflow_internal
ãã¦ã
$ $py36 -c 'import tensorflow; print("hello")' hello $ $py36 oreno.py * Serving Flask app "server" (lazy loading) * Environment: production ... INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) ...
ããããæ£å¸¸ã«èµ·åã§ãã¾ããï¼ï¼ï¼
ããsocket.getaddrinfo()
ã失æãã¦ååãå¼ããâ¦
ã¾ã¨ã
ld-linux.so
ã¯ã³ãã³ãã¨ãã¦ãå®è¡ã§ãã¦ã--library-path
ã§dynamic loadããshared objectã®ãã¹ãæå®ã§ããï¼ç°å¢å¤æ°LD_LIBRARY_PATH
ã«æ¯ã¹ä½ç¨ç¯å²ãéå®çã«ã§ããï¼- ELFã«ã¯ãdynamic linker (interpreter) ã¨ã©ã¤ãã©ãªã®ãµã¼ããã¹ï¼runpathï¼ãåãè¾¼ããã¨ãã§ãã
patchelf
ã³ãã³ãã§å¤æ´ã§ãã
ã¨ããã§ã
debootstrap
㧠bionic ã®ç°å¢ãä½ã£ã¦ã¾ãã£ã¨CentOS 6ã«ã³ãã¼ã㦠chroot
ããæ¹ãããã£ãããããã⦠試ãã¦ãªããã©åãããããªããã¨â¦
kernelãå¤ãã¦æ®å¿µããã¡ã§ããï¼
# chroot ./bionic /bin/bash FATAL: kernel too old # file bionic/bin/bash bionic/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.2.0, stripped