Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kernel command line: add support for arbitrary configuration settings #1983

Merged
merged 6 commits into from
Dec 15, 2023

Conversation

francescolavra
Copy link
Member

@francescolavra francescolavra commented Dec 13, 2023

This patch set adds support for changing arbitrary settings in the root tuple via the kernel command line (which is retrieved by the kernel when booting under AWS Firecracker on x86).
With these changes, it is possible for example to override the network settings when starting an instance from a given image (without modifying the image itself) by specifying those settings in the kernel command line ("boot_args" parameter in the Firecracker configuration file), as in the following example:
"en1.ipaddr=10.3.3.6 en1.netmask=255.255.0.0 en1.gateway=10.3.0.1".
In the above example, "en1" identifies the first network interface; if multiple interfaces are used (en2, en3, etc.), each of them can be configured independently.
Example to configure a static IPv6 address on the first network interface:
"en1.ip6addr=20::A8FC:FF:7600:AA"
Example to add an environment variable (or override its value if the variable is already present in the image):
"environment.VAR_NAME=VAR_VALUE"
Example to modify the program arguments:
"arguments.0=/bin/my-program arguments.1=--my-option"

The first 3 commits are fixes for issues that have been exposed by the last 2 commits; the fix in the first commit allows all available physical memory ranges to be used by the kernel, without requiring 2MB alignment of the range start.

Closes #1976

The id heap has the property that allocated values are aligned to
the nearest power-of-2 value equal to or greater than the
allocation size. In the current code, it can happen that an
allocation of a given size served by an id heap range whose start
value is not aligned to the allocation size returns a non-aligned
value.
This patch fixes the above issue by removing the padding of the
start argument in the bitmap allocation function (because the start
value is already appropriately aligned by the id heap in the
id_alloc_from_range() function).
In order to optimize performance of bitmap allocations, bitmap
ranges added to an id heap have now a start value always aligned to
BITMAP_WORDLEN (even if the corresponding id heap range is not
aligned), so that the start argument to bitmap_alloc_within_range()
is always aligned to BITMAP_WORDLEN for allocation size values
greater than (BITMAP_WORDLEN / 2). The bitmap_start field of struct
id_range contains the aligned start value of a range, and is used
to apply the appropriate offsets during allocations and
deallocations.
Since now the id heap works correctly with arbitrarily aligned
ranges, we can remove the padding to 2MB of the start value of
physical memory ranges, which was causing a noticeable waste of
memory space in low-memory machines.
src/kernel/init.c Outdated Show resolved Hide resolved
This new parameter is used to determine whether a tagged region
allocator should be multithread-safe. This change, beside allowing
to remove duplicated code, avoids the unnecessary instantiation of
locking heap wrappers in the aarch64 code, where the tagged region
allocator uses directly the locked heap and thus is always
multithread-safe.
Initialization of tagged region allocators is being moved from
platform-specific code to kernel_runtime_init(). In addition, the
management subsystem now uses locking heaps instead of non-locking
heaps, so that it can be used safely at runtime.
The general (non-locked) kernel heap is not safe to use after the
call to kernel_runtime_init(); this change replaces this heap with
the locked heap in a few places where the code is executed from the
scheduler runloop.
This function returns true if the value supplied as argument is of
a composite type, i.e. it can be operated on using get(), set() and
iterate().
Calls to is_tuple() and is_vector() have been refactored to use
is_composite() where appropriate; this removes some duplicated
code.
This patch enhances the tuple_notifer implementation so that it can
be used with a parent vector (alternatively to a parent tuple) and
adds a copy-on-write functionality that allows to operate (i.e.
execute get, set or iterate operations) on a composite value (tuple
or vector) without modifying the original value or any nested
composite values.
These new features can be used for example to modify the root
configuration tuple (e.g. to add or change debug options,
environment variables, or program arguments) without persisting
these changes in the root filesystem.
The get_root_tuple() kernel function now returns the tuple_notifier
that wraps the root tuple (instead of the root tuple itself), so
that configuration settings are initially retrieved from the root
filesystem and can be changed at runtime without affecting the
contents of the boot disk.
This patch adds support for changing arbitrary settings in the root
tuple via the kernel command line (which is retrieved by the kernel
when booting under AWS Firecracker on x86).
The PC platform code has been amended by adding a new
REGION_CMDLINE region type holding the location and size of the
command line, which can be accessed later in the boot process. The
existing parsing of the virtio_mmio command line options has been
moved to kernel/init.c, so that it can be called by
virtio_mmio_enum_devs() instead of platform-specific code. The only
platform-specific code is the code that retrieves (and potentially
updates) the command line, while the parsing implementation is in
kernel/init.c.
With these changes, it is possible for example to override the
network settings when starting an instance from a given image
(without modifying the image itself) by specifying those settings
in the kernel command line ("boot_args" parameter in the
Firecracker configuration file), as in the following example:
"en1.ipaddr=10.3.3.6 en1.netmask=255.255.0.0 en1.gateway=10.3.0.1".
In the above example, "en1" identifies the first network interface;
if multiple interfaces are used (en2, en3, etc.), each of them can
be configured independently.
Example to configure a static IPv6 address on the first network
interface:
"en1.ip6addr=20::A8FC:FF:7600:AA"
Example to add an environment variable (or override its value if
the variable is already present in the image):
"environment.VAR_NAME=VAR_VALUE"
Example to modify the program arguments:
"arguments.0=/bin/my-program arguments.1=--my-option"

Closes #1976
@francescolavra
Copy link
Member Author

I added 2 commits to fix concurrency issues observed when running CI tests.

@francescolavra francescolavra merged commit efd391b into master Dec 15, 2023
5 checks passed
@francescolavra francescolavra deleted the feature/ture/cmdline branch December 15, 2023 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

allow passing in network settings via kernel boot args for firecracker
3 participants