З цим питанням ми стикаємося, коли говоримо про позначки часу в файловій системі Linux. У цьому матеріалі ми розглянемо, яким чином система оновлює ці позначки та як ми можемо самостійно їх змінювати.
Різниця між atime, mtime та ctime
Кожен файл в Linux має три мітки часу: час останнього доступу (atime), час останньої модифікації (mtime) та час зміни метаданих (ctime).
Мітка часу доступу (atime) фіксує момент, коли файл був востаннє прочитаний. Це відбувається, коли програма переглядає вміст файлу або зчитує з нього дані. Важливо, що при цьому сам файл не редагується і не змінюється.
Мітка часу модифікації (mtime) вказує на час останньої зміни вмісту файлу. Програми або процеси, які редагують або маніпулюють файлом, оновлюють цю мітку. “Модифікація” означає, що дані в файлі були змінені, видалені або доповнені.
Змінена мітка часу (ctime), натомість, не відстежує зміни у вмісті файлу. Вона фіксує час, коли змінювалися метадані, пов’язані з файлом. Наприклад, зміна прав доступу до файлу призведе до оновлення ctime.
Стандартна файлова система ext4 в Linux має місце для збереження мітки часу створення файлу, проте ця функція ще не повністю реалізована. Інколи це поле заповнюється, однак не варто покладатися на його значення.
Структура мітки часу
Часові позначки в Linux представлені числом, а не безпосередньо датою та часом. Це число – кількість секунд, які минули після епохи Unix, що розпочалася опівночі (00:00:00) 1 січня 1970 року за всесвітнім координованим часом (UTC). Варто зазначити, що високі розряди секунд у цих позначках ігноруються.
Коли Linux необхідно відобразити часову позначку, він перетворює кількість секунд на дату та час. Це робить інформацію зручнішою для сприйняття користувачем. Перетворення залежить від місця розташування комп’ютера та його часового поясу. Це також гарантує, що назви місяців відображаються правильною мовою.
То скільки секунд можна зберегти в часовій позначці? Багато – 2 147 483 647, якщо бути точними. Це велике число, але чи достатньо? Якщо додати це значення до епохи Unix, отримаємо вівторок, 19 січня 2038 року, о 03:14:07 ранку. Отже, до цього часу нам знадобиться нова система для часових позначок.
Перегляд міток часу
Використовуючи опцію -l (довгий список) з командою ls, можна переглянути час останньої модифікації (mtime):
ls -l dp.c
Для перегляду часу останнього доступу (atime), скористайтеся опцією -lu (час доступу):
ls -lu dp.c
Щоб побачити час останньої зміни метаданих (ctime), використовуйте опцію -lc (час зміни):
ls -lc dp.c
Вищенаведені результати показують, що файл був востаннє змінений 21 квітня 2019 року. Час доступу та час модифікації ідентичні, оскільки файл був скопійований з іншого комп’ютера 20 січня 2020 року, і обидві мітки були оновлені в цей час.
Щоб переглянути усі часові мітки одночасно, використовуйте команду stat:
stat dp.c
Внизу виводу відображається інформація про часові пояси. Як бачимо, час має дуже точну, дробову частину секунди. В кінці кожного рядка з часом можна також бачити -0500 або -0400.
Це є зміщення часового поясу. Файлова система зберігає часові мітки в форматі UTC, а потім перетворює їх у локальний часовий пояс при виведенні командою stat. Комп’ютер, який використовувався для підготовки цієї статті, налаштований на східний стандартний час (EST) США.
Цей часовий пояс на п’ять годин відстає від UTC, коли діє EST. Однак, коли діє східний літній час (EDT), різниця складає чотири години. У квітні 2019 року, коли була змінена мітка часу, діяв EDT. Тому дві мітки часу мають п’ятигодинний зсув, а змінена – чотиригодинний.
Зміщення та часові пояси ніде не зберігаються. Немає спеціального місця для їх зберігання ні в inode, ні у файловій системі. Вони обчислюються динамічно, виходячи з мітки часу (яка завжди у форматі UTC), місцевого часового поясу комп’ютера, на якому відображається файл, і того, чи діє літній час.
Також можна бачити мітку часу “Народження”, яка зарезервована для дати створення файлу. Проте наразі це поле не реалізоване і відображається дефісом “-“.
Зміна позначок часу
При необхідності можна змінювати часові мітки файлів. Для зміни часу доступу та часу модифікації можна скористатися командою touch:
touch -a dp.c
Опція -a (час доступу) дозволяє встановити нову мітку часу доступу. Ця команда встановлює час останнього доступу на поточний час:
stat dp.c
Час доступу змінився, як і очікувалося. Проте час модифікації також був оновлений – це нормальна поведінка.
Для зміни часу модифікації використовуйте опцію -m (змінений час):
touch -m dp.c
stat dp.c
Цього разу були оновлені обидві мітки – і час модифікації, і час зміни.
Опція -d (дата) дозволяє одночасно змінити час доступу та час модифікації. Крім того, можна вказати конкретну дату та час, а не тільки поточний.
Для прикладу, встановимо час доступу та час модифікації на 10:30:45 15 січня 2020 року:
touch -d "2020-01-15 10:30:45" dp.c
stat dp.c
Тепер час доступу і час модифікації встановлені на дату в минулому. Час зміни також оновився до поточного часу комп’ютера.
Якщо потрібно встановити часові мітки одного файлу на основі міток іншого, використовуйте опцію -r (посилання):
touch dp.c -r dice_words.sl3
stat dp.c
Знову отримаємо мікс часових міток з різними зміщеннями часових поясів.
Спробуємо зробити щось, що вплине лише на час зміни метаданих. Використаємо команду chmod для надання файлу прав на виконання для всіх користувачів:
chmod +x dp
stat dp
Лише час зміни метаданих було оновлено. Це відбувається тому, що сам файл не змінювався, до нього не зверталися. Проте, метадані файлу були модифіковані.
Як файлова система оновлює позначки часу
При монтуванні файлової системи можна використовувати параметри для налаштування її роботи. Ці параметри зберігаються в файлі /etc/fstab, який зчитується під час завантаження системи. Також є можливість налаштувати параметри для керування оновленням часу доступу.
Ось деякі з найпоширеніших варіантів:
strictatime: цей параметр оновлює час доступу до файлу при кожному зверненні до нього. Це накладає певні витрати, але деякі сервери можуть використовувати цю схему. Для настільних комп’ютерів цей підхід не має переваг.
noatime: цей параметр повністю відключає оновлення часу доступу до файлів та каталогів. Проте час модифікації буде оновлюватися.
nodiratime: дозволяє оновлювати час доступу для файлів, але відключає його для каталогів.
relatime: оновлює час доступу, лише якщо він старший за 24 години або якщо попередня мітка часу доступу старша за поточні час модифікації або час зміни метаданих. Цей параметр забезпечує гарний баланс між частотою оновлення міток доступу.
Поглянемо на файл /etc/fstab на цьому комп’ютері:
less /etc/fstab
Зміст файлу /etc/fstab:
Ось вміст файлу без обгортання:
# /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> # / was on /dev/sda1 during installation UUID=4a143d08-8695-475b-8243-b13b56050fc2 / ext4 errors=remount-ro 0 1 /swapfile none swap sw 0 0
Тут є два записи, один з яких є файлом підкачки, який можна ігнорувати. Інший монтується в кореневу файлову систему (/) і був на пристрої /dev/sda1 під час встановлення. Це перший розділ на першому жорсткому диску, який містить файлову систему ext4.
Єдиним параметром для нього є errors=remount-ro, який інструктує систему перемонтувати файлову систему як read-only, якщо виникають помилки при спробі змонтувати її як read-write.
Отже, тут не вказано, як обробляються мітки часу доступу. Давайте поглянемо на /proc/mounts. Виведемо інформацію з /proc/mounts за допомогою grep. Нашим пошуковим рядком буде “sda” – ідентифікатор жорсткого диска.
Введемо наступну команду:
cat /proc/mounts | grep "sda"
Тепер бачимо такі параметри:
rw: файлова система буде змонтована як read-write.
relatime: для оновлення часу доступу файлова система використовуватиме схему “відносного часу”.
Звідки це взялося? Схема relatime використовується в таких випадках:
Якщо в /etc/fstab використовуються параметри за замовчуванням.
Якщо в /etc/fstab використовується параметр relatime.
Якщо в /etc/fstab не використовуються параметри часу доступу, і ви використовуєте ядро Linux 2.6.30 або новіше.
Наш запис /etc/fstab для файлової системи ext4 не містить параметрів оновлення часу доступу, тому Linux автоматично застосував relatime.
Важливість часових позначок
Часові позначки дозволяють легко відстежити, коли файл був доступний, змінений або коли змінювалися його метадані. Вони також важливі для програм резервного копіювання та синхронізації даних, які використовують їх для визначення того, які файли потрібно копіювати.
Можливість маніпулювати часовими мітками може знадобитися для того, щоб примусово переконати програму включити або ігнорувати певний файл чи групу файлів.