Skip to content

Reload environment variables when an initialized module is started.#8

Closed
cfallin wants to merge 1 commit intobytecodealliance:mainfrom
cfallin:reload-env-vars
Closed

Reload environment variables when an initialized module is started.#8
cfallin wants to merge 1 commit intobytecodealliance:mainfrom
cfallin:reload-env-vars

Conversation

@cfallin
Copy link
Copy Markdown
Member

@cfallin cfallin commented Mar 9, 2021

wasi-libc caches environment variable state on the first call to
getenv(). Some applications using Wizer may invoke getenv() during
initialization, but still wish to access the current environment
variables (not their values at pre-initialization) during runtime.
Fortunately, wasi-libc provides an API for this: invoking
__wasilibc_initialize_environ() clears its cached state and allows it
to fetch the environment anew the next time getenv() is called.
This is likely less surprising than the alternative (environment
variables captured during pre-init) because calls to getenv() may be
buried in unsuspecting places, e.g. inside of libraries that take
logging settings from the environment.

cc @tschneidereit

wasi-libc caches environment variable state on the first call to
`getenv()`. Some applications using Wizer may invoke `getenv()` during
initialization, but still wish to access the current environment
variables (not their values at pre-initialization) during runtime.
Fortunately, wasi-libc provides an API for this: invoking
`__wasilibc_initialize_environ()` clears its cached state and allows it
to fetch the environment anew the next time `getenv()` is called.
This is likely less surprising than the alternative (environment
variables captured during pre-init) because calls to `getenv()` may be
buried in unsuspecting places, e.g. inside of libraries that take
logging settings from the environment.
Copy link
Copy Markdown
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to clear the cached values at the end of the initialization, rather than always eagerly spending time on repopulating the cache on resumption? If a program isn't using env vars, or isn't using them right away, then this is wasted initialization work, and our whole goal here is to avoid unnecessary initialization :-p

@cfallin
Copy link
Copy Markdown
Member Author

cfallin commented Mar 9, 2021

I sadly did not find a function to do that, and the underlying global variable whose value indicates whether initialization has occurred does not seem to be exported from libc, so we can't modify it from the outside.

@sunfishcode any thoughts on adding an API to allow this (or more generally "clear all cached state in libc")?

@tschneidereit
Copy link
Copy Markdown
Member

Thank you for tackling this! I agree with @fitzgen that clearing the cache post-init would be much nicer, if we can get it to work, yes. At least this unblocks usage of Wizer for use cases that need env var as part of the interface, though.

@fitzgen
Copy link
Copy Markdown
Member

fitzgen commented Mar 10, 2021

To be clear, I'm not against landing this as a temporary work around, but I'd really like to get the proper solution in place sooner rather than later.

@tschneidereit
Copy link
Copy Markdown
Member

To be clear, I'm not against landing this as a temporary work around, but I'd really like to get the proper solution in place sooner rather than later.

Understood! :) I, OTOH, would prefer having the proper solution, and only land this as a stop-gap should we conclude that the proper solution might take a while. @sunfishcode, your guidance on that would be very valuable.

sunfishcode added a commit to WebAssembly/wasi-libc that referenced this pull request Mar 11, 2021
Add a `__wasilibc_deinit_environ` function which clears the current
environment variable state to the state where next time the environment
variable functions are called, they'll reinitialize the environment.

And add a `__wasilibc_maybe_reinitialize_environ_eagerly` function to
reinitialize the environment variable state if `environ` or `_environ`
are needed.

These functions are needed by wizer to be able to suspend and resume
a program and have it read new environment variables from the host
environment; see bytecodealliance/wizer#8 for background.
@sunfishcode
Copy link
Copy Markdown
Member

Yes, I think this is something WASI libc can do. It's a little tricky because C's environ static variable API doesn't have a function call that we can use to kick off lazy initialization.

I've now filed WebAssembly/wasi-libc#237 to propose a fix for this. The way to use it is to call __wasilibc_deinitialize_environ before suspending, and __wasilibc_maybe_reinitialize_environ_eagerly after resuming. If environ isn't used, __wasilibc_maybe_reinitialize_environ_eagerly will do nothing. If environ is used, __wasilibc_maybe_reinitialize_environ_eagerly will perform an eager initialization.

sunfishcode added a commit to WebAssembly/wasi-libc that referenced this pull request May 25, 2021
Add a `__wasilibc_deinit_environ` function which clears the current
environment variable state to the state where next time the environment
variable functions are called, they'll reinitialize the environment.

And add a `__wasilibc_maybe_reinitialize_environ_eagerly` function to
reinitialize the environment variable state if `environ` or `_environ`
are needed.

These functions are needed by wizer to be able to suspend and resume
a program and have it read new environment variables from the host
environment; see bytecodealliance/wizer#8 for background.
@fitzgen
Copy link
Copy Markdown
Member

fitzgen commented Aug 4, 2021

@cfallin now that WebAssembly/wasi-libc#237 has merged, I think this PR can be updated to use that new API and then we can (finally!) merge this.

@cfallin
Copy link
Copy Markdown
Member Author

cfallin commented Aug 5, 2021

Ah, great, I hadn't seen that merge!

@sunfishcode are there plans to cut a new release of wasi-sdk soon that includes that patch? It looks like the last release was on 2020-12-02.

@sunfishcode
Copy link
Copy Markdown
Member

Yes, we should cut a new release soon.

@cfallin
Copy link
Copy Markdown
Member Author

cfallin commented Feb 9, 2022

Cleaning up old PRs and closing this now.

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.

4 participants