summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2024-03-13 00:40:09 +0200
committerzsdc <taras@vyos.io>2024-03-13 00:40:09 +0200
commitf74923202311e853b677e52cd83bae2be9605c26 (patch)
tree81677eaa9f6e6993cb1129fba5a26a68ea83a54f /python
parenta4e21377271cfcf6359ed23db8a90129e264ba4d (diff)
downloadvyos-1x-f74923202311e853b677e52cd83bae2be9605c26.tar.gz
vyos-1x-f74923202311e853b677e52cd83bae2be9605c26.zip
grub: T4548: Fixed configuration files order
To iterate files on ext* file systems GRUB reads their inodes one by one, ignoring names. This breaks our configuration logic that relies on proper loading order. This commit adds a helper `sort_inodes()` that needs to be used whenever GRUB configuration files are created. It recreates files, changing their inodes in a way where inodes order matches alphabetical order.
Diffstat (limited to 'python')
-rw-r--r--python/vyos/system/grub.py36
1 files changed, 36 insertions, 0 deletions
diff --git a/python/vyos/system/grub.py b/python/vyos/system/grub.py
index 2e8b20972..864ed65aa 100644
--- a/python/vyos/system/grub.py
+++ b/python/vyos/system/grub.py
@@ -17,6 +17,7 @@ import platform
from pathlib import Path
from re import MULTILINE, compile as re_compile
+from shutil import copy2
from typing import Union
from uuid import uuid5, NAMESPACE_URL, UUID
@@ -422,3 +423,38 @@ def set_kernel_cmdline_options(cmdline_options: str, version_name: str,
version_add(version_name=version_name, root_dir=root_dir,
boot_opts_config=cmdline_options)
+
+
+def sort_inodes(dir_path: str) -> None:
+ """Sort inodes for files inside a folder
+ Regenerate inodes for each file to get the same order for both inodes
+ and file names
+
+ GRUB iterates files by inodes, not alphabetically. Therefore, if we
+ want to read them in proper order, we need to sort inodes for all
+ config files in a folder.
+
+ Args:
+ dir_path (str): a path to directory
+ """
+ dir_content: list[Path] = sorted(Path(dir_path).iterdir())
+ temp_list_old: list[Path] = []
+ temp_list_new: list[Path] = []
+
+ # create a copy of all files, to get new inodes
+ for item in dir_content:
+ # skip directories
+ if item.is_dir():
+ continue
+ # create a new copy of file with a temporary name
+ copy_path = Path(f'{item.as_posix()}_tmp')
+ copy2(item, Path(copy_path))
+ temp_list_old.append(item)
+ temp_list_new.append(copy_path)
+
+ # delete old files and rename new ones
+ for item in temp_list_old:
+ item.unlink()
+ for item in temp_list_new:
+ new_name = Path(f'{item.as_posix()[0:-4]}')
+ item.rename(new_name)