Android 10 में Android का लाइव-लॉक डीमन शामिल है
(llkd
), जिसे कर्नेल डेडलॉक को पकड़ने और उन्हें कम करने के लिए डिज़ाइन किया गया है. llkd
कॉम्पोनेंट एक डिफ़ॉल्ट स्टैंडअलोन इंप्लिमेंटेशन देता है, लेकिन
इसके अलावा, llkd
कोड को किसी दूसरी सेवा में इंटिग्रेट किया जा सकता है. ऐसा या तो इसके हिस्से के तौर पर किया जा सकता है
मुख्य लूप या अलग थ्रेड के रूप में
पहचान करने की स्थितियां
llkd
में पहचान की पुष्टि की दो स्थितियां होती हैं: परसिस्टेंट D या Z स्टेट और परसिस्टेंट
स्टैक सिग्नेचर.
परसिस्टेंट D या Z स्टेट
अगर कोई थ्रेड D (बिना रुकावट स्लीप मोड) या Z (ज़ॉम्बी) स्टेटस में है, लेकिन फ़ॉरवर्ड नहीं किया जा सकता
ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms
से ज़्यादा समय तक चले,
llkd
इस प्रोसेस को बंद कर देता है या पैरंट प्रोसेस को बंद कर देता है. अगर बाद में स्कैन करने पर,
वही प्रोसेस जारी है. llkd
, लाइव लॉक की स्थिति की पुष्टि करता है और
कर्नेल को इस तरह पैन करता है कि
स्थिति.
llkd
में एक सेल्फ़ वॉच डॉग है, जो llkd
के लॉक होने पर अलार्म बजाता है; वॉचडॉग है
मेनलूप से होकर गुज़रने के लिए अनुमानित समय दोगुना होता है और सैंपलिंग हर
ro.llk_sample_ms
.
स्थायी स्टैक सिग्नेचर
उपयोगकर्ता डीबग रिलीज़ के लिए, llkd
स्थायी यूआरएल का इस्तेमाल करके कर्नेल लाइव-लॉक का पता लगा सकता है
हस्ताक्षर की जांच करने के लिए. अगर Z को छोड़कर किसी भी राज्य में थ्रेड स्थायी है
सूचीबद्ध ro.llk.stack
कर्नेल प्रतीक जो से ज़्यादा समय के लिए रिपोर्ट किया जाता है
ro.llk.timeout_ms
या ro.llk.stack.timeout_ms
, llkd
इस प्रोसेस को खत्म कर देता है
(भले ही, फ़ॉरवर्ड को शेड्यूल किया जा रहा हो). अगर बाद में स्कैन करने पर,
वही प्रोसेस जारी है. llkd
, लाइव लॉक की स्थिति की पुष्टि करता है और
कर्नेल को इस तरह पैन करता है कि
स्थिति.
लाइव लॉक की स्थिति में बदलाव होने पर और lldk
की जांच लगातार जारी रहती है
यह बनाई गई स्ट्रिंग symbol+0x
या symbol.cfi+0x
Linux पर /proc/pid/stack
फ़ाइल है. प्रतीकों की सूची ro.llk.stack
और
यह डिफ़ॉल्ट रूप से कॉमा लगाकर अलग की गई सूची पर सेट होती है
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
.
प्रतीक इतने कम और अल्पकालिक होने चाहिए कि किसी सामान्य प्रणाली में
फ़ंक्शन को टाइम आउट की अवधि में, सैंपल में सिर्फ़ एक बार देखा जाता है
ro.llk.stack.timeout_ms
(नमूने हर ro.llk.check_ms
में दिखते हैं). कमी की वजह से
अगर है, तो गलत ट्रिगर को रोकने का सिर्फ़ यही एक तरीका है. प्रतीक
फ़ंक्शन को लॉक करने वाले फ़ंक्शन के नीचे दिखना चाहिए. अगर आपने
लॉक नीचे या सिम्बॉल फ़ंक्शन में होता है, जो कि पूरी तरह से प्रभावित जगहों पर दिखता है
प्रोसेस नहीं करेगा, न कि सिर्फ़ वह जिसकी वजह से लॉकअप हुआ है.
कवरेज
llkd
को डिफ़ॉल्ट रूप से लागू करने की प्रोसेस, init
, [kthreadd]
या
[kthreadd]
स्पॉन्स. [kthreadd]
-स्पॉन्ड धागे को कवर करने के लिए, llkd
के लिए:
- ड्राइवर को लगातार D स्थिति में नहीं रहना चाहिए,
या
- अगर थ्रेड खत्म हो जाए, तो ड्राइवर के पास उसे रिकवर करने का तरीका होना चाहिए
बाहर से ऐसा कर सकें. उदाहरण के लिए, इसके बजाय
wait_event_interruptible()
का इस्तेमाल करेंwait_event()
.
अगर ऊपर दी गई शर्तों में से कोई एक पूरी होती है, तो llkd
ब्लॉकलिस्ट में बदलाव किया जा सकता है
कर्नेल कॉम्पोनेंट को कवर करता है. स्टैक सिंबल की जांच करने के लिए एक अन्य प्रोसेस को पूरा करना पड़ता है
ptrace
को ब्लॉक करने वाली सेवाओं पर, नीति के उल्लंघन को रोकने के लिए ब्लॉकलिस्ट
कार्रवाइयां.
Android प्रॉपर्टी
llkd
, कई Android प्रॉपर्टी (नीचे दी गई सूची) के बारे में बताता है.
prop_ms
नाम की प्रॉपर्टी मिलीसेकंड में होती हैं.- जिन प्रॉपर्टी में सूचियों के लिए कॉमा (,) सेपरेटर का इस्तेमाल किया जाता है वे सेपरेटर का इस्तेमाल किया जाता है
डिफ़ॉल्ट एंट्री को सुरक्षित रखें, फिर वैकल्पिक प्लस वाली एंट्री को जोड़ें या घटाएं
प्रीफ़िक्स (+) और माइनस (-) के चिह्न होते हैं. इन सूचियों के लिए, स्ट्रिंग
false
खाली सूची का समानार्थी है, और खाली या छूटी हुई एंट्री का रिज़ॉर्ट डिफ़ॉल्ट मान सेट किया गया हो.
ro.config.low_ram
डिवाइस को सीमित मेमोरी के साथ कॉन्फ़िगर किया गया है.
ro.debuggable
डिवाइस को userdebug या eng बिल्ड के लिए कॉन्फ़िगर किया गया है.
Ro.llk.sysrq_t
अगर प्रॉपर्टी eng
है, तो ro.config.low_ram
या ro.debuggable
डिफ़ॉल्ट नहीं है.
अगर true
है, तो सभी थ्रेड (sysrq t
) डंप करें.
ro.llk.enable
लाइव-लॉक डीमन को चालू करने की अनुमति दें. डिफ़ॉल्ट वैल्यू false
है.
llk.enable
इंजीनियरिंग बिल्ड के लिए आकलन किया गया. डिफ़ॉल्ट वैल्यू ro.llk.enable
है.
ro.kungtask.enable
[khungtask]
डीमन को चालू करने की अनुमति दें. डिफ़ॉल्ट वैल्यू false
है.
kungtask.enable
इंजीनियरिंग बिल्ड के लिए आकलन किया गया. डिफ़ॉल्ट वैल्यू ro.khungtask.enable
है.
ro.llk.mlockall
mlockall()
पर कॉल करने की सुविधा चालू करें. डिफ़ॉल्ट वैल्यू false
है.
CANNOT TRANSLATE
ज़्यादा से ज़्यादा [khungtask]
समय सीमा. डिफ़ॉल्ट अवधि 12 मिनट है.
ro.llk.timeout_ms
D या Z की ज़्यादा से ज़्यादा समयसीमा. डिफ़ॉल्ट अवधि 10 मिनट है. वैल्यू को सेट करने के लिए, इस वैल्यू को दोगुना करें
llkd
के लिए अलार्म वॉचडॉग.
ro.llk.D.timeout_ms
D ज़्यादा से ज़्यादा समयसीमा. डिफ़ॉल्ट वैल्यू ro.llk.timeout_ms
है.
ro.llk.Z.timeout_ms
Z की ज़्यादा से ज़्यादा समयसीमा. डिफ़ॉल्ट वैल्यू ro.llk.timeout_ms
है.
ro.llk.stack.timeout_ms
यह जांच करके स्थायी स्टैक सिंबल की ज़्यादा से ज़्यादा समयसीमा की जांच की जाती है. डिफ़ॉल्ट है
ro.llk.timeout_ms
. यह सुविधा सिर्फ़ userdebug या eng बिल्ड पर ऐक्टिव है.
ro.llk.check_ms
D या Z के लिए थ्रेड के सैंपल. डिफ़ॉल्ट सेटिंग दो मिनट है.
ro.llk.stack
कर्नेल स्टैक सिंबल की जांच करता है, जो लगातार मौजूद होने पर यह दिखाता है कि
सबसिस्टम लॉक है. डिफ़ॉल्ट है
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
कर्नेल सिंबल की कॉमा-सेपरेटेड लिस्ट. इस जांच से, शेड्यूल किए गए अपॉइंटमेंट को शेड्यूल नहीं किया जा सकता
इस अवधि के दौरान हर ro.llk_check_ms
में होने वाले पोल को छोड़कर, एबीए
ro.llk.stack.timeout_ms
है, इसलिए स्टैक सिंबल बहुत कम होने चाहिए और
यह थोड़े समय के लिए ही दिखता है (किसी सिंबल के दिखने की संभावना बेहद कम है)
सैंपल). symbol+0x
के लिए मैच की जांच करता है या
स्टैक एक्सपैंशन में symbol.cfi+0x
. यह सुविधा सिर्फ़ userdebug या eng पर उपलब्ध है
बिल्ड; उपयोगकर्ताओं के सभी बिल्ड पर सुरक्षा से जुड़ी चिंताओं का असर
इस जाँच को रोकें.
ro.llk.black.process
llkd
तय प्रोसेस को नहीं देखता है. डिफ़ॉल्ट सेटिंग 0,1,2
(kernel
,
init
और [kthreadd]
) और प्रोसेस के नाम
init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1]
.
प्रोसेस, comm
, cmdline
या pid
पहचान फ़ाइल हो सकती है. अपने-आप काम करने वाली डिफ़ॉल्ट सेटिंग
यह संख्या, प्रॉपर्टी के मौजूदा साइज़ 92 से ज़्यादा हो सकती है.
ro.llk.black.पैरंट
llkd
उन प्रक्रियाओं को नहीं देखता है जिनमें बताए गए अभिभावक होते हैं. डिफ़ॉल्ट
0,2,adbd&[setsid]
है (kernel
, [kthreadd]
, और ज़ॉम्बी के लिए सिर्फ़ adbd
)
setsid
) के साथ काम करता है. एंपरसैंड (&) सेपरेटर से पता चलता है कि पैरंट को सिर्फ़ अनदेखा किया गया है
टारगेट चाइल्ड प्रोसेस के साथ हो सकता है. ऐंपरसेंड को चुना गया, क्योंकि यह
किसी प्रोसेस के नाम का कभी हिस्सा न हो; हालांकि, शेल में setprop
की ज़रूरत होती है
ऐंपरसेंड को एस्केप या कोट किया जाना चाहिए, हालांकि init rc
फ़ाइल जहां यह है
सामान्य रूप से बताया गया है तो में यह समस्या नहीं है. पैरंट या टारगेट प्रोसेस के तहत,
comm
, cmdline
या pid
रेफ़रंस.
Ro.llk.black.uid
llkd
, बताए गए यूआईडी से मेल खाने वाली प्रोसेस नहीं देखता.
यूआईएस नंबर या नामों की कॉमा-सेपरेटेड लिस्ट. डिफ़ॉल्ट वैल्यू, false
या खाली है.
ro.llk.black.process.stack
llkd
, लाइव लॉक स्टैक के लिए तय की गई प्रोसेस के सबसेट को मॉनिटर नहीं करता
हस्ताक्षर. प्रोसेस के नाम डिफ़ॉल्ट तौर पर सेट होते हैं
init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd
. से-नीति को रोकता है
ptrace
को ब्लॉक करने वाली प्रोसेस से जुड़ा उल्लंघन. इसकी वजह यह है कि
चुना गया है). यह सुविधा सिर्फ़ userdebug और eng बिल्ड पर ऐक्टिव है. बिल्ड के बारे में जानकारी के लिए
टाइप के लिए, बिल्डिंग Android देखें.
वास्तुकला से जुड़ी समस्याएं
- प्रॉपर्टी में ज़्यादा से ज़्यादा 92 वर्ण हो सकते हैं. हालांकि, डिफ़ॉल्ट रूप से इसे अनदेखा किया जाता है
(सोर्स में)
include/llkd.h
फ़ाइल में बताई गई है). - पहले से मौजूद
[khungtask]
डीमन बहुत जेनरिक है. यह ड्राइवर कोड का इस्तेमाल करके बनाया गया है D स्थिति में बहुत ज़्यादा मौजूद है. S का इस्तेमाल करने पर, टास्क के खत्म होने की संभावना बढ़ जाती है (और ज़रूरत पड़ने पर ड्राइवर फिर से इस्तेमाल कर सकते हैं).
लाइब्रेरी इंटरफ़ेस (ज़रूरी नहीं)
आपके पास विकल्प के तौर पर, llkd
को किसी अन्य खास अधिकार वाले डीमन के तौर पर शामिल करने का विकल्प होता है. इसके लिए,
libllkd
कॉम्पोनेंट से नीचे दिया गया सी इंटरफ़ेस:
#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void) /* ms to sleep for next check */
अगर थ्रेड का नाम दिया जाता है, तो एक थ्रेड अपने-आप जनरेट होता है. अगर ऐसा नहीं होता है, तो कॉलर
llkCheckMilliseconds
को उसके मुख्य लूप में कॉल करना चाहिए. फ़ंक्शन,
इस हैंडलर को अगली अनुमानित कॉल मिलने से पहले की समयावधि.