LINUX.ORG.RU

Определить «реальность» времени (т.е. наличие CMOS-часов или NTP-синхронизации)

 , , ,


1

2

Предположим у нас есть некий unix-blackbox без часов реального времени (без батарейки в них) и без NTP (вообще без сети). Тогда при каждом запуске (включении и загрузки) на системных часах такого unix-box будет примерно одинаковое время (или совсем одинаковое).

Задача: Переносимым способом определять такую ситуацию (для тех кто в танке: «переносимо» == «не только на linux, а на любом POSIX/Unix»).

Дополнение в 2019-10-31 20:25 (исправляю упущение в исходной формулировке задачи): Очевидный вариант «увеличивать счетчик в файле при старте» не подходит, так как TL;DR должно работать в библиотеке без изменения её API и без вмешательства в процесс загрузки системы.

У меня есть вариант решения (назовём его «900»), но хочется услышать идеи от молодых и талантливых.

Для понимания: Всё это нужно (т.е. полная постановка задачи) для принятия решения «откатывать или нет» последние транзакции при открытии БД внутри libmdbx (встраиваемый движок БД, замена Berkeley DB), что требует переносимого аналога /proc/sys/kernel/random/boot_id, что в свою очередь требует определения boot time. И вот тут-то и нужно понять что это самое «boot time» не будет одинаковым при каждой загрузке.


Итоговый вариант решения был исходно обозначен как «900» и не изменился:

  • минимальная разница между часовыми поясами 900 секунд (15 минут);
  • Контролируем разницу между CLOCK_REALTIME и CLOCK_MONOTONIC;
  • Если она примерно кратна 900 секундам, то считаем что в системе нет CMOS-часов и/или синхронизации по NTP;

Как и почему это работает:

  • Если в системе нет cmos/NTP, то нет повода чтобы CLOCK_REALTIME и CLOCK_MONOTONIC шли в разнобой, т.е. разница будет равна некоторому часовому поясу (в том числе нулю в случае TZ=UTC).
  • Шаг «квантования» временных зон 15 минут, т.е. любая тайм-зона (в том числе еще не определенная) будет иметь смещение кратное 15 минутам.
  • Поэтому, если разность между CLOCK_REALTIME и CLOCK_MONOTONIC не кратна 15 минутам, то их разность не может быть объяснена только использованием какого-либо часового пояса. Следовательно CLOCK_REALTIME включает сдвиг для соответствия реальному времени и в системе где-то есть источник реального времени (CMOS или NTP).

Эта схема не идеальна и может давать ложно-отрицательный результат. Например, «алгоритм» посчитает что «время не настоящее»:

  • Система вправе инициализировать CLOCK_MONOTONIC от любого удобного источника, включая CMOS-часы. Тогда при наличии СMOS-часов работающих в нужной TZ получается всегда CLOCK_MONOTONIC == CLOCK_REALTIME.
  • С некоторой вероятностью разность может быть кратной 15 минутам.

Тем не менее, субъективно этот вариант лучше остальных (проверке условия «текущая время меньше даты исходников или сборки»). В контексте полной постановки задачи, важно что этот способ не даёт ложно-положительных результатов, и не имеет абсолютных точек привязки ко времени (идемпотентен по временной оси).

Исходники PoC для баловства = https://abf.io/erthink/poc4-boottime-nearly-constant


Добавлено 2019-11-01 в 12:18: В целом тредик/срач для меня полезен благодаря выводам:

  • на embedded-like платформах (как минимум на Linux) следует полагаться только на нативный bootid, ибо boottime может превращаться в тыкву распространенными рецептами в rc-скриптах.
  • генерацию bootid из boottime следует вынести в опцию, ибо нет 100% гарантии выявить все варианты предыдущего пункта.

Всем еще раз спасибо за дискус/срачик. Всё.

Deleted

Последнее исправление: Deleted (всего исправлений: 6)

Переносимым способом определять такую ситуацию

А как вся твоя балалайка деплоится? Вероятно каким-то непереносимым способом? Тогда можно просто «захардкодить» время при ребуте системы один раз при установке/настройке балалайки и просто с ним потом сверять.

no-such-file ★★★★★
()
Ответ на: комментарий от Deleted

Соглашусь только с упущением в ТС о том, что нельзя вмешиваться в процесс старта ОС (что уже поправил).

Ты можешь управлять последовательностью старта твоих процессов работающих с твоим БД?

Если да, первым стартуешь процесс, который систематически пишет время в БД и свой статус. «Систематически» - это сам выбирай: периодически, при каждой записи, при sync, при коммитах транзакций, ... Эта «систематичность» и опредляет «валидность».

anonymous
()
Ответ на: комментарий от Deleted
  • если был системный сбой (выключение питания, ядерный oops и т.п.), то откат нужен.
  • НО если просто упал (убит OOM-киллером) процесс работающий с БД, то откатывать не надо.

Какая-то странная стратегия «отката». Разве сам БД с этим не справляется?

anonymous
()
Ответ на: комментарий от anonymous

Ты можешь управлять последовательностью старта твоих процессов работающих с твоим БД?

Нет.

Я делаю только библиотеку, которая реализует встраиваемую БД. Библиотекой может пользоваться любое кол-во процессов, с разными правами, разными БД размещенными в произвольных местах ФС, разной логикой работы, последовательностью запуска и своими собственными глюками.

Если да, первым стартуешь процесс, который систематически пишет время в БД и свой статус. «Систематически» - это сам выбирай: периодически, при каждой записи, при sync, при коммитах транзакций, … Эта «систематичность» и опредляет «валидность».

Как уже писал выше задача решается намного проще, если вмешиваться/встраиваться в процесс запуска. Кроме этого, предложенный рецепт «ломается» при переводе времени.

Deleted
()
Ответ на: комментарий от anonymous

Какая-то странная стратегия «отката».

Дополню. И, вообще, вся эта твоя каша-малаша какая-то выдуманная нереальная хрень.

anonymous
()
Ответ на: комментарий от anonymous

Какая-то странная стратегия «отката». Разве сам БД с этим не справляется?

БД уже с этим справляется. Но эту БД (движок) разрабатываю я и речь о том, чтобы не делать отката когда в этом нет необходимости (формулировки в ТС уже уточнил).

Deleted
()
Ответ на: комментарий от Deleted

Я делаю только библиотеку, которая реализует встраиваемую БД. Библиотекой может пользоваться любое кол-во процессов, с разными правами, разными БД размещенными в произвольных местах ФС, разной логикой работы, последовательностью запуска и своими собственными глюками.

:)

Ясно-понятно. Как и думал - каша-малаша. Тебе не нужна помощь других. Успехов.

anonymous
()
Ответ на: комментарий от anonymous

И, вообще, вся эта твоя каша-малаша какая-то выдуманная нереальная хрень.

Ну задача значит не твоя, если условия не помешаются в голову )

Deleted
()
Ответ на: комментарий от anonymous

Ясно-понятно. Как и думал - каша-малаша. Тебе не нужна помощь других. Успехов.

Мне действительно не нужны бесполезные советы:

  • не по теме обозначенной в ТС.
  • без понимания условий задачи.
  • от людей не понимающих смысла задачи (практической ценности).
Deleted
()
Ответ на: комментарий от Deleted

Ну задача значит не твоя

Если ты задаешь вопрос про «реальность» времени, вместо вопросов обеспечения целостности данных, то тут тебе никто не поможет.

anonymous
()
Ответ на: комментарий от no-such-file

А как вся твоя балалайка деплоится? Вероятно каким-то непереносимым способом? Тогда можно просто «захардкодить» время при ребуте системы один раз при установке/настройке балалайки и просто с ним потом сверять.

Это совсем вне контекста. Собственно никакой одной «балалайки» нет. Есть задача определения (не)волатильности boot time без возможности вмешиваться в процесс загрузки ОС (формулировки в ТС уже уточнены).

Озвученный выше рецепт «900» пока вне конкуренции.

Deleted
()
Ответ на: комментарий от anonymous

Если ты задаешь вопрос про «реальность» времени, вместо вопросов обеспечения целостности данных, то тут тебе никто не поможет.

Все вопросы обеспечения целостности данных в libmdbx уже давно решены. В том числе, (уместно упомянуть) с устранением нескольких проблем LMDB, которая к тому времени прошла несколько review и исследований (см. тут).

Сейчас же речь о том, чтобы на системах без нативной поддержки bootid, обеспечить целостность и долговечность данных не прибегая к откату (без потери изменений) в ситуациях когда этого можно избежать, и всё это с учетом гипотетических сбойных ситуаций (сдохла батарейка и/или eeprom) на экзотических embedded системах.

На всякий еще раз уточню - дело не в том, что «БД не умеет» обеспечивать целостность, а в том чтобы обеспечить целостность данных с минимальными потерями изменений, когда пользователь сознательно попросил не делать sync при фиксации каждой транзакции.

Вот такая вот «реальность» времени )

Deleted
()
Ответ на: комментарий от Deleted

если у тебя можно сделать мтайм, то почему нельзя записать время работы в свой файл? при запуске читай значение из файла (или ноль) и каждую секунду (или другой интервал) пиши в него инкремент.

пиши туда же время полученое от сисьтемы в пердыдущий раз и сравнивай с тем что получил снова.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 2)
Ответ на: комментарий от Deleted

Озвученный выше рецепт «900» пока вне конкуренции.

Если «минимальная разница в часовых поясах» - признак «реальности», то я живу другой реальности. Поэтому мы «по опредлению» не должны друг друга понимать.

Не очень-то и хотелось конкурировать с «альтернативной» реальностью, где «минимальная разница в часовых поясах» влияет на целостность данных.

anonymous
()
Ответ на: комментарий от anonymous

Если «минимальная разница в часовых поясах» - признак «реальности», то я живу другой реальности. Поэтому мы «по опредлению» не должны друг друга понимать.

Не очень-то и хотелось конкурировать с «альтернативной» реальностью, где «минимальная разница в часовых поясах» влияет на целостность данных.

Не по теме, не остроумно, без прочтения уже данных ответов, в том числе о целостности данных. Короче, анонимная пурга.

Deleted
()
Ответ на: комментарий от Deleted

Давай уже, рассказывай про алтернативную реальность, как обеспечение монотонности времени коррелирует с «минимальной разницей в часовых поясах» да еще разных платформах.

Что будет, если я отправлю систему в сон (suspend) ровно на 900*N секунд?

anonymous
()

Тогда при каждом запуске (включении и загрузки) на системных часах такого unix-box будет примерно одинаковое время (или совсем одинаковое).

разбежался

anonymous
()
Ответ на: комментарий от Deleted

Сейчас же речь о том, чтобы не делать отката когда в нём нет необходимости.

Файл.

Но всё это означает изменения API и/или поведение движка БД.

В каком блин месте? Чего бы эту задачу не заскриптовать и не озадачить инит этим делом?

Ты тролль.

Соглашусь.

нельзя вмешиваться в процесс старта системы

и

без изменения API это реализуется только посредством сверки bootid

Ну вообще не в тему. Даже переписав код движка БД полностью, ты можешь сохранить API. Твое условие задачи означает - в инит не лезть, в код движка БД тоже. Но вот добавить функционал движку БД - надо.

БД уже давно всё делает правильно, в том числе откат к крайней sync-фиксации

и

Сейчас же речь о том, чтобы не делать отката когда в нём нет необходимости

опять не согласуется. Значит двиг БД не правильно определяет необходимость отката. Фиксить надо именно это.

Если бы ты не хотел донести какую-то муть про какое-то «решение 900», которое вообще работает только в частных (хоть и частых) случаях, ты бы взял и решил уже эту задачу. bootsequence хранить в персистентном файле - лишний гемор.

Короче ты или не можешь пояснить цель или выдумал задачу из ничего или тупо решил развести «умный» срачик.

Deleted
()
Ответ на: комментарий от anonymous

Давай уже, рассказывай про алтернативную реальность, как обеспечение монотонности времени коррелирует с «минимальной разницей в часовых поясах» да еще разных платформах.

Никак, вы анонимны до тупости и поэтому не поняли о чем речь.

Что будет, если я отправлю систему в сон (suspend) ровно на 900*N секунд?

Примерно нет систем, которые умеют suspend и при этим не имеют нативного bootid, BOOT_TIME через sysctl или CLOCK_BOOTTIME (если сомневаетесь. то покажите).

Соответственно, не возникает задачи обозначенной в ТС.

Deleted
()
Ответ на: комментарий от Deleted

Примерно нет систем, которые умеют suspend и при этим не имеют нативного bootid, BOOT_TIME через sysctl или CLOCK_BOOTTIME (если сомневаетесь. то покажите).

Ыыыы. Да даже x86 некоторые. Vortex86 какие-то были, мы на них QNX крутили.

Deleted
()

При старте запускаешь отдельный процесс. Если отдельный процесс при старте уже есть, значит юникс не перезагружался.

Не за что.

anonymous
()
Ответ на: комментарий от Deleted

Твое условие задачи означает - в инит не лезть, в код движка БД тоже. Но вот добавить функционал движку БД - надо.

Нет, не так (и я уже поправил формулировку в ТС). Мое условие = доработать внутренности библиотеки (движка БД), не меняя его API, т.е. не требуя каких-либо изменений в коде использующем эту библиотеку.

опять не согласуется. Значит двиг БД не правильно определяет необходимость отката. Фиксить надо именно это.

Это off-topic и вы не поняли.

Движок отлично все определяет - не было fdatasync/msync, значит нужно откатывать. Однако, «на самом деле», с учетом особенностей работы движка в релевантных режимах, все данные целые, если ядро не перезагрузилось, а (следовательно) выполнит запись на диск грязных буферов файловой системы и грязных страниц после последнего msync(MS_ASYNC).

Предвидя «данные могут поломаться потому-что может отвалится асинхронная запись в ядре» отвечаю - да может, но пользователь принимает эти риски явно выбирая соответствующий режим работы с БД (без sync при фиксации каждой транзакции и т.п.).

Короче ты или не можешь пояснить цель или выдумал задачу из ничего или тупо решил развести «умный» срачик.

Не надо ваше непонимание сваливать на чужую голову. Вопрос был обозначен и уточнен в ТС. Вы же пытаетесь генерировать решение вне обозначенного scope, делая при этом неверные предположения (о том как работает libmdbx) исходя из знаний о распространенных не-встраиваемых БД.

Если вы хотите продолжить дискуссию в этом направлении, то нужно погружаться в тему (хотя-бы прочесть README и описание API).

Deleted
()
Ответ на: комментарий от Deleted

А, да, чуть не забыл. CLOCK_MONOTONIC берётся в линуксе от старта системы. А в спецификации POSIX вообще нет указания, откуда оно должно считаться. И если реализация часов в системе такова, что при загрузке системы берётся время, которое было последним и оно было сохранено в EEPROM - тогда ой, т.к. классический юникс берёт значение CLOCK_MONOTONIC не от старта системы - так делает только линукс, ЕМНИП.

Deleted
()
Ответ на: комментарий от Deleted

Лорчую. ТС не понимает базовых понятий ИБ и натягивает сову на глобус.

Еще раз - если вы не можете (или не хотите) понять ТС, то не нужно писать здесь ерунду.

Deleted
()
Ответ на: комментарий от Deleted

не меняя его API, т.е. не требуя каких-либо изменений в коде использующем эту библиотеку.

Ну ещё раз. Изменение кода != изменение API.

Движок отлично все определяет

Не определяет. Так как он должен при запуске проверить консистентность данных, и если надо - починить, а не откатывать своё состояние при каждом чихе.

делая при этом неверные предположения (о том как работает libmdbx) исходя из знаний о распространенных не-встраиваемых БД.

В данном контексте разницы нет. При OOM данные даже в грязных страницах могут быть не полными - транзакция может быть завершена не полностью.

Deleted
()
Ответ на: комментарий от Deleted

то не нужно писать здесь ерунду.

Ерунду пишет здесь ТС, т.к. он не понимает, что его задача должна решаться по-другому.

Deleted
()
Ответ на: комментарий от Deleted

Ыыыы. Да даже x86 некоторые. Vortex86 какие-то были, мы на них QNX крутили.

Suspend на уровне процессора без соответствующей поддержки в ОС создает массу проблем. Поэтому в промышленной эксплуатации таких систем примерно нет (точнее никогда не было).

Так всё-таки - покажите/назовёте POSIX-систему с поддержкой susend и при этом без bootid/sysctl(boottime)/clock_gettime(CLOCK_BOOTTIME) ?

Deleted
()
Ответ на: комментарий от Deleted

bootid/sysctl(boottime)/clock_gettime(CLOCK_BOOTTIME)

AIX.

Deleted
()
Ответ на: комментарий от Deleted

Теперь поехали дальше. Понятие часового пояса имеет значение только для gmtime и localtime. clock_realtime не имеет часового пояса. Вообще. Т.е. о каких там 900 секундах ты настропалил - не ясно. Ясно одно - что в linux после загрузки системы clock_realtime будет равно случайному времени, забитому в прошивке а clock_monotonic будет содержать время от старта системы в Linux, а в AIX и *BSD оно будет содержать начало отсчета от Epoch. Поэтому свой говнокод можешь засунуть обратно, откуда он вылез. И это я тебе ещё об аппаратных особенностях некоторых RTC, используемых в embedded не рассказал.

Тебе популярно объяснили, что ты в параллельной реальности живёшь. Поэтому - единственное, что ты можешь сделать - нормлаьно обеспечить контроль целостности. И контроль целостности должен быть именно контролем целостности, а не как в твоей поделке - бабка надвое сказала: не ясно, толи данные повреждены, толи нет. Ты даже транзакционную целостность у себя при таком подходе обеспечить не можешь. Хотел культурнее объяснить, но пришлось доходчивее.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

Теперь поехали дальше. Понятие часового пояса имеет значение только для gmtime и localtime. clock_realtime не имеет часового пояса. Вообще. Т.е. о каких там 900 секундах ты настропалил - не ясно. Ясно одно - что в linux после загрузки системы clock_realtime будет равно случайному времени, забитому в прошивке а clock_monotonic будет содержать время от старта системы в Linux, а в AIX и *BSD оно будет содержать начало отсчета от Epoch. Поэтому свой говнокод можешь засунуть обратно, откуда он вылез. И это я тебе ещё об аппаратных особенностях некоторых RTC, используемых в embedded не рассказал.

В ТС добавлено описания решения, т.е. исходного варианта «900». Начинайте критиковать оттуда и лучше перед зеркалом.

Что касается экспрессивного выражения «говнокод», то по совокупности написанного вами - мне до лампочки ваше мнение.

Об RTC - лучше тоже перед зеркалом, но встав на табуретку )

Тебе популярно объяснили, что ты в параллельной реальности живёшь. Поэтому - единственное, что ты можешь сделать - нормлаьно обеспечить контроль целостности. И контроль целостности должен быть именно контролем целостности, а не как в твоей поделке - бабка надвое сказала: не ясно, толи данные повреждены, толи нет. Ты даже транзакционную целостность у себя при таком подходе обеспечить не можешь. Хотел культурнее объяснить, но пришлось доходчивее.

Для тех кто в танке:

  • ACID есть, у меня в libmdbx буквально такой-же (чистая MVCC) как в LMDB и BoltDB.
  • Выше были пояснения о целостности #1, #2. Говорить/пояснять/обсуждать что-либо еще стоит только после изучения инфы ниже, либо исходного кода.
  • Если вы хотите что-то обсуждать дальше, что сначала RTFM от простого к сложому: #1, #2, #3, #4, #5.
Deleted
()
Ответ на: комментарий от Deleted

Задача уже решена https://abf.io/erthink/poc4-boottime-nearly-constant

только ответ ожидаемо неправильный :) после обычного ребута

# uname -a
Linux buildroot 4.14.98+g5d6cbeafb80c #1 SMP PREEMPT Wed Oct 30 17:14:05 MSK 2019 aarch64 GNU/Linux

# hwclock && date && ./poc
Thu Jan  1 00:11:55 1970  0.000000 seconds
Thu Jan  1 00:11:56 UTC 1970
CLOCK_REALTIME and CLOCK_MONOTONIC difference is 651.006745500
900' remainder is 651.006745500
900' margin is 248.993254500
treshold is 0.023809523
margin is enough, "boottime" is non constant with probability 1:1.890000e+04
anonymous
()
Ответ на: комментарий от anonymous
# hwclock && date && ./poc
Thu Jan  1 00:11:55 1970  0.000000 seconds
Thu Jan  1 00:11:56 UTC 1970
CLOCK_REALTIME and CLOCK_MONOTONIC difference is 651.006745500
900' remainder is 651.006745500
900' margin is 248.993254500

Наверное PoC нужно докручивать, в том числе «фильтровать» совсем плохое время.

С другой стороны, есть три «отмазки»:

  • встроенных часов нет совсем и у ядра это можно узнать (чего не делает PoC).
  • есть некая нелогичность в том что, hwclock совсем нет и мы зная об этом загружаем из него CLOCK_REALTIME уже после старта.
  • всё-таки тут Linux, в котором есть нативный bootid.

Но в целом, я действительно не учел, что CLOCK_REALTIME может быть «тупо» загружен нулем из отсутствующего (или неработающего) hwclock уже после первоначального совместного старта CLOCK_MONOTONIC и CLOCK_REALTIME. Напрашивается проверка на ноль hwclock, что нужно делать для каждой ОС индивидуально (не переносимо).

Deleted
()
Ответ на: комментарий от Deleted

из отсутствующего (или неработающего) hwclock

я не понял о чём ты, тут как раз нормально работающий RTC без батарейки - очень распространённый вариант в embedded, система «голая» - никакие загрузочные скрипты ничего не трогают, системное время устанавливается штатно ядром при инициализации из rtc0

# ls -l /dev | grep rtc
lrwxrwxrwx    1 root     root             4 Jan  1 00:00 rtc -> rtc0
crw-------    1 root     root      253,   0 Jan  1 00:00 rtc0

reboot через некоторое время - питание с RTC не снимается при этом

# hwclock && date && ./poc
Thu Jan  1 00:28:12 1970  0.000000 seconds
Thu Jan  1 00:28:11 UTC 1970
CLOCK_REALTIME and CLOCK_MONOTONIC difference is 1652.986395500
900' remainder is 752.986395500
900' margin is 147.013604500
treshold is 0.023809523
margin is enough, "boottime" is non constant with probability 1:1.890000e+04

вот «холодный» старт - в этом случае определяет правильно

# hwclock && date && ./poc
Thu Jan  1 00:00:18 1970  0.000000 seconds
Thu Jan  1 00:00:19 UTC 1970
CLOCK_REALTIME and CLOCK_MONOTONIC difference is 0.000000000
900' remainder is 0.000000000
900' margin is 0.000000000
treshold is 0.023809523
margin is too small (0.0%), "boottime" is nearly constant.
anonymous
()
Ответ на: комментарий от anonymous

из отсутствующего (или неработающего) hwclock

я не понял о чём ты, тут как раз нормально работающий RTC без батарейки

Тут похоже мы друг-друга не поняли (говорили про разные вещи) и запутали.

Во-первых я действительно не учел варианта, о котором писал - если 0 будет загружен из неработающего RTC.

Во-вторых, почти тоже самое происходит при теплой перезагрузки с работающим RTC без батарейки. Но здесь все несколько усложняется:

  • при теплой перезагрузки boot time будет другое, т.е. PoC как-бы не соврал.
  • при холодной перезагрузки boot time будет примерно тот-же, т.е. PoC опять как-бы не соврал.
  • но проблема в том, что результат меняется от теплоты рестарта ;)

Так вот, вторым коммитом в PoC добавлена еще одна проверка, которая должна всё починить. Тем не менее, пока вся логика только без абсолютных точек во времени (анализируется только разница).

Deleted
()
Ответ на: комментарий от Deleted

Так вот, вторым коммитом в PoC добавлена еще одна проверка

холодный старт

# hwclock && date && ./poc
Thu Jan  1 00:00:13 1970  0.000000 seconds
Thu Jan  1 00:00:15 UTC 1970
CLOCK_REALTIME and CLOCK_MONOTONIC difference is 0.000000000
difference is too small, "boottime" is nearly constant.

эмулируем установку системного времени прошивкой в загрузочном скрипте

# date -s 2010-11-01
Mon Nov  1 00:00:00 UTC 2010

и независимо от теплоты старта получаем неправильный результат

# hwclock && date && ./poc
Thu Jan  1 00:00:34 1970  0.000000 seconds
Mon Nov  1 00:00:03 UTC 2010
CLOCK_REALTIME and CLOCK_MONOTONIC difference is 1288569567.399560452
900' remainder is 867.399560500
900' margin is 32.600439500
treshold is 0.023809523
margin is enough, "boottime" is non constant with probability 1:1.890000e+04

прикол в том что всё это с минимальным кодом отлавливается простым способом предложенным в самом начале

Определить «реальность» времени (т.е. наличие CMOS-часов или NTP-синхронизации) (комментарий)

anonymous
()
Ответ на: комментарий от anonymous

эмулируем установку системного времени прошивкой в загрузочном скрипте

Так вы «эмулируете» работу NTP и получаете от PoC правильный результат независимо от теплоты старта.

прикол в том что всё это с минимальным кодом отлавливается простым способом предложенным в самом начале

Нет. «Прикол» в том, что это заведомо недопустимый вариант, дающий ложно-положительный результат в 50% пространства аргументов.

Deleted
()
Ответ на: комментарий от Deleted

Так вы «эмулируете» работу NTP и получаете от PoC правильный результат независимо от теплоты старта.

нет, я эмулировал это

Определить «реальность» времени (т.е. наличие CMOS-часов или NTP-синхронизации) (комментарий)

дающий ложно-положительный результат в 50% пространства аргументов

нет, он дает 100% проавильный результат

Определить «реальность» времени (т.е. наличие CMOS-часов или NTP-синхронизации) (комментарий)

для ясности - речь о сохранённом времени сборки, как например сохраняется при сборке ядра Linux

# uname -a Linux buildroot 4.14.98+g5d6cbeafb80c #1 SMP PREEMPT Wed Oct 30 17:14:05 MSK 2019 aarch64 GNU/Linux

anonymous
()

Честно говоря, я так и не понял зачем это определять. Если там не 1970, а любое другое время, то мне кажется это уже всё - кирдык, на время в такой системе можно не смотреть.

Понятно что такие системы бывают, но нет возможности снабжать их GPS приемником, вроде можно со спутника дату время ловить?

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от anonymous

Так вы «эмулируете» работу NTP и получаете от PoC правильный результат независимо от теплоты старта.

нет, я эмулировал это

Вы меняете время из скрипта запуска, ровно также как NTP при первичной синхронизации. Соответственно, PoC это определяет и выдает правильный результат, соответствующий произведенным действиям.

Дискуссия о правильности установки RTC при старте таким способом и корректности работы PoC в этой ситуации смыла не имеет:

  • если в системе что-то (некий rc-скрипт) действует как NTP, то последствия в принципе нельзя отличить от «настоящего» NTP как с правильным, так и совсем не верным временем.
  • в linux прошивках «все так делают» (ибо проще чем заморачиваться инициализацией RTC внутри ядра).
  • 99% прошивок с таким скриптами работают на linux с нативным bootid (который тоже может быть левым при отсутствии источника энтропии).

нет, он дает 100% проавильный результат

Тут 50/50 как с динозавром: если дата «в прошивке» меньше даты релиза библиотеки, то результат будет верный, иначе нет.

Но примерно нет повода помещать новую библиотеку в прошивку со со старой датой. Напротив, более вероятен другой вариант - стабильная версия библиотеки будет в новой прошивке и тогда результат будет всегда неверный (при том ложно-положительный).

Deleted
()
Ответ на: комментарий от Deleted

корректности работы PoC в этой ситуации смыла не имеет если в системе что-то (некий rc-скрипт) действует как NTP, то последствия в принципе нельзя отличить от «настоящего» NTP как с правильным, так и совсем не верным временем.

ты для себя это еще раз десять повтори - может дойдёт

смотри системное время и если оно из прошлого по отношению даты создания кода то синхронизации времени нет.

Эта эвристика входит в мой рецепт, но не всегда «прокатывает». Например, в embedded время может стартовать не c 1970-01-01, а с даты выпуска прошивки. Кроме этого, при наличии CMOS может быть выставлено неверное время (бывает относительно часто). erthink (31.10.19 11:24:08)

не даёт твой poc ничего, совсем. По сравнению с 2 строчками сравнения даты сборки и системного времени.

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Честно говоря, я так и не понял зачем это определять.

Мне нужно понять - могу ли я генерировать уникальный bootid из boot time. Другими словами, отличается ли полученное сейчас от системы boot time от значения показанного мне до перезагрузки.

Если они разные, то я могу генерировать bootid из boot time (например так), невидимо для пользователя запомнить это значение внутри БД и потом использовать его для определения факта перезагрузки.

Потом, при открытии БД первым процессом, я всегда вижу была ли БД закрыта/shutdow как положена, либо нет. Если нормального shutdown не было (нет отметки об успешном sync-ке последних изменений), то я могу сравнить значения bootid внутри БД с текущим и сделать важный вывод:

  • Если значения разные, то значит система была перезагружена, грязные буфера внутри ядра могли не записаться и поэтому мне нужно откатить состояние БД к последнему sync-у с диском.
  • Если же значения одинаковые, то перезагрузки системы не было и все данные пользователя либо уже записаны на диск, либо еще живы в буферах ядра. В этой ситуации я могу НЕ делать отката, сохранив последние изменения пользователя в сценарии когда он сознательно выключил sync при каждой транзакции и его использующий БД процесс был убит или сам упал.

На всякий:

  • Незакоммиченные транзакции видны только выполняющему их потоку и конечно не виды после аварии.
  • По-умолчанию каждая транзакция полностью sync-ается на диск при коммите, но пользователь может явно запросить не делать sync.
  • Если же пользователь попросил не-sync-ать, то при аварии будет откат, а все танцы с bootid-бубном только для того, чтобы в некоторых ситуациях спасти транзакции пользователя после крайнего sync-а.

Если там не 1970, а любое другое время, то мне кажется это уже всё - кирдык, на время в такой системе можно не смотреть.

Понятно что такие системы бывают, но нет возможности снабжать их GPS приемником, вроде можно со спутника дату время ловить?

Основная «фишка» в том, что мы с приемлемой достоверностью без ложно-положительных результатов определяем было ли переведено время после старта системы.

Если время было переведено, то можно предположить что это делалось для установке времени ядра по RTC, либо по NTP. Соответственно, в таком случае можно рассчитывать, что при следующей загрузке будет другое bootid.

Однако, в linux-прошивках есть мода/традиция/карго-культ в rc-скриптах переводить время «для красоты» на дату формирования прошивки. Соответственно, в таких прошивках c карго-культом обозначенная «фишка» не работает.

Deleted
()
Ответ на: комментарий от Deleted

Да, теперь проблема ясна.

Хорошо, а можно ведь сделать перехватывалку NTP или RTC. Или нельзя так вмешиваться в целевую систему? Но если можно…

Если можно, я бы написал прослойки, через которые можно было бы определить что RTC отработало, что NTP получило время. А может есть стандартные методы извлечения таких фактов из сислога например?

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от Deleted

в linux-прошивках есть мода/традиция/карго-культ в rc-скриптах переводить время «для красоты» на дату формирования прошивки.

карго-культ - это твой poc, а в прошивках с Linux это защита от ситуации когда даты создания/изменения файлов оказвыаются из будущего или изменны раньше чем созданы.

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Да, я вижу что портабельно надо… Но помочь не могу[code][ 0.892847] rtc_cmos 00:05: RTC can wake from S4 [ 0.893265] rtc_cmos 00:05: rtc core: registered rtc_cmos as rtc0 [ 0.893344] rtc_cmos 00:05: alarms up to one month, y3k, 242 bytes nvram, hpet irqs [ 0.907354] rtc_cmos 00:05: setting system clock to 2019-11-01 06:13:18 UTC (1572588798)[/code]Про NTP не знаю…

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от anonymous

корректности работы PoC в этой ситуации смыла не имеет если в системе что-то (некий rc-скрипт) действует как NTP, то последствия в принципе нельзя отличить от «настоящего» NTP как с правильным, так и совсем не верным временем.

ты для себя это еще раз десять повтори - может дойдёт

Вы расширяете условия задачи до заведомо некорректных условий, а потом упрекаете меня в том, что я не хочу учитывать «логику» embedded-систем с намерено сломанным/странным поведением.

не даёт твой poc ничего, совсем. По сравнению с 2 строчками сравнения даты сборки и системного времени.

Еще раз, сравнения даты сборки и системного времени в отдельности ни дает вообще ничего:

  • если current time > build time = система загружена и работает с каким-то временем, которое может быть как «реальным», так и «нереальным», но невозможно сделать каких-либо выводов о значении boot time в предыдущем или следующем запуске.
  • если current time < build time = система загружена и работает с каким-то временем плохим (в том числе с неверно установленным в RTC/CMOS c батарейкой), но невозможно сделать каких-либо выводов о значении boot time в предыдущем или следующем запуске.
Deleted
()
Ответ на: комментарий от Deleted

если current time > build time = система загружена и работает с каким-то временем, которое может быть как «реальным», так и «нереальным», но невозможно сделать каких-либо выводов о значении boot time в предыдущем или следующем запуске.

точно так же как и poc - смотри мою эмуляцию утсановки фиксированного времени, твой poc точно так же обсерется и посчитает что время загрузки разное, хотя оно 100% будет одним и тем же, только с меньшей вероятностью

если current time < build time = система загружена и работает с каким-то временем плохим (в том числе с неверно установленным в RTC/CMOS c батарейкой), но невозможно сделать каких-либо выводов о значении boot time в предыдущем или следующем запуске.

в этом случае poc обсерется намного жиже, в отличии от сравнения времени он всегда будет считать фиксированное время загрузки за рандомное

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.