時間ネームスペースはどのように使用すればよいですか?

時間ネームスペースはどのように使用すればよいですか?

私は次のようにできると思います。

sudo unshare -T bash -c 'date -s "$1" && foobar' sh "$(date -d -1day)"

したがって、foobar残りのシステム時間とは異なるシステム時間が表示されます。ただし、システム時間に対する変更は含まれていないようです。システム全体のシステム時間を変更します。

このLWN記事この名前空間は、私が提供したい目的に合わせて設計されていることを示しているようです。

システム時間を調整するシステム呼び出しは、ルート時間の名前空間の外で呼び出されると、名前空間ごとのオフセットを調整します。

それを見ると、strace date -s ...別の出力が表示されます。

clock_settime(CLOCK_REALTIME, {tv_sec=1619044910, tv_nsec=0}) = 0

ただし、以下をお読みくださいtime_namespaces(7)

これは、clock_gettime(2)、clock_nanosleep(2)、nanosleep(2)、timer_settime(2)、timerfd_settime(2)、/proc/uptime など、これらのクロックを測定するさまざまな API に影響します。

私はそれが言及されたものを見ませんでしたclock_settime(2)。 「含む」という言葉は、これが完全なリストではないかもしれませんが、そうであるかもしれません。

私も理解できません--boottime/ --monotonic。を見るとclock_settime(2)次のようになります。

CLOCK_MONOTONIC単調な時間(POSIXで説明したように)で「過去の未指定の一部点」を示す設定不可能なシステム全体の時計です。 Linuxでは、このポイントは起動後にシステムが実行された時間(秒単位)に対応します。

CLOCK_BOOTTIME (Linux 2.6.39 以降; Linux のみ) CLOCK_MONOTONIC と同じですが設定できないシステム全体の時計ですが、システムが停止した時間も含まれます。

しかし、試してみると変わらないようですuptime

$ uptime -s
2021-04-10 10:30:45
$ sudo unshare -T --boottime 1000000000 uptime -s
2021-04-10 10:30:45
$ sudo unshare -T --monotonic 1000000000 uptime -s
2021-04-10 10:30:45
$ sudo unshare -T --boottime -100000 uptime -s
2021-04-10 10:30:45
$ sudo unshare -T --monotonic -100000 uptime -s
2021-04-10 10:30:45

これは call ではなくstrace uptime読んでいることがわかり、ドキュメントでは上で引用した内容に影響を与えると示していますが call とそのオフセットの影響を受けないようです。/proc/uptimeclock_gettime(2)/proc/uptimeunsharetime_namespaces(7)/proc/uptime

この名前空間はどのように使用すればよいですか?影響を受ける可能性のあるコマンドが見つからないようですunshare --time

ベストアンサー1

あなたの推論には説明が必要な3つのことがあると思います。


最初時間の名前空間共有をオフにすると影響を受けます。子供たち生産その時から呼び出しunshare(2)プロセス自体は影響を受けません。これはPIDネームスペースと多少似ていますが、これまでに見た他のネームスペースタイプとは異なります。ただし、呼び出しプロセス可能まだ新しく作成された時間の名前空間を入力します。これを行うには、CLI用語setns(2)としてnsenter(1)独自に入力する必要があります。

これはunshare -T、実行中のコマンドが実際にそのコマンドを新しく作成された時間名前空間に移動しないことを意味します。指定したコマンドを独自のコマンドではなくサブコマンドとして実行する-fオプションを追加するだけです。このように指定されたコマンドは、対応する時間名前空間に存在します。unshare(1)execve(2)

もちろん、それは正しく行われたので、これらの時計に対する時間ネームスペースのビジョンを「歪める」ためのオプションおよび/--boottimeまたは指定も必要です。それ以外の場合は、子時間名前空間が親時間名前空間と同じビジョンを持ちます。--monotonic

要約すると、私のコンピュータで試したことを例に挙げます。

$ sudo unshare -T --boottime 1000000000 uptime -s
2021-04-23 11:07:10
$ sudo unshare -fT --boottime 1000000000 uptime -s
1989-08-15 09:20:30
$

これらの便利なオプションを使用することに加えて、/proc/self/timens_offsetsサブキーが生成される前にファイルを手動で設定することもできます。上記と同等の「手動」は次のとおりです。

$ sudo unshare -T dash -c 'echo "boottime 1000000000 0" > /proc/self/timens_offsets; uptime -s'
1989-08-15 09:20:30

ここでは、dash独自のブートローダの子エントリを作成せずに組み込みecho(サブファイルを生成しないため)を使用して独自のtimens_offsetsファイルを設定します。その時点から実行されるすべての後続のコマンドには、dash「歪んだ」開始時刻が表示されます。

しかし、これを行う場合は、exec uptime -sこれは親時間の名前空間dash に置き換えられ、まだ存在するためuptime〜しない限りあなたもnsenter(1)事前に。考慮する:

$ sudo unshare -T dash -c 'echo "boottime 1000000000 0" > /proc/self/timens_offsets; exec uptime -s'
2021-04-23 11:07:10
$ sudo unshare -T dash -c 'echo "boottime 1000000000 0" > /proc/self/timens_offsets; exec nsenter --time=/proc/self/ns/time_for_children uptime -s'
1989-08-15 09:20:30
$

2番目のポイント私が見つけた説明はdate特にこのコマンドに関するものでした。

気づくカーネルv5.11から開始CLOCK_BOOTIME(そして現在最新のv5.12-rc8)CLOCK_MONOTONIC次のように、新しい時間の名前空間で「反り」があります。コメントtime_namespaces(7):

時間ネームスペースはCLOCK_REALTIMEクロックを仮想化しません。このクロックの仮想化は、カーネル内の複雑さとオーバーヘッドによって防止されます。

しかし、コマンドが示すように、date時計でのみ動作します。これは、私がこの記事を書いている間、コマンドはまだそのコマンドが属する時間の名前空間から独立していることを意味します。CLOCK_REALTIMEstrace date -s ...date

コマンドのクイック例はいCLOCK_MONOTONICisを参照しているので、実際には時間ネームスペースの影響を受けますdmesg。次のようにしてみてください。

$ sudo unshare -fT --monotonic 1000000000 dmesg -T

第三要点はこの文章にあるようです。

システム時間を調整するシステム呼び出しは、ルート時間の名前空間の外で呼び出されると、名前空間ごとのオフセットを調整します。

もちろん、これは少し誤解を招く可能性があります。 (現在)明らかにいいえおそらく偶然時間ネームスペースの時間範囲の変更それから、単にCLOCK_MONOTONICCLOCK_BOOTTIME実際に不変だからです。これら二つの時計は意味は不変になります。

したがって、許可される唯一の作業は、これを(初期時間の名前空間と比較して)いくつかのオフセットで「ブートストラップ」することです。今後すべてのプロセスがその時間の名前空間に参加したため、どのプロセスもこれら2つの時計の間にジャンプしません(順方向ではありません)。

これがunshare(2)、呼び出しプロセスが新しく作成された一時名前空間に移動されない理由です。これにより、そのプロセス(または他のプロセス)が「ブートストラップ」オフセットを指定する機会があります。これは、2つのプロセスのうちの1つが一時的な名前空間に入った後は実際には不可能です。オフセット。時間ネームスペース。正しいオフセットを計算することは明らかに繊細な作業であり、「名前空間マネージャ」の作業です。

おすすめ記事