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


15

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

संक्षेप में, समाधान लिनक्स एब्सट्रैक्ट नेमस्पेस डोमेन सॉकेट्स पर निर्भर करता है, जो फाइलों पर निर्भर रहने के बजाय आपके लिए सॉकेट्स का ट्रैक रखता है, जो डेमॉन SIGKILL'd के बाद चारों ओर चिपक सकता है। उदाहरण से पता चलता है कि प्रक्रिया के मृत हो जाने पर लिनक्स सॉकेट को मुक्त करता है।

लेकिन मैं लिनक्स में निश्चित दस्तावेज़ीकरण नहीं पा सकता हूं जो कहता है कि क्या लिनक्स अमूर्त सॉकेट के साथ करता है जब बाध्य प्रक्रिया SIGKILL'd है। क्या कोई जानता है?

दूसरा रास्ता रखो, जब सार सॉकेट को फिर से इस्तेमाल करने के लिए मुक्त किया जाता है?

जब तक यह निश्चित रूप से समस्या का हल नहीं करता मैं पीआईडी ​​फ़ाइल तंत्र को सार सॉकेट के साथ बदलना नहीं चाहता।


3
मुझे ऐसा कुछ भी नहीं मिला, जो इसका सीधा जवाब दे। लेकिन चूंकि सार सॉकेट को हटाने के लिए कोई एपीआई नहीं है, ऐसा लगता है कि उन्हें कर्नेल द्वारा स्वचालित रूप से प्रबंधित करना होगा। जब सॉकेट खोलने के साथ कोई प्रक्रिया नहीं होती है, तो इसे दूर जाना चाहिए।
बरमार

@ बरमार मेला काफी एक उत्तर के रूप में इसे जोड़ने के लिए देखभाल?
CivFan

मैं अधिक निश्चित जानकारी रखना पसंद करूंगा।
बमर

जवाबों:


5

हां, लिनक्स स्वचालित रूप से "सॉकेट्स" को इस हद तक साफ कर देता है कि सफाई भी समझ में आती है। यहां एक न्यूनतम काम करने का उदाहरण दिया गया है जिसके साथ आप इसे सत्यापित कर सकते हैं:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>

int
main(int argc, char **argv)
{
  int s;
  struct sockaddr_un sun;

  if (argc != 2 || strlen(argv[1]) + 1 > sizeof(sun.sun_path)) {
    fprintf(stderr, "usage: %s abstract-path\n", argv[0]);
    exit(1);
  }

  s = socket(AF_UNIX, SOCK_STREAM, 0);
  if (s < 0) {
    perror("socket");
    exit(1);
  }
  memset(&sun, 0, sizeof(sun));
  sun.sun_family = AF_UNIX;
  strcpy(sun.sun_path + 1, argv[1]);
  if (bind(s, (struct sockaddr *) &sun, sizeof(sun))) {
    perror("bind");
    exit(1);
  }
  pause();
}

इस प्रोग्राम को पहले चलाएं ./a.out /test-socket &, फिर चलाएं ss -ax | grep test-socket, और आपको उपयोग में सॉकेट दिखाई देगा। फिर kill %./a.out, और ss -axदिखाएगा कि सॉकेट चला गया है।

हालाँकि, आप किसी भी दस्तावेज़ में इस सफाई को नहीं पा सकते हैं, यह वास्तव में एक ही अर्थ में सफाई नहीं है कि गैर-अमूर्त यूनिक्स-डोमेन सॉकेट्स को सफाई की आवश्यकता है। एक गैर-अमूर्त सॉकेट वास्तव में एक इनकोड आवंटित करता है और एक निर्देशिका में एक प्रविष्टि बनाता है, जिसे अंतर्निहित फ़ाइल सिस्टम में साफ करने की आवश्यकता होती है। इसके विपरीत, एक टीसीपी या यूडीपी पोर्ट नंबर की तरह एक अमूर्त सॉकेट के बारे में सोचें। निश्चित रूप से, यदि आप एक टीसीपी पोर्ट को बांधते हैं और फिर बाहर निकलते हैं, तो वह टीसीपी पोर्ट फिर से मुक्त हो जाएगा। लेकिन जो भी 16-बिट नंबर आपने उपयोग किया वह अभी भी हमेशा मौजूद है और हमेशा किया है। पोर्ट संख्याओं का नाम स्थान 1-65535 है और कभी भी सफाई या परिवर्तन की आवश्यकता नहीं होती है।

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


इसने पहले ही बतख परीक्षण पास कर लिया। यह अजगर के रूप में कुछ चीजों के लिए ठीक है, लेकिन मैं लिनक्स कर्नेल सुविधाओं के लिए अधिक उम्मीद करता हूं। टीसीपी / यूडीपी पोर्ट के अपने उदाहरण लें - पोर्ट का पुन: उपयोग किए जाने पर ठीक-ठीक वर्णन करने वाले बहुत सारे दस्तावेज़ हैं।
CivFan

2
और वह दस्तावेज अमूर्त सॉकेट्स के लिए समान रूप से क्यों लागू नहीं होता है? क्या आपके पास एक संदर्भ है? एक बेहतर सवाल यह हो सकता है कि गैर-अमूर्त यूनिक्स-डोमेन सॉकेट्स के लिए अतिरिक्त क्लीन-अप जटिलता कहां दर्ज़ की गई है। मेरे सिस्टम पर, यह यूनिक्स (7) में है , जो कहता है "लिनक्स एक अमूर्त नेमस्पेस का भी समर्थन करता है जो फाइल सिस्टम से स्वतंत्र है।" तो मेरे लिए "फाइल सिस्टम से स्वतंत्र" का अर्थ है कोई फ़ाइल-सिस्टम-विशिष्ट सफाई नहीं।
user3188445

5

मैंने एक साल पहले यह सवाल पोस्ट किया था और निश्चित प्रलेखन की कमी से कभी भी संतुष्ट नहीं था। मुझे लगता है मैं किसी भी अद्यतन के लिए फिर से लिनक्स प्रलेखन जाँच था सोचा, और खुश था यह देखने के लिए :

सार सॉकेट

सॉकेट अनुमतियों का सार सॉकेट के लिए कोई अर्थ नहीं है: अमूर्त सॉकेट को बांधते समय प्रक्रिया umask (2) का कोई प्रभाव नहीं होता है, और ऑब्जेक्ट के स्वामित्व और अनुमतियों को बदलकर (fchown (2) और fchmod (2) के माध्यम से कोई प्रभाव नहीं पड़ता है सॉकेट की पहुंच।

सॉकेट सॉकेट स्वचालित रूप से गायब हो जाता है जब सॉकेट के सभी खुले संदर्भ बंद हो जाते हैं।

इसके अलावा, माइकल केरिस्क द्वारा लिनक्स प्रोग्रामिंग इंटरफेस प्रश्न (क्रॉस-पोस्ट से) को कवर करता है इस अन्य उत्तर ):

57.6 लिनक्स सार सॉकेट नाम स्थान

तथाकथित सार नाम स्थान एक लिनक्स-विशिष्ट विशेषता है जो हमें एक नाम के बिना UNIX डोमेन सॉकेट को बांधने की अनुमति देता है, उस नाम के बिना फाइल सिस्टम में बनाया जा सकता है। यह कुछ संभावित लाभ प्रदान करता है:

  • हमें फ़ाइल सिस्टम में मौजूदा नामों के साथ संभावित टकराव के बारे में चिंता करने की आवश्यकता नहीं है।
  • सॉकेट पाथनाम को अनलिंक करने के लिए आवश्यक नहीं है जब हमने सॉकेट का उपयोग किया है। सॉकेट बंद होने पर सार नाम स्वचालित रूप से हटा दिया जाता है।
  • हमें सॉकेट के लिए एक फ़ाइल-सिस्टम पथनाम बनाने की आवश्यकता नहीं है। यह चेरोट वातावरण में उपयोगी हो सकता है, या यदि हमारे पास फ़ाइल सिस्टम तक पहुंच नहीं है।

एक अमूर्त बंधन बनाने के लिए, हम sun_path फ़ील्ड के पहले बाइट को एक शून्य बाइट (\ 0) के रूप में निर्दिष्ट करते हैं । [...]

मुझे लगता है कि @ user3188445 के जवाब के साथ, यह सवाल को बहुत सटीक रूप से स्पष्ट करता है।

उस ने कहा, यहाँ अभी भी एक धारणा है, जो प्रक्रियाएँ जो SIGKILL'd हैं, वे सभी खुली हुई कुर्सियाँ बंद होंगी। यह एक उचित धारणा लगती है, लेकिन मेरे पास ऐसा दस्तावेज नहीं है जो उस व्यवहार को परिभाषित करे।


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

अनलिंक करना आवश्यक नहीं है ... - उम, चूंकि कोई पथनाम नहीं है, इसलिए अनलिंक करना संभव नहीं है, न केवल अनावश्यक।
domen
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.