क्रैश के बिना साझा लाइब्रेरी को अपग्रेड कैसे करें?


18

यहाँ यह कहता है कि आप एक निष्पादन योग्य फ़ाइल को फिर से लिख सकते हैं और यह प्रक्रिया ठीक-ठीक चलेगी - प्रक्रिया के फिर से शुरू होने पर इसे फिर से पढ़ा जाएगा।

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

ऐसा क्यों? क्या मैं कुछ भूल रहा हूँ? मैं किसी प्रक्रिया को रोक / क्रैश किए बिना बाइनरी फ़ाइलों को कैसे बदल सकता हूं?


आप निर्भरता की जांच करने के लिए .soफ़ाइल का उपयोग ldd filename.soकर सकते हैं
राहुल पाटिल

मैं निर्भरता जानता हूं। मैं चल रही प्रक्रियाओं को प्रभावित किए बिना उन फ़ाइलों को बदलने का एक तरीका चाहता हूं। जैसा कि जुड़ा हुआ प्रश्न है
सैम

डाउनटाइम की आवश्यकता है .. या आप ऐसा कर सकते हैं stop app && create symlink of .so && start app
राहुल पाटिल

जवाबों:


21

जैसा कि क्यों कहा जाता है कि एक सॉफ्टवेयर पैकेज उन्नत होने के बावजूद भी ठीक चलता है? , लॉक फाइल नाम पर नहीं इनोड पर रखा गया है। जब आप किसी बाइनरी को लोड और निष्पादित करते हैं, तो फ़ाइल को व्यस्त के रूप में चिह्नित किया जाता है - यही कारण है कि जब आप इसे लिखने का प्रयास करते हैं तो आपको ETXTBSY (फ़ाइल व्यस्त) त्रुटि मिलती है।

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

इसलिए अद्यतन करने का सही तरीका है:

  1. फ़ाइल को निकालना, जो फ़ाइल सिस्टम से डेटा के संदर्भ को हटा देता है, ताकि यह किसी भी नव-निर्मित अनुप्रयोगों के लिए सुलभ न हो, जो इसका उपयोग करना चाहते हैं, जबकि किसी के लिए डेटा को सुलभ रखना जो पहले से ही खुला है (या मैप किया गया है) ;

  2. अद्यतन सामग्री के साथ एक नई फ़ाइल बनाना।

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

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


6

एक आरपीएम अपग्रेड एक ही करता है - रनिंग बायनेरीज़ और लाइब्रेरीज़ के साथ जबकि कुछ भी क्रैश नहीं होता है।

तो अंतर क्या है:

  1. फ़ाइल को अनलिंक करें
  2. उसी नाम से नई फ़ाइल लिखें

यह फ़ाइल इनप्ले को प्रतिस्थापित नहीं करेगा: इन-बाइनरी के संदर्भ में इनोड अभी भी "व्यस्त" है, जब तक कि अंतिम ऑब्जेक्ट इसे खुले फिनिशिंग में नहीं रखता। नई फ़ाइल एक नए इन-नंबर के साथ बनाई जाएगी।

अब scpया cpफ़ाइल को inplace को बदलने की कोशिश करेंगे - जो सामग्री को इनोड में बदल रहा है। यह काम नहीं करता है - जैसा कि आपने वर्णित किया है।

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