Skip to content

Commit f3dcc2f

Browse files
committed
boot-qemu.py: Refactor getting values from configuration
This will come in handy in trying to warn people when they are missing configurations needed for certain features. While we are at it, make getting the configuration value a little more robust using re.search() + match groups. Signed-off-by: Nathan Chancellor <[email protected]>
1 parent 2eca31e commit f3dcc2f

File tree

2 files changed

+50
-34
lines changed

2 files changed

+50
-34
lines changed

boot-qemu.py

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,42 @@ def can_use_kvm(can_test_for_kvm, guest_arch):
152152
return False
153153

154154

155+
def get_config_val(kernel_arg, config_key):
156+
"""
157+
Attempt to get configuration value from a .config relative to
158+
kernel_location.
159+
160+
Parameters:
161+
kernel_arg (str): The value of the '--kernel' argument.
162+
163+
Returns:
164+
The configuration value if it can be found, None if not.
165+
"""
166+
# kernel_arg is either a path to the kernel source or a full kernel
167+
# location. If it is a file, we need to strip off the basename so that we
168+
# can easily navigate around with '..'.
169+
if (kernel_dir := Path(kernel_arg)).is_file():
170+
kernel_dir = kernel_dir.parent
171+
172+
# If kernel_location is the kernel source, the configuration will be at
173+
# <kernel_dir>/.config
174+
#
175+
# If kernel_location is a full kernel location, it could either be:
176+
# * <kernel_dir>/.config (if the image is vmlinux)
177+
# * <kernel_dir>/../../../.config (if the image is in arch/*/boot/)
178+
# * <kernel_dir>/config (if the image is in a TuxMake folder)
179+
config_locations = [".config", "../../../.config", "config"]
180+
if (config_file := utils.find_first_file(kernel_dir,
181+
config_locations,
182+
required=False)):
183+
config_txt = config_file.read_text(encoding='utf-8')
184+
if (match := re.search(f"^{config_key}=(.*)$", config_txt,
185+
flags=re.M)):
186+
return match.groups()[0]
187+
188+
return None
189+
190+
155191
def get_smp_value(args):
156192
"""
157193
Get the value of '-smp' based on user input and kernel configuration.
@@ -176,41 +212,16 @@ def get_smp_value(args):
176212
if args.smp:
177213
return args.smp
178214

179-
# kernel_location is either a path to the kernel source or a full kernel
180-
# location. If it is a file, we need to strip off the basename so that we
181-
# can easily navigate around with '..'.
182-
kernel_dir = Path(args.kernel_location)
183-
if kernel_dir.is_file():
184-
kernel_dir = kernel_dir.parent
185-
186-
# If kernel_location is the kernel source, the configuration will be at
187-
# <kernel_dir>/.config
188-
#
189-
# If kernel_location is a full kernel location, it could either be:
190-
# * <kernel_dir>/.config (if the image is vmlinux)
191-
# * <kernel_dir>/../../../.config (if the image is in arch/*/boot/)
192-
# * <kernel_dir>/config (if the image is in a TuxMake folder)
193-
config_file = None
194-
for config_name in [".config", "../../../.config", "config"]:
195-
config_path = kernel_dir.joinpath(config_name)
196-
if config_path.is_file():
197-
config_file = config_path
198-
break
199-
200215
# Choose a sensible default value based on treewide defaults for
201216
# CONFIG_NR_CPUS then get the actual value if possible.
202-
config_nr_cpus = 8
203-
if config_file:
204-
with open(config_file, encoding='utf-8') as file:
205-
for line in file:
206-
if "CONFIG_NR_CPUS=" in line:
207-
config_nr_cpus = int(line.split("=", 1)[1])
208-
break
217+
if not (config_nr_cpus := get_config_val(args.kernel_location,
218+
'CONFIG_NR_CPUS')):
219+
config_nr_cpus = 8
209220

210221
# Use the minimum of the number of usable processors for the script or
211222
# CONFIG_NR_CPUS.
212223
usable_cpus = os.cpu_count()
213-
return min(usable_cpus, config_nr_cpus)
224+
return min(usable_cpus, int(config_nr_cpus))
214225

215226

216227
def setup_cfg(args):

utils.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def die(string):
3030
sys.exit(1)
3131

3232

33-
def find_first_file(relative_root, possible_files):
33+
def find_first_file(relative_root, possible_files, required=True):
3434
"""
3535
Attempts to find the first option available in the list of files relative
3636
to a specified root folder.
@@ -41,6 +41,8 @@ def find_first_file(relative_root, possible_files):
4141
possible_files (list): A list of Paths that may be within the relative
4242
root folder. They will be automatically appended
4343
to relative_root.
44+
required (bool): Whether or not the requested file is required for the
45+
script to work properly.
4446
Returns:
4547
The full path to the first file found in the list. If none could be
4648
found, an Exception is raised.
@@ -49,10 +51,13 @@ def find_first_file(relative_root, possible_files):
4951
if (full_path := relative_root.joinpath(possible_file)).exists():
5052
return full_path
5153

52-
files_str = "', '".join([str(elem) for elem in possible_files])
53-
raise Exception(
54-
f"No files from list ('{files_str}') could be found within '{relative_root}'!"
55-
)
54+
if required:
55+
files_str = "', '".join([str(elem) for elem in possible_files])
56+
raise Exception(
57+
f"No files from list ('{files_str}') could be found within '{relative_root}'!"
58+
)
59+
60+
return None
5661

5762

5863
def get_full_kernel_path(kernel_location, image, arch=None):

0 commit comments

Comments
 (0)