static int jlog_logio_cleanse(noit_log_stream_t ls) { jlog_asynch_ctx *actx; jlog_ctx *log; DIR *d; struct dirent *de, *entry; int cnt = 0; char path[PATH_MAX], current_log[9]; int size = 0; actx = (jlog_asynch_ctx *)ls->op_ctx; if(!actx) return -1; log = actx->log; if(!log) return -1; if(jlog_lspath_to_fspath(ls, path, sizeof(path), NULL) <= 0) return -1; d = opendir(path); snprintf(current_log, sizeof(current_log), "%08x", log->current_log); #ifdef _PC_NAME_MAX size = pathconf(path, _PC_NAME_MAX); if(size < 0) size = PATH_MAX + 128; #endif size = MIN(size, PATH_MAX + 128); de = alloca(size); if(!d) return -1; while(portable_readdir_r(d, de, &entry) == 0 && entry != NULL) { u_int32_t logid; /* the current log file isn't a deletion target. period. */ if(is_datafile(entry->d_name, &logid) && strcmp(current_log, entry->d_name)) { int rv; struct stat st; char fullfile[PATH_MAX]; char fullidx[PATH_MAX]; snprintf(fullfile, sizeof(fullfile), "%s/%s", path, entry->d_name); snprintf(fullidx, sizeof(fullidx), "%s/%s" INDEX_EXT, path, entry->d_name); /* coverity[fs_check_call] */ while((rv = stat(fullfile, &st)) != 0 && errno == EINTR); if(rv == 0) { int readers; readers = __jlog_pending_readers(log, logid); if(readers == 0) { /* coverity[toctou] */ unlink(fullfile); unlink(fullidx); } } } } closedir(d); return cnt; }
static int __jlog_set_checkpoint(jlog_ctx *ctx, const char *s, const jlog_id *id) { jlog_file *f; int rv = -1; jlog_id old_id; u_int32_t log; if(ctx->subscriber_name && !strcmp(ctx->subscriber_name, s)) { if(!ctx->checkpoint) { ctx->checkpoint = __jlog_open_named_checkpoint(ctx, s, 0); } f = ctx->checkpoint; } else f = __jlog_open_named_checkpoint(ctx, s, 0); if(!f) return -1; if (!jlog_file_lock(f)) goto failset; if (jlog_file_size(f) == 0) { /* we're setting it for the first time, no segments were pending on it */ old_id.log = id->log; } else { if (!jlog_file_pread(f, &old_id, sizeof(old_id), 0)) goto failset; } if (!jlog_file_pwrite(f, id, sizeof(*id), 0)) goto failset; if (ctx->safety == JLOG_SAFE) { jlog_file_sync(f); } jlog_file_unlock(f); rv = 0; for (log = old_id.log; log < id->log; log++) { if (__jlog_pending_readers(ctx, log) == 0) { __jlog_unlink_datafile(ctx, log); } } failset: if (f && f != ctx->checkpoint) jlog_file_close(f); return rv; }
static int process_jlog(const char *file, const char *sub) { jlog_ctx *log = jlog_new(file); if (add_subscriber) { if (jlog_ctx_add_subscriber(log, add_subscriber, JLOG_BEGIN)) { fprintf(stderr, "Could not add subscriber '%s': %s\n", add_subscriber, jlog_ctx_err_string(log)); } else { OUT("Added subscriber '%s'\n", add_subscriber); } } if (remove_subscriber) { if (jlog_ctx_remove_subscriber(log, remove_subscriber) <= 0) { fprintf(stderr, "Could not erase subscriber '%s': %s\n", remove_subscriber, jlog_ctx_err_string(log)); } else { OUT("Erased subscriber '%s'\n", remove_subscriber); } } if (!sub) { if (jlog_ctx_open_writer(log)) { fprintf(stderr, "error opening '%s'\n", file); return 0; } } else { if (jlog_ctx_open_reader(log, sub)) { fprintf(stderr, "error opening '%s'\n", file); return 0; } } if (show_progress) { char buff[20], buff2[20], buff3[20]; jlog_id id, id2, id3; jlog_get_checkpoint(log, sub, &id); if (jlog_ctx_last_log_id(log, &id3)) { fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log)); fprintf(stderr, "error calling jlog_ctx_last_log_id\n"); } jlog_snprint_logid(buff, sizeof(buff), &id); jlog_snprint_logid(buff3, sizeof(buff3), &id3); OUT("--------------------\n" " Perspective of the '%s' subscriber\n" " current checkpoint: %s\n" " Last write: %s\n", sub, buff, buff3); if (jlog_ctx_read_interval(log, &id, &id2) < 0) { fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log)); } jlog_snprint_logid(buff, sizeof(buff), &id); jlog_snprint_logid(buff2, sizeof(buff2), &id2); OUT(" next interval: [%s, %s]\n" "--------------------\n\n", buff, buff2); } if (show_subscribers) { char **list; int i; jlog_ctx_list_subscribers(log, &list); for (i = 0; list[i]; i++) { char buff[20]; jlog_id id; jlog_get_checkpoint(log, list[i], &id); jlog_snprint_logid(buff, sizeof(buff), &id); OUT("\t%32s @ %s\n", list[i], buff); } jlog_ctx_list_subscribers_dispose(log, list); } if (show_files) { struct dirent *de; DIR *dir; dir = opendir(file); if (!dir) { fprintf(stderr, "error opening '%s'\n", file); return 0; } while ((de = readdir(dir)) != NULL) { uint32_t logid; if (is_datafile(de->d_name, &logid)) { char fullfile[MAXPATHLEN]; char fullidx[MAXPATHLEN]; struct stat sb; int readers; snprintf(fullfile, sizeof(fullfile), "%s/%s", file, de->d_name); snprintf(fullidx, sizeof(fullidx), "%s/%s" INDEX_EXT, file, de->d_name); if (stat(fullfile, &sb)) { OUT("\t%8s [error stat(2)ing file: %s\n", de->d_name, strerror(errno)); } else { readers = __jlog_pending_readers(log, logid); OUT("\t%8s [%ju bytes] %d pending readers\n", de->d_name, sb.st_size, readers); if (show_index_info) { if (stat(fullidx, &sb)) { OUT("\t\t idx: none\n"); } else { uint32_t marker; int closed; if (jlog_idx_details(log, logid, &marker, &closed)) { OUT("\t\t idx: error\n"); } else { OUT("\t\t idx: %u messages (%08x), %s\n", marker, marker, closed ? "closed" : "open"); } } } if (analyze_datafiles) { analyze_datafile(log, logid); } if (readers == 0 && cleanup) { unlink(fullfile); unlink(fullidx); } } } } closedir(dir); } jlog_ctx_close(log); }