On Wed, Mar 31, 2021 at 12:40:57PM +0200, Claudio Jeker wrote:
> The current code to cleanup the repository after validation did not
> cleanup directories and also skipped any repo directory that is no
> referenced.
> 
> Adjust the cleanup code to fix these two issues. This uses the fact that
> the cache directory now only contains 2 directories rsync & ta.
> Thanks to the internal order of the RB tree, the code can use RB_NFIND()
> to figure out if a path is used or not.
> 
> With this the cleanup works but is also more aggressiv.
> For example if you run
>       rpki-client -t /etc/rpki/afrinic.tal
> then this will clean out all other repositories from arin, apnic, lacnic
> and ripe. For regular use this is no isssue since you normally run
> rpki-client over and over again with the same flags.
> 

This version also skips the cleanup run if rpki-client was started with -n

-- 
:wq Claudio

Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.59
diff -u -p -r1.59 extern.h
--- extern.h    29 Mar 2021 12:41:34 -0000      1.59
+++ extern.h    31 Mar 2021 08:38:33 -0000
@@ -306,6 +306,7 @@ struct      stats {
        size_t   vrps; /* total number of vrps */
        size_t   uniqs; /* number of unique vrps */
        size_t   del_files; /* number of files removed in cleanup */
+       size_t   del_dirs ;/* number of directories removed in cleanup */
        char    *talnames;
        struct timeval  elapsed_time;
        struct timeval  user_time;
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.126
diff -u -p -r1.126 main.c
--- main.c      29 Mar 2021 03:45:35 -0000      1.126
+++ main.c      31 Mar 2021 11:39:56 -0000
@@ -154,6 +154,22 @@ filepath_exists(char *file)
        return RB_FIND(filepath_tree, &fpt, &needle) != NULL;
 }
 
+/*
+ * Return true if a filepath entry exists that starts with path.
+ */
+static int
+filepath_dir_exists(char *path)
+{
+       struct filepath needle;
+       struct filepath *res;
+
+       needle.file = path;
+       res = RB_NFIND(filepath_tree, &fpt, &needle);
+       if (res != NULL && strstr(res->file, path) == res->file)
+               return 1;
+       return 0;
+}
+
 RB_GENERATE(filepath_tree, filepath, entry, filepathcmp);
 
 void
@@ -767,56 +783,56 @@ add_to_del(char **del, size_t *dsz, char
        return del;
 }
 
-static size_t
+static void
 repo_cleanup(void)
 {
-       size_t i, delsz = 0;
-       char *argv[2], **del = NULL;
-       struct repo *rp;
+       size_t i, delsz = 0, dirsz = 0;
+       char *argv[3], **del = NULL, **dir = NULL;
        FTS *fts;
        FTSENT *e;
 
-       SLIST_FOREACH(rp, &repos, entry) {
-               argv[0] = rp->local;
-               argv[1] = NULL;
-               if ((fts = fts_open(argv, FTS_PHYSICAL | FTS_NOSTAT,
-                   NULL)) == NULL)
-                       err(1, "fts_open");
-               errno = 0;
-               while ((e = fts_read(fts)) != NULL) {
-                       switch (e->fts_info) {
-                       case FTS_NSOK:
-                               if (!filepath_exists(e->fts_path))
-                                       del = add_to_del(del, &delsz,
-                                           e->fts_path);
-                               break;
-                       case FTS_D:
-                       case FTS_DP:
-                               /* TODO empty directory pruning */
-                               break;
-                       case FTS_SL:
-                       case FTS_SLNONE:
-                               warnx("symlink %s", e->fts_path);
-                               del = add_to_del(del, &delsz, e->fts_path);
-                               break;
-                       case FTS_NS:
-                       case FTS_ERR:
-                               warnx("fts_read %s: %s", e->fts_path,
-                                   strerror(e->fts_errno));
-                               break;
-                       default:
-                               warnx("unhandled[%x] %s", e->fts_info,
+       argv[0] = "ta";
+       argv[1] = "rsync";
+       argv[2] = NULL;
+       if ((fts = fts_open(argv, FTS_PHYSICAL | FTS_NOSTAT, NULL)) == NULL)
+               err(1, "fts_open");
+       errno = 0;
+       while ((e = fts_read(fts)) != NULL) {
+               switch (e->fts_info) {
+               case FTS_NSOK:
+                       if (!filepath_exists(e->fts_path))
+                               del = add_to_del(del, &delsz,
                                    e->fts_path);
-                               break;
-                       }
-
-                       errno = 0;
+                       break;
+               case FTS_D:
+                       break;
+               case FTS_DP:
+                       if (!filepath_dir_exists(e->fts_path))
+                               dir = add_to_del(dir, &dirsz,
+                                   e->fts_path);
+                       break;
+               case FTS_SL:
+               case FTS_SLNONE:
+                       warnx("symlink %s", e->fts_path);
+                       del = add_to_del(del, &delsz, e->fts_path);
+                       break;
+               case FTS_NS:
+               case FTS_ERR:
+                       warnx("fts_read %s: %s", e->fts_path,
+                           strerror(e->fts_errno));
+                       break;
+               default:
+                       warnx("unhandled[%x] %s", e->fts_info,
+                           e->fts_path);
+                       break;
                }
-               if (errno)
-                       err(1, "fts_read");
-               if (fts_close(fts) == -1)
-                       err(1, "fts_close");
+
+               errno = 0;
        }
+       if (errno)
+               err(1, "fts_read");
+       if (fts_close(fts) == -1)
+               err(1, "fts_close");
 
        for (i = 0; i < delsz; i++) {
                if (unlink(del[i]) == -1)
@@ -826,8 +842,17 @@ repo_cleanup(void)
                free(del[i]);
        }
        free(del);
+       stats.del_files = delsz;
 
-       return delsz;
+       for (i = 0; i < dirsz; i++) {
+               if (rmdir(dir[i]) == -1)
+                       warn("rmdir %s", dir[i]);
+               if (verbose > 1)
+                       logx("deleted dir %s", dir[i]);
+               free(dir[i]);
+       }
+       free(dir);
+       stats.del_dirs = dirsz;
 }
 
 void
@@ -1228,7 +1253,8 @@ main(int argc, char *argv[])
                }
        }
 
-       stats.del_files = repo_cleanup();
+       if (!noop)
+               repo_cleanup();
 
        gettimeofday(&now_time, NULL);
        timersub(&now_time, &start_time, &stats.elapsed_time);
@@ -1259,7 +1285,8 @@ main(int argc, char *argv[])
        logx("Certificate revocation lists: %zu", stats.crls);
        logx("Ghostbuster records: %zu", stats.gbrs);
        logx("Repositories: %zu", stats.repos);
-       logx("Files removed: %zu", stats.del_files);
+       logx("Cleanup: removed %zu files, %zu directories",
+           stats.del_files, stats.del_dirs);
        logx("VRP Entries: %zu (%zu unique)", stats.vrps, stats.uniqs);
 
        /* Memory cleanup. */

Reply via email to