パスワードを忘れた? アカウント作成
3741 story

NetBSDが全てのexecutableをdynamic linkに 51

ストーリー by wakatono
ダイナミックリンクの正しい使い方 部門より

brake-handle曰く、"Luke Mewburnがnetbsd-current-usersに流したmailによると、NetBSD-currentは一両日中に/binや/sbin以下を含めた全ての実行可能ファイルをdynamic linkにするそうだ。これにともない、/binや/sbin向けのshared objectが/libへ移動する、static link版のexecutableを/rescue以下に用意するなどの変化が生じる。

全てのexecutableをdynamic linkにする最大の効用はファイルサイズの節約。Luke Mewburnが測定した結果によると、/binおよび/sbinのサイズが15.9MBから9.2MBに減少、約4割減となった(1.6_BETA3/i386)。容量の厳しいFDやflash cardなどでは助かることだろう。

Solarisでも/binが実は/usr/binでdynamic linkだったなんてことはあったが、/sbinまでやってしまうとは。恐れ入りました。"

いまさら容量節約なんて…と思う人もいるかもしれないが、PDA等大きな記憶領域を持てないデバイスにとって切実な問題だ。そういうデバイスでもっとBSDを…という人には朗報かな。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • sbinの意味が (スコア:3, 参考になる)

    by Anonymous Coward on 2002年08月27日 19時50分 (#153958)
    static linkじゃなく、symbolic linkになってしまう日がやってくる…
    なんてことは既に議論されているんでしょうねぇ?
    • Re:sbinの意味が (スコア:2, すばらしい洞察)

      by Anonymous Coward on 2002年08月27日 22時46分 (#154087)
      sbinという名称の正式な由来については知らないし、以下、FreeBSDでの話なので、NetBSDとは状況が違うとは思うけど....

      FreeBSDで/usr/sbin見たらdynamically linkedなバイナリが満載。かと思えば/usr/binにもstatic linkedなバイナリは存在します。さらに言えば、/binや/sbinはほとんどがstatic linkedです。ってことで、リンク方式で言えば、

      static : /{bin,sbin}
      dynamic: /usr/{bin,sbin}

      と分かれていて、それぞれの中に入ってるコマンドの傾向としては

      一般用途 : /bin /usr/bin
      システム管理用途 : /sbin /usr/sbin

      に分かれているんだと今まで思っていました。この認識を改めないといけないでしょうか?
      親コメント
    • Re:sbinの意味が (スコア:1, おもしろおかしい)

      by Anonymous Coward on 2002年08月27日 19時58分 (#153967)
      あがっ!system binの事だと思ってたよー

      #恥さらしなのでACで
      親コメント
      • by Anonymous Coward
        同じく。system binaryだと…。
        知るは一瞬の恥。知らぬは一生の恥。
        ということでー。

        勉強になります。φ(.. )メモメモ
    • by Anonymous Coward
      NetBSD の場合、symlink にはなりません。
      SunOS のアレは気持ち悪いでそ。
    • by Anonymous Coward
      ぬあー。知らなかった。superuser binaryかと…

      static link binaryは必然、それ単体で動くために
      スーパユーザが実行するものが多く、結果system binary
      とかsuperuser binaryとか思ってしまった、ってことかし
      らん?
  • 容量はメリットの一つですが、 dynamic link にするとライブラリに致命的なバグが見つかったときにライブラリを make し直すだけで済むというメリットもあるのではと思います(本当に全体を make し直す必要がないかどうかはわかりませんが)。

    普通は /bin や /sbin が static link だろうが dynamic link だろうが、 /usr/lib に入っているライブラリを更新したときには全体を make し直すものかもしれませんが。
    --
    鵜呑みにしてみる?
    • 確かに、zlib の時にも大騒ぎになりましたよね。
      多くのソフトウェアで使われているライブラリに障害が見つかった場合、
      稼働中のシステムでは全部 make し直すというのは
      かなり厳しい作業でしょうから、そういった意味でも
      dynamic link になるのはいいことですよね。
      ただ、今度はライブラリの下位互換性の問題が生まれるのでしょうが……

      .NET Framework では、共有アセンブリのバージョン管理に工夫をしているようで
      サイドバイサイド実行 [microsoft.com]なんていうものもできるそうなのですが、
      Unix の .so はどうなっているのでしょう。
      よく、
      /usr/local/lib/libVFlib2.so -> libVFlib2.so.24.0.1*
      /usr/local/lib/libVFlib2.so.24 -> libVFlib2.so.24.0.1*
      /usr/local/lib/libVFlib2.so.24.0.1*
      のようになっているので、うまくやれば下位互換性に
      悩まされずに共有ライブラリを使えそうだなぁ、とは思うのですが
      実際の所はどうなのでしょう。
      バージョン番号に関する共通のコンベンションってあるんでしょうか。
      親コメント
      • by brake-handle (5065) on 2002年08月27日 20時50分 (#154008)

        とりあえず、現在最もよく用いられているelfの場合。

        elfの場合、shared objectにはversion numberという概念はありません(確かa.outではld.soの動作に意味を持つversion numberが存在した)。その代りに、major version number(executable作成時とruntimeで一致していなければならない)をheaderに埋め込むことによってversion controlを実現しています。

        major version numberは、dynamic sectionのSONAMEに保存されます。gnu binutilsの場合、objdump(1)で確認できます。

        silver% objdump -x /usr/lib/libc.so.5 | head -n 20
        (snip)
        Dynamic Section:
        SONAME libc.so.5

        .NETのやり方は、fileではなくsymbolにversion controlを入れようという考え方です。Unixのlinkerにもweak symbol(weakでない同名のsymbolがあった場合、weakでないものを優先する)がありますが、これをより複雑にしたものです。並列開発などでは効くのかも知れませんが、runtime linkerの仕事が非常に重くなりそうなのでprocessをたて続けに起動するような場合にはつらいかも知れません。

        親コメント
        • by G7 (3009) on 2002年08月28日 2時57分 (#154284)
          >runtime linkerの仕事が非常に重くなりそうなのでprocessをたて続けに起動するような場合にはつらいかも知れません。

          .NETも、unixみたいに、「processを」たて続けに起動する
          なんて使い方をするんだろうか?とか、一瞬思ってしまいました。

          やっぱり、目指す(べき)ところは、「立ち上げっぱなし」および
          「動かすかどうか、と、Loadされているかどうか、の独立」っすよね…
          親コメント
          • 最近はprocessを使うのもずいぶん楽になりました。risc-based workstationを使い慣れていない人は全く知らないと思いますが(私もついこの前初めて知った)、実はaddress spaceの切り換えというのはprocessorの工夫によってある程度安く済むようになっています。典型はSPARC V9上のSolaris 2で、kernel address spaceにprocess address spaceを全くmapしません。もともとはkernel address spaceを増やす事が目的でしたが、system callのた

            • 今となっては、processを使うことをためらわせるぐらいaddress spaceの切り替えが高くつくのはIntelぐらいでしょうねぇ...
              具体的にはどういうことなのでしょうか? 素人にもわかるように教えていただけると幸いです。
              • by brake-handle (5065) on 2002年08月28日 13時08分 (#154537)

                virtual address spaceが使えるprocessorには、virtual address spaceの各pageをphysical memoryのpageに変換する(対応するphysical pageが存在しないこともある)表を持っています。この表は通常memory上にあるのですが、実際にはそれをaddress参照の度に読んでいるとprocessorの実行がmemory busの帯域にboundしてしまいます。そこで、通常は表の一部をcacheに持っておきます。これがTLB(Translation Lookaside Buffer)です。

                Intelのprocessorでは、一度に1つの変換表しか使うことができません。また、TLBはvirtual address spaceを切り換えた時に全て無効化されてしまいます。これはTLB miss(注目しているvirtual addressがTLBに見つからない場合のcache miss)を増加させる原因になります。UltraSPARC IおよびIIではaddress space identifier(実体は8bitの数値)によってaddress spaceに名前をつけ、address space全体を切り換えることなく複数のaddress spaceを使い分けることが可能です。TLBがそのまま使えるので、kernel address spaceからuser process address spaceへのデータ転送などで不必要なTLB missを防ぐことができます。

                親コメント
              • Intelだとaddress変換表のcacheがムダになってしまうことが多いが、SPARCはその心配がないというぐらいの意味です。実際、TLBに入っている情報というのは変換表の一部をコピーしたものなので。

                補足ですが、TLBは変換表のコピーに過ぎないので、TLB missが生じたらtrapを発生してOSにTLBの補充を行わせるという考え方もあります。MIPSやUltraSPARCのようにriscの血を引き継いでいるprocessorではどちらかというとこの発想が普通です。

                親コメント
        • シンボルベースのリビジョン管理は GNU ld もそういう機能をもっていて、
          実際 glibc が使ってます。元ネタは Solaris 。
          振り向くとそこにはプロストではなくて Solaris がいるのが UNIX の世界。
          • by brake-handle (5065) on 2002年08月27日 21時12分 (#154026)

            元仕事場のSolaris 7で調べてみました。mapfileの中にsymbolのversionが書けるようですね。

            ...しかし、gnu libtoolが対応するまでは存在に気づかない人が多いのでは?

            親コメント
            • >...しかし、gnu libtoolが対応するまでは存在に気づかない人が多いのでは?

              とっくに対応していますが何か?
              • by brake-handle (5065) on 2002年08月27日 21時57分 (#154053)

                gnu binutilsやlibtoolなど、objectを扱うものの場合「とっくに対応している」という論法は通用しません。というのは、各種Unixごとに採用しているbinutilsなどのversionが異なる(主にkernel buildの際、address spaceを正しく作る必要がある)ため、いまだに古いものを使わざるを得ない場合もあるのです。

                親コメント
      • so のリビジョン番号は SunOS 4 a.out のオリジナルの実装が一番優れていて、
        これが NetBSD の a.out 実装でも踏襲されていたんですが、
        ELF の採用に伴って退化しました。
        • by Anonymous Coward on 2002年08月27日 20時54分 (#154011)
          というのはメカニズムの話で、NetBSD のりビジョン管理ポリシ
          そのものは a.out のときのものを踏襲しています。つまり、
              - メジャーバージョンが違うものは全くバイナリ互換性がない
              - メジャーバージョンが同じ場合、マイナーバージョンが
                  大きなものほど新しく、新しいものは古いものに対して
                  後方互換性をもっている
              - libc のメジャーバージョンを変更するのは禁忌 :D
          という感じです。
          親コメント
  • i386でも恩恵あり (スコア:2, 参考になる)

    by brake-handle (5065) on 2002年08月27日 19時54分 (#153965)

    少し補足すると、最近私用で可動部分を一切用いない、1UのハイトでハーフサイズのPC/AT機を見せてもらいました。Linuxが載っていてflash ATAでbootするのですが、どう頑張っても256MBの壁があるためやはり/binや/sbinは厳しいそうです(機能拡張のためにHDDを載せるオプションもあるそうで)。

    多くのarchitectureでflash ATAが使えるようになったという背景もあるでしょうが、i386などに絞り込んでみても太ったbashやashの問題が片づくと思わぬ使い方が出てきそうで楽しみです。

    • by Anonymous Coward

      容量がきびしい環境では crunched binary にすれば? という気がするんだが…

      それはさておき、/ と /usr を別パーティションにする習慣が一部にあるためにライブラリの置き場が /usr/lib と /lib の2箇所になってしまうのがなんかいやん。

      • この表現を見て、ちょっと驚きました。いろいろな考えがある
        ものだと思いました。

        BSDの歴史において、/と/usrを別にするのは伝統であり、
        暗黙の了解事項だと思って今まで生きてきました。
        PDPあたりのディスクの制限であったり、シングルユーザモード
        で走行するための最小環境であるために、歴史的に/は小さく
        作られてきたのだと思います。

        また、ディスクレスWSなるものが導入された時、/は個々のWS
        固有のデータを、/usrは共有可能な領域でリードオンリーとされた
        こともありました。

        バックアップ時は、/はシステムの一時ファイルを保持したり、
        システム設定ファイルが編集修正されるため、バックアップ頻度
        を多くし、/usrは新ソフトを追加しない限り変更はないものとし、
        頻度を下げることが出来る領域だとも思っていました。

        僕は今もそう思って、多くのサーバを今でも管理しています。
        ひとによって環境は違うのでしょうが、僕にはちょっと驚きの表現
        でした。
        親コメント
        • /usrと/が別パーティションなのは、一部でも何でもなく、普通のことだと思いますよ。ただ、現在はディスクの性能も上がり、そこまで気にしなくてもいいようになって来てはいるのかな、という気はしますね。
          むしろ/が小さすぎて、システムアップグレード時に溢れちゃったりすると悲しかったり(/kernel.oldと/modules.oldを削除してなんとかなりましたが)。

          FreeBSDあたりはAを押せばお任せでパーティションを切ってくれるのでそのまま使ってますが、linux系のシステムはそういうのが無いので、/とswapだけ作ってインストール、なんてこともよくやります。
          はじめて使うシステムなどですと、どこがどれだけ食うか把握できないので、この方が安全なこともあったりしますね。debianをはじめていれた時、FreeBSDしか知らなかったもので、/varに30Mしか割り振らずに悲しい思いをしました。debianは/varを酷使しますね。今では1Gあっても足りないと思ってます^^;;
          親コメント
        •  ふつー/varも別パーティションに置かないですかね?
           /tmpはmfsするもんだし。
          #ちなみにNetBSDはcronで /var/backupにcvsで/etcの各種設定ファイルを保存してくれる。便利。

           なもんで/に一時ファイルとか言われるとなんか気持ち悪い。
          • 使い方によっては、/varだけでなく/var/spoolや/var/mailも別にしてしまうこともありますね。/var/spool以下はinodeを大量に使う可能性がありますし(mailやnewsをため込む場合)、/var/mailはファイルサイズが太る恐れがあります。

            うちの場合、/var/spoolで何度かinodeが足りなくなったため、現在はinode数を4倍に増やしたfilesystemを使っています。

            親コメント
          • /var が別パーティションゆーんは当然。

            まあ同じアーキテクチャの同じ OS の同じバージョンのマシンを何台も管理してれば / と /usr をわけるとちょっとは楽なんでしょうけど。その程度のことでしょ? / で変更されやすいのは /etc ぐらいだろうし、/bin /sbin の更新頻度と /usr/bin /usr/sbin の更新頻度が違

      • by brake-handle (5065) on 2002年08月27日 21時02分 (#154019)

        boot fdとかだと、crunchかつ{g,b}zipしても1.44MBに収まるかどうかという厳しい条件になることもあります(そのたびに何を削るかでもめる)。こういう場合は/libが別建てになると助かります。

        もしPC/ATが早い段階で素直にOpenBootを使っていて、どんな計算機でも気軽にnetbootできる状況ならばSolarisよろしくいきなり/、/var、/usrをmountできて一番楽なんだけどなぁ...(恨めしい)

        親コメント
      • by brake-handle (5065) on 2002年08月27日 21時46分 (#154048)

        crunchで残る問題として、crunched binary全体をaddress spaceにmapしなければならないことがあります。crunchが大きくなれば必要なpage数も増えます。中には実際には実行されないにもかかわらずmapされてしまうpageもあるでしょう。

        こんな時にshared objectが使えれば、実行しないtext、読まないdataには一切pageを使う必要がありません。pmapを初めとするvm metadataを切り詰めた状態でも動くものができる可能性があります。

        親コメント
      • by Anonymous Coward
        どうせ /bin と /usr/bin も二箇所だ。気にするな。
    • by Anonymous Coward
      普通 busybox 使わない?
  • by Anonymous Coward on 2002年08月27日 20時44分 (#154001)
    容量もメリットなのでしょうが、基本的には/bin/*や/sbin/*から
    dlopen()を呼べるようにする、というのが目的かと。

    今のままではPAMやlocaleのサポートに無理があります。

    デメリットとしては、遅くなることと、なんとなくイヤ (笑) と
    いうのがあります。前者は遅いプラットフォームを多数抱える
    NetBSDではかなり辛いものがあります。

    ちなみにld.soやlibc.soが壊れたときのために、/rescue/*に
    いちぶ実行ファイルがcrunched binaryとして用意されます。
    • デメリットとしては、/lib が増えるので管理の手間が増える、
      というのもあります。/ パーティションを太らせないためには
      /lib をクリーンアップする必要があるので、開発者には
      ちょっとだけ負担がかかります。
      # cron で古いライブラリを /usr へ移動させればいいだけだが。
  • by Anonymous Coward on 2002年08月27日 23時57分 (#154149)
    ファイルサイズの節約。Luke Mewburnが測定した結果によると、/binおよび/sbinのサイズが15.9MBから9.2MBに減少、約4割減となった(1.6_BETA3/i386)。
    Lukeさんの補足 [netbsd.org]で15.9MBから6.2MBになったと書いていると思いますよ.6割減です.半分以下とは驚いた.試みは面白いけど一両日中に変更は急すぎる気がする.そのせいかMLの流通量が多すぎて辛いです.
    • by Anonymous Coward
      本来この手の議論はtech-*@netbsd.orgで行うのが通例で、この件についても実際かなり前に議論されました。commit前にアナウンスする必要すらなかったんじゃないかな。

      # とはいえ結論を覚えていない:)

      現在のcurrent-usersのメールは当時の蒸し返しと理解の足りない一部の人による感情論とであり、読む必要はありません。
  • by Digitune (119) on 2002年08月28日 9時23分 (#154360) ホームページ 日記
    最初、「NetBSDが全てのexecutableをsymbolic linkに」と読み違え、Debian の alternatives みたいな感じかなーその意図はなんだろなーとしばらく考えてしまいました。
    --
    Only Jav^Hpanese available :-)
  • by Anonymous Coward on 2002年08月27日 22時37分 (#154079)
    コードを共有すれば、必要な容量が減るのは理解できるのですが、
    どうせ、static版のバイナリを /rescue に置くぐらいなら
    そのまま今まで通り /sbin に static版のものを
    置いておけば良いような?
    • by Anonymous Coward on 2002年08月27日 23時23分 (#154120)
      /sbin にあるコマンドは、nsswitch を参照するものが多いので、
      動的にロードする nsswitch モジュールを提供しようとした
      時に、dynamic でないと困ります。
      親コメント
      • 要するに、 容量を減らす目的で dynamic にした訳じゃないのですね。

        # 最初のタレコミで 先入観を植え付けられてしまった。
        • そうなんですな。

          lukem のアナウンスもこのタレコミも容量削減が目的のように読めてしまうけど、ほんとは dlopen() を使えるようにするのが目的なわけで。current-users がヒートしたのも、lukem のアナウンスでの説明不足が原因じゃないかな。

          • FreeBSD の /bin/sh が NetBSD とほとんど同じ(ashベース)なのにだいぶでかいのは、(~ の展開のために) NIS/YP 部分も静的リンクしているせいだったりする。
typodupeerror

弘法筆を選ばず、アレゲはキーボードを選ぶ -- アレゲ研究家

読み込み中...