BPF మరియు eBPF లకు సంక్షిప్త పరిచయం

హలో, హబ్ర్! మేము ఒక పుస్తకాన్ని విడుదల చేయడానికి సిద్ధం చేస్తున్నామని మీకు తెలియజేస్తున్నాము."BPFతో Linux పరిశీలన".

BPF మరియు eBPF లకు సంక్షిప్త పరిచయం
BPF వర్చువల్ మెషీన్ అభివృద్ధి చెందుతూనే ఉంది మరియు ఆచరణలో చురుకుగా ఉపయోగించబడుతోంది కాబట్టి, మేము దాని ప్రధాన సామర్థ్యాలు మరియు ప్రస్తుత స్థితిని వివరించే కథనాన్ని మీ కోసం అనువదించాము.

ఇటీవలి సంవత్సరాలలో, అధిక-పనితీరు గల ప్యాకెట్ ప్రాసెసింగ్ అవసరమయ్యే సందర్భాలలో Linux కెర్నల్ యొక్క పరిమితులను భర్తీ చేయడానికి ప్రోగ్రామింగ్ సాధనాలు మరియు సాంకేతికతలు బాగా ప్రాచుర్యం పొందాయి. ఈ రకమైన అత్యంత ప్రజాదరణ పొందిన పద్ధతుల్లో ఒకటి అంటారు కెర్నల్ బైపాస్ (కెర్నల్ బైపాస్) మరియు కెర్నల్ నెట్‌వర్క్ లేయర్‌ను దాటవేసి, వినియోగదారు స్థలం నుండి అన్ని ప్యాకెట్ ప్రాసెసింగ్‌ను నిర్వహించడానికి అనుమతిస్తుంది. కెర్నల్‌ను బైపాస్ చేయడంలో నెట్‌వర్క్ కార్డ్‌ను నియంత్రించడం కూడా ఉంటుంది వినియోగదారు స్థలం. మరో మాటలో చెప్పాలంటే, నెట్‌వర్క్ కార్డ్‌తో పని చేస్తున్నప్పుడు, మేము డ్రైవర్‌పై ఆధారపడతాము వినియోగదారు స్థలం.

నెట్‌వర్క్ కార్డ్ యొక్క పూర్తి నియంత్రణను వినియోగదారు-స్పేస్ ప్రోగ్రామ్‌కి బదిలీ చేయడం ద్వారా, మేము కెర్నల్ ఓవర్‌హెడ్ (సందర్భ మార్పిడి, నెట్‌వర్క్ లేయర్ ప్రాసెసింగ్, అంతరాయాలు మొదలైనవి) తగ్గిస్తాము, ఇది 10Gb/s లేదా అంతకంటే ఎక్కువ వేగంతో నడుస్తున్నప్పుడు చాలా ముఖ్యమైనది. కెర్నల్ బైపాస్ మరియు ఇతర లక్షణాల కలయిక (బ్యాచ్ ప్రాసెసింగ్) మరియు జాగ్రత్తగా పనితీరు ట్యూనింగ్ (NUMA అకౌంటింగ్, CPU ఐసోలేషన్, మొదలైనవి) వినియోగదారు స్థలంలో అధిక-పనితీరు గల నెట్‌వర్క్ ప్రాసెసింగ్ యొక్క ఫండమెంటల్స్‌కు అనుగుణంగా ఉంటాయి. ప్యాకెట్ ప్రాసెసింగ్‌కి ఈ కొత్త విధానానికి బహుశా ఒక ఆదర్శప్రాయమైన ఉదాహరణ డిపిడికె ఇంటెల్ నుండి (డేటా ప్లేన్ డెవలప్‌మెంట్ కిట్), సిస్కో యొక్క VPP (వెక్టర్ ప్యాకెట్ ప్రాసెసింగ్), నెట్‌మ్యాప్ మరియు, వాస్తవానికి, ఇతర ప్రసిద్ధ సాధనాలు మరియు సాంకేతికతలు ఉన్నప్పటికీ, స్నాబ్.

వినియోగదారు స్థలంలో నెట్‌వర్క్ పరస్పర చర్యలను నిర్వహించడం వలన అనేక ప్రతికూలతలు ఉన్నాయి:

  • OS కెర్నల్ అనేది హార్డ్‌వేర్ వనరుల కోసం ఒక సంగ్రహణ పొర. వినియోగదారు స్పేస్ ప్రోగ్రామ్‌లు తమ వనరులను నేరుగా నిర్వహించవలసి ఉంటుంది కాబట్టి, వారు తమ స్వంత హార్డ్‌వేర్‌ను కూడా నిర్వహించాలి. ఇది తరచుగా మీ స్వంత డ్రైవర్లను ప్రోగ్రామ్ చేయవలసి ఉంటుంది.
  • మేము కెర్నల్ స్థలాన్ని పూర్తిగా వదులుకుంటున్నందున, మేము కెర్నల్ అందించిన నెట్‌వర్కింగ్ ఫంక్షనాలిటీని కూడా వదులుకుంటున్నాము. వినియోగదారు-స్పేస్ ప్రోగ్రామ్‌లు తప్పనిసరిగా కెర్నల్ లేదా ఆపరేటింగ్ సిస్టమ్ ద్వారా అందించబడే ఫంక్షన్‌లను మళ్లీ అమలు చేయాలి.
  • ప్రోగ్రామ్‌లు శాండ్‌బాక్స్ మోడ్‌లో పనిచేస్తాయి, ఇది వాటి పరస్పర చర్యను తీవ్రంగా పరిమితం చేస్తుంది మరియు ఆపరేటింగ్ సిస్టమ్‌లోని ఇతర భాగాలతో వాటిని ఏకీకృతం చేయకుండా నిరోధిస్తుంది.

సారాంశంలో, వినియోగదారు స్థలంలో నెట్‌వర్కింగ్ చేస్తున్నప్పుడు, ప్యాకెట్ ప్రాసెసింగ్‌ను కెర్నల్ నుండి వినియోగదారు స్థలానికి తరలించడం ద్వారా పనితీరు లాభాలు సాధించబడతాయి. XDP సరిగ్గా వ్యతిరేకం చేస్తుంది: ఇది నెట్‌వర్కింగ్ ప్రోగ్రామ్‌లను వినియోగదారు స్థలం (ఫిల్టర్‌లు, పరిష్కారాలు, రూటింగ్, మొదలైనవి) నుండి కెర్నల్ స్పేస్‌లోకి తరలిస్తుంది. ప్యాకెట్ నెట్‌వర్క్ ఇంటర్‌ఫేస్‌ను తాకిన వెంటనే మరియు అది కెర్నల్ నెట్‌వర్క్ సబ్‌సిస్టమ్‌లోకి వెళ్లడం ప్రారంభించే ముందు నెట్‌వర్క్ ఫంక్షన్‌ను నిర్వహించడానికి XDP అనుమతిస్తుంది. ఫలితంగా, ప్యాకెట్ ప్రాసెసింగ్ వేగం గణనీయంగా పెరుగుతుంది. అయితే, కెర్నల్ స్పేస్‌లో వారి ప్రోగ్రామ్‌లను అమలు చేయడానికి వినియోగదారుని కెర్నల్ ఎలా అనుమతిస్తుంది? ఈ ప్రశ్నకు సమాధానమిచ్చే ముందు, BPF అంటే ఏమిటో చూద్దాం.

BPF మరియు eBPF

గందరగోళంగా పేరు ఉన్నప్పటికీ, BPF (బర్కిలీ ప్యాకెట్ ఫిల్టరింగ్) నిజానికి, ఒక వర్చువల్ మెషీన్ మోడల్. ఈ వర్చువల్ మెషీన్ మొదట ప్యాకెట్ ఫిల్టరింగ్‌ని నిర్వహించడానికి రూపొందించబడింది, అందుకే దీనికి పేరు వచ్చింది.

BPFని ఉపయోగించే అత్యంత ప్రసిద్ధ సాధనాల్లో ఒకటి tcpdump. ఉపయోగించి ప్యాకెట్లను సంగ్రహిస్తున్నప్పుడు tcpdump వినియోగదారు ప్యాకెట్లను ఫిల్టర్ చేయడానికి ఒక వ్యక్తీకరణను పేర్కొనవచ్చు. ఈ వ్యక్తీకరణకు సరిపోలే ప్యాకెట్‌లు మాత్రమే క్యాప్చర్ చేయబడతాయి. ఉదాహరణకు, వ్యక్తీకరణ "tcp dst port 80” పోర్ట్ 80కి వచ్చే అన్ని TCP ప్యాకెట్‌లను సూచిస్తుంది. కంపైలర్ ఈ వ్యక్తీకరణను BPF బైట్‌కోడ్‌కి మార్చడం ద్వారా తగ్గించవచ్చు.

$ sudo tcpdump -d "tcp dst port 80"
(000) ldh [12] (001) jeq #0x86dd jt 2 jf 6
(002) ldb [20] (003) jeq #0x6 jt 4 jf 15
(004) ldh [56] (005) jeq #0x50 jt 14 jf 15
(006) jeq #0x800 jt 7 jf 15
(007) ldb [23] (008) jeq #0x6 jt 9 jf 15
(009) ldh [20] (010) jset #0x1fff jt 15 jf 11
(011) ldxb 4*([14]&0xf)
(012) ldh [x + 16] (013) jeq #0x50 jt 14 jf 15
(014) ret #262144
(015) ret #0

పై ప్రోగ్రామ్ ప్రాథమికంగా చేస్తుంది:

  • సూచన (000): ఆఫ్‌సెట్ 12 వద్ద ప్యాకెట్‌ను 16-బిట్ పదంగా, అక్యుమ్యులేటర్‌లోకి లోడ్ చేస్తుంది. ఆఫ్‌సెట్ 12 ప్యాకెట్ యొక్క ఈథర్‌టైప్‌కు అనుగుణంగా ఉంటుంది.
  • సూచన (001): అక్యుమ్యులేటర్‌లోని విలువను 0x86ddతో పోలుస్తుంది, అంటే IPv6 కోసం ఈథర్‌టైప్ విలువతో. ఫలితం నిజమైతే, ప్రోగ్రామ్ కౌంటర్ ఇన్‌స్ట్రక్షన్ (002)కి వెళుతుంది మరియు కాకపోతే (006)కి వెళ్తుంది.
  • సూచన (006): విలువను 0x800తో పోలుస్తుంది (IPv4 కోసం ఈథర్‌టైప్ విలువ). సమాధానం నిజమైతే, ప్రోగ్రామ్ (007), కాకపోతే (015)కి వెళుతుంది.

మరియు ప్యాకెట్ ఫిల్టరింగ్ ప్రోగ్రామ్ ఫలితాన్ని ఇచ్చే వరకు. ఇది సాధారణంగా బూలియన్. సున్నా కాని విలువను (సూచన (014)) అందించడం అంటే ప్యాకెట్ ఆమోదించబడిందని మరియు సున్నా విలువను (సూచన (015)) అందించడం అంటే ప్యాకెట్ అంగీకరించబడలేదని అర్థం.

BPF వర్చువల్ మెషీన్ మరియు దాని బైట్‌కోడ్‌లను 1992 చివరిలో స్టీవ్ మెక్‌కాన్ మరియు వాన్ జాకబ్సన్ వారి పేపర్ ప్రచురించినప్పుడు ప్రతిపాదించారు. BSD ప్యాకెట్ ఫిల్టర్: వినియోగదారు-స్థాయి ప్యాకెట్ క్యాప్చర్ కోసం కొత్త ఆర్కిటెక్చర్, ఈ సాంకేతికత మొదటిసారిగా 1993 శీతాకాలంలో యూసెనిక్స్ సమావేశంలో ప్రదర్శించబడింది.

BPF ఒక వర్చువల్ మెషీన్ అయినందున, ఇది ప్రోగ్రామ్‌లు అమలు చేసే వాతావరణాన్ని నిర్వచిస్తుంది. బైట్‌కోడ్‌తో పాటు, ఇది బ్యాచ్ మెమరీ మోడల్ (లోడ్ సూచనలు బ్యాచ్‌కి పరోక్షంగా వర్తింపజేయబడతాయి), రిజిస్టర్‌లు (A మరియు X; అక్యుమ్యులేటర్ మరియు ఇండెక్స్ రిజిస్టర్‌లు), స్క్రాచ్ మెమరీ స్టోరేజ్ మరియు ఇంప్లిసిట్ ప్రోగ్రామ్ కౌంటర్‌ను కూడా నిర్వచిస్తుంది. ఆసక్తికరంగా, BPF బైట్‌కోడ్ Motorola 6502 ISA తర్వాత రూపొందించబడింది. స్టీవ్ మెక్కాన్ తనలో గుర్తుచేసుకున్నాడు సర్వసభ్య నివేదిక Sharkfest '11లో, అతను Apple IIలో తన హైస్కూల్ రోజుల ప్రోగ్రామింగ్ నుండి బిల్డ్ 6502తో సుపరిచితుడయ్యాడు మరియు ఈ జ్ఞానం BPF బైట్‌కోడ్ రూపకల్పనలో అతని పనిని ప్రభావితం చేసింది.

BPF మద్దతు Linux కెర్నల్‌లో v2.5 మరియు అంతకంటే ఎక్కువ వెర్షన్‌లలో అమలు చేయబడింది, ప్రధానంగా జే షులిస్ట్ ప్రయత్నాల ద్వారా జోడించబడింది. 2011 వరకు BPF కోడ్ మారలేదు, ఎరిక్ డ్యుమాసెట్ BPF ఇంటర్‌ప్రెటర్‌ని JIT మోడ్‌లో అమలు చేయడానికి పునఃరూపకల్పన చేసింది (మూలం: ప్యాకెట్ ఫిల్టర్‌ల కోసం JIT) దీని తరువాత, కెర్నల్, BPF బైట్‌కోడ్‌ను వివరించే బదులు, BPF ప్రోగ్రామ్‌లను నేరుగా టార్గెట్ ఆర్కిటెక్చర్‌గా మార్చగలదు: x86, ARM, MIPS, మొదలైనవి.

తరువాత, 2014లో, అలెక్సీ స్టార్వోయిటోవ్ BPF కోసం కొత్త JIT మెకానిజంను ప్రతిపాదించారు. వాస్తవానికి, ఈ కొత్త JIT కొత్త BPF-ఆధారిత నిర్మాణంగా మారింది మరియు eBPF అని పిలువబడింది. రెండు VMలు కొంత కాలం పాటు కలిసి ఉన్నాయని నేను భావిస్తున్నాను, అయితే ప్రస్తుతం ప్యాకెట్ ఫిల్టరింగ్ eBPF ఆధారంగా అమలు చేయబడుతుంది. వాస్తవానికి, ఆధునిక డాక్యుమెంటేషన్ యొక్క అనేక ఉదాహరణలలో, BPF అంటే eBPF అని అర్థం చేసుకోవచ్చు మరియు క్లాసికల్ BPFని నేడు cBPF అని పిలుస్తారు.

eBPF క్లాసిక్ BPF వర్చువల్ మెషీన్‌ను అనేక విధాలుగా విస్తరించింది:

  • ఆధునిక 64-బిట్ ఆర్కిటెక్చర్ల ఆధారంగా. eBPF 64-బిట్ రిజిస్టర్‌లను ఉపయోగిస్తుంది మరియు అందుబాటులో ఉన్న రిజిస్టర్‌ల సంఖ్యను 2 (అక్యుమ్యులేటర్ మరియు X) నుండి 10కి పెంచుతుంది. eBPF అదనపు ఆప్‌కోడ్‌లను కూడా అందిస్తుంది (BPF_MOV, BPF_JNE, BPF_CALL...).
  • నెట్‌వర్క్ లేయర్ సబ్‌సిస్టమ్ నుండి వేరు చేయబడింది. BPF బ్యాచ్ డేటా మోడల్‌తో ముడిపడి ఉంది. ఇది ప్యాకెట్ ఫిల్టరింగ్ కోసం ఉపయోగించబడినందున, దాని కోడ్ నెట్‌వర్క్ కమ్యూనికేషన్‌లను అందించే సబ్‌సిస్టమ్‌లో ఉంది. అయితే, eBPF వర్చువల్ మెషీన్ ఇకపై డేటా మోడల్‌తో ముడిపడి ఉండదు మరియు ఏదైనా ప్రయోజనం కోసం ఉపయోగించవచ్చు. కాబట్టి, ఇప్పుడు eBPF ప్రోగ్రామ్‌ను ట్రేస్‌పాయింట్ లేదా kprobeకి కనెక్ట్ చేయవచ్చు. ఇది ఇతర కెర్నల్ సబ్‌సిస్టమ్‌ల సందర్భంలో eBPF ఇన్‌స్ట్రుమెంటేషన్, పనితీరు విశ్లేషణ మరియు అనేక ఇతర వినియోగ సందర్భాలకు మార్గాన్ని తెరుస్తుంది. ఇప్పుడు eBPF కోడ్ దాని స్వంత మార్గంలో ఉంది: kernel/bpf.
  • మ్యాప్స్ అని పిలువబడే గ్లోబల్ డేటా స్టోర్స్. మ్యాప్‌లు వినియోగదారు స్థలం మరియు కెర్నల్ స్థలం మధ్య డేటా మార్పిడిని ప్రారంభించే కీ-విలువ స్టోర్‌లు. eBPF అనేక రకాల మ్యాప్‌లను అందిస్తుంది.
  • ద్వితీయ విధులు. ప్రత్యేకించి, ప్యాకేజీని తిరిగి వ్రాయడానికి, చెక్‌సమ్‌ను లెక్కించండి లేదా ప్యాకేజీని క్లోన్ చేయండి. ఈ విధులు కెర్నల్ లోపల నడుస్తాయి మరియు వినియోగదారు-స్పేస్ ప్రోగ్రామ్‌లు కావు. మీరు eBPF ప్రోగ్రామ్‌ల నుండి సిస్టమ్ కాల్‌లను కూడా చేయవచ్చు.
  • కాల్‌లను ముగించండి. eBPFలో ప్రోగ్రామ్ పరిమాణం 4096 బైట్‌లకు పరిమితం చేయబడింది. టెయిల్ కాల్ ఫీచర్ ఒక కొత్త eBPF ప్రోగ్రామ్‌కు నియంత్రణను బదిలీ చేయడానికి eBPF ప్రోగ్రామ్‌ను అనుమతిస్తుంది మరియు తద్వారా ఈ పరిమితిని దాటవేస్తుంది (ఈ విధంగా 32 ప్రోగ్రామ్‌లను లింక్ చేయవచ్చు).

eBPF: ఉదాహరణ

Linux కెర్నల్ మూలాల్లో eBPF కోసం అనేక ఉదాహరణలు ఉన్నాయి. అవి నమూనాలు/bpf/ వద్ద అందుబాటులో ఉన్నాయి. ఈ ఉదాహరణలను కంపైల్ చేయడానికి, కేవలం నమోదు చేయండి:

$ sudo make samples/bpf/

నేను eBPF కోసం కొత్త ఉదాహరణ రాయను, కానీ నమూనాలు/bpf/లో అందుబాటులో ఉన్న నమూనాలలో ఒకదాన్ని ఉపయోగిస్తాను. నేను కోడ్‌లోని కొన్ని భాగాలను చూసి, అది ఎలా పని చేస్తుందో వివరిస్తాను. ఉదాహరణగా, నేను ప్రోగ్రామ్‌ని ఎంచుకున్నాను tracex4.

సాధారణంగా, నమూనాలు/bpf/లోని ప్రతి ఉదాహరణలో రెండు ఫైల్‌లు ఉంటాయి. ఈ విషయంలో:

  • tracex4_kern.c, కెర్నల్‌లో eBPF బైట్‌కోడ్‌గా అమలు చేయాల్సిన సోర్స్ కోడ్‌ని కలిగి ఉంటుంది.
  • tracex4_user.c, యూజర్ స్పేస్ నుండి ప్రోగ్రామ్‌ను కలిగి ఉంది.

ఈ సందర్భంలో, మేము కంపైల్ చేయాలి tracex4_kern.c eBPF బైట్‌కోడ్‌కి. ప్రస్తుతం లో gcc eBPF కోసం బ్యాకెండ్ లేదు. అదృష్టవశాత్తూ, clang eBPF బైట్‌కోడ్‌ని అవుట్‌పుట్ చేయగలదు. Makefile ఉపయోగాలు clang సంకలనం కోసం tracex4_kern.c ఆబ్జెక్ట్ ఫైల్‌కి.

eBPF యొక్క అత్యంత ఆసక్తికరమైన లక్షణాలలో మ్యాప్‌లు ఒకటి అని నేను పైన పేర్కొన్నాను. tracex4_kern ఒక మ్యాప్‌ని నిర్వచిస్తుంది:

struct pair {
    u64 val;
    u64 ip;
};  

struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(long),
    .value_size = sizeof(struct pair),
    .max_entries = 1000000,
};

BPF_MAP_TYPE_HASH eBPF అందించే అనేక రకాల కార్డ్‌లలో ఒకటి. ఈ సంద ర్భంలో ఇది హాష్ మాత్రమే. మీరు ఒక ప్రకటనను కూడా గమనించి ఉండవచ్చు SEC("maps"). SEC అనేది బైనరీ ఫైల్ యొక్క కొత్త విభాగాన్ని సృష్టించడానికి ఉపయోగించే ఒక మాక్రో. నిజానికి, ఉదాహరణలో tracex4_kern మరో రెండు విభాగాలు నిర్వచించబడ్డాయి:

SEC("kprobe/kmem_cache_free")
int bpf_prog1(struct pt_regs *ctx)
{   
    long ptr = PT_REGS_PARM2(ctx);

    bpf_map_delete_elem(&my_map, &ptr); 
    return 0;
}
    
SEC("kretprobe/kmem_cache_alloc_node") 
int bpf_prog2(struct pt_regs *ctx)
{
    long ptr = PT_REGS_RC(ctx);
    long ip = 0;

    // получаем ip-адрес вызывающей стороны kmem_cache_alloc_node() 
    BPF_KRETPROBE_READ_RET_IP(ip, ctx);

    struct pair v = {
        .val = bpf_ktime_get_ns(),
        .ip = ip,
    };
    
    bpf_map_update_elem(&my_map, &ptr, &v, BPF_ANY);
    return 0;
}   

ఈ రెండు విధులు మ్యాప్ నుండి ఎంట్రీని తొలగించడానికి మిమ్మల్ని అనుమతిస్తాయి (kprobe/kmem_cache_free) మరియు మ్యాప్‌కి కొత్త ఎంట్రీని జోడించండి (kretprobe/kmem_cache_alloc_node) పెద్ద అక్షరాలతో వ్రాసిన అన్ని ఫంక్షన్ పేర్లు నిర్వచించిన మాక్రోలకు అనుగుణంగా ఉంటాయి bpf_helpers.h.

నేను ఆబ్జెక్ట్ ఫైల్ యొక్క విభాగాలను డంప్ చేస్తే, ఈ కొత్త విభాగాలు ఇప్పటికే నిర్వచించబడి ఉన్నాయని నేను చూడాలి:

$ objdump -h tracex4_kern.o

tracex4_kern.o: file format elf64-little

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 kprobe/kmem_cache_free 00000048 0000000000000000 0000000000000000 00000040 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
2 kretprobe/kmem_cache_alloc_node 000000c0 0000000000000000 0000000000000000 00000088 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
3 maps 0000001c 0000000000000000 0000000000000000 00000148 2**2
CONTENTS, ALLOC, LOAD, DATA
4 license 00000004 0000000000000000 0000000000000000 00000164 2**0
CONTENTS, ALLOC, LOAD, DATA
5 version 00000004 0000000000000000 0000000000000000 00000168 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .eh_frame 00000050 0000000000000000 0000000000000000 00000170 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

కూడా ఉంది tracex4_user.c, ప్రధాన కార్యక్రమం. సాధారణంగా, ఈ ప్రోగ్రామ్ ఈవెంట్‌లను వింటుంది kmem_cache_alloc_node. అటువంటి సంఘటన జరిగినప్పుడు, సంబంధిత eBPF కోడ్ అమలు చేయబడుతుంది. కోడ్ ఆబ్జెక్ట్ యొక్క IP లక్షణాన్ని మ్యాప్‌లో సేవ్ చేస్తుంది మరియు ఆబ్జెక్ట్ ప్రధాన ప్రోగ్రామ్ ద్వారా లూప్ చేయబడుతుంది. ఉదాహరణ:

$ sudo ./tracex4
obj 0xffff8d6430f60a00 is 2sec old was allocated at ip ffffffff9891ad90
obj 0xffff8d6062ca5e00 is 23sec old was allocated at ip ffffffff98090e8f
obj 0xffff8d5f80161780 is 6sec old was allocated at ip ffffffff98090e8f

వినియోగదారు స్పేస్ ప్రోగ్రామ్ మరియు eBPF ప్రోగ్రామ్ ఎలా సంబంధం కలిగి ఉంటాయి? ప్రారంభించడంపై tracex4_user.c ఆబ్జెక్ట్ ఫైల్‌ను లోడ్ చేస్తుంది tracex4_kern.o ఫంక్షన్ ఉపయోగించి load_bpf_file.

int main(int ac, char **argv)
{
    struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
    char filename[256];
    int i;

    snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

    if (setrlimit(RLIMIT_MEMLOCK, &r)) {
        perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)");
        return 1;
    }

    if (load_bpf_file(filename)) {
        printf("%s", bpf_log_buf);
        return 1;
    }

    for (i = 0; ; i++) {
        print_old_objects(map_fd[1]);
        sleep(1);
    }

    return 0;
}

చేయడం వలన load_bpf_file eBPF ఫైల్‌లో నిర్వచించబడిన ప్రోబ్స్ జోడించబడతాయి /sys/kernel/debug/tracing/kprobe_events. ఇప్పుడు మేము ఈ ఈవెంట్‌లను వింటాము మరియు అవి జరిగినప్పుడు మా ప్రోగ్రామ్ ఏదైనా చేయగలదు.

$ sudo cat /sys/kernel/debug/tracing/kprobe_events
p:kprobes/kmem_cache_free kmem_cache_free
r:kprobes/kmem_cache_alloc_node kmem_cache_alloc_node

నమూనా/bpf/లోని అన్ని ఇతర ప్రోగ్రామ్‌లు అదేవిధంగా నిర్మాణాత్మకంగా ఉంటాయి. అవి ఎల్లప్పుడూ రెండు ఫైల్‌లను కలిగి ఉంటాయి:

  • XXX_kern.c: eBPF ప్రోగ్రామ్.
  • XXX_user.c: ప్రధాన కార్యక్రమం.

eBPF ప్రోగ్రామ్ ఒక విభాగానికి సంబంధించిన మ్యాప్‌లు మరియు ఫంక్షన్‌లను గుర్తిస్తుంది. కెర్నల్ ఒక నిర్దిష్ట రకం ఈవెంట్‌ను జారీ చేసినప్పుడు (ఉదాహరణకు, tracepoint), కట్టుబడి విధులు అమలు చేయబడతాయి. కార్డ్‌లు కెర్నల్ ప్రోగ్రామ్ మరియు యూజర్ స్పేస్ ప్రోగ్రామ్ మధ్య కమ్యూనికేషన్‌ను అందిస్తాయి.

తీర్మానం

ఈ వ్యాసం BPF మరియు eBPF గురించి సాధారణ పరంగా చర్చించింది. ఈరోజు eBPF గురించి చాలా సమాచారం మరియు వనరులు ఉన్నాయని నాకు తెలుసు, కాబట్టి తదుపరి అధ్యయనం కోసం నేను మరికొన్ని వనరులను సిఫార్సు చేస్తాను

నేను చదవమని సిఫార్సు చేస్తున్నాను:

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి