2010-03-01 13 views
14

लिनक्स और अन्य यूनिक्स जैसी ऑपरेटिंग सिस्टम की मूल स्वामित्व प्रक्रिया ढूंढें, यह इंटरनेट सॉकेट साझा करने के लिए दो (या अधिक) प्रक्रियाओं के लिए possible है। मान लीजिए कि प्रक्रियाओं के बीच कोई अभिभावक-बाल संबंध नहीं है, क्या यह बताने का कोई तरीका है कि मूल रूप से किस सॉकेट ने सॉकेट बनाया है?लिनक्स सॉकेट

स्पष्टीकरण: मुझे /proc फाइल सिस्टम या इसी तरह के उपयोग से प्रक्रियाओं के बाहर "इसे" निर्धारित करने की आवश्यकता है। मैं प्रक्रियाओं के कोड को संशोधित नहीं कर सकता। मैं पहले ही बता सकता हूं कि /proc/<pid>/fd पढ़कर कौन सी प्रक्रियाएं सॉकेट साझा कर रही हैं, लेकिन यह मुझे नहीं बताती कि मूल रूप से उन्हें किस प्रक्रिया ने बनाया है।

+0

कृपया विस्तार से बताएं कि आप बिना किसी माता-पिता के रिश्ते वाले सॉकेट साझा करने की व्यवस्था कैसे करेंगे। – bmargulies

+0

जो प्रश्न मैंने लिंक किया है, उसे समझाता है। मैंने यह भी देखा है कि यह मेरे लिनक्स बॉक्स पर होता है। –

+0

ओह, ठीक है। मैं पूरी तरह से भूल गया। – bmargulies

उत्तर

-1

मुझे एक प्रक्रिया से दूसरी प्रक्रिया में सॉकेट भेजने के लिए sendmsg() का उपयोग करने के बारे में पता नहीं है।

मुझे पता है कि बाइंड() सिस्टम-कॉल EADDRINUSE लौटाएगी यदि दूसरी प्रक्रिया उसी पोर्ट का उपयोग करने का प्रयास करती है।

3

आप संभावित रूप से पार्सिंग/proc/net/tcp (और अन्य प्रोटोकॉल के लिए समान "फाइलें) द्वारा साझा सॉकेट पा सकते हैं।/Proc/net/tcp here पर कुछ दस्तावेज़ हैं।

आपको सॉकेट (शायद इसके आईपी पते/पोर्ट नंबरों द्वारा) ढूंढना होगा और इनोड नंबर को पार्स करना होगा। एक बार आपके पास इनोड हो जाने के बाद, आप /proc/*/fd/* के माध्यम से सभी लिंक के लिए stat पर कॉल करके struct stat के सदस्य को तब तक खोज सकते हैं जब तक आपको कोई मिलान न मिल जाए।

इनोड संख्या 2 प्रक्रियाओं के बीच मेल खाना चाहिए, इसलिए जब आप सभी /proc/*/fd/* से गुजर चुके हैं तो आपको उन्हें दोनों मिलना चाहिए था।

यदि आपको पता है कि पहले की प्रक्रिया आईडी और सॉकेट एफडी है, तो आपको/proc/net/tcp के माध्यम से जाने की आवश्यकता नहीं है, आपको केवल /proc/<pid>/fd/<fd> की स्थिति है और शेष /proc/*/fd/* खोजें एक मिलान इनोड। यदि आप आईपी पते/पोर्ट नंबर लाने के लिए चाहते हैं तो आपको/proc/net/tcp की आवश्यकता होगी - यदि आप इनोड नंबर

+0

शायद मैंने खुद को अच्छी तरह से समझाया नहीं। मुझे पहले से ही पता है कि कैसे प्रक्रियाएं सॉकेट साझा कर रही हैं। मैं आपके द्वारा वर्णित विधि का उपयोग कर ऐसा करता हूं। लेकिन इससे मुझे यह निर्धारित करने में मदद नहीं मिलती कि कौन सी प्रक्रिया मूल रूप से सॉकेट के स्वामित्व में थी। शायद मुझे प्रत्येक प्रक्रिया की उम्र के आधार पर अनुमान लगाने की आवश्यकता है। –

+0

यदि आप अपने प्रश्न को उस स्थिति में अपडेट करते हैं जो आप खोज रहे हैं, तो यह बहुत उपयोगी होगा, और आप इसे शामिल किसी भी कार्यक्रम से बाहर कर रहे हैं। हालांकि मूल मालिक या निर्माता पर कहीं भी कोई सीधी जानकारी नहीं है। आपको प्राप्त होने वाली सबसे नज़दीकी चीज/proc/pid/fd/fd में लिंक पर 'lstat' को कॉल कर रही है और अनुमान लगाएं कि सबसे पुराना टाइमस्टैम्प (सीटाइम संभवतः) मूल निर्माता था। – nos

+0

स्पष्ट करने के लिए प्रश्न को अपडेट किया गया। –

7

'lsof -Ua' मदद नहीं करते हैं, तो आप पाएंगे कि आप क्या पा सकते हैं?

+0

अतिरिक्त जानकारी के साथ अच्छा जवाब: यह काम करता है हालांकि मेरा मानना ​​है कि एक अनावश्यक है क्योंकि परिणाम समान और बिना दिखते हैं, लेकिन, कुछ लिनक्स पर, ऐसा लगता है कि 'lsof' काफी हद तक निपुण है और इस जानकारी को खोजने के लिए ऊंची अनुमतियों की आवश्यकता है । उदाहरण के लिए, मैं /tmp/ssh-W1Tl4i8HiftZ/agent.21283 के पीआईडी ​​को जानना चाहता था, लेकिन 'lsof -Ua /tmp/ssh-W1Tl4i8HiftZ/agent.21283' कुछ भी नहीं दिखाता है - यहां तक ​​कि एक त्रुटि संदेश भी नहीं। दूसरी ओर, 'सुडो lsof -Ua /tmp/ssh-W1Tl4i8HiftZ/agent.21283' बहुत खुलासा था और एक पीआईडी ​​दिखाया था। अफसोस की बात है, सूडो या उन्नत अनुमतियां कई कार्यों के लिए व्यवहार्य नहीं हैं। – kbulgrien

18

आप इसके लिए नेटस्टैट का उपयोग कर सकते हैं। आपको कॉलम 'लोकल एड्रेस' और 'पीआईडी ​​/ प्रोग्राम नाम' में देखना चाहिए।

[email protected]:~$ netstat -tulpen 
(Not all processes could be identified, non-owned process info 
will not be shown, you would have to be root to see it all.) 
Active Internet connections (only servers) 
Proto Recv-Q Send-Q Local Address   Foreign Address   State  User  Inode  PID/Program name 
tcp  0  0 127.0.0.1:4005   0.0.0.0:*    LISTEN  1000  68449  7559/sbcl  
tcp  0  0 0.0.0.0:6000   0.0.0.0:*    LISTEN  0   3938  -    
tcp6  0  0 :::6000     :::*     LISTEN  0   3937  -    
udp  0  0 0.0.0.0:68    0.0.0.0:*       0   4528  -    
0

एक टेस्ट केस बनाने प्रयोजनों के लिए, एक स्थिति है जहाँ कई ssh-agent प्रक्रियाओं चल रहे हैं पर विचार करें और खुले सॉकेट की है। अर्थात। एक उपयोगकर्ता ssh-agent कई बार चलाता है और दिए गए जब एजेंट शुरू कर दिया सॉकेट/पीआईडी ​​जानकारी खो देता है:

$ find /tmp -path "*ssh*agent*" 2>/dev/null 
/tmp/ssh-0XemJ4YlRtVI/agent.14405 
/tmp/ssh-W1Tl4i8HiftZ/agent.21283 
/tmp/ssh-w4fyViMab8wr/agent.10966 

बाद में, उपयोगकर्ता प्रोग्राम के रूप में एक विशेष ssh-एजेंट सॉकेट की पीआईडी ​​मालिक निर्धारित करने के लिए चाहता है (यानी/tmp/ssh -W1Tl4i8HiftZ/एजेंट।21,283):

$ stat /tmp/ssh-W1Tl4i8HiftZ/agent.21283 
    File: '/tmp/ssh-W1Tl4i8HiftZ/agent.21283' 
    Size: 0    Blocks: 0   IO Block: 4096 socket 
Device: 805h/2053d  Inode: 113   Links: 1 
Access: (0600/srw-------) Uid: (4000/ myname) Gid: (4500/ mygrp) 
Access: 2018-03-07 21:23:08.373138728 -0600 
Modify: 2018-03-07 20:49:43.638291884 -0600 
Change: 2018-03-07 20:49:43.638291884 -0600 
Birth: - 

इस मामले में, क्योंकि ssh-agent एक मानव दर्शक, अनुमान लगा सकते हैं कि सॉकेट 21,284 पीआईडी ​​के अंतर्गत आता है क्योंकि सॉकेट नाम एक अंकीय घटक है कि एक पीआईडी ​​से एक बंद होता है के रूप में अपनी सॉकेट अच्छी तरह से नामित ps के साथ की पहचान:

$ ps -ef | grep ssh-agent 
myname 10967  1 0 16:54 ?  00:00:00 ssh-agent 
myname 14406  1 0 20:35 ?  00:00:00 ssh-agent 
myname 21284  1 0 20:49 ?  00:00:00 ssh-agent 

यह किसी भी धारणा है कि PIDs इतना विश्वसनीय हमेशा की तरह केवल एक ही रूप से बंद हो सकता है, लेकिन यह भी हो जाएगा बनाने के लिए अत्यधिक मूर्ख लगता है, एक लगता है हो सकता है कि नहीं सभी सॉकेट रचनाकारों सॉकेट नाम होगा बहुत अच्छी तरह से।

@ साइफर का जवाब सॉकेट मालिक के पीआईडी ​​की पहचान करने की समस्या के सीधा समाधान के लिए इंगित करता है, लेकिन lsof के रूप में अपूर्ण है, वास्तव में केवल इस पीआईडी ​​को ऊंची अनुमतियों के साथ पहचान सकता है।

$ sudo lsof /tmp/ssh-W1Tl4i8HiftZ/agent.21283 
COMMAND  PID USER FD TYPE    DEVICE SIZE/OFF NODE NAME 
ssh-agent 21284 myname  3u unix 0xffff971aba04cc00  0t0 1785049 /tmp/ssh-W1Tl4i8HiftZ/agent.21283 type=STREAM 

इस मामले में, पीआईडी ​​(myname) और सॉकेट का मालिक था: ऊंचा अनुमतियाँ के बिना, कोई परिणाम आगामी हैं:

$ lsof /tmp/ssh-W1Tl4i8HiftZ/agent.21283 
$ 
ऊंचा अनुमतियाँ के साथ

, तथापि, पीआईडी ​​की पहचान की है कोई सवाल कर रहा है, इसलिए ऐसा लगता है कि उन्नत अनुमतियों की आवश्यकता नहीं है। इसके अलावा, क्वेरी करने का कार्य अनुमतियों को बढ़ाने में सक्षम नहीं होना चाहिए था, इसलिए मैंने एक और जवाब देखा।

इससे मुझे ओपी की समस्या के समाधान के रूप में netstat -tulpen का प्रस्ताव देने के लिए @ whoplisp का उत्तर दिया गया। हालांकि यह ओपी के लिए प्रभावी हो सकता है, कमांड लाइन सामान्य प्रयोजन कमांड के रूप में सेवा करने के लिए बहुत ही सीमित है और इस मामले में पूरी तरह से अप्रभावी थी (यहां तक ​​कि ऊंची अनुमतियों के साथ)।

$ sudo netstat -tulpen | grep -E -- '(agent.21283|ssh-agent)' 
$ 

netstat, हालांकि, करीब आ सकता है अगर एक अलग कमांड लाइन प्रयोग किया जाता है: दुर्भाग्य से भी

$ netstat -ap | grep -E -- '(agent.21283)' 
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) 
unix 2  [ ACC ]  STREAM  LISTENING  1785049 -     /tmp/ssh-W1Tl4i8HiftZ/agent.21283 

, यहाँ, पीआईडी ​​ऊंचा अनुमतियों के बिना मायावी है:

$ sudo netstat -ap | grep -E -- '(agent.21283|ssh-agent)' 
unix 2  [ ACC ]  STREAM  LISTENING  1765316 10967/ssh-agent  /tmp/ssh-w4fyViMab8wr/agent.10966 
unix 2  [ ACC ]  STREAM  LISTENING  1777450 14406/ssh-agent  /tmp/ssh-0XemJ4YlRtVI/agent.14405 
unix 2  [ ACC ]  STREAM  LISTENING  1785049 21284/ssh-agent  /tmp/ssh-W1Tl4i8HiftZ/agent.21283 

दो समाधानों में से, lsof स्पष्ट रूप से दौड़ में जीतता है:

$ time sudo netstat -ap | grep -E -- '(agent.21283|ssh-agent)' >/dev/null 

real 0m5.159s 
user 0m0.010s 
sys  0m0.019s 
$ time sudo lsof /tmp/ssh-W1Tl4i8HiftZ/agent.21283 >/dev/null 

real 0m0.120s 
user 0m0.038s 
sys  0m0.066s 

फिर भी एक और उपकरण netstat आदमी पृष्ठ के अनुसार मौजूद है:

$ man netstat | grep -iC1 replace 
NOTES 
     This program is mostly obsolete. Replacement for netstat is ss. Replacement for netstat -r is ip route. Replacement for netstat -i 
     is ip -s link. Replacement for netstat -g is ip maddr. 

दुःख की बात है ss भी ऊंचा अनुमति की आवश्यकता नहीं पीआईडी ​​पहचान करने के लिए, लेकिन, यह दोनों netstat और lsof निष्पादन बार धड़कता है:

$ time sudo ss -ap | grep -E "(agent.21283|ssh-agent)" 
u_str LISTEN  0  128 /tmp/ssh-w4fyViMab8wr/agent.10966 1765316    * 0      users:(("ssh-agent",pid=10967,fd=3)) 
u_str LISTEN  0  128 /tmp/ssh-0XemJ4YlRtVI/agent.14405 1777450    * 0      users:(("ssh-agent",pid=14406,fd=3)) 
u_str LISTEN  0  128 /tmp/ssh-W1Tl4i8HiftZ/agent.21283 1785049    * 0      users:(("ssh-agent",pid=21284,fd=3)) 

real 0m0.043s 
user 0m0.018s 
sys  0m0.021s 

निष्कर्ष में, ऐसा लगता है कि कुछ पीआईडी ​​पहचान के लिए, ऐसा प्रतीत होता है कि उन्नत अनुमतियां आवश्यक हैं।

नोट: सभी ऑपरेटिंग सिस्टम को उन्नत अनुमतियों की आवश्यकता नहीं है। उदाहरण के लिए, एससीओ ओपनसेवर 5.0.7 के lsof अनुमतियों को उठाए बिना ठीक काम करना प्रतीत होता था।

चेतावनी: यह उत्तर सॉकेट के "मूल निर्माता" को खोजने के लिए ओपी की योग्यता के संबंध में विफल हो सकता है।उदाहरण के लिए, इसमें कोई संदेह नहीं है कि पीआईडी ​​21283 सॉकेट के निर्माण का उत्प्रेरक था क्योंकि इस पीआईडी ​​को सॉकेट नाम में पहचाना जाता है। न तो lsof और न ही netstat मूल निर्माता के रूप में पीआईडी ​​21283 की पहचान की, हालांकि स्पष्ट रूप से पीआईडी ​​21284 वर्तमान रखरखाव है।

संबंधित मुद्दे