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

[LibOS] Add support for two new pseudo files in /proc dir #1245

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions libos/include/libos_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ typedef uint32_t IDTYPE;

#define PID_MAX_LIMIT 4194304 /* Linux limit 2^22, this value is *one greater* than max PID */
#define PID_MAX (PID_MAX_LIMIT - 1)
/* The following values are taken from Linux v6.2 */
#define PIPE_MAX_SIZE 1048576
#define LEASE_BREAK_TIME_MAX 45

typedef uint64_t HASHTYPE;

Expand Down
48 changes: 47 additions & 1 deletion libos/src/fs/proc/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,49 @@ static int proc_pid_max_load(struct libos_dentry* dent, char** out_data, size_t*
return 0;
}

static int proc_lease_break_time_load(struct libos_dentry* dent, char** out_data,
size_t* out_size) {
__UNUSED(dent);

size_t buffer_size = 8; /* enough to hold LEASE_BREAK_TIME_MAX */
char* buffer = malloc(buffer_size);
if (!buffer)
return -ENOMEM;

static_assert(LEASE_BREAK_TIME_MAX <= UINT_MAX, "wrong types");
int ret = snprintf(buffer, buffer_size, "%u", LEASE_BREAK_TIME_MAX);
if (ret < 0) {
free(buffer);
return ret;
}
assert((size_t)ret < buffer_size);

*out_data = buffer;
*out_size = buffer_size;
return 0;
}

static int proc_pipe_max_load(struct libos_dentry* dent, char** out_data, size_t* out_size) {
__UNUSED(dent);

size_t buffer_size = 16; /* enough to hold PIPE_MAX_SIZE */
char* buffer = malloc(buffer_size);
if (!buffer)
return -ENOMEM;

static_assert(PIPE_MAX_SIZE <= UINT_MAX, "wrong types");
int ret = snprintf(buffer, buffer_size, "%u", PIPE_MAX_SIZE);
if (ret < 0) {
free(buffer);
return ret;
}
assert((size_t)ret < buffer_size);

*out_data = buffer;
*out_size = buffer_size;
return 0;
}

int proc_self_follow_link(struct libos_dentry* dent, char** out_target) {
__UNUSED(dent);
IDTYPE pid = g_process.pid;
Expand Down Expand Up @@ -71,8 +114,11 @@ int init_procfs(void) {

struct pseudo_node* sys = pseudo_add_dir(root, "sys");
struct pseudo_node* kernel = pseudo_add_dir(sys, "kernel");
pseudo_add_str(kernel, "pid_max", &proc_pid_max_load);
struct pseudo_node* fs = pseudo_add_dir(sys, "fs");

pseudo_add_str(fs, "pipe-max-size", &proc_pipe_max_load);
pseudo_add_str(fs, "lease-break-time", &proc_lease_break_time_load);
pseudo_add_str(kernel, "pid_max", &proc_pid_max_load);
pseudo_add_str(root, "meminfo", &proc_meminfo_load);
pseudo_add_str(root, "cpuinfo", &proc_cpuinfo_load);
pseudo_add_str(root, "stat", &proc_stat_load);
Expand Down
8 changes: 7 additions & 1 deletion libos/test/fs/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@
type __dummy; \
__builtin_add_overflow((val), 0, &__dummy); \
})

#define CHECK(x) ({ \
__typeof__(x) _x = (x); \
if (_x == -1) { \
err(1, "error at %s (line %d): %m", #x, __LINE__); \
} \
_x; \
})
noreturn void fatal_error(const char* fmt, ...);
void setup(void);
int open_input_fd(const char* path);
Expand Down
1 change: 1 addition & 0 deletions libos/test/fs/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ tests = {
},
'open_close': {},
'open_flags': {},
'proc_pseudo_files': {},
'read_write': {},
'seek_tell': {},
'seek_tell_truncate': {},
Expand Down
64 changes: 64 additions & 0 deletions libos/test/fs/proc_pseudo_files.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2023 Fortanix Inc
* Nirjhar Roy <[email protected]> */

/* Test description: this test reads the contents of the pseudo file /proc/sys/fs/pipe-max-size and
* /proc/sys/fs/lease-break-time and then tries to match the read contents with the expected
* contents. */

#include <assert.h>
#include <err.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ucontext.h>

#include "common.h"

#define BUF_SZ 1024
/* The following values are defined in gramine/libos/include/libos_types.h */
#define PIPE_MAX_SIZE "1048576"
#define LEASE_BREAK_TIME "45"

int main(void) {
struct test_cases {
const char* path;
const char* expected_value;
size_t expected_length;
} tc [] = {
{
"/proc/sys/fs/pipe-max-size",
PIPE_MAX_SIZE,
strlen(PIPE_MAX_SIZE)
},
{
"/proc/sys/fs/lease-break-time",
LEASE_BREAK_TIME,
strlen(LEASE_BREAK_TIME)
},
};

char buf[BUF_SZ];
for (size_t i = 0; i < sizeof(tc)/sizeof(*tc); i++) {
memset(buf, 0, sizeof(buf));
int fd = open_input_fd(tc[i].path);
if (fd < 0)
errx(1,"opening file %s failed", tc[i].path);
read_fd(tc[i].path, fd, buf, tc[i].expected_length);
if (strcmp(tc[i].expected_value, buf)) {
errx(1,"Content mismatch for file = %s. Expected %s got %s", tc[i].path,
tc[i].expected_value, buf);
}

struct stat sb;
CHECK(stat(tc[i].path, &sb));
if (!S_ISREG(sb.st_mode))
errx(1,"Unexpected type for file = %s. Expected S_ISREG", tc[i].path);
CHECK(close(fd));
}
puts("TEST OK");
return 0;
}
14 changes: 14 additions & 0 deletions libos/test/fs/test_fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,17 @@ def test_002_multiple_writers_many_processes(self):
@unittest.skip('file handle sync is not supported yet')
def test_003_multiple_writers_many_processes_and_threads(self):
self._test_multiple_writers(20, 5, 5)

class TC_02_Proc_Pseudo_Files(RegressionTestCase):
TEST_DIR = 'tmp'

def setUp(self):
shutil.rmtree(self.TEST_DIR, ignore_errors=True)
os.mkdir(self.TEST_DIR)

def tearDown(self):
shutil.rmtree(self.TEST_DIR)

def test_000_proc_pseudo_files(self):
stdout, stderr = self.run_binary(['proc_pseudo_files'])
self.assertIn('TEST OK', stdout)
1 change: 1 addition & 0 deletions libos/test/fs/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ manifests = [
"multiple_writers",
"open_close",
"open_flags",
"proc_pseudo_files",
"read_write",
"seek_tell",
"seek_tell_truncate",
Expand Down