VPN ইনস্টলার 32-বিট বলে: বরং ELF হেডার দেখুন
শব্দের আকার নির্দেশনা সেট চিহ্নিত করে না। ক্লাস, মেশিন ও ইন্টারপ্রেটার পড়ার এবং তারপর হোস্টের সঙ্গে মেলা বিল্ড চাওয়ার পদ্ধতি।
একটি ডাউনলোড পেজ 32-বিট বলে, ফাইলটি Raspberry Pi-তে পৌঁছায়, আর ইনস্টলার এমন বার্তা দিয়ে ব্যর্থ হয় যা সমস্যার কোনো উপকারী অংশের নাম বলে না। দুটি সম্পূর্ণ ভিন্ন এক্সিকিউটেবল ELF অর্থে দুটিই 32-বিট হিসেবে গণ্য, আর তাদের মধ্যে কেবল একটি ওই বোর্ডে চলতে পারে। ক্লাস ফিল্ড একটি তথ্য, মেশিন ফিল্ড আরেকটি, আর ফাইলের নাম আপনাকে দুটির কোনোটিই নির্ভরযোগ্যভাবে বলে না। লাইব্রেরি বদলানো বা অন্য মিরর চেষ্টা করার আগে হেডারটি পড়ুন।
ক্লাস বলে শব্দের আকার, মেশিন বলে নির্দেশনা সেট
Linux ELF রেফারেন্স ফাইল হেডারে একটি ক্লাস ফিল্ড ও একটি মেশিন ফিল্ড সংজ্ঞায়িত করে, আর দুটি ভিন্ন প্রশ্নের উত্তর দেয়। ক্লাস বলে ফাইলটি 32-বিট না 64-বিট রূপ ব্যবহার করে; মেশিন বলে এটি কোন নির্দেশনা সেটের জন্য তৈরি। একটি 32-বিট x86 বিল্ড ও একটি 32-বিট ARM বিল্ড প্রথমটিতে একমত এবং দ্বিতীয়টিতে ভিন্ন। এভাবেই সঠিক শব্দের আকারের প্রতিশ্রুতি দেওয়া লেবেলও এমন কোড দেয় যা প্রসেসর ডিকোড করতে পারে না। পড়ার যোগ্য তৃতীয় মানটি হলো অনুরোধকৃত ইন্টারপ্রেটার, যা প্রোগ্রাম হেডার নাম দেয় যখন বাইনারি একটি ঘোষণা করে।
readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED
প্রথম কমান্ড হেডার ছাপে, দ্বিতীয়টি ফাইলে থাকলে প্রোগ্রাম হেডার ছাপে, আর তৃতীয়টি লোডারের প্রয়োজনীয় শেয়ার্ড অবজেক্ট তালিকা করে। ক্লাস, মেশিন ও ইন্টারপ্রেটার একসঙ্গে লিখে রাখুন, কারণ এই তিনটি মানই এই স্তরে সামগ্রিক সামঞ্জস্যের প্রশ্ন। তিনটির কোনোটিই ডাউনলোড বোতামে দেখা যায় না, তাই ফাইলটি বর্ণনা নয়, পরীক্ষা করতে হয়।
এটি কার্নেলের কাছে কোন ইন্টারপ্রেটার চায়
ইন্টারপ্রেটার ঘোষণা করা এক্সিকিউটেবল কার্নেলের কাছে একটি নির্দিষ্ট লোডার পথ চায়। ওই লোডার না থাকলে, আপনার নাম দেওয়া ফাইল ঠিক সেখানেই থাকলেও চালু হওয়া ব্যর্থ হয়। এখানেই মানুষ ভাবে ডাউনলোড নষ্ট, অথচ আসল উত্তর হলো এমন লোডার যা ডিস্ট্রিবিউশন সরবরাহ করে না।
লোডারটিকে আপনি সত্যিই যে সিস্টেম চালান তার সঙ্গে মেলান: OS সংস্করণ, ইউজারস্পেস আর্কিটেকচার এবং যে প্যাকেজ লোডার দেয়। 64-বিট কার্নেল 32-বিট ইউজারস্পেস চালাতে পারে কেবল যখন সেই ইউজারস্পেস ও তার লোডার ইনস্টল থাকে, তাই প্রসেসরের সামর্থ্য নির্ধারক নয়। একটি সংক্ষিপ্ত পরীক্ষা ইন্টারপ্রেটারের নাম এক লাইনে বলে, আর এটি সাপোর্ট টিকিটের চেয়ে কম সময় নেয়। শেল স্ক্রিপ্ট আরও ভিন্নভাবে ব্যর্থ হয়, কারণ এর ইন্টারপ্রেটার ELF হেডারে নয়, প্রথম লাইনে লেখা থাকে, আর সেই লাইন পড়তে কিছুই খরচ হয় না।
file --brief ./vendor-vpn
ডাউনলোডকে প্যাকেজ আর্কিটেকচারের সঙ্গে মেলান
ডিস্ট্রিবিউশন প্যাকেজ আর্কিটেকচার একই পার্থক্য নিজস্ব পরিভাষায় প্রকাশ করে, আর সেই পরিভাষাই ভেন্ডরের সাপোর্ট বিবৃতি বোঝায়। আপনার প্যাকেজ ম্যানেজার যে মান জানায় তা ভেন্ডরের নথিভুক্ত মানের সঙ্গে তুলনা করুন, মার্কেটিং লেবেলকে ফাইলের নামের সঙ্গে তুলনা করার বদলে। যে জোড়াগুলো সমস্যা করে সেগুলো হলো amd64 বনাম arm64, এবং armhf বনাম armel, কারণ প্রতিটি জোড়া ডাউনলোড তালিকায় বিনিময়যোগ্য দেখায়। x64 বা ia32-এ শেষ হওয়া ফাইলের নাম একটি বিল্ড টার্গেট বোঝায়, যে মেশিন এটি ধরে আছে তা নয়।
| Label on the download | ELF class | e_machine | Interpreter the kernel wants | How it fails on the wrong host |
|---|---|---|---|---|
| amd64 | ELF64 | x86-64 | /lib64/ld-linux-x86-64.so.2 | Immediate exec failure on an ARM board |
| armhf | ELF32 | ARM | /lib/ld-linux-armhf.so.3 | Loads on a soft-float system, then fails on a float ABI call |
| i386 | ELF32 | Intel 80386 | /lib/ld-linux.so.2 | Exec format error where no 32-bit loader package exists |
প্রতিটি সারি এমন একটি ঘটনা যেখানে শব্দের আকার ঠিক মনে হয় আর কোড তবুও ভুল আচরণ করে, বা যেখানে এটি শুরু হয়ে এক স্তর নিচে ব্যর্থ হয়। ইন্টারপ্রেটার কলামটিকে ইঙ্গিত নয়, কঠোর শর্ত হিসেবে পড়ুন, কারণ কার্নেল আপনার কোনো কোড চালানোর আগেই সেই পথ সমাধান করে। এমুলেশন নিজস্ব কর্মক্ষমতা ও সাপোর্ট পরিণতি সহ একটি ডিপ্লয়মেন্ট সিদ্ধান্ত, আর প্রশস্ত শব্দের আকার বিজ্ঞাপন দেওয়া প্রসেসর কখনোই তা নিহিত করে না।
dpkg --print-architecture
ENOEXEC আর ENOENT ভিন্ন ব্যর্থতা
লঞ্চ পর্যায় দুটি ত্রুটির একটি রিপোর্ট করে, আর সেগুলো ভিন্ন সমস্যার দিকে ইশারা করে। ত্রুটির মান পড়া অন্য কিছু চালানোর আগেই ব্যর্থতাটিকে শ্রেণিবদ্ধ করে।
ENOEXEC মানে ফরম্যাট চেনা যায়নি: ভুল আর্কিটেকচার, ভুল ক্লাস, বা এমন কিছু যা আদৌ এক্সিকিউটেবল নয়। ELF ফাইলে ENOENT সাধারণত মানে ইন্টারপ্রেটার অনুপস্থিত, যদিও আপনার চাওয়া ফাইলটি আছে। একই ENOENT মানে স্ক্রিপ্টের ইন্টারপ্রেটারও অনুপস্থিত হতে পারে, তাই স্ক্রিপ্টের প্রথম লাইন গুরুত্বপূর্ণ। যেভাবেই হোক বার্তাটি স্তরটির নাম বলে, আর প্রতিটি “পাওয়া যায়নি”-কে অনুপস্থিত কনফিগারেশন ভাবা তদন্তকে ভুল দিকে পাঠায়। টিকিটে ত্রুটির মান উদ্ধৃত করুন, কারণ এটি আশপাশের বাক্যের চেয়ে পুনর্কথনে ভালো টেকে।
বাইনারি চালু না হলে কী করবেন না
ব্যাখ্যাহীন বাইনারিকে শেল মোড়কে জোর করে চালানো তাকে চালায় না। যে ফাইলে আস্থা নেই তার ওপর নির্ভরতা পরীক্ষক হেলাফেলায় চালাবেন না, কারণ চালালে কিছু পরিস্থিতিতে বাইনারি থেকে কোড চলতে পারে। বার্তা এড়াতে লোডার সিমলিংক যোগ করবেন না, হোস্ট লাইব্রেরি বদলাবেন না বা তৃতীয় পক্ষের মিরর থেকে পুরোনো আর্কাইভ আনবেন না। এর প্রত্যেকটি হেডার যে অমিলের নাম ইতিমধ্যে বলেছে তা না ছুঁয়ে পরিবর্তনের পরিধি বাড়ায়।
ভেন্ডরের কাছে যাওয়ার সময় গল্প নয়, মান পাঠান: OS সংস্করণ, প্যাকেজ আর্কিটেকচার, ক্লাস ও মেশিন স্ট্রিং, অনুরোধকৃত ইন্টারপ্রেটার এবং প্রথম ত্রুটির লাইন। এই সেটটি ব্যর্থ ইনস্টলারের স্ক্রিনশটের চেয়ে দ্রুত সাপোর্ট প্রশ্ন সমাধান করে। পুরোনো আর্টিফ্যাক্ট আর মনে রাখা ফোরামের আউটপুট বর্তমান সাপোর্ট ম্যাট্রিক্স নয়, আর নেটিভ বাইনারি লোড হওয়ার পর প্রোফাইল, প্রমাণীকরণ ও রাউটিং আলাদা কাজ থাকে।