Skip to content

Commit

Permalink
Merge pull request #1151 from giuseppe/read-proc-file-using-page
Browse files Browse the repository at this point in the history
minor cleanups to read_file
  • Loading branch information
flouthoc committed Feb 27, 2023
2 parents e94022c + 4748543 commit 2c83c0e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
56 changes: 40 additions & 16 deletions src/libcrun/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,19 @@ check_running_in_user_namespace (libcrun_error_t *err)
return ret;
}

static size_t
get_page_size ()
{
static atomic_long cached_pagesize = 0;
atomic_long pagesize = cached_pagesize;
if (pagesize == 0)
{
pagesize = (long) sysconf (_SC_PAGESIZE);
cached_pagesize = pagesize;
}
return (size_t) pagesize;
}

static int selinux_enabled = -1;
static int apparmor_enabled = -1;

Expand All @@ -725,7 +738,7 @@ libcrun_initialize_selinux (libcrun_error_t *err)
if (UNLIKELY (fd < 0))
return crun_make_error (err, errno, "open /proc/mounts");

ret = read_all_fd (fd, "/proc/mounts", &out, &len, err);
ret = read_all_fd_with_size_hint (fd, "/proc/mounts", &out, &len, get_page_size (), err);
if (UNLIKELY (ret < 0))
return ret;

Expand Down Expand Up @@ -866,21 +879,26 @@ set_apparmor_profile (const char *profile, bool now, libcrun_error_t *err)
}

int
read_all_fd (int fd, const char *description, char **out, size_t *len, libcrun_error_t *err)
read_all_fd_with_size_hint (int fd, const char *description, char **out, size_t *len, size_t size_hint, libcrun_error_t *err)
{
int ret;
cleanup_free char *buf = NULL;
size_t nread, allocated;
size_t pagesize = 0;
off_t size = 0;
cleanup_free char *buf = NULL;
int ret;

ret = get_file_size (fd, &size);
if (UNLIKELY (ret < 0))
return crun_make_error (err, errno, "error stat'ing file `%s`", description);
if (size_hint)
allocated = size_hint;
else
{
ret = get_file_size (fd, &size);
if (UNLIKELY (ret < 0))
return crun_make_error (err, errno, "error stat'ing file `%s`", description);

allocated = size == 0 ? 1023 : size;
}

/* NUL terminate the buffer. */
allocated = size + 1;
if (size == 0)
allocated = 1023;
buf = xmalloc (allocated + 1);
nread = 0;
while ((size && nread < (size_t) size) || size == 0)
Expand All @@ -896,7 +914,14 @@ read_all_fd (int fd, const char *description, char **out, size_t *len, libcrun_e

if (nread == allocated)
{
allocated += 4096;
if (size)
break;

if (pagesize == 0)
pagesize = get_page_size ();

allocated += pagesize;

buf = xrealloc (buf, allocated + 1);
}
}
Expand Down Expand Up @@ -1160,15 +1185,14 @@ copy_from_fd_to_fd (int src, int dst, int consume, libcrun_error_t *err)
{
int ret;
ssize_t nread;
size_t pagesize = get_page_size ();
do
{
cleanup_free char *buffer = NULL;
ssize_t remaining;

#define BUFFER_SIZE 4096

#ifdef HAVE_COPY_FILE_RANGE
nread = copy_file_range (src, NULL, dst, NULL, BUFFER_SIZE, 0);
nread = copy_file_range (src, NULL, dst, NULL, pagesize, 0);
if (nread < 0 && (errno == EINVAL || errno == EXDEV))
goto fallback;
if (consume && nread < 0 && errno == EAGAIN)
Expand All @@ -1182,8 +1206,8 @@ copy_from_fd_to_fd (int src, int dst, int consume, libcrun_error_t *err)
fallback:
#endif

buffer = xmalloc (BUFFER_SIZE);
nread = TEMP_FAILURE_RETRY (read (src, buffer, BUFFER_SIZE));
buffer = xmalloc (pagesize);
nread = TEMP_FAILURE_RETRY (read (src, buffer, pagesize));
if (consume && nread < 0 && errno == EAGAIN)
return 0;
if (nread < 0 && errno == EIO)
Expand Down
8 changes: 7 additions & 1 deletion src/libcrun/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,13 @@ int add_selinux_mount_label (char **ret, const char *data, const char *label, co

int set_apparmor_profile (const char *profile, bool now, libcrun_error_t *err);

int read_all_fd (int fd, const char *description, char **out, size_t *len, libcrun_error_t *err);
int read_all_fd_with_size_hint (int fd, const char *description, char **out, size_t *len, size_t hint, libcrun_error_t *err);

static inline int
read_all_fd (int fd, const char *description, char **out, size_t *len, libcrun_error_t *err)
{
return read_all_fd_with_size_hint (fd, description, out, len, 0, err);
}

int read_all_file (const char *path, char **out, size_t *len, libcrun_error_t *err);

Expand Down

0 comments on commit 2c83c0e

Please sign in to comment.