Alvaro Herrera wrote: > > In addition to that, it might be a good idea to do what the comment in the > > code suggests, namely do more than zero checking on each file name to try > > to make sure it looks like a stats temp file name that we'd generate > > before we delete it. The ownership/permissions test wouldn't be enough > > to prevent you from pointing at, say, ~postgres and thereby losing some > > files you'd rather not. > > This seems pretty simple to do; see second attachment. (It would delete > files named, "db_1234.tmpfoobar", that is, valid names with suffixes, > but I can't see that being a problem). (I haven't really tested this > part at all.)
Here's the second attachment. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
*** a/src/backend/postmaster/pgstat.c --- b/src/backend/postmaster/pgstat.c *************** *** 562,576 **** pgstat_reset_remove_files(const char *directory) struct dirent *entry; char fname[MAXPGPATH]; ! dir = AllocateDir(pgstat_stat_directory); ! while ((entry = ReadDir(dir, pgstat_stat_directory)) != NULL) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; ! /* XXX should we try to ignore files other than the ones we write? */ ! snprintf(fname, MAXPGPATH, "%s/%s", pgstat_stat_directory, entry->d_name); unlink(fname); } --- 562,589 ---- struct dirent *entry; char fname[MAXPGPATH]; ! dir = AllocateDir(directory); ! while ((entry = ReadDir(dir, directory)) != NULL) { + Oid tmp_oid; + char tmp_type[5]; + int nitems; + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; ! /* ! * Skip directory entries that don't match the file names we write. ! * See get_dbstat_filename for the pattern. ! */ ! nitems = sscanf(fname, "db_%u.%4s", &tmp_oid, tmp_type); ! if (nitems != 2) ! continue; ! if (strncmp(tmp_type, "tmp", 4) != 0 && ! strncmp(tmp_type, "stat", 4) != 0) ! continue; ! snprintf(fname, MAXPGPATH, "%s/%s", directory, entry->d_name); unlink(fname); } *************** *** 3627,3632 **** get_dbstat_filename(bool permanent, bool tempname, Oid databaseid, --- 3640,3646 ---- { int printed; + /* NB -- pgstat_reset_remove_files knows about the pattern this uses */ printed = snprintf(filename, len, "%s/db_%u.%s", permanent ? PGSTAT_STAT_PERMANENT_DIRECTORY : pgstat_stat_directory,
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers