कर्नेल चलाने में समर्थित सिस्टम कॉल


9

क्या वर्तमान में लिनक्स कर्नेल द्वारा समर्थित सिस्टम कॉल की संख्या या सूची प्राप्त करने का कोई तरीका है? इसलिए मैं एक रनिंग कर्नेल की syscall टेबल को 'रीड' करने का तरीका खोजना चाहता हूं।

जवाबों:


15

फ़ाइल /proc/kallsymsचल रहे कर्नेल के सभी प्रतीकों को सूचीबद्ध करती है। कन्वेंशन द्वारा, सिस्टम कॉल में एक नाम होता है, जो शुरू होता है sys_। 64-बिट सिस्टम पर, 32-बिट प्रोग्राम के लिए सिस्टम कॉल का एक नाम है जो इसके साथ शुरू होता है sys32_। सच पूछिये तो, इस सूचियों आंतरिक गिरी काम करता है, नहीं सिस्टम कॉल, लेकिन मुझे लगता है कि पत्राचार काम करता है लगता है (हर सिस्टम कॉल एक आंतरिक गिरी समारोह का आह्वान काम करने के लिए, और मुझे लगता है कि नाम हमेशा सिस्टम कॉल के नाम के साथ है sys_prepended )।

</proc/kallsyms sed -n 's/.* sys_//p'

यह आमतौर पर उपयोगी जानकारी नहीं है, क्योंकि सिस्टम कॉल बहुत धीरे-धीरे बदलते हैं। वैकल्पिक घटक मौजूदा सिस्टम कॉल के संदर्भ में कार्यक्षमता प्रदान करते हैं, सामान्य सुविधाओं का उपयोग करते हैं जैसे उपकरणों ( ioctl के साथ जब readऔर writeइसे काट नहीं करते हैं), फाइलसिस्टम, सॉकेट्स, आदि समर्थित syscalls की सूची का निर्धारण आपको सुविधाओं के बारे में कुछ भी नहीं बताएगा। यह सिस्टम सपोर्ट करता है। अन्य आंतरिक फ़ंक्शन नाम या तो मदद नहीं करेंगे क्योंकि ये बहुत जल्दी बदल जाते हैं: फ़ंक्शन का नाम जो एक कर्नेल संस्करण पर कुछ सुविधा को लागू करता है अगले संस्करण पर बदल सकता है।


+1। अब मेरा यही मतलब है जब मैंने कहा "मैं किसी को अपने जवाब से ज्यादा अनुभव के साथ रहने दूंगा" । इसके अतिरिक्त, चूंकि /proc/kallsymsकिसी भी अन्य फ़ाइल की तरह हेरफेर किया जा सकता है , इसलिए प्रोग्राम में इसका उपयोग करना काफी आसान हो जाता है।
जॉन डब्ल्यूएच स्मिथ

2
@JohnWHSmith "किसी भी अन्य फ़ाइल की तरह हेरफेर किया जा सकता है" ... इस चेतावनी के साथ कि कर्नेल ASLR वाले सिस्टम पर, यह फ़ाइल केवल रूट द्वारा पठनीय होनी चाहिए।
गिल्स एसओ- बुराई को रोकना '

7

टी एल; डॉ

मैं इस उत्तर को लिखते समय नए विकल्प खोजता रहा, इसलिए मैंने उनमें से प्रत्येक के बारे में थोड़ा सा विवरण लिखा और कुछ आँकड़े बनाए। मूल रूप से, आप या तो कर सकते हैं:

  • गाइल्स का जवाब पढ़ें, जो इसे करने के लिए एक साफ और तेज तरीका प्रदान करता है (पर निर्भर करता है /proc)।
  • प्रलेखन संसाधनों का उपयोग करें।
  • अपने सिस्टम की C हेडर फ़ाइलों का उपयोग करें।
  • कर्नेल स्रोत कोड का ही उपयोग करें।
  • /sysनिर्देशिका का उपयोग करें ।

गणित करने के बाद, मैं /sysफाइल सिस्टम का उपयोग करके (अपने विकल्पों में से) सलाह दूंगा , क्योंकि यह सिस्टम कॉल की संख्या के मामले में सबसे अच्छा परिणाम देता है। यदि आप अन्य ट्रिक्स के बारे में नहीं पढ़ना चाहते हैं तो आप उस सेक्शन पर जा सकते हैं।

प्रलेखन संसाधनों का उपयोग करना

जब आप उनमें से कुछ को याद कर सकते हैं, तो आप aproposधारा 2 (सिस्टम कॉल) से संबंधित सभी मैनपेज़ को सूचीबद्ध करने के लिए उपयोग कर सकते हैं :

$ apropos -s2 . | awk '{print $1}' | column

columnयदि आप फैंसी स्तंभित आउटपुट नहीं चाहते हैं तो निकालें ।

मुझे अभी पता चला है, लेकिन सिस्टम कॉल के बारे में लिनक्स मैन पेज है, और आप उनमें से अधिकांश को ढूंढ पाएंगे।

$ man syscalls

मैं इन दो वेब साइटों पर भी आया जो दिलचस्प हो सकती हैं:

हेडर फ़ाइलों का उपयोग करना

संपादित करें: अब, जब यह प्रोग्रामिक रूप से आता है (या कम से कम, दस्तावेज सुविधाओं पर निर्भर हुए बिना) यह निर्धारित करते हुए कि सिस्टम कॉल उपलब्ध हैं, मुझे डर है कि कर्नेल अपने सिस्टम कॉल की तालिका नहीं रखता है, कम से कम के रूप में नहीं तार की एक सूची (जैसा कि आप शायद उन्हें हेरफेर करने की उम्मीद करेंगे)। इस स्तर पर, हम फ़ंक्शन के नामों के बजाय फ़ंक्शंस पते और संकेत के बारे में अधिक बात कर रहे हैं।

मैंने अभी-अभी अपनी /usr/includeनिर्देशिका को तैयार किया है और grepकुछ चीज़ों की खोज की है: आपको निम्नलिखित निर्देशिकाएँ दिलचस्प लग सकती हैं। उनमें से कुछ आपके आर्किटेक्चर और वितरण के आधार पर आपकी मशीन पर भिन्न हो सकते हैं, लेकिन मुझे यकीन है कि आप उन्हें अनुकूलित कर पाएंगे।

  • / Usr / शामिल / लिनक्स
  • / Usr / शामिल / x86_64-linux-gnu
  • / Usr / शामिल / sys
  • / Usr / शामिल / ASM-सामान्य

इस फ़ाइल में फ़ंक्शन परिभाषाओं की तलाश करके, आप कई सिस्टम कॉल पर आएंगे, भले ही वे पूरी तरह से वहां परिभाषित न हों। मैं grepइन निर्देशिकाओं में कुछ एस चला गया और मैं कुछ सिस्टम कॉल का उल्लेख खोजने में सक्षम था। यहाँ एक उदाहरण है:

$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)

इसलिए, मैं उनमें से कुछ को खोजने का एक और तरीका अनुमान लगा रहा हूं:

$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'

कर्नेल के स्रोत कोड और इसकी syscall तालिका का उपयोग करना

एक अन्य उपाय कर्नेल स्रोत कोड का उपयोग करना है (और न केवल हेडर!), और इसे कुशलता से खोजने का एक तरीका है। चूंकि कर्नेल 303395ac3bf3e2cb488435537d416bc840438fcb करता है , इसलिए आपको यह पहले से थोड़ा आसान लग सकता है। यहाँ 3.13 के लिए एक उदाहरण है (जो मेरी कर्नेल है):

$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl

अब जब आपको वास्तविक syscalls तालिका मिली है, तो इसे ब्राउज़ करें:

$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl

आप एक तरह से मिल सकता है, का उपयोग करते हुए unameऔर archडाउनलोड करने के लिए, tblसे फाइल सीधे git.kernel.org , अपने चल रहे कर्नेल संस्करण और वास्तुकला पर आधारित।

/sysफाइलसिस्टम का उपयोग करना

गिल्स के जवाब ने मुझे थोड़ी प्रेरणा दी, और हो सकता है कि आप उन सिस्टम कॉल को अपने अंदर पा सकें /sys/kernel/debug/tracing/events/syscalls। इस निर्देशिका का उपयोग सिस्टम पर प्रत्येक सिस्टम कॉल के उपयोग की निगरानी के लिए किया जाता है। प्रत्येक syscall में दो निर्देशिकाएं हैं:

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

इसलिए, का उपयोग कर ls, grepऔर cut...

$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3

आँकड़े

मेरे सिस्टम पर:

  • मैन पेज के इस्तेमाल से 440 सिस्टम कॉल का पता चला।
  • grepके लिए आईएनजी __SYSCALLहेडर फाइल में 212 सिस्टम कॉल का पता चला।
  • कर्नेल स्रोतों से syscalls तालिका को पढ़ने से 346 सिस्टम कॉल का पता चला।
  • /sysखुलासा 290 सिस्टम कॉल का उपयोग करना ।

अब, अगर मैं सब कुछ एक साथ लाता हूं ...

$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt

$ sort < system_calls.txt | uniq | wc -l
707

वहां हम जाते हैं, 707 सिस्टम कॉल! बेशक, यह संख्या एक "सिस्टम कॉल" की बहुत लचीली परिभाषा को दर्शाती है, क्योंकि 3.13 केवल 274 सिस्टम कॉल प्रदान करने के लिए माना जाता है (रीडिंग /sysनिकटतम समाधान लगता है)।


मैं सिस्टम कॉल टेबल को किसी तरह से 'पढ़ने' के संदर्भ में एक और तरीका खोज रहा हूं जो यह पता लगाने के बजाय कि सिस्टम कॉल किस मैन पेज में प्रलेखित हैं
स्वायर

मुझे नहीं लगता कि कर्नेल अपने syscalls की सूची रखता है, कम से कम तार की सूची के रूप में नहीं। मैंने अपना उत्तर संपादित किया। अगर ऐसा करने का कोई वास्तविक तरीका है, तो मैं आपको जवाब देने के बजाय किसी और अनुभव का अनुभव दूंगा;)
जॉन डब्ल्यूएच स्मिथ

इसलिए मैं इसके बारे में सोच रहा था जब मैंने कर्नेल में एक सिस्टम कॉल जोड़ा और इसका उपयोग करने की कोशिश "फ़ंक्शन कार्यान्वित नहीं" दे रहा था, और मुझे आश्चर्य हुआ कि क्या वर्तमान कर्नेल के लिए syscall तालिका प्राप्त करने का कोई तरीका था। जब मैं '#make इंस्टॉल' करता हूं, तो ग्रब को अपडेट करें और एक नया कर्नेल शुरू करें, किस कदम पर नए कर्नेल को प्रासंगिकता मिलती है जिसमें नई सिस्टम कॉल शामिल हैं?
स्वायर

1
यदि आप सिस्टम कॉल नहीं पाते हैं, तो आपने इसे सही तरीके से लागू नहीं किया है। मेरा जवाब आपको बताता है कि लिनक्स के सिस्टम कॉल को कैसे खोजना है, लेकिन अपने खुद के डिबग कैसे करें (क्योंकि यह वह नहीं है जो आप पूछ रहे हैं)। यदि आपको इसे विकसित करने में समस्या हो रही है, तो आपको विशेष रूप से इसके बारे में एक प्रश्न पूछना चाहिए, और XY समस्या से बचना चाहिए ।
जॉन डब्ल्यूएच स्मिथ

@swair सिस्टम कॉल जोड़कर कार्यक्षमता को जोड़ना अत्यधिक असामान्य है। हम यह सुनिश्चित करने के लिए नहीं बता सकते हैं कि आपके द्वारा कोई कोड प्रदान नहीं किए जाने के बाद क्या गलत है (और यदि आपके प्रश्न को C कोड की आवश्यकता है, तो यह यहां ऑफ-टॉपिक है, लेकिन स्टैक ओवरफ्लो पर घर पर )। मुझे संदेह है कि आपने सिस्टम कॉल (सही ढंग से या नहीं) लागू किया है और आप इसे C प्रोग्राम से उपयोग करने का प्रयास कर रहे हैं, और आप सी फ़ंक्शन लिखने का चरण याद कर रहे हैं जो सिस्टम कॉल करता है। एक सिस्टम कॉल एक साधारण फ़ंक्शन कॉल नहीं है।
गिल्स एसओ- बुराई को रोकें '

1

सभी उत्तर ठीक हैं।

यदि आप एक विशिष्ट सिस्टम कॉल नाम की तलाश कर रहे हैं:

$ cat /proc/kallsyms | grep <sys_call_name>

यदि आप सभी सिस्टम कॉल की सूची देख रहे हैं:

$ cat /proc/kallsyms
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.