1
0
mirror of https://github.com/systemd/systemd synced 2026-04-10 09:04:50 +02:00

Compare commits

..

23 Commits

Author SHA1 Message Date
Yu Watanabe
f836390fa7
Merge pull request #21642 from yuwata/network-state-file-ignore-dynamic-when-dbus-entry-exists
network: state-file: ignore dynamic entries when specified by DBus method
2021-12-07 09:51:38 +09:00
Luca Boccassi
5328f80e92
Merge pull request #21646 from mrc0mmand/lgtm-followups
LGTM follow-ups
2021-12-07 00:14:45 +00:00
Luca Boccassi
3f88d5046f
Merge pull request #21639 from yuwata/network-dhcp6pd-use-dhcp6_pd_prefix_acquired
network: dhcp6pd: use dhcp6 pd prefix acquired() and drop dhcp6_pd_distribute_prefix()
2021-12-07 00:14:04 +00:00
Yu Watanabe
a0af85e02c
Merge pull request #21196 from yuwata/process-util-nulstr
process-util: handle double NUL as the end of command line
2021-12-07 08:29:34 +09:00
Franck Bui
051ea718f2 TEST-10: don't attempt to write a byte to the socket
Writing a byte to test10.socket is actually the root cause of issue #19154:
depending on the timing, it's possible that PID1 closes the socket before socat
(or nc, it doesn't matter which tool is actually used) tries to write that one
byte to the socket. In this case writing to the socket returns EPIPE, which
causes socat to exit(1) and subsequently make the test fail.

Since we're only interested in connecting to the socket and triggering the rate
limit of the socket, this patch removes the parts that write the single byte to
the socket, which should remove the race for good.

Since it shouldn't matter whether the test uses socat or nc, let's switch back
to nc and hence remove the sole user of socat. The exit status of nc is however
ignored because some versions might choke when the socket is closed
unexpectedly.
2021-12-07 08:29:09 +09:00
dependabot[bot]
7285145dfc build(deps): bump github/codeql-action from 1.0.24 to 1.0.25
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1.0.24 to 1.0.25.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](e095058bfa...546b30f35a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 02:20:53 +03:00
Yu Watanabe
56437e33a6 network: state-file: do not append dynamic entries when specified by DBus method
Fixes #21515.
2021-12-07 06:43:14 +09:00
Christian Göttsche
ef6bb4dd3e core: use correct level for CPU time log message
raise_level() takes the info condition as second argument and the notice
one as third. For the consumed CPU time these conditions are swapped.

Fixes: 37109b856aeb ("pid1: use LOG_DEBUG/INFO/NOTICE for unit resource consumption message")
2021-12-06 20:55:22 +01:00
Zbigniew Jędrzejewski-Szmek
ea599435a7
Merge pull request #21372 from DaanDeMeyer/journal-truncate
journal-file: truncate archived journals
2021-12-06 20:52:19 +01:00
Yu Watanabe
2756fb24ee network: state-file: honor dhcp6_use_domains flag 2021-12-07 01:58:35 +09:00
Frantisek Sumsal
33b7988d2e analyze,resolve: suppress a couple of false-positive alerts 2021-12-06 17:45:37 +01:00
Frantisek Sumsal
7fd2b742c9 core: check for NULL in one more place 2021-12-06 17:45:20 +01:00
Yu Watanabe
aa9de5b1c0 process-util: handle double NUL as the end of command line
Fixes #21186.
2021-12-06 23:42:25 +09:00
Yu Watanabe
95a511b704 process-util: rename function arguments for storing results 2021-12-06 23:21:08 +09:00
Daan De Meyer
6127ff9870 journal: punch holes in unused parts of entry arrays when archiving
Entry arrays grow exponentially, so when archiving a journal file is
archived, it's very likely that the final entry array objects in each
entry array chain aren't fully used. Let's punch holes in the unused
parts so the filesystem can reclaim this unused space and use it for
something else.
2021-12-06 14:54:06 +01:00
Daan De Meyer
ab6e257b3e journal: truncate archived journals
Journal files have space allocated in 8MiB-aligned increments. This
can add up to substantial wasted space as many archived journals
accumulate without using all the allocated space. Let's truncate
journal files to their actually used size when archiving them to
reclaim this unused space.

As the mmap cache is not thread-safe, we can't call
journal_file_move_to_object() from the offline thread. Instead,
we use journal_file_read_object() which doesn't rely on the mmap
cache.
2021-12-06 14:54:06 +01:00
Daan De Meyer
117e21121e journal: Add journal_file_read_object() 2021-12-06 14:54:06 +01:00
Yu Watanabe
416644567b network: dhcp6pd: make dhcp6_pd_assign_prefixes() used also by dhcp6_pd_prefix_acquired() 2021-12-06 21:35:53 +09:00
Yu Watanabe
21cf8e9e6d network: dhcp6pd: first check prefixes, then calculate lifetime 2021-12-06 21:35:53 +09:00
Yu Watanabe
542d04950e network: dhcp6pd: shorten code a bit 2021-12-06 21:35:53 +09:00
Yu Watanabe
c3cd535132 network: dhcp6pd: skip to assign prefixes to a downstream link if it is not ready 2021-12-06 21:35:53 +09:00
Yu Watanabe
5014e66019 network: dhcp6pd: move dhcp6_pd_assign_prefixes()
Preparation for the later commits.
2021-12-06 21:35:53 +09:00
Yu Watanabe
4c004e2a71 network: dhcp6pd: also allow to only assign prefix route for delegated prefix to upstream interface 2021-12-06 21:35:53 +09:00
14 changed files with 431 additions and 315 deletions

View File

@ -38,14 +38,14 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@e095058bfa09de8070f94e98f5dc059531bc6235 uses: github/codeql-action/init@546b30f35ae5a3db0e0be1843008c2224f71c3b0
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- run: sudo -E .github/workflows/unit_tests.sh SETUP - run: sudo -E .github/workflows/unit_tests.sh SETUP
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@e095058bfa09de8070f94e98f5dc059531bc6235 uses: github/codeql-action/autobuild@546b30f35ae5a3db0e0be1843008c2224f71c3b0
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e095058bfa09de8070f94e98f5dc059531bc6235 uses: github/codeql-action/analyze@546b30f35ae5a3db0e0be1843008c2224f71c3b0

View File

@ -982,7 +982,7 @@ static int list_dependencies_one(sd_bus *bus, const char *name, unsigned level,
return r; return r;
STRV_FOREACH(c, deps) { STRV_FOREACH(c, deps) {
times = hashmap_get(unit_times_hashmap, *c); times = hashmap_get(unit_times_hashmap, *c); /* lgtm [cpp/inconsistent-null-check] */
if (times_in_range(times, boot) && times->activated >= service_longest) if (times_in_range(times, boot) && times->activated >= service_longest)
service_longest = times->activated; service_longest = times->activated;
} }
@ -991,7 +991,7 @@ static int list_dependencies_one(sd_bus *bus, const char *name, unsigned level,
return r; return r;
STRV_FOREACH(c, deps) { STRV_FOREACH(c, deps) {
times = hashmap_get(unit_times_hashmap, *c); times = hashmap_get(unit_times_hashmap, *c); /* lgtm [cpp/inconsistent-null-check] */
if (times_in_range(times, boot) && service_longest - times->activated <= arg_fuzz) if (times_in_range(times, boot) && service_longest - times->activated <= arg_fuzz)
to_print++; to_print++;
} }
@ -1000,7 +1000,7 @@ static int list_dependencies_one(sd_bus *bus, const char *name, unsigned level,
return r; return r;
STRV_FOREACH(c, deps) { STRV_FOREACH(c, deps) {
times = hashmap_get(unit_times_hashmap, *c); times = hashmap_get(unit_times_hashmap, *c); /* lgtm [cpp/inconsistent-null-check] */
if (!times_in_range(times, boot) || service_longest - times->activated > arg_fuzz) if (!times_in_range(times, boot) || service_longest - times->activated > arg_fuzz)
continue; continue;

View File

@ -181,13 +181,13 @@ static int get_process_cmdline_nulstr(
return r; return r;
} }
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line) { int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
_cleanup_free_ char *t = NULL; _cleanup_free_ char *t = NULL;
size_t k; size_t k;
char *ans; char *ans;
assert(line);
assert(pid >= 0); assert(pid >= 0);
assert(ret);
/* Retrieve and format a commandline. See above for discussion of retrieval options. /* Retrieve and format a commandline. See above for discussion of retrieval options.
* *
@ -214,11 +214,17 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
assert(!(flags & PROCESS_CMDLINE_USE_LOCALE)); assert(!(flags & PROCESS_CMDLINE_USE_LOCALE));
_cleanup_strv_free_ char **args = NULL; _cleanup_strv_free_ char **args = NULL;
char **p;
args = strv_parse_nulstr(t, k); args = strv_parse_nulstr(t, k);
if (!args) if (!args)
return -ENOMEM; return -ENOMEM;
/* Drop trailing empty strings. See issue #21186. */
STRV_FOREACH_BACKWARDS(p, args)
if (isempty(*p))
*p = mfree(*p);
ans = quote_command_line(args, shflags); ans = quote_command_line(args, shflags);
if (!ans) if (!ans)
return -ENOMEM; return -ENOMEM;
@ -240,7 +246,7 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
ans = str_realloc(ans); ans = str_realloc(ans);
} }
*line = ans; *ret = ans;
return 0; return 0;
} }
@ -447,29 +453,29 @@ int is_kernel_thread(pid_t pid) {
return !!(flags & PF_KTHREAD); return !!(flags & PF_KTHREAD);
} }
int get_process_capeff(pid_t pid, char **capeff) { int get_process_capeff(pid_t pid, char **ret) {
const char *p; const char *p;
int r; int r;
assert(capeff);
assert(pid >= 0); assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "status"); p = procfs_file_alloca(pid, "status");
r = get_proc_field(p, "CapEff", WHITESPACE, capeff); r = get_proc_field(p, "CapEff", WHITESPACE, ret);
if (r == -ENOENT) if (r == -ENOENT)
return -ESRCH; return -ESRCH;
return r; return r;
} }
static int get_process_link_contents(const char *proc_file, char **name) { static int get_process_link_contents(const char *proc_file, char **ret) {
int r; int r;
assert(proc_file); assert(proc_file);
assert(name); assert(ret);
r = readlink_malloc(proc_file, name); r = readlink_malloc(proc_file, ret);
if (r == -ENOENT) if (r == -ENOENT)
return -ESRCH; return -ESRCH;
if (r < 0) if (r < 0)
@ -478,32 +484,33 @@ static int get_process_link_contents(const char *proc_file, char **name) {
return 0; return 0;
} }
int get_process_exe(pid_t pid, char **name) { int get_process_exe(pid_t pid, char **ret) {
const char *p; const char *p;
char *d; char *d;
int r; int r;
assert(pid >= 0); assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "exe"); p = procfs_file_alloca(pid, "exe");
r = get_process_link_contents(p, name); r = get_process_link_contents(p, ret);
if (r < 0) if (r < 0)
return r; return r;
d = endswith(*name, " (deleted)"); d = endswith(*ret, " (deleted)");
if (d) if (d)
*d = '\0'; *d = '\0';
return 0; return 0;
} }
static int get_process_id(pid_t pid, const char *field, uid_t *uid) { static int get_process_id(pid_t pid, const char *field, uid_t *ret) {
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
const char *p; const char *p;
int r; int r;
assert(field); assert(field);
assert(uid); assert(ret);
if (pid < 0) if (pid < 0)
return -EINVAL; return -EINVAL;
@ -533,60 +540,62 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
l[strcspn(l, WHITESPACE)] = 0; l[strcspn(l, WHITESPACE)] = 0;
return parse_uid(l, uid); return parse_uid(l, ret);
} }
} }
return -EIO; return -EIO;
} }
int get_process_uid(pid_t pid, uid_t *uid) { int get_process_uid(pid_t pid, uid_t *ret) {
if (pid == 0 || pid == getpid_cached()) { if (pid == 0 || pid == getpid_cached()) {
*uid = getuid(); *ret = getuid();
return 0; return 0;
} }
return get_process_id(pid, "Uid:", uid); return get_process_id(pid, "Uid:", ret);
} }
int get_process_gid(pid_t pid, gid_t *gid) { int get_process_gid(pid_t pid, gid_t *ret) {
if (pid == 0 || pid == getpid_cached()) { if (pid == 0 || pid == getpid_cached()) {
*gid = getgid(); *ret = getgid();
return 0; return 0;
} }
assert_cc(sizeof(uid_t) == sizeof(gid_t)); assert_cc(sizeof(uid_t) == sizeof(gid_t));
return get_process_id(pid, "Gid:", gid); return get_process_id(pid, "Gid:", ret);
} }
int get_process_cwd(pid_t pid, char **cwd) { int get_process_cwd(pid_t pid, char **ret) {
const char *p; const char *p;
assert(pid >= 0); assert(pid >= 0);
assert(ret);
if (pid == 0 || pid == getpid_cached()) if (pid == 0 || pid == getpid_cached())
return safe_getcwd(cwd); return safe_getcwd(ret);
p = procfs_file_alloca(pid, "cwd"); p = procfs_file_alloca(pid, "cwd");
return get_process_link_contents(p, cwd); return get_process_link_contents(p, ret);
} }
int get_process_root(pid_t pid, char **root) { int get_process_root(pid_t pid, char **ret) {
const char *p; const char *p;
assert(pid >= 0); assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "root"); p = procfs_file_alloca(pid, "root");
return get_process_link_contents(p, root); return get_process_link_contents(p, ret);
} }
#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U) #define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U)
int get_process_environ(pid_t pid, char **env) { int get_process_environ(pid_t pid, char **ret) {
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *outcome = NULL; _cleanup_free_ char *outcome = NULL;
size_t sz = 0; size_t sz = 0;
@ -594,7 +603,7 @@ int get_process_environ(pid_t pid, char **env) {
int r; int r;
assert(pid >= 0); assert(pid >= 0);
assert(env); assert(ret);
p = procfs_file_alloca(pid, "environ"); p = procfs_file_alloca(pid, "environ");
@ -626,7 +635,7 @@ int get_process_environ(pid_t pid, char **env) {
} }
outcome[sz] = '\0'; outcome[sz] = '\0';
*env = TAKE_PTR(outcome); *ret = TAKE_PTR(outcome);
return 0; return 0;
} }
@ -685,13 +694,13 @@ int get_process_ppid(pid_t pid, pid_t *ret) {
return 0; return 0;
} }
int get_process_umask(pid_t pid, mode_t *umask) { int get_process_umask(pid_t pid, mode_t *ret) {
_cleanup_free_ char *m = NULL; _cleanup_free_ char *m = NULL;
const char *p; const char *p;
int r; int r;
assert(umask);
assert(pid >= 0); assert(pid >= 0);
assert(ret);
p = procfs_file_alloca(pid, "status"); p = procfs_file_alloca(pid, "status");
@ -699,7 +708,7 @@ int get_process_umask(pid_t pid, mode_t *umask) {
if (r == -ENOENT) if (r == -ENOENT)
return -ESRCH; return -ESRCH;
return parse_mode(m, umask); return parse_mode(m, ret);
} }
int wait_for_terminate(pid_t pid, siginfo_t *status) { int wait_for_terminate(pid_t pid, siginfo_t *status) {

View File

@ -38,17 +38,17 @@ typedef enum ProcessCmdlineFlags {
PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3, PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3,
} ProcessCmdlineFlags; } ProcessCmdlineFlags;
int get_process_comm(pid_t pid, char **name); int get_process_comm(pid_t pid, char **ret);
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line); int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
int get_process_exe(pid_t pid, char **name); int get_process_exe(pid_t pid, char **ret);
int get_process_uid(pid_t pid, uid_t *uid); int get_process_uid(pid_t pid, uid_t *ret);
int get_process_gid(pid_t pid, gid_t *gid); int get_process_gid(pid_t pid, gid_t *ret);
int get_process_capeff(pid_t pid, char **capeff); int get_process_capeff(pid_t pid, char **ret);
int get_process_cwd(pid_t pid, char **cwd); int get_process_cwd(pid_t pid, char **ret);
int get_process_root(pid_t pid, char **root); int get_process_root(pid_t pid, char **ret);
int get_process_environ(pid_t pid, char **environ); int get_process_environ(pid_t pid, char **ret);
int get_process_ppid(pid_t pid, pid_t *ppid); int get_process_ppid(pid_t pid, pid_t *ret);
int get_process_umask(pid_t pid, mode_t *umask); int get_process_umask(pid_t pid, mode_t *ret);
int wait_for_terminate(pid_t pid, siginfo_t *status); int wait_for_terminate(pid_t pid, siginfo_t *status);

View File

@ -148,6 +148,7 @@ static int target_serialize(Unit *u, FILE *f, FDSet *fds) {
static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
Target *s = TARGET(u); Target *s = TARGET(u);
assert(s);
assert(u); assert(u);
assert(key); assert(key);
assert(value); assert(value);

View File

@ -2304,8 +2304,8 @@ static int unit_log_resources(Unit *u) {
message_parts[n_message_parts++] = t; message_parts[n_message_parts++] = t;
log_level = raise_level(log_level, log_level = raise_level(log_level,
nsec > NOTICEWORTHY_CPU_NSEC, nsec > MENTIONWORTHY_CPU_NSEC,
nsec > MENTIONWORTHY_CPU_NSEC); nsec > NOTICEWORTHY_CPU_NSEC);
} }
for (CGroupIOAccountingMetric k = 0; k < _CGROUP_IO_ACCOUNTING_METRIC_MAX; k++) { for (CGroupIOAccountingMetric k = 0; k < _CGROUP_IO_ACCOUNTING_METRIC_MAX; k++) {

View File

@ -91,6 +91,144 @@
# pragma GCC diagnostic ignored "-Waddress-of-packed-member" # pragma GCC diagnostic ignored "-Waddress-of-packed-member"
#endif #endif
static int journal_file_tail_end(JournalFile *f, uint64_t *ret_offset) {
Object tail;
uint64_t p;
int r;
assert(f);
assert(f->header);
assert(ret_offset);
p = le64toh(f->header->tail_object_offset);
if (p == 0)
p = le64toh(f->header->header_size);
else {
uint64_t sz;
r = journal_file_read_object(f, OBJECT_UNUSED, p, &tail);
if (r < 0)
return r;
sz = le64toh(tail.object.size);
if (sz > UINT64_MAX - sizeof(uint64_t) + 1)
return -EBADMSG;
sz = ALIGN64(sz);
if (p > UINT64_MAX - sz)
return -EBADMSG;
p += sz;
}
*ret_offset = p;
return 0;
}
static int journal_file_truncate(JournalFile *f) {
uint64_t p;
int r;
/* truncate excess from the end of archives */
r = journal_file_tail_end(f, &p);
if (r < 0)
return log_debug_errno(r, "Failed to determine end of tail object: %m");
/* arena_size can't exceed the file size, ensure it's updated before truncating */
f->header->arena_size = htole64(p - le64toh(f->header->header_size));
if (ftruncate(f->fd, p) < 0)
log_debug_errno(errno, "Failed to truncate %s: %m", f->path);
return 0;
}
static int journal_file_entry_array_punch_hole(JournalFile *f, uint64_t p, uint64_t n_entries) {
Object o;
uint64_t offset, sz, n_items = 0, n_unused;
int r;
if (n_entries == 0)
return 0;
for (uint64_t q = p; q != 0; q = le64toh(o.entry_array.next_entry_array_offset)) {
r = journal_file_read_object(f, OBJECT_ENTRY_ARRAY, q, &o);
if (r < 0)
return r;
n_items += journal_file_entry_array_n_items(&o);
p = q;
}
if (p == 0)
return 0;
if (n_entries > n_items)
return -EBADMSG;
/* Amount of unused items in the final entry array. */
n_unused = n_items - n_entries;
if (n_unused == 0)
return 0;
offset = p + offsetof(Object, entry_array.items) +
(journal_file_entry_array_n_items(&o) - n_unused) * sizeof(le64_t);
sz = p + le64toh(o.object.size) - offset;
if (fallocate(f->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, sz) < 0)
return log_debug_errno(errno, "Failed to punch hole in entry array of %s: %m", f->path);
return 0;
}
static int journal_file_punch_holes(JournalFile *f) {
HashItem items[4096 / sizeof(HashItem)];
uint64_t p, sz;
size_t to_read;
int r;
r = journal_file_entry_array_punch_hole(
f, le64toh(f->header->entry_array_offset), le64toh(f->header->n_entries));
if (r < 0)
return r;
p = le64toh(f->header->data_hash_table_offset);
sz = le64toh(f->header->data_hash_table_size);
to_read = MIN((size_t) f->last_stat.st_blksize, sizeof(items));
for (uint64_t i = p; i < p + sz; i += sizeof(items)) {
ssize_t n_read;
n_read = pread(f->fd, items, MIN(to_read, p + sz - i), i);
if (n_read < 0)
return n_read;
for (size_t j = 0; j < (size_t) n_read / sizeof(HashItem); j++) {
Object o;
for (uint64_t q = le64toh(items[j].head_hash_offset); q != 0;
q = le64toh(o.data.next_hash_offset)) {
r = journal_file_read_object(f, OBJECT_DATA, q, &o);
if (r < 0) {
log_debug_errno(r, "Invalid data object: %m, ignoring");
break;
}
if (le64toh(o.data.n_entries) == 0)
continue;
(void) journal_file_entry_array_punch_hole(
f, le64toh(o.data.entry_array_offset), le64toh(o.data.n_entries) - 1);
}
}
}
return 0;
}
/* This may be called from a separate thread to prevent blocking the caller for the duration of fsync(). /* This may be called from a separate thread to prevent blocking the caller for the duration of fsync().
* As a result we use atomic operations on f->offline_state for inter-thread communications with * As a result we use atomic operations on f->offline_state for inter-thread communications with
* journal_file_set_offline() and journal_file_set_online(). */ * journal_file_set_offline() and journal_file_set_online(). */
@ -117,6 +255,11 @@ static void journal_file_set_offline_internal(JournalFile *f) {
break; break;
case OFFLINE_SYNCING: case OFFLINE_SYNCING:
if (f->archive) {
(void) journal_file_truncate(f);
(void) journal_file_punch_holes(f);
}
(void) fsync(f->fd); (void) fsync(f->fd);
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_OFFLINING)) if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_OFFLINING))
@ -990,6 +1133,65 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset
return 0; return 0;
} }
int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, Object *ret) {
int r;
Object o;
uint64_t s;
assert(f);
assert(ret);
/* Objects may only be located at multiple of 64 bit */
if (!VALID64(offset))
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read object at non-64bit boundary: %" PRIu64,
offset);
/* Object may not be located in the file header */
if (offset < le64toh(f->header->header_size))
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read object located in file header: %" PRIu64,
offset);
/* This will likely read too much data but it avoids having to call pread() twice. */
r = pread(f->fd, &o, sizeof(Object), offset);
if (r < 0)
return r;
s = le64toh(o.object.size);
if (s == 0)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read uninitialized object: %" PRIu64,
offset);
if (s < sizeof(ObjectHeader))
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read overly short object: %" PRIu64,
offset);
if (o.object.type <= OBJECT_UNUSED)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read object with invalid type: %" PRIu64,
offset);
if (s < minimum_header_size(&o))
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read truncated object: %" PRIu64,
offset);
if (type > OBJECT_UNUSED && o.object.type != type)
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
"Attempt to read object of unexpected type: %" PRIu64,
offset);
r = journal_file_check_object(f, offset, &o);
if (r < 0)
return r;
*ret = o;
return 0;
}
static uint64_t journal_file_entry_seqnum( static uint64_t journal_file_entry_seqnum(
JournalFile *f, JournalFile *f,
uint64_t *seqnum) { uint64_t *seqnum) {
@ -1030,7 +1232,7 @@ int journal_file_append_object(
int r; int r;
uint64_t p; uint64_t p;
Object *tail, *o; Object *o;
void *t; void *t;
assert(f); assert(f);
@ -1042,27 +1244,10 @@ int journal_file_append_object(
if (r < 0) if (r < 0)
return r; return r;
p = le64toh(f->header->tail_object_offset); r = journal_file_tail_end(f, &p);
if (p == 0)
p = le64toh(f->header->header_size);
else {
uint64_t sz;
r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &tail);
if (r < 0) if (r < 0)
return r; return r;
sz = le64toh(READ_NOW(tail->object.size));
if (sz > UINT64_MAX - sizeof(uint64_t) + 1)
return -EBADMSG;
sz = ALIGN64(sz);
if (p > UINT64_MAX - sz)
return -EBADMSG;
p += sz;
}
r = journal_file_allocate(f, p, size); r = journal_file_allocate(f, p, size);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -202,6 +202,7 @@ static inline bool VALID_EPOCH(uint64_t u) {
FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_KEYED_HASH) FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_KEYED_HASH)
int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret); int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret);
int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, Object *ret);
uint64_t journal_file_entry_n_items(Object *o) _pure_; uint64_t journal_file_entry_n_items(Object *o) _pure_;
uint64_t journal_file_entry_array_n_items(Object *o) _pure_; uint64_t journal_file_entry_array_n_items(Object *o) _pure_;

View File

@ -570,47 +570,6 @@ static int dhcp6_pd_assign_prefix(
return 1; return 1;
} }
static int dhcp6_pd_distribute_prefix(
Link *dhcp6_link,
const struct in6_addr *pd_prefix,
uint8_t pd_prefix_len,
usec_t lifetime_preferred_usec,
usec_t lifetime_valid_usec) {
Link *link;
int r;
assert(dhcp6_link);
assert(dhcp6_link->manager);
assert(pd_prefix);
assert(pd_prefix_len <= 64);
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
continue;
if (!dhcp6_pd_is_uplink(link, dhcp6_link, /* accept_auto = */ true))
continue;
if (link->network->dhcp6_pd_announce && !link->radv)
continue;
if (link == dhcp6_link && !link->network->dhcp6_pd_assign)
continue;
r = dhcp6_pd_assign_prefix(link, pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec);
if (r < 0) {
if (link == dhcp6_link)
return r;
link_enter_failed(link);
continue;
}
}
return 0;
}
static int dhcp6_pd_prepare(Link *link) { static int dhcp6_pd_prepare(Link *link) {
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0; return 0;
@ -624,7 +583,7 @@ static int dhcp6_pd_prepare(Link *link) {
link_mark_addresses(link, NETWORK_CONFIG_SOURCE_DHCP6PD, NULL); link_mark_addresses(link, NETWORK_CONFIG_SOURCE_DHCP6PD, NULL);
link_mark_routes(link, NETWORK_CONFIG_SOURCE_DHCP6PD, NULL); link_mark_routes(link, NETWORK_CONFIG_SOURCE_DHCP6PD, NULL);
return 0; return 1;
} }
static int dhcp6_pd_finalize(Link *link) { static int dhcp6_pd_finalize(Link *link) {
@ -633,12 +592,6 @@ static int dhcp6_pd_finalize(Link *link) {
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0; return 0;
if (!link_dhcp6_pd_is_enabled(link))
return 0;
if (link->network->dhcp6_pd_announce && !link->radv)
return 0;
if (link->dhcp6_pd_messages == 0) { if (link->dhcp6_pd_messages == 0) {
link->dhcp6_pd_configured = false; link->dhcp6_pd_configured = false;
@ -793,103 +746,6 @@ static int dhcp6_pd_prefix_add(Link *link, const struct in6_addr *prefix, uint8_
return prefixlen <= 64; return prefixlen <= 64;
} }
int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
usec_t timestamp_usec;
Link *link;
int r;
assert(dhcp6_link);
assert(dhcp6_link->dhcp6_lease);
r = sd_dhcp6_lease_get_timestamp(dhcp6_link->dhcp6_lease, clock_boottime_or_monotonic(), &timestamp_usec);
if (r < 0)
return log_link_warning_errno(dhcp6_link, r, "Failed to get timestamp of DHCPv6 lease: %m");
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
r = dhcp6_pd_prepare(link);
if (r < 0) {
/* When failed on the upstream interface (i.e., the case link == dhcp6_link),
* immediately abort the assignment of the prefixes. As, the all assigned
* prefixes will be dropped soon in link_enter_failed(), and it is meaningless
* to continue the assignment. */
if (link == dhcp6_link)
return r;
link_enter_failed(link);
}
}
for (sd_dhcp6_lease_reset_pd_prefix_iter(dhcp6_link->dhcp6_lease);;) {
uint32_t lifetime_preferred_sec, lifetime_valid_sec;
usec_t lifetime_preferred_usec, lifetime_valid_usec;
struct in6_addr pd_prefix;
uint8_t pd_prefix_len;
r = sd_dhcp6_lease_get_pd(dhcp6_link->dhcp6_lease, &pd_prefix, &pd_prefix_len,
&lifetime_preferred_sec, &lifetime_valid_sec);
if (r < 0)
break;
lifetime_preferred_usec = usec_add(lifetime_preferred_sec * USEC_PER_SEC, timestamp_usec);
lifetime_valid_usec = usec_add(lifetime_valid_sec * USEC_PER_SEC, timestamp_usec);
r = dhcp6_pd_prefix_add(dhcp6_link, &pd_prefix, pd_prefix_len);
if (r < 0)
return r;
if (r == 0)
continue;
r = dhcp6_request_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len, lifetime_valid_usec);
if (r < 0)
return r;
/* We are doing prefix allocation in two steps:
* 1. all those links that have a preferred subnet id will be assigned their subnet
* 2. all those links that remain will receive prefixes in sequential order. Prefixes
* that were previously already allocated to another link will be skipped.
* The assignment has to be split in two phases since subnet id
* preferences should be honored. Meaning that any subnet id should be
* handed out to the requesting link and not to some link that didn't
* specify any preference. */
assert(pd_prefix_len <= 64);
/* Mask prefix for safety. */
r = in6_addr_mask(&pd_prefix, pd_prefix_len);
if (r < 0)
return log_link_error_errno(dhcp6_link, r, "Failed to mask DHCPv6 PD prefix: %m");
if (DEBUG_LOGGING) {
uint64_t n_prefixes = UINT64_C(1) << (64 - pd_prefix_len);
_cleanup_free_ char *buf = NULL;
(void) in6_addr_prefix_to_string(&pd_prefix, pd_prefix_len, &buf);
log_link_debug(dhcp6_link, "Assigning up to %" PRIu64 " prefixes from %s",
n_prefixes, strna(buf));
}
r = dhcp6_pd_distribute_prefix(dhcp6_link,
&pd_prefix,
pd_prefix_len,
lifetime_preferred_usec,
lifetime_valid_usec);
if (r < 0)
return r;
}
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
r = dhcp6_pd_finalize(link);
if (r < 0) {
if (link == dhcp6_link)
return r;
link_enter_failed(link);
}
}
return 0;
}
static int dhcp6_pd_assign_prefixes(Link *link, Link *uplink) { static int dhcp6_pd_assign_prefixes(Link *link, Link *uplink) {
usec_t timestamp_usec; usec_t timestamp_usec;
int r; int r;
@ -898,14 +754,11 @@ static int dhcp6_pd_assign_prefixes(Link *link, Link *uplink) {
assert(uplink); assert(uplink);
assert(uplink->dhcp6_lease); assert(uplink->dhcp6_lease);
/* This is similar to dhcp6_pd_prefix_acquired(), but called when a downstream interface r = dhcp6_pd_prepare(link);
* appears later or reconfiguring the interface. */ if (r <= 0)
r = sd_dhcp6_lease_get_timestamp(uplink->dhcp6_lease, clock_boottime_or_monotonic(), &timestamp_usec);
if (r < 0)
return r; return r;
r = dhcp6_pd_prepare(link); r = sd_dhcp6_lease_get_timestamp(uplink->dhcp6_lease, clock_boottime_or_monotonic(), &timestamp_usec);
if (r < 0) if (r < 0)
return r; return r;
@ -920,9 +773,6 @@ static int dhcp6_pd_assign_prefixes(Link *link, Link *uplink) {
if (r < 0) if (r < 0)
break; break;
lifetime_preferred_usec = usec_add(lifetime_preferred_sec * USEC_PER_SEC, timestamp_usec);
lifetime_valid_usec = usec_add(lifetime_valid_sec * USEC_PER_SEC, timestamp_usec);
if (pd_prefix_len > 64) if (pd_prefix_len > 64)
continue; continue;
@ -931,14 +781,76 @@ static int dhcp6_pd_assign_prefixes(Link *link, Link *uplink) {
if (r < 0) if (r < 0)
return r; return r;
lifetime_preferred_usec = usec_add(lifetime_preferred_sec * USEC_PER_SEC, timestamp_usec);
lifetime_valid_usec = usec_add(lifetime_valid_sec * USEC_PER_SEC, timestamp_usec);
r = dhcp6_pd_assign_prefix(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); r = dhcp6_pd_assign_prefix(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec);
if (r < 0) if (r < 0)
return r; return r;
} }
r = dhcp6_pd_finalize(link); return dhcp6_pd_finalize(link);
}
int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
usec_t timestamp_usec;
Link *link;
int r;
assert(dhcp6_link);
assert(dhcp6_link->dhcp6_lease);
r = sd_dhcp6_lease_get_timestamp(dhcp6_link->dhcp6_lease, clock_boottime_or_monotonic(), &timestamp_usec);
if (r < 0)
return log_link_warning_errno(dhcp6_link, r, "Failed to get timestamp of DHCPv6 lease: %m");
/* First, logs acquired prefixes and request unreachable routes. */
for (sd_dhcp6_lease_reset_pd_prefix_iter(dhcp6_link->dhcp6_lease);;) {
uint32_t lifetime_preferred_sec, lifetime_valid_sec;
usec_t lifetime_valid_usec;
struct in6_addr pd_prefix;
uint8_t pd_prefix_len;
r = sd_dhcp6_lease_get_pd(dhcp6_link->dhcp6_lease, &pd_prefix, &pd_prefix_len,
&lifetime_preferred_sec, &lifetime_valid_sec);
if (r < 0)
break;
/* Mask prefix for safety. */
r = in6_addr_mask(&pd_prefix, pd_prefix_len);
if (r < 0)
return log_link_error_errno(dhcp6_link, r, "Failed to mask DHCPv6 PD prefix: %m");
lifetime_valid_usec = usec_add(lifetime_valid_sec * USEC_PER_SEC, timestamp_usec);
r = dhcp6_pd_prefix_add(dhcp6_link, &pd_prefix, pd_prefix_len);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0)
continue;
r = dhcp6_request_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len, lifetime_valid_usec);
if (r < 0)
return r;
}
/* Then, assign subnet prefixes. */
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
if (!dhcp6_pd_is_uplink(link, dhcp6_link, /* accept_auto = */ true))
continue;
r = dhcp6_pd_assign_prefixes(link, dhcp6_link);
if (r < 0) {
/* When failed on the upstream interface (i.e., the case link == dhcp6_link),
* immediately abort the assignment of the prefixes. As, the all assigned
* prefixes will be dropped soon in link_enter_failed(), and it is meaningless
* to continue the assignment. */
if (link == dhcp6_link)
return r;
link_enter_failed(link);
}
}
return 0; return 0;
} }

View File

@ -350,6 +350,11 @@ static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
} }
static void link_save_dns(Link *link, FILE *f, struct in_addr_full **dns, unsigned n_dns, bool *space) { static void link_save_dns(Link *link, FILE *f, struct in_addr_full **dns, unsigned n_dns, bool *space) {
bool _space = false;
if (!space)
space = &_space;
for (unsigned j = 0; j < n_dns; j++) { for (unsigned j = 0; j < n_dns; j++) {
const char *str; const char *str;
@ -418,6 +423,45 @@ static void serialize_addresses(
fputc('\n', f); fputc('\n', f);
} }
static void link_save_domains(Link *link, FILE *f, OrderedSet *static_domains, DHCPUseDomains use_domains) {
bool space = false;
const char *p;
assert(link);
assert(link->network);
assert(f);
ORDERED_SET_FOREACH(p, static_domains)
fputs_with_space(f, p, NULL, &space);
if (use_domains == DHCP_USE_DOMAINS_NO)
return;
if (link->dhcp_lease && link->network->dhcp_use_domains == use_domains) {
const char *domainname;
char **domains;
if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname) >= 0)
fputs_with_space(f, domainname, NULL, &space);
if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0)
fputstrv(f, domains, NULL, &space);
}
if (link->dhcp6_lease && link->network->dhcp6_use_domains == use_domains) {
char **domains;
if (sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains) >= 0)
fputstrv(f, domains, NULL, &space);
}
if (link->network->ipv6_accept_ra_use_domains == use_domains) {
NDiscDNSSL *dd;
SET_FOREACH(dd, link->ndisc_dnssl)
fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
}
}
int link_save(Link *link) { int link_save(Link *link) {
const char *admin_state, *oper_state, *carrier_state, *address_state, *ipv4_address_state, *ipv6_address_state; const char *admin_state, *oper_state, *carrier_state, *address_state, *ipv4_address_state, *ipv6_address_state;
_cleanup_(unlink_and_freep) char *temp_path = NULL; _cleanup_(unlink_and_freep) char *temp_path = NULL;
@ -470,8 +514,7 @@ int link_save(Link *link) {
admin_state, oper_state, carrier_state, address_state, ipv4_address_state, ipv6_address_state); admin_state, oper_state, carrier_state, address_state, ipv4_address_state, ipv6_address_state);
if (link->network) { if (link->network) {
char **dhcp6_domains = NULL, **dhcp_domains = NULL; const char *online_state;
const char *dhcp_domainname = NULL, *online_state, *p;
bool space; bool space;
online_state = link_online_state_to_string(link->online_state); online_state = link_online_state_to_string(link->online_state);
@ -497,11 +540,14 @@ int link_save(Link *link) {
/************************************************************/ /************************************************************/
/* Make sure to flush out old entries before we use the NDisc data */
ndisc_vacuum(link);
fputs("DNS=", f); fputs("DNS=", f);
space = false;
if (link->n_dns != UINT_MAX) if (link->n_dns != UINT_MAX)
link_save_dns(link, f, link->dns, link->n_dns, &space); link_save_dns(link, f, link->dns, link->n_dns, NULL);
else else {
space = false;
link_save_dns(link, f, link->network->dns, link->network->n_dns, &space); link_save_dns(link, f, link->network->dns, link->network->n_dns, &space);
serialize_addresses(f, NULL, &space, serialize_addresses(f, NULL, &space,
@ -514,22 +560,25 @@ int link_save(Link *link) {
sd_dhcp6_lease_get_dns, sd_dhcp6_lease_get_dns,
NULL); NULL);
/* Make sure to flush out old entries before we use the NDisc data */ if (link->network->ipv6_accept_ra_use_dns) {
ndisc_vacuum(link);
if (link->network->ipv6_accept_ra_use_dns && link->ndisc_rdnss) {
NDiscRDNSS *dd; NDiscRDNSS *dd;
SET_FOREACH(dd, link->ndisc_rdnss) SET_FOREACH(dd, link->ndisc_rdnss)
serialize_in6_addrs(f, &dd->address, 1, &space); serialize_in6_addrs(f, &dd->address, 1, &space);
} }
}
fputc('\n', f); fputc('\n', f);
/************************************************************/ /************************************************************/
if (link->ntp) {
fputs("NTP=", f);
fputstrv(f, link->ntp, NULL, NULL);
fputc('\n', f);
} else
serialize_addresses(f, "NTP", NULL, serialize_addresses(f, "NTP", NULL,
link->ntp ?: link->network->ntp, link->network->ntp,
link->dhcp_lease, link->dhcp_lease,
link->network->dhcp_use_ntp, link->network->dhcp_use_ntp,
SD_DHCP_LEASE_NTP, SD_DHCP_LEASE_NTP,
@ -547,59 +596,20 @@ int link_save(Link *link) {
/************************************************************/ /************************************************************/
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO && link->dhcp_lease) {
(void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
(void) sd_dhcp_lease_get_search_domains(link->dhcp_lease, &dhcp_domains);
}
if (link->network->dhcp6_use_domains != DHCP_USE_DOMAINS_NO && link->dhcp6_lease)
(void) sd_dhcp6_lease_get_domains(link->dhcp6_lease, &dhcp6_domains);
fputs("DOMAINS=", f); fputs("DOMAINS=", f);
space = false; if (link->search_domains)
ORDERED_SET_FOREACH(p, link->search_domains ?: link->network->search_domains) link_save_domains(link, f, link->search_domains, DHCP_USE_DOMAINS_NO);
fputs_with_space(f, p, NULL, &space); else
link_save_domains(link, f, link->network->search_domains, DHCP_USE_DOMAINS_YES);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
if (dhcp_domainname)
fputs_with_space(f, dhcp_domainname, NULL, &space);
if (dhcp_domains)
fputstrv(f, dhcp_domains, NULL, &space);
if (dhcp6_domains)
fputstrv(f, dhcp6_domains, NULL, &space);
}
if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_YES) {
NDiscDNSSL *dd;
SET_FOREACH(dd, link->ndisc_dnssl)
fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
}
fputc('\n', f); fputc('\n', f);
/************************************************************/ /************************************************************/
fputs("ROUTE_DOMAINS=", f); fputs("ROUTE_DOMAINS=", f);
space = false; if (link->route_domains)
ORDERED_SET_FOREACH(p, link->route_domains ?: link->network->route_domains) link_save_domains(link, f, link->route_domains, DHCP_USE_DOMAINS_NO);
fputs_with_space(f, p, NULL, &space); else
link_save_domains(link, f, link->network->route_domains, DHCP_USE_DOMAINS_ROUTE);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
if (dhcp_domainname)
fputs_with_space(f, dhcp_domainname, NULL, &space);
if (dhcp_domains)
fputstrv(f, dhcp_domains, NULL, &space);
if (dhcp6_domains)
fputstrv(f, dhcp6_domains, NULL, &space);
}
if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_ROUTE) {
NDiscDNSSL *dd;
SET_FOREACH(dd, link->ndisc_dnssl)
fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
}
fputc('\n', f); fputc('\n', f);
/************************************************************/ /************************************************************/

View File

@ -170,7 +170,7 @@ int dns_answer_add(
/* Entry already exists, keep the entry with the higher TTL. */ /* Entry already exists, keep the entry with the higher TTL. */
if (rr->ttl > exist->rr->ttl) { if (rr->ttl > exist->rr->ttl) {
dns_resource_record_unref(exist->rr); dns_resource_record_unref(exist->rr);
exist->rr = dns_resource_record_ref(rr); exist->rr = dns_resource_record_ref(rr); /* lgtm [cpp/inconsistent-null-check] */
/* Update RRSIG and RR at the same time */ /* Update RRSIG and RR at the same time */
if (rrsig) { if (rrsig) {

View File

@ -484,8 +484,8 @@ TEST(get_process_cmdline_harder) {
/* Test with multiple arguments that do require quoting */ /* Test with multiple arguments that do require quoting */
#define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0" #define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0"
#define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\" \"\"" #define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\""
#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``' \"\"" #define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
assert_se(lseek(fd, SEEK_SET, 0) == 0); assert_se(lseek(fd, SEEK_SET, 0) == 0);
assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1); assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1);
assert_se(ftruncate(fd, sizeof CMDLINE1) == 0); assert_se(ftruncate(fd, sizeof CMDLINE1) == 0);
@ -503,8 +503,8 @@ TEST(get_process_cmdline_harder) {
line = mfree(line); line = mfree(line);
#define CMDLINE2 "foo\0\1\2\3\0\0" #define CMDLINE2 "foo\0\1\2\3\0\0"
#define EXPECT2 "foo \"\\001\\002\\003\" \"\" \"\"" #define EXPECT2 "foo \"\\001\\002\\003\""
#define EXPECT2p "foo $'\\001\\002\\003' \"\" \"\"" #define EXPECT2p "foo $'\\001\\002\\003'"
assert_se(lseek(fd, SEEK_SET, 0) == 0); assert_se(lseek(fd, SEEK_SET, 0) == 0);
assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2); assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2);
assert_se(ftruncate(fd, sizeof CMDLINE2) == 0); assert_se(ftruncate(fd, sizeof CMDLINE2) == 0);

View File

@ -175,7 +175,6 @@ BASICTOOLS=(
sfdisk sfdisk
sh sh
sleep sleep
socat
stat stat
su su
sulogin sulogin

View File

@ -7,8 +7,7 @@ ExecStartPre=rm -f /failed /testok
Type=oneshot Type=oneshot
ExecStart=rm -f /tmp/nonexistent ExecStart=rm -f /tmp/nonexistent
ExecStart=systemctl start test10.socket ExecStart=systemctl start test10.socket
ExecStart=sh -x -c 'printf x >test.file' ExecStart=-nc -w20 -U /run/test.ctl
ExecStart=-socat -T20 OPEN:test.file UNIX-CONNECT:/run/test.ctl
# TriggerLimitIntervalSec= by default is set to 2s. A "sleep 10" should give # TriggerLimitIntervalSec= by default is set to 2s. A "sleep 10" should give
# systemd enough time even on slower machines, to reach the trigger limit. # systemd enough time even on slower machines, to reach the trigger limit.
ExecStart=sleep 10 ExecStart=sleep 10