相关的Issue

#I4O67U:shell相关代码master分支同步到3.0LTS

原因(目的、解决的问题等)

Issue中提及Ctrl+C处理异常的原因是因为mksh、用户态shell等对于console->pgrpId设置错误。在console->pgrpId=默认值-1的情况下,KillPgrp意味着Kill所有进程,导致关键的几个用户态进程全部退出,和预期不符。

  • 用户态shell需要正确维护前台进程。
  • 由硬中断触发的回调函数处于中断上下文并非进程上下文中,KillPgrp()不应该使用OsCurrProcessGet()获取consoleID,否则获取到的进程可能并非是关联我们期望的console的进程(比如,大概率会命中KIdle进程)。
  • KillPgrp()不应该有杀死所有进程的逻辑。
  • mksh启动时会先调用tcgetpgrp()获取前台进程组。由于此时console->pgrpId尚未初始化具有-1的默认值,会导致tcgetpgrp()返回-1,mksh误以为调用失败,后续不再维护前台进程组。

描述(做了什么,变更了什么)

  • 用户态shell需要正确维护前台进程。fork的子进程设置前台进程为自身(现有逻辑),父进程等待子进程退出,然后调用tcsetpgrp设置前台进程为自身。
  • KillPgrp()改成由调用方传入consoleID。
  • KillPgrp()对-1的默认值做保护。
  • 支持非交互式shell直接通过exec执行外部命令。init先拉起shell,由shell充当类似linux中/usr/bin/login的角色,初始化正确的前台进程组,再拉起mksh。

测试用例(新增、改动、可能影响的功能)

qemu测试,启动后拉起mksh正常

[ERR][bundle_daemon:thread2]ServiceManager not set!
[ERR][bundle_daemon:thread2]ServiceManager not set!
[ERR][wms_server:thread3]ServiceManager not set!
[ERR][bundle_daemon:thread2]ServiceManager not set!
[ERR][wms_server:thread3]ServiceManager not set!
[ERR][bundle_daemon:thread2]ServiceManager not set!
[ERR][wms_server:thread3]ServiceManager not set!
[ERR][bundle_daemon:thread2]ServiceManager not set!

OHOS:/$ 

  allCpu(%):    5.41 sys,   94.59 idle

  PID  PPID PGID       UID  Status VirtualMem ShareMem PhysicalMem CPUUSE10s  PName
    1    -1    1         0 Pending   0x333000  0xb3000     0x58f11      0.0   init                            
    2    -1    2         0 Pending   0x458854        0    0x458854      0.65  KProcess                        
    3     1    3         2 Pending   0x1f3000  0x3f000     0x485cd      0.0   mksh

mksh启动后键入Ctrl+C,mksh另起一行,未杀死其他用户态关键系统进程

OHOS:/$ 
OHOS:/$ ^C
OHOS:/$

mksh拉起ping,键入Ctrl+C,正常终止前台进程(未打印statistics)

OHOS:/$ ping 127.0.0.1
Ping 127.0.0.1 (127.0.0.1): 56(84) bytes.
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms

OHOS:/$ ^C
OHOS:/$ 

mksh拉起一个后台进程,mksh再拉起一个前台进程,后台进程未停止,前台进程正常停止(statistics只打印了一次)

OHOS:/$ ^C
OHOS:/$ ping 127.0.0.1 -c 10 &
[1] 11
OHOS:/$ Ping 127.0.0.1 (127.0.0.1): 56(84) bytes.
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=0 ms
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms

OHOS:/$ ping 127.0.0.1 -c 10 &84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms

Ping 127.0.0.1 (127.0.0.1): 56(84) bytes.
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=310 ms
……
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=7 ms

OHOS:/$ ^C
OHOS:/$ 84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=3 ms
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=4 ms
……
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms

--- 127.0.0.1 ping statistics ---
10 packets transmitted, 24 received, 429496589% packet loss
round-trip min/avg/max = 0/0/53 ms

[1] + Done                 \toybox ping 127.0.0.1 -c 10 
OHOS:/$ 

qemu拉起shell,键入Ctrl+C,未杀死其它用户态关键系统进程

OHOS:/$ ^C
OHOS:/$ shell
OHOS # 
:command not found
OHOS # 

shell拉起ping,键入Ctrl+C,正常终止前台进程(未打印statistics)

OHOS # cd bin
OHOS # ./toybox ping 127.0.0.1
Ping 127.0.0.1 (127.0.0.1): 56(84) bytes.
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=0 ms
84 bytes from 127.0.0.1: icmp_seq=0 ttl=0 time=1 ms
OHOS # 

退出shell,mksh保持了正常运行

OHOS # kill -9 13
Killed 
OHOS:/$ ps

  allCpu(%):    2.82 sys,   97.18 idle

  PID  PPID PGID       UID  Status VirtualMem ShareMem PhysicalMem CPUUSE10s  PName
    1    -1    1         0 Pending   0x333000  0xb4000     0x58711      0.0   init                            
    2    -1    2         0 Pending   0x463d48        0    0x463d48      0.90  KProcess                        
    3     1    3         2   Ready   0x1f3000  0x40000     0x47dcd      0.8   mksh
……

通过绝对路径令shell执行外部命令和内部命令正常

OHOS:/$ /bin/shell exec /bin/toybox
chgrp chmod chown cp date du free help ifconfig kill ls mkdir mount
mv ping ps reboot rm rmdir top touch umount uname 
OHOS:/$ /bin/shell ls                                                          
Directory /bin:
-r-xr-xr-x 18344    u:0     g:0     bm        
-r-xr-xr-x 10980    u:0     g:0     aa        
-r-xr-xr-x 176004   u:0     g:0     mksh      
-r-x------ 42900    u:0     g:0     init      
-r-xr-xr-x 16384    u:0     g:0     tftp      
-r-xr-xr-x 5500     u:0     g:0     trace     
-r-x------ 21480    u:0     g:0     shell     
-r-xr-xr-x 73584    u:0     g:0     toybox    
-r-xr-xr-x 10208    u:0     g:0     sample_window
-r-xr-xr-x 46304    u:0     g:0     bundle_daemon
-r-x------ 3840     u:7     g:7     foundation
-r-xr-xr-x 11836    u:0     g:0     appspawn  
-r-xr-xr-x 32556    u:0     g:0     wms_server
-r-xr-xr-x 6704     u:0     g:0     os_dump   
-r-xr-xr-x 3336     u:0     g:0     softbus_server
-r-xr-xr-x 369332   u:0     g:0     sample_ui 
-r-xr-xr-x 10220    u:0     g:0     simple_ui_demo
-r-xr-xr-x 343544   u:0     g:0     deviceauth_service
-r-xr-xr-x 369580   u:0     g:0     sample_auto_ui
-r-x------ 6492     u:4     g:4     hidumper  
-r-xr-xr-x 7108     u:0     g:0     hilogcat  
-r-x------ 9360     u:4     g:4     apphilogcat
OHOS:/$