1 पॉइंट द्वारा GN⁺ 2 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • BusyBox एक multicall binary है जो कई commands को एक ही executable file में उपलब्ध कराता है, और Alpine का डिफ़ॉल्ट wget भी BusyBox के ज़रिए चलता है
  • Alpine container में /usr/bin/wget असली binary नहीं था, बल्कि /bin/busybox की ओर इशारा करने वाला symbolic link था
  • BusyBox चलने पर argv[0] से call किया गया नाम पढ़ता है, और path के आख़िरी नाम के आधार पर यह तय करता है कि कौन-सा applet चलाना है
  • हर applet को उसके नाम से खोजकर उसके संबंधित main function में प्रवेश किया जाता है; wget का implementation wget.c में है और अंत में wget_main चलाया जाता है
  • busybox --list से compiled commands देखे जा सकते हैं, और Alpine उदाहरण में 304 दिखते हैं; हर utility अपने मूल utility के कुछ संक्षिप्त संस्करण जैसी लगती है

BusyBox कैसे काम करता है

  • BusyBox कई commands को एक executable file में उपलब्ध कराने के लिए multicall binary संरचना का उपयोग करता है
  • Alpine container में /usr/bin/wget असली executable file नहीं था, बल्कि /bin/busybox की ओर इशारा करने वाला symbolic link था
    docker run --rm -it alpine sh
    / # which wget
    /usr/bin/wget
    / # ls -lah /usr/bin/wget
    lrwxrwxrwx    1 root     root          12 Apr 15 04:51 /usr/bin/wget -> /bin/busybox
    
  • /usr/bin में 130 से ज़्यादा executable files ऐसे दिखाई देते हैं मानो वे एक ही binary से आए हों, और यह BusyBox की multicall binary संरचना से जुड़ा है
  • BusyBox चलते समय argv[0] से call किया गया नाम लेता है, और path का आख़िरी नाम निकालकर यह तय करता है कि कौन-सा applet चलाना है
    applet_name = argv[0];
    if (applet_name[0] == '-')
      applet_name++;
    applet_name = bb_basename(applet_name);
    
  • busybox ls -1 की तरह अगर applet का नाम सीधे दिया जाए तब भी यह काम करता है, और अगर कोई ऐसा नाम दिया जाए जो मौजूद नहीं है तो applet not found दिखाता है
    / # busybox ls -1
    bin
    dev
    etc
    home
    
    / # busybox meheh
    meheh: applet not found
    

Applet की संरचना और installation का तरीका

  • BusyBox पहले applet को उसके नाम से खोजता है और फिर उस applet का main function चलाता है
    int applet = find_applet_by_name(name);
    // ...
    run_applet_no_and_exit(applet, name, argv);
    // ...
    xfunc_error_retval = applet_main[applet_no](argc, argv);
    
  • हर applet की अपनी अलग C file होती है, और wget का implementation wget.c में है
  • हर applet की setting code comments के रूप में परिभाषित होती है; WGET setting में wget (41 kb), डिफ़ॉल्ट रूप से enabled होना, HTTP और FTP servers से non-interactive तरीके से files डाउनलोड करने वाली utility का help text, और build target wget.o शामिल हैं
    //config:config WGET
    //config:	bool "wget (41 kb)"
    //config:	default y
    //config:	help
    //config:	wget is a utility for non-interactive download of files from HTTP
    //config:	and FTP servers.
    //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP))
    //kbuild:lib-$(CONFIG_WGET) += wget.o
    
  • अंत में wget applet wget_main में प्रवेश करता है
    int wget_main(int argc UNUSED_PARAM, char **argv)
    
  • BusyBox hard link को भी support करता है, और busybox --install -s में -s का मतलब symbolic link बनाना है
    busybox --install -s
    
  • compilation में शामिल commands की सूची busybox --list से देखी जा सकती है, और Alpine के उदाहरण environment में 304 दिखाई देते हैं
    / # busybox --list | wc -l
    304
    
  • Alpine के कई commands BusyBox-आधारित binary के interface की तरह काम करते हैं, और हर utility अपने पूर्ण मूल utility की तुलना में कुछ संक्षिप्त संस्करण जैसी लगती है

1 टिप्पणियां

 
GN⁺ 2 시간 전
Lobste.rs की राय
  • उद्धृत सवाल का जवाब रीइम्प्लीमेंटेशन के ज़्यादा करीब है
    BusyBox का परिचय https://busybox.net/about.html पर है, और source https://github.com/vda-linux/busybox_mirror पर है

  • किसी प्रोग्राम का असल में कुछ और होते हुए किसी दूसरे नाम का दिखावा करना काफ़ी खटकता है
    macOS में gcc चलाने पर असल में clang निकलना सबसे बुरा उदाहरण है, और PowerShell भी कुछ ऐसा ही करता है। बेहतर होता कि बस दूसरा नाम इस्तेमाल किया जाता

    • यह समस्या कुछ हद तक इसलिए भी बनी क्योंकि इसकी शुरुआत उस दौर में हुई थी जब बहुत से developers clang को नहीं जानते थे, उनके पास test करने के लिए Mac नहीं था, या कोई व्यावहारिक विकल्प नहीं था
      Nixpkgs को https://github.com/NixOS/nixpkgs/… जैसी बहुत-सी patches लगानी पड़ती हैं, और sqlite जैसे मशहूर project भी इससे अछूते नहीं हैं। इसके उलट, macOS ने बस भ्रमित करने वाले path का रास्ता चुना
    • बहुत से software के makefile इस्तेमाल करने वाले लोग cc के बारे में नहीं जानते
    • झुंझलाहट समझ में आती है, लेकिन अगर यह ज़्यादातर build scripts चलाने लायक काफ़ी compatible हो, तो Linux और कई Unix परिवारों में एक ही scripts को कुछ हद तक दोबारा इस्तेमाल किया जा सकता है, इसलिए शायद यह फैला
    • कभी-कभी यह व्यवहारिक रूप से नामुमकिन होता है
      बहुत-सी makefile में gcc hardcode किया हुआ होगा, और दूसरे contexts में भी ऐसा ही है। उदाहरण के लिए, बहुत से मौजूदा program सही समाधान terminfo database की जगह TERM environment variable में xterm-* देखते हैं, इसलिए दूसरा नाम चुनने वाला तरीका काम नहीं करता
  • container में अजीब problems diagnose करते समय मैं अक्सर podman cp /usr/bin/busybox-static somecontainer:/bin इस्तेमाल करता हूँ

  • toybox की संरचना भी मिलती-जुलती है
    कुछ tools शायद दूसरी जगहों से लिए गए या port किए गए लगते हैं, लेकिन काफ़ी सारे BusyBox के लिए नए सिरे से implement किए गए थे, और लक्ष्य यह है कि इन्हें छोटा रखा जाए और static linking पर छोटा compile होने के लिए libc की सीमित functionality ही इस्तेमाल की जाए। एक और फ़ायदा यह है कि shell scripts में इन tools को built-in commands की तरह इस्तेमाल किया जा सकता है। कुछ को fork+exec की जगह fork+jump से चलाया जाता है, और कुछ तो fork के बिना सामान्य function call से भी चलते हैं

    • मेरी जानकारी में toybox मूल रूप से GPL-licensed BusyBox का BSD-licensed विकल्प बनाकर तैयार किया गया था
      और जोड़ूँ तो, Toybox on Wikipedia के अनुसार, “Toybox की शुरुआत 2006 की शुरुआत में तब हुई जब Rob Landley ने BusyBox के मूल निर्माता Bruce Perens के साथ विवाद के बाद BusyBox maintainer की भूमिका छोड़ दी”
  • तकनीकी रूप से यह रीइम्प्लीमेंटेशन है। हाँ, अगर license इसकी अनुमति देता हो तो मूल बड़े implementation से कुछ code लिया गया हो, यह चौंकाने वाली बात नहीं होगी
    From the 'pedia: के अनुसार BusyBox को Bruce Perens ने 1995 में पहली बार लिखा था, और 1996 में इसे अपने इच्छित उपयोग के लिए पूरा घोषित कर दिया गया था। शुरुआती लक्ष्य था Debian distribution की recovery disk और installer के रूप में काम करने वाला पूरा bootable system एक ही floppy disk में समेटना। बाद में यह embedded Linux devices और Linux distribution installers में core user-space utilities के de facto standard set के रूप में फैल गया, और क्योंकि हर Linux executable को कई KB overhead चाहिए होता है, इसलिए 200 से ज़्यादा programs को एक में जोड़ देने से disk space और memory की बड़ी बचत हो सकती है
    इसी संदर्भ में Toybox की संरचना और दर्शन भी मिलते-जुलते हैं, लेकिन उसका license BSD है। मुझे याद है कि इसके मुख्य developer Rob Landley का मानना था कि अगर license व्यावसायिक स्वीकार्यता के लिहाज़ से आसान हो, तो इसे Android devices में शामिल किया जा सकता है, और तब हर Android phone और tablet एक Unix-जैसे development environment में बदलने की क्षमता रखेगा। Toybox अब भी Android का हिस्सा लगता है, लेकिन Termux जैसे ऊपर की layer के helper tools के बिना Android को Unix की तरह इस्तेमाल करना आसान नहीं है

    • यह दिखाने के लिए इससे बेहतर textbook example मुश्किल है कि Google जैसी कंपनियों को मुफ़्त मज़दूरी देना आख़िरकार आपके ही ख़िलाफ़ कैसे जा सकता है
      खासकर जब यह भी देखें कि Google वर्षों से Termux को रोकने की धमकी देता आया है
  • Windows port भी है: https://github.com/rmyorston/busybox-w32
    BusyBox का छोटा आकार ऐसे port को और व्यवहारिक बनाता है। हालाँकि अब Windows के भीतर Linux को सीधे चलाया जा सकता है, इसलिए इसकी प्रासंगिकता कुछ कम हुई लगती है