systemd: merge branch systemd into master

This commit is contained in:
Beniamino Galvani 2018-02-23 14:13:43 +01:00
commit 823839e933
15 changed files with 197 additions and 75 deletions

View file

@ -1183,6 +1183,7 @@ int fflush_and_check(FILE *f) {
return 0;
}
#if 0 /* NM_IGNORED */
int fflush_sync_and_check(FILE *f) {
int r;
@ -1195,8 +1196,13 @@ int fflush_sync_and_check(FILE *f) {
if (fsync(fileno(f)) < 0)
return -errno;
r = fsync_directory_of_file(fileno(f));
if (r < 0)
return r;
return 0;
}
#endif /* NM_IGNORED */
/* This is much like mkostemp() but is subject to umask(). */
int mkostemp_safe(char *pattern) {

View file

@ -561,6 +561,17 @@ int tmp_dir(const char **ret) {
return tmp_dir_internal("/tmp", ret);
}
int unlink_or_warn(const char *filename) {
if (unlink(filename) < 0 && errno != ENOENT)
/* If the file doesn't exist and the fs simply was read-only (in which
* case unlink() returns EROFS even if the file doesn't exist), don't
* complain */
if (errno != EROFS || access(filename, F_OK) >= 0)
return log_error_errno(errno, "Failed to remove \"%s\": %m", filename);
return 0;
}
int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
int r;
@ -963,4 +974,34 @@ int unlinkat_deallocate(int fd, const char *name, int flags) {
return 0;
}
int fsync_directory_of_file(int fd) {
_cleanup_free_ char *path = NULL, *dn = NULL;
_cleanup_close_ int dfd = -1;
int r;
r = fd_verify_regular(fd);
if (r < 0)
return r;
r = fd_get_path(fd, &path);
if (r < 0)
return r;
if (!path_is_absolute(path))
return -EINVAL;
dn = dirname_malloc(path);
if (!dn)
return -ENOMEM;
dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
if (dfd < 0)
return -errno;
if (fsync(dfd) < 0)
return -errno;
return 0;
}
#endif /* NM_IGNORED */

View file

@ -64,6 +64,8 @@ int get_files_in_directory(const char *path, char ***list);
int tmp_dir(const char **ret);
int var_tmp_dir(const char **ret);
int unlink_or_warn(const char *filename);
#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
@ -105,3 +107,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
int access_fd(int fd, int mode);
int unlinkat_deallocate(int fd, const char *name, int flags);
int fsync_directory_of_file(int fd);

View file

@ -139,7 +139,7 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
assert(fd >= 0);
assert(buf);
if (nbytes > (size_t) SSIZE_MAX)
if (_unlikely_(nbytes > (size_t) SSIZE_MAX))
return -EINVAL;
do {

View file

@ -536,6 +536,30 @@ int safe_atoi16(const char *s, int16_t *ret) {
}
#if 0 /* NM_IGNORED */
int safe_atoux16(const char *s, uint16_t *ret) {
char *x = NULL;
unsigned long l;
assert(s);
assert(ret);
s += strspn(s, WHITESPACE);
errno = 0;
l = strtoul(s, &x, 16);
if (errno > 0)
return -errno;
if (!x || x == s || *x != 0)
return -EINVAL;
if (s[0] == '-')
return -ERANGE;
if ((unsigned long) (uint16_t) l != l)
return -ERANGE;
*ret = (uint16_t) l;
return 0;
}
int safe_atod(const char *s, double *ret_d) {
_cleanup_(freelocalep) locale_t loc = (locale_t) 0;
char *x = NULL;

View file

@ -54,6 +54,8 @@ int safe_atou8(const char *s, uint8_t *ret);
int safe_atou16(const char *s, uint16_t *ret);
int safe_atoi16(const char *s, int16_t *ret);
int safe_atoux16(const char *s, uint16_t *ret);
static inline int safe_atou32(const char *s, uint32_t *ret_u) {
assert_cc(sizeof(uint32_t) == sizeof(unsigned));
return safe_atou(s, (unsigned*) ret_u);

View file

@ -403,37 +403,61 @@ use_saved_argv:
}
int is_kernel_thread(pid_t pid) {
_cleanup_free_ char *line = NULL;
unsigned long long flags;
size_t l, i;
const char *p;
size_t count;
char c;
bool eof;
FILE *f;
char *q;
int r;
if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
return 0;
if (!pid_is_valid(pid))
return -EINVAL;
assert(pid > 1);
p = procfs_file_alloca(pid, "stat");
r = read_one_line_file(p, &line);
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
return r;
p = procfs_file_alloca(pid, "cmdline");
f = fopen(p, "re");
if (!f) {
if (errno == ENOENT)
return -ESRCH;
return -errno;
/* Skip past the comm field */
q = strrchr(line, ')');
if (!q)
return -EINVAL;
q++;
/* Skip 6 fields to reach the flags field */
for (i = 0; i < 6; i++) {
l = strspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
l = strcspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
}
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
/* Skip preceeding whitespace */
l = strspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
count = fread(&c, 1, 1, f);
eof = feof(f);
fclose(f);
/* Truncate the rest */
l = strcspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q[l] = 0;
/* Kernel threads have an empty cmdline */
r = safe_atollu(q, &flags);
if (r < 0)
return r;
if (count <= 0)
return eof ? 1 : -errno;
return 0;
return !!(flags & PF_KTHREAD);
}
int get_process_capeff(pid_t pid, char **capeff) {
@ -831,17 +855,33 @@ int kill_and_sigcont(pid_t pid, int sig) {
return r;
}
int getenv_for_pid(pid_t pid, const char *field, char **_value) {
int getenv_for_pid(pid_t pid, const char *field, char **ret) {
_cleanup_fclose_ FILE *f = NULL;
char *value = NULL;
int r;
bool done = false;
size_t l;
const char *path;
size_t l;
assert(pid >= 0);
assert(field);
assert(_value);
assert(ret);
if (pid == 0 || pid == getpid_cached()) {
const char *e;
e = getenv(field);
if (!e) {
*ret = NULL;
return 0;
}
value = strdup(e);
if (!value)
return -ENOMEM;
*ret = value;
return 1;
}
path = procfs_file_alloca(pid, "environ");
@ -849,13 +889,13 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value) {
if (!f) {
if (errno == ENOENT)
return -ESRCH;
return -errno;
}
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
l = strlen(field);
r = 0;
do {
char line[LINE_MAX];
@ -880,14 +920,14 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value) {
if (!value)
return -ENOMEM;
r = 1;
break;
*ret = value;
return 1;
}
} while (!done);
*_value = value;
return r;
*ret = NULL;
return 0;
}
bool pid_is_unwaited(pid_t pid) {

View file

@ -179,6 +179,7 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i
}
char ***strv_free_free(char ***l);
DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free);
char **strv_skip(char **l, size_t n);

View file

@ -410,3 +410,22 @@ int utf8_encoded_valid_unichar(const char *str) {
return len;
}
size_t utf8_n_codepoints(const char *str) {
size_t n = 0;
/* Returns the number of UTF-8 codepoints in this string, or (size_t) -1 if the string is not valid UTF-8. */
while (*str != 0) {
int k;
k = utf8_encoded_valid_unichar(str);
if (k < 0)
return (size_t) -1;
str += k;
n++;
}
return n;
}

View file

@ -61,3 +61,5 @@ static inline bool utf16_is_trailing_surrogate(char16_t c) {
static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) {
return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000;
}
size_t utf8_n_codepoints(const char *str);

View file

@ -523,29 +523,6 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
return m / max;
}
int update_reboot_parameter_and_warn(const char *param) {
int r;
if (isempty(param)) {
if (unlink("/run/systemd/reboot-param") < 0) {
if (errno == ENOENT)
return 0;
return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m");
}
return 0;
}
RUN_WITH_UMASK(0022) {
r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE);
if (r < 0)
return log_warning_errno(r, "Failed to write reboot parameter file: %m");
}
return 0;
}
int version(void) {
puts(PACKAGE_STRING "\n"
SYSTEMD_FEATURES);

View file

@ -186,8 +186,6 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max);
uint64_t system_tasks_max(void);
uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
int update_reboot_parameter_and_warn(const char *param);
int version(void);
int str_verscmp(const char *s1, const char *s2);

View file

@ -775,8 +775,6 @@ static int client_parse_message(
size_t pos = 0;
int r;
bool clientid = false;
uint8_t *id = NULL;
size_t id_len;
uint32_t lt_t1 = ~0, lt_t2 = ~0;
assert(client);
@ -821,8 +819,8 @@ static int client_parse_message(
break;
case SD_DHCP6_OPTION_SERVERID:
r = dhcp6_lease_get_serverid(lease, &id, &id_len);
if (r >= 0 && id) {
r = dhcp6_lease_get_serverid(lease, NULL, NULL);
if (r >= 0) {
log_dhcp6_client(client, "%s contains multiple serverids",
dhcp6_message_type_to_string(message->type));
return -EINVAL;
@ -960,21 +958,23 @@ static int client_parse_message(
}
if (client->state != DHCP6_STATE_INFORMATION_REQUEST) {
r = dhcp6_lease_get_serverid(lease, &id, &id_len);
if (r < 0)
r = dhcp6_lease_get_serverid(lease, NULL, NULL);
if (r < 0) {
log_dhcp6_client(client, "%s has no server id",
dhcp6_message_type_to_string(message->type));
return r;
}
return -EINVAL;
}
if (lease->ia.addresses) {
lease->ia.ia_na.lifetime_t1 = htobe32(lt_t1);
lease->ia.ia_na.lifetime_t2 = htobe32(lt_t2);
}
} else {
if (lease->ia.addresses) {
lease->ia.ia_na.lifetime_t1 = htobe32(lt_t1);
lease->ia.ia_na.lifetime_t2 = htobe32(lt_t2);
}
if (lease->pd.addresses) {
lease->pd.ia_pd.lifetime_t1 = htobe32(lt_t1);
lease->pd.ia_pd.lifetime_t2 = htobe32(lt_t2);
if (lease->pd.addresses) {
lease->pd.ia_pd.lifetime_t1 = htobe32(lt_t1);
lease->pd.ia_pd.lifetime_t2 = htobe32(lt_t2);
}
}
return 0;

View file

@ -97,11 +97,14 @@ int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
assert_return(lease, -EINVAL);
assert_return(id, -EINVAL);
assert_return(len, -EINVAL);
*id = lease->serverid;
*len = lease->serverid_len;
if (!lease->serverid)
return -ENOMSG;
if (id)
*id = lease->serverid;
if (len)
*len = lease->serverid_len;
return 0;
}

View file

@ -25,6 +25,7 @@
#include <unistd.h>
#include "fd-util.h"
#include "fs-util.h"
#include "hexdecoct.h"
#include "id128-util.h"
#include "io-util.h"
@ -185,9 +186,13 @@ int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
if (do_sync) {
if (fsync(fd) < 0)
return -errno;
r = fsync_directory_of_file(fd);
if (r < 0)
return r;
}
return r;
return 0;
}
int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) {