[lxc-devel] [lxc/master] lxc_user_nic: don't depend on MAP_FIXED
brauner on Github
lxc-bot at linuxcontainers.org
Tue Mar 17 14:06:58 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 407 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200317/9ed9f121/attachment.bin>
-------------- next part --------------
From e0b03bf9c08a488330de8a85ebeb638fc0d1bb1f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 17 Mar 2020 14:55:45 +0100
Subject: [PATCH] lxc_user_nic: don't depend on MAP_FIXED
as this breaks on sparc.
Closes #3262.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/cmd/lxc_user_nic.c | 87 +++++++++-----------------------------
src/lxc/file_utils.c | 13 +++++-
src/lxc/file_utils.h | 3 ++
3 files changed, 35 insertions(+), 68 deletions(-)
diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c
index 7a2e47011b..682db719b0 100644
--- a/src/lxc/cmd/lxc_user_nic.c
+++ b/src/lxc/cmd/lxc_user_nic.c
@@ -77,7 +77,7 @@ static int open_and_lock(const char *path)
int ret;
struct flock lk;
- fd = open(path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
+ fd = open(path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | O_CLOEXEC);
if (fd < 0) {
CMD_SYSERROR("Failed to open \"%s\"\n", path);
return -1;
@@ -592,40 +592,29 @@ struct entry_line {
static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
char *net_dev, bool *found_nicname)
{
+ __do_free char *buf = NULL;
__do_free struct entry_line *entry_lines = NULL;
- int i, ret;
- char *buf, *buf_end, *buf_start;
- struct stat sb;
int n = 0;
+ size_t length = 0;
+ char *buf_end, *buf_start;
bool found, keep;
- ret = fstat(fd, &sb);
- if (ret < 0) {
- CMD_SYSERROR("Failed to fstat\n");
- return false;
- }
-
- if (!sb.st_size)
- return false;
-
- buf = lxc_strmmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (buf == MAP_FAILED) {
- CMD_SYSERROR("Failed to establish shared memory mapping\n");
+ buf = fd_to_buf(fd, &length);
+ if (!buf) {
+ CMD_SYSERROR("Failed to read database file\n");
return false;
}
buf_start = buf;
- buf_end = buf + sb.st_size;
+ buf_end = buf + length;
while ((buf_start = find_line(buf_start, buf_end, name, net_type,
net_link, net_dev, &(bool){true}, &found,
&keep))) {
struct entry_line *newe;
newe = realloc(entry_lines, sizeof(*entry_lines) * (n + 1));
- if (!newe) {
- lxc_strmunmap(buf, sb.st_size);
+ if (!newe)
return false;
- }
if (found)
*found_nicname = true;
@@ -643,7 +632,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
buf_start = buf;
- for (i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
if (!entry_lines[i].keep)
continue;
@@ -653,12 +642,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
buf_start++;
}
- ret = ftruncate(fd, buf_start - buf);
- lxc_strmunmap(buf, sb.st_size);
- if (ret < 0)
- CMD_SYSERROR("Failed to set new file size\n");
-
- return true;
+ return ftruncate(fd, buf_start - buf) == 0;
}
static int count_entries(char *buf, off_t len, char *name, char *net_type, char *net_link)
@@ -685,14 +669,13 @@ static int count_entries(char *buf, off_t len, char *name, char *net_type, char
static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
char *intype, char *br, int allowed, char **cnic)
{
- __do_free char *newline = NULL;
+ __do_free char *buf = NULL, *newline = NULL;
+ size_t length = 0;
int ret;
size_t slen;
char *owner;
char nicname[IFNAMSIZ];
- struct stat sb;
struct alloted_s *n;
- char *buf = NULL;
uid_t uid;
for (n = names; n != NULL; n = n->next)
@@ -703,34 +686,25 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
owner = names->name;
- ret = fstat(fd, &sb);
- if (ret < 0) {
- CMD_SYSERROR("Failed to fstat\n");
+ buf = fd_to_buf(fd, &length);
+ if (!buf) {
+ CMD_SYSERROR("Failed to read database file\n");
return NULL;
}
- if (sb.st_size > 0) {
- buf = lxc_strmmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (buf == MAP_FAILED) {
- CMD_SYSERROR("Failed to establish shared memory mapping\n");
- return NULL;
- }
-
+ if (length > 0) {
owner = NULL;
for (n = names; n != NULL; n = n->next) {
int count;
- count = count_entries(buf, sb.st_size, n->name, intype, br);
+ count = count_entries(buf, length, n->name, intype, br);
if (count >= n->allowed)
continue;
owner = n->name;
break;
}
-
- lxc_strmunmap(buf, sb.st_size);
}
if (!owner)
@@ -787,29 +761,8 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
return NULL;
}
- /* Note that the file needs to be truncated to the size **without** the
- * \0 byte! Files are not \0-terminated!
- */
- ret = ftruncate(fd, sb.st_size + slen);
- if (ret < 0)
- CMD_SYSERROR("Failed to truncate file\n");
-
- buf = lxc_strmmap(NULL, sb.st_size + slen, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (buf == MAP_FAILED) {
- CMD_SYSERROR("Failed to establish shared memory mapping\n");
-
- if (lxc_netdev_delete_by_name(nicname) != 0)
- usernic_error("Error unlinking %s\n", nicname);
-
- return NULL;
- }
-
- /* Note that the memory needs to be moved in the buffer **without** the
- * \0 byte! Files are not \0-terminated!
- */
- memmove(buf + sb.st_size, newline, slen);
- lxc_strmunmap(buf, sb.st_size + slen);
+ if (lxc_pwrite_nointr(fd, newline, slen, length) != slen)
+ CMD_SYSERROR("Failed to append new entry \"%s\" to database file", newline);
return strdup(nicname);
}
diff --git a/src/lxc/file_utils.c b/src/lxc/file_utils.c
index ab445751bd..650facc8d0 100644
--- a/src/lxc/file_utils.c
+++ b/src/lxc/file_utils.c
@@ -133,6 +133,17 @@ ssize_t lxc_write_nointr(int fd, const void *buf, size_t count)
return ret;
}
+ssize_t lxc_pwrite_nointr(int fd, const void *buf, size_t count, off_t offset)
+{
+ ssize_t ret;
+
+ do {
+ ret = pwrite(fd, buf, count, offset);
+ } while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
ssize_t lxc_send_nointr(int sockfd, void *buf, size_t len, int flags)
{
ssize_t ret;
@@ -400,7 +411,7 @@ int fd_to_fd(int from, int to)
return 0;
}
-static char *fd_to_buf(int fd, size_t *length)
+char *fd_to_buf(int fd, size_t *length)
{
__do_free char *copy = NULL;
diff --git a/src/lxc/file_utils.h b/src/lxc/file_utils.h
index 8b31b976e6..cb69f793ab 100644
--- a/src/lxc/file_utils.h
+++ b/src/lxc/file_utils.h
@@ -24,6 +24,8 @@ extern int lxc_read_from_file(const char *filename, void *buf, size_t count);
/* send and receive buffers completely */
extern ssize_t lxc_write_nointr(int fd, const void *buf, size_t count);
+extern ssize_t lxc_pwrite_nointr(int fd, const void *buf, size_t count,
+ off_t offset);
extern ssize_t lxc_send_nointr(int sockfd, void *buf, size_t len, int flags);
extern ssize_t lxc_read_nointr(int fd, void *buf, size_t count);
extern ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count,
@@ -49,6 +51,7 @@ extern FILE *fopen_cloexec(const char *path, const char *mode);
extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset,
size_t count);
extern char *file_to_buf(const char *path, size_t *length);
+extern char *fd_to_buf(int fd, size_t *length);
extern int fd_to_fd(int from, int to);
extern int lxc_open_dirfd(const char *dir);
extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer);
More information about the lxc-devel
mailing list