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

lkl: add LKL_HIJACK_SYSCTL to configure sysctl values #319

Merged
merged 1 commit into from
Feb 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Documentation/lkl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@ are the list of those variable for your environment.
```
$ LKL_HIJACK_OFFLOAD=0x8002 lkl-hijack.sh ./netserver -D -f
```
* LKL_HIJACK_SYSCTL

Configure sysctl values of the booted kernel via the hijack library. Multiple
entries can be specified.
```
$ LKL_HIJACK_SYSCTL="net.ipv4.tcp_wmem=4096 87380 2147483647"
./bin/lkl-hijack.sh ip address show
```

FAQ
===
Expand Down
19 changes: 19 additions & 0 deletions tools/lkl/include/lkl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ extern "C" {
#undef class
#endif

#if defined(__MINGW32__)
#define strtok_r strtok_s
#endif

#if __LKL__BITS_PER_LONG == 64
#define lkl_sys_stat lkl_sys_newstat
#define lkl_sys_lstat lkl_sys_newlstat
Expand Down Expand Up @@ -479,6 +483,21 @@ int lkl_qdisc_add(int ifindex, char *root, char *type);
*/
void lkl_qdisc_parse_add(int ifindex, char *entries);

/**
* lkl_sysctl - write a sysctl value
*
* @path - the path to an sysctl entry (e.g., "net.ipv4.tcp_wmem");
* @value - the value of the sysctl (e.g., "4096 87380 2147483647")
*/
int lkl_sysctl(const char *path, const char *value);

/**
* lkl_sysctl_parse_write - Configure sysctl parameters with strings
*
* @sysctls - Configure sysctl parameters as the form of "key=value;..."
*/
void lkl_sysctl_parse_write(const char *sysctls);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions tools/lkl/lib/hijack/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ hijack_init(void)
char *offload1 = getenv("LKL_HIJACK_OFFLOAD");
int offload = 0;
char boot_cmdline[256] = "\0";
char *sysctls = getenv("LKL_HIJACK_SYSCTL");

memset(&nd_args, 0, sizeof(struct lkl_netdev_args));
if (!debug) {
Expand Down Expand Up @@ -436,6 +437,8 @@ hijack_init(void)
if (nd_ifindex >= 0 && qdisc_entries)
lkl_qdisc_parse_add(nd_ifindex, qdisc_entries);

if (sysctls)
lkl_sysctl_parse_write(sysctls);
}

void __attribute__((destructor))
Expand Down
56 changes: 56 additions & 0 deletions tools/lkl/lib/utils.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <lkl_host.h>

static const char * const lkl_err_strings[] = {
Expand Down Expand Up @@ -205,3 +206,58 @@ void lkl_bug(const char *fmt, ...)

lkl_host_ops.panic();
}

int lkl_sysctl(const char *path, const char *value)
{
int ret;
int fd;
char *delim, *p;
char full_path[256];
Copy link
Member

Choose a reason for hiding this comment

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

Is it better to copy path into full_path first and then replace "." so that lkl_sysctl can be called with const char.

Copy link
Member Author

Choose a reason for hiding this comment

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

agree. fixed this.


lkl_mount_fs("proc");

snprintf(full_path, sizeof(full_path), "/proc/sys/%s", path);
p = full_path;
while ((delim = strstr(p, "."))) {
*delim = '/';
p = delim + 1;
}

fd = lkl_sys_open(full_path, LKL_O_WRONLY | LKL_O_CREAT, 0);
if (fd < 0) {
lkl_printf("lkl_sys_open %s: %s\n",
full_path, lkl_strerror(fd));
return -1;
}
ret = lkl_sys_write(fd, value, strlen(value));
if (ret < 0) {
lkl_printf("lkl_sys_write %s: %s\n",
full_path, lkl_strerror(fd));
}

lkl_sys_close(fd);

return 0;
}

/* Configure sysctl parameters as the form of "key=value;key=value;..." */
void lkl_sysctl_parse_write(const char *sysctls)
{
char *saveptr = NULL, *token = NULL;
char *key = NULL, *value = NULL;
char strings[256];
int ret = 0;

strcpy(strings, sysctls);
for (token = strtok_r(strings, ";", &saveptr); token;
token = strtok_r(NULL, ";", &saveptr)) {
key = strtok(token, "=");
value = strtok(NULL, "=");
ret = lkl_sysctl(key, value);
if (ret) {
lkl_printf("Failed to configure sysctl entries: %s\n",
lkl_strerror(ret));
return;
}
}
}