시간 네임스페이스는 어떻게 사용해야 합니까?

시간 네임스페이스는 어떻게 사용해야 합니까?

나는 다음과 같이 할 수 있다고 생각합니다.

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

귀하의 추론에는 설명이 필요한 세 가지 사항이 있다고 생각합니다.


첫 번째시간 네임스페이스 공유를 해제하면 영향을 받습니다.어린이들생산그때부터호출 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
$

두 번째 포인트내가 찾은 설명은 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실제로 불변이기 때문입니다. 이 두 시계는의미는불변이 됩니다.

따라서 허용되는 유일한 작업은 이를 (초기 시간 네임스페이스에 상대적인) 일부 오프셋으로 "부트스트랩"하는 것입니다.앞으로모든 프로세스가 해당 시간 네임스페이스에 합류했으므로 어떤 프로세스도 이 두 시계 사이에 점프가 발생하지 않습니다(정방향도 아님).

이것이 unshare(2)호출 프로세스가 새로 생성된 임시 네임스페이스로 이동되지 않는 이유입니다. 이렇게 하면 해당 프로세스(또는 다른 프로세스)가 "부트스트랩" 오프셋을 지정할 기회를 갖게 됩니다. 이는 두 프로세스 중 하나가 임시 네임스페이스에 들어간 후에는 실제로 불가능합니다. 오프셋. 시간 네임스페이스. 올바른 오프셋을 계산하는 것은 분명히 섬세한 작업이며 "네임스페이스 관리자"의 작업입니다.

관련 정보