স্ট্যাক ওভারফ্লো প্রশ্নটি প্রথমে যথেষ্ট বলে মনে হলেও, আমি আপনার মন্তব্যগুলি থেকে বুঝতে পেরেছি কেন আপনার এখনও এই বিষয়ে সন্দেহ থাকতে পারে। আমার কাছে, দুটি UNIX সাবসিস্টেমগুলি (প্রক্রিয়া এবং ফাইল) যোগাযোগ করার সময় ঠিক এই ধরনের জটিল পরিস্থিতি জড়িত।
আপনি যেমন জানেন যে ইউনিক্স সিস্টেমগুলি সাধারণত দুটি উপ-সিস্টেমে বিভক্ত থাকে: ফাইল সাবসিস্টেম এবং প্রক্রিয়া সাবসিস্টেম। এখন, যদি না এটি সিস্টেম কলের মাধ্যমে অন্যথায় নির্দেশ দেওয়া হয়, কার্নেলের এই দুটি সাবসিস্টেমগুলি একে অপরের সাথে ইন্টারঅ্যাক্ট করা উচিত নয়। তবে একটি ব্যতিক্রম আছে: প্রক্রিয়াটির পাঠ্য অঞ্চলগুলিতে এক্সিকিউটেবল ফাইলের লোড । অবশ্যই, কেউ তর্ক করতে পারে যে এই অপারেশনটি একটি সিস্টেম কল ( execve
) দ্বারা ট্রিগারও করা হয়েছিল , তবে এটি সাধারণত এমন এক ক্ষেত্রে পরিচিত যা প্রক্রিয়া সাবসিস্টেমটি ফাইল সাবসিস্টেমটিতে একটি অন্তর্নিহিত অনুরোধ করে।
যেহেতু প্রক্রিয়া সাবসিস্টেমের স্বাভাবিকভাবেই ফাইলগুলি পরিচালনা করার কোনও উপায় নেই (অন্যথায় পুরো জিনিসটিকে দুটি ভাগে ভাগ করার কোনও মানে হবে না), ফাইল অ্যাক্সেসের জন্য ফাইল সাবসিস্টেম যা কিছু সরবরাহ করে তা ব্যবহার করতে হবে। এর অর্থ হ'ল ফাইল সংস্করণ / মোছার বিষয়ে ফাইল সাবসিস্টেমটি যা পরিমাপ করে তা প্রক্রিয়া সাবসিস্টেমটি জমা দেওয়া হয়। এই বিন্দু, আমি পড়া সুপারিশ করবে গিলেজ 'উত্তর করার জন্য এই ইউ & এল প্রশ্ন । আমার বাকী উত্তরটি গিলসের আরও সাধারণের উপর ভিত্তি করে।
প্রথম যে কাজটা উল্লেখ করা উচিত যে অভ্যন্তরীণভাবে, ফাইল মাধ্যমে শুধুমাত্র প্রবেশযোগ্য হয় inodes । যদি কার্নেলটিকে কোনও পথ দেওয়া হয়, তবে এর প্রথম পদক্ষেপটি অন্য সমস্ত ক্রিয়াকলাপের জন্য ব্যবহৃত হওয়ার জন্য এটি একটি ইনোডে অনুবাদ করা হবে। যখন কোনও প্রক্রিয়া একটি এক্সিকিউটেবলকে মেমরিতে লোড করে, এটি এটি তার ইনোডের মাধ্যমে করে, যা কোনও পাথ অনুবাদ করার পরে ফাইল সাবসিস্টেম দ্বারা সরবরাহ করা হয়েছিল। আইওনডগুলি বেশ কয়েকটি পাথ (লিঙ্ক) এর সাথে সম্পর্কিত হতে পারে এবং প্রোগ্রামগুলি কেবল লিঙ্কগুলি মুছতে পারে। কোনও ফাইল এবং এর ইনোড মোছার জন্য, ব্যবহারকারীল্যান্ডকে অবশ্যই সেই ইনোডের সমস্ত বিদ্যমান লিঙ্কগুলি সরিয়ে ফেলতে হবে এবং নিশ্চিত করতে হবে যে এটি সম্পূর্ণরূপে অব্যবহৃত। এই শর্তগুলি পূরণ করা হলে, কার্নেলটি স্বয়ংক্রিয়ভাবে ডিস্ক থেকে ফাইলটি মুছবে।
গিলসের উত্তরের এক্সিকিউটেবল অংশের প্রতিস্থাপনের দিকে যদি আপনার নজর থাকে তবে আপনি দেখতে পাবেন যে আপনি ফাইলটি কীভাবে সম্পাদনা / মুছবেন তার উপর নির্ভর করে কার্নেল সর্বদা ফাইল সাবসিস্টেমের মধ্যে প্রয়োগকৃত একটি ব্যবস্থার মাধ্যমে আলাদাভাবে প্রতিক্রিয়া / মানিয়ে নেবে।
- আপনি যদি কৌশলটির একটিকে চেষ্টা করেন ( শূন্য / লেখার জন্য মুক্ত / কাটা বা নতুন আকারে ওপেন / রাইটিং / ট্রুনসেট ), আপনি দেখতে পাবেন যে কার্নেল আপনার অনুরোধটি পরিচালনা করতে বিরক্ত করবে না। আপনি একটি ত্রুটি পাবেন 26: পাঠ্য ফাইল ব্যস্ত (
ETXTBSY
)। যাই হোক না কেন কোনও ফল।
- আপনি যদি কৌশল দুটি চেষ্টা করে থাকেন তবে প্রথম পদক্ষেপটি হ'ল আপনার এক্সিকিউটেবলকে মোছা। তবে, যেহেতু এটি কোনও প্রক্রিয়া দ্বারা ব্যবহৃত হচ্ছে, তাই ফাইল সাবসিস্টেমটি ফাইলটিকে (এবং এর ইনোড) ডিস্ক থেকে সত্যই মুছে ফেলা থেকে বিরত রাখবে । এই জায়গা থেকে, পুরানো ফাইলের সামগ্রীতে অ্যাক্সেসের একমাত্র উপায় হ'ল এটির ইনোডের মাধ্যমে এটি করা, যা প্রক্রিয়া সাবসিস্টেমটি যখনই পাঠ্য বিভাগে নতুন ডেটা লোড করার প্রয়োজন হয় (অভ্যন্তরীণভাবে, পথগুলি ব্যবহার করার কোনও মানে হয় না) এগুলি ইনোডে অনুবাদ করার সময়)। আপনি লিঙ্কযুক্ত থাকলেওফাইলটি (এর সমস্ত পথ সরিয়ে দেওয়া হয়েছে), প্রক্রিয়াটি এখনও এটিকে এমনভাবে ব্যবহার করতে পারে যেন আপনি কিছুই করেন নি। পুরানো পথ দিয়ে একটি নতুন ফাইল তৈরি করা কোনও পরিবর্তন করে না: নতুন ফাইলটিকে সম্পূর্ণ নতুন ইনোড দেওয়া হবে, যার চলমান প্রক্রিয়াটির কোনও জ্ঞান নেই।
2 এবং 3 কৌশলগুলি এক্সিকিউটেবলের জন্যও নিরাপদ: চালানো এক্সিকিউটেবল (এবং ডায়নামিকভাবে লোড করা লাইব্রেরিগুলি) ফাইল বর্ণনাকারী অর্থে খোলার ফাইল না হলেও তারা খুব অনুরূপ আচরণ করে। যতক্ষণ না কিছু প্রোগ্রাম কোড চালাচ্ছে ততক্ষণ ডিরেক্টরি এন্ট্রি ছাড়াই ফাইলটি ডিস্কে থেকে যায়।
- কৌশল তিনটি বেশ সমান কারণ
mv
অপারেশনটি একটি পারমাণবিক। এটির জন্য সম্ভবত rename
সিস্টেম কল ব্যবহারের প্রয়োজন হবে এবং কার্নেল মোডে থাকাকালীন প্রক্রিয়াগুলিতে বাধা দেওয়া যাবে না, যতক্ষণ না এটি সম্পন্ন হয় (সফলভাবে না হয়) যতক্ষণ না এই অপারেশনটিতে কিছুই হস্তক্ষেপ করতে পারে না। আবার, পুরানো ফাইলের ইনোডের কোনও পরিবর্তন নেই: একটি নতুন তৈরি করা হয়েছে, এবং ইতিমধ্যে চলমান প্রক্রিয়াগুলির কোনও জ্ঞান থাকবে না, এমনকি এটি পুরানো ইনোডের লিঙ্কগুলির মধ্যে একটির সাথে যুক্ত থাকলেও।
কৌশল 3 এর সাথে নতুন ফাইলটিকে বিদ্যমান নামে স্থানান্তরিত করার পদক্ষেপটি পুরাতন সামগ্রীর দিকে পরিচালিত ডিরেক্টরি এন্ট্রি সরিয়ে দেয় এবং নতুন সামগ্রীর দিকে পরিচালিত ডিরেক্টরি এন্ট্রি তৈরি করে। এটি একটি পারমাণবিক অপারেশনে করা হয়, সুতরাং এই কৌশলটির একটি বড় সুবিধা রয়েছে: কোনও প্রক্রিয়া যে কোনও সময় ফাইলটি খুললে এটি পুরানো সামগ্রী বা নতুন সামগ্রী দেখতে পাবে - মিশ্র সামগ্রী বা ফাইলটি না পাওয়ার কোনও ঝুঁকি নেই বিদ্যমান।
একটি ফাইল পুনরায় সংকলন : ব্যবহার করার সময় gcc
(এবং আচরণটি সম্ভবত অন্যান্য অনেক সংকলকগুলির জন্য একই রকম), আপনি কৌশল 2 ব্যবহার করছেন You আপনি দেখতে পাচ্ছেন যে strace
আপনার সংকলকটির একটি প্রক্রিয়া চালিয়ে :
stat("a.out", {st_mode=S_IFREG|0750, st_size=8511, ...}) = 0
unlink("a.out") = 0
open("a.out", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
chmod("a.out", 0750) = 0
- কম্পাইলার সনাক্ত করে যে ফাইল আগে থেকেই মাধ্যমে বিদ্যমান
stat
এবং lstat
সিস্টেম কল।
- ফাইলটি লিঙ্কযুক্ত । এখানে, যদিও এটি নামের মাধ্যমে আর অ্যাক্সেসযোগ্য নয়
a.out
, এর ইনোড এবং বিষয়বস্তু ডিস্কে থেকে যায়, যতক্ষণ না তারা ইতিমধ্যে চলমান প্রক্রিয়াগুলি দ্বারা ব্যবহৃত হয়।
- একটি নতুন ফাইল তৈরি করা হয় এবং নামের অধীনে কার্যকর করা যায়
a.out
। এটি একেবারে নতুন ইনোড এবং ব্র্যান্ডের নতুন বিষয়বস্তু, যা ইতিমধ্যে চলমান প্রক্রিয়াগুলি যত্ন করে না।
এখন, ভাগ করা লাইব্রেরিগুলির ক্ষেত্রে এটি একই আচরণ প্রযোজ্য হবে। যতক্ষণ না কোনও প্রক্রিয়া দ্বারা কোনও লাইব্রেরি অবজেক্ট ব্যবহার করা হয়, ততক্ষণ আপনি এটির লিঙ্কগুলি কীভাবে পরিবর্তন করেন না কেন এটি ডিস্ক থেকে মুছে ফেলা হবে না। যখনই কোনও কিছু মেমোরিতে লোড করতে হয়, কার্নেলটি ফাইলের ইনোডের মাধ্যমে এটি করবে এবং অতএব আপনি এর লিঙ্কগুলিতে করা পরিবর্তনগুলি উপেক্ষা করবেন (যেমন নতুন ফাইলগুলির সাথে যুক্ত করে)।