Tmpfs / এর এই অদ্ভুত বিরল ফাইল হ্যান্ডলিংয়ের ব্যাখ্যা কী হতে পারে?


14

আমার ext4ফাইল সিস্টেম পার্টিশনে আমি নিম্নলিখিত কোডটি চালাতে পারি:

fs="/mnt/ext4"

#create sparse 100M file on ${fs}
dd if=/dev/zero \
   of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2> /dev/null

#show its actual used size before
echo "Before:"
ls ${fs}/sparse100M -s

#setting the sparse file up as loopback and run md5sum on loopback
losetup /dev/loop0 ${fs}/sparse100M 
md5sum /dev/loop0

#show its actual used size afterwards
echo "After:"
ls ${fs}/sparse100M -s

#release loopback and remove file
losetup -d /dev/loop0
rm ${fs}/sparse100M

যা ফলন দেয়

Before:
0 sparse100M
2f282b84e7e608d5852449ed940bfc51  /dev/loop0
After:
0 sparse100M

Tmpfs এ খুব একই জিনিসটি করা:

fs="/tmp"

উৎপাদনের

Before:
0 /tmp/sparse100M
2f282b84e7e608d5852449ed940bfc51  /dev/loop0
After:
102400 /tmp/sparse100M

যার মূলত এর অর্থ হ'ল এমন কিছু যা আমি কেবল ডেটা পড়ার প্রত্যাশা করেছিলাম, এর ফলে স্পার্স ফাইলটি "বেলুনের মতো ফুঁপিয়ে উঠেছে"?

আমি আশা করি ফাইল tmpfsসিস্টেমে স্পার্স ফাইলের জন্য কম নিখুঁত সমর্থন এবং বিশেষত FIEMAP ioctl হারিয়ে যাওয়ার কারণে, তবে আমি নিশ্চিত নই যে এই আচরণের কারণ কী? তুমি কি আমাকে বলতে পার?


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

সম্ভবত এটি একটি উত্তর পেতে পারে যদি এটি হয়? কেবল একটি চিন্তা

1
/ Tmp এর আউটপুট এর আগে / পরে বিভিন্ন ফাইল থাকে। এটা কি টাইপো? পূর্বে: 0 / tmp / sparse100 (শেষে এম ছাড়াই) পরে: 102400 / tmp / sparse100M (পিছনে এম সহ)।
YoMismo

@YoMismo, হ্যাঁ একটি নামমাত্র টাইপো ছিল
humanityANDpeace

উত্তর:


4

প্রথমে আপনি এই ধরণের সমস্যা নিয়ে বিস্মিত হয়ে একা নন

এটি কেবল সীমাবদ্ধ নয় tmpfsতবে এটি এনএফএসভি 4 এর সাথে উদ্ধৃত একটি উদ্বেগ ।

যদি কোনও অ্যাপ্লিকেশন একটি ছিদ্রযুক্ত ফাইলের 'ছিদ্র' পড়েন, ফাইল সিস্টেম শূন্য ব্লকগুলিকে জিরো ভরাট "রিয়েল" ব্লকে রূপান্তর করে এবং সেগুলিকে অ্যাপ্লিকেশনটিতে ফিরিয়ে দেয়।

যখন md5sumকোনও ফাইল স্ক্যান করার চেষ্টা করা হয় তখন এটি স্পষ্টতই অনুক্রমিক ক্রমে এটি করার জন্য চয়ন করে , যা এমডি 5সাম কী করার চেষ্টা করছে তার উপর ভিত্তি করে অনেক অর্থবোধ করে।

যেহেতু ফাইলটিতে মৌলিকভাবে "ছিদ্র" রয়েছে, এই ক্রমিক পাঠকটি (কিছু পরিস্থিতিতে) ফাইলটি পূরণ করার জন্য অপারেশনের মতো লেখার অনুলিপি তৈরি করতে চলেছে। এরপরে fallocate()এটি ফাইলসিস্টেম সমর্থন হিসাবে প্রয়োগ করা হয়েছে কিনা তা আশেপাশের গভীর সমস্যার মধ্যে পড়ে FALLOC_FL_PUNCH_HOLE

ভাগ্যক্রমে, এটি কেবল tmpfsসমর্থন করে না তবে গর্তগুলি আবার "খনন" করার ব্যবস্থা রয়েছে।

সিএলআই ইউটিলিটি ব্যবহার করে fallocateআমরা সফলভাবে এই গর্তগুলি সনাক্ত করতে এবং পুনরায় খনন করতে পারি।

অনুসারে man 1 fallocate:

-d, --dig-holes
      Detect and dig holes.  This makes the file sparse in-place, without
      using extra disk space.  The minimum size of the hole depends on
      filesystem I/O  block size (usually 4096 bytes).  Also, when using
      this option, --keep-size is implied.  If no range is specified by
      --offset and --length, then the entire file is analyzed for holes.

      You can think of this option as doing a "cp --sparse" and then
      renaming the destination file to the original, without the need for
      extra disk space.

      See --punch-hole for a list of supported filesystems.

fallocateকরে পরিচালিত ফাইল স্তর যদিও এবং আপনি দৌড়াচ্ছে md5sum একটি বিরুদ্ধে ব্লক ডিভাইস (অনুরোধ অনুক্রমিক সার্চ) আপনি কিভাবে মধ্যে সঠিক ফাঁক আপ দ্রুতগামী করছি fallocate()প্রাপ্ত syscall চালনা করা উচিত নয়। আমরা এটি কার্যকরভাবে দেখতে পারি:

ক্রিয়া হিসাবে, আপনার উদাহরণ ব্যবহার করে আমরা নিম্নলিখিতটি দেখতে পাই:

$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ONTGAS8L06
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ONTGAS8L06/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ sudo md5sum /dev/loop0
2f282b84e7e608d5852449ed940bfc51  /dev/loop0
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 102400 /tmp/tmp.ONTGAS8L06/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ONTGAS8L06/sparse100M

এখন ... এটি আপনার প্রাথমিক প্রশ্নের উত্তর দেয়। আমার সাধারণ উদ্দেশ্যটি "অদ্ভুত হয়ে উঠুন" তাই আমি আরও খনন করেছি ...

$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ZcAxvW32GY
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51  /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51  /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 516 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51  /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 512 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51  /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M

আপনি যে নিছক আইন দেখতে করণlosetup বিক্ষিপ্ত ফাইলের আকারের পরিবর্তন। সুতরাং এটি যেখানে tmpfs, HOLE_PUNCH প্রক্রিয়া fallocate, এবং ব্লক ডিভাইসগুলি ছেদ করে একটি আকর্ষণীয় সংমিশ্রণে পরিণত হয় ।


2
আপনার উত্তরের জন্য ধন্যবাদ. আমি সচেতন tmpfsবিচ্ছিন্ন ফাইল এবং পাঞ্চ_হোল সমর্থন করে। এটিই এটি এত বিভ্রান্তিকর করে তোলে - এটি tmpfs সমর্থন করে , তবে লুপ ডিভাইসটি পড়ার সময় কেন স্পর্শকৃত গর্তগুলি পূরণ করুন? losetupফাইলের আকার পরিবর্তন করে না, তবে এটি একটি ব্লক ডিভাইস তৈরি করে, যা বেশিরভাগ সিস্টেমে এই জাতীয় সামগ্রীর জন্য স্ক্যান করা হয়: একটি বিভাজন সারণী আছে? ইউআইডি সহ কোনও ফাইল সিস্টেম আছে? আমি কি তখন / ডি / ডিস্ক / বাই-ইউইডি / সিমলিংক তৈরি করব? এবং এই পাঠগুলি ইতিমধ্যে স্পার ফাইলের কিছু অংশ বরাদ্দ দেয়, কারণ কিছু রহস্যজনক কারণে , tmpfs (কিছু) পড়তে গর্ত পূরণ করে।
frostschutz

1
অনুগ্রহ করে আপনি কি " ক্রমবিন্যাসের পাঠক (কিছু পরিস্থিতিতে) অপারেশনের মতো লেখার অনুলিপি তৈরি করতে চলেছেন ", দয়া করে? আমি জানতে আগ্রহী যে কীভাবে একটি পঠন অপারেশন লেখার ক্রিয়াতে একটি অনুলিপি ট্রিগার করবে। ধন্যবাদ!
রোয়াইমা

এটা বিজোড়। আমার সিস্টেমে আমি একই পদক্ষেপগুলি অনুসরণ করেছি, যদিও ম্যানুয়ালি এবং কোনও স্ক্রিপ্টে নয়। প্রথমে আমি ওপি এর মতোই একটি 100 এম ফাইল করেছি। তারপরে আমি কেবলমাত্র 10MB ফাইল দিয়ে পদক্ষেপগুলি পুনরাবৃত্তি করেছি। প্রথম ফলাফল: ls -s sparse100M ছিল 102400 But তবে 10 এমবি ফাইলটিতে এলএস-এস ছিল কেবল 328 ব্লক। ??
প্যাট্রিক টেলর

1
ইউএইউডি স্ক্যানার আসার পরে @ পেট্রিকটেলর ~ 328K কী ব্যবহার করছে সে সম্পর্কে, তবে আপনি সম্পূর্ণ পঠনের জন্য লুপ ডিভাইসটিকে বিড়াল / এমডি 5 সুম করেন নি।
frostschutz

1
আমি লুপ কার্নেল মডিউলটির জন্য উত্সটি খনন করছিলাম (ইন loop.c) এবং দেখেছি দুটি প্রাসঙ্গিক ফাংশন রয়েছে : lo_read_simple& lo_read_transfer। তারা কীভাবে নিম্ন স্তরের মেমরি বরাদ্দ করে তাতে কিছু ছোটখাটো পার্থক্য রয়েছে ... কলটি করার সময় lo_read_transferআসলে slab.h( GFP_NOIO) থেকে অবরুদ্ধকরণ আইও-র অনুরোধ করে alloc_page()lo_read_simple()অন্যদিকে পারফর্ম করছে না alloc_page()
ব্রায়ান রেডবার্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.