mirror of
https://github.com/systemd/systemd
synced 2025-10-03 18:54:45 +02:00
Compare commits
5 Commits
97e535c724
...
b33cd6b3ee
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b33cd6b3ee | ||
![]() |
da0d560905 | ||
![]() |
ee1aa61c47 | ||
![]() |
d227b6a7c0 | ||
![]() |
b12dba35d1 |
22
.github/workflows/mkosi.yml
vendored
22
.github/workflows/mkosi.yml
vendored
@ -29,18 +29,22 @@ jobs:
|
|||||||
- name: Install
|
- name: Install
|
||||||
run: sudo apt-get update && sudo apt-get install --no-install-recommends python3-pexpect
|
run: sudo apt-get update && sudo apt-get install --no-install-recommends python3-pexpect
|
||||||
|
|
||||||
# glibc 2.33-3 shipped on 2021-02-06 breaks running Arch containers on
|
|
||||||
# systems with older kernels (like Ubuntu Focal). Until the issue is
|
|
||||||
# resolved, let's pin the Arch repositories to glibc 2.32-5 to mitigate
|
|
||||||
# the annoying CI fails.
|
|
||||||
#
|
|
||||||
# See: https://bugs.archlinux.org/task/69563
|
|
||||||
- name: Pin repositories to 2021-02-05
|
|
||||||
run: sed -i '/^\[Distribution\]/aMirror=https://archive.archlinux.org/repos/2021/02/05/' .mkosi/mkosi.arch
|
|
||||||
|
|
||||||
- name: Symlink
|
- name: Symlink
|
||||||
run: ln -s .mkosi/mkosi.${{ matrix.distro }} mkosi.default
|
run: ln -s .mkosi/mkosi.${{ matrix.distro }} mkosi.default
|
||||||
|
|
||||||
|
# Ubuntu's systemd-nspawn doesn't support faccessat2() syscall, which is
|
||||||
|
# required, since current Arch's glibc implements faccessat() via faccessat2().
|
||||||
|
- name: Update systemd-nspawn
|
||||||
|
if: ${{ matrix.distro == 'arch' }}
|
||||||
|
run: |
|
||||||
|
echo "deb-src http://archive.ubuntu.com/ubuntu/ $(lsb_release -cs) main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list
|
||||||
|
sudo apt update
|
||||||
|
sudo apt build-dep systemd
|
||||||
|
meson build
|
||||||
|
ninja -C build
|
||||||
|
sudo ln -svf $PWD/build/systemd-nspawn `which systemd-nspawn`
|
||||||
|
systemd-nspawn --version
|
||||||
|
|
||||||
- name: Build ${{ matrix.distro }}
|
- name: Build ${{ matrix.distro }}
|
||||||
run: sudo python3 -m mkosi --password= --qemu-headless build
|
run: sudo python3 -m mkosi --password= --qemu-headless build
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ int copy_bytes_full(
|
|||||||
copy_progress_bytes_t progress,
|
copy_progress_bytes_t progress,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
bool try_cfr = true, try_sendfile = true, try_splice = true;
|
bool try_cfr = true, try_sendfile = true, try_splice = true, copied_something = false;
|
||||||
int r, nonblock_pipe = -1;
|
int r, nonblock_pipe = -1;
|
||||||
size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
|
size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
|
||||||
|
|
||||||
@ -211,9 +211,20 @@ int copy_bytes_full(
|
|||||||
|
|
||||||
try_cfr = false;
|
try_cfr = false;
|
||||||
/* use fallback below */
|
/* use fallback below */
|
||||||
} else if (n == 0) /* EOF */
|
} else if (n == 0) { /* likely EOF */
|
||||||
|
|
||||||
|
if (copied_something)
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
|
/* So, we hit EOF immediately, without having copied a single byte. This
|
||||||
|
* could indicate two things: the file is actually empty, or we are on some
|
||||||
|
* virtual file system such as procfs/sysfs where the syscall actually
|
||||||
|
* doesn't work but doesn't return an error. Try to handle that, by falling
|
||||||
|
* back to simple read()s in case we encounter empty files.
|
||||||
|
*
|
||||||
|
* See: https://lwn.net/Articles/846403/ */
|
||||||
|
try_cfr = try_sendfile = try_splice = false;
|
||||||
|
} else
|
||||||
/* Success! */
|
/* Success! */
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@ -227,9 +238,14 @@ int copy_bytes_full(
|
|||||||
|
|
||||||
try_sendfile = false;
|
try_sendfile = false;
|
||||||
/* use fallback below */
|
/* use fallback below */
|
||||||
} else if (n == 0) /* EOF */
|
} else if (n == 0) { /* likely EOF */
|
||||||
|
|
||||||
|
if (copied_something)
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
|
try_sendfile = try_splice = false; /* same logic as above for copy_file_range() */
|
||||||
|
break;
|
||||||
|
} else
|
||||||
/* Success! */
|
/* Success! */
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@ -239,14 +255,14 @@ int copy_bytes_full(
|
|||||||
|
|
||||||
/* splice()'s asynchronous I/O support is a bit weird. When it encounters a pipe file
|
/* splice()'s asynchronous I/O support is a bit weird. When it encounters a pipe file
|
||||||
* descriptor, then it will ignore its O_NONBLOCK flag and instead only honour the
|
* descriptor, then it will ignore its O_NONBLOCK flag and instead only honour the
|
||||||
* SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour here, and
|
* SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour
|
||||||
* check if either of the specified fds are a pipe, and if so, let's pass the flag
|
* here, and check if either of the specified fds are a pipe, and if so, let's pass
|
||||||
* automatically, depending on O_NONBLOCK being set.
|
* the flag automatically, depending on O_NONBLOCK being set.
|
||||||
*
|
*
|
||||||
* Here's a twist though: when we use it to move data between two pipes of which one has
|
* Here's a twist though: when we use it to move data between two pipes of which one
|
||||||
* O_NONBLOCK set and the other has not, then we have no individual control over O_NONBLOCK
|
* has O_NONBLOCK set and the other has not, then we have no individual control over
|
||||||
* behaviour. Hence in that case we can't use splice() and still guarantee systematic
|
* O_NONBLOCK behaviour. Hence in that case we can't use splice() and still guarantee
|
||||||
* O_NONBLOCK behaviour, hence don't. */
|
* systematic O_NONBLOCK behaviour, hence don't. */
|
||||||
|
|
||||||
if (nonblock_pipe < 0) {
|
if (nonblock_pipe < 0) {
|
||||||
int a, b;
|
int a, b;
|
||||||
@ -264,12 +280,13 @@ int copy_bytes_full(
|
|||||||
(a == FD_IS_BLOCKING_PIPE && b == FD_IS_NONBLOCKING_PIPE) ||
|
(a == FD_IS_BLOCKING_PIPE && b == FD_IS_NONBLOCKING_PIPE) ||
|
||||||
(a == FD_IS_NONBLOCKING_PIPE && b == FD_IS_BLOCKING_PIPE))
|
(a == FD_IS_NONBLOCKING_PIPE && b == FD_IS_BLOCKING_PIPE))
|
||||||
|
|
||||||
/* splice() only works if one of the fds is a pipe. If neither is, let's skip
|
/* splice() only works if one of the fds is a pipe. If neither is,
|
||||||
* this step right-away. As mentioned above, if one of the two fds refers to a
|
* let's skip this step right-away. As mentioned above, if one of the
|
||||||
* blocking pipe and the other to a non-blocking pipe, we can't use splice()
|
* two fds refers to a blocking pipe and the other to a non-blocking
|
||||||
* either, hence don't try either. This hence means we can only use splice() if
|
* pipe, we can't use splice() either, hence don't try either. This
|
||||||
* either only one of the two fds is a pipe, or if both are pipes with the same
|
* hence means we can only use splice() if either only one of the two
|
||||||
* nonblocking flag setting. */
|
* fds is a pipe, or if both are pipes with the same nonblocking flag
|
||||||
|
* setting. */
|
||||||
|
|
||||||
try_splice = false;
|
try_splice = false;
|
||||||
else
|
else
|
||||||
@ -285,9 +302,13 @@ int copy_bytes_full(
|
|||||||
|
|
||||||
try_splice = false;
|
try_splice = false;
|
||||||
/* use fallback below */
|
/* use fallback below */
|
||||||
} else if (n == 0) /* EOF */
|
} else if (n == 0) { /* likely EOF */
|
||||||
|
|
||||||
|
if (copied_something)
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
|
try_splice = false; /* same logic as above for copy_file_range() + sendfile() */
|
||||||
|
} else
|
||||||
/* Success! */
|
/* Success! */
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@ -345,11 +366,12 @@ int copy_bytes_full(
|
|||||||
max_bytes -= n;
|
max_bytes -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sendfile accepts at most SSIZE_MAX-offset bytes to copy,
|
/* sendfile accepts at most SSIZE_MAX-offset bytes to copy, so reduce our maximum by the
|
||||||
* so reduce our maximum by the amount we already copied,
|
* amount we already copied, but don't go below our copy buffer size, unless we are close the
|
||||||
* but don't go below our copy buffer size, unless we are
|
* limit of bytes we are allowed to copy. */
|
||||||
* close the limit of bytes we are allowed to copy. */
|
|
||||||
m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
|
m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
|
||||||
|
|
||||||
|
copied_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* return 0 if we hit EOF earlier than the size limit */
|
return 0; /* return 0 if we hit EOF earlier than the size limit */
|
||||||
|
@ -272,7 +272,7 @@ static bool mount_entry_read_only(const MountEntry *p) {
|
|||||||
static bool mount_entry_noexec(const MountEntry *p) {
|
static bool mount_entry_noexec(const MountEntry *p) {
|
||||||
assert(p);
|
assert(p);
|
||||||
|
|
||||||
return p->noexec || IN_SET(p->mode, NOEXEC, INACCESSIBLE, SYSFS, PROCFS);
|
return p->noexec || IN_SET(p->mode, NOEXEC, INACCESSIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mount_entry_exec(const MountEntry *p) {
|
static bool mount_entry_exec(const MountEntry *p) {
|
||||||
|
@ -304,6 +304,22 @@ static void test_copy_atomic(void) {
|
|||||||
assert_se(copy_file_atomic("/etc/fstab", q, 0644, 0, 0, COPY_REPLACE) >= 0);
|
assert_se(copy_file_atomic("/etc/fstab", q, 0644, 0, 0, COPY_REPLACE) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_copy_proc(void) {
|
||||||
|
_cleanup_(rm_rf_physical_and_freep) char *p = NULL;
|
||||||
|
_cleanup_free_ char *f = NULL, *a = NULL, *b = NULL;
|
||||||
|
|
||||||
|
/* Check if copying data from /proc/ works correctly, i.e. let's see if https://lwn.net/Articles/846403/ is a problem for us */
|
||||||
|
|
||||||
|
assert_se(mkdtemp_malloc(NULL, &p) >= 0);
|
||||||
|
assert_se(f = path_join(p, "version"));
|
||||||
|
assert_se(copy_file("/proc/version", f, 0, (mode_t) -1, 0, 0, 0) >= 0);
|
||||||
|
|
||||||
|
assert_se(read_one_line_file("/proc/version", &a) >= 0);
|
||||||
|
assert_se(read_one_line_file(f, &b) >= 0);
|
||||||
|
assert_se(streq(a, b));
|
||||||
|
assert_se(strlen(a) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
test_setup_logging(LOG_DEBUG);
|
test_setup_logging(LOG_DEBUG);
|
||||||
|
|
||||||
@ -318,6 +334,7 @@ int main(int argc, char *argv[]) {
|
|||||||
test_copy_bytes_regular_file(argv[0], false, 32000); /* larger than copy buffer size */
|
test_copy_bytes_regular_file(argv[0], false, 32000); /* larger than copy buffer size */
|
||||||
test_copy_bytes_regular_file(argv[0], true, 32000);
|
test_copy_bytes_regular_file(argv[0], true, 32000);
|
||||||
test_copy_atomic();
|
test_copy_atomic();
|
||||||
|
test_copy_proc();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user