50
50
#define DEFAULT_DATA_THRESHOLD (64*1024)
52
/* We return an error here only if we didn't manage to
53
memorize the real error. */
54
static int set_put_error(sd_journal *j, int r) {
60
k = set_ensure_allocated(&j->errors, trivial_hash_func, trivial_compare_func);
64
return set_put(j->errors, INT_TO_PTR(r));
52
67
static void detach_location(sd_journal *j) {
190
208
_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
191
Match *l2, *l3, *add_here = NULL, *m;
209
Match *l3, *l4, *add_here = NULL, *m;
203
221
if (!match_is_valid(data, size))
209
* level 3: concrete matches */
228
* level 4: concrete matches */
211
230
if (!j->level0) {
212
j->level0 = match_new(NULL, MATCH_OR_TERM);
231
j->level0 = match_new(NULL, MATCH_AND_TERM);
217
236
if (!j->level1) {
218
j->level1 = match_new(j->level0, MATCH_AND_TERM);
237
j->level1 = match_new(j->level0, MATCH_OR_TERM);
223
assert(j->level0->type == MATCH_OR_TERM);
224
assert(j->level1->type == MATCH_AND_TERM);
243
j->level2 = match_new(j->level1, MATCH_AND_TERM);
248
assert(j->level0->type == MATCH_AND_TERM);
249
assert(j->level1->type == MATCH_OR_TERM);
250
assert(j->level2->type == MATCH_AND_TERM);
226
252
le_hash = htole64(hash64(data, size));
228
LIST_FOREACH(matches, l2, j->level1->matches) {
229
assert(l2->type == MATCH_OR_TERM);
254
LIST_FOREACH(matches, l3, j->level2->matches) {
255
assert(l3->type == MATCH_OR_TERM);
231
LIST_FOREACH(matches, l3, l2->matches) {
232
assert(l3->type == MATCH_DISCRETE);
257
LIST_FOREACH(matches, l4, l3->matches) {
258
assert(l4->type == MATCH_DISCRETE);
234
260
/* Exactly the same match already? Then ignore
235
261
* this addition */
236
if (l3->le_hash == le_hash &&
238
memcmp(l3->data, data, size) == 0)
262
if (l4->le_hash == le_hash &&
264
memcmp(l4->data, data, size) == 0)
241
267
/* Same field? Then let's add this to this OR term */
242
if (same_field(data, size, l3->data, l3->size)) {
268
if (same_field(data, size, l4->data, l4->size)) {
1209
1253
j->on_network =
1210
(long)sfs.f_type == (long)CIFS_MAGIC_NUMBER ||
1211
sfs.f_type == CODA_SUPER_MAGIC ||
1212
sfs.f_type == NCP_SUPER_MAGIC ||
1213
sfs.f_type == NFS_SUPER_MAGIC ||
1214
sfs.f_type == SMB_SUPER_MAGIC;
1254
sfs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER ||
1255
sfs.f_type == (__SWORD_TYPE) CODA_SUPER_MAGIC ||
1256
sfs.f_type == (__SWORD_TYPE) NCP_SUPER_MAGIC ||
1257
sfs.f_type == (__SWORD_TYPE) NFS_SUPER_MAGIC ||
1258
sfs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC;
1217
1261
static int add_file(sd_journal *j, const char *prefix, const char *filename) {
1262
_cleanup_free_ char *path = NULL;
1220
1264
JournalFile *f;
1235
1279
return -ENOMEM;
1237
if (hashmap_get(j->files, path)) {
1281
if (hashmap_get(j->files, path))
1242
1284
if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
1243
1285
log_debug("Too many open journal files, not adding %s, ignoring.", path);
1286
return set_put_error(j, -ETOOMANYREFS);
1248
1289
r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
1252
1291
if (errno == ENOENT)
1346
1383
m = hashmap_get(j->directories_by_path, path);
1348
1385
m = new0(Directory, 1);
1352
1387
return -ENOMEM;
1355
1389
m->is_root = false;
1356
1390
m->path = path;
1358
1392
if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
1362
1394
return -ENOMEM;
1397
path = NULL; /* avoid freeing in cleanup */
1365
1398
j->current_invalidate_counter ++;
1367
1400
log_debug("Directory %s got added.", m->path);
1369
} else if (m->is_root) {
1402
} else if (m->is_root)
1376
1405
if (m->wd <= 0 && j->inotify_fd >= 0) {
1395
1424
if (dirent_is_file_with_suffix(de, ".journal") ||
1396
1425
dirent_is_file_with_suffix(de, ".journal~")) {
1397
1426
r = add_file(j, m->path, de->d_name);
1399
log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r));
1428
log_debug("Failed to add file %s/%s: %s",
1429
m->path, de->d_name, strerror(-r));
1430
r = set_put_error(j, r);
1403
1437
check_network(j, dirfd(d));
1410
1442
static int add_root_directory(sd_journal *j, const char *p) {
1443
_cleanup_closedir_ DIR *d = NULL;
1477
1503
if (dirent_is_file_with_suffix(de, ".journal") ||
1478
1504
dirent_is_file_with_suffix(de, ".journal~")) {
1479
1505
r = add_file(j, m->path, de->d_name);
1481
log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r));
1507
log_debug("Failed to add file %s/%s: %s",
1508
m->path, de->d_name, strerror(-r));
1509
r = set_put_error(j, r);
1483
1513
} else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) &&
1484
1514
sd_id128_from_string(de->d_name, &id) >= 0) {
1531
1559
/* We ignore most errors here, since the idea is to only open
1532
1560
* what's actually accessible, and ignore the rest. */
1534
NULSTR_FOREACH(p, search_paths)
1535
add_root_directory(j, p);
1562
NULSTR_FOREACH(p, search_paths) {
1563
r = add_root_directory(j, p);
1564
if (r < 0 && r != -ENOENT) {
1565
r = set_put_error(j, r);
1570
1604
j->path = strdup(path);
1577
1609
j->files = hashmap_new(string_hash_func, string_compare_func);
1584
1610
j->directories_by_path = hashmap_new(string_hash_func, string_compare_func);
1585
if (!j->directories_by_path) {
1586
hashmap_free(j->files);
1592
1611
j->mmap = mmap_cache_new();
1594
hashmap_free(j->files);
1595
hashmap_free(j->directories_by_path);
1612
if (!j->files || !j->directories_by_path || !j->mmap)
1618
sd_journal_close(j);
1604
1622
_public_ int sd_journal_open(sd_journal **ret, int flags) {
1989
2010
return j->inotify_fd;
2013
_public_ int sd_journal_get_events(sd_journal *j) {
2019
fd = sd_journal_get_fd(j);
2026
_public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) {
2034
fd = sd_journal_get_fd(j);
2038
if (!j->on_network) {
2039
*timeout_usec = (uint64_t) -1;
2043
/* If we are on the network we need to regularly check for
2044
* changes manually */
2046
*timeout_usec = j->last_process_usec + JOURNAL_FILES_RECHECK_USEC;
1992
2050
static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
2010
2068
if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
2011
2069
r = add_file(j, d->path, e->name);
2013
log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r));
2071
log_debug("Failed to add file %s/%s: %s",
2072
d->path, e->name, strerror(-r));
2073
set_put_error(j, r);
2015
2076
} else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) {
2119
2183
return determine_change(j);
2122
if (j->on_network) {
2123
/* If we are on the network we need to regularly check
2124
* for changes manually */
2126
if (timeout_usec == (uint64_t) -1 || timeout_usec > JOURNAL_FILES_RECHECK_USEC)
2127
timeout_usec = JOURNAL_FILES_RECHECK_USEC;
2186
r = sd_journal_get_timeout(j, &t);
2190
if (t != (uint64_t) -1) {
2193
n = now(CLOCK_MONOTONIC);
2194
t = t > n ? t - n : 0;
2196
if (timeout_usec == (uint64_t) -1 || timeout_usec > t)
2461
2531
return -EINVAL;
2463
return catalog_get(id, ret);
2533
return catalog_get(CATALOG_DATABASE, id, ret);
2466
2536
_public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) {