Обсуждение: Ignoring symlinks when recovering time zone identifiers in initdb
There's a story making the rounds that the removal of the /usr/share/zoneinfo/US/Pacific etc. in Debian broke installations. These identifiers should not be used, but they may get picked by initdb if they are shorter than the alternatives. The length-based tie breaking was introduced in commit e3846a00c2f ("Prefer timezone name "UTC" over alternative spellings."). Would it make sense to ignore symbolic links when searching for the time zone identifier under /usr/share/zoneinfo in scan_available_timezones? Something like this (untested): diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c index 2b2ae39adf3..e492e904993 100644 --- a/src/bin/initdb/findtimezone.c +++ b/src/bin/initdb/findtimezone.c @@ -677,7 +677,11 @@ scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry *tt, snprintf(tzdir + tzdir_orig_len, MAXPGPATH - tzdir_orig_len, "/%s", name); - if (stat(tzdir, &statbuf) != 0) + /* + * Ignore symbolic links, so that shorter aliases in directories such + * as "US" are not preferred over the "America" directory. + */ + if (lstat(tzdir, &statbuf) != 0) { #ifdef DEBUG_IDENTIFY_TIMEZONE fprintf(stderr, "could not stat \"%s\": %m\n", @@ -693,7 +697,7 @@ scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry *tt, scan_available_timezones(tzdir, tzdirsub, tt, bestscore, bestzonename); } - else + else if (S_ISREG(statbuf.st_mode)) { /* Load and test this file */ int score = score_timezone(tzdirsub, tt);
Florian Weimer <fw@deneb.enyo.de> writes: > There's a story making the rounds that the removal of the > /usr/share/zoneinfo/US/Pacific etc. in Debian broke installations. > These identifiers should not be used, but they may get picked by > initdb if they are shorter than the alternatives. Ugh. (Fortunately, I don't think fixing this is any harder than editing the timezone entries in postgresql.conf.) > The length-based > tie breaking was introduced in commit e3846a00c2f ("Prefer timezone > name "UTC" over alternative spellings."). Just for the record, it's far older than that. Looks like it dates to 2def4552e from 2004. > Would it make sense to ignore symbolic links when searching for the > time zone identifier under /usr/share/zoneinfo in scan_available_timezones? That seems only vaguely related to the problem. If a distro arbitrarily decides they can remove some zoneinfo entries, that's going to break someone. Also, it's common to implement zone links as hardlinks not symlinks (Red Hat, for one, does it that way), in which case this heuristic won't help at all. I'd just as soon not introduce a behavior that will result in choosing different zone names on different platforms even when they have logically-equivalent zoneinfo contents. regards, tom lane
I wrote: > Florian Weimer <fw@deneb.enyo.de> writes: >> There's a story making the rounds that the removal of the >> /usr/share/zoneinfo/US/Pacific etc. in Debian broke installations. >> These identifiers should not be used, but they may get picked by >> initdb if they are shorter than the alternatives. > Ugh. (Fortunately, I don't think fixing this is any harder than > editing the timezone entries in postgresql.conf.) BTW, I wonder why 23bd3cec6 ("Attempt to identify system timezone by reading /etc/localtime symlink") didn't help here. It looks to me like Debian follows the convention of /etc/localtime being a symlink, so we should have chosen whichever zone is the system's setting and never fallen back to our zone-name heuristics at all. regards, tom lane