मैं लिनक्स कर्नेल सिस्टम कॉल के कार्यान्वयन को कैसे पा सकता हूं?


375

मैं यह समझने की कोशिश कर रहा हूं mkdirकि कर्नेल स्रोत को देखते हुए कोई फ़ंक्शन कैसे काम करता है। यह कर्नेल इंटर्ल्स को समझने और विभिन्न कार्यों के बीच नेविगेट करने का एक प्रयास है। मुझे पता mkdirहै कि में परिभाषित किया गया है sys/stat.h। मुझे प्रोटोटाइप मिला:

/* Create a new directory named PATH, with permission bits MODE.  */
extern int mkdir (__const char *__path, __mode_t __mode)
     __THROW __nonnull ((1));

अब मुझे यह देखने की जरूरत है कि यह फ़ंक्शन किस सी फाइल में लागू किया गया है। स्रोत निर्देशिका से, मैंने कोशिश की

ack "int mkdir"

जो प्रदर्शित किया गया

security/inode.c
103:static int mkdir(struct inode *dir, struct dentry *dentry, int mode)

tools/perf/util/util.c
4:int mkdir_p(char *path, mode_t mode)

tools/perf/util/util.h
259:int mkdir_p(char *path, mode_t mode);

लेकिन उनमें से कोई भी परिभाषा से मेल नहीं खाता है sys/stat.h

प्रशन

  1. किस फ़ाइल में mkdirकार्यान्वयन है?
  2. उपरोक्त जैसी फ़ंक्शन परिभाषा के साथ, मैं यह कैसे पता लगा सकता हूं कि किस फ़ाइल का कार्यान्वयन है? क्या कोई पैटर्न है जो कर्नेल को परिभाषित करने और लागू करने के तरीकों का पालन करता है?

नोट: मैं कर्नेल 2.6.36-rc1 का उपयोग कर रहा हूं


2
वैसे, इसे देखें: voinici.ceata.org/~tct/resurse/utlk.pdf
टॉम ब्रिटो

जवाबों:


386

सिस्टम कॉल को नियमित फ़ंक्शन कॉल की तरह नियंत्रित नहीं किया जाता है। यह उपयोगकर्ता कोड से कर्नेल स्पेस में संक्रमण करने के लिए विशेष कोड लेता है, मूल रूप से कॉल साइट पर आपके प्रोग्राम में इंजेक्ट असेंबली कोड का एक सा कोड होता है। कर्नेल साइड कोड जो सिस्टम कॉल को "कैच" करता है, वह भी निम्न स्तर का सामान है जिसे आपको कम से कम पहले समझने की आवश्यकता नहीं है।

में include/linux/syscalls.hअपने कर्नेल स्रोत निर्देशिका के अंतर्गत, तो आप इस पाते हैं:

asmlinkage long sys_mkdir(const char __user *pathname, int mode);

फिर /usr/include/asm*/unistd.h, आप यह पाते हैं:

#define __NR_mkdir                              83
__SYSCALL(__NR_mkdir, sys_mkdir)

यह कोड कह रहा है कि mkdir(2)सिस्टम कॉल # 83 है। कहने का तात्पर्य यह है कि सिस्टम कॉल को नंबर से बुलाया जाता है, न कि पते के रूप में, अपने प्रोग्राम के भीतर एक सामान्य फ़ंक्शन कॉल के साथ या अपने प्रोग्राम से जुड़ी लाइब्रेरी में एक फंक्शन के लिए। इनलाइन असेंबली गोंद कोड जिसका मैंने ऊपर उल्लेख किया है, इसका उपयोग उपयोगकर्ता से कर्नेल स्थान में संक्रमण बनाने के लिए करता है, साथ में अपने मापदंडों को लेकर।

एक और साक्ष्य कि चीजें यहां थोड़ी अजीब हैं, यह है कि सिस्टम कॉल के लिए हमेशा सख्त पैरामीटर सूची नहीं होती है: open(2)उदाहरण के लिए, 2 या 3 पैरामीटर ले सकते हैं। इसका मतलब open(2)है कि अतिभारित , C ++ की सुविधा, C नहीं, फिर भी syscall इंटरफ़ेस C- संगत है। (यह सी के वैरैगस फीचर के समान नहीं है , जो एकल फ़ंक्शन को चर संख्या में तर्क लेने की अनुमति देता है।)

आपके पहले प्रश्न का उत्तर देने के लिए, कोई एकल फ़ाइल mkdir()मौजूद नहीं है। लिनक्स कई अलग-अलग फ़ाइल सिस्टमों का समर्थन करता है और प्रत्येक में "mkdir" ऑपरेशन का अपना कार्यान्वयन है। अमूर्त परत जो कर्नेल को एक सिस्टम कॉल के पीछे सभी को छिपाने देती है, VFS कहलाता है । तो, आप शायद के fs/namei.cसाथ खुदाई शुरू करना चाहते हैं vfs_mkdir()। निम्न-स्तरीय फ़ाइल सिस्टम संशोधन कोड के वास्तविक कार्यान्वयन कहीं और हैं। उदाहरण के लिए, ext4 कार्यान्वयन कहा जाता है ext4_mkdir(), में परिभाषित किया गया है fs/ext4/namei.c

जैसा कि आपके दूसरे प्रश्न के लिए है, हाँ इस सब के पैटर्न हैं, लेकिन एक भी नियम नहीं है। वास्तव में आपको जिस चीज की आवश्यकता है वह इस बात की काफी व्यापक समझ है कि कर्नेल यह पता लगाने के लिए काम करता है कि आपको किसी विशेष सिस्टम कॉल के लिए कहां देखना चाहिए। सभी सिस्टम कॉल में VFS शामिल नहीं होता है, इसलिए उनकी कर्नेल-साइड कॉल चेन सभी शुरू नहीं होती हैं fs/namei.cmmap(2)उदाहरण के लिए, इसमें शुरू होता है mm/mmap.c, क्योंकि यह कर्नेल के मेमोरी प्रबंधन ("मिमी") सबसिस्टम का हिस्सा है।

मेरा सुझाव है कि आप Bovet और Cesati द्वारा " लिनक्स कर्नेल को समझना " की एक प्रति प्राप्त करें ।


बहुत अच्छा जवाब। आपके द्वारा उल्लिखित पुस्तक के बारे में एक बिंदु, "लिनक्स कर्नेल को समझना"। मेरे पास यह नहीं है, लेकिन रिलीज की तारीख (2000) और TOC (ओटिली साइट पर) से मुझे लगता है कि लगभग 2.2 गुठली है और 2.4 गुठली से कुछ अंतर्दृष्टि (लेकिन मैं गलत हूं)। मेरा सवाल है: एक बराबर किताब है जो 2.6 गुठली के आंतरिक को कवर करती है? (या इससे भी बेहतर है कि 2.2, 2.4 और 2.6 को कवर करें)?
दावालपी

2
@DavAlPi: जहां तक ​​मेरी जानकारी है, बोवेट और सिसाती अभी भी इस विषय पर सर्वश्रेष्ठ एकल पुस्तक है। जब मुझे इसे अधिक सामग्री के साथ पूरक करने की आवश्यकता होती है, तो मैं Documentationजिस कर्नेल के साथ काम कर रहा हूं उसके लिए स्रोत पेड़ की उपनिर्देशिका में खुदाई करता हूं।
वॉरेन यंग

1
वास्तव में खुला (2) एक varargs फ़ंक्शन है। इसे कॉल करने के केवल दो तरीके हैं, इसलिए मैनपेज इसे इस तरह से प्रलेखित करता है, वास्तविक प्रोटोटाइप ...में किसी भी प्रकार का कार्य होता है। बेशक, यह एफबीआईसी स्तर पर लागू किया गया है। तीसरे पैरामीटर का उपयोग न करने पर यह कर्नेल ABI के लिए या तो 0 या कचरा मान पास कर सकता है।
रैंडम 832

"यह कुछ ऐसा है जिसे आपको समझने की आवश्यकता नहीं है"। अगर इस तरह का वाक्य स्टैटेक्सचेंज नेटवर्क पर नहीं मिलता तो दुनिया एक बेहतर जगह होती।
पेट्र

84

यह संभवत: आपके प्रश्न का सीधे उत्तर नहीं देता है, लेकिन जब मैं straceअंतर्निहित सिस्टम कॉल को समझने की कोशिश कर रहा हूं, तो वास्तव में शांत होना चाहिए, कार्रवाई में, जो कि सबसे सरल शेल कमांड के लिए भी बना है। जैसे

strace -o trace.txt mkdir mynewdir

कमांड के लिए सिस्टम कॉल्स mkdir mynewdirको आपके देखने की खुशी के लिए ट्रेस.टेक्स्ट में डंप किया जाएगा।


5
+1 नीट ट्रिक! मैं उस से पहले इस्तेमाल नहीं किया था
डेविड वनिल

3
बेहतर अभी तक, आउटपुट फ़ाइल ट्रेस.स्ट्रेस बनाएं, और इसे वीआईएम में खोलें। VIM इसे हाइलाइट करेगा, जिससे इसे पढ़ना बहुत आसान हो जाएगा।
मार्सिन

55

लिनक्स कर्नेल स्रोत को पढ़ने के लिए एक अच्छी जगह लिनक्स क्रॉस-रेफरेंस (LXR) the है । खोज मुक्त पाठ खोज परिणामों के अलावा टाइप किए गए मिलान (फ़ंक्शन प्रोटोटाइप, चर घोषणाएं, आदि) लौटाती है, इसलिए यह एक मात्र grep (और तेज़ी से) से भी कम है।

LXR प्रीप्रोसेसर परिभाषाओं का विस्तार नहीं करता है। सिस्टम कॉल में प्रीप्रोसेसर द्वारा सभी जगह अपना नाम मंगवाया गया है। हालांकि, अधिकांश (सभी?) सिस्टम कॉल SYSCALL_DEFINExमैक्रोज़ के परिवारों में से एक के साथ परिभाषित हैं। चूंकि mkdirदो तर्क लगते हैं, syscallSYSCALL_DEFINE2(mkdir की घोषणा कीmkdir ओर जाता है :

SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
{
    return sys_mkdirat(AT_FDCWD, pathname, mode);
}

ठीक है, sys_mkdiratइसका मतलब यह है कि mkdiratsyscall है, इसलिए इस पर क्लिक करने से आप केवल घोषणा में आगे बढ़ते हैं include/linux/syscalls.h, लेकिन परिभाषा अभी ऊपर है।

mkdiratकॉल करना vfs_mkdir(वीएफएस सामान्य फाइलसिस्टम परत है) का मुख्य काम है । उस पर चढ़ाई दो खोज परिणामों को दिखाती है: घोषणा में include/linux/fs.hऔर ऊपर कुछ पंक्तियों की परिभाषा। का मुख्य काम vfs_mkdirफाइलसिस्टम-विशिष्ट कार्यान्वयन को कॉल करना है dir->i_op->mkdir:। यह कैसे लागू किया जाता है, यह जानने के लिए, आपको अलग-अलग फाइल सिस्टम के कार्यान्वयन की ओर मुड़ने की जरूरत है, और कोई कठिन-तेज़ नियम नहीं है - यह कर्नेल ट्री के बाहर भी एक मॉड्यूल हो सकता है।

¹ LXR एक इंडेक्सिंग प्रोग्राम है। कई वेबसाइटें हैं जो LXR को एक इंटरफ़ेस प्रदान करती हैं, जिनमें ज्ञात संस्करणों के थोड़े अलग सेट और थोड़े अलग वेब इंटरफेस हैं। वे आते हैं और जाते हैं, इसलिए यदि आप का उपयोग नहीं किया जाता है, तो दूसरे को खोजने के लिए "लिनक्स क्रॉस-संदर्भ" के लिए एक वेब खोज करें।


यह एक संसाधन की एक बिल्ली है। बहुत बढ़िया जवाब।

Linux.no के लिंक में "आंतरिक सर्वर त्रुटि" ।
फ्रेड्रिक गॉस 5

@FredrickGauss कुछ समय के लिए lxr.linux.no जो LXR का सबसे अच्छा इंटरफ़ेस था, लेकिन इसमें लगातार डाउनटाइम था। अब मुझे लगता है कि यह अच्छे के लिए चला गया है। मैंने पहले लिंक को दूसरे LXR इंटरफ़ेस में बदल दिया।
गिल्स

21

सिस्टम कॉल आमतौर पर SYSCALL_DEFINEx()मैक्रो में लिपटे होते हैं , यही वजह है कि एक साधारण grepउन्हें नहीं मिलता है:

fs/namei.c:SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)

मैक्रो का विस्तार होने के बाद अंतिम फ़ंक्शन नाम को समाप्त किया जा रहा है sys_mkdirSYSCALL_DEFINEx()मैक्रो कोड है कि प्रत्येक syscall परिभाषा की जरूरत का पता लगाने की तरह बॉयलरप्लेट बातें कहते हैं।


17

नोट: .h फ़ाइल फ़ंक्शन को परिभाषित नहीं करती है। यह उस .h फ़ाइल में घोषित है और कहीं और परिभाषित (कार्यान्वित) है। यह संकलक को फ़ंक्शन के हस्ताक्षर (प्रोटोटाइप) के बारे में जानकारी शामिल करने की अनुमति देता है ताकि प्रकार के तर्कों की जाँच की जा सके और अपने कोड में किसी भी कॉलिंग संदर्भ में रिटर्न प्रकारों का मिलान किया जा सके।

सामान्य में .h (हैडर) फाइलें C में फ़ंक्शन को घोषित करने और मैक्रोज़ को परिभाषित करने के लिए उपयोग की जाती हैं।

mkdirविशेष रूप से एक सिस्टम कॉल है। उस सिस्टम कॉल के आसपास एक GNU libc आवरण हो सकता है (लगभग निश्चित रूप से, वास्तव में)। mkdirविशेष रूप से कर्नेल स्रोतों और सिस्टम कॉल को खोजकर इसका सही कर्नेल कार्यान्वयन पाया जा सकता है।

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


8

आपके द्वारा पाया गया कोई भी कार्यान्वयन sys / stat.h में प्रोटोटाइप से मेल नहीं खाता है। हो सकता है कि इस हेडर फ़ाइल के साथ एक सम्मिलित कथन की खोज अधिक सफल हो?


1
कार्यान्वयन (जैसा कि sys / stat.h में वर्णित है) उपयोगकर्ता और libc का व्यवसाय है। कर्नेल आंतरिक सामग्री (यह वास्तव में कैसे किया जाता है) कर्नेल आंतरिक व्यवसाय है। सभी कर्नेल हैकर्स देखभाल के लिए, आंतरिक फ़ंक्शन को xyzzy कहा जा सकता है और 5 पैरामीटर ले सकता है। यह उपयोगकर्ता के कॉल को लेने के लिए libc का काम है, जो भी कर्नेल आवृत्तियों की आवश्यकता है, उसका अनुवाद करें, इसे शिप करें और कोई भी परिणाम एकत्र करें।
वॉनब्रांड

6

यहाँ निम्न स्तर के कर्नेल स्रोत कोड के शिकार के लिए विभिन्न तकनीकों का वर्णन करने वाले एक जोड़े वास्तव में महान ब्लॉग पोस्ट हैं।


12
कृपया केवल ब्लॉग या फ़ोरम के लिंक पोस्ट न करें, अपनी सामग्री संक्षेप में दें ताकि पाठक देख सकें कि वे क्या कर रहे हैं, और साइटों के गायब होने पर कुछ छोड़ दिया है। इसके अलावा, आपका पहला लिंक libc के बारे में है, जो इस प्रश्न के लिए ऑफ-टॉपिक है।
गाइल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.