从Solaris向LinuxonPOWER迁移指南

ChinaUnix 发表于:12年08月17日 14:00 [转载] ChinaUnix

  • 分享:
[导读]从Solaris向LinuxonPOWER迁移指南

表 1 列出了 Solaris 系统调用,这些系统调用与 Linux 中系统调用的名称、签名不同,或在 Linux 中不可用:

表 1. Solaris 系统调用

Solaris Linux 说明
acl、facl N/A 获取或设置文件的 Access Control List (ACL)
adjtime N/A 更正时间,以允许系统时钟同步
audit N/A 向审计日志写入记录
auditon N/A 对审计进行操作
auditsvc N/A 向特定文件描述符写入审计日志
getacct、putacct、wracct N/A 获取、放入或写入扩展报告数据
getaudit、setaudit、getaudit_addr、setaudit_addr N/A 获取和设置进程审计信息
getauid、setauid N/A 获取和设置用户审计身份
getdents getdents** 读取目录条目,并以单独格式将其放入文件系统中。Linux 中的 Dirent 结构与 Solaris 中的不同
getmsg、getpmsg N/A 获取数据流中的下一条消息
getpflags、setpflags N/A 获取或设置流程标记
getppriv、setppriv N/A 获取或设置进程标志
getustack、setustack N/A 检索或更改 per-LWP 堆栈边界信息
issetugid N/A 确定当前可执行程序是在运行 setuid 还是在运行 setgid
llseek _llseek 移动扩展读/写文件指针
_lwp_cond_signal、_lwp_cond_broadcast N/A 对条件变量发送信号
_lwp_cond_wait、_lwp_cond_timedwait、_lwp_cond_reltimedwaid N/A 等待条件变量
_lwp_info N/A 返回单个 LWP 的时间核算信息
_lwp_kill N/A 向 LWP 发送信号
_lwp_mutex_lock、_lwp_mutex_unlock、_lwp_mutex_trylock N/A 互斥
_lwp_self N/A 获取 LWP 标识符
_lwp_sema_wait、_lwp_sema_trywait、_lwp_sema_init、_lwp_sema_post N/A 信号灯操作
_lwp_suspend、_lwp_continue N/A 继续或暂停 LWP 执行
memcntl N/A 内存管理控制
meminfo N/A 提供内存信息
mount mount* 装载文件系统。Solaris 中此系统调用的签名与 Linux 的不同
msgids N/A 发现所有消息队列标识符
msgrcv msgrcv* 消息接收操作。Linux 在其一个参数中使用 struct msgbuf 类型
msgsnap N/A 消息队列快照操作
msgsnd msgsnd* 消息发送操作。Linux 在其一个参数中使用 struct msgbuf 类型
ntp_adjtime N/A 调整本地时钟参数
ntp_gettime N/A 获取本地时钟值
open、openat open* 打开文件。openat() 不能在 Linux 中使用
pcsample N/A 程序执行时间配置文件
p_online N/A 返回或更改处理器操作状态
priocntl N/A 进程调度器控制
priocntlset N/A 一般化的进程调度器控制
processor_bind sched_setaffinity 将 LWP 绑定到处理器
processor_info N/A 确定处理器类型和状态
pset_bind N/A 将 LWP 绑定到处理器集合
pset_create、pset_destroy、pset_assign N/A 管理处理器集合
pset_info N/A 获取处理器集合的信息
pset_list N/A 获取处理器集合的列表
pset_setattr、pset_getattr N/A 设置或获取处理器集合属性
putmsg、putpmsg N/A 发送流消息
rename、renameat rename* 更改文件名。Linux 没有 renameat() 函数
resolvepath N/A 分析路径名称的所有符号链接
semids N/A 发现所有信号灯标识符
setrctl、getrctl N/A 设置或获取资源控制值
settaskid、gettaskid、getprojid N/A 设置或获取任务或项目 ID
shmids N/A 发现所有共享内存标识符
sigsend、sigsendset N/A 向处理器或处理器组发送信号
__sparc_utrap_install N/A 安装 SPARC V9 用户陷阱处理程序
fstatat N/A 获取文件状态
swapctl N/A 管理交换空间
uadmin N/A 管理控制
unlink、unlinkat unlink* 删除目录条目。Linux 没有 unlinkat() 函数
futimesat N/A 设置文件访问权和修改时间。它分析关于 fildes 参数的路径
waitid N/A 等待子进程来更改状态
yield sched_yield 放弃对其他轻量级进程的执行

信号

信号用于向进程或线程通知特定事件。Linux 支持 POSIX 标准信号和 POSIX 实时信号。每个信号都有惟一名称和相应的信号编号。例如,对于 Solaris,SIGSTOP 的信号编号是 23,但是对于 Linux on POWER,其信号编号则为 19。/usr/include/bits/signum 中可以找到 Linux 上的信号编号定义。

对于所有可能的信号,系统会定义出现信号时执行的默认操作:

Terminate:默认操作是终止进程。

Ignore:默认操作是忽略信号。

Core:默认操作是终止进程并转储内核。

Stop:默认操作是停止进程。

有关 Linux 信号的完整列表,包括每个信号的简短描述及发出信号时的默认行为,请通过调用下列命令查看 Section 7 中的信号手册:# man 7 signal。对于 Linux,请注意以下事项:

SIGABRT 和 SIGIOT 是相同的。

SIGCLD 和 SIGCHLD 是相同的。

SIGPOLL 和 SIGIO 是相同的。

对于 Linux,SIGPWR 的默认操作是终止进程,而在 Solaris 中则忽略该操作。

表 2 显示了 Solaris 支持但 Linux on POWER 不支持的信号:

表 2. Solaris 支持的信号

名称 默认操作 说明
SIGEMT core 模拟陷阱
SIGWAITING ignore 线程库使用的并发信号
SIGLWP ignore 线程库使用的 Inter-LWP 信号
SIGFREEZE ignore 检查点暂停
SIGTHAW ignore 检查点继续
SIGCANCEL ignore 线程库使用的取消信号
SIGLOST ignore 资源丢失(运行于 Sparc 上的 Linux 支持该项)
SIGXRES ignore 资源控制超出

在 Soalris 和 Linux 上,sigset_t 的定义有所不同。在 Linux 上,它在 /usr/include/bits/sigset.h 中定义为:

清单 2. 如何在 Linux 上定义 sigset_t

				 # define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) typedef struct    {        unsigned long int __val[_SIGSET_NWORDS];    } __sigset_t; #endif 

在 Solaris 上,它在 /usr/include/sys/signal.h 中定义为:

清单 3. 如何在 Solaris 上定义 sigset_t

				 typedef struct  {                                     /* signal set type */              unsigned int       __sigbits[4]; } sigset_t; 

基本数据类型和对齐

系统中可以有两种不同的数据类型:基本数据类型 和衍生数据类型。

基本数据类型是 C 和 C++ 语言规范定义的所有数据类型。表 3 对 Linux on POWER 和 Solaris 中的基本数据类型进行了比较(值以字节为单位):

表 3. 基本数据类型

基本类型 Linux on POWER, ILP32 Linux on POWER, LP64 Solaris, ILP32 Solaris, LP64
_Bool,bool 1 1 1 1
char 1 1 1 1
wchar_t 2 4 4 4
short 2 2 2 2
int 4 4 4 4
float 4 4 4 4
long 4 8 4 8
pointer 4 8 4 8
long long 8 8 8 8
double 8 8 8 8
long double 16* 16* 16 16

*从 Red Hat Enterprise Linux 5 (RHEL5) 和 SUSE Linux Enterprise Server 10 (SLES10) 开始,在 Linux on POWER 中 long double 的默认大小是 128 位。在 RHEL5 或 SLES10 之前,如果 XL 编译器中使用了编译器选项 -qldbl128,那么其大小可以增加到 128 位。

当在平台之间或在 32 位和 64 位模式之间移植应用程序时,需要考虑不同环境中可用对齐设置之间的差别,以避免可能发生的性能下降和数据损坏。对于 IBM XL C/C++ 编译器,集合(C/C++ 结构/联合及 C++ 类)内的每个数据类型将根据 linuxppc 或 bit-packed 规则沿字节边界对齐(使用 -qalign 选项),其中 linuxppc 为默认值。linuxppc 使用 GNU C/C++ 对齐规则维护与 GNU C/C++ 对象的二进制兼容性。

表 4 用显示了 linuxppc 和 bit-packed 规则的对齐值:

表 4. 对齐值

数据类型 linuxppc bit-packed
_Bool,bool 1 1
char 1 1
wchar_t (32-bit) 2 1
wchar_t (64-bit) 4 1
int 4 1
short 2 1
long (32-bit) 4 1
long (64-bit) 8 1
long long 8 1
float 4 1
double 8 1
long double 16 1

SPARC 平台通常要求数据对齐遵循相等的数据大小:2 字节类型必须在 2 字节区域内,4 字节类型必须在 4 字节区域内。因此,当您从 Solaris 移植到 Linux 时,必须特别注意 Solaris 和 Linux 之间的不同大小的数据类型。

系统衍生数据类型

衍生数据类型是现有基本类型或其他衍生类型的衍生物或结构。根据使用的数据模型(32 位或 64 位)和硬件平台,系统衍生数据类型可以具有不同的字节大小。表 5 显示了 Linux 中的一些衍生数据类型,它们与 Solaris 中的那些衍生数据类型不同:

表 5. 衍生数据类型

数据类型 Solaris ILP32 Solaris LP64 Linux on POWER ILP32 Linux on POWER LP64
gid_t long int unsigned int unsigned int
mode_t unsigned long unsigned int unsigned int unsigned int
pid_t long int int int
uid_t long int unsigned int unsigned int
wint_t long int unsigned int unsigned int

GNU Make 与 Solaris Make

如果在源平台中使用 Solaris Make,为了在 Linux 中使用 GNU Make,需要修改 makefile。要获得 Solaris Make 和 GNU Make 之间差别的详细信息,请参阅 IBM 红皮书 “AIX 5L Porting Guide” 的第 6 章。

编译器选项

表 6 列出了 SUN Studio C/C++ 编译器广泛使用的编译器选项,以及 GNU Compiler Collection 和 IBM XL 编译器的等同选项:

表 6. 编译器选项

Sun Studio 选项 GNU GCC 选项 XL C/C++ 选项 说明
-# -v -v 指示编译器报告编译进度信息
-### -### -# 跟踪编译,而不调用任何东西
-dn -static -qstaticlink 指定静态链接
-dy (Default) (Default) 指定动态链接
-G -shared -qmkshrobj 生成共享对象,而不是生成动态链接可执行程序
-xmemalign -malign-natural、
-malign-power
-qalign 指定最大假定内存对齐(memory alignment),以及未对齐数据访问的行为
-xO1、-xO2、-xO3、-xO4、-xO5 -O、-O2、-O3 -O、-O2、-O3、-O4、-O5 编译过程中在所有级别上优化代码
-KPIC -fPIC -qpic=large 生成位置无关代码以用于共享库中(大模型)
-Kpic -fpic -qpic=small 生成位置无关代码以用于共享库中(小模型)
-mt -pthread Use _r invocation mode 编译和链接多线程代码
-R dirlist -Wl、-rpath、dirlist -Wl、-rpath、dirlist 构建可执行文件的动态库搜索路径
-xarch -mcpu、-march -qarch、-qtune 指定目标架构指令集合

XL C/C++ 编译器支持 GNU 编译器选项的一部分,从而有利于移植使用 GCC 和 g++ 编译器开发的应用程序。将 gxlc 或 gxlc++ 调用命令与 GNU 编译器选项一起使用来启用该支持。这些调用命令使用纯文本配置文件来控制 GNU-to-XL C/C++ 选项映射和默认值。您可以根据需求更改这些配置文件。参考 XL 编译器手册更多地了解 gxlc 和 gxlc++。

Solaris 线程和 NPTL

这一节将说明开发人员将多线程应用程序从 Solaris 迁移到 Linux 时会遇到的问题。

Solaris 支持两种线程实现:Solaris 线程和 POSIX 线程(pthreads)。有一些函数由 Solaris 线程 API 实现,而不是由 pthreads API 实现,反之亦然。对于那些符合以上情况的函数,关联的参数可能不符合。下列是仅受 Solaris 线程 API 支持的特性:

创建守护进程线程的能力。守护进程线程不影响进程退出状态。进程可以通过调用 exit() 退出,也可以通过让进程中的每个非守护进程线程调用 thr_exit() 来退出。

使用 thr_suspend() 和 thr_continue() 来暂停或继续线程执行的能力。注意 thr_suspend() 可以暂停目标线程,而不涉及线程可能拥有的锁。如果暂停线程调用某一个函数,而该函数需要已暂停的目标线程所拥有的锁,那么就会出现死锁。

允许线程等待进程中任何未检验出的线程终止的能力。当 thr_join() 的第一个参数设为 0 时就会这样。如果将 pthread_join() 的第一个参数设为 0,程序将因段错误而终止。

表 7 将关键 Solaris 线程函数与 pthreads 函数进行了比较。对于其他 Solaris 线程函数,请参阅 SUN 的 “Multithreaded Porting Guide”(见 参考资料)。

表 7. 线程和 pthreads 函数

Solaris 线程 API Linux POSIX 线程 API 说明
thr_create() pthread_create() 创建新的控制线程
thr_exit() pthread_exit() 终止执行调用线程
thr_join() pthread_join() 暂停调用线程,直到目标线程完成
thr_kill() pthread_kill() 向其他线程发送信号
thr_self() pthread_self() 返回调用进程的线程 ID
thr_yield() sched_yield() 用其他线程替换当前线程
thr_getprio() pthread_getschedparam() 获取线程的优先级参数
thr_setprio() pthread_setschedparam() 修改线程的优先级参数
thr_getspecific() pthread_getspecific() 将新的线程特定值绑定到特定键
thr_setspecific() pthread_setspecific() 将新的线程特定值绑定到特定键
thr_getconcurrency() pthread_getconcurrency() 获取线程并发级别
thr_setconcurrency() pthread_setconcurrency() 设置线程并发级别
thr_sigsetmask() pthread_sigmask() 更改或检查调用线程的信号掩码
thr_keycreate() pthread_key_create() 创建确定线程特定数据的位置的键
N/A pthread_key_delete() 删除确定线程特定数据的位置的键
thr_suspend() N/A 暂停执行指定的线程
thr_continue() N/A 继续执行暂停的线程
fork1() fork() 常规分支
forkall() N/A 复制所有分支

在 Solaris 9 及其更早的版本中,fork() 的行为与 POSIX 线程中 fork() 的行为不同。在 POSIX 线程中,fork() 创建新的进程,复制子进程中的全部地址空间。不过,它只复制子进程中的调用线程。Solaris 线程 API 还提供复制所有分支语义的 forkall()。该函数复制子进程中的地址空间和所有线程。POSIX 线程标准不支持这个特性。

有一些 POSIX 线程例程在 Solaris 中可以实现,但在 Linux 中却无法实现,反之亦然。表 8 列出了这些例程:

表 8. POSIX 线程例程

例程 Solaris Linux
pthread_cond_reltimedwait_np y n
pthread_mutexattr_getrobust_np y n
pthread_mutexattr_setrobust_np y n
pthread_mutex_consistent_np y n
pthread_mutex_reltimedlock_np y n
pthread_rwlock_reltimedrdlock_np y n
pthread_rwlock_reltimedwrlock_np y n
pthread_attr_getaffinity_np n y
pthread_attr_setaffinity_np n y
pthread_cleanup_pop_restore_np n y
pthread_cleanup_push_defer_np n y
pthread_getattr_np n y
pthread_kill_other_threads_np n y
pthread_rwlockattr_getkind_np n y
pthread_rwlockattr_setkind_np n y
pthread_timedjoin_np n y
pthread_tryjoin_np n y

2.6 版之前发行的所有 Linux 版本中的 Linux 线程库都称为 LinuxThreads。该库自 glibc 2.0 以来已经得到 GNU C 库支持,而且在很大程度上与 POSIX 是兼容的。从 2.6 内核开始,引入了新的经过改善的线程库,称为 Native POSIX Threading Library(NPTL)。该实现在 LinuxThreads 之上提供了显著的性能提高。NPTL 与 POSIX 规范的兼容性也强于 LinuxThreads 包与 POSIX 规范的兼容性。然而,只使用 2.6 内核并不意味着就使用了 NPTL。发出下列命令可以查看正在使用的 POSIX 实现:

$ getconf GNU_LIBPTHREAD_VERSION

NPTL 实现一对一线程模型,在该模型中,用户线程与内核线程之间存在一对一的关系。NPTL 还实现进程间 POSIX 同步原语。特别是线程选项 PTHREAD_PROCESS_SHARED 现在已受支持。在默认情况下,创建每个线程时,detachstate 属性被设为 PTHREAD_CREATE_JOINABLE,调用策略设为 SCHED_OTHER,而且没有用户提供的堆栈。

如果 Solaris 应用程序使用 POSIX 线程 API,那么将其移植到 Linux 会非常简单。注意,即使使用 GCC,Solaris 也不支持 NPTL。表 9 显示了 Linux 中 POSIX 线程属性的默认值:

表 9. Linux 中 POSIX 线程属性的默认值

属性 默认值
scope PTHREAD_SCOPE_SYSTEM
detachstate PTHREAD_CREATE_JOINABLE
schedparam 0
inhiritsched PTHREAD_EXPLICIT_SCHED
schedpolicy SCHED_OTHER

虽然许多应用程序将从 2.4 内核迁移到 2.6,而无需重新编译,但是增加 NPTL 可能需要在多线程应用程序中进行少量的修改。关于如何通过使用 LinuxThreads 将应用程序迁移到 NPTL 超出了本文的范围。LinuxDevices.com 上的文章 “Migrating to Linux kernel 2.6” 提供其他相关信息(见 参考资料)。




?

性能调优

一旦在 Linux 中移植并成功执行了代码,需要完成性能监控和性能调优,以确保移植的代码在目标平台上可以正常执行。这一节将提供 Linux on POWER 中可以使用的工具列表,帮助您完成以上操作。

常用性能调优工具

两个常用的工具(sysstat 包 和 nmon)使得性能监控和调优更加容易:

sysstat 包包含用于基础性能监控的通用扩展工具,包括 mpstat、iostat 和 sar 等工具。

nmon 将各种经典的系统监控工具集成到一个一站式的数据收集工具中。此外,还包含许多方便使用的后期处理插件,可用于收集、绘制和合并信息。

OProfile

Oprofile 基于硬件相关事件(比如缓存遗漏或 CPU 周期)提供代码的配置文件。例如,Oprofile 可以帮助确定是哪个源例程导致大部分缓存遗漏。Oprofile 使用包括 IBM POWER4?、POWER5?、POWER6? 和 PowerPC? 970 在内的许多 CPU 中提供的硬件性能计数器。有关的

[责任编辑:赵航]
咸师
中国企业信息化从90年代初期开始起步,经过20年的发展,许多企业尤其是大中型企业的IT架构已经搭建完毕。但是,中国企业信息化建设有一个非常显著的特点是,IT系统建设是根据企业各个阶段的需求完成,并没有一个整体的规划。这就导致企业各个IT系统是孤立的,各个系统无法有效地连接起来。
官方微信
weixin
精彩专题更多
存储风云榜”是由DOIT传媒主办的年度大型活动。回顾2014年,存储作为IT系统架构中最基础的元素,已经成为了推动信息产业发展的核心动力,存储产业的发展迈向成熟,数据经济的概念顺势而为的提出。
华为OceanStor V3系列存储系统是面向企业级应用的新一代统一存储产品。在功能、性能、效率、可靠性和易用性上都达到业界领先水平,很好的满足了大型数据库OLTP/OLAP、文件共享、云计算等各种应用下的数据存储需求。
联想携ThinkServer+System+七大行业解决方案惊艳第十六届高交会
 

公司简介 | 媒体优势 | 广告服务 | 客户寄语 | DOIT历程 | 诚聘英才 | 联系我们 | 会员注册 | 订阅中心

Copyright © 2013 DOIT Media, All rights Reserved. 北京楚科信息技术有限公司 版权所有.