내 GNU/Linux 시스템의 날짜를 에포크로 설정할 수 없는 이유는 무엇입니까?

내 GNU/Linux 시스템의 날짜를 에포크로 설정할 수 없는 이유는 무엇입니까?

액세스할 수 있는 Raspberry Pi 및 Ubuntu 16.04 x86_64 머신에서 다음을 실행합니다.

# date -s @0

반품

date: cannot set date: Invalid argument
thu 1 jan 1970 01:00:00 CET

나는 알고 싶다:

  • 불가능의 이유는 무엇인가,
  • 시스템 시간을 Epoch로 재설정하는 프로그래밍 방식이 있습니까?

답변1

이전 시스템에서는 "잘못된 인수"를 정확하게 재현할 수 없지만 다음과 같습니다.

# strace date -s '@-1'
clock_settime(CLOCK_REALTIME, {4294967295, 0}) = -1 EINVAL (Invalid argument)
settimeofday({4294967295, 0}, NULL)     = -1 EINVAL (Invalid argument)
write(2, "date: ", 6date: )                   = 6
write(2, "cannot set date", 15cannot set date)         = 15
write(2, ": Invalid argument", 18: Invalid argument)      = 18
write(2, "\n", 1

( date실제로 아직 설정되지 않았더라도 설정하려는 날짜가 표시됩니다.)

일반 영어에서는 date커널을 호출하여 날짜를 신기원 1초 전으로 설정하고 커널은 제안된 날짜가 유효하지 않다고 알려줍니다.

이제 위의 추적에서 초가 -1 대신 4294967295임을 알 수 있습니다. 숫자는 2^32-1이고 32비트 시스템에서 실행 중입니다. 이것은 실제로아니요문제의 원인: strace값에 서명해야 하는지 알 수 없다는 점에서 디스플레이 문제입니다. 실제로 초 수는 부호 있는 정수 유형입니다 time_t. Linux의 Glibc 2.23은 , as , as 및 as 에서 time_t64 비트 부호 있는 유형을 정의합니다. 커널 측에서 4.4부터 호출 매개변수 유형의 정의는 다음과 같습니다.__time_t/usr/include/time.h__time_t__TIME_T_TYPE/usr/include/bits/types.h __TIME_T_TYPE__SYSCALL_SLONG_TYPE__SQUAD_TYPE/usr/include/bits/typesizes.h__SQUAD_TYPE/usr/include/bits/types.hsettimeofdaystruct timespec초는 어디에 있나요?__kernel_time_t64비트 시스템의 부호 있는 64비트 유형입니다.time64_t이는 32비트 시스템의 부호 있는 64비트 유형입니다. 따라서 커널은 -1을 큰 양수가 아닌 -1로 처리합니다.

이전 시대로 돌아갈 수 없는 이유는 Linux 커널이 이를 명시적으로 거부하기 때문입니다. 이것settimeofday시스템 호출if가 EINVAL("잘못된 매개변수")를 반환하는 경우timeval_valid주어진 시간적 구조를 거부하고,이 기능음수 초는 거부됩니다.

커널 버전마다 코드 구성이 다르지만 동작이 바뀌지는 않는다고 생각합니다.

정확히 0인 시간을 거부할 이유가 없으며 테스트한 VM에서 작동합니다.

아마도 이 온전성 검사의 이유는 에포크 이후의 시간을 부호 없는 정수로 저장하는 코드가 있어서 에포크 이전의 날짜를 처리할 수 없기 때문일 것입니다. 일부 코드는 0을 "알 수 없는 날짜"로 해석할 수 있으므로 0을 거부하는 것이 합리적이지만 Linux는 실제로 그렇게 하지 않으며 1초만 지속됩니다.

시대 이전 시대는 확실히 재현되고 조작될 수 있습니다. 많은 소프트웨어에서는 과거 이벤트 시간을 추적해야 합니다. 거의 모든 운영 체제에서 사용되는 시간대 데이터베이스에는 시간대가 코드화된 시기(철도가 사용되기 시작한 시기)까지 거슬러 올라가는 기록 데이터가 포함되어 있습니다. 하지만 Linux 컴퓨터에는 알 수 없습니다.현재의때는 1970년 이전이었다.

답변2

이는 현재 시간대의 에포크 개념이 (UTC) Unix 에포크보다 이전인 경우 발생할 수 있습니다. 그러한 시대는 대표할 수 없습니다.

관련 정보