#include <gmodule.h>
#include <limits.h>
#include <regex.h>
+#include <time.h>
#include "log.h"
#include "cleanup.h"
int level;
};
+struct cleanup_history {
+ enum cleanup_running_type type;
+ int level;
+ time_t tm;
+};
+
#define REMOVE(path) { \
if(remove(path) != 0) { \
_E("Failed to remove(%s): %d", path, errno); \
} \
}
+#define CLEANUP_INTERVAL_SEC (10 * 60)
+
static pthread_mutex_t mutex_cancel;
static pthread_mutex_t mutex_lock;
static pthread_t cleanup_th = 0;
static GList *request_queue = NULL;
static int cleanup_canceled = 0;
+static GSList *history = NULL;
static int is_cleanup_canceled()
{
return ret;
}
+static bool check_history(enum cleanup_running_type type, int level)
+{
+ time_t interval;
+ GSList *list = NULL;
+ struct cleanup_history *item = NULL;
+ bool ret = true;
+
+ /*
+ * When requesting the same or lower level of cleanup again
+ (warning->warning, full->critical or critical->warning),
+ do it at a specific interval (10 minutes).
+
+ * When requesting the higher level of cleanup again
+ (warning->critical or critical->full),
+ do it immediately.
+ */
+ for (list = history; list != NULL; list = g_slist_next(list)) {
+ item = list->data;
+ if (item->type == type) {
+ if (item->level > level)
+ break;
+
+ interval = time(NULL) - item->tm;
+ if (interval < CLEANUP_INTERVAL_SEC) {
+ //_D("Cleanup(type:%d, level:%d) is already requested before %u seconds.", type, level, (unsigned int)interval);
+ ret = false;
+ }
+
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static void update_history(enum cleanup_running_type type, int level)
+{
+ GSList *list = NULL;
+ struct cleanup_history *item = NULL, *find = NULL;
+
+ for (list = history; list != NULL; list = g_slist_next(list)) {
+ item = list->data;
+ if (item->type == type) {
+ find = item;
+ break;
+ }
+ }
+
+ if (find == NULL) {
+ find = malloc(sizeof(struct cleanup_history));
+ if (!find) {
+ _E("Failed to call malloc function.");
+ return ;
+ }
+ find->type = type;
+ find->level = level;
+ find->tm = time(NULL);
+ history = g_slist_prepend(history, find);
+ } else {
+ find->level = level;
+ find->tm = time(NULL);
+ }
+}
+
static int add_request_queue(int type, int level)
{
int ret = 0;
void cleanup_storage(enum tzplatform_variable path_id, int level)
{
bool bth = (get_request_queue() == NULL);
- int type = CLEANUP_TYPE_NONE;
+ enum cleanup_running_type type = CLEANUP_TYPE_NONE;
int ret;
if (path_id == TZ_SYS_OPT)
return ;
}
+ if (!check_history(type, level))
+ return ;
+
if (add_request_queue(type, level) != 0) {
_E("Failed to add request.");
return ;
}
//_D("Add cleanup request.(type:%d, level:%d)", type, level);
+ update_history(type, level);
+
if (bth) {
ret = pthread_create(&cleanup_th, NULL, cleanup_storage_start, NULL);
if (ret != 0)
request_queue = NULL;
pthread_mutex_unlock(&mutex_lock);
+ if (history)
+ g_slist_free_full(history, free);
+ history = NULL;
+
if (cleanup_th) {
_D("Cancel cleanup thread %d.", (int)cleanup_th);
cleanup_cancel();