কে আমার অযৌক্তিক সংস্থান ব্যবহার করছে?


49

ফেডোরা 15-এ সাম্প্রতিক আপগ্রেড করার পরে, আমি দেখতে পাচ্ছি যে বেশ কয়েকটি সরঞ্জাম ত্রুটির সাথে ব্যর্থ হচ্ছে:

tail: inotify resources exhausted
tail: inotify cannot be used, reverting to polling

এটি কেবল tailঅযৌক্তিক সমস্যা নিয়ে রিপোর্ট করা নয়। কোন প্রক্রিয়া বা প্রক্রিয়াগুলি ইনোটিফাই সংস্থানগুলি গ্রাস করছে তা অনুসন্ধান করার জন্য কার্নেলকে জিজ্ঞাসাবাদ করার কোনও উপায় আছে কি? বর্তমান ইনোটিফাই-সম্পর্কিত sysctlসেটিংস এর মতো দেখাচ্ছে:

fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 8192
fs.inotify.max_queued_events = 16384

উত্তর:


39

মনে হয় প্রক্রিয়াটি ইনোটাইফাইনিট () এর মাধ্যমে ইনোটাইফাই উদাহরণ তৈরি করে, ফলস্বরূপ ফাইল যা / প্রো ফাইল সিস্টেমটিতে ফাইলডস্ক্রিপ্টর উপস্থাপন করে (অ-বিদ্যমান) 'আনন_ইনোড: ইনোটাইফাই' ফাইলের একটি সিমিলিংক।

$ cd /proc/5317/fd
$ ls -l
total 0
lrwx------ 1 puzel users 64 Jun 24 10:36 0 -> /dev/pts/25
lrwx------ 1 puzel users 64 Jun 24 10:36 1 -> /dev/pts/25
lrwx------ 1 puzel users 64 Jun 24 10:36 2 -> /dev/pts/25
lr-x------ 1 puzel users 64 Jun 24 10:36 3 -> anon_inode:inotify
lr-x------ 1 puzel users 64 Jun 24 10:36 4 -> anon_inode:inotify

আমি ধারণাটি ভুল বুঝে না নিলে নীচের কমান্ডটি আপনাকে প্রক্রিয়াগুলির তালিকা প্রদর্শন করবে (তাদের / প্রোপাক্টের মধ্যে উপস্থাপনা), তারা ব্যবহার করবে এমন বিভিন্ন সংখ্যার অনুসারে বাছাই করা।

for foo in /proc/*/fd/*; do readlink -f $foo; done | grep inotify | sort | uniq -c | sort -nr

8
চমৎকার আপনাকে ধন্যবাদ! ইনোটিফায়ার ইনডগুলি / প্রোকে দেখানো সম্পর্কে আমি জানতাম না। আমার উদ্দেশ্যগুলির জন্য, কমান্ডটি এটিকে সহজ করা যেতে পারে:find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print
লারস্ক করে

আমি আনন্দিত এটি সাহায্য করেছে। এবং অনুসন্ধান-নামটির সাথে আপনার সমাধানটি লুপ এবং রিডলিংকের জন্য আমার চেয়ে অনেক সুন্দর।
পেটর উজেল

3
দ্রষ্টব্য যে আপনিও ঘড়ির বাইরে থাকতে পারেন (উদাহরণ নয়)। উদাহরণস্বরূপ, আমার সিস্টেমে, এটি নিম্ন-কিশোর সংখ্যার উদাহরণ দেয় তবে কে-ডি-ই এর ডেস্কটপ অনুসন্ধান থেকে হাজার হাজার ঘড়ি রয়েছে। এটি খুব খারাপ যে কত ঘড়ি / দৃষ্টান্তগুলি ব্যবহার করা হচ্ছে তা পরীক্ষা করার সহজ উপায় নেই, যেহেতু কার্নেলটি পরিষ্কারভাবে জানে ...
ডার্ববার্ট

আপত্তিজনক প্রোগ্রামগুলির কমান্ড লাইনগুলি দেখানোর জন্য:find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -exec sh -c 'cat $(dirname {})/../cmdline; echo ""' \; 2>/dev/null
কে কে কোয়ান

@ডারবার্ট আমি পর্যবেক্ষকদের গ্রাসকারী প্রক্রিয়াগুলি তালিকাভুক্ত করার জন্য একটি স্ক্রিপ্ট তৈরি করেছি, যা সাধারণত কোনও ব্যক্তিকেই যত্নশীল করে তোলে। আমার উত্তর নীচে দেখুন।
অলিগোফ্রেন

25

আপনি সম্ভবত inotify চলমান আউট হয় ঘড়ির দৃষ্টান্ত বদলে। কে প্রচুর ঘড়ি তৈরি করছে তা সন্ধান করতে:

  1. কি echo 1 >> /sys/kernel/debug/tracing/events/syscalls/sys_exit_inotify_add_watch/enableদেখার যোগ হদিশ সক্ষম করতে;
  2. কি cat /sys/kernel/debug/tracing/tracing_enabledনিশ্চিত করুন যে এটি 1 থেকে সেট এবং যদি তা না করা হয় করতে echo 1 >> /sys/kernel/debug/tracing/tracing_enabled;
  3. আপনার প্রচুর ঘড়ি তৈরির সন্দেহ আছে এমন উদ্বেগজনক উদাহরণগুলি (পেটর উজেলের উত্তরে বর্ণিত হিসাবে নির্ধারিত) দিয়ে প্রক্রিয়াগুলি পুনরায় চালু করুন; এবং
  4. /sys/kernel/debug/tracing/traceকত ঘড়ি তৈরি করা হয় এবং কোন প্রক্রিয়া দ্বারা ফাইলটি পড়ুন ।

আপনার কাজ শেষ হয়ে গেলে, ট্রেসিং বন্ধ করার জন্য সক্ষম ফাইল (এবং ট্রেসিং_নেবল ফাইলটি যদি আপনার পাশাপাশি সক্ষম করে তুলতে হয়) তে 0 প্রতিধ্বনি নিশ্চিত করুন যাতে আপনার ট্রেস চালিয়ে যাওয়ার পারফরম্যান্সের আঘাতটি ব্যয় করতে না পারে।


এটি একটি ব্যাকআপ অ্যাপ্লিকেশন যা প্রচুর পরিমাণে ইনোটিফাই ঘড়ি তৈরি করে এবং গ্রহণযোগ্য উত্তরের সমাধানটি অপরাধীকে সনাক্ত করতে সহায়তা করে। তবে, আপনি এখানে প্রদর্শিত সিস্টেম কল ট্রেসিংয়ের সাথে আগে আমার পরিচিত ছিল না। খুব ঠান্ডা. তথ্যের জন্য ধন্যবাদ!
'16

2
আপনি কি নিশ্চিত যে এটি '/ sys / কার্নেল / ডিবাগ / ট্রেসিং / ট্রেসিং_নেবল'? আমার সিস্টেমে দেখে মনে হচ্ছে সঠিক পথটি '/ sys / কার্নেল / ডিবাগ / ট্রেসিং / ট্রেসিং_' ...
কার্টোচ

জেন্টু লিনাক্সে কোনও / সিস / কার্নেল / ডিবাগ / ট্রেসিং / ইভেন্টস / সিসকল / সিস_এক্সিট_ইনোটাইফাইড / এ্যাড_ওয়াচ / সক্ষম বা / sys / কার্নেল / ডিবাগ / ট্রেসিং / ট্রেসিং_নেবল নেই , তবে / sys / কার্নেল / ডিবাগ / ট্রেসিং / ট্রেসিং_েনবল বিদ্যমান exists তা কেন?
zeekvfu

@ কার্টোকের ইঙ্গিত হিসাবে, আপনাকে echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_onআধুনিক ডিস্ট্রোস (উবুন্টু 18.04.2 এলটিএস) করতে হবে।
অলিগোফ্রেন

কমান্ডগুলি আমার পক্ষে করা যথেষ্ট ছিল না, আমাকে আরও করতে হবে: d সিডি / সিএস / কার্নেল / ডিবাগ / ট্রেসিং /; প্রতিধ্বনি ফাংশন> কারেন্ট_ট্রেসার; প্রতিধ্বনি SyS_inotify_add_watch> set_ftrace_filter`
oligofren থেকে

7

@ জোনাথন কামেনস যেমন বলেছিলেন, আপনার সম্ভবত নজর নেই। আমার একটি প্রাক তৈরি স্ক্রিপ্ট রয়েছে , inotify-consumersএটি আপনার জন্য এটি তালিকাভুক্ত করে:

$ time inotify-consumers  | head

   INOTIFY
   WATCHER
    COUNT     PID     CMD
----------------------------------------
    6688    27262  /home/dvlpr/apps/WebStorm-2018.3.4/WebStorm-183.5429.34/bin/fsnotifier64
     411    27581  node /home/dvlpr/dev/kiwi-frontend/node_modules/.bin/webpack --config config/webpack.dev.js
      79     1541  /usr/lib/gnome-settings-daemon/gsd-xsettings
      30     1664  /usr/lib/gvfs/gvfsd-trash --spawner :1.22 /org/gtk/gvfs/exec_spaw/0
      14     1630  /usr/bin/gnome-software --gapplication-service

real    0m0.099s
user    0m0.042s
sys 0m0.062s

এখানে আপনি দ্রুত দেখতে পাচ্ছেন কেন 8K প্রহরীদের ডিফল্ট সীমাটি বিকাশকারী মেশিনে খুব কম, যেমন node_modulesহাজার হাজার ফোল্ডার সহ কোনও ফোল্ডারের মুখোমুখি হওয়ার সময় কেবল ওয়েবস্টোরম উদাহরণটি এটিকে দ্রুত সরিয়ে দেয় । সমস্যার গ্যারান্টি দিতে একটি ওয়েবপ্যাক প্রদর্শক যুক্ত করুন ...

কেবল স্ক্রিপ্টের সামগ্রীগুলি (বা গিটহাবের ফাইল) অনুলিপি করুন এবং এটি আপনার $PATHপছন্দ মতো অন্য কোথাও রেখে দিন /usr/local/bin। রেফারেন্সের জন্য, স্ক্রিপ্টের মূল বিষয়বস্তু কেবল এটি

find /proc/*/fd \
    -lname anon_inode:inotify \
    -printf '%hinfo/%f\n' 2>/dev/null \
    \
    | xargs grep -c '^inotify'  \
    | sort -n -t: -k2 -r 

আপনি কীভাবে সীমাবদ্ধতা বাড়াবেন তা ভাবতে থাকলে, এটিকে কীভাবে স্থায়ী করা যায় তা এখানে:

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

1
অন্যান্য অনেক পরামর্শ আমার পক্ষে ভাল কাজ করেনি, তবে এই স্ক্রিপ্টটি ফেডোরা ২৯ এ দুর্দান্ত কাজ করেছে Thanks ধন্যবাদ!
রিচার্ড এস হল 13

6

আমি এই সমস্যায় পড়েছি, এবং এই উত্তরগুলির কোনও উত্তরই আপনাকে " প্রতিটি প্রক্রিয়া বর্তমানে কত ঘড়ি ব্যবহার করছে?" এর উত্তর দেয় না ওয়ান-লাইনারগুলি আপনাকে জানায় যে কয়টি দৃষ্টান্ত উন্মুক্ত, যা কেবল গল্পের অংশ, এবং ট্রেস স্টাফগুলি কেবল নতুন ঘড়ি খোলার জন্য দরকারী।

টিএল; ডিআর: এটি আপনাকে ওপেন inotifyদৃষ্টান্তের তালিকা এবং তারা যে পিড এবং বাইনারিগুলি তৈরি করেছিল এবং ঘড়ির গণনা অনুসারে ক্রমবর্ধমান ক্রমে সাজানো রয়েছে তার সাথে ঘড়ির সংখ্যাগুলির তালিকা সহ একটি ফাইল পাবে:

sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -nr > watches

এটি মেসের একটি বড় বল, তাই আমি এখানে কিভাবে পেলাম। শুরু করার জন্য, আমি tailএকটি পরীক্ষার ফাইলে দৌড়েছি , এবং এফডি এর এটি খোলার দিকে তাকিয়েছি:

joel@gladstone:~$ tail -f test > /dev/null &
[3] 22734
joel@opx1:~$ ls -ahltr /proc/22734/fd
total 0
dr-xr-xr-x 9 joel joel  0 Feb 22 22:34 ..
dr-x------ 2 joel joel  0 Feb 22 22:34 .
lr-x------ 1 joel joel 64 Feb 22 22:35 4 -> anon_inode:inotify
lr-x------ 1 joel joel 64 Feb 22 22:35 3 -> /home/joel/test
lrwx------ 1 joel joel 64 Feb 22 22:35 2 -> /dev/pts/2
l-wx------ 1 joel joel 64 Feb 22 22:35 1 -> /dev/null
lrwx------ 1 joel joel 64 Feb 22 22:35 0 -> /dev/pts/2

সুতরাং, 4 হ'ল fd আমরা তদন্ত করতে চাই। আসুন দেখুন এর জন্য কী রয়েছে fdinfo:

joel@opx1:~$ cat /proc/22734/fdinfo/4
pos:    0
flags:  00
mnt_id: 11
inotify wd:1 ino:15f51d sdev:ca00003 mask:c06 ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:1df51500a75e538c

নীচের দিকে ঘড়ির জন্য এন্ট্রি লাগছে!

আসুন আরও ঘড়ির সাহায্যে কিছু চেষ্টা করুন, এবার inotifywaitইউটিলিটি সহ, যা আছে তা কেবল দেখছি /tmp:

joel@gladstone:~$ inotifywait /tmp/* &
[4] 27862
joel@gladstone:~$ Setting up watches.
Watches established.
joel@gladstone:~$ ls -ahtlr /proc/27862/fd | grep inotify
lr-x------ 1 joel joel 64 Feb 22 22:41 3 -> anon_inode:inotify
joel@gladstone:~$ cat /proc/27862/fdinfo/3
pos:    0
flags:  00
mnt_id: 11
inotify wd:6 ino:7fdc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:dc7f0000551e9d88
inotify wd:5 ino:7fcb sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cb7f00005b1f9d88
inotify wd:4 ino:7fcc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cc7f00006a1d9d88
inotify wd:3 ino:7fc6 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c67f00005d1d9d88
inotify wd:2 ino:7fc7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c77f0000461d9d88
inotify wd:1 ino:7fd7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:d77f00000053c98b

আহা! আরও এন্ট্রি! সুতরাং আমাদের /tmpতখন ছয়টি জিনিস থাকা উচিত :

joel@opx1:~$ ls /tmp/ | wc -l
6

চমৎকার। আমার নতুন inotifywaitহয়েছে এক তার মধ্যে এন্ট্রি fdতালিকা (যা অন্য এক liners, এখানে বেড়ে চলেছে করা হয়), কিন্তু তার ছয় এন্ট্রি fdinfoফাইল। সুতরাং আমরা নির্ধারণ করতে পারি যে প্রদত্ত প্রসেসের জন্য প্রদত্ত এফডি এর fdinfoফাইলের সাথে পরামর্শ করে কতটা ঘড়ি ব্যবহার করছে । এখন এটিকে উপরের কিছুগুলির সাথে একত্রে প্রসেসের একটি তালিকা দখল করার জন্য রয়েছে যা ঘড়িগুলি খোলা রয়েছে এবং প্রতিটিটিতে প্রবেশের সংখ্যা গণনা করার জন্য এটি ব্যবহার করে fdinfo। এটি উপরের মতই, সুতরাং আমি এখানে ওয়ান-লাইনারটি ফেলে দেব:

sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); echo -e $count"\t"$fdi; done

এখানে কিছু পুরু স্টাফ রয়েছে, তবে মূল কথাটি হ'ল আমি আউটপুট থেকে awkএকটি fdinfoপথ তৈরি করতে lsof, পিড এবং এফডি নম্বরটি ধরে, উত্তর / ইউ / আর / ডাব্লু পতাকাটি ছিনিয়ে নিতে ব্যবহার করি। তারপরে প্রতিটি নির্মিত fdinfoপাথের জন্য, আমি inotifyলাইন সংখ্যা এবং আউটপুট গণনা এবং পিডকে গণনা করি।

এই পিডগুলি একই জায়গায় উপস্থাপিত করার জন্য আমার কী প্রক্রিয়াগুলি থাকত তা যদি ঠিক হয় তবে ভাল লাগবে? আমিও তাই ভাবছিলাম. সুতরাং, একটি বিশেষ নোংরা কিছুক্ষনের মধ্যে আমি কলিং উপর বসতি স্থাপন dirnameদুইবার fdinfoপথে প্যাক পেতে /proc/<pid>যোগ /exeএটা, এবং তারপর চলমান readlinkউপর যে প্রক্রিয়ার EXE নাম জন্য। এটি সেখানে ফেলে দিন, এটিকে ঘড়ির সংখ্যা অনুসারে বাছাই করুন এবং এটি নিরাপদে রক্ষার জন্য একটি ফাইলে পুনর্নির্দেশ করুন এবং আমরা পেয়েছি:

sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -n > watches

উপরে চালানো আমার প্রক্রিয়াগুলি দেখানোর জন্য sudo ছাড়া এটি চালানো , আমি পেয়েছি:

joel@gladstone:~$ cat watches 
6   /proc/4906/fdinfo/3 /usr/bin/inotifywait
1   /proc/22734/fdinfo/4    /usr/bin/tail

পারফেক্ট! প্রক্রিয়াগুলির একটি তালিকা, এফডি এবং প্রতিটি কতগুলি ঘড়ি ব্যবহার করছে, যা আমার প্রয়োজন ঠিক তাই।


lsofএই উদ্দেশ্যে ব্যবহার করার সময় , আমি -nPবিপরীত ডিএনএস এবং বন্দর নামগুলির অপ্রয়োজনীয় অনুসন্ধানগুলি এড়াতে পতাকাগুলি ব্যবহার করার পরামর্শ দেব । এই বিশেষ ক্ষেত্রে, -bwসাইককলগুলি সম্ভাব্য ব্লক করা এড়াতে যুক্ত করার পরামর্শ দেওয়া হয়। এটি বলেছিল যে lsofআমার নম্র ওয়ার্কস্টেশনটিতে 3 সেকেন্ড ওয়াল ঘড়ির সময় কাটানো (যার মধ্যে 2 সেকেন্ড কার্নেলে ব্যয় করা হয়েছে), এই পদ্ধতির অনুসন্ধানের জন্য দুর্দান্ত তবে হায় আফসোস নিরীক্ষণের উদ্দেশ্যে অপ্রয়োজনীয়।
বার্টডি

আমি আপনার ওয়ান-লাইনারটিকে অত্যন্ত ধীর বলে মনে করেছি, তবে কিছুটা ক্ষতির পরিমাণে (আমরা ফাইলের বিবরণীর চেয়ে প্রসেসের প্রতি নজর রাখব) একটি দুর্দান্ত উন্নতি সম্ভব: প্রথমে একটি মধ্যবর্তী ফাইল তৈরি করুন: lsof | awk '/a_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | sed 's/fdinfo.*//' | sort | uniq > uniq-oতারপরেcat uniq-o | while read fdi; do count=$(cat ${fdi}fdinfo/* | grep -c inotify 2>/dev/null); exe=$(readlink ${fdi}exe); echo -e $count"\t"${fdi}"\t"$exe; done > watches
এলএলএএমএনওয়াইপি

5

ট্রেস যা প্রসেস inotify গ্রাস ঘড়ির (না দৃষ্টান্ত) যদি এটি আপনার কার্নেলের মধ্যে সক্রিয় করা হয় আপনি কার্নেল গতিশীল ftrace বৈশিষ্ট্য ব্যবহার করতে পারেন।

আপনার প্রয়োজনীয় কার্নেল বিকল্পটি CONFIG_DYNAMIC_FTRACE

যদি আগে থেকেই মাউন্ট না করা হয় তবে প্রথমে ডিবাগগুলি ফাইল সিস্টেমটি মাউন্ট করুন।

mount -t debugfs nodev /sys/kernel/debug

tracingএই ডিবাগ ডিরেক্টরিতে সাব-ডিরেক্টরিতে যান

cd /sys/kernel/debug/tracing

ফাংশন কলগুলির ট্রেসিং সক্ষম করুন

echo function > current_tracer

ফিল্টার করুন কেবলমাত্র SyS_inotify_add_watchসিস্টেম কল

echo SyS_inotify_add_watch > set_ftrace_filter

ট্রেস রিং বাফারটি খালি না হলে সাফ করুন

echo > trace

এটি ইতিমধ্যে সক্ষম না থাকলে ট্রেসিং সক্ষম করুন

echo 1 > tracing_on

সন্দেহজনক প্রক্রিয়াটি পুনরায় চালু করুন (আমার ক্ষেত্রে এটি ক্র্যাশপ্ল্যান, একটি ব্যাকআপ অ্যাপ্লিকেশন ছিল)

ক্লান্ত হয়ে যাওয়া inotify_watch দেখুন

wc -l trace
cat trace

সম্পন্ন


3
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' 2>/dev/null | cut -f 1-4 -d'/' |  sort | uniq -c  | sort -nr

1

যেগুলি প্রক্রিয়াজাতকরণ সম্পদ গ্রহণ করছে সেগুলির তালিকা দেখানোর জন্য আমি উপরে উপস্থিত স্ক্রিপ্টটি সংশোধন করেছি :

ps -p `find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print | sed s/'^\/proc\/'/''/ | sed s/'\/fd.*$'/''/`

আমি মনে করি আমার ডাবল শেড প্রতিস্থাপন করার একটি উপায় আছে ।


হ্যাঁ. হয় ব্যবহার করুন

cut -f 3 -d '/'   

অথবা

sed -e 's/^\/proc\/\([0-9]*\)\/.*/\1'  

এবং আপনি কেবল পিড পাবেন
এছাড়াও, আপনি যোগ করুন

2> /dev/null  

অনুসন্ধানে, আপনি সন্ধানের দ্বারা ছুঁড়ে দেওয়া কোনও সমস্যাযুক্ত ত্রুটি রেখা থেকে মুক্তি পাবেন। সুতরাং এটি কাজ করবে:

ps -p $(find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print 2> /dev/null | sed -e 's/^\/proc\/\([0-9]*\)\/.*/\1/')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.