]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Remove some retention/removal restrictions
authorGlenn-1990 <g_christiaensen@msn.com>
Sun, 18 Dec 2016 15:04:44 +0000 (16:04 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 20 Dec 2016 09:00:06 +0000 (10:00 +0100)
src/dvr/dvr_autorec.c
src/dvr/dvr_config.c
src/dvr/dvr_db.c
src/dvr/dvr_timerec.c

index b4292813d8c1750c178bcab0d84ab890a2c94971..7c184157524c2d6f48c96d815aec561ecad39317 100644 (file)
@@ -1197,7 +1197,7 @@ const idclass_t dvr_autorec_entry_class = {
       .type     = PT_U32,
       .id       = "retention",
       .name     = N_("DVR log retention"),
-      .desc     = N_("Number of days to retain infomation about recording."),
+      .desc     = N_("Number of days to retain information about recording."),
       .def.i    = DVR_RET_REM_DVRCONFIG,
       .off      = offsetof(dvr_autorec_entry_t, dae_retention),
       .list     = dvr_entry_class_retention_list,
@@ -1518,11 +1518,6 @@ dvr_autorec_get_retention_days( dvr_autorec_entry_t *dae )
     if (dae->dae_retention > DVR_RET_REM_FOREVER)
       return DVR_RET_REM_FOREVER;
 
-    uint32_t removal = dvr_autorec_get_removal_days(dae);
-    /* As we need the db entry when deleting the file on disk */
-    if (removal != DVR_RET_REM_FOREVER && removal > dae->dae_retention)
-      return DVR_RET_ONREMOVE;
-
     return dae->dae_retention;
   }
   return dvr_retention_cleanup(dae->dae_config->dvr_retention_days);
index 8f693d1ad3d526e5c848a0c2a59aef61d2879850..fac2345eb7a88299c8a4ac0751f8faff30b507fc 100644 (file)
@@ -531,9 +531,6 @@ dvr_config_changed(dvr_config_t *cfg)
   dvr_config_storage_check(cfg);
   if (cfg->dvr_cleanup_threshold_free < 50)
     cfg->dvr_cleanup_threshold_free = 50; // as checking is only periodically, lower is not save
-  if (cfg->dvr_removal_days != DVR_RET_REM_FOREVER &&
-      cfg->dvr_removal_days > cfg->dvr_retention_days)
-    cfg->dvr_retention_days = DVR_RET_ONREMOVE;
   if (cfg->dvr_removal_days > DVR_RET_REM_FOREVER)
     cfg->dvr_removal_days = DVR_RET_REM_FOREVER;
   if (cfg->dvr_retention_days > DVR_RET_REM_FOREVER)
index 9944eaa424254c05a8dfc83da24e052597d10a0c..3877042f94c0cb803f3ef0f0b1289a233b5dec31 100644 (file)
@@ -46,6 +46,7 @@ static void dvr_entry_deferred_destroy(dvr_entry_t *de);
 static void dvr_entry_set_timer(dvr_entry_t *de);
 static void dvr_timer_rerecord(void *aux);
 static void dvr_timer_expire(void *aux);
+static void dvr_timer_disarm(void *aux);
 static void dvr_timer_remove_files(void *aux);
 static void dvr_entry_start_recording(dvr_entry_t *de, int clone);
 static void dvr_timer_start_recording(void *aux);
@@ -413,11 +414,6 @@ dvr_entry_get_retention_days( dvr_entry_t *de )
     if (de->de_retention > DVR_RET_REM_FOREVER)
       return DVR_RET_REM_FOREVER;
 
-    /* As we need the db entry when deleting the file on disk */
-    if (dvr_entry_get_removal_days(de) != DVR_RET_REM_FOREVER &&
-        dvr_entry_get_removal_days(de) > de->de_retention && !de->de_file_removed)
-      return DVR_RET_ONREMOVE;
-
     return de->de_retention;
   }
   return dvr_retention_cleanup(de->de_config->dvr_retention_days);
@@ -506,6 +502,26 @@ dvr_entry_retention_arm(dvr_entry_t *de, gti_callback_t *cb, time_t when)
   gtimer_arm_absn(&de->de_timer, cb, de, when);
 }
 
+/*
+ * Returns 1 if the database entry should be deleted on file removal
+ * NOTE: retention can be postponed when retention < removal
+ */
+static int
+dvr_entry_delete_retention_expired(dvr_entry_t *de)
+{
+  uint32_t retention = dvr_entry_get_retention_days(de);
+  time_t stop;
+
+  if (retention == DVR_RET_ONREMOVE)
+    return 1;
+  if (retention < DVR_RET_ONREMOVE) {
+    stop = time_t_out_of_range((int64_t)de->de_stop + retention * (int64_t)86400);
+    if (stop <= gclk())
+      return 1;
+  }
+  return 0;
+}
+
 /*
  *
  */
@@ -517,7 +533,7 @@ dvr_entry_retention_timer(dvr_entry_t *de)
   uint32_t retention = dvr_entry_get_retention_days(de);
   int save;
 
-  if ((removal > 0 || retention == 0) && removal < DVR_REM_SPACE && !de->de_file_removed) {
+  if ((removal > 0 || retention == 0) && removal < DVR_REM_SPACE && dvr_get_filesize(de, 0) > 0) {
     stop = time_t_out_of_range((int64_t)de->de_stop + removal * (int64_t)86400);
     if (stop > gclk()) {
       dvr_entry_retention_arm(de, dvr_timer_remove_files, stop);
@@ -525,9 +541,9 @@ dvr_entry_retention_timer(dvr_entry_t *de)
     }
     save = 0;
     if (dvr_get_filename(de))
-      save = dvr_entry_delete(de);    // delete actual file
-    if (retention == DVR_RET_ONREMOVE) {
-      dvr_entry_deferred_destroy(de); // also remove database entry
+      save = dvr_entry_delete(de);                // delete actual file
+    if (dvr_entry_delete_retention_expired(de)) { // in case retention was postponed (retention < removal)
+      dvr_entry_deferred_destroy(de);             // also remove database entry
       return;
     }
     if (save) {
@@ -536,12 +552,14 @@ dvr_entry_retention_timer(dvr_entry_t *de)
     }
   }
 
-  if (retention < DVR_RET_ONREMOVE) {
+  if (retention < DVR_RET_ONREMOVE &&
+      (dvr_get_filesize(de, 0) < 0 || removal == DVR_RET_REM_FOREVER)) { // we need the database entry for later file removal
     stop = time_t_out_of_range((int64_t)de->de_stop + retention * (int64_t)86400);
     dvr_entry_retention_arm(de, dvr_timer_expire, stop);
-  } else {
-    dvr_entry_trace(de, "retention timer - disarm");
-    gtimer_disarm(&de->de_timer);
+  }
+  else {
+    dvr_entry_retention_arm(de, dvr_timer_disarm,
+        dvr_entry_get_rerecord_errors(de) ? INT_MAX : 0); // extend disarm to keep the rerecord logic running
   }
 }
 
@@ -1566,6 +1584,17 @@ dvr_timer_expire(void *aux)
 }
 
 
+/**
+ *
+ */
+static void
+dvr_timer_disarm(void *aux)
+{
+  dvr_entry_t *de = aux;
+  dvr_entry_trace(de, "retention timer - disarm");
+  gtimer_disarm(&de->de_timer);
+}
+
 /**
  *
  */
@@ -3673,12 +3702,13 @@ dvr_entry_cancel_delete_remove(dvr_entry_t *de, int rerecord, int _delete)
     dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0);
   case DVR_MISSED_TIME:
   case DVR_COMPLETED:
-    save = dvr_entry_delete(de); /* Remove files */
-    if (_delete || dvr_entry_get_retention_days(de) == DVR_RET_ONREMOVE)
-      dvr_entry_destroy(de, 1);  /* Delete database */
+    save = dvr_entry_delete(de);                           /* Remove files */
+    if (_delete || dvr_entry_delete_retention_expired(de)) /* In case retention was postponed (retention < removal) */
+      dvr_entry_destroy(de, 1);                            /* Delete database */
     else if (save) {
       idnode_changed(&de->de_id);
       htsp_dvr_entry_update(de);
+      dvr_entry_retention_timer(de);                       /* As retention timer depends on file removal */
     }
     break;
   case DVR_SCHEDULED:
index 19e8972386b0525b9482f65b11e1cb5df0059b4b..c779969e9b55466394289edc95c3b50ff7038e82 100644 (file)
@@ -793,12 +793,7 @@ dvr_timerec_get_retention_days( dvr_timerec_entry_t *dte )
   if (dte->dte_retention > 0) {
     if (dte->dte_retention > DVR_RET_REM_FOREVER)
       return DVR_RET_REM_FOREVER;
-
-    /* As we need the db entry when deleting the file on disk */
-    if (dvr_timerec_get_removal_days(dte) != DVR_RET_REM_FOREVER &&
-        dvr_timerec_get_removal_days(dte) > dte->dte_retention)
-      return DVR_RET_ONREMOVE;
-
+      
     return dte->dte_retention;
   }
   return dvr_retention_cleanup(dte->dte_config->dvr_retention_days);