-
Notifications
You must be signed in to change notification settings - Fork 171
Mount a tmpfs if requested #635
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -835,7 +835,104 @@ char **concat_entrypoint_argv(char **entrypoint, char **config_argv) | |
| return argv; | ||
| } | ||
|
|
||
| static int config_parse_file(char ***argv, char **workdir, | ||
| static unsigned int config_parse_skip(jsmntok_t *token) | ||
| { | ||
| unsigned int n = 1; | ||
|
|
||
| for (int i = 0; i < token->size; i++) { | ||
| n += config_parse_skip(&token[n]); | ||
| } | ||
|
|
||
| return n; | ||
| } | ||
|
|
||
| static bool is_mount_point(const char *path) | ||
| { | ||
| /* | ||
| * Beware that Podman arranges tmpfs auto-mounts. This means stat/lstat | ||
| * cannot be used to check the mount status as it would cause mounting the | ||
| * host tmpfs. Let's look at /proc/mounts instead. | ||
| */ | ||
| FILE *mounts; | ||
| char line[1024]; | ||
| char mount_point[512]; | ||
|
mz-pdm marked this conversation as resolved.
mz-pdm marked this conversation as resolved.
|
||
| bool found = false; | ||
|
|
||
| mounts = fopen("/proc/mounts", "r"); | ||
| if (!mounts) { | ||
| perror("fopen(/proc/mounts)"); | ||
| return false; | ||
| } | ||
|
|
||
| while (fgets(line, sizeof(line), mounts)) { | ||
| /* | ||
| * This doesn't handle escape sequences for spaces and tabs in paths. | ||
| * Not an issue currently as we don't mount any such paths, but could be | ||
| * improved in future. | ||
| */ | ||
| if (sscanf(line, "%*s %511s %*s %*s %*d %*d", mount_point) == 1) { | ||
|
mz-pdm marked this conversation as resolved.
mz-pdm marked this conversation as resolved.
|
||
| if (strcmp(mount_point, path) == 0) { | ||
| found = true; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
mz-pdm marked this conversation as resolved.
|
||
|
|
||
| fclose(mounts); | ||
| return found; | ||
| } | ||
|
|
||
| static char *config_parse_mounts(char *data, jsmntok_t *token) | ||
| { | ||
| jsmntok_t *tmount, *tdestination, *ttype, *tsource; | ||
| unsigned int i, j; | ||
| unsigned int t = 0; | ||
|
|
||
| if (token[t++].type != JSMN_ARRAY) { | ||
| printf("Mounts not an array\n"); | ||
| return NULL; | ||
| } | ||
|
|
||
| for (i = 0; i < token->size; i++) { | ||
| tmount = &token[t++]; | ||
| if (tmount->type != JSMN_OBJECT) { | ||
| printf("Unexpected mounts contents\n"); | ||
| return NULL; | ||
| } | ||
|
mz-pdm marked this conversation as resolved.
|
||
|
|
||
| tdestination = ttype = tsource = NULL; | ||
| for (j = 0; j < tmount->size; j++) { | ||
| if (jsoneq(data, &token[t], "destination") == 0) { | ||
| tdestination = &token[t + 1]; | ||
| t += 2; | ||
| } else if (jsoneq(data, &token[t], "type") == 0) { | ||
| ttype = &token[t + 1]; | ||
| t += 2; | ||
| } else if (jsoneq(data, &token[t], "source") == 0) { | ||
| tsource = &token[t + 1]; | ||
| t += 2; | ||
|
mz-pdm marked this conversation as resolved.
|
||
| } else { | ||
| t += config_parse_skip(&token[t]); | ||
| } | ||
| } | ||
|
|
||
| if (tdestination && ttype && tsource && | ||
| jsoneq(data, ttype, "tmpfs") == 0 && | ||
| jsoneq(data, tsource, "tmpfs") == 0) { | ||
|
mz-pdm marked this conversation as resolved.
|
||
| char *path = config_parse_string(data, tdestination); | ||
| if (path) { | ||
| if (!is_mount_point(path)) { | ||
| return path; | ||
| } | ||
| free(path); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return NULL; | ||
| } | ||
|
mz-pdm marked this conversation as resolved.
|
||
|
|
||
| static int config_parse_file(char ***argv, char **workdir, char **tmpfs, | ||
| const char *config_file) | ||
| { | ||
| jsmn_parser parser; | ||
|
|
@@ -845,7 +942,8 @@ static int config_parse_file(char ***argv, char **workdir, | |
| off_t data_len; | ||
| char **config_argv; | ||
| char **entrypoint; | ||
| int parsed_env, parsed_workdir, parsed_args, parsed_entrypoint; | ||
| int parsed_env, parsed_workdir, parsed_args, parsed_entrypoint, | ||
| parsed_tmpfs; | ||
| int num_tokens; | ||
| int ret = -1; | ||
| int fd; | ||
|
|
@@ -893,10 +991,12 @@ static int config_parse_file(char ***argv, char **workdir, | |
|
|
||
| config_argv = NULL; | ||
| entrypoint = NULL; | ||
| parsed_env = parsed_workdir = parsed_args = parsed_entrypoint = 0; | ||
| parsed_env = parsed_workdir = parsed_args = parsed_entrypoint = | ||
| parsed_tmpfs = 0; | ||
|
|
||
| for (i = 1; i < num_tokens && (!parsed_env || !parsed_args || | ||
| !parsed_workdir || !parsed_entrypoint); | ||
| for (i = 1; | ||
| i < num_tokens && (!parsed_env || !parsed_args || !parsed_workdir || | ||
| !parsed_entrypoint || !parsed_tmpfs); | ||
| i++) { | ||
| if (!parsed_env && jsoneq(data, &tokens[i], "Env") == 0 && | ||
| (i + 1) < num_tokens && tokens[i + 1].type == JSMN_ARRAY) { | ||
|
|
@@ -933,6 +1033,12 @@ static int config_parse_file(char ***argv, char **workdir, | |
| entrypoint = config_parse_args(data, &tokens[i + 1]); | ||
| parsed_entrypoint = 1; | ||
| } | ||
|
|
||
| if (!parsed_tmpfs && jsoneq(data, &tokens[i], "mounts") == 0 && | ||
| (i + 1) < num_tokens && | ||
| (*tmpfs = config_parse_mounts(data, &tokens[i + 1]))) { | ||
|
mz-pdm marked this conversation as resolved.
|
||
| parsed_tmpfs = 1; | ||
| } | ||
| } | ||
|
|
||
| if (config_argv && entrypoint) { | ||
|
|
@@ -1193,6 +1299,7 @@ int main(int argc, char **argv) | |
| #endif | ||
| char *env_init_pid1; | ||
| char *config_workdir, *env_workdir; | ||
| char *config_tmpfs; | ||
| char *rlimits; | ||
| char **config_argv, **exec_argv; | ||
| const char *config_file; | ||
|
|
@@ -1321,6 +1428,7 @@ int main(int argc, char **argv) | |
|
|
||
| config_argv = NULL; | ||
| config_workdir = NULL; | ||
| config_tmpfs = NULL; | ||
|
|
||
| config_file = getenv("KRUN_CONFIG"); | ||
|
|
||
|
|
@@ -1334,14 +1442,26 @@ int main(int argc, char **argv) | |
| config_file = CONFIG_FILE_PATH; | ||
| } | ||
|
|
||
| config_parse_file(&config_argv, &config_workdir, config_file); | ||
| config_parse_file(&config_argv, &config_workdir, &config_tmpfs, | ||
| config_file); | ||
|
|
||
| #if __FreeBSD__ | ||
| if (config_file_mounted) { | ||
| unmount_config_iso(); | ||
| } | ||
| #endif | ||
|
|
||
| if (config_tmpfs) { | ||
| /* TODO: Honour mount flags from the config file. Most notably, | ||
| * tmpcopyup is set by Podman by default, requesting copying the files | ||
| * present in the original directory, e.g. from the image. */ | ||
| if (mount("tmpfs", config_tmpfs, "tmpfs", | ||
| MS_NOEXEC | MS_NOSUID | MS_NODEV | MS_RELATIME, NULL) < 0) { | ||
| perror("mount for tmpfs"); | ||
| exit(-1); | ||
| } | ||
| } | ||
|
Comment on lines
+1445
to
+1463
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The config_tmpfs string is allocated via malloc (inside config_parse_string called by config_parse_mounts) but is never freed in main. This results in a small memory leak. References
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True but it is consistent with handling the other |
||
|
|
||
| krun_home = getenv("KRUN_HOME"); | ||
| if (krun_home) { | ||
| setenv("HOME", krun_home, 1); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.