If llog_reader tries to read an empty log file (0 bytes) it does not
detect this as an error, since it tries to read 0 bytes from the llog
and then tries to parse an empty llog header.
Return an error if the llog file is smaller than struct llog_log_hdr.
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Change-Id: Ife482eb6d73b35f09cc70ca4b79bfd7b053ebb35
Reviewed-on: http://review.whamcloud.com/17627
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Frank Zago <fzago@cray.com>
Reviewed-by: Olaf Faaland-LLNL <faaland1@llnl.gov>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
#include <fcntl.h>
#include <sys/vfs.h>
#include <linux/magic.h>
#include <fcntl.h>
#include <sys/vfs.h>
#include <linux/magic.h>
#include <time.h>
#include <lnet/nidstr.h>
#include <lustre/lustre_idl.h>
#include <time.h>
#include <lnet/nidstr.h>
#include <lustre/lustre_idl.h>
struct llog_rec_hdr ***recs,
int *recs_number)
{
struct llog_rec_hdr ***recs,
int *recs_number)
{
- int rc = 0, recs_num, rd;
- off_t file_size;
+ int rc = 0, recs_num, rd = 0;
+ long long file_size;
struct stat st;
char *file_buf = NULL, *recs_buf = NULL;
struct llog_rec_hdr **recs_pr = NULL;
struct stat st;
char *file_buf = NULL, *recs_buf = NULL;
struct llog_rec_hdr **recs_pr = NULL;
llapi_error(LLAPI_MSG_ERROR, rc, "Got file stat error.");
goto out;
}
llapi_error(LLAPI_MSG_ERROR, rc, "Got file stat error.");
goto out;
}
- if (file_size == 0) {
- rc = -1;
- llapi_error(LLAPI_MSG_ERROR, rc, "File is empty.");
+ if (file_size < sizeof(**llog)) {
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "File too small for llog header: "
+ "need %zd, size %lld\n",
+ sizeof(**llog), file_size);
+ rc = -EIO;
}
*llog = (struct llog_log_hdr *)file_buf;
}
*llog = (struct llog_log_hdr *)file_buf;
- rd = read(fd, file_buf, file_size);
+ do {
+ rc = read(fd, file_buf + rd, file_size - rd);
+ if (rc > 0)
+ rd += rc;
+ } while (rc > 0 && rd < file_size);
+
- rc = -EIO; /*FIXME*/
- llapi_error(LLAPI_MSG_ERROR, rc, "Read file error.");
+ rc = rc < 0 ? -errno : -EIO;
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "Error reading llog header: need %zd, got %d",
+ sizeof(**llog), rd);
goto clear_file_buf;
}
/* the llog header not countable here.*/
recs_num = le32_to_cpu((*llog)->llh_count) - 1;
goto clear_file_buf;
}
/* the llog header not countable here.*/
recs_num = le32_to_cpu((*llog)->llh_count) - 1;
- recs_buf = malloc(recs_num * sizeof(struct llog_rec_hdr *));
+ recs_buf = malloc(recs_num * sizeof(**recs_pr));
if (recs_buf == NULL) {
rc = -ENOMEM;
if (recs_buf == NULL) {
rc = -ENOMEM;
- llapi_error(LLAPI_MSG_ERROR, rc, "Memory Alloc for recs_buf.");
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "Error allocating %zd bytes for recs_buf",
+ recs_num * sizeof(**recs_pr));
goto clear_file_buf;
}
recs_pr = (struct llog_rec_hdr **)recs_buf;
goto clear_file_buf;
}
recs_pr = (struct llog_rec_hdr **)recs_buf;
int idx;
unsigned long offset;
int idx;
unsigned long offset;
- if (ptr + sizeof(struct llog_rec_hdr) >
- file_buf + file_size) {
+ if (ptr + sizeof(**recs_pr) > file_buf + file_size) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc,
"The log is corrupt (too big at %d)", i);
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc,
"The log is corrupt (too big at %d)", i);