liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 00aeb8181190a2f731ea48d52841898d70595778
parent a809c28ddef5baa03d9b5af502b62a015d969c8b
Author: Daniel Barlow <dan@telent.net>
Date:   Fri, 19 May 2023 23:49:11 +0100

min-list-garbage: check all store paths against file

this is step 1 of min-collect-garbage, no point implementing
deletion ourselves when rm -r exists

(arguably no point in implementing any of it, but this is the bit we
can't do efficiently in bourne shell - it means we're reading the
store-paths list once instead of grepping it afresh for every entry in
/nix/store/)

Diffstat:
Mpkgs/min-copy-closure/default.nix | 8++++++--
Apkgs/min-copy-closure/min-list-garbage.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/pkgs/min-copy-closure/default.nix b/pkgs/min-copy-closure/default.nix @@ -8,9 +8,13 @@ buildInputs = [ ]; propagatedBuildInputs = [ cpio openssh nix ]; src = ./.; + makeFlags = [ "min-list-garbage" ]; installPhase = '' mkdir -p $out/bin - cp min-copy-closure.sh $out/bin/min-copy-closure - cp liminix-rebuild.sh $out/bin/liminix-rebuild + for i in min-copy-closure liminix-rebuild; do + echo $i + cp ''${i}.sh $out/bin/$i + done + cp min-list-garbage $out/bin ''; } diff --git a/pkgs/min-copy-closure/min-list-garbage.c b/pkgs/min-copy-closure/min-list-garbage.c @@ -0,0 +1,79 @@ +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <unistd.h> + +typedef char hash_t[32]; +hash_t *hash_list = NULL; +int hash_list_entries = 0; +int hash_list_size = 0; + +int add_list_entry(char *name) +{ + name += strlen("/nix/store/"); + if(hash_list_entries >= hash_list_size) { + if(hash_list_size == 0) hash_list_size = 4; + hash_list_size = hash_list_size * 2; + hash_list = realloc(hash_list, hash_list_size * sizeof(hash_t)); + } + strncpy(hash_list[hash_list_entries++], name, 32); + printf("%d %d\n", hash_list_entries, hash_list_size); +} + +int read_list(char *filename) +{ + char s[1024]; + FILE *fp; + if(fp = fopen(filename, "r")) { + while(fgets(s, 1024, fp)) { + if(strrchr(s, '\n')) { + add_list_entry(s); + } else { + puts("hash list entry too long"); + exit(1); + } + } + } + fclose(fp); +} + +int on_list(char *name) +{ + int i; + for(i = 0; i < hash_list_entries; i++) { + if(!strncmp(hash_list[i], name, 32)) { + return 1; + } + } + return 0; +} + +int main(int argc, char * argv[]) +{ + struct dirent * de; + DIR * dirp; + char hash[32]; + + if(argc < 2) { + puts("Usage: min-list-garbage store-paths-file\n\nChecks all store paths against the list of expected paths in store-paths-file,\n and prints any which are present unexpectedly"); + exit(1); + } + + read_list(argv[1]); + + if((dirp = opendir("/nix/store")) == NULL) { + puts("can't open /nix/store"); + exit(1); + } + + while(de = readdir(dirp)) { + if(strlen(de->d_name) >= 32) { + strncpy(hash, de->d_name, 32); + if(!on_list(hash)) puts(de->d_name); + } + } + + closedir(dirp); +}