集群系统MOSIX分析(6)_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3447 | 回复: 0   主题: 集群系统MOSIX分析(6)        下一篇 
cc
注册用户
等级:中校
经验:1900
发帖:195
精华:0
注册:2011-7-25
状态:离线
发送短消息息给cc 加好友    发送短消息息给cc 发消息
发表于: IP:您无权察看 2011-9-5 11:31:47 | [全部帖] [楼主帖] 楼主

由于MOSIX的一个实现目标就是透明性,给用户一个单系统印象(SSI)。MOSIX实现了迁移进程的位置无关性,用户和应用并不需要知道进程已被迁移走。即使节点A上的进程a被迁移走,A上的用户通过ps -ax命令仍能看到进程a,似乎进程a并未迁移走 。另外,在前面介绍的迁移过程中,并没有迁移进程的打开文件。但是remote进程仍能正常处理文件的读写,并保持与其它进程的网络通讯。通过deputy和remote的交互配合,MOSIX系统实现了很高的透明性。

大多数处理器都有几种执行状态,如:核心态和用户态。操作系统内核运行在核心态,用户进程运行在用户态。用户进程不能直接执行运行在核心态的内核代码或者存取操作系统内核的数据结构。这种方法保护了操作系统内核,提高了系统的安全性。系统运行模式的区分虽然带来了安全性,但同时也带来了不便。因为系统的许多工作必须由内核代码完成(如创建进程、分配内存、驱动设备等),用户程序无法、也不能直接做这些工作。但用户程序又不得不做这些工作(如创建子进程等),因此操作系统必须提供一种机制让用户程序能在用户代码段中调用操作系统内核的函数。这就是通过系统调用。在MOSIX中,remote部分是对用户级的封装,而deputy则是进程内核级的封装,进程通过系统调用进入核心态,在MOSIX中是怎么处理的呢?

当进程迁移成功后,deputy和remote之间仍然保持着迁移中建立起来的那条通讯连接。 Remote则按照程序流程,恢复执行,当遇到系统相关的系统调用或资源请求时,如果不能在本地处理,则向deputy发送请求,然后等待Deputy处理后的结果。Deputy在进程迁移后,一直处于核心态中,等待remote发送的请求,然后根据请求类型,作出相应的处理,将处理结果回复给remote。

系统调用的处理

MOSIX中,位置透明性是通过将节点相关的系统调用转发到home节点上的deputy来实现的。系统调用是用户上下文和系统上下文之间的一种同步的交互形式。进程执行的所有系统调用都被远程节点的连接层所截获。如果是节点无关的,则在远程节点上本地执行。否则,系统调用将被转发给deputy,deputy则代表home节点上的进程执行该系统调用。结果返回给Remote,Remote然后从系统调用返回,继续执行用户代码。

我们知道,进程是通过系统调用进入核心态的,请求OS提供服务。在Linux中,系统调用处理程序地址都保存在表sys_call_table中。【kernel/entry.S】中定义了系统调用的入口ENTRY(system_call),通过系统调用号查找sys_call_table表,找到对应的系统调用处理程序并调用之。MOSIX中则定义了一个相应的remote_sys_call_table,并修改了ENTRY(system_call)。

在ENTRY(system_call)中,首先判断进程是否为Remote。如果是,则查找remote_sys_call_table;否则查找sys_call_table。对于本地的非remote进程,对系统调用的处理和通常的一样,大家都很熟悉。我们主要介绍对remote进程系统调用的处理情况。remote_sys_call_table中保存的为对应的系统调用的remote版本,对于大多数系统相关的调用的处理都是remote发送请求给deputy,再由deputy调用本地相应的处理函数处理的,然后将结果返回给remote。

对于remote进程的各种系统调用,处理方式也各不一样。有的只是直接调用原有的系统调用,并不作改变,像remote_sys_brk,remote_sys_mprotect等。有的则作些额外处理,然后通过remote_standard_system_call来实现。remote_standard_system_call将系统调用的参数封装成syscall_h包,然后向Deputy发送请求,请求类型为REM_SYSCALL,然后等待Deputy的回复消息(remote_wait(REM_SYSCALL|REPLY,,) )。Deputy一直在deputy_main_loop中一直循环等待消息的到来,当收到请求后,判断其类型,并作相应的处理。对于 REM_SYSCALL请求,则调用deputy_syscall( )处理。deputy_syscall则从传入的参数中取出系统调用号,拷贝寄存器值,然后根据系统调用号查找系统调用表syscall_table中对应的处理例程,由它完成真正的处理过程。然后,开中断,通过deputy_reply(REM_SYSCALL,,)发回响应消息和处理结果。

deputy这种方式将会给系统调用的执行带来不少的开销,主要是网络延迟。而系统调用是比较频繁的,因此这会给进程的执行带来一部分代价。



从系统调用返回

在系统调用最终真正返回,回到用户态之前,将会转到straight_to_mosix标号,调用mosix_pre_usermode_actions,在返回用户态之前作些MOSIX系统相关的处理工作。首先对当前进程的性质进行判断。

如果当前进程是REMOTE,则调用remote_pre_usermode_actions()。首先检查deputy是否还需要它在核心态中为其做某些处理工作,如果是,则睡眠等待直到deputy的允许进程继续运行。然后检查是否处于错误的节点,如果是,则设置需要迁移回home节点。如果出现紧急事件,如前面设置需要迁移回home节点,则通知deputy有紧急事件发生。最后,如果存在未处理的异步信号或内核强制投递的信号,则将信号转发给deputy处理。

如果是DEPUTY,则调用deputy_main_loop(),根据DEPUTY的特性,我们知道它只是REMOTE在HOME节点的剩余,它应该主要处理和REMOTE的交互,而不是作实际的进程处理工作(计算或IO)。所以DEPUTY进程应该在deputy_main_loop()中循环等待和REMOTE的交互,直到意外死亡或不再是DEPUTY。这就是我们前面所说为什么deputy一直处于核心态的原因。

当前进程应该是本地的普通节点,作local_pre_usermode_actions()。首先做负载信息的衰退工作。如果进程被选中迁移了,则调用follow_whereto()迁移之。每个进程都不是独立的,不可能不受系统运行其它进程的影响。如果其它进程对本进程告知了某些请求,则必须检查并处理它。下面是一些考虑的请求:
DREQ_CHECKCONF:请求该进程检查MOSIX配置。
DREQ_CAPCNG:进程的权能被改变了。
DREQ_DFSASYNC:DFSA改变,需要被同步
DREQ_CHECKSTAY:检查进程是否需要继续呆在当前节点。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论