日本ソフトウェア科学会第 37 回大会 (2020 年度) 講演論文集

動的 OS 切り替えを目的とした FreeBSD におけるLinux 互換プロセスのマイグレーション機構
松原 克弥

髙川 雄平

これまでのコンピュータ技術進歩の過程において，基盤ソフトウェアであるオペレーティングシステム（OS）の研究開発が盛んに行われ，数多くの OS 実装が利用可能となった．デスクトップ PC やスマートフォン，エンタープラ
イズサーバなどの一部のプラットフォーム向けでは，Windows や Linux などの少数の OS が寡占状態にあるが，すべてのシステムにおいて特定の OS が独占して採用されることはなく，現在でも，システムの目的や用途，プラットフォームの特性などに応じて複数の OS を使い分けている．著者らは，特性の異なる複数の OS を状況の変化に応じて動的に切り替えることで，OS 上で稼働するサービスの負荷耐性や性能の改善を試みる手法を提案している．本論
文では，Linux と FreeBSD を対象として，サービス稼働中にそのシステム基盤である OS の動的な切り替えを可能とすることを目的として，FreeBSD における Linux 互換プロセスのマイグレーション機構の実現手法についてまと
める．Linux におけるプロセスマイグレーション機構の標準ツールである CRIU とのチェックポイントデータの相互互換性を維持することで，Linux と FreeBSD 間で同一のプロセスをマイグレーションする仕組みを実現する．本実現法では，FreeBSD カーネルと Linux カーネルの OS 機能の違いだけでなく，内部構造やインタフェース仕様の違いにも着目し，CRIU の各機能と同等の機能を FreeBSD 上で実現する際の課題や実装の詳細について解説する．

In the process of technological progress of the computer, research and development of the operating system(OS), which is the primary software, has been actively carried out, and several OS implementations havebecome available in use. Although a few operating systems, such as Windows and Linux, are in an oligopoly
for some platforms, such as desktop PCs, smartphones, and enterprise servers, no one OS has a monopoly for
all systems. Even today, each of the existing multiple OSes is selectively used in diﬀerent ways, dependingon the purpose and platform characteristics of the target system. The authors propose a method to improve
the load tolerance and performance of services running on an OS by dynamically switching between multiple
OSes with diﬀerent characteristics according to the changing situation. In this paper, we summarize theimplementation of a Linux-compatible migration mechanism for Linux and FreeBSD to enable the dynamic
switching of the operating system on the system’s infrastructure during the service operation. By maintaining the mutual compatibility of checkpoint data with CRIU, the standard tool for process migration
mechanism in Linux, we implement a mechanism for migration of the same process between Linux and
FreeBSD. This article focuses not only on the diﬀerences between the functions of the FreeBSD and Linuxkernels but also on the diﬀerences in their internal structures and interface speciﬁcations. It explains thechallenges and techniques for implementing the same functions as those of the CRIU tool on FreeBSD.

サーバを追加投入するスケールアウトや，より高性能

1 はじめになハードウェアへ置き換えるスケールアップによりスマートフォンの普及や IoT の活用拡大にともな

対応することが一般的となっている．一方，スケール

うインターネットユーザの増大に合わせて，Web サー

アウトやスケールアップには，ハードウェアの購入やビス基盤に対するアクセス性能と可用性への要求が買い替え，さらに構築というコストがかかり，オンプ

厳しくなっている．商用サービスでは，負荷に応じてレミスのサーバや小規模な Web サービス基盤では，これらの対応を行うことが難しい場合がある．

A Mechanism to Migrate Linux-compatible Processes
on FreeBSD for Dynamic OS Switching
Katsuya Matsubara, Yuhei Takagawa, 公立はこだて未来大学, Future University Hakodate.

著者らは，ネットワーク通信など同様の機能が利用可能な複数の OS の間でも，その設計方針や実装の違いにより，性能特性が異なる可能性があることに着目

ために，FreeBSD で対応する Linux 互換プロセスを• 状況に応じた可用性と応答性能のバランス＃ ：Server＃

負荷耐性を優先LinuxA

FreeBSD

B

C対象としたマイグレーション機構を実装する．Linuxのプロセスマイグレーションにおける標準ツールである CRIU を用いて作成したプロセスのチェックポイ

応答性能を優先

ントを，FreeBSD 上の Linux 互換プロセスとして，その実行状態をレストアする．本論文では，主にプロ• OSの脆弱性をつく攻撃の回避

セスマイグレーション機構の実装にフォーカスして，

FreeBSD
B

FreeBSD カーネルと Linux カーネルが提供する OS

Linux

機能の違いだけでなく，内部構造やインタフェース仕Linuxの脆弱性を
ついた攻撃

z

A

OSセキュリティ
更新が完了するまでサーバを退避様の違いにも着目し，Linux CRIU の各機能と同等の機能を FreeBSD 上で実現する際の課題とそれに対処

図1

動的 OS 切り替えのユースケース

した実装の詳細を解説する．
以降，第 2 章では，実システムにおける動的 OS

した．デスクトップ PC やスマートフォン，エンター

切り替えの実現可能性を明らかにするために，稼働

プライズサーバなど，Windows や Linux などのいく中の Web サーバを対象とした可用性向上の評価実

つかの OS で寡占状態にあるプラットフォームも存験結果について示す．第 3 章では，プロセスマイグ

在するが，特定の OS が独占しているプラットフォー

レーションに関する先行技術と関連研究について紹

ムは存在せず，現在でも，システムの目的や用途，プ介する．第 4 章では，異種 OS 間のプロセスマイグ

ラットフォームの特性などに応じて複数の OS を使いレーションを実現する上での技術的課題をあげつつ，分けている現状がある．そこで，本研究では，特性のLinux-FreeBSD 間のプロセスマイグレーション実現

異なる複数の OS を状況に合わせて動的に切り替える

へのアプローチ，および，FreeBSD 上での Linux 互

ことで，OS 上で稼働するサービスの負荷耐性や性能換プロセスマイグレーション機構の実装詳細についの改善を試みる手法を提案している [6]．図 1 に示すて述べる．最後に，第 5 章で，まとめと今後の課題にユースケースのように，システム稼働中の動的な OS

ついて述べる．

切り替えが可能となることで，OS 上で実現されているサービスの可用性向上に効果的なソリューション

2 動的 OS 切り替えのフィジビリティ評価が実現可能となる．前者のユースケースでは，OS の著者らの先行研究 [6] において，動的 OS 切り替え

ネットワーク性能特性の違いを活用することで，低負を用いた Web サービスの可用性向上に関する実現可荷時の応答性能のメリットを享受しつつ，高負荷時に能性について，実験を用いた評価を行った．本章では負荷耐性の高い OS へ動的に切り替えることで，処は，動的 OS 切り替えの有用性を明らかにするため理性能と可用性のバランスをとることができる．後者に，本評価結果の要約を示す．

のユースケースでは，OS 依存の脆弱性が発覚してシLinux と FreeBSD のそれぞれの OS 環境上で動作

ステムを更新する必要がある場合に，脆弱性のない別する Web サーバ Nginx に対して Apache Benchmark

OS に動作中のサービスを移行させることで可用性をを用いてアクセス負荷をかけたときの性能について維持できる．

測定した．表 1 に示す仕様の PC 2 台のうち，1 台

本研究では，Linux と FreeBSD を対象として，サーの PC で Apache Benchmark を実行し，ネットワー

ビス稼働中の状況に応じた複数 OS の動的な切り替え

クに接続されたもう 1 台の PC で FreeBSD またはを実現するために，両 OS 間で相互運用できるプロセ

Linuxw 上で Nginx を稼働させた．Linux カーネル

スマイグレーションを実現する．特に，Linux 上で動と FreeBSD カーネル，Nginx サーバは，それぞれ表

作中のプロセスを FreeBSD へ移送して実行継続する

2，表 3，表 4 に示す設定を行った．また，Apache

140

表1

実験環境

CPU

Intel Core-i3 2.4GHz

100

RAM

4GB

80

Disk

SATA 5400RPM HDD

NICIntel 82579V Gigabit Ethernet

所要時間(s)

120

60
40

CentOS 7.7-1908 (Linux kernel: 3.10)

OS

20
0
1

2

3

4

5

6

7

8

9 10 11 12 13 14 15 16 17 18 19 20

FreeBSD 13.0-CURRENTWeb Server

Nginx v1.16

Client App.

ApacheBench v2.3

同時接続レベル(x1000)Linux

FreeBSDOS switching

表2
図2

Apache Benchmark における 100 万リクエストの処理に要した時間

ulimit open files

113958

net.core.somaxconn

20000

net.ipv4.tcp keepalive time

7200
1

net.ipv4.tcp tw reuse

3500
3000
失敗したリクエスト数(req)Linux カーネルのパラメータ設定値

2500

net.ipv4.ip local port range

10000 65535

net.ipv4.tcp max syn backlog

20000

2000

表3

1500
1000
500

FreeBSD カーネルのパラメータ設定値

ulimit open files

113958kern.ipc.maxsockets

126627kern.ipc.soacceptqueue

20000

0
1

2

3

4

5

6

7

8

9 10 11 12 13 14 15 16 17 18 19 20

同時接続レベル(x1000)Linux

FreeBSDOS switching

表4

Nginx の設定

worker processes
図3

Apache Benchmark 実行時における同時接続レベル別接続エラー発生数

Benchmark は，Web サーバとの接続エラーが発生しworker connections

1
20000

sendfile

oﬀ

keepalive timeout

65

backlog

65535ても実行を中断しないように設定した．
図 2 は，Apache Benchmark から送信した全リクが FreeBSD よりも速いことが確認できる．

エストに対するレスポンスを受信するまでに要した所

図 3 は，同時接続数レベルを変化させたときに，レ

要時間を測定した．横軸は，Apache Benchmark でスポンスを正しく受信できずに完了できなかったリク

指定した同時接続数の目標値（以下，同時接続数レ

エストの数を示している．Linux の結果では，同時実ベル）を示し，縦軸は，全 20 万リクエストを送信し行レベルが 6000 を超えると，一部のリクエストが送信て，それらに対するレスポンスをすべて受信するのにに失敗していることがわかる．一方，FreeBSD では，要した所要時間である．100 万リクエストの総処理時

同時実行レベルが変化しても，Apache Benchmark

間について Linux 上と FreeBSD 上の結果を比較するが送信したすべてのリクエストを処理できている．

と，Linux の一部の結果で応答時間に揺れが生じてい前述の予備実験結果から，Linux と FreeBSD では，るが，すべての同時実行レベルにおいて Linux の方

ネットワーク通信性能に関して異なる特性を持っていることが確認できた．FreeBSD のネットワーク機能

特徴は，プロセスマイグレーションに必要な機能の多は，同時接続数の増加などの高負荷状態に対して耐性

くをユーザ空間で実装することで，OS カーネルへのがある．一方，Linux のネットワーク機能は高負荷耐追加変更を最小限にしている点である．ネットワー

性という点で FreeBSD に劣る部分があるが，処理性

ク通信状況やファイルアクセス状態など OS カーネル能の面では FreeBSD より優れていると判断できる．

内で管理されるプロセス関連情報の取得と復元に必

前述までの Linux と FreeBSD のネットワーク通信要とされるプリミティブな機能のみを OS カーネルに特性を考慮して，Linux から FreeBSD への動的 OS

追加実装している．

切り替えによる Web サーバの性能への影響を計測しLinux では，ユーザ空間で動作するプロセスに対した．Linux 環境上で動作する Nginx プロセスに対して，他のプロセスの内部状態を取得したり変更するて，Apache Benchmark からのリクエスト送信を開ような操作を制限している．CRIU では，パラサイト

始してから 30 秒後にその実行中プロセスのチェックコードと呼ばれる，ptrace システムコールを用いてポイントを作成し，ネットワーク経由で転送した後，他プロセスから任意のプログラムをプロセスのメモ

別の FreeBSD 環境上でその Nginx プロセスの実行

リへ書き込んで実行させる手段を用いることで，ユー状態を復元して Apache Benchmark からのリクエス

ザ空間では外部からの操作が困難な，ファイルアクセ

トを継続受信できるようにした．本測定では，プロセ

ス情報やネットワーク通信などの状態の取得と復元

ス移行時に転送される確立済 TCP コネクション数をを実現している．

最小限に抑えるために，Apache Benchmark におけ

プロセスの実行状態の取得は，ptrace システムコー

る HTTP KeepAlive の使用を無効にし，さらに，プルと procfs 仮想ファイルシステムを用いる．例え

ロセスのチェックポイント開始直前に到着する SYN

ば，プロセス内のコードを実行している CPU レジス

パケットをドロップするパケットフィルタを有効にしタの値は，ptrace システムコールの GETREGS をている．図 2 と図 3 の系列”OS switching”は，Linux

用いて取得できる．CPU 実行状態のレストアでは，から FreeBSD へ OS を切り替えた場合の総所要時間

割り込み処理が呼ばれた際に自動的にセットされると接続エラー発生数である．Linux と FreeBSD の結

rt sigreturn システムコールを利用して，取得したレ果の中間に分布しているこれらの計測結果から，OS

ジスタ値を CPU レジスタへ設定する．プロセスのメ

切り替え前後でそれぞれの稼働 OS に応じた性能特性

モリマップに関する情報は，procfs の maps ファイを享受できており，OS 切り替えによってサーバの可ルから取得する．メモリの内容は，対象プロセス内で用性や性能の特性を動的に変化させることは可能で

vmsplice システムコールと splice システムコールをあることが確認できた．

用いて取得し，プロセス間通信機構であるパイプを用いてプロセス外へ出力する．メモリのレストアは，

3 先行技術mmap システムコールを利用して，メモリ内容を保存

プロセスマイグレーションに関連する既存技術にしたファイルをプロセスのメモリ空間にマップする．

ついて説明する．

CRIU では，メモリとソケットバッファ以外のプロ
セスの実行状態を，標準的なデータ形式のひとつであ3. 1 CRIU (Checkpoint/Restore in Userspace)
Linux におけるプロセスマイグレーションの標準

る Google Protocol Buﬀer [4] 形式で保存する．メモリとソケットバッファの内容は，バイナリ RAW デー
タ形式のまま保存する．

ツールとして知られている CRIU [1] [2] は，実行中のプロセスの状態を保存するチェックポイント機能と，保存したプロセスの実行状態を復元して実行を再開
するレストア機能を実現している．CRIU の最大の

3. 2 FreeBSD VPS (Virtual Private Sys-

表5Linux と FreeBSD における open システムコー

出すことができない場合がある．

ルの差異

FreeBSDFreeBSD の Linux バイナリ互換機能は，Linux ELF

2

5

形式のプログラムコードに含まれるシステムコール

0x200

0x0040に対して，その実行時にシステムコールテーブルのLinux
システムコール番号
パラメータ値 O CREAT の定義を再開しても，移行先のカーネルの機能を正しく呼び

順番変更や引数パラメータの値の変換を行い，対応

tem)

する FreeBSD のシステムコールを利用できるように

FreeBSD VPS [7] は，FreeBSD におけるプロセス

している．Linux バイナリ互換機能は，プロセスのメ

マイグレーション機構のひとつである．FreeBSD Jail

モリへ実行可能ファイルの内容がロードされる際に，の拡張機能として実装されており，VPS インスタンス

Linux ELF 形式であるかどうかを判別する．Linuxと呼ばれるプロセス隔離環境を単位として，FreeBSD

ELF の場合には，対応するプロセス向けの OS カーネ

間でのマイグレーションを実現している．前述のル内のシステムコールテーブルを変更し，Linux 互換

CRIU とは異なり，プロセスマイグレーションに必要用システムコールテーブルに差し替える．プロセスかな機能のほとんどを OS カーネル内で実装している．

ら Linux のシステムコールが実行された際，FreeBSD

FreeBSD VPS におけるプロセス実行状態の取得

カーネル内部に実装された Linux システムコール関数

処理では，ユーザ空間のメモリ内容だけでなく，OSが呼び出され，その関数内で対応する FreeBSD カー

カーネル空間のメモリも取得している．カーネル空ネル機能を呼び出す．また，Linux のシステムコール

間には，プロセスごとのカーネルスタックが存在して引数として渡されるパラメータ値は，OS カーネル内

おり，このカーネルスタックを取得することができで FreeBSD で処理できるパラメータに変換する．

る．CPU の情報は，カーネルスタックの先頭部分に前述した全ての処理が OS カーネル内で行われるた存在する PCB（Process Control Block，プロセス制

め，ユーザ空間のプロセスのメモリ内容は，スタック

御ブロック）を利用する．PCB は，プロセスが待ちを含めて Linux で実行した場合と同じ内容となる．

状態になった場合に，処理が中断されても，続きから再開できるように，CPU レジスタの情報がカーネルによって格納される．

4 Linux-FreeBSD 間プロセスマイグレー
ションの実装プロセスのレストア時は，メモリ内容を復元する際前章で述べたとおり，Linux と FreeBSD のそれぞに合わせて復元されるカーネル空間内の PCB を利用

れには，同一 OS 内のプロセスマイグレーションを実し，実行可能プロセスとして OS スケジューラに登録

現する機能が存在する．また，FreeBSD には，Linuxすることで実行を再開する．

ELF 形式のプログラムを実行するためのバイナリ互換機能が備わっている．しかし，Linux と FreeBSD

3. 3 FreeBSD の Linux バイナリ互換機能の既存プロセスマイグレーション機能はその設計やLinux バイナリ互換機能 [3] [5] は，Linux ELF 形式

実装が大きく異なり，それぞれで作成したプロセスのプログラムファイルを FreeBSD 上で実行できるよ

チェックポイントを相互運用することはできない．

うにする機能である．Linux と FreeBSD の両 OS に本研究では，Linux-FreeBSD 間でのプロセスマイグ

おいて，同等な機能を持つシステムコールが数多くでレーションを実現するために，相互運用可能なプロセ提供されておるが，同じ機能のシステムコールにおいスのチェックポイント／レストア手法を確立する．

ても，システムコール番号や引数パラメータが異なる

Linux-FreeBSD 間で相互運用可能なプロセスマイ

場合がある（表 5 参照）．そのため，本研究が目的とグレーションを実現するアプローチとして，FreeBSD

する異なる OS 間でプロセスに含まれるプログラム

VPS のチェックポイント／レストア機能や入出力形

コードとその実行状態をマイグレーションして実行式に対応するように Linux CRIU を改造する手法と，

Linux CRIU のチェックポイント／レストア機能や

表6

入出力形式に対応するように FreeBSD のプロセスマ

システムコール呼び出し時のレジスタ

レジスタ

イグレーション機構を実現する手法が考えられる．前者の場合，FreeBSD VPS が OS カーネル内で実装されているため，カーネルの内部データ形式に合わせてシステムコール

RAX

番号

RDI

第 1 引数RSI

第 2 引数る可能性がある．後者の場合，CRIU がもつ機能の多RDX

第 3 引数

くがユーザ空間で実装されているため，FreeBSD 上

R10

第 4 引数での実現が比較的容易であると考える．これらの考R8

第 5 引数察から，FreeBSD 上の Linux 互換プロセスを対象と

R9

第 6 引数Linux カーネルや CRIU への大幅な変更を必要とす

して，Linux CRIU と相互運用可能なプロセスマイグ
レーション機構を実装することとした．
以降，FreeBSD 上における Linux 互換プロセスのチェックポイント／レストア実現に必要な機能について，それぞれの技術的課題と実装における解決手法
ptrace(2)の詳細を述べる．
他
プロセス

カーネル

H/W

4. 1 システムコール・インジェクション
write(2)read(2)

外部からプロセスに関連する内部情報を取得した

procfs/mem

memoryり設定・制御できる procfs をもつ Linux と比較して，FreeBSD では外部からプロセスを制御できる範囲により制約されている．本実装では，CRIU におけるパラサイトコードと同様の技術を活用して，対象プロセ

図4

プロセス実行状態復元の概要図

ス自身にプロセスに関する制御を行わせる手段として，システムコール・インジェクション機能を実現し

4. 2. 1 プロセスの初期化た．ptrace システムコールを用いて，システムコール

Linux バイナリ互換機能を利用するプロセスを復を呼び出すための命令である syscall 命令 (0x050f)，

元する場合，復元の実行タイミングに特別な対処を

および，実行後にトレースを再開するためのブレイク必要とする．通常，プロセスを復元する場合，ptrace

ポイントである int3 命令 (0xcccc) を対象プロセスのシステムコールの TRACEME を有効にすることで，空きメモリへ書き込む．さらに，表 6 で示す各レジス

対象プロセスのエントリポイントをフックし復元処

タに対して，システムコール番号と引数を設定する．

理を行う．しかし，Linux バイナリ互換機能を利用するプロセスでは，Linux 互換機能を有効にするための4. 2 プロセス実行状態の移送

初期化処理が必要であるため，プロセスのエントリポ

プロセス実行状態とは，CPU レジスタとメモリのイントは復元処理実行の適切なタイミングではない．

状態である．復元時には，対象プロセスを作成するたLinux 互換初期化処理が完了しているタイミングのめに，fork システムコールと execve システムコール

取得方法として，ブレイクポイントである int3 命令を用いる．図 4 は，CPU レジスタとメモリの状態をを main 関数の開始命令に書き込む．int3 命令により復元する概要図である．

main 関数実行直前のタイミングで制御を取得し，プ
ロセスの状態を復元する．なお，本研究では，main関数の開始命令のアドレスをバイナリ解析を行うこ

4

0

Linux

8

12

15

byte

r13
r14
r12
r10
rbx
r11
r8
rcx
rax
orig̲raxrdi
rsi
cs
eflagsrsp
fs̲base gs̲base
ds
fs
gs

r15
rbp
r9
rdx
rip
ss
es

r15
r13
r11
r9
rdi
rbp
rdx

FreeBSD

r14
r12
r10
r8
rsi
rbx
rcx

r̲trapno r̲fs r̲gs
rax
r̲es r̲dsr̲ripr̲rflags
r̲cs
r̲ss
r̲rsp

r̲err

図5

Linux と FreeBSD のレジスタ構造体

Linux のメンバ変数 orig rax と rax から選択する必要がある．次に実行すべき命令のアドレスを指すプロ
グラムカウンタが示している命令が，syscall 命令 †1であり，汎用レジスタ AX がシステムコール番号ではなく，システムコール返り値を指している場合，シ
ステムコール番号が異なり，正しく実行されず，プロセスが停止してしまうためである．判断はプログラム
カウンタが指す命令からシステムコール実行の前後を判断して，システムコール実行前であれば，Linuxのメンバ変数 orig rax を格納し，システムコール実
行後であれば，Linux のメンバ変数 rax を格納する．
また，OS が異なるでセグメントレジスタをそのまま復元する場合，セグメントのサイズや位置などが変わってしまい，復元後正しく動作しないため，Intelとで取得している．

x86 アーキテクチャでは，レジスタ構造体の情報を復4. 2. 2 CPU レジスタ値の移送元する際に，セグメントレジスタ (cs,ss,es,fs,gs) は，

取得時には，ptrace システムコールの GETREGS

OS がプロセス生成時に割り当てた値をする必要があを用いてレジスタの情報を格納する構造体 (以下，レる．本実装では，取得したセグメントレジスタの値を

ジスタ構造体) を利用する．レジスタ構造体には，汎使用せず，レストア先の OS が割り当てた値をそのま用レジスタ，インデックスレジスタ，セグメントレジ

ま利用する．

スタ，フラグレジスタの各値が格納されている．

4. 2. 3 メモリ内容の移送復元時には，レジスタ構造体に取得したレジスタのCRIU では，vmsplice システムコールや splice シ

情報を格納し，ptrace システムコールの SETREGS

ステムコールを利用することで，パイプ経由でメモを利用する．

リ状態をファイルに保存していたが，FreeBSD には

ABI が異なる Linux と FreeBSD では，ptrace シ

vmsplice システムコールや splice システムコールがステムコールで扱うレジスタ構造体が異なる（図 5 参

存在しないため，CRIU と同様の方式でメモリの取得

照）．メンバ変数の順番の差異，サイズ，汎用レジスタができない．そのため，メモリ状態は，ptrace シス

AX を表すメンバ変数の差異があるため，異なる OS

テムコールのアタッチ時に，procfs の mem ファイルで取得した構造体データを変換する必要がある．一般を読み込むことで取得する．取得するメモリ内容は，的に，汎用レジスタ AX には呼び出すシステムコー

プロセス実行中に値が変更されていく仮想メモリ空ル番号とシステムコール返り値が格納される．Linux間におけるデータ領域やヒープ領域，スタック領域，

では，レジスタ構造体に汎用レジスタ AX を表すメン

mmap システムコールで新しく確保した領域を対象

バ変数として，orig rax と rax が存在する．orig raxとする．プロセスマイグレーションは同じプログラにはシステムコール番号が格納され，rax にはシステ

ムを実行することが前提であるため，テキスト領域やムコール返り値が格納される．一方，FreeBSD では，共有ライブラリは取得する必要がない．ただし，テキ

レジスタ構造体に汎用レジスタ AX を表すメンバ変スト領域内部に含まれるライブラリ関数を参照する

数は rax しか存在せず，システムコール番号とシス

ためのアドレスを保持しているテーブルは，ライブラ

テムコール返り値のどちらかが格納される．

リのロード時に変更されるため，取得しなければなら異種 OS 間プロセスマイグレーションを実現するた
めには，FreeBSD のメンバ変数 rax に格納する値を†1 システムコール実行の割り込みを発生させるアセンブ
ラ命令

0x000000000000

0x000000000000

0x000000000000

テキスト

0x00000000

User
0xC0000000

Kernel

Text

Text

Data

Data
Heap

Heap
Stack
Linux

テキスト

データ

データ

ヒープ

ヒープ
領域復元

領域解放

ライブラリ

Stack

ライブラリ

FreeBSD

スタック

スタック
0x800000000000

図60x800000000000

0x800000000000

Linux と FreeBSD のメモリ領域の差異
図7

メモリレイアウト変更の手順

ない．
これらの領域は，仮想メモリ上に連続しないように

0x000000000

Text

Text

配置されるため，各領域のメモリ内容を取得するため

Data

Data

には，仮想メモリの領域 (以下，メモリマップ) 情報を

Heap

Heap

取得する必要がある．メモリマップ情報は，procfs のUser

map ファイル，あるいは，libprocstat ライブラリを利用することで取得できる．本実装では，既存の構造体として情報を扱える libprocstat ライブラリを利用する．libprocstat ライブラリによって取得できる構造体 kinfo vmentry には，その領域の開始アドレス，
終端アドレス，アクセス権限などが格納されている．

0x800000000

Kernel(4)BSD vDSO Text

(1)vDSO JMP(3)vDSO JMP

Stack

Stack

(2)vDSO Text
Linux上の元プロセス

図8

FreeBSD上の復元プロセス

vDSO の差異

復元の際には，メモリマップ情報をもとに，procfs

ルなどの頻繁に呼び出されるような特定のシステムの mem ファイルを介して，取得したメモリのデータ，コールを高速に実行するためのライブラリである．

ヒープ，スタックの各領域のメモリ状態を書き込む．

図 8 には，Linux と FreeBSD における vDSO の図 6 で示すように，OS が異なるヒープ領域やス

配置に関して示している．vDSO のテキスト領域は，

タック領域，ライブラリの配置アドレスが異なる．こLinux ではカーネル空間内 (2) に配置され，FreeBSDの場合，メモリを復元する際に書き込みを正しく行

ではユーザ空間内 (4) に配置される．(1) の領域は，えず，適切なメモリとして復元することができない．

vDSO のテキスト領域へアクセスするための領域でそこで，本実装では，図 7 で示すように，すでに配あり，カーネル内部に配置されている (2) にアクセス置されているメモリ領域を munmap システムコール

する．そのため，FreeBSD 上で (3) の領域を復元しを用いて解放し，mmap システムコールを用いて再たとしても，カーネル空間を参照しているアドレス

度確保することで，正しいアドレスにメモリ領域が存にはアクセスできないため，実行することはできな

在するようにする．なお，munmap システムコール

い．そこで，本研究では復元した (3) の領域が (4) のと mmap システムコールに関しても，システムコー

vDSO のテキスト領域を指すように変更する．

ルインジェクションを行う必要がある．

4. 2. 4 vDSO への対処

4. 3 ファイルアクセス状態の移送

vDSO(virual dynamic shared object) は，gettime-

プロセスがファイルにアクセスする手段には，open

ofday システムコールや clock gettime システムコー

システムコールを用いてファイルディスクリプタを介する場合と，mmap システムコールを用いて仮想報を取得できる libprocstat ライブラリを利用するこ

メモリ内にマッピングする場合が存在する．

とでファイルに関する情報を取得する．libprocstat

4. 3. 1 mmap システムコールによるファイルア
クセス

ライブラリはプロセスが持つ情報をまとめた構造体のリストを制御するライブラリで，特定のプロセスを

mmap システムコールの場合には，ファイルがメ

PID によって指定することができる．libprocstat ラ

モリにマッピングされ，他のメモリ領域と同様にア

イブラリによって取得できる ﬁlestat 構造体は，ファドレス参照による入出力が可能となる．取得時には，

イルディスクリプタ，ファイルパス，ファイルオフ

4. 2. 3 項で述べた方法と同様に，ファイルの内容をメセットなどを含む．

モリの状態として取得するが，どのファイルディス

また，性能向上のためにファイルの書き込みは，遅クリプタと関連づけられていたかを取得する必要が延書き込み (または，writeback) で行われる．遅延書ある．

き込みでは，write システムコールを用いたとしても，復元する際には，以下のようにメモリ上へのファ

一度 OS のバッファ (ページキャッシュ) に格納されイルマッピングと，4. 2. 3 項で述べたメモリの復元をた後，同時に書込みが行われる．そのため，プロセス行う．

から見た書込みと実際のファイルへの書き込みは異1. 復元すべきフィイルを open システムコールを用いて開く

2. open システムコールのオプションにアクセス
モードやフラグを設定

3. mmap システムコールを用いて，ファイルディ
スクリプタ番号を指定してメモリ上に配置する

4. close システムコールを用いて，open システム
コールで開いたファイルを閉じる

5. procfs の mem ファイルに対して write システ
ムコールでデータを書き込む

4. 3. 2 open システムコールによるファイルアク
セスなる場合がある．sync システムコールを用いること
で，バッファ上のデータをファイルに書き込む．
復元時には，システムコールインジェクションを行
い，以下の手順で復元する．

1. 復元すべきファイルを open システムコールを用いて開く

2. open システムコールのオプションにアクセス
モードやフラグを設定

3. dup2/close システムコールを用いて，ファイル
ディスクリプタ番号を変更

4. lseek システムコールを用いて，ファイルオフ
セットの位置を変更

open システムコールの場合には，ファイルに対して，ファイルディスクリプタと呼ばれる番号が振られ

4. 4 ネットワーク通信状態の移送

る．read システムコールや write システムコールな

ネットワーク通信状態である TCP コネクションのどのファイルを扱うシステムコールは全てファイル

状態を復元することを TCP repair と呼ぶ．TCP コ

ディスクリプタを利用して読み込みや書き込みなど

ネクションの状態とは，送信キューのデータ，受信が行われる．プロセスマイグレーションに必要な情

キューのデータやシーケンス番号などを指す．TCP

報は，オープンしているファイルのパス名，ファイル

repair は Linux Kernel 3.6 に組み込まれた機能であディスクリプタ，ファイルのシーク位置 (ファイルオ

る．本研究では FreeBSD カーネルに TCP repair をフセット)，オープンモードやフラグである．ファイ

移植するために，FreeBSD カーネルのネットワーク

ルに関する情報は，devfs の fd ディレクトリから取得に関する処理に手を加える．

することができる．しかし，devfs の fd ディレクトリ
はアクセスしたプロセスの情報しか表示しないため，
他のプロセスからファイルアクセス情報を取得することはできない．そこで本実装では，他のプロセスの情

TCP repair を行うためには，以下の要件を満たす必要がある．

TCP repair オプション追加
ネットワークに関する情報を扱う getsockopt シ

ステムコール/setsockopt システムコールを介しことができるデータである．(3) のデータはパケットて TCP コネクションに関するパラメータの取得ロスした際に，TCP の再送制御によって再送されると復元を行えるようにするため

データである．(2) と (4) のデータは通常であれば，送受信キューのデータの取得と反映

ユーザ空間からは復元することのできないデータでマイグレーション後に，送受信中のデータが損失し，正常なデータを送受信できなくなるのを防ぐため
シーケンス番号の取得と反映

ある．

FreeBSD カーネルでは，sendmsg システムコールを使った場合，送信キューにデータがコピーされる．

recvmsg システムコールを使った場合，受信キュー

マイグレーション後に，送受信パケットの位置がからデータがコピーされる．既存のカーネル機能でリセットされ，正常に送受信できなくなるのを防は，送信キューからデータをコピーする手段と受信

ぐため

キューにデータをコピーする手段がない．そのため，接続の維持

setsockopt システムコールに SO REPAIR QUEUE

マイグレーション時に，コネクションが切断さオプションを使うことで，recvmsg システムコールをれ，再接続のために，通信する両者が接続処理を用いて，指定したキューからデータを取得し，sendmsg

再度行わなければならないのを防ぐため

システムコールを用いて，指定したキューにデータを

4. 4. 1 送受信キュー内のデータの移送
Linux では，getsockopt/setsockopt システムコールのオプションに，SO REPAIR，SO REPAIR QUEUE，

SO QUEUE SEQ を追加している．

コピーするようにカーネルを変更する．

4. 4. 2 シーケンス番号の移送
TCP 通信において，シーケンス番号は送受信されたパケットの位置を示すため，シーケンス番号を正SO REPAIR オプションを無効にした場合，従来しく復元できない場合，TCP 通信が正しく行えなくまでの送受信処理と同様に．SO REPAIR オプショ

なる．そのため，シーケンス番号を復元する必要がンを有効にした場合，送受信キューのデータの取得ある．

と反映，シーケンス番号の取得と反映，接続の維持

FreeBSD カーネルでは，シーケンス番号を tcpcbが可能となる．SO REPAIR QUEUE オプションで構造体で管理している．送信キューのシーケンス番

は，取得または復元する対象のキューを送信キュー

号は，メンバ変数 snd nxt，受信キューのシーケンスと受信キューから選択する．SO REPAIR SEQ オプ

番号はメンバ変数 rcv nxt に格納されている．シー

ションでは，シーケンス番号の取得と復元を行う．

ケンス番号の取得と復元を行う setsockopt システ

図 9 に示す番号はプロセスから送信された通信デー

ムコールに SO REPAIR SEQ オプションを追加し，タの各状態を示しており，それぞれ以下の状態を示し

SO REPAIR QUEUE オプションを用いて指定したている．

キューにシーケンス番号を取得，反映できるように

1. ユーザ空間からカーネル空間にコピーされていないデータ

2. カーネル空間にあるが，まだネットワークに送信されていないデータ

3. ネットワークに送信されたが，まだ受信されてないデータ

4. 受信してカーネル空間にあるが，まだユーザ空
間に読まれていないデータ

カーネルを変更する．

4. 4. 3 接続状態の維持・復元
TCP 通信において，ソケットを閉鎖させる場合，3
ウェイハンドシェイクにより，FIN パケットを送信
し切断処理を行い，コネクションが切断されるため，再度通信をするためには接続要求である SYN パケッ
トの送信が必要となる．この場合，クライアントは再接続を見越した実装が予めされていなければならな

5. ユーザ空間のプロセスが受け取ったデータ

い．そのため，ソケット閉鎖時に FIN パケットを送(1) と (5) のデータはユーザ空間で取得し，復元する

信せず，接続要求時に SYN パケットも送信しないよdataMachine A

Machine B

APP

APP

BufferBuffer(1)(5)

KernelKernelSend queue

Receive queue

(2)

(4)

(3)

図9

TCP 通信におけるデータの状態

うにすることで，実際には接続が切断されている状態

本研究のアプローチとしては，復元後最初の評価

でも，クライアント側は接続が切断されていない状態のみを必ず真にするように，条件式 (1) を満たすようとしてレスポンスを待つ状態を保つことができる．

にする．つまり，復元時には SND.WL1 をシーケン

TCP repair が有効になっている場合に，connect

ス番号よりも小さく保つように復元する．SND.WL1

システムコールを SYN パケットを送信しないようにと SND.WL2 は評価直後に正しい値が設定されるた変更し，close システムコールを FIN パケットを送信

め，変更しても問題がない．

しないように変更する．

4. 4. 4 フロー制御関連パラメータの移送

4. 5 イベントハンドラ登録の移送

OS が異なるとネットワーク・プロトコルスタック

イベントハンドラとは，シグナルや I/O などのイベの実装が異なる．この場合，カーネル内部で利用してントがあった際に，カーネルがイベントに応じた処理

いるネットワーク通信のための変数や条件式が異なをプロセスに実行させるものである．例えば，Nginx

るため，変数を正しく復元できず，条件式を満たすこ

では I/O イベントを用いて，HTTP 接続を要求されとができないことがある．条件式を満たすことがでるまでプロセスを待機状態にすることで，プロセスがきなければ，データの送受信に影響がある．特に本論使うリソースを削減する．また，シグナルイベント

文の対象としている Linux から FreeBSD にプロセスを用いて，設定ファイルの更新やログファイルの開

マイグレーションをする際には，フロー制御が行われき直しなどを行う．シグナルイベントは，sigaction

ず，ウィンドウサイズが減少し続け，通信できなくな

システムコールを実行することでカーネルに登録さる可能性がある．FreeBSD 上でウィンドウサイズがれ，I/O イベントは，epoll システムコール群を用い更新されなくなるのは，送信キューのウィンドウの開ることで OS カーネルにイベントを登録する．さら

始位置である SND.WL2 を Linux では利用しておらに，epoll create システムコールで専用のインスタン

ず，取得されないため，適した値を SND.WL2 に代スを作成し，epoll ctl システムコールでイベントを入できないからである (図 10 参照)．

OS カーネルに登録できる．

FreeBSD におけるウィンドウサイズ更新の評価に

本実装では，システムコールインジェクションを用関するフローチャートを表 11 に示す．SND.WL2 は

いて sigaction システムコールや epoll システムコー

利用できないため，条件式 (3)，(4) は偽となり更新

ルをレストア対象のプロセス内で実行させることで，されない．そのため，条件式 (2) が真になる場合は全マイグレーション先の OS カーネルにイベントハンドて更新されない．

ラを再登録する．

LinuxSND.WND

送達済み
送信ウィンドウ

・・・・・・

SND.UNA

ACK

SND.NXT

同一PC内の送受信キュー

FreeBSD
SND.WND

送達済み

送信ウィンドウ

・・・

・・・

SND.WL2ACK
SND.UNA

図 10

SND.NXTLinux と FreeBSD のフロー制御

プロセスのチェックポイント機能，および，Linux 上
SND.WL1 < SEQ

YES

で実行中のプロセスに対して CRIU を使って作成されNO
SND.WL1 == SEQ

YESたチェックポイントを FreeBSD 上でレストアする機NO能の実現に際して，技術的課題と対処手法，FreeBSD

YES

上での実装詳細をとりまとめた．Linux と FreeBSD

SND.WL2 < ACK

間のプロセスマイグレーションを実現するために，NOLinux のプロセス形式を共通形式とし，FreeBSD で

SND.WL2 == ACK

は Linux バイナリ互換機能により Linux プロセスのNO実行を可能にする．マイグレーション技術について

YES
YES
updating
window size

SND.WND < sizeNO

not updating
window size

も Linux の CRIU を標準技術とし，FreeBSD 上で

CRIU ライクなプロセスマイグレーション機構を実現
図 11

ウィンドウサイズ更新のフローチャート

した．ネットワーク通信状態のマイグレーションを可能にするために，TCP repair 機能を FreeBSD に実epoll システムコール群は，Linux にしか存在しな

装した．Linux カーネルで実装されている FreeBSDいシステムコールであるが，FreeBSD の Linux バイの Linux バイナリ互換機能が対応できない Linux とナリ互換機能によって同等のシステムコール機能がFreeBSD の差異については，メモリレイアウトや実現されている t ため，FreeBSD における Linux プ

vDSO，ネットワーク・プロトコルスタックのそれぞ

ロセスのレストアに際して特段の対処は必要ない．

れに対して OS 毎の差異に対処する方法を検討して実装した．

5 おわりに今後の課題として，OS 切り替え契機の判断をより

本論文では，Linux と FreeBSD の間での動的な OS

適応的に行う仕組みの考案がある．第 2 章で示した切り替えを目的として，FreeBSD 上での Linux 互換評価実験では，固定されたタイミングでプロセスマ

イグレーションを行っていた．状況の変化に対して，

参 考 文 献

マイグレーションオーバヘッドも考慮しつつ OS 切

[1] A. Mirkin, A. Kuznetsov and K. Kolyshkin: Containers checkpointing and live migration, Proceedings of the 2008 Ottawa Linux Symposium, Vol. 2,
2008, pp. 85–90.
[2] CRIU: Checkpoint/Restart in Userspace.
[3] Divacky Roman: Linux® emulation in FreeBSD.
[4] Google Inc.: Protocol Buﬀers.
[5] Jim Mock: Chapter 10. Linux Binary Compatibility, https://www.freebsd.org/doc/handbook/linuxemu.html.
[6] Matsubara, K. and Takagawa, Y.: Adaptive OS
Switching for Improving Availability During Web
Traﬃc Surges: A Feasibility Study, Proceedings of
The 8th IEEE Internat. Workshop on Architecture,
Design, Deployment & Management of Networks& Applications (ADMNET 2020), 2020, pp. 1176–
1182.
[7] Ohrhallinger, K. P.: Virtual Private System for
FreeBSD, EuroBSDCon 2010, 2010.
[8] Takagawa, Y. and Matsubara, K.: Yet Another
Container Migration on FreeBSD, AsiaBSDCon
2019 Proceedings, 2019, pp. 97–102.

り替えをすべきかどうかを柔軟に判断する手法を確立する．また，プロセスマイグレーション時のオーバ
ヘッドとなる，チェックポイントしたプロセス情報の転送最適化を行いたい．本実装では，チェックポイン
ト処理によりプロセス状態をファイルに一旦保存した後，ファイルシステム間でネットワークコピーした
後にレストア処理を開始していたが，プレコピーやポストコピー技術を導入することで，プロセスマイグ
レーション時のダウンタイムの削減を試みる．さらに，ソフトウェア流通の単位として近年急速に普及しているコンテナを単位とした Linux-FreeBSD 間マイグレーションの実現がある．コンテナを実現する計算資源の隔離や制限機能について Linux と FreeBSDのそれぞれの対応機能を精査した結果 [8] にもとづいて，Linux-FreeBSD 間のコンテナマイグレーション機構を実現したい．