mirror of https://github.com/ArduPilot/ardupilot
DataFlash: avoid stat of current log file
this avoids getting invalid data base for stat() for the current log file. It also only gives up writing to a log file if writes fail for 2 seconds. This avoids a temporary write failure causing the log to be closed (that can happen on ChibiOS with directory listing while writing)
This commit is contained in:
parent
8a2f1fdb3d
commit
777b4c8cfe
|
@ -631,6 +631,15 @@ uint32_t DataFlash_File::_get_log_size(const uint16_t log_num) const
|
||||||
if (fname == nullptr) {
|
if (fname == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (_write_fd != -1 && write_fd_semaphore->take_nonblocking()) {
|
||||||
|
if (_write_filename != nullptr && strcmp(_write_filename, fname) == 0) {
|
||||||
|
// it is the file we are currently writing
|
||||||
|
free(fname);
|
||||||
|
write_fd_semaphore->give();
|
||||||
|
return _write_offset;
|
||||||
|
}
|
||||||
|
write_fd_semaphore->give();
|
||||||
|
}
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (::stat(fname, &st) != 0) {
|
if (::stat(fname, &st) != 0) {
|
||||||
printf("Unable to fetch Log File Size: %s\n", strerror(errno));
|
printf("Unable to fetch Log File Size: %s\n", strerror(errno));
|
||||||
|
@ -647,6 +656,15 @@ uint32_t DataFlash_File::_get_log_time(const uint16_t log_num) const
|
||||||
if (fname == nullptr) {
|
if (fname == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (_write_fd != -1 && write_fd_semaphore->take_nonblocking()) {
|
||||||
|
if (_write_filename != nullptr && strcmp(_write_filename, fname) == 0) {
|
||||||
|
// it is the file we are currently writing
|
||||||
|
free(fname);
|
||||||
|
write_fd_semaphore->give();
|
||||||
|
return hal.util->get_system_clock_ms() / 1000U;
|
||||||
|
}
|
||||||
|
write_fd_semaphore->give();
|
||||||
|
}
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (::stat(fname, &st) != 0) {
|
if (::stat(fname, &st) != 0) {
|
||||||
free(fname);
|
free(fname);
|
||||||
|
@ -882,20 +900,25 @@ uint16_t DataFlash_File::start_new_log(void)
|
||||||
if (log_num > MAX_LOG_FILES) {
|
if (log_num > MAX_LOG_FILES) {
|
||||||
log_num = 1;
|
log_num = 1;
|
||||||
}
|
}
|
||||||
char *fname = _log_file_name(log_num);
|
|
||||||
if (fname == nullptr) {
|
|
||||||
_open_error = true;
|
|
||||||
return 0xFFFF;
|
|
||||||
}
|
|
||||||
if (!write_fd_semaphore->take(1)) {
|
if (!write_fd_semaphore->take(1)) {
|
||||||
_open_error = true;
|
_open_error = true;
|
||||||
return 0xFFFF;
|
return 0xFFFF;
|
||||||
}
|
}
|
||||||
|
if (_write_filename) {
|
||||||
|
free(_write_filename);
|
||||||
|
_write_filename = nullptr;
|
||||||
|
}
|
||||||
|
_write_filename = _log_file_name(log_num);
|
||||||
|
if (_write_filename == nullptr) {
|
||||||
|
_open_error = true;
|
||||||
|
write_fd_semaphore->give();
|
||||||
|
return 0xFFFF;
|
||||||
|
}
|
||||||
#if HAL_OS_POSIX_IO
|
#if HAL_OS_POSIX_IO
|
||||||
_write_fd = ::open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666);
|
_write_fd = ::open(_write_filename, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666);
|
||||||
#else
|
#else
|
||||||
//TODO add support for mode flags
|
//TODO add support for mode flags
|
||||||
_write_fd = ::open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC);
|
_write_fd = ::open(_write_filename, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
_cached_oldest_log = 0;
|
_cached_oldest_log = 0;
|
||||||
|
|
||||||
|
@ -905,19 +928,18 @@ uint16_t DataFlash_File::start_new_log(void)
|
||||||
write_fd_semaphore->give();
|
write_fd_semaphore->give();
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
::printf("Log open fail for %s - %s\n",
|
::printf("Log open fail for %s - %s\n",
|
||||||
fname, strerror(saved_errno));
|
_write_filename, strerror(saved_errno));
|
||||||
hal.console->printf("Log open fail for %s - %s\n",
|
hal.console->printf("Log open fail for %s - %s\n",
|
||||||
fname, strerror(saved_errno));
|
_write_filename, strerror(saved_errno));
|
||||||
free(fname);
|
|
||||||
return 0xFFFF;
|
return 0xFFFF;
|
||||||
}
|
}
|
||||||
free(fname);
|
_last_write_ms = AP_HAL::millis();
|
||||||
_write_offset = 0;
|
_write_offset = 0;
|
||||||
_writebuf.clear();
|
_writebuf.clear();
|
||||||
write_fd_semaphore->give();
|
write_fd_semaphore->give();
|
||||||
|
|
||||||
// now update lastlog.txt with the new log number
|
// now update lastlog.txt with the new log number
|
||||||
fname = _lastlog_file_name();
|
char *fname = _lastlog_file_name();
|
||||||
|
|
||||||
// we avoid fopen()/fprintf() here as it is not available on as many
|
// we avoid fopen()/fprintf() here as it is not available on as many
|
||||||
// systems as open/write
|
// systems as open/write
|
||||||
|
@ -1038,14 +1060,20 @@ void DataFlash_File::_io_timer(void)
|
||||||
ssize_t nwritten = ::write(_write_fd, head, nbytes);
|
ssize_t nwritten = ::write(_write_fd, head, nbytes);
|
||||||
last_io_operation = "";
|
last_io_operation = "";
|
||||||
if (nwritten <= 0) {
|
if (nwritten <= 0) {
|
||||||
hal.util->perf_count(_perf_errors);
|
if (tnow - _last_write_ms > 2000) {
|
||||||
last_io_operation = "close";
|
// if we can't write for 2 seconds we give up and close
|
||||||
close(_write_fd);
|
// the file. This allows us to cope with temporary write
|
||||||
last_io_operation = "";
|
// failures caused by directory listing
|
||||||
_write_fd = -1;
|
hal.util->perf_count(_perf_errors);
|
||||||
_initialised = false;
|
last_io_operation = "close";
|
||||||
printf("Failed to write to File: %s\n", strerror(errno));
|
close(_write_fd);
|
||||||
|
last_io_operation = "";
|
||||||
|
_write_fd = -1;
|
||||||
|
_initialised = false;
|
||||||
|
printf("Failed to write to File: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_last_write_ms = tnow;
|
||||||
_write_offset += nwritten;
|
_write_offset += nwritten;
|
||||||
_writebuf.advance(nwritten);
|
_writebuf.advance(nwritten);
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -65,6 +65,9 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _write_fd;
|
int _write_fd;
|
||||||
|
char *_write_filename;
|
||||||
|
uint32_t _last_write_ms;
|
||||||
|
|
||||||
int _read_fd;
|
int _read_fd;
|
||||||
uint16_t _read_fd_log_num;
|
uint16_t _read_fd_log_num;
|
||||||
uint32_t _read_offset;
|
uint32_t _read_offset;
|
||||||
|
|
Loading…
Reference in New Issue