講義教程案例linux-init process analyse_第1頁
講義教程案例linux-init process analyse_第2頁
講義教程案例linux-init process analyse_第3頁
講義教程案例linux-init process analyse_第4頁
講義教程案例linux-init process analyse_第5頁
已閱讀5頁,還剩120頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、init 進(jìn)程探悉前言2INIT配置文件分析4INIT的資料9INIT命令的手冊(cè)9配置文件/ETC/INITTAB的手冊(cè)15INIT詳細(xì)分析21INIT PROCESS是怎么被啟動(dòng)的?21INIT進(jìn)程分析26init 1 的運(yùn)行27主流程分析27輔助函數(shù)介紹54init 2 的運(yùn)行68init 3 的運(yùn)行74主流程分析74輔助函數(shù)82后記98. 99附錄100環(huán)境100INITTAB中ACTION的注解100關(guān)機(jī)分析101關(guān)機(jī)流程介紹101Shutdown源碼106前言init是個(gè)普通的用戶態(tài)進(jìn)程,它是Unix系統(tǒng)內(nèi)核初始化與用戶態(tài)初始化的接合點(diǎn),它是所有process的祖宗。在運(yùn)行init以

2、前是內(nèi)核態(tài)初始化,該過程(內(nèi)核初始化)的最后一個(gè)動(dòng)作就是運(yùn)行/sbin/init可執(zhí)行文件。從init process運(yùn)行開始進(jìn)入U(xiǎn)nix系統(tǒng)的用戶態(tài)初始化。我對(duì)整個(gè)系統(tǒng)初始化的定義是從開機(jī)到屏幕上出現(xiàn)登錄界面為止。這整個(gè)過程被init一分為二。當(dāng)然init不單單啟動(dòng)了用戶態(tài)的初始化,而且它在系統(tǒng)運(yùn)行的整個(gè)期間都扮演著非常重要的角色。比如在運(yùn)行當(dāng)中,具有 root 權(quán)限的用戶可以通過再次運(yùn)行 init 來切換到不同的運(yùn)行級(jí)別(run level) init process 有認(rèn)領(lǐng)系統(tǒng)中的所有孤兒進(jìn)程的責(zé)任當(dāng) root 權(quán)限用戶想通過按 Ctrl-Ael 三鍵來重啟系統(tǒng),也是由 init 最終來

3、處理的如果你想要一個(gè) daemon 進(jìn)程有這樣的效果,它在整個(gè)系統(tǒng)運(yùn)行期間一直要運(yùn)行,即使它由于各種各樣的原因(如在某種情況下它出錯(cuò)而退出了,或被某個(gè)用戶 kill 掉了)停止運(yùn)行了,也希望能馬上被再次啟動(dòng)(當(dāng)然不是依靠人力來手工啟動(dòng)),你可以在 init 運(yùn)行的配置文件中加入類是與下面的一行:myrun:ondemand:/home/wzhou/mydaemon則/home/wzhou/mydaemon 這個(gè)腳本只要系統(tǒng)在運(yùn)行,它必然也在運(yùn)行。即使有人把它 kill 掉,等一會(huì)兒馬上又會(huì)被 init process 啟動(dòng)等等而這一切都依賴于 init process。init 配置文件分析i

4、nit process的運(yùn)行完全受其配置文件/etc/inittab的控制,這里分析一下該配置文件。來個(gè)現(xiàn)實(shí)系統(tǒng)中的/etc/inittab 配置文件來解釋一下。wzhoudcmp10 $ cat /etc/inittab # inittabThis file describes how the INIT process should set up #the system in a certain run-level.# Author:Miquel van Smoorenburg, <> #Modified for RHS L

5、inux by Marc Ewing and Donnie Barnes # Default runlevel. The runlevels used by RHS are:#0 - halt (Do NOT set initdefault to this) #1 - Single user mode#2 - Multiuser, without NFS (The same as 3, if you do not have networking) #3 - Full multiuser mode#4 - unused#5 - X11#6 - reboot (Do NOT set initdef

6、ault to this) #id:5:initdefault:# System initialization. si:sysinit:/etc/rc.d/rc.sysinitl0:0:wait:/etc/rc.d/rc 0l1:1:wait:/etc/rc.d/rc 1l2:2:wait:/etc/rc.d/rc 2l3:3:wait:/etc/rc.d/rc 3這一行表示系統(tǒng)啟動(dòng)后將運(yùn)行在 run level 5,即 X Window 的 Full multiuser modesysinit 表示這是用戶態(tài)系統(tǒng)啟動(dòng),不管任何運(yùn)行級(jí)別(run level)都要執(zhí)行/etc/rc.d/rc.s

7、ysinit如果你要追蹤操作系統(tǒng)內(nèi)核態(tài)的初始化過程,則要從 init/main.c 中的 start_kernel()開始;而如果你想追蹤操作系統(tǒng)用戶態(tài)的啟動(dòng)過程,則可以從/etc/rc.d/rc.sysinit開始。si:sysinit:/etc/rc.d/rc.sysinitid:5:initdefault:l4:4:wait:/etc/rc.d/rc 4l5:5:wait:/etc/rc.d/rc 5l6:6:wait:/etc/rc.d/rc 6# Trap CTRL-AELETEca:ctrlael:/sbin/shutdown -t3 -r now# When our UPS te

8、lls us power has failed, assume we have a few minutes # of power left. Schedule a shutdown for 2 minutes from now.# This does, of course, assume you have powerd installed and your # UPS connected and working correctly.pf:powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down&quo

9、t;# If power was restored before the shutdown kicked in, cancel it. pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"# Run gettys in standard runlevels 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:

10、respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6# Run xdm in runlevel 5 x:5:respawn:/etc/X11/prefdm -nodaemon顯然/etc/rc.d/rc 也是個(gè)系統(tǒng)初始化的很重要的所代表的 process 的完成。上面的 wait action 表示 init process 在啟動(dòng)其他的動(dòng)作以前,必須等待該行上的動(dòng)作這一行表示無論在什么 run level,如果 root 用戶按了 Ctrl+A/sbi

11、n/shutdown -t3 -r nowel 三鍵則運(yùn)行如下命令:即讓 init 進(jìn)程監(jiān)視 Ctrl+Ael,一旦收到,它應(yīng)當(dāng)運(yùn)行該命令。shutdown 命令會(huì)從現(xiàn)在(now)開始先向系統(tǒng)中的所有進(jìn)程發(fā)warning,然后等待 3 秒,再殺死進(jìn)程,讓系統(tǒng)重啟。從上面的注釋可以知道該行的動(dòng)作。同樣該行是不分 run level 的,是否發(fā)生“powerfail”的。在運(yùn)行級(jí)別為 1,2,3,4,5 的情況下,如果發(fā)生“powerokwait” action,則運(yùn)行命令/sbin/shutdown -c "Power Restored; Shutdown Cancelled"

12、;,即取消發(fā)出的關(guān)機(jī)指令。# Run gettys in standard runlevels 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3# If power was restored before the shutdown kicked in, cancel it. pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled&qu

13、ot;# When our UPS tells us power has failed, assume we have a few minutes # of power left. Schedule a shutdown for 2 minutes from now.# This does, of course, assume you have powerd installed and your # UPS connected and working correctly.pf:powerfail:/sbin/shutdown -f -h +2 "Power Failure; Syst

14、em Shutting Down"ca:ctrlael:/sbin/shutdown -t3 -r nowl0:0:wait:/etc/rc.d/rc 0 如果系統(tǒng)的 run level 是 0,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 0 l1:1:wait:/etc/rc.d/rc 1 如果系統(tǒng)的 run level 是 1,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 1 l2:2:wait:/etc/rc.d/rc 2 如果系統(tǒng)的 run level 是 2,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 2 l3:3:wait:/etc/rc.d/rc 3 如果系統(tǒng)的 run lev

15、el 是 3,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 3 l4:4:wait:/etc/rc.d/rc 4 如果系統(tǒng)的 run level 是 4,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 4 l5:5:wait:/etc/rc.d/rc 5 如果系統(tǒng)的 run level 是 5,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 5 l6:6:wait:/etc/rc.d/rc 6 如果系統(tǒng)的 run level 是 6,則運(yùn)行/etc/rc.d/rc ,參數(shù)為 6上面的 6 行指示 init process 在run level 是 2,3,4,5 的情況下,運(yùn)行到 tty6 的終端上啟動(dòng)字符登

16、陸界面。/sbin/mingetty,并接受不同的參數(shù)。這里的功能是在從 tty1上圖中用藍(lán)框圍起來的就是啟動(dòng)的 6 個(gè)虛擬終端。我用 root 帳號(hào)登錄在 tty1,所以該終端顯示“l(fā)ogin - root”,而其他 5 個(gè)虛擬終端并沒有用戶登錄,所以還是由 mingetty 在等待著。# Run xdm in runlevel 5 x:5:respawn:/etc/X11/prefdm -nodaemon4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/min

17、getty tty6該行表示如果 run level 是 5,則要運(yùn)行腳本/etc/X11/prefdm nodaemon,其實(shí)就是啟動(dòng) X Window,進(jìn)入 GUI 界面。上面是對(duì) inittab 配置文件的靜態(tài)的解釋,下面解釋 init process 依據(jù)該配置文件動(dòng)態(tài)運(yùn)行情況。init process 由“initdefault”知道系統(tǒng)將在 run level 5 下運(yùn)行init process 首先運(yùn)行“sysinit”標(biāo)注的 action,即運(yùn)行/etc/rc.d/rc.sysinit 腳本運(yùn)行 identifier 為“l(fā)5”的動(dòng)作l5:5:wait:/etc/rc.d/rc

18、 5由于該行告訴 init process 的反映是“wait”,即在 init process 繼續(xù)執(zhí)行 inittab 配置文件中其他 action 以前,必須等待“/etc/rc.d/rc 5”的結(jié)束接下來執(zhí)行下面的 6 個(gè) action 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:

19、2345:respawn:/sbin/mingetty tty6由于上面 6 行的 run level 告訴 initprocess,在 2,3,4,5 之下都要執(zhí)行這里的命令“/sbin/mingetty tty5”。同時(shí)這里的“respawn”表示如果/sbin/mingetty 所代表的 process 不運(yùn)行了(無論哪種情況,是自己退出或出現(xiàn)問題而 crash),init process 都有責(zé)任讓他再次運(yùn)行。當(dāng)啟動(dòng) Linux 后我們通過 Alt-F1,Alt-F6 可以切換到相應(yīng)的終端,就是這幾行運(yùn)行的緣故。另外,當(dāng)你登錄到某個(gè)終端,比如 tty1,然后在命令行上輸入 exit,在

20、該終端上又會(huì)出現(xiàn)登錄界面,這就是 init process 在響應(yīng)“respawn”動(dòng)作。當(dāng)你輸入 exit 時(shí),/sbin/mingetty 代表的 process 退出,被 init process 監(jiān)控到,馬上在該終端上又運(yùn)行“/sbin/mingetty tty1”,從而在退出的tty1 上再次出現(xiàn)登錄界面。最后運(yùn)行的是/etc/X11/prefdm nodaemon,即啟動(dòng) X Window 登錄。在配置文件中的下面的配置行并不會(huì)執(zhí)行,但會(huì)被 init process 紀(jì)錄狀態(tài)。只有當(dāng)系統(tǒng)出現(xiàn)對(duì)應(yīng)的情況時(shí),才會(huì)運(yùn)行。ca:ctrlael:/sbin/shutdown -t3 -r n

21、owpf:powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"比如當(dāng) root 用戶按了 Ctrl-Ael 鍵以后,init process 將執(zhí)行如下命令行“/sbin/shutdown-t3 -r now”進(jìn)行關(guān)機(jī);而當(dāng)UPS 報(bào)告電源出現(xiàn)故障,馬上要斷電時(shí),就執(zhí)行“/sbin/shutdown-f -h +2

22、"Power Failure; System Shutting Down"”;當(dāng)UPS 報(bào)告從電源故障恢復(fù)以后,執(zhí)行“/sbin/shutdown -c "Power Restored; Shutdown Cancelled"”。那么 init process 是怎么感知這些消息的呢?即該進(jìn)程怎么知道 root 權(quán)限用戶按下了 Ctrl-Ael 鍵,UPS 報(bào)告電源出現(xiàn)故障及電源恢復(fù)呢?都是通過 Unix特有的 signal 機(jī)制。對(duì) init process 來說,它只要正確處理對(duì)應(yīng)的 signal 就好。init 的資料init 的作者親手寫了與 i

23、nit 相關(guān)的手冊(cè),即 man init 與 man inittab。仔細(xì)看看,對(duì)理解 init process 有很大幫助。init 命令的手冊(cè)NAMEinit, telinit - process control initializationSYNOPSIS/sbin/init -a -s -b -z 0123456Ss /sbin/telinit -t sec 0123456sS abcUu DESCRIPTIONInitInit is the parent of all processes. Its primary role is to create processes from a

24、script stored in the file /etc/inittab (see inittab(5). This file usually has entries which cause init to spawn gettys on each line that users can log in. It also controls autonomous processes required by any particular system.RUNLEVELSA runlevel is a software configuration of the system which allow

25、s only a selected group of processes to exist. The processes spawned by init for each of these runlevels are defined in the /etc/inittab file. Init can be in one of eight runlevels: 0â“6 and S or s. The runlevel is changed by having a priv- ileged user run telinit, which sends appropriate signa

26、ls to init, telling it which runlevel to change to.Runlevels 0, 1, and 6 are . Runlevel 0 is used to halt the system, runlevel 6 is used to reboot the system, and runlevel 1 is used to get the system down into single user mode. Runlevel S is not really meant to be used directly, but more for the scr

27、ipts that are executed when entering runlevel 1. For more information on this, see the manpages for shutdown(8) and inittab(5).Runlevels 7-9 are also valid, though not really documented. This is because "traditional" Unix variants donât use them. In case youâre curious, runlevels

28、 S and s are in fact the same. Internally they are aliases for the same run- level.BOOTINGAfter init is invoked as the last step of the kernel boot sequence, it looks for the file /etc/inittab to see if there is an entry of the type initdefault (see inittab(5). The initdefault entry determines the i

29、nitial runlevel of the system. If there is no such entry (or no /etc/inittab at all), a runlevel must be entered at the system console.Runlevel S or s bring the system to single user mode and do not require an/etc/inittab file.In single user mode, a root shell is opened on /dev/con- sole.When enteri

30、ng single user mode, init initializes the consoles stty settings to sane values. Clocal mode is set. Hardware speed and handshaking are not changed.When entering a multi-user mode for the first time, init performs the boot and bootwait entries to allow file systems to be mounted before users can log

31、 in. Then all entries matching the runlevel are processed.When starting a new process, initfirstcheckswhetherthefile/etc/initscript exists. If it does, it uses this script to start the process.Each time a child terminates, init records the fact and the reason it died in/var/run/utmp and /var/log/wtm

32、p, provided that these files exist.CHANGING RUNLEVELSAfter it has spawned all of the processes specified, init waits for one of its descendant processes to die, a powerfail signal, or until it is signaled by telinit to change the systemâs runlevel. When one of the above three condi- tions occur

33、s, it re-examines the /etc/inittab file. New entries can be added to this file at any time. However, init still waits for one of the above three conditions to occur. To provide for an instantaneous response, the telinit Q or q command can wake up init to re-examine the /etc/inittab file.If init is n

34、ot in single user mode and receives a powerfail signal (SIGPWR), it reads the file /etc/powerstatus. It then starts a command based on the con- tents of this file:F(AIL) Power is failing, UPS is providing the power. Execute the powerwait and powerfail entries.O(K) The power has been restored, execut

35、e the powerokwait entries.L(OW) The power is failing and the UPS has a low battery. Execute the power- failnow entries.If /etc/powerstatus doesnât exist or contains anything else then the letters F, O or L, init will behave as if it has read the letter F.Usage of SIGPWR and /etc/powerstatus is

36、discouraged. Someone wanting to inter- act with init should use the /dev/initctl control channel - see the source code of the sysvinit package for more documentation about this.When init is requested to change the runlevel, it sends the warning signal SIGTERM to all processes that are undefined in t

37、he new runlevel. It then waits 5 seconds before forcibly terminating these processes via the SIGKILL signal. Note that init assumes that all these processes (and their descen- dants) remain in the same process group which init originally created for them. If any process changes its process group aff

38、iliation it will not receive these signals. Such processes need to be terminated separately.TELINIT/sbin/telinit is linked to /sbin/init. It takes a one-character argument and signals init to perform the appropriate action. The following arguments serve as directives to telinit:0,1,2,3,4,5 or 6tell

39、init to switch to the specified run level.a,b,c tell init to process only those /etc/inittab file entries having run- level a,b or c.Q or q tell init to re-examine the /etc/inittab file. S or s tell init to switch to single user mode.U or u tell init to re-execute itself (preserving the state). No r

40、e-examining of /etc/inittab file happens. Run level should be one of Ss12345, oth- erwise request would be silently ignored.telinit can also tell init how long it should wait between sending processes the SIGTERM and SIGKILL signals. The default is 5 seconds, but this can be changed with the -t sec

41、option.telinit can be invoked only by users with appropriate privileges.The init binary checks if it is init or telinit by looking at its process id; the real initâs process id is always 1. From this it follows that instead of calling telinit one can also just use init instead as a shortcut.ENV

42、IRONMENTInit sets the following environment variables for all its children: PATH/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/binINIT_VERSIONAs the name says. Useful to determine if a script runs directly from init.RUNLEVELThe current system runlevel.PREVLEVELThe previous runlevel (useful after a runlev

43、el switch).CONSOLEThe system console. This is really inherited from the kernel; however if it is not set init will set it to /dev/console by default.BOOTFLAGSIt is possible to pass a number of flags to init from the boot monitor (eg. LILO). Init accepts the following flags:-s, S, singleSingle user m

44、ode boot. In this mode /etc/inittab is examined and the bootup rc scripts are usually run before the single user mode shell is started.1-5 Runlevel to boot into.-b, emergencyBoot directly into a single user shell without running any other startup scripts.-a, autoThe LILO boot loader adds the word &q

45、uot;auto" to the command line if it booted the kernel with the default command line (without user interven- tion). If this is found init sets the "AUTOBOOT" environment variable to "yes". Note that you cannot use this for any security measures - of course the user could spec

46、ify "auto" or -a on the command line manually.-zThe argument to -z is ignored. You can use this to expand the command line a bit, so that it takes some more space on the stack. Init can then manipulate the command line so that ps(1) shows the current runlevel.INTERFACEInit listens on a fif

47、o in /dev, /dev/initctl, for messages. Telinit uses this to communicate with init. The interface is not very well documented or fin- ished. Those interested should study the initreq.h file in the src/ subdirec- tory of the init source code tar archive.SIGNALSInit reacts to several signals:SIGHUPHas

48、the same effetelinit q.SIGUSR1On receipt of this signals, init closes and re-opens its control fifo,/dev/initctl. Useful for bootscripts when /dev is remounted.SIGINTNormally the kernel sends this signal to init when CTRL-AEL is pressed. It activates the ctrlael action.SIGWINCHThe kernel sends this

49、signal when the KeyboardSignal key is hit. It activates the kbrequest action.CONFORMING TOInit is compatible with the System V init. It works closely together with the scripts in the directories /etc/init.d and /etc/rcrunlevel.d. If your sys- tem uses this convention, there should be a README file i

50、n the directory/etc/init.d explaining how these scripts work.FILES/etc/inittab/etc/initscript/dev/console/var/run/utmp/var/log/wtmp/dev/initctl配置文件/etc/inittab 的手冊(cè)INITTAB(5)Linux System Administrator's ManualINITTAB(5)NAMEinittab - format of the inittab file used by thepatible init processDESCRI

51、PTIONThe inittab file describes which processes are started at bootup and during normal operation (e.g. /etc/init.d/boot, /etc/init.d/rc, gettys.). Init(8) distinguishes multiple runlevels,WARNINGSInit assumes that processes and descendants of processes remain in the same process group which was ori

52、ginally created for them. If the processes change their group, init canât kill them and you may end up with two processes read- ing from one terminal line.DIAGNOSTICSIf init finds that it is continuously respawning an entry more than 10 times in 2 minutes, it will assume that there is an error

53、in the command string, generate an error message on the system console, and refuse to respawn this entry until either 5 minutes has elapsed or it receives a signal. This pre- vents it from eating up system resources when someone makes a typographical error in the /etc/inittab file or the program for

54、 the entry is removed.AUTHORMiquel van Smoorenburg (miquelscistron.nl), initial manual page by Michael Haardt (rmatik.rwth-aachen.de).SEE ALSOgetty(1), login(1), sh(1), runlevel(8), shutdown(8), kill(1), inittab(5), initscript(5), utmp(5)18 April 2003INIT(8)each of which can have its

55、 own set of processes that are started. Valid runlevels are 0-6 plus A, B, and C for ondemand entries. An entry in the inittab file has the following format:id:runlevels:action:process Lines beginning with '#' are ignored.idis a unique sequence of 1-4 characters which identifies an entry in

56、inittab (for ver- sions of sysvinit compiled with the old libc5 (< 5.2.18) or a.out libraries the limit is2 characters).Note: traditionally, for getty and other login processes, the value of the id field is kept the same as the suffix of the corresponding tty, e.g. 1 for tty1. Some ancient login

57、accounting programs might expect this, though I can't think of any.runlevelslists the runlevels for which the specified action should be taken. action describes which action should be cessspecifies the process to be executed. If the process field starts with a '+' character, init will not do utmp and wtmp accounting for that process. This is needed for gettys that insist on d

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論