apache的啟動過程原代碼分析_第1頁
apache的啟動過程原代碼分析_第2頁
apache的啟動過程原代碼分析_第3頁
apache的啟動過程原代碼分析_第4頁
apache的啟動過程原代碼分析_第5頁
已閱讀5頁,還剩23頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

ldhomeapachehttpdserverlsmaincmain.cuxlncxhomeapachehttpdserverconstcharconstargv{arconfnameSERVERCONFIGFILEhardefserverrootHTTPDROOTartemperrorlogNULLrorcessrecprocessrconfltpgloballtpconfaprpooltplogPooloflogstreams,reset_after_eachreadofconf*/aprpooltptempPoolfortemporaryconfigstuff,resetoften*/aprpooltpcommands*Poolfor-D,-Cand-cswitches*/topttoptatustrvmodule*mod;targAPR_OPTIONAL_FN_TYPE(ap_signal_server)*signal_server;AP_MONCONTROL(0);/*turnoffprofilingofstartup*/processinitprocessargc&argv);pglobalprocesspool;pconfprocesspconf;serverargvprocessshortnameHARSETEBCDICif(ap_init_ebcdic(pglobal)!=APR_SUCCESS){destroyandexitprocessprocess1);}poolcreatepcommandspglobalrpooltagpcommandspcommandsapserverprereadconfigaprarraymakepcommands1,sizeof(char*));apserverpostreadconfigaprarraymakepcommands1,sizeof(char*));apserverconfigdefinesaprarraymakepcommands1,sizeof(char*));tupprelinkedmodulesprocessif(error){aplogerrorAPLOGMARKAPLOGSTARTUPAPLOGEMERG0,NULL,"%s:%s",erverargverrordestroyandexitprocessprocess1);}rewriteargsprocessMaintainAPSERVERBASEARGSlistinhttp_main.htoallowtheMPM*tosafelypassonourargsfromitsrewrite_args()handler.aprgetoptinitoptpcommandsprocessargc,process->argv);while((rv=apr_getopt(opt,AP_SERVER_BASEARGS,&c,&optarg))==APR_SUCCESS){switch(c){newchar)apr_array_push(ap_server_post_read_config);newaprpstrduppcommandsoptarg);newchar)apr_array_push(ap_server_pre_read_config);newaprpstrduppcommandsoptarg);rootoptargnewchar)apr_array_push(ap_server_config_defines);newaprpstrduppcommandsoptarg);SettingDDUMP_VHOSTSisequivalenttosetting-S*/optargDUMPVHOSTSconfigtestonly=1;SettingDDUMP_MODULESisequivalenttosetting-M*/optargDUMPMODULESconfigtestonly=1;if(strcasecmp(optarg,"emerg")==0){aultloglevelAPLOGEMERG}elseif(strcasecmp(optarg,"alert")==0){aultloglevelAPLOGALERT}elseif(strcasecmp(optarg,"crit")==0){aultloglevelAPLOGCRIT}elseif(strncasecmp(optarg,"err",3)==0){aultloglevelAPLOGERR}elseif(strncasecmp(optarg,"warn",4)==0){aultloglevelAPLOGWARNING}elseif(strcasecmp(optarg,"notice")==0){aultloglevelAPLOGNOTICE}elseif(strcasecmp(optarg,"info")==0){apdefaultloglevelAPLOGINFO}elseif(strcasecmp(optarg,"debug")==0){aultloglevelAPLOGDEBUG}else{geprocess}perrorlogaprpstrdupprocesspooloptargnewchar)apr_array_push(ap_server_config_defines);ewDEBUGargprintfServerversionsn",ap_get_server_description());printfServerbuilts\n",ap_get_server_built());troyandexitprocessprocessngstroyandexitprocessprocessodulestroyandexitprocessprocessdirectivestroyandexitprocessprocessconfigtestonly=1;configtestonly=1;newchar)apr_array_push(ap_server_config_defines);wDUMPVHOSTSconfigtestonly=1;newchar)apr_array_push(ap_server_config_defines);wDUMPMODULESgeprocess}}badcmdlineoption?thenwedie*/if(rv!=APR_EOF||opt->ind<opt->argc){geprocess}poolcreateplogpglobalprpooltagplogplogpoolcreateptemppconfprpooltagptempptempNotethatwepreflighttheconfigfileonce*beforereadingit_again_inthemainloop.hisallowsthingslogfilesconfiguration*forexample,tosettledown.rverrootdefserverrootif(temp_error_log){apreplacestderrlogprocesspooltemp_error_log);}//*===========下面這一段是對配置文件進行處理==================*/erconfapreadconfigprocessptempconfnameapconftreeif(!server_conf){destroyandexitprocessprocess1);}if(ap_run_pre_config(pconf,plog,ptemp)!=OK){aplogerrorAPLOGMARKAPLOG_STARTUP|APLOG_ERR,0,NULL"Pre-configurationfailed");destroyandexitprocessprocess1);}rvapprocessconfigtreeserver_conf,ap_conftree,rocesspconfptempif(rv==OK){apfixupvirtualhostspconfserverconfapfinivhostconfigpconfserverconfooksortallif(configtestonly){untestconfigpconfserverconfaplogerrorAPLOGMARKAPLOGSTARTUPNULL,"SyntaxOK");destroyandexitprocessprocess;}}======上面這一段是對配置文件進行處理==================*/rverAPRRETRIEVEOPTIONALFNapsignalserverif(signal_server){if(signal_server(&exit_status,pconf)!=0){oyandexitprocessprocessexitstatus}}Ifourconfigfailed,dealwiththathere.*/if(rv!=OK){destroyandexitprocessprocess1);}lclearplogif(ap_run_open_logs(pconf,plog,ptemp,server_conf)!=OK){plogerrorAPLOGMARKAPLOGSTARTUPAPLOGERRNULLUnabletoopenlogs");destroyandexitprocessprocess1);}if(ap_run_post_config(pconf,plog,ptemp,server_conf)!=OK){aplogerrorAPLOGMARKAPLOG_STARTUP|APLOG_ERR,0,NULL"ConfigurationFailed");destroyandexitprocessprocess1);}ldestroyptempforfor(;;){ookderegisteralllclearpconffor(mod=ap_prelinked_modules;*mod!=NULL;mod++){egisterhooksmodpconf}Thisisahackuntilwefinishthecodesothatitonlyreads*theconfigfileonceandjustoperatesonthetreealreadyinmoryrbbreeNULLpoolcreateptemppconfprpooltagptempptemprverrootdefserverroot//*===========下面這一段是對配置文件進行處理,每次循環(huán)都要處理==================*/confapreadconfigprocessptempconfnameapconftreeif(!server_conf){destroyandexitprocessprocess1);}if(ap_run_pre_config(pconf,plog,ptemp)!=OK){plogerrorAPLOGMARKAPLOGSTARTUPAPLOGERRULLPreconfigurationfaileddestroyandexitprocessprocess1);}figtreeserverconfapconftreeprocesspconfptemp)!=OK){destroyandexitprocessprocess1);}apfixupvirtualhostspconfserverconfapfinivhostconfigpconfserverconfooksortalllclearplogif(ap_run_open_logs(pconf,plog,ptemp,server_conf)!=OK){plogerrorAPLOGMARKAPLOGSTARTUPAPLOGERRNULLUnabletoopenlogs");destroyandexitprocessprocess1);}if(ap_run_post_config(pconf,plog,ptemp,server_conf)!=OK){plogerrorAPLOGMARKAPLOGSTARTUPAPLOGERRLLConfigurationFaileddestroyandexitprocessprocess1);}======上面這一段是對配置文件進行處理,每次循環(huán)都要處理==================*/ldestroyptempaprpoollock(pconf,1);optionalfnretrieveaprpoollockpconf父父進程的這個循環(huán),每次都會重新讀入配置文件進行處理。然后調(diào)用ap_mpm_run()重新生成子進程。aprpoollockpconftroyandexitprocessprocessreturn/*Termination'ok'*/}mpmrunaprpooltpconfaprpooltplogserverrecs{tostartatustrvapap_log_pid(pconf,ap_pid_fname);tserverlimitserverlimitif(changed_limit_at_restart){aplog_error(APLOG_MARK,APLOG_WARNING,0,s,WARNING:AttempttochangeServerLimit"restartangedlimitatrestart}Initializecrossprocessacceptlock*/aplockfnameaprpsprintfpconfs.%"APR_PID_T_FMT,pserverrootrelativepconfaplockfnamervrv=apr_proc_mutex_create(&accept_mutex,ap_lock_fname,ceptlockmechpconfif(ap_accept_lock_mech==APR_LOCK_SYSVSEM){rvunixdsetprocmutexpermsacceptmutex);}if(!is_graceful){if(ap_run_pre_mpm(s->process->pool,SB_SHARED)!=OK){mpmstate=AP_MPMQ_STOPPING;return1;}fixthegenerationnumberintheglobalscore;wejustgotanew,edscoreboardapscoreboardimageglobalrunninggenerationapmygeneration;}Apachectlrestart,apachectlstop,apachectlgraceful,這些命令將會導(dǎo)致信號處理函數(shù)設(shè)定hutdownpendingestartpendingeisgracefulifif(one_process){APMONCONTROL);make_child(ap_server_conf,0);}else{ifapdaemonsmaxfreeapdaemonsminfreeDontthrash..*/ap_daemons_max_free=ap_daemons_min_free+1;*Ifwe'redoingagraceful_restartthenwe'regoingtoseealotofchildrenexitingimmediatelywhenwegetintothemainloopbelowbecausewejustsentthemAPSIG_GRACEFUL).Thishappensprettyrapidlyandforeachonethatexitswe'llstartanewoneuntilwereachatleastdaemonsminfreeButwemaybepermittedtostartmorethanthatsowelljustkeeptrackofhowmanywe'resupposedtostartupwithoutthesecondpenaltybetweeneachfork.remainingchildrentostartap_daemons_to_start;if(remaining_children_to_start>ap_daemons_limit){remainingchildrentostart=ap_daemons_limit;}if(!is_graceful){renremainingchildrentostartremainingchildrentostart=0;}else{givethesystemsometimetorecoverbeforekickingintontialmodehold_off_on_exponential_spawning=10;}aplogerrorAPLOGMARKAPLOGNOTICE0,ap_server_conf,uredresumingnormaloperationstserverdescriptionaplogerrorAPLOGMARKAPLOGINFO0,ap_server_conf,erbuiltsapgetserverbuiltdefAPMPMWANTSETACCEPTLOCKMECHaplogerrorAPLOGMARKAPLOGDEBUG0,ap_server_conf,utexsdefaultsocmutexnameacceptmutexrocmutexdefnamerestartpendingshutdown_pending=0;mpmstateAP_MPMQ_RUNNING;while(!restart_pending&&!shutdown_pending){:這里每隔一秒就往返一次。一直進行不停itwhyeexitwhytusthisisamemoryleak,butI'llfixitlater.*/ctpidapap_wait_or_timeout(&exitwhy,&status,&pid,pconf);XXXifittakeslongerthan1secondforallourchildrentostartupandgetintoIDLEstatethenwemayspawnanildif(pid.pid!=-1){processedstatusapprocesschildstatus&pid,exitwhy,status);if(processed_status==APEXIT_CHILDFATAL){mpmstate=AP_MPMQ_STOPPING;return1;}nonfataldeathnotethatit'sgoneinthescoreboard.*/slotfindchildbypidpidif(child_slot>=0){tSERVERDEADif(processed_status==APEXIT_CHILDSICK){childdetectedaresourceshortage(E[NM]FILE,ENOBUFS,etc)uttheforkratetotheminimumwnrate}emainingchildrentostart&&child_slot<ap_daemons_limit){werestilldoinga1-for-1replacementofdeadrenwithnewchildrenmake_child(ap_server_conf,child_slot);remainingchildrentostart;}HASOTHERCHILD}elseif(apr_proc_other_child_alert(&pid,APR_OC_REASON_DEATH,status)==APR_SUCCESS){handled/}elseif(is_graceful){Greatwe'veprobablyjustlostaslotinthescoreboardSomehowwedon'tknowaboutthis*child.gerrorAPLOGMARKAPLOGWARNINGrverconflonglostchildcamehomepidldlongpidpid}Dontperformidlemaintenancewhenachilddies,*onlydoitwhenthere'satimeout.Rememberonlyafinitenumberofchildrencandieandit'sprettyathologicalforalottodiesuddenly}elseif(remaining_children_to_start){wehitasecondtimeoutinwhichnoneofthepreviousgenerationofchildrenneededtobereaped...soassume*they'realldone,andpickuptheslackifanyisleft.renremainingchildrentostartremainingchildrentostart=0;InanyeventwereallyshouldntdothecodebelowbecausefewoftheserverswejuststartedareintheIDLEstateyetsowedmistakenlycreateanextraserver.}rformidleservermaintenancepconf它主要進行子進程的檢查。循環(huán)的條件是由信號處理,以及對子進行檢查的結(jié)果來決定的。在啟用apachectlrestart命令后,父進程收到SIGHUPreceived.Attemptingto}}/*one_process*/mpmstate=AP_MPMQ_STOPPING;if(shutdown_pending&&!is_graceful){Timetoshutdown*Killchildprocesses,tellthemtocallchild_exit,etc...if(unixd_killpg(getpgrp(),SIGTERM)<0){aplogerrorAPLOGMARKAPLOGWARNINGerrnoapserver_conf,"killpgSIGTERM");}apreclaimchildprocesses/*StartwithSIGTERM*/cleanuppidfileonnormalshutdown*/{pidfileNULLpidfileapserverrootrelative(pconf,ap_pid_fname);dfileNULLunlinkpidfileaplogerrorAPLOGMARKAPLOGINFO,rverconfmovedPIDfilespidldpidfilelonggetpid());}aplogerrorAPLOGMARKAPLOGNOTICE0,ap_server_conf,TERMshuttingdownreturn1;}elseif(shutdown_pending){Timetoperformagracefulshutdown:Reaptheinactivechildrenandasktheactiveonestoclosetheirlistenersthenwaituntiltheyare*alldonetoexit.aprtimetcutoff0;Stoplistening*/selistenerskillofftheidleones*/apmpmpodkillpgpodapmaxdaemons_limit);SendSIGUSRtotheactivechildren*/activechildrenfor(index=0;index<ap_daemons_limit;++index){if(ap_scoreboard_image->servers[index][0].status!=SERVER_DEAD){Askeachchildtocloseitslisteners.*/apmpmsafekillMPMCHILDPIDindexAPSIGGRACEFUL);hildren}}Alloweachchildwhichactuallyfinishedtoexit*/evechildprocessescleanuppidfile*/{pidfileNULLpidfileapserverrootrelative(pconf,ap_pid_fname);dfileNULLunlinkpidfileaplogerrorAPLOGMARKAPLOGINFO,rverconfmovedPIDfilespidldpidfilelonggetpid());}aplogerrorAPLOGMARKAPLOGNOTICE0,ap_server_conf,aughtAPSIGGRACEFULSTOPSTRINGshuttingdowngracefullyif(ap_graceful_shutdown_timeout){cutoffaprtimenow()+prtimefromsecapgracefulshutdowntimeout}Dontreallyexituntileachchildhasfinished*/ndingdo{Pauseforasecond*/Relieveanychildrenwhichhavenowexited*/evechildprocessesactivechildrenfor(index=0;index<ap_daemons_limit;++index){if(ap_mpm_safe_kill(MPM_CHILD_PID(index),0)==APR_SUCCESS){active_children=1;Havingjustonechildisenoughtostayaround*/}}shutdownpendingactivechildrenoffWemightbeherebecausewereceivedSIGTERM,eitherwaytryandmakesurethatallofourprocessesare*reallydead.unixdkillpggetpgrpSIGTERM);return1;}wevebeentoldtorestart*/aprsignalSIGHUPSIGIGNaprsignalAPSIGGRACEFULSIGIGN);if(one_process){notworththinkingabout*/return1;}advancetothenextgeneration*//*XXX:wereallyneedtomakesurethisnewgenerationnumberisn'tin*usebyanyofthechildren.nerationapscoreboardimageglobalrunninggenerationapmy_generation;if(is_graceful){aplogerrorAPLOGMARKAPLOGNOTICE0,ap_server_conf,startrequesteddoingrestartkillofftheidleones*/apmpmpodkillpgpodapmaxdaemons_limit);Thisismostlyfordebugging...sothatweknowwhatisstillgracefullydealingwithexistingrequestThiswillbreakinaverynastywayifweeverhavethescoreboardtotallylebasednosharedmemoryfor(index=0;index<ap_daemons_limit;++index){boardimageserversindexstatusSERVERDEADapscoreboardimageserversindexstatus=SERVER_GRACEFUL;/*Askeachchildtocloseitslisteners.*NOTEweusethescoreboardbecauseifwesendSIGUSR1toeveryprocessinthegroupthismayincludeCGI's,pipedloggersetcTheyalmostcertainlywon'thandleefullyapmpmsafekillapscoreboardimageparentindexpidAP_SIG_GRACEFUL);}}}else{Killemoff*/if(unixd_killpg(getpgrp(),SIGHUP)<0){aplogerrorAPLOGMARKAPLOGWARNINGerrnoapserver_conf,"killpgSIGHUP");}apreclaimchildprocesses/*Notwhenjuststartingup*/aplogerrorAPLOGMARKAPLOGNOTICE0,ap_server_conf,eivedAttemptingtorestart}return}這這個child_main()函數(shù)是重中之重!?。?!ildmainintchildnumarg{ltptransocatortallocatoratuststatustenreclrlsettpollsethandletsbhbucketalloctbucketallocmpm_state=AP_MPMQ_STARTING;/*forbenefitofanyhooksthatrunasthisdinitializesmychild_num=child_num_arg;mypidgetpidrequeststhischild=0;apfatalsignalchildsetupapserverconfGetasubcontextforglobalallocationsinthischild,sothat*wecanhavecleanupsoccurwhenthechildexits.locatorcreateallocatoraprallocatormaxfreesetallocatorapmaxmemfree);aprpoolcreateexpchildpconfNULLallocator);allocatorownersetallocatorpchildpoolcreateptranspchildrpooltagptranstransactionneedstobedonebeforeweswitchUIDssowehavepermissions*/apreopenscoreboardpchildNULL);usaprprocmutexchildinitacceptmutexaplockfnamepchildif(status!=APR_SUCCESS){aplogerrorAPLOGMARKAPLOGEMERGstatus,ap_server_conf,sdaplockfnameapacceptlockmech;exitAPEXITCHILDFATAL}if(unixd_setup_child()){exitAPEXITCHILDFATAL}aprunchildinitpchildapserverconf;apcreatesbhandlesbhpchildmy_child_num,0);equestrecNULLSetupthepollfdarray*/#checkthestatus*/ockspchildfor(lr=ap_listeners,i=num_listensocks;i--;lr=lr->next){aprpollfdtpfd={0};pfddesctypeAPRPOLL_SOCKET;pfddescs=lr->sd;dreqeventsAPRPOLLINpfd.client_data=lr;#checkthestatus*/}mpmstateAP_MPMQ_RUNNING;bucketallocaprbucketalloc_create(pchild);dienowissetwhenAP_SIG_GRACEFULisreceivedinthechild;shutdownpendingissetwhenSIGTERMisreceivedwhenrunninginsingleprocessmode.*/while(!die_now&&!shutdown_pending){urrentconnsd*(Re)initializethischildtoapre-connectionstate.aprpoolclearptrans;第一次執(zhí)行axrequestsperchild&&requests_this_child++>=ap_max_requests_per_child)){ldexit}equestrecNULL*Waitforanacceptableconnectiontoarrive.Lockaround"accept",ifnecessary*/FEACCEPTacceptmutexonif(num_listensocks==1){Thereisonlyonelistenerrecordsorefertothatone.*/steners}multiplelisteningsockets-needtopoll*/for(;;){ttnumdescollfdtpdesctimeout=-1==waitforever*/usaprpollsetpollpollsetnumdescpdescif(status!=APR_SUCCESS){if(APR_STATUS_IS_EINTR(status)){if(one_process&&shutdown_pending){}elseif(die_now){Ingracefulstoprestartdropthemutexandterminatethechild.*/FEACCEPTacceptmutexoffldexit}}SingleUnixdocumentsselectasreturningerrnosEBADFEINTRandEINVAL...andinnoneofthosecasesdoesitmakesensetocontinue.InfactonLinuxxweseemtoendupwithEFAULT*occasionally,andwe'dloopforeverduetoit.logerrorAPLOGMARKAPLOGERRstatusapserverconfaprpollsetpolllisten);FEACCEPTacceptmutexoffldexit}Wecanalwaysusepdesc0],butsocketsatpositionNcouldendupcompletelystarvedofattentioninaverybusyserverTherefore,weround-robinacrossthereturnedsetofdescriptorsWhileitispossiblethatthereturnedsetofdescriptorsmightfliparoundandcontinuetostarvesomesockets,wehappentoknowtheternalpollsetimplementationretainsorderingstabilityofthesocketsThus,theround-robinshouldensurethatasocketwilleventuallybeservicedcGrabalistenerrecordfromtheclient_dataofthepolldescriptorandadvanceoursavedindextoround-robinxtfetch*hmmthisdescriptormighthavePOLLERRratheranPOLLINollidxclientdatafd}}*ifweaccept()somethingwedon'twanttodie,sowehavetofertheexitstatuslracceptfunccsdlrptrans);子進程會在這里等待。如果有訪問,就會執(zhí)行SAFEACCEPTacceptmutexoff;/*unlockafter"accept"*/if(status==APR_EGENERAL){resourceshortageorshould-not-occuroccured*/ldexit}elseif(status!=APR_SUCCESS){}Wenowhaveaconnectionsosetitupwiththeappropriate*socketoptions,filedescriptors,andread/writebuffers.if(current_conn){}/*CheckthepodandthegenerationnumberafterprocessingaconnectionsothatwellgoawayifagracefulrestartoccurredwhilewewereprocessingtheconnectionorwearetheluckydleserverprocessthatgetstodiempmpodcheckpodAPRSUCCESSselectedasidledienow=1;}elseif(ap_my_generation!=apscoreboardimageglobalrunninggeneration){/*restart?*/yeahthiscouldbenon-gracefulrestart,inwhichcasetheparentwillkillussoonenoughbutwhybotherchecking?dienow=1;}}ldexit}RedHatEnterpriseLinuxASrelease3(TaroonUpdate4)kernel7.ELglibc95.30apache.53Serverversi

溫馨提示

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

評論

0/150

提交評論