Skip to content

Commit

Permalink
replay-log: add validations for corrupt log entries
Browse files Browse the repository at this point in the history
Check for all zeros entry and for non zero padded entry
and report log offset of corrupted log entry.

Also report log offsets with -v and -vv debug prints.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
  • Loading branch information
amir73il committed Aug 31, 2017
1 parent 7be311a commit bb946de
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
55 changes: 46 additions & 9 deletions src/log-writes/log-writes.c
Expand Up @@ -117,6 +117,26 @@ int log_discard(struct log *log, struct log_write_entry *entry)
return 0;
}

/*
* @entry: entry to be replayed.
*
* @return: 1 if the entry is sane, 0 if it is invalid.
*
* Check if this is a sane log entry.
*/
int log_entry_valid(struct log_write_entry *entry)
{
u64 flags = le64_to_cpu(entry->flags);

/* Suspect all zeroes entry */
if (!flags && !entry->nr_sectors)
return 0;
/* Suspect non zero padded entry */
if (flags != LOG_MARK_FLAG && entry->data[0] != 0)
return 0;
return 1;
}

/*
* @log: the log we are replaying.
* @entry: where we put the entry.
Expand All @@ -141,11 +161,16 @@ int log_replay_next_entry(struct log *log, struct log_write_entry *entry,
if (log->cur_entry >= log->nr_entries)
return 1;

offset = lseek(log->logfd, 0, SEEK_CUR);
ret = read(log->logfd, entry, read_size);
if (ret != read_size) {
fprintf(stderr, "Error reading entry: %d\n", errno);
return -1;
}
if (!log_entry_valid(entry)) {
fprintf(stderr, "Malformed entry @%llu\n", offset / log->sectorsize);
return -1;
}
log->cur_entry++;

size = le64_to_cpu(entry->nr_sectors) * log->sectorsize;
Expand All @@ -158,12 +183,13 @@ int log_replay_next_entry(struct log *log, struct log_write_entry *entry,
}
}

if (log_writes_verbose)
printf("replaying %d: sector %llu, size %llu, flags %llu\n",
(int)log->cur_entry - 1,
if (log_writes_verbose) {
printf("replaying %d@%llu: sector %llu, size %llu, flags %llu\n",
(int)log->cur_entry - 1, offset / log->sectorsize,
(unsigned long long)le64_to_cpu(entry->sector),
(unsigned long long)size,
(unsigned long long)le64_to_cpu(entry->flags));
}
if (!size)
return 0;

Expand Down Expand Up @@ -221,15 +247,20 @@ int log_seek_entry(struct log *log, u64 entry_num)
ssize_t ret;
off_t seek_size;
u64 flags;
off_t offset = lseek(log->logfd, 0, SEEK_CUR);

ret = read(log->logfd, &entry, sizeof(entry));
if (ret != sizeof(entry)) {
fprintf(stderr, "Error reading entry: %d\n", errno);
return -1;
}
if (!log_entry_valid(&entry)) {
fprintf(stderr, "Malformed entry @%llu\n", offset / log->sectorsize);
return -1;
}
if (log_writes_verbose > 1)
printf("seek entry %d: %llu, size %llu, flags %llu\n",
(int)i,
printf("seek entry %d@%llu: %llu, size %llu, flags %llu\n",
(int)i, offset / log->sectorsize,
(unsigned long long)le64_to_cpu(entry.sector),
(unsigned long long)le64_to_cpu(entry.nr_sectors),
(unsigned long long)le64_to_cpu(entry.flags));
Expand Down Expand Up @@ -264,17 +295,23 @@ int log_seek_next_entry(struct log *log, struct log_write_entry *entry,
{
size_t read_size = read_data ? log->sectorsize :
sizeof(struct log_write_entry);
off_t offset;
u64 flags;
ssize_t ret;

if (log->cur_entry >= log->nr_entries)
return 1;

offset = lseek(log->logfd, 0, SEEK_CUR);
ret = read(log->logfd, entry, read_size);
if (ret != read_size) {
fprintf(stderr, "Error reading entry: %d\n", errno);
return -1;
}
if (!log_entry_valid(entry)) {
fprintf(stderr, "Malformed entry @%llu\n", offset / log->sectorsize);
return -1;
}
log->cur_entry++;

if (read_size < log->sectorsize) {
Expand All @@ -286,14 +323,14 @@ int log_seek_next_entry(struct log *log, struct log_write_entry *entry,
}
}
if (log_writes_verbose > 1)
printf("seek entry %d: %llu, size %llu, flags %llu\n",
(int)log->cur_entry - 1,
printf("seek entry %d@%llu: %llu, size %llu, flags %llu\n",
(int)log->cur_entry - 1, offset / log->sectorsize,
(unsigned long long)le64_to_cpu(entry->sector),
(unsigned long long)le64_to_cpu(entry->nr_sectors),
(unsigned long long)le64_to_cpu(entry->flags));

flags = le32_to_cpu(entry->flags);
read_size = le32_to_cpu(entry->nr_sectors) * log->sectorsize;
flags = le64_to_cpu(entry->flags);
read_size = le64_to_cpu(entry->nr_sectors) * log->sectorsize;
if (!read_size || (flags & LOG_DISCARD_FLAG))
return 0;

Expand Down
1 change: 1 addition & 0 deletions src/log-writes/log-writes.h
Expand Up @@ -43,6 +43,7 @@ struct log_write_entry {
__le64 nr_sectors;
__le64 flags;
__le64 data_len;
char data[1];
};

#define LOG_IGNORE_DISCARD (1 << 0)
Expand Down
8 changes: 5 additions & 3 deletions src/log-writes/replay-log.c
Expand Up @@ -69,7 +69,7 @@ static int should_stop(struct log_write_entry *entry, u64 stop_flags,
{
u64 flags = le64_to_cpu(entry->flags);
int check_mark = (stop_flags & LOG_MARK_FLAG);
char *buf = (char *)(entry + 1);
char *buf = entry->data;

if (flags & stop_flags) {
if (!check_mark)
Expand Down Expand Up @@ -284,8 +284,10 @@ int main(int argc, char **argv)
num_entries++;
if ((run_limit && num_entries == run_limit) ||
should_stop(entry, stop_flags, end_mark)) {
printf("%llu\n",
(unsigned long long)log->cur_entry - 1);
off_t offset = lseek(log->logfd, 0, SEEK_CUR);

printf("%llu@%llu\n",
(unsigned long long)log->cur_entry - 1, offset / log->sectorsize);
log_free(log);
return 0;
}
Expand Down

0 comments on commit bb946de

Please sign in to comment.