Try other storage areas if we fail to create event dir on the assigned area.

This commit is contained in:
Isaac Connor
2020-11-27 13:28:38 -05:00
parent a6245d9e90
commit 95cbc053fc
2 changed files with 127 additions and 74 deletions

View File

@@ -78,8 +78,6 @@ Event::Event(
start_time = now;
}
Storage * storage = monitor->getStorage();
scheme = storage->Scheme();
unsigned int state_id = 0;
zmDbRow dbrow;
@@ -87,8 +85,58 @@ Event::Event(
state_id = atoi(dbrow[0]);
}
Storage * storage = monitor->getStorage();
if ( !SetPath(storage) ) {
// Try another
Warning("Failed creating event dir at %s", storage->Path());
std::string sql = stringtf("SELECT `Id` FROM `Storage` WHERE `Id` != %u", storage->Id());
if ( monitor->ServerId() )
sql += stringtf(" AND ServerId=%u", monitor->ServerId());
Debug(1, "%s", sql.c_str());
storage = nullptr;
MYSQL_RES *result = zmDbFetch(sql.c_str());
if ( result ) {
for ( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) {
storage = new Storage(atoi(dbrow[0]));
if ( SetPath(storage) )
break;
delete storage;
storage = nullptr;
} // end foreach row of Storage
mysql_free_result(result);
result = nullptr;
}
if ( !storage ) {
Info("No valid local storage area found. Trying all other areas.");
// Try remote
std::string sql = "SELECT `Id` FROM `Storage` WHERE ServerId IS NULL";
if ( monitor->ServerId() )
sql += stringtf(" OR ServerId != %u", monitor->ServerId());
MYSQL_RES *result = zmDbFetch(sql.c_str());
if ( result ) {
for ( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) {
storage = new Storage(atoi(dbrow[0]));
if ( SetPath(storage) )
break;
delete storage;
storage = nullptr;
} // end foreach row of Storage
mysql_free_result(result);
result = nullptr;
}
}
if ( !storage ) {
storage = new Storage();
Warning("Failed to find a storage area to save events.");
}
}
Debug(1, "Using storage area at %s", path.c_str());
char sql[ZM_SQL_MED_BUFSIZ];
struct tm *stime = localtime(&start_time.tv_sec);
snprintf(sql, sizeof(sql), "INSERT INTO Events "
"( MonitorId, StorageId, Name, StartDateTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs, Scheme )"
" VALUES ( %u, %u, 'New Event', from_unixtime( %ld ), %u, %u, '%s', '%s', %u, %d, %d, '%s', %d, '%s' )",
@@ -116,7 +164,7 @@ Event::Event(
db_mutex.unlock();
if ( untimedEvent ) {
Warning("Event %d has zero time, setting to current", id);
Warning("Event %" PRIu64 " has zero time, setting to current", id);
}
end_time.tv_sec = 0;
frames = 0;
@@ -124,77 +172,7 @@ Event::Event(
tot_score = 0;
max_score = 0;
alarm_frame_written = false;
std::string id_file;
path = stringtf("%s/%d", storage->Path(), monitor->Id());
// Try to make the Monitor Dir. Normally this would exist, but in odd cases might not.
if ( mkdir(path.c_str(), 0755) ) {
if ( errno != EEXIST )
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
}
if ( storage->Scheme() == Storage::DEEP ) {
int dt_parts[6];
dt_parts[0] = stime->tm_year-100;
dt_parts[1] = stime->tm_mon+1;
dt_parts[2] = stime->tm_mday;
dt_parts[3] = stime->tm_hour;
dt_parts[4] = stime->tm_min;
dt_parts[5] = stime->tm_sec;
std::string date_path;
std::string time_path;
for ( unsigned int i = 0; i < sizeof(dt_parts)/sizeof(*dt_parts); i++ ) {
path += stringtf("/%02d", dt_parts[i]);
if ( mkdir(path.c_str(), 0755) ) {
// FIXME This should not be fatal. Should probably move to a different storage area.
if ( errno != EEXIST )
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
}
if ( i == 2 )
date_path = path;
}
time_path = stringtf("%02d/%02d/%02d", stime->tm_hour, stime->tm_min, stime->tm_sec);
// Create event id symlink
id_file = stringtf("%s/.%" PRIu64, date_path.c_str(), id);
if ( symlink(time_path.c_str(), id_file.c_str()) < 0 )
Error("Can't symlink %s -> %s: %s", id_file.c_str(), time_path.c_str(), strerror(errno));
} else if ( storage->Scheme() == Storage::MEDIUM ) {
path += stringtf("/%04d-%02d-%02d",
stime->tm_year+1900, stime->tm_mon+1, stime->tm_mday
);
if ( mkdir(path.c_str(), 0755) ) {
if ( errno != EEXIST )
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
}
path += stringtf("/%" PRIu64, id);
if ( mkdir(path.c_str(), 0755) ) {
if ( errno != EEXIST )
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
}
} else {
path += stringtf("/%" PRIu64, id);
if ( mkdir(path.c_str(), 0755) ) {
if ( errno != EEXIST )
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
}
// Create empty id tag file
id_file = stringtf("%s/.%" PRIu64, path.c_str(), id);
if ( FILE *id_fp = fopen(id_file.c_str(), "w") ) {
fclose(id_fp);
} else {
Error("Can't fopen %s: %s", id_file.c_str(), strerror(errno));
}
} // deep storage or not
last_db_frame = 0;
video_name = "";
snapshot_file = path + "/snapshot.jpg";
@@ -739,3 +717,77 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
end_time = timestamp;
} // end void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *alarm_image)
bool Event::SetPath(Storage *storage) {
scheme = storage->Scheme();
path = stringtf("%s/%d", storage->Path(), monitor->Id());
// Try to make the Monitor Dir. Normally this would exist, but in odd cases might not.
if ( mkdir(path.c_str(), 0755) and ( errno != EEXIST ) ) {
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
return false;
}
struct tm *stime = localtime(&start_time.tv_sec);
if ( scheme == Storage::DEEP ) {
int dt_parts[6];
dt_parts[0] = stime->tm_year-100;
dt_parts[1] = stime->tm_mon+1;
dt_parts[2] = stime->tm_mday;
dt_parts[3] = stime->tm_hour;
dt_parts[4] = stime->tm_min;
dt_parts[5] = stime->tm_sec;
std::string date_path;
std::string time_path;
for ( unsigned int i = 0; i < sizeof(dt_parts)/sizeof(*dt_parts); i++ ) {
path += stringtf("/%02d", dt_parts[i]);
if ( mkdir(path.c_str(), 0755) and ( errno != EEXIST ) ) {
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
return false;
}
if ( i == 2 )
date_path = path;
}
time_path = stringtf("%02d/%02d/%02d", stime->tm_hour, stime->tm_min, stime->tm_sec);
// Create event id symlink
std::string id_file = stringtf("%s/.%" PRIu64, date_path.c_str(), id);
if ( symlink(time_path.c_str(), id_file.c_str()) < 0 ) {
Error("Can't symlink %s -> %s: %s", id_file.c_str(), time_path.c_str(), strerror(errno));
return false;
}
} else if ( scheme == Storage::MEDIUM ) {
path += stringtf("/%04d-%02d-%02d",
stime->tm_year+1900, stime->tm_mon+1, stime->tm_mday
);
if ( mkdir(path.c_str(), 0755) and ( errno != EEXIST ) ) {
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
return false;
}
path += stringtf("/%" PRIu64, id);
if ( mkdir(path.c_str(), 0755) and ( errno != EEXIST ) ) {
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
return false;
}
} else {
path += stringtf("/%" PRIu64, id);
if ( mkdir(path.c_str(), 0755) and ( errno != EEXIST ) ) {
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
return false;
}
// Create empty id tag file
std::string id_file = stringtf("%s/.%" PRIu64, path.c_str(), id);
if ( FILE *id_fp = fopen(id_file.c_str(), "w") ) {
fclose(id_fp);
} else {
Error("Can't fopen %s: %s", id_file.c_str(), strerror(errno));
return false;
}
} // deep storage or not
return true;
} // end bool Event::SetPath

View File

@@ -133,6 +133,7 @@ class Event {
void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps );
void WriteDbFrames();
void UpdateFramesDelta(double offset);
bool SetPath(Storage *storage);
public:
static const char *getSubPath( struct tm *time ) {