Control: tag -1 + patch Hi,
Quoting Johannes Schauer Marin Rodrigues (2022-05-14 08:46:48) > the contents of index.db are unreproducible across different > hosts/filesystems. With the same host/filesystem, it works fine: > > $ export SOURCE_DATE_EPOCH=1652473183 > $ mmdebstrap --variant=standard unstable out1.tar > $ mmdebstrap --variant=standard unstable out2.tar > $ cmp out1.tar out2.tar > $ echo $? > 0 > > Now lets mmdebstrap use a filesystem mounted with disorderfs as its > TMPDIR to simulate the problem: > > $ mkdir emptydir disorder > $ sudo disorderfs --multi-user=yes --shuffle-dirents=yes > --reverse-dirents=no emptydir disorder > $ export TMPDIR=$(pwd)/disorder > $ mmdebstrap --variant=standard unstable out1.tar > $ mmdebstrap --variant=standard unstable out2.tar > $ diffoscope out1.tar out2.tar | grep ├── > ├── file list > ├── ./var/cache/man/cs/index.db > ├── ./var/cache/man/da/index.db > ├── ./var/cache/man/de/index.db > ├── ./var/cache/man/es/index.db > ├── ./var/cache/man/fr/index.db > ... > > I attached the contents of /var/cache/man/index.db so that you can see > that it is indeed the order that differs between individual runs. I now have a patch (attached). Thanks! cheers, josch
--- a/src/check_mandirs.c +++ b/src/check_mandirs.c @@ -342,8 +342,8 @@ static void add_dir_entries (MYDBM_FILE { char *manpage; int len; - struct dirent *newdir; - DIR *dir; + int n; + struct dirent **namelist; gl_list_t names; const char *name; @@ -356,8 +356,8 @@ static void add_dir_entries (MYDBM_FILE * or . files (such as current, parent dir). */ - dir = opendir (infile); - if (!dir) { + n = scandir(infile, &namelist, NULL, alphasort); + if (n < 0) { error (0, errno, _("can't search directory %s"), manpage); free (manpage); return; @@ -367,13 +367,13 @@ static void add_dir_entries (MYDBM_FILE /* strlen(newdir->d_name) could be replaced by newdir->d_reclen */ - while ((newdir = readdir (dir)) != NULL) { - if (*newdir->d_name == '.' && - strlen (newdir->d_name) < (size_t) 3) + while (n--) { + if (*namelist[n]->d_name == '.' && + strlen (namelist[n]->d_name) < (size_t) 3) continue; - gl_list_add_last (names, xstrdup (newdir->d_name)); + gl_list_add_last (names, xstrdup (namelist[n]->d_name)); } - closedir (dir); + free(namelist); order_files (infile, &names); @@ -516,8 +516,8 @@ static void fix_permissions_tree (const static int testmandirs (MYDBM_FILE dbf, const char *path, const char *catpath, struct timespec last, bool create) { - DIR *dir; - struct dirent *mandir; + int n; + struct dirent **namelist; int amount = 0; bool created = false; @@ -526,28 +526,28 @@ static int testmandirs (MYDBM_FILE dbf, if (catpath) fix_permissions_tree (catpath); - dir = opendir (path); - if (!dir) { + n = scandir(path, &namelist, NULL, alphasort); + if (n < 0) { error (0, errno, _("can't search directory %s"), path); return 0; } if (chdir (path) != 0) { error (0, errno, _("can't change to directory %s"), path); - closedir (dir); + free(namelist); return 0; } - while( (mandir = readdir (dir)) ) { + while (n--) { struct stat stbuf; struct timespec mtime; - if (strncmp (mandir->d_name, "man", 3) != 0) + if (strncmp (namelist[n]->d_name, "man", 3) != 0) continue; - debug ("Examining %s\n", mandir->d_name); + debug ("Examining %s\n", namelist[n]->d_name); - if (stat (mandir->d_name, &stbuf) != 0) /* stat failed */ + if (stat (namelist[n]->d_name, &stbuf) != 0) /* stat failed */ continue; if (!S_ISDIR(stbuf.st_mode)) /* not a directory */ continue; @@ -556,14 +556,14 @@ static int testmandirs (MYDBM_FILE dbf, /* scanned already */ debug ("%s modified %ld.%09ld, " "db modified %ld.%09ld\n", - mandir->d_name, + namelist[n]->d_name, (long) mtime.tv_sec, (long) mtime.tv_nsec, (long) last.tv_sec, (long) last.tv_nsec); continue; } debug ("\tsubdirectory %s has been 'modified'\n", - mandir->d_name); + namelist[n]->d_name); if (create && !created) { /* We seem to have something to do, so create the @@ -577,13 +577,13 @@ static int testmandirs (MYDBM_FILE dbf, if (errno == EACCES || errno == EROFS) { debug ("database %s is read-only\n", dbf->name); - closedir (dir); + free(namelist); return 0; } else { error (0, errno, _("can't create index cache %s"), dbf->name); - closedir (dir); + free(namelist); return -1; } } @@ -592,7 +592,7 @@ static int testmandirs (MYDBM_FILE dbf, created = true; } else if (!ensure_db_open (dbf)) { - closedir (dir); + free(namelist); return 0; } @@ -603,14 +603,14 @@ static int testmandirs (MYDBM_FILE dbf, fprintf (stderr, "\r"); fprintf (stderr, _("Updating index cache for path " - "`%s/%s'. Wait..."), path, mandir->d_name); + "`%s/%s'. Wait..."), path, namelist[n]->d_name); if (!tty) fprintf (stderr, "\n"); } - add_dir_entries (dbf, path, mandir->d_name); + add_dir_entries (dbf, path, namelist[n]->d_name); amount++; } - closedir (dir); + free(namelist); return amount; }
signature.asc
Description: signature