Claudio Jeker(cje...@diehard.n-r-g.com) on 2021.04.29 15:34:15 +0200:
> Like for rsync repos files in the RRDP repos should be delayed until after
> the validation finished. As with anything RPKI related there is little
> trust in the repositories and their abilities to not botch an update.
> 
> One thing I'm not sure is what should happen if a file is supposed to be
> removed but is still referenced by some other file. For now this fact is
> logged and the file is kept in the repo. I'm unsure about keeping the

fine with me, ok benno@

> file, it feels like the right move but may result in unreferenced files
> piling  up in the rrdp repo dirs.
> 
> There is no way to detect stale files in RRDP repos (apart from removing
> all files and fetching a snapshot). So until RRDP grows up to a real sync
> protocol the only thing one can do is to provide a large enough partition
> and to remove the cache from time to time.

You could get a file listing at the start and then remove files from the
list that are referenced, at the end you delete the ones left.

> -- 
> :wq Claudio
> 
> 
> Index: repo.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/repo.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 repo.c
> --- repo.c    19 Apr 2021 17:04:35 -0000      1.6
> +++ repo.c    29 Apr 2021 13:12:34 -0000
> @@ -553,16 +553,19 @@ rrdp_free(void)
>       }
>  }
>  
> -static int
> +static struct rrdprepo *
>  rrdp_basedir(const char *dir)
>  {
>       struct rrdprepo *rr;
>  
>       SLIST_FOREACH(rr, &rrdprepos, entry)
> -             if (strcmp(dir, rr->basedir) == 0)
> -                     return 1;
> +             if (strcmp(dir, rr->basedir) == 0) {
> +                     if (rr->state == REPO_FAILED)
> +                             return NULL;
> +                     return rr;
> +             }
>  
> -     return 0;
> +     return NULL;
>  }
>  
>  /*
> @@ -840,27 +843,6 @@ rrdp_merge_repo(struct rrdprepo *rr)
>       struct filepath *fp, *nfp;
>       char *fn, *rfn;
>  
> -     /* XXX should delay deletes */
> -     RB_FOREACH_SAFE(fp, filepath_tree, &rr->deleted, nfp) {
> -             fn = rrdp_filename(rr, fp->file, 1);
> -             rfn = rrdp_filename(rr, fp->file, 0);
> -
> -             if (fn == NULL || rfn == NULL)
> -                     errx(1, "bad filepath");        /* should not happen */
> -
> -             if (unlink(rfn) == -1) {
> -                     if (errno == ENOENT) {
> -                             if (unlink(fn) == -1)
> -                                     warn("%s: unlink", fn);
> -                     } else
> -                             warn("%s: unlink", rfn);
> -             }
> -
> -             free(rfn);
> -             free(fn);
> -             filepath_put(&rr->deleted, fp);
> -     }
> -
>       RB_FOREACH_SAFE(fp, filepath_tree, &rr->added, nfp) {
>               fn = rrdp_filename(rr, fp->file, 1);
>               rfn = rrdp_filename(rr, fp->file, 0);
> @@ -1146,12 +1128,40 @@ add_to_del(char **del, size_t *dsz, char
>       *dsz = i + 1;
>       return del;
>  }
> +
> +static char **
> +repo_rrdp_cleanup(struct filepath_tree *tree, struct rrdprepo *rr,
> +    char **del, size_t *delsz)
> +{
> +     struct filepath *fp, *nfp;
> +     char *fn;
> +
> +     RB_FOREACH_SAFE(fp, filepath_tree, &rr->deleted, nfp) {
> +             fn = rrdp_filename(rr, fp->file, 0);
> +             /* temp dir will be cleaned up by repo_cleanup() */
> +
> +             if (fn == NULL)
> +                     errx(1, "bad filepath");        /* should not happen */
> +
> +             if (!filepath_exists(tree, fn))
> +                     del = add_to_del(del, delsz, fn);
> +             else
> +                     warnx("%s: referenced file supposed to be deleted", fn);
> +
> +             free(fn);
> +             filepath_put(&rr->deleted, fp);
> +     }
> +
> +     return del;
> +}
> +
>  void
>  repo_cleanup(struct filepath_tree *tree)
>  {
> -     size_t i, delsz = 0, dirsz = 0;
> +     size_t i, cnt, delsz = 0, dirsz = 0;
>       char **del = NULL, **dir = NULL;
>       char *argv[4] = { "ta", "rsync", "rrdp", NULL };
> +     struct rrdprepo *rr;
>       FTS *fts;
>       FTSENT *e;
>  
> @@ -1166,10 +1176,12 @@ repo_cleanup(struct filepath_tree *tree)
>                                   e->fts_path);
>                       break;
>               case FTS_D:
> -                     /* skip rrdp base directories during cleanup */
> -                     if (rrdp_basedir(e->fts_path))
> +                     /* special cleanup for rrdp directories */
> +                     if ((rr = rrdp_basedir(e->fts_path)) != NULL) {
> +                             del = repo_rrdp_cleanup(tree, rr, del, &delsz);
>                               if (fts_set(fts, e, FTS_SKIP) == -1)
>                                       err(1, "fts_set");
> +                     }
>                       break;
>               case FTS_DP:
>                       if (!filepath_dir_exists(tree, e->fts_path))
> @@ -1203,25 +1215,31 @@ repo_cleanup(struct filepath_tree *tree)
>       if (fts_close(fts) == -1)
>               err(1, "fts_close");
>  
> +     cnt = 0;
>       for (i = 0; i < delsz; i++) {
> -             if (unlink(del[i]) == -1)
> -                     warn("unlink %s", del[i]);
> -             if (verbose > 1)
> -                     logx("deleted %s", del[i]);
> +             if (unlink(del[i]) == -1) {
> +                     if (errno != ENOENT)
> +                             warn("unlink %s", del[i]);
> +             } else {
> +                     if (verbose > 1)
> +                             logx("deleted %s", del[i]);
> +                     cnt++;
> +             }
>               free(del[i]);
>       }
>       free(del);
> -     stats.del_files = delsz;
> +     stats.del_files = cnt;
>  
> +     cnt = 0;
>       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]);
> +             else
> +                     cnt++;
>               free(dir[i]);
>       }
>       free(dir);
> -     stats.del_dirs = dirsz;
> +     stats.del_dirs = cnt;
>  }
>  
>  void
> 

Reply via email to