पता करें कि कौन से फाइल डिस्क्रिप्टर समान "ओपन फाइल विवरण" साझा करते हैं


17

अगर मैं (एक बॉर्न की तरह खोल में):

exec 3> file 4>&3 5> file 6>> file

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

अब, lsofआउटपुट में, हम सभी देखते हैं:

zsh     21519 stephane    3w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    4w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    5w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    6w   REG  254,2        0 10505865 /home/stephane/file

यह थोड़ा बेहतर है lsof +fg:

zsh     21519 stephane    3w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    4w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    5w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    6w   REG       W,AP,LG  254,2        0 10505865 /home/stephane/file

(यहाँ लिनक्स ३.१६ पर) हम देखते हैं कि fd ६ में अलग-अलग झंडे हैं, इसलिए इसे ३, ४ या ५ में से एक से एक अलग खुली फ़ाइल का विवरण होना चाहिए , लेकिन इससे हम नहीं बता सकते कि fd ५ पर है विभिन्न खुले फ़ाइल विवरण । के साथ -o, हम भी ऑफसेट देख सकते हैं, लेकिन फिर से वही ऑफसेट की गारंटी नहीं है यह एक ही खुला फ़ाइल विवरण है

वहाँ किसी भी गैर घुसपैठ 1 तरीका है कि पता लगाने के लिए है? बाहरी रूप से, या किसी प्रक्रिया के लिए स्वयं के फ़ाइल डिस्क्रिप्टर?


1 है । एक हेयुरिस्टिक दृष्टिकोण के साथ एक एफडी के झंडे को बदलने के लिए हो सकता है fcntl()और देखें कि अन्य फाइल डिस्क्रिप्टर के परिणामस्वरूप उनके झंडे अपडेट किए गए हैं, लेकिन यह स्पष्ट रूप से आदर्श नहीं है और न ही मूर्ख प्रमाण


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

@ धन्यवाद, धन्यवाद, लेकिन यह कम या ज्यादा दृष्टिकोण मैं पहले से ही सवाल का सुझाव है। पट्टों (आपको लगता है कि F_SETLEASE fcntl का अर्थ है, मुझे उनके बारे में पता करने के लिए धन्यवाद BTW) केवल आपके पास नियमित फ़ाइलों के लिए काम करेगा और नहीं अगर वहाँ एक ही फ़ाइल (EBUSY) के लिए एक और " खुला " फ़ाइल विवरण है, और यह बिल्कुल गैर नहीं है -दखल।
स्टीफन चेजालस 12

क्या आपने इस प्रश्न को छोड़ दिया है? मैंने कुछ जानकारी पोस्ट की कि कैसे SystemTap आप जो चाहते हैं, कर सकते हैं, लेकिन आपने कोई जवाब पूरा नहीं किया है ...?
अज़रेई

जवाबों:


2

लिनक्स 3.5 और उसके बाद, यह kcmp (3) के साथ पूरा किया जा सकता है :

KCMP_FILE

  • जाँच करें कि क्या एक फ़ाइल वर्णनकर्ता idx1 प्रक्रिया में pid1 ही खुली हुई फ़ाइल विवरण को संदर्भित करता है (देखें खुला (2) फ़ाइल वर्णनकर्ता के रूप में) idx2 प्रक्रिया में pid2 । दो फ़ाइल डिस्क्रिप्टर का अस्तित्व जो एक ही ओपन फाइल डिस्क्रिप्शन को संदर्भित करता है, डुबकी (2) (और इसी तरह) कांटा (2) , या एक डोमेन सॉकेट ( यूनिक्स देखें (7) देखें ) के माध्यम से फाइल डिस्क्रिप्टर के परिणामस्वरूप हो सकता है ।

मैन पेज विशेष रूप से उपयोग के मामले के लिए एक उदाहरण प्रदान करता है ओपी ने पूछा। ध्यान दें कि इस syscall के लिए कर्नेल को CONFIG_CHECKPOINT_RESTOREसेट के साथ संकलित करने की आवश्यकता होती है ।


धन्यवाद। बिल्कुल वही, जिसकी मुझे तलाश थी। ध्यान दें कि जब तक आप सुपरसुअर नहीं हो जाते, तब तक यह आपकी दो प्रक्रियाएँ होनी चाहिए (और सेट्युड / सेटगिड नहीं होना चाहिए ...) (समझ में आता है)
स्टीफन चेज़लस

@ स्टीफनचेज़लस बिल्कुल। यदि किसी कारण से CPIU समर्थन आपके कर्नेल में नहीं बनाया गया था और आप इसे फिर से बनाना नहीं चाहते हैं, तो मुझे लगता है कि आप हमेशा एक कर्नेल मॉड्यूल लिख सकते हैं जो कुछ यूजरलैंड इंटरफ़ेस को निर्यात करता है जो आपको struct file *पॉइंटर्स की तुलना करने देता है ।
माइनमैक्सवग

3

आप जिस struct fileचीज़ की तुलना करना चाहते हैं, वह वे बिंदु हैं जो फ़ाइल डिस्क्रिप्टर इंगित करते हैं। (कर्नेल के अंदर task_structप्रत्येक थ्रेड के लिए एक डेटा संरचना है। इसमें किसी अन्य संरचना के लिए एक पॉइंटर होता है, जिसे कहा जाता है files_struct। और उस संरचना में पॉइंटर्स की एक सरणी होती है, प्रत्येक में एक struct file। यह struct fileवह है जो साक ऑफसेट, खुले झंडे और धारण करता है। कुछ अन्य क्षेत्र।)

मुझे किसी भी उपयोगकर्ता-दृश्य तरीके का पता नहीं है files_structजिसमें कुछ घुसपैठिए उपकरणों के उपयोग के अलावा संकेत देखने के लिए । उदाहरण के लिए, SystemTap को एक PID दिया जा सकता है और यह इसी का पता लगा सकता है task_structऔर संकेत का पालन कर सकता है । यदि आप निष्क्रिय की तलाश कर रहे हैं, हालांकि, मुझे लगता है कि इसके बारे में है। डेल ने बहुत समय पहले KME (कर्नेल मेमोरी एडिटर) नामक एक टूल जारी किया था जो कि कर्नेल मेमोरी को लाइव करने के लिए एक स्प्रेडशीट जैसा इंटरफ़ेस देता था और यह वही कर सकता है जो आप चाहते हैं, लेकिन इसे कभी भी 64-बिट में पोर्ट नहीं किया गया था। (मैंने कोशिश की और कभी भी इसे पूरी तरह से काम नहीं मिला, और निश्चित नहीं था कि क्यों।)

आपके lsofद्वारा मददगार नहीं होने का एक कारण यह है कि यह उन बिंदुओं को या तो नहीं देखता है (लेकिन +fगैर-लिनक्स सिस्टम के लिए विकल्प देखें)। आप सैद्धांतिक रूप से सभी क्षेत्रों की तुलना कर सकते हैं struct fileऔर सोच सकते हैं कि दो संरचनाएं समान हैं, फिर भी वे अलग-अलग open(2)कॉल से हो सकते हैं।

विचारों के लिए pfiles SystemTap स्क्रिप्ट पर एक नज़र डालें । यदि आपने इसका पता छापने के लिए संशोधित किया है struct file, तो आपके पास अपना समाधान होगा। आप भी open_file_by_pid.stp की जांच कर सकते हैं क्योंकि इसमें एक फ़ंक्शन है जो चलता है files_struct, यानी। फ़ाइल डिस्क्रिप्टर तालिका, struct fileऑब्जेक्ट्स को देखकर ...

क्या मैं पूछ सकता हूं कि आप क्या हासिल करना चाहते हैं?


मुझे स्वीकार करना होगा कि मुझे उस मामले को याद नहीं करना चाहिए जहाँ मुझे इसकी आवश्यकता थी। कुछ डिबगिंग या फोरेंसिक कार्य में कोई संदेह नहीं है।
स्टीफन चेजेलस

मैं PoC systemtap कोड :-)
स्टीफन चेज़लस

इससे पहले कि मैं सवाल पोस्ट करता, मैं systemtap या / proc / kcore दृष्टिकोण पर एक नज़र रखता था। मुश्किल हिस्सा यह था कि हर कार्य के लिए हर fd के लिए जानकारी प्राप्त करें । मेरे द्वारा पाया गया सबसे आशाजनक दृष्टिकोण / proc / * / task / fd निर्देशिका की सामग्री को उत्पन्न करने वाले कार्यों में शामिल था, लेकिन एकमात्र व्यावहारिक चीजें जो मैं स्रोत फ़ाइल में विशिष्ट लाइन नंबरों पर शामिल होने के साथ आ सकती थी, ऐसा नहीं एक कर्नेल संस्करण से अगले तक पोर्टेबल। आप सिस्टमटैप में वास्तव में कार्य सूची के माध्यम से लूप नहीं कर सकते। शायद / proc / kcore के माध्यम से संभव है, लेकिन बहुत अधिक प्रयास और शायद अविश्वसनीय।
स्टीफन चेज़लस

अब तक की सर्वश्रेष्ठ प्रतिक्रिया के लिए धन्यवाद। मैं आपके संकेत पर एक नजर डालूंगा।
स्टीफन चेजेलस

जरूर आप कर सकते हो! एक probe beginब्लॉक सेट करें और इसे for_each_processस्क्रिप्ट में एम्बेडेड सी कोड के ब्लॉक में मैक्रो का उपयोग करें (आपको सी कोड एम्बेड करने के लिए "गुरु" मोड सिस्टमटैप का उपयोग करना होगा)। वास्तव में, इसे दिलचस्प (!) बनाने के लिए, आप सिस्टमटैप के सहयोगी सरणियों में से एक का उपयोग कर सकते हैं; files_structपते को कुंजी के रूप में और मानों के रूप में पीआईडी ​​/ टीआईडी ​​की सूची का उपयोग करें । अब आपके पास प्रत्येक खोली गई फ़ाइल की एक सूची है और कौन से कार्य उन्हें साझा कर रहे हैं (वे माता-पिता / बच्चे के बीच साझा किए जा सकते हैं)। यदि आप SystemTap पर चर्चा करना चाहते हैं तो फिर से उत्तर दें।
ऐजरेई

0

यहाँ एक लिनक्स विशिष्ट समाधान है: / proc / self / fd वर्तमान प्रक्रिया में खुली फ़ाइल हैंडल के लिए प्रतीकात्मक लिंक की एक निर्देशिका है। आप बस लिंक मूल्यों की तुलना कर सकते हैं। यह एक बच्चे की प्रक्रिया का उपयोग करते समय अधिक जटिल हो जाता है, क्योंकि बच्चे के पास एक अलग / प्रोक / स्व होगा क्योंकि यह एक पीआईडी ​​पर निर्भर प्रतीकात्मक लिंक है। आप इस समस्या को हल / खरीद / $ / $ / fd कर सकते हैं, जहाँ $ $ वांछित पिड है।


धन्यवाद। लेकिन ऐसा मैं नहीं पूछ रहा हूं। लिनक्स पर, lsof वास्तव में झंडे के लिए प्रत्येक फ़ाइल डिस्क्रिप्टर और / proc / pid / fdinfo के लिए पथ प्राप्त करने के लिए / proc / pid / fd का उपयोग करता है। लेकिन जो मैं चाहता हूं, वह यह है कि दो एफडी के लिए एक ही फाइल के लिए चाहे वे एक ही ओपन फाइल विवरण की ओर इशारा करें या दो फाइल डिस्क्रिप्टर स्वतंत्र रूप से खुले हों।
स्टीफन चेज़लस

ठीक है, जब आपको फ़ाइल डिस्क्रिप्टर के जोड़े मिले हैं जो एक ही फ़ाइल नाम के लिए खुले हैं, तो दोनों पर एक विवरण दें और परिणामों की तुलना करें, यदि वे अलग हैं तो वे अलग हैं। यदि वे एक फाइल डिस्क्रिप्टर और रिपीट पर समान हैं, यदि वे अभी भी मेल खाते हैं तो वे समान हैं।
हल्दी

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