diff options
| author | zsdc <taras@vyos.io> | 2024-03-13 00:40:09 +0200 | 
|---|---|---|
| committer | zsdc <taras@vyos.io> | 2024-03-13 00:40:09 +0200 | 
| commit | f74923202311e853b677e52cd83bae2be9605c26 (patch) | |
| tree | 81677eaa9f6e6993cb1129fba5a26a68ea83a54f /python | |
| parent | a4e21377271cfcf6359ed23db8a90129e264ba4d (diff) | |
| download | vyos-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.py | 36 | 
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) | 
