コンピュータ科学において、動的ソフトウェア更新(DSU )は、プログラムの実行中にアップデートを行う研究分野です。DSUは現在、産業界で広く利用されているわけではありません。しかし、研究者たちはDSUを実現するための様々なシステムや技術を開発してきました。これらのシステムは、実際のプログラムでテストされるのが一般的です。
現在のオペレーティングシステムやプログラミング言語は、一般的にDSU(動的更新)を念頭に置いて設計されていません。そのため、DSUの実装では、既存のツールを利用するか、専用のコンパイラを実装するのが一般的です。これらのコンパイラは元のプログラムのセマンティクスを保持しつつ、ソースコードまたはオブジェクトコードに計測器を挿入して、動的に更新可能なプログラムを生成します。研究者は、DSU対応のプログラムと元のプログラムを比較し、安全性とパフォーマンスのオーバーヘッドを評価します。
実行中のプログラムはタプルと考えることができる、 どこ現在のプログラムの状態と現在のプログラムコードです。動的なソフトウェア更新システムは、実行中のプログラムを変換します。新しいバージョンへそのためには、状態を表現に変換する必要がある。期待される。これには状態変換関数が必要である。したがって、DSUはプログラムを変換する。に更新は、実行中のプログラムがポイントタプルに還元できるそれは、プログラムの新しいバージョンの開始点から到達可能であり、[ 1 ]
プログラム内で動的更新が発生する箇所は、更新ポイントと呼ばれます。既存のDSU実装では、更新ポイントの扱い方が大きく異なります。UpStareやPoLUSなどのシステムでは、実行中のどの時点でも更新が発生する可能性があります。Ginsengのコンパイラは、更新ポイントに適した場所を推測しようとしますが、プログラマが指定した更新ポイントを使用することもできます。KitsuneとEkidenでは、開発者がすべての更新ポイントを手動で指定し、名前を付ける必要があります。
更新システムは、サポートするプログラム変更の種類が異なります。たとえば、Ksplice は関数内のコード変更のみをサポートし、状態表現の変更はサポートしません。これは、Ksplice が一般的な更新ではなく、主にセキュリティ変更を対象としているためです。一方、Ekiden は、異なるプログラミング言語で書かれたプログラムであっても、実行可能な他のプログラムにプログラムを更新できます。システム設計者は、更新の範囲を制限することで、パフォーマンスや安全性に関する貴重な保証を得ることができます。たとえば、更新の安全性チェックは、その安全性チェックに合格した更新に更新の範囲を制限します。コードと状態を変換するために使用されるメカニズムは、システムがサポートする更新の種類に影響を与えます。
DSUシステムはツールとして、開発者にとっての使いやすさや分かりやすさという観点からも評価できます。Ginsengなどの多くのDSUシステムでは、プログラムが様々な静的解析に合格する必要があります。これらの解析はDSUにとって価値のあるプログラムの特性を証明するものですが、本質的に高度で理解しにくいものです。静的解析を使用しないDSUシステムでは、専用コンパイラが必要になる場合があります。中には、静的解析も専用コンパイラも必要としないDSUシステムもあります。
DSUシステムによって更新されるプログラムは、ターゲットプログラムと呼ばれます。DSUシステムに関する学術論文では、ケーススタディとして複数のターゲットプログラムが取り上げられるのが一般的です。vsftpd 、OpenSSH、PostgreSQL、Tor、Apache、GNU Zebra 、 memcached 、 Redisなどは、様々なシステムにおける動的更新のターゲットです。動的更新を念頭に置いて開発されたプログラムは少ないため、既存のプログラムを改修することは、DSUシステムの実用性を評価する上で有効な手段となります。
動的更新によって解決される問題領域は、他のいくつかの問題の交点と考えることができます。例としては、チェックポイント、動的リンク、永続化などが挙げられます。例えば、ディスク上のファイル形式の以前のバージョンとの下位互換性が必要なデータベースは、動的更新システムに求められるのと同じタイプの状態変換を実現する必要があります。同様に、プラグインアーキテクチャを持つプログラムは、実行時に新しいコードをロードして実行できる必要があります。
同様の手法は、動的デッドコード除去の目的でも使用されることがあり、ロード時または実行時に条件付きでデッドコードまたは到達不能なコードを削除し、残りのコードを再結合してメモリ使用量を最小限に抑えたり、速度を向上させたりします。[ 2 ] [ 3 ]
動的なソフトウェア更新の最も初期の先駆けは、冗長システムです。冗長環境では、メインシステムに障害が発生した場合にアクティブな計算処理を引き継ぐための予備システムが存在します。これらのシステムは、メインマシンとホットスペアで構成されています。ホットスペアには、プライマリシステムのチェックポイントが定期的に書き込まれます。障害が発生した場合、ホットスペアが処理を引き継ぎ、メインマシンが新しいホットスペアになります。このパターンは更新にも一般化できます。更新が発生すると、ホットスペアが起動し、メインシステムが更新され、更新されたシステムが制御を再開します。
最も初期の真の動的ソフトウェア更新システムは、DYMOS(Dynamic Modification System)です。 [ 4 ] 1983年にInsup Leeの博士論文で発表されたDYMOSは、対話型ユーザーインターフェース、 Modulaバリアントのコンパイラとランタイム、およびソースコードにアクセスできる完全に統合されたシステムでした。これにより、DYMOSは更新を既存のプログラムに対して型チェックすることができました。
DSUシステムは、実行中のプログラムに新しいコードをロードし、既存の状態を新しいコードが理解できる形式に変換する必要があります。DSUの多くの利用事例は時間的制約が厳しいため(例えば、稼働中の脆弱なシステムにセキュリティ修正を適用する場合など)、DSUシステムは十分なアップデート提供時間を確保する必要があります。また、一部のDSUシステムは、アップデートを適用する前にその安全性を確認しようと試みます。
これらの問題には、唯一の標準的な解決策はありません。一般的に、ある問題領域で優れた性能を発揮するDSUシステムは、他の問題領域とのトレードオフを伴います。たとえば、動的更新の経験的テストでは、更新ポイントの数を増やすと、安全でない更新の数が増えることが示されています。[ 5 ]
ほとんどの DSU システムでは、更新のコード単位としてサブルーチンを使用しますが、新しい DSU システムではプログラム全体の更新が実装されています。 [ 6 ] [ 7 ]
対象プログラムが仮想マシン言語で実装されている場合、最新の仮想マシンはDSU(主にデバッグ)以外の用途でもランタイムロードをサポートしているため、VMは既存のインフラストラクチャを使用して新しいコードをロードできます。HotSpot JVMはランタイムコードロードをサポートしており、 Java(プログラミング言語)を対象とするDSUシステムはこの機能を利用できます。
CやC++などのネイティブ言語では、DSUシステムはプログラムに間接参照を挿入する専用コンパイラを使用できます。更新時には、この間接参照は最新バージョンを指すように更新されます。DSUシステムがこれらの間接参照を静的に挿入するコンパイラを使用しない場合、バイナリ書き換えによって実行時に挿入します。バイナリ書き換えとは、実行中のネイティブプログラムのメモリイメージに低レベルのコードを書き込んで関数をリダイレクトするプロセスです。これにはプログラムの静的解析は必要ありませんが、プラットフォームに大きく依存します。
EkidenとKitsuneは、 fork-execまたは動的ロードのいずれかによってまったく新しいプログラムを開始することにより、新しいプログラムコードをロードします。既存のプログラムの状態は、新しいプログラム空間に転送されます。[ 6 ] [ 7 ]
アップデート時には、プログラムの状態を元の表現から新しいバージョンの表現に変換する必要があります。これを状態変換と呼びます。状態オブジェクトまたはオブジェクト群を変換する関数は、トランスフォーマー関数または状態トランスフォーマーと呼ばれます。
DSUシステムは、トランスフォーマー関数を自動的に合成しようとする場合と、開発者が手動で入力する必要がある場合がある。一部のシステムはこれらのアプローチを組み合わせ、トランスフォーマーの一部の要素を推論しつつ、他の要素については開発者の入力を必要とする。
これらの変換関数は、旧バージョンの状態がアクセスされるたびに遅延的にプログラム状態に適用することも、更新時にすべての状態を変換する即時的に適用することもできます。遅延変換では、更新が定数時間で完了することが保証されますが、オブジェクトへのアクセスに定常状態のオーバーヘッドが発生します。即時変換では、更新時にコストが増大し、すべての変換関数が実行されている間、システムが停止する必要があります。しかし、即時変換では、コンパイラが状態アクセスを完全に最適化できるため、遅延変換に伴う定常状態のオーバーヘッドを回避できます。
ほとんどのDSUシステムは、アップデートの安全性を確保しようと試みています。最も一般的な安全性チェックは型安全性であり、アップデートによって新しいコードが古い状態表現上で動作したり、その逆が行われたりしない場合に、アップデートは安全であるとみなされます。
型の安全性は、通常、アクティブ性安全性またはコンフリー性安全性のいずれかを示すことで確認されます。プログラムは、更新時にコールスタック上に更新された関数が存在しない場合、アクティブ性安全性があるとみなされます。これは、制御がデータの新しい表現にアクセスする古いコードに戻ることが決してないため、安全性が証明されることを意味します。
Cons-Freenessは、型安全性を証明するもう 1 つの方法です。コードの一部が、型表現の知識を必要とする方法で特定の型の状態にアクセスしない場合、そのコードは安全であるとみなされます。このコードは、抽象的に状態にアクセスすることはできますが、具体的に状態にアクセスしないと言えます。コードの任意の部分にあるすべての型についてcons-freenessを証明または反証することが可能であり、DSU システム Ginseng はこれを使用して型安全性を証明しています。[ 8 ] [ 9 ]関数がcons-free であることが証明されれば、古い表現を使用して状態にアクセスしても型エラーが発生しないため、スタック上で実行されていても更新できます。
Hayden らによる保守性および能動性の安全性に関する実証的分析によると、どちらの手法もほとんどの正しい更新を可能にし、ほとんどの誤った更新を拒否します。しかし、更新ポイントを手動で選択すると、更新エラーはゼロになり、頻繁な更新も可能になります。[ 5 ]
DYMOSは、最初に提案されたDSUシステムであるという点で注目に値します。DYMOSは、 Modulaの派生言語で記述されたプログラムのための完全に統合された環境で構成されており、 REPLと同様に、コマンドインタープリタ、ソースコード、コンパイラ、およびランタイム環境にアクセスできます。DYMOSでは、更新は対話型環境でユーザーがコマンドを実行することによって開始されます。このコマンドには、更新が発生するタイミングを指定するディレクティブが含まれており、これはwhen条件と呼ばれます。DYMOSが利用できる情報により、実行中のターゲットプログラムに関して更新の型安全性を強制することができます。[ 4 ]
KspliceはLinux カーネルのみを対象とする DSU システムであり、オペレーティングシステムのカーネルを対象プログラムとしてサポートする特殊な DSU システムの 1 つです。Ksplice はソースレベルの差分を使用して、Linux カーネルの現在のバージョンと更新されたバージョンの間の変更を特定し、バイナリ書き換えを使用して変更を実行中のカーネルに挿入します。[ 10 ] Ksplice は、元の開発者によって設立された商用ベンチャーである Ksplice Inc. によって維持されていましたが、2011 年 7 月にOracle Corporationに買収されました。 [ 11 ] Ksplice は商用ベースで使用され、Oracle Linuxディストリビューションでのみ使用されます。[ 12 ]
SUSE はライブ カーネル パッチのオープンソース代替としてkGraft を開発し、 Red Hat も同様にkpatch を開発しました。どちらも、ftraceによって確立されたライブ パッチ メカニズムに依存しながら、実行中の Linux カーネルに機能レベルの変更を適用できます。kGraft と kpatch の主な違いは、ホット パッチの適用中に更新されたコード セクションの実行時一貫性を確保する方法です。kGraft と kpatch はそれぞれ 2014 年 4 月と 2014 年 5 月にLinux カーネル メインラインへの組み込みのために提出され[ 13 ] [ 14 ]、ライブ パッチの最小限の基盤は、2015 年 4 月 12 日にリリースされたカーネル バージョン 4.0 で Linux カーネル メインラインに統合されました[ 15 ]。
2015年4月以降、kpatchとkGraftをLinuxカーネルのメインラインが提供する共通のライブパッチコアに移植する作業が継続的に行われています。しかし、関数のオリジナルバージョンとパッチ適用バージョン間の安全な移行に必要な関数レベルの一貫性メカニズムの実装は、適切なスタックフレームを持たないアセンブリコードを含む状況ではLinuxカーネルが提供するコールスタックが信頼できない可能性があるため、遅れています。その結果、2015年9月現在、移植作業は継続中です。 カーネルのコールスタックの信頼性を向上させるため、カーネルのコンパイル時オブジェクトファイルをチェックし、コールスタックが常に維持されることを保証することを目的とした、特殊な健全性チェックスタックツールユーザースペースユーティリティも開発されました。また、カーネルのoopsメッセージの一部として、より信頼性の高いコールスタックを実現する可能性も開きます。[ 16 ] [ 17 ]
Ginsengは汎用的なDSUシステムです。これはcons-freeness安全技術を採用した唯一のDSUシステムであり、スタック上で稼働中の関数が更新対象の型に具体的なアクセスを行わない限り、関数を更新することができます。
Ginsengは、 OCamlのC中間言語フレームワークを使用して記述されたソース間コンパイラとして実装されています。このコンパイラは、すべての関数呼び出しと型アクセスに間接参照を挿入し、プログラム実行全体に定数時間のオーバーヘッドを課すという代償を伴いながら、Ginsengが状態を遅延変換できるようにします。[ 9 ] Ginsengのコンパイラは、初期プログラム全体と動的パッチのcons-freenessプロパティを証明します。
Ginseng の後のバージョンでは、トランザクション安全性の概念もサポートされています。これにより、開発者は関数呼び出しのシーケンスを論理単位として注釈付けすることができ、アクティブ性安全性やcons-freeness安全性では検出できない方法で更新がプログラムのセマンティクスに違反するのを防ぐことができます。たとえば、 Ginseng の開発者が調査したOpenSSHの 2 つのバージョンでは、重要なユーザー検証コードが、順番に呼び出される 2 つの関数間で移動されていました。最初の関数の最初のバージョンが実行され、更新が発生し、2 番目の関数の新しいバージョンが実行されると、検証は決して実行されません。このセクションをトランザクションとしてマークすることで、更新によって検証が妨げられないことが保証されます。[ 18 ]
UpStareは、スタック再構築という独自の更新メカニズムを使用するDSUシステムです。UpStareでプログラムを更新するには、開発者は可能なスタックフレーム間のマッピングを指定します。UpStareはこのマッピングを使用して、任意の時点で、任意の数のスレッドとスタック上で実行中の任意の関数を使用して、プログラムを即座に更新できます。[ 19 ]
PoLUSはC言語用のバイナリ書き換えDSUシステムです。未変更のプログラムを実行中の任意の時点で更新できます。関数を更新するには、対象関数のプレリュードを書き換えて新しい関数にリダイレクトし、これらのリダイレクトを複数のバージョンにわたって連鎖させます。これにより、更新されていない関数の定常状態のオーバーヘッドを回避できます。[ 20 ]
Katanaは、ユーザーモードELFバイナリに対して、限定的な動的更新機能(Kspliceとその派生版と同様)を提供する研究用システムです。Katanaのパッチ適用モデルはELFオブジェクトのレベルで動作するため、コンパイル対象がELFである限り、言語に依存しないという特長があります。
EkidenとKitsuneは、 C言語で書かれたプログラムに対して状態転送方式のDSUを実装する単一のDSUシステムの2つの派生版です。EkidenとKitsuneは、単一プログラム内の関数を更新するのではなく、プログラム全体にわたって更新を行い、2つの実行間で必要な状態を転送します。Ekidenは、UNIXのfork-execイディオムを使用して新しいプログラムを開始し、対象プログラムの状態をシリアル化して転送することでこれを実現しますが、Kitsuneは動的リンクを使用して「インプレース」で状態転送を実行します。KitsuneはEkidenのコードベースから派生しており、Ekidenの後のバージョンとみなすことができます。
EkidenとKitsuneは、専用のランタイムやコンパイラではなく、主にアプリケーションレベルのライブラリとして実装されている点でも注目に値します。そのため、EkidenやKitsuneを使用するには、アプリケーション開発者は転送する状態を手動でマークし、プログラム内で更新が発生する箇所を手動で選択する必要があります。このプロセスを容易にするために、Kitsuneには状態変換器を記述するためのドメイン固有言語を実装した専用コンパイラが含まれています。[ 6 ] [ 7 ]
Erlangは動的ソフトウェア更新をサポートしていますが、これは一般的に「ホットコードローディング」と呼ばれています。Erlangは更新に関して安全性を保証する必要はありませんが、Erlangの文化では、開発者は更新によって発生する型エラーを適切に処理できるような防御的なスタイルで記述することが推奨されています。
Pymoult は、Python で書かれた動的更新のためのプロトタイピング プラットフォームです。他のシステムから多くのテクニックを集め、それらを組み合わせて構成することができます。このプラットフォームの目的は、開発者がニーズに最も適した更新テクニックを選択できるようにすることです。たとえば、Ginseng のように状態の遅延更新と、Kitsune や Ekiden のようにアプリケーションのコード全体を変更することを組み合わせることができます。[ 21 ] [ 22 ]
Microsoft は、Microsoft Visual C++ 用の内部パッチ技術を利用しており、パッチの機能的正確性を維持しながら個々の C++ 関数にパッチを適用できます。現在知られているアプリケーションは、Azure SQL Database の SQL Server です。[ 23 ]
{{cite journal}}:ジャーナルを引用するには|journal=(ヘルプ)