Merge pull request #1758 from poettering/varietygalore
A grab bag of stuff
This commit is contained in:
@@ -256,6 +256,7 @@
|
||||
/test-socket-util
|
||||
/test-ssd
|
||||
/test-strbuf
|
||||
/test-string-util
|
||||
/test-strip-tab-ansi
|
||||
/test-strv
|
||||
/test-strxcpyx
|
||||
|
||||
@@ -1447,6 +1447,7 @@ tests += \
|
||||
test-utf8 \
|
||||
test-ellipsize \
|
||||
test-util \
|
||||
test-string-util \
|
||||
test-extract-word \
|
||||
test-parse-util \
|
||||
test-user-util \
|
||||
@@ -1748,6 +1749,12 @@ test_util_SOURCES = \
|
||||
test_util_LDADD = \
|
||||
libshared.la
|
||||
|
||||
test_string_util_SOURCES = \
|
||||
src/test/test-string-util.c
|
||||
|
||||
test_string_util_LDADD = \
|
||||
libshared.la
|
||||
|
||||
test_extract_word_SOURCES = \
|
||||
src/test/test-extract-word.c
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ int main(int argc, char *argv[]) {
|
||||
_cleanup_free_ char *value = NULL;
|
||||
const char *clamp;
|
||||
|
||||
if (!shall_restore_state())
|
||||
if (shall_restore_state() == 0)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
if (!validate_device(udev, device))
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
* the watchdog pings will keep the loop busy. */
|
||||
#define DEFAULT_EXIT_USEC (30*USEC_PER_SEC)
|
||||
|
||||
/* The default value for the net.unix.max_dgram_qlen sysctl */
|
||||
#define DEFAULT_UNIX_MAX_DGRAM_QLEN 512UL
|
||||
|
||||
#define SYSTEMD_CGROUP_CONTROLLER "name=systemd"
|
||||
|
||||
#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
|
||||
|
||||
@@ -81,6 +81,19 @@ int parse_mode(const char *s, mode_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_ifindex(const char *s, int *ret) {
|
||||
int ifi, r;
|
||||
|
||||
r = safe_atoi(s, &ifi);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (ifi <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
*ret = ifi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_size(const char *t, uint64_t base, uint64_t *size) {
|
||||
|
||||
/* Soo, sometimes we want to parse IEC binary suffixes, and
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
int parse_boolean(const char *v) _pure_;
|
||||
int parse_pid(const char *s, pid_t* ret_pid);
|
||||
int parse_mode(const char *s, mode_t *ret);
|
||||
int parse_ifindex(const char *s, int *ret);
|
||||
|
||||
int parse_size(const char *t, uint64_t base, uint64_t *size);
|
||||
int parse_range(const char *t, unsigned *lower, unsigned *upper);
|
||||
|
||||
@@ -141,5 +141,5 @@ int shall_restore_state(void) {
|
||||
if (r == 0)
|
||||
return true;
|
||||
|
||||
return parse_boolean(value) != 0;
|
||||
return parse_boolean(value);
|
||||
}
|
||||
|
||||
+23
-8
@@ -748,23 +748,38 @@ int free_and_strdup(char **p, const char *s) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void string_erase(char *x) {
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
|
||||
void* memory_erase(void *p, size_t l) {
|
||||
volatile uint8_t* x = (volatile uint8_t*) p;
|
||||
|
||||
/* This basically does what memset() does, but hopefully isn't
|
||||
* optimized away by the compiler. One of those days, when
|
||||
* glibc learns memset_s() we should replace this call by
|
||||
* memset_s(), but until then this has to do. */
|
||||
|
||||
for (; l > 0; l--)
|
||||
*(x++) = 'x';
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
char* string_erase(char *x) {
|
||||
|
||||
if (!x)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* A delicious drop of snake-oil! To be called on memory where
|
||||
* we stored passphrases or so, after we used them. */
|
||||
|
||||
memory_erase(x, strlen(x));
|
||||
return memory_erase(x, strlen(x));
|
||||
}
|
||||
|
||||
char *string_free_erase(char *s) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
string_erase(s);
|
||||
return mfree(s);
|
||||
return mfree(string_erase(s));
|
||||
}
|
||||
|
||||
bool string_is_safe(const char *p) {
|
||||
|
||||
@@ -162,8 +162,8 @@ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const
|
||||
return memmem(haystack, haystacklen, needle, needlelen);
|
||||
}
|
||||
|
||||
#define memory_erase(p, l) memset((p), 'x', (l))
|
||||
void string_erase(char *x);
|
||||
void* memory_erase(void *p, size_t l);
|
||||
char *string_erase(char *x);
|
||||
|
||||
char *string_free_erase(char *s);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
|
||||
|
||||
@@ -63,7 +63,8 @@ const sd_bus_vtable bus_service_vtable[] = {
|
||||
SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid, offsetof(Service, main_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", NULL, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NFileDescriptorStore", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store), 0),
|
||||
SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("StatusErrno", "i", NULL, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
+40
-1
@@ -1242,12 +1242,50 @@ static int status_welcome(void) {
|
||||
|
||||
static int write_container_id(void) {
|
||||
const char *c;
|
||||
int r;
|
||||
|
||||
c = getenv("container");
|
||||
if (isempty(c))
|
||||
return 0;
|
||||
|
||||
return write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE);
|
||||
r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to write /run/systed/container, ignoring: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bump_unix_max_dgram_qlen(void) {
|
||||
_cleanup_free_ char *qlen = NULL;
|
||||
unsigned long v;
|
||||
int r;
|
||||
|
||||
/* Let's bump the net.unix.max_dgram_qlen sysctl. The kernel
|
||||
* default of 16 is simply too low. We set the value really
|
||||
* really early during boot, so that it is actually applied to
|
||||
* all our sockets, including the $NOTIFY_SOCKET one. */
|
||||
|
||||
r = read_one_line_file("/proc/sys/net/unix/max_dgram_qlen", &qlen);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to read AF_UNIX datagram queue length, ignoring: %m");
|
||||
|
||||
r = safe_atolu(qlen, &v);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to parse AF_UNIX datagram queue length, ignoring: %m");
|
||||
|
||||
if (v >= DEFAULT_UNIX_MAX_DGRAM_QLEN)
|
||||
return 0;
|
||||
|
||||
qlen = mfree(qlen);
|
||||
if (asprintf(&qlen, "%lu\n", DEFAULT_UNIX_MAX_DGRAM_QLEN) < 0)
|
||||
return log_oom();
|
||||
|
||||
r = write_string_file("/proc/sys/net/unix/max_dgram_qlen", qlen, 0);
|
||||
if (r < 0)
|
||||
return log_full_errno(IN_SET(r, -EROFS, -EPERM, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to bump AF_UNIX datagram queue length, ignoring: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@@ -1613,6 +1651,7 @@ int main(int argc, char *argv[]) {
|
||||
hostname_setup();
|
||||
machine_id_setup(NULL);
|
||||
loopback_setup();
|
||||
bump_unix_max_dgram_qlen();
|
||||
|
||||
test_mtab();
|
||||
test_usr();
|
||||
|
||||
@@ -6,6 +6,8 @@ import argparse
|
||||
PARSER = argparse.ArgumentParser()
|
||||
PARSER.add_argument('n', type=int)
|
||||
PARSER.add_argument('--dots', action='store_true')
|
||||
PARSER.add_argument('--data-size', type=int, default=4000)
|
||||
PARSER.add_argument('--data-type', choices={'random', 'simple'})
|
||||
OPTIONS = PARSER.parse_args()
|
||||
|
||||
template = """\
|
||||
@@ -38,10 +40,16 @@ facility = 6
|
||||
src = open('/dev/urandom', 'rb')
|
||||
|
||||
bytes = 0
|
||||
counter = 0
|
||||
|
||||
for i in range(OPTIONS.n):
|
||||
message = repr(src.read(2000))
|
||||
data = repr(src.read(4000))
|
||||
if OPTIONS.data_type == 'random':
|
||||
data = repr(src.read(OPTIONS.data_size))
|
||||
else:
|
||||
# keep the pattern non-repeating so we get a different blob every time
|
||||
data = '{:0{}}'.format(counter, OPTIONS.data_size)
|
||||
counter += 1
|
||||
|
||||
entry = template.format(m=m,
|
||||
realtime_ts=realtime_ts,
|
||||
|
||||
@@ -2705,7 +2705,7 @@ int journal_file_open(
|
||||
}
|
||||
|
||||
if (f->last_stat.st_size < (off_t) HEADER_SIZE_MIN) {
|
||||
r = -EIO;
|
||||
r = -ENODATA;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ struct sd_journal {
|
||||
Hashmap *directories_by_path;
|
||||
Hashmap *directories_by_wd;
|
||||
|
||||
Set *errors;
|
||||
Hashmap *errors;
|
||||
};
|
||||
|
||||
char *journal_make_match_string(sd_journal *j);
|
||||
|
||||
@@ -1708,36 +1708,50 @@ static int access_check_var_log_journal(sd_journal *j) {
|
||||
static int access_check(sd_journal *j) {
|
||||
Iterator it;
|
||||
void *code;
|
||||
char *path;
|
||||
int r = 0;
|
||||
|
||||
assert(j);
|
||||
|
||||
if (set_isempty(j->errors)) {
|
||||
if (hashmap_isempty(j->errors)) {
|
||||
if (ordered_hashmap_isempty(j->files))
|
||||
log_notice("No journal files were found.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
|
||||
if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
|
||||
(void) access_check_var_log_journal(j);
|
||||
|
||||
if (ordered_hashmap_isempty(j->files))
|
||||
r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
|
||||
}
|
||||
|
||||
SET_FOREACH(code, j->errors, it) {
|
||||
HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
|
||||
int err;
|
||||
|
||||
err = -PTR_TO_INT(code);
|
||||
assert(err > 0);
|
||||
err = abs(PTR_TO_INT(code));
|
||||
|
||||
if (err == EACCES)
|
||||
switch (err) {
|
||||
case EACCES:
|
||||
continue;
|
||||
|
||||
log_warning_errno(err, "Error was encountered while opening journal files: %m");
|
||||
if (r == 0)
|
||||
r = -err;
|
||||
case ENODATA:
|
||||
log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
|
||||
break;
|
||||
|
||||
case EPROTONOSUPPORT:
|
||||
log_warning_errno(err, "Journal file %s uses an unsupported feature, ignoring file.", path);
|
||||
break;
|
||||
|
||||
case EBADMSG:
|
||||
log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warning_errno(err, "An error was encountered while opening journal file %s, ignoring file.", path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
+150
-146
@@ -73,19 +73,46 @@ static bool journal_pid_changed(sd_journal *j) {
|
||||
return j->original_pid != getpid();
|
||||
}
|
||||
|
||||
/* We return an error here only if we didn't manage to
|
||||
memorize the real error. */
|
||||
static int set_put_error(sd_journal *j, int r) {
|
||||
static int journal_put_error(sd_journal *j, int r, const char *path) {
|
||||
char *copy;
|
||||
int k;
|
||||
|
||||
/* Memorize an error we encountered, and store which
|
||||
* file/directory it was generated from. Note that we store
|
||||
* only *one* path per error code, as the error code is the
|
||||
* key into the hashmap, and the path is the value. This means
|
||||
* we keep track only of all error kinds, but not of all error
|
||||
* locations. This has the benefit that the hashmap cannot
|
||||
* grow beyond bounds.
|
||||
*
|
||||
* We return an error here only if we didn't manage to
|
||||
* memorize the real error. */
|
||||
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
k = set_ensure_allocated(&j->errors, NULL);
|
||||
k = hashmap_ensure_allocated(&j->errors, NULL);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
return set_put(j->errors, INT_TO_PTR(r));
|
||||
if (path) {
|
||||
copy = strdup(path);
|
||||
if (!copy)
|
||||
return -ENOMEM;
|
||||
} else
|
||||
copy = NULL;
|
||||
|
||||
k = hashmap_put(j->errors, INT_TO_PTR(r), copy);
|
||||
if (k < 0) {
|
||||
free(copy);
|
||||
|
||||
if (k == -EEXIST)
|
||||
return 0;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void detach_location(sd_journal *j) {
|
||||
@@ -1183,6 +1210,8 @@ static bool file_has_type_prefix(const char *prefix, const char *filename) {
|
||||
}
|
||||
|
||||
static bool file_type_wanted(int flags, const char *filename) {
|
||||
assert(filename);
|
||||
|
||||
if (!endswith(filename, ".journal") && !endswith(filename, ".journal~"))
|
||||
return false;
|
||||
|
||||
@@ -1207,7 +1236,7 @@ static bool file_type_wanted(int flags, const char *filename) {
|
||||
|
||||
static int add_any_file(sd_journal *j, const char *path) {
|
||||
JournalFile *f = NULL;
|
||||
int r;
|
||||
int r, k;
|
||||
|
||||
assert(j);
|
||||
assert(path);
|
||||
@@ -1216,20 +1245,23 @@ static int add_any_file(sd_journal *j, const char *path) {
|
||||
return 0;
|
||||
|
||||
if (ordered_hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
|
||||
log_warning("Too many open journal files, not adding %s.", path);
|
||||
return set_put_error(j, -ETOOMANYREFS);
|
||||
log_debug("Too many open journal files, not adding %s.", path);
|
||||
r = -ETOOMANYREFS;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to open journal file %s: %m", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* journal_file_dump(f); */
|
||||
|
||||
r = ordered_hashmap_put(j->files, f->path, f);
|
||||
if (r < 0) {
|
||||
journal_file_close(f);
|
||||
return r;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
log_debug("File %s added.", f->path);
|
||||
@@ -1239,11 +1271,17 @@ static int add_any_file(sd_journal *j, const char *path) {
|
||||
j->current_invalidate_counter ++;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
k = journal_put_error(j, r, path);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int add_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
int r;
|
||||
const char *path;
|
||||
|
||||
assert(j);
|
||||
assert(prefix);
|
||||
@@ -1253,34 +1291,24 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
!file_type_wanted(j->flags, filename))
|
||||
return 0;
|
||||
|
||||
path = strjoin(prefix, "/", filename, NULL);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
r = add_any_file(j, path);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
return r;
|
||||
path = strjoina(prefix, "/", filename);
|
||||
return add_any_file(j, path);
|
||||
}
|
||||
|
||||
static int remove_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
_cleanup_free_ char *path;
|
||||
static void remove_file(sd_journal *j, const char *prefix, const char *filename) {
|
||||
const char *path;
|
||||
JournalFile *f;
|
||||
|
||||
assert(j);
|
||||
assert(prefix);
|
||||
assert(filename);
|
||||
|
||||
path = strjoin(prefix, "/", filename, NULL);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
path = strjoina(prefix, "/", filename);
|
||||
f = ordered_hashmap_get(j->files, path);
|
||||
if (!f)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
remove_file_real(j, f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void remove_file_real(sd_journal *j, JournalFile *f) {
|
||||
@@ -1309,12 +1337,27 @@ static void remove_file_real(sd_journal *j, JournalFile *f) {
|
||||
j->current_invalidate_counter ++;
|
||||
}
|
||||
|
||||
static int dirname_is_machine_id(const char *fn) {
|
||||
sd_id128_t id, machine;
|
||||
int r;
|
||||
|
||||
r = sd_id128_get_machine(&machine);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_id128_from_string(fn, &id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_id128_equal(id, machine);
|
||||
}
|
||||
|
||||
static int add_directory(sd_journal *j, const char *prefix, const char *dirname) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
int r;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
sd_id128_t id, mid;
|
||||
struct dirent *de = NULL;
|
||||
Directory *m;
|
||||
int r, k;
|
||||
|
||||
assert(j);
|
||||
assert(prefix);
|
||||
@@ -1323,35 +1366,36 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
|
||||
log_debug("Considering %s/%s.", prefix, dirname);
|
||||
|
||||
if ((j->flags & SD_JOURNAL_LOCAL_ONLY) &&
|
||||
(sd_id128_from_string(dirname, &id) < 0 ||
|
||||
sd_id128_get_machine(&mid) < 0 ||
|
||||
!(sd_id128_equal(id, mid) || path_startswith(prefix, "/run"))))
|
||||
!(dirname_is_machine_id(dirname) > 0 || path_startswith(prefix, "/run")))
|
||||
return 0;
|
||||
|
||||
path = strjoin(prefix, "/", dirname, NULL);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
if (!path) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
d = opendir(path);
|
||||
if (!d) {
|
||||
log_debug_errno(errno, "Failed to open %s: %m", path);
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
return -errno;
|
||||
r = log_debug_errno(errno, "Failed to open directory %s: %m", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
m = hashmap_get(j->directories_by_path, path);
|
||||
if (!m) {
|
||||
m = new0(Directory, 1);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
if (!m) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
m->is_root = false;
|
||||
m->path = path;
|
||||
|
||||
if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
|
||||
free(m);
|
||||
return -ENOMEM;
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
path = NULL; /* avoid freeing in cleanup */
|
||||
@@ -1373,41 +1417,30 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
|
||||
inotify_rm_watch(j->inotify_fd, m->wd);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
struct dirent *de;
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
if (!de && errno != 0) {
|
||||
r = -errno;
|
||||
log_debug_errno(errno, "Failed to read directory %s: %m", m->path);
|
||||
return r;
|
||||
}
|
||||
if (!de)
|
||||
break;
|
||||
FOREACH_DIRENT_ALL(de, d, return log_debug_errno(errno, "Failed to read directory %s: %m", m->path)) {
|
||||
|
||||
if (dirent_is_file_with_suffix(de, ".journal") ||
|
||||
dirent_is_file_with_suffix(de, ".journal~")) {
|
||||
r = add_file(j, m->path, de->d_name);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to add file %s/%s: %m",
|
||||
m->path, de->d_name);
|
||||
r = set_put_error(j, r);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
dirent_is_file_with_suffix(de, ".journal~"))
|
||||
(void) add_file(j, m->path, de->d_name);
|
||||
}
|
||||
|
||||
check_network(j, dirfd(d));
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
k = journal_put_error(j, r, path ?: dirname);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int add_root_directory(sd_journal *j, const char *p) {
|
||||
static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
struct dirent *de;
|
||||
Directory *m;
|
||||
int r;
|
||||
int r, k;
|
||||
|
||||
assert(j);
|
||||
assert(p);
|
||||
@@ -1420,26 +1453,35 @@ static int add_root_directory(sd_journal *j, const char *p) {
|
||||
p = strjoina(j->prefix, p);
|
||||
|
||||
d = opendir(p);
|
||||
if (!d)
|
||||
return -errno;
|
||||
if (!d) {
|
||||
if (errno == ENOENT && missing_ok)
|
||||
return 0;
|
||||
|
||||
r = log_debug_errno(errno, "Failed to open root directory %s: %m", p);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
m = hashmap_get(j->directories_by_path, p);
|
||||
if (!m) {
|
||||
m = new0(Directory, 1);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
if (!m) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
m->is_root = true;
|
||||
m->path = strdup(p);
|
||||
if (!m->path) {
|
||||
free(m);
|
||||
return -ENOMEM;
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
|
||||
free(m->path);
|
||||
free(m);
|
||||
return -ENOMEM;
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
j->current_invalidate_counter ++;
|
||||
@@ -1462,42 +1504,27 @@ static int add_root_directory(sd_journal *j, const char *p) {
|
||||
if (j->no_new_files)
|
||||
return 0;
|
||||
|
||||
for (;;) {
|
||||
struct dirent *de;
|
||||
FOREACH_DIRENT_ALL(de, d, return log_debug_errno(errno, "Failed to read directory %s: %m", m->path)) {
|
||||
sd_id128_t id;
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
if (!de && errno != 0) {
|
||||
r = -errno;
|
||||
log_debug_errno(errno, "Failed to read directory %s: %m", m->path);
|
||||
return r;
|
||||
}
|
||||
if (!de)
|
||||
break;
|
||||
|
||||
if (dirent_is_file_with_suffix(de, ".journal") ||
|
||||
dirent_is_file_with_suffix(de, ".journal~")) {
|
||||
r = add_file(j, m->path, de->d_name);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to add file %s/%s: %m",
|
||||
m->path, de->d_name);
|
||||
r = set_put_error(j, r);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
} else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) &&
|
||||
sd_id128_from_string(de->d_name, &id) >= 0) {
|
||||
|
||||
r = add_directory(j, m->path, de->d_name);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to add directory %s/%s: %m", m->path, de->d_name);
|
||||
}
|
||||
dirent_is_file_with_suffix(de, ".journal~"))
|
||||
(void) add_file(j, m->path, de->d_name);
|
||||
else if (IN_SET(de->d_type, DT_DIR, DT_LNK, DT_UNKNOWN) &&
|
||||
sd_id128_from_string(de->d_name, &id) >= 0)
|
||||
(void) add_directory(j, m->path, de->d_name);
|
||||
}
|
||||
|
||||
check_network(j, dirfd(d));
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
k = journal_put_error(j, r, p);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void remove_directory(sd_journal *j, Directory *d) {
|
||||
@@ -1522,8 +1549,8 @@ static void remove_directory(sd_journal *j, Directory *d) {
|
||||
}
|
||||
|
||||
static int add_search_paths(sd_journal *j) {
|
||||
int r;
|
||||
const char search_paths[] =
|
||||
|
||||
static const char search_paths[] =
|
||||
"/run/log/journal\0"
|
||||
"/var/log/journal\0";
|
||||
const char *p;
|
||||
@@ -1533,14 +1560,8 @@ static int add_search_paths(sd_journal *j) {
|
||||
/* We ignore most errors here, since the idea is to only open
|
||||
* what's actually accessible, and ignore the rest. */
|
||||
|
||||
NULSTR_FOREACH(p, search_paths) {
|
||||
r = add_root_directory(j, p);
|
||||
if (r < 0 && r != -ENOENT) {
|
||||
r = set_put_error(j, r);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
NULSTR_FOREACH(p, search_paths)
|
||||
(void) add_root_directory(j, p, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1564,17 +1585,14 @@ static int add_current_paths(sd_journal *j) {
|
||||
if (!dir)
|
||||
return -ENOMEM;
|
||||
|
||||
r = add_root_directory(j, dir);
|
||||
if (r < 0) {
|
||||
set_put_error(j, r);
|
||||
r = add_root_directory(j, dir, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int allocate_inotify(sd_journal *j) {
|
||||
assert(j);
|
||||
|
||||
@@ -1702,11 +1720,9 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
r = add_root_directory(j, path);
|
||||
if (r < 0) {
|
||||
set_put_error(j, r);
|
||||
r = add_root_directory(j, path, false);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*ret = j;
|
||||
return 0;
|
||||
@@ -1731,10 +1747,8 @@ _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int fla
|
||||
|
||||
STRV_FOREACH(path, paths) {
|
||||
r = add_any_file(j, *path);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to open %s: %m", *path);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
j->no_new_files = true;
|
||||
@@ -1751,6 +1765,7 @@ fail:
|
||||
_public_ void sd_journal_close(sd_journal *j) {
|
||||
Directory *d;
|
||||
JournalFile *f;
|
||||
char *p;
|
||||
|
||||
if (!j)
|
||||
return;
|
||||
@@ -1778,10 +1793,13 @@ _public_ void sd_journal_close(sd_journal *j) {
|
||||
mmap_cache_unref(j->mmap);
|
||||
}
|
||||
|
||||
while ((p = hashmap_steal_first(j->errors)))
|
||||
free(p);
|
||||
hashmap_free(j->errors);
|
||||
|
||||
free(j->path);
|
||||
free(j->prefix);
|
||||
free(j->unique_field);
|
||||
set_free(j->errors);
|
||||
free(j);
|
||||
}
|
||||
|
||||
@@ -2074,7 +2092,7 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
|
||||
if (j->no_new_files)
|
||||
r = add_current_paths(j);
|
||||
else if (j->path)
|
||||
r = add_root_directory(j, j->path);
|
||||
r = add_root_directory(j, j->path, true);
|
||||
else
|
||||
r = add_search_paths(j);
|
||||
if (r < 0)
|
||||
@@ -2121,7 +2139,6 @@ _public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) {
|
||||
|
||||
static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
|
||||
Directory *d;
|
||||
int r;
|
||||
|
||||
assert(j);
|
||||
assert(e);
|
||||
@@ -2137,20 +2154,10 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
|
||||
|
||||
/* Event for a journal file */
|
||||
|
||||
if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
|
||||
r = add_file(j, d->path, e->name);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to add file %s/%s: %m",
|
||||
d->path, e->name);
|
||||
set_put_error(j, r);
|
||||
}
|
||||
|
||||
} else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) {
|
||||
|
||||
r = remove_file(j, d->path, e->name);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to remove file %s/%s: %m", d->path, e->name);
|
||||
}
|
||||
if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB))
|
||||
(void) add_file(j, d->path, e->name);
|
||||
else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT))
|
||||
remove_file(j, d->path, e->name);
|
||||
|
||||
} else if (!d->is_root && e->len == 0) {
|
||||
|
||||
@@ -2163,11 +2170,8 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
|
||||
|
||||
/* Event for root directory */
|
||||
|
||||
if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
|
||||
r = add_directory(j, d->path, e->name);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to add directory %s/%s: %m", d->path, e->name);
|
||||
}
|
||||
if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB))
|
||||
(void) add_directory(j, d->path, e->name);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -2176,7 +2180,7 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
|
||||
if (e->mask & IN_IGNORED)
|
||||
return;
|
||||
|
||||
log_warning("Unknown inotify event.");
|
||||
log_debug("Unknown inotify event.");
|
||||
}
|
||||
|
||||
static int determine_change(sd_journal *j) {
|
||||
|
||||
@@ -356,13 +356,10 @@ int device_set_ifindex(sd_device *device, const char *_ifindex) {
|
||||
assert(device);
|
||||
assert(_ifindex);
|
||||
|
||||
r = safe_atoi(_ifindex, &ifindex);
|
||||
r = parse_ifindex(_ifindex, &ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ifindex <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = device_add_property_internal(device, "IFINDEX", _ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -632,11 +629,9 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
|
||||
struct ifreq ifr = {};
|
||||
int ifindex;
|
||||
|
||||
r = safe_atoi(&id[1], &ifr.ifr_ifindex);
|
||||
r = parse_ifindex(&id[1], &ifr.ifr_ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
else if (ifr.ifr_ifindex <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
sk = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sk < 0)
|
||||
|
||||
@@ -932,9 +932,7 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) {
|
||||
|
||||
*(char*) (mempcpy(buf, word, l)) = 0;
|
||||
|
||||
if (safe_atoi(buf, &ifi) < 0)
|
||||
continue;
|
||||
if (ifi <= 0)
|
||||
if (parse_ifindex(buf, &ifi) < 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
|
||||
|
||||
@@ -325,16 +325,14 @@ int machine_load(Machine *m) {
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
if (r == 0)
|
||||
break;
|
||||
else if (r == -ENOMEM)
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
else if (r < 0) {
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to parse NETIF: %s", netif);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (safe_atoi(word, &ifi) < 0)
|
||||
continue;
|
||||
if (ifi <= 0)
|
||||
if (parse_ifindex(word, &ifi) < 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
|
||||
|
||||
@@ -521,7 +521,7 @@ static int link_status_one(
|
||||
assert(rtnl);
|
||||
assert(name);
|
||||
|
||||
if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
|
||||
if (parse_ifindex(name, &ifindex) >= 0)
|
||||
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
|
||||
else {
|
||||
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
|
||||
|
||||
@@ -103,7 +103,7 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
r = safe_atoi(identifier, &ifindex);
|
||||
r = parse_ifindex(identifier, &ifindex);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -300,8 +300,7 @@ static int parse_address(const char *s, int *family, union in_addr_union *addres
|
||||
|
||||
percent = strchr(s, '%');
|
||||
if (percent) {
|
||||
r = safe_atoi(percent+1, &ifi);
|
||||
if (r < 0 || ifi <= 0) {
|
||||
if (parse_ifindex(percent+1, &ifi) < 0) {
|
||||
ifi = if_nametoindex(percent+1);
|
||||
if (ifi <= 0)
|
||||
return -EINVAL;
|
||||
@@ -521,7 +520,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case 'i': {
|
||||
int ifi;
|
||||
|
||||
if (safe_atoi(optarg, &ifi) >= 0 && ifi > 0)
|
||||
if (parse_ifindex(optarg, &ifi) >= 0)
|
||||
arg_ifindex = ifi;
|
||||
else {
|
||||
ifi = if_nametoindex(optarg);
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@ static int load_state(
|
||||
assert(udev);
|
||||
assert(event);
|
||||
|
||||
if (!shall_restore_state())
|
||||
if (shall_restore_state() == 0)
|
||||
return 0;
|
||||
|
||||
r = find_device(udev, event, &device);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2015 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "string-util.h"
|
||||
|
||||
static void test_string_erase(void) {
|
||||
char *x;
|
||||
|
||||
x = strdupa("");
|
||||
assert_se(streq(string_erase(x), ""));
|
||||
|
||||
x = strdupa("1");
|
||||
assert_se(streq(string_erase(x), "x"));
|
||||
|
||||
x = strdupa("12");
|
||||
assert_se(streq(string_erase(x), "xx"));
|
||||
|
||||
x = strdupa("123");
|
||||
assert_se(streq(string_erase(x), "xxx"));
|
||||
|
||||
x = strdupa("1234");
|
||||
assert_se(streq(string_erase(x), "xxxx"));
|
||||
|
||||
x = strdupa("12345");
|
||||
assert_se(streq(string_erase(x), "xxxxx"));
|
||||
|
||||
x = strdupa("123456");
|
||||
assert_se(streq(string_erase(x), "xxxxxx"));
|
||||
|
||||
x = strdupa("1234567");
|
||||
assert_se(streq(string_erase(x), "xxxxxxx"));
|
||||
|
||||
x = strdupa("12345678");
|
||||
assert_se(streq(string_erase(x), "xxxxxxxx"));
|
||||
|
||||
x = strdupa("123456789");
|
||||
assert_se(streq(string_erase(x), "xxxxxxxxx"));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_string_erase();
|
||||
return 0;
|
||||
}
|
||||
@@ -35,9 +35,6 @@ net.ipv4.conf.all.promote_secondaries = 1
|
||||
# Fair Queue CoDel packet scheduler to fight bufferbloat
|
||||
net.core.default_qdisc = fq_codel
|
||||
|
||||
# Make sure we can queue more than just a few datagrams in AF_UNIX sockets.
|
||||
net.unix.max_dgram_qlen = 512
|
||||
|
||||
# Enable hard and soft link protection
|
||||
fs.protected_hardlinks = 1
|
||||
fs.protected_symlinks = 1
|
||||
|
||||
Reference in New Issue
Block a user