DAEMONS Daemon background TechnicallynotpartofthekernelbutstillpartoftheOSGoodexample networkTCPservers AUnixdaemonisdifferentfromanormalprogramInparticularaserverdoesnotinteractwithause ID: 488050
Download Pdf The PPT/PDF document "=Aprogramdoessomethingusefulwithoutinter..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
DAEMONS Daemon =Aprogramdoessomethingusefulwithoutinteractingdirectlywiththeuser(sitsinthe background )Technicallynotpartofthekernel,butstillpartoftheOSGoodexample: network(TCP)servers A(Unix)daemonisdifferentfromanormalprogramInparticular,aserverdoesnotinteractwithauserItcommunicatesinsteadwithotherprogramsmaybeoveranetworkItalsospawnsthreads/processes(whicharenotunderimmediateusercontrol)Oneisfacedthuswithabunchofnewissues,includingpreventinguserstoaffectserver'sexecutioninotherwaysthantheonesspeci-edprovidingamechanismfortheservertoreportstatusanderrorsresourcemanagementaccesscontrolandothersecurityissues CS409,FALL2013DAEMONS/1 DAEMONS=BACKGROUND Anormalprogramrunsin foreground Itisattachedtoa terminal (moregeneral,atty)Itreceivesuser input fromthatterminalItprints output (using cout , printf ,...)and errormessages (using cerr , perror ,...)tothesameterminalAdaemonrunsin background IsnotattachedtoanyterminalInstead,itislauncheduponboot,maybeevenbeforeterminalsarebornThus,itdoesnotacceptuserinputItmustsendtheoutputtosomethingelsethanaterminal CS409,FALL2013DAEMONS/2 PROGRAMMINGADAEMON Theeasyway:putthedaemoninthebackgroundexplicitly bbserv-cbb.conf-fbbfile& Thehardway:thedaemonputsitselfintothebackgroundStartwithaprocessthatdoestheserverinitializationItprintswhatevermessagesitwants(totheterminal)Itthengoesinthebackgroundfortherestofthejobintmain(...){ Initializestuff(networkserver:socketbinding,preparationofthelesystem) intbgpid=fork();if(bgpid0){perror("startupfork");return1;}if(bgpid) //parentdies! return0; Childcontinuesandbecomesthedaemon } CS409,FALL2013DAEMONS/3 THEHARDWAY(CONT'D) OK,butwhy?Adaemonisstartedupbythe initprocess initstartsthedaemonsinaspecicordere.g.,remotelesystemaccessshouldbestartedbeforeanybodyneedsitinitcannotputeverythingintothebackgroundfromtheverystartithastomakesurethatthedaemonactuallystartedbeforemovingforwardOntheotherhand,ifthedaemonnevergetstothebackground,initnevergetsachancetogoaheadandstarttheotherservicesErgo,adaemonthatexpectstobelaunchedbyinit(theyallshould!)sitsintheforegrounduntilitmakessurethatthestartupsucceededgoesthenintobackgroundfortheactualwork CS409,FALL2013DAEMONS/4 TALKINGTODAEMONS WehaversttondtheprocessidofthedaemonprocessWedo psaux ,wegetalotoflineslikethisUSERPID%CPU%MEMVSZRSSTTYSTATSTARTTIMECOMMANDbruda133190.00.12572816pts/1S12:150:00bbservbbbandthenwehuntforourdaemonbetweenthemWedo psaux|grep name ,wegetonlythelinesthatcontain nameWealreadyhavethepid(useful!)Buthow?Wecouldthensendsignalstothedaemon kill pid sendsSIGQUITto pid(which may terminate) kill-KILL pid sendsSIGKILLto pid(which will terminate) kill-HUP pid sendsSIGHUPto pid(whichnormallyrestarts) CS409,FALL2013DAEMONS/5 LONELYDAEMONS Daemonsarelonely.ItdoesnotmakesensetorunmultiplecopiesofadaemononthesamemachineHowdowepreventmultiplecopiestorun? Eachdaemonhasawell-knownassociatedlockleDifferentdaemonsusedifferentlockles,butadaemonwillalwaysusethesamelockleImmediatelyuponstartupthedaemontriestoacquirealockonthisleIfitsucceeds,itgoesaheadwiththerestIfitfails,itterminates(thereisanothercopyrunning)Anerrormessagewouldbenicetoo...Whenthedaemonexits,itreleasesthelockontheleanddeletestheleLooselyspeaking,eachdaemonrunsinacriticalregionThelockleisalsoagoodplacetoholdtheprocessidofthedaemon! CS409,FALL2013DAEMONS/6 LONELYDAEMONS Daemonsarelonely.ItdoesnotmakesensetorunmultiplecopiesofadaemononthesamemachineHowdowepreventmultiplecopiestorun?Eachdaemonhasawell-knownassociated lockle Differentdaemonsusedifferentlockles,butadaemonwillalwaysusethesamelockleImmediatelyuponstartupthedaemontriestoacquirealockonthisleIfitsucceeds,itgoesaheadwiththerestIfitfails,itterminates(thereisanothercopyrunning)Anerrormessagewouldbenicetoo...Whenthedaemonexits,itreleasesthelockontheleanddeletestheleLooselyspeaking,eachdaemonrunsinacriticalregion Thelockleisalsoagoodplacetoholdtheprocessidofthedaemon! CS409,FALL2013DAEMONS/6 LONELYDAEMONS Daemonsarelonely.ItdoesnotmakesensetorunmultiplecopiesofadaemononthesamemachineHowdowepreventmultiplecopiestorun?Eachdaemonhasawell-knownassociated lockle Differentdaemonsusedifferentlockles,butadaemonwillalwaysusethesamelockleImmediatelyuponstartupthedaemontriestoacquirealockonthisleIfitsucceeds,itgoesaheadwiththerestIfitfails,itterminates(thereisanothercopyrunning)Anerrormessagewouldbenicetoo...Whenthedaemonexits,itreleasesthelockontheleanddeletestheleLooselyspeaking,eachdaemonrunsinacriticalregionThelockleisalsoagoodplacetoholdthe processidofthedaemon ! CS409,FALL2013DAEMONS/6 GRUMPYDAEMONS Exceptforthesignalstheylike,daemonsdonotwanttotalktoyouIfyouleavetheminthesatetypicalforanormalprogram,theymightevengetangryandrefusetodotheworkThishappenswhentheytrytoaccessstandardinput(descriptor0)Sowehaveto close descriptor0Whattheheck,weclose all thedescriptorsexceptstandardoutputandstandarderror! for(inti=0;igetdtablesize();i++)if(i!=1&&i!=2)close(i); Closingdescriptorsisveryimportant, wethuspreventthedaemonfromcon-sumingresourcesunnecessarily Butnotethatweclosethem beforeopeningbackthosedescriptorsweactuallyneed (suchaswhoknowswhatleonwhichthedaemondoesitsstuff)Closingdescriptor0doesnotmakeourdaemonhappythough!( why? ) CS409,FALL2013DAEMONS/7 GRUMPYDAEMONS(CONT'D) Thedaemonmaystilltrytoaccessdescriptor0ManylibraryfunctionsassumethattherstthreedescriptorsareopenWejustexchangeoneerrorforanother!Soweopendescriptor0againThistime,descriptor0willpointtoaspecialdevicewhichdoesnothing(bitbucket)Thisdeviceiscalled,suggestively, /dev/null readingfrom/dev/nullalwaysreturnanendofleanythingyouwriteto/dev/nullissimplydiscardedfor(inti=0;igetdtablesize();i++)if(i!=1&&i!=2)close(i); //Wecloseddescriptor0already,sothis//willbethefirstoneavailable!intfd=open("/dev/null",O_RDWR); CS409,FALL2013DAEMONS/8 DETACHEDDAEMONS EachUnixprocessinheritsaconnectiontoits controllingtty Auserthatstartedaprocesscancontrolitbyissuingappropriatecontrolcom-mandstothatprocess'controllingttyUnlikenormalprograms,daemonsshouldnotreceivesignalsgeneratedbythepro-cessthatstarteditSignalingfromthettytothepieceofcodethatstartsthedaemonisacceptable(sometimesdesired),signalingtothedaemonitselfisnotAdaemonmust detachitself fromthecontrollingtty #includesys/ioctl.h-1.3;çintfd=open("/dev/tty",O_RDWR);ioctl(fd,TIOCNOTTY,0);close(fd); CS409,FALL2013DAEMONS/9 DETACHEDDAEMONSANDTHEIROUTPUT OK,sowehavenownoterminal,wheredoweputtheoutput? InitializationcodeoutputstowhateverisinheritedfromtheparentprocessWethenredirectstandardoutput(descriptor1)andstandarderror(descriptor2)toles//Wecloseeverything!!for(inti=getdtablesize()-1;i=0;i--)close(i);intfd=open("/dev/null",O_RDWR);//Descriptor0//Wenowre-opendescriptors1and2,inthisorder:Samele:fd=open("global-output-file",O_RDWR);dup(fd);Differentles:fd=open("output-file",O_RDWR);fd=open("error-file",O_RDWR); CS409,FALL2013DAEMONS/10 DETACHEDDAEMONSANDTHEIROUTPUT OK,sowehavenownoterminal,wheredoweputtheoutput?InitializationcodeoutputstowhateverisinheritedfromtheparentprocessWethen redirect standardoutput(descriptor1)andstandarderror(descriptor2)to les //Wecloseeverything!!for(inti=getdtablesize()-1;i=0;i--)close(i);intfd=open("/dev/null",O_RDWR);//Descriptor0//Wenowre-opendescriptors1and2,inthisorder:Samele:fd=open("global-output-file",O_RDWR);dup(fd);Differentles:fd=open("output-file",O_RDWR);fd=open("error-file",O_RDWR); CS409,FALL2013DAEMONS/10 DAEMONSDON'TLIKESIGNALS Thereisnosignalfromthecontrollingtty,butnonethelessadaemonmayreceivesignals(e.g.,fromyouwhenyouusethecommandkill)Somesignals(e.g.,SIGHUP,maybe)havesomemeaningtothedaemonOnesignal always hassomemeaningtoanyUnixprogram,namelySIGKILLSignalswithmeaningsshouldhaveassociated signalhandlers (exceptSIGKILL) signal( signal, handler-function); SomeothersignalsdonothaveanymeaningSignalsthatarenotneeded shouldbeignored Thereisapredenedfunctionthatdoesexactlythis:SIG_IGN signal( signal,SIG_IGN); CS409,FALL2013DAEMONS/11 SIGPIPE NotablesignalSenttoanetworkserverwhenaclientquitsunexpectedly(withoutshuttingdownthesocket)WhenunhandledaSIGPIPEbringsdownthewholeprocessAservermustnotdiewhenaclientmisbehavesErgo,thissignalshouldalwaysbeexplicitlyhandledignoringitisneformostapplications,sincethesocket also receivesanendofle CS409,FALL2013DAEMONS/12 DAEMONSARENOTGREGARIOUS Unixplaceseachprocessina processgroup ItcanthentreatasetofrelatedprocessesasoneentityAdaemoninheritsmembershipinaprocessgroup But :usually,adaemonoperatesindependentlyfromanyprocessgroupE.g.,itshouldnotreceivesignalssenttoitsparent'sgroupThedaemonmustthus leave itsparent'sgroup: setpgid( what-process, to-what-group); Theprocessidofthecurrentprocess(whichispassedtosetpgid)canbeobtainedbyusingthefunctiongetpidTocreateanew,privategroupwepass0assecondargumentofsetpgrp.Sowedo: setpgrp(getpid(),0); CS409,FALL2013DAEMONS/13 SECUREDAEMONS Daemonsmayrunwith rootprivileges Inotherwords,theycandowhatevertheypleasewithyoursystemSo youtheprogrammer havetomakesuretheydonotdothingsthatinterferewithnormalsystemoperationCarefulprogrammingisonewayofkeepingthematbayInparticular,itiscrucialthatyoucheckforarraybounds,andthatyoudonotaccessmemoryareasyoudonotownNotcheckingfortheseisthemostusualcauseforissuingsecurityupdates(andforpeoplecrackingintoyoursystem)ThisisofcourseacomplexproblemInaddition,youshouldbecarefulaboutwhatdaemonswritetodiskandwhere CS409,FALL2013DAEMONS/14 DAEMONSANDTHEIRDIRECTORIES Whenaprogramislaunched,itinheritsanenvironmentvariablecalledthe currentworkingdirectory Whenaprogramcreatesoropensale,itlooksinthiscurrentworkingdirectoryDaemonsarelaunchedbytheinitscript,whichworksinadirectorywhosecontentshouldnotbemodiedDaemonshavethishabittowriteondiskYoucanspecifythedirectorytheywriteintobyprovidingabsolutepathstoyourles But adaemonthatencountersanerrorconditionmight dumpcore (writetodiskamemoryimagefordebuggingpurposes...inthecurrentworkingdirectory!) But adaemonstartedbythesystemadministratorwillhavethecurrentdirectoryasthehomedirectoryoftheadministrator(verybad!) But adaemonworkinginsomedirectorywillpreventthatdirectorytobeunmountedevenifthedaemondoesnotreallyusethedirectoryforanything Conclusion: Youshouldmoveadaemontoa known,safedirectory .Youthendo: chdir("/"); CS409,FALL2013DAEMONS/15 CONFIDENTIALDAEMONS Somedatathatiswrittentolesislogdata,whichshouldbeinspectablebymanypeopleSomeotherdatashouldnotbeaccessibletoanybodyelse(e.g.,passwords)EachleinaUnixlesystemhasasetofpermissionsYoucanspecifyatcreationtimethepermissionsoftheleyoucreateYoucanalsospecifyasetofpermissionsthatwillneverbeset(the umask ) read permission setexecute permission set rxw others:group:owner: rwxr-xrw-111101110756 740 permissions for the file (declared): umask (denied permissions): actual permissions for the file: Bitwise AND with 037 CS409,FALL2013DAEMONS/16 SETTINGAUMASK Youdonotwanttorunintothepossibilityofcreatingaleownedbytheadministratorandwithallthepermissionsset(777)Notevenbychance!So,besidessettingsuitablepermissionsforeachleyoucreate,itisaverygoodideatoprovideasuitableumaskforthedaemonasawholeToseta(new)umask,youusethesystemcall umask Itisverycomfortabletoworkwithnumbersin octal whenyoudealwithleper-missionsThiswayadigitcorrespondswithasetofpermissionsforagivengroupofusersInC/C++aliteralintegerwhoserstdigitis0isconsideredtobeinbase8Sowhenyoucallumask,itislikelythatyoudonotwanttowriteumask(137);butrather umask(0137); Alwayskeepinmindthattheumaskspeciespermissionsthatare denied CS409,FALL2013DAEMONS/17