背景

产品实验室出现一例日志转储问题,经定位发现当前版本号没有提供nice命令,而cron拉起定时任务时,却调用了nice命令,对定时任务做优先级调整。

毫无疑问兴许版本号须要提供nice命令,可是是否能在之前的版本号升级到兴许版本号时。将该nice命令copy一份到升级前的版本号里,先做日志转储。再升级呢?

Linux 兼容性

当前版本号的nice命令,是否能在低版本号上正常执行。这属于二进制兼容性的范畴。

Linux领域有个二进制规范标准,称为LSB(Linux Standards Base),这个组织专门制订Linux二进制接口的标准(当前最新公布标准为LSB 5.0),不论什么影响二进制接口变化的因素,她都须要考虑。

当然LSB支持的二进制兼容性是向后兼容(backwards compatibility),这是什么意思呢?简单地说就是:

  1. 在低版本号Linux编译的二进制,能够直接执行在高版本号上
  2. 在高版本号Linux编译的二进制,不能保证一定能够执行在低版本号上

其实,我们遇到的兼容性问题都是第2类。而非第1类。在这样的场景上(特别是开源软件)。从技术上是无法做保证100%兼容的。

为什么会有LSB,大家想过吗?仅仅要API兼容,大不了编译一把出一个新的二进制,不就能够解决这个二进制兼容性问题了么?

二进制兼容。在业界其实算不上什么新奇的事情,各种场景下根本无法重编和重出版本号(由于老版本号压根就没有这个东西,重出版本号解决不了升级场景。由于他影响不了老版本号)

LSB就是来解决这个事情的,仅仅需公布一个二进制程序,就能通吃全部的公布版。

nice命令依赖分析

前面提及,LSB或者一般软件,仅仅能保证向后兼容,无法保证向前兼容。如今遇到的问题是有限版本号的向前兼容问题,仅仅须要正向分析一下曾经全部版本号是否OK就能够了。

当前全部历史版本号,kernel和glibc的版本号号是没有发生变化的,他们遵守的LSB版本号也是同样的,从这个角度来说。应该是兼容的。

除非nice依赖glibc/kernel二进制中的新增接口。造成新软件老法在老版本号上执行。

nice命令库依赖分析

通过ldd命令可一目了然知道nice命令依赖那些执行库:

$ ldd /usr/bin/nice
linux-vdso.so.1 => (0x00007ff5761000)
libc.so.6 => /lib64/libc.so.6 (0x00007fd4c2268000)
/lib64/ld-linux-x86-64.so.2(0x00007fd4c25c6000)

咋一看nice依赖3个执行库,各自是 linux-vdso, libc以及ld-linux。

  1. linux-vdso.so.1是Linux kernel提供的虚拟库,不是nice二进制明白依赖的。
  2. libc.so.6正是 glibc执行库,nice依赖于它
  3. ld-linux-x86-64.so.2是86-64 Linux的动态链接器

综上。仅仅需之前全部版本号都提供libc.so.6和ld-linux-x86-64.so.2这两个库。并且SONAME保持一致就可以。

经分析,满足。

nice命令函数依赖分析

通过readelf可查看nice命令所调用的外部定义函数和变量:

$ readelf -s /usr/bin/nice | grep UND | grep -v NOTYPE
1:0000000000000000 0 FUNC GLOBAL DEFAULT UND memset@GLIBC_2.2.5 (2)
2:0000000000000000 0 FUNC GLOBAL DEFAULT UND mbrtowc@GLIBC_2.2.5 (2)
3:0000000000000000 0 FUNC GLOBAL DEFAULT UND abort@GLIBC_2.2.5 (2)
4:0000000000000000 0 FUNC GLOBAL DEFAULT UND __fprintf_chk@GLIBC_2.3.4 (3)
6:0000000000000000 0 FUNC GLOBAL DEFAULT UND textdomain@GLIBC_2.2.5 (2)
7:0000000000000000 0 FUNC GLOBAL DEFAULT UND execvp@GLIBC_2.2.5 (2)
8:0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.2.5 (2)
9:0000000000000000 0 FUNC GLOBAL DEFAULT UND __assert_fail@GLIBC_2.2.5 (2)
10:0000000000000000 0 FUNC GLOBAL DEFAULT UND __printf_chk@GLIBC_2.3.4 (3)
11:0000000000000000 0 FUNC GLOBAL DEFAULT UND bindtextdomain@GLIBC_2.2.5 (2)
12:0000000000000000 0 FUNC GLOBAL DEFAULT UND malloc@GLIBC_2.2.5 (2)
13:0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
14:0000000000000000 0 FUNC GLOBAL DEFAULT UND getpriority@GLIBC_2.2.5 (2)
15:0000000000000000 0 FUNC GLOBAL DEFAULT UND _exit@GLIBC_2.2.5 (2)
16:0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.2.5 (2)
17:0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5 (2)
18:0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.2.5 (2)
19:0000000000000000 0 FUNC GLOBAL DEFAULT UND opterr@GLIBC_2.2.5 (2)
20:0000000000000000 0 FUNC GLOBAL DEFAULT UND __ctype_get_mb_cur_max@GLIBC_2.2.5 (2)
21:0000000000000000 0 FUNC GLOBAL DEFAULT UND __vfprintf_chk@GLIBC_2.3.4 (3)
22:0000000000000000 0 FUNC GLOBAL DEFAULT UND __ctpe_b_loc@GLIBC_2.3.4 (3)
23:0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs_unlocked@GLIBC_2.2.5 (2)
24:0000000000000000 0 FUNC GLOBAL DEFAULT UND setpriority@GLIBC_2.2.5 (2)
25:0000000000000000 0 FUNC GLOBAL DEFAULT UND __fpending@GLIBC_2.2.5 (2)
26:0000000000000000 0 FUNC GLOBAL DEFAULT UND strtol@GLIBC_2.2.5 (2)
27:0000000000000000 0 FUNC GLOBAL DEFAULT UND memcpy@GLIBC_2.2.5 (2)
28:0000000000000000 0 FUNC GLOBAL DEFAULT UND strchr@GLIBC_2.2.5 (2)
29:0000000000000000 0 FUNC GLOBAL DEFAULT UND getopt_long@GLIBC_2.2.5 (2)
30:0000000000000000 0 FUNC GLOBAL

posted on
2017-07-21 09:35 
slgkaifa 
阅读(...) 
评论(...) 
编辑 
收藏

05-15 15:18