Re: [COMMITTERS] pgsql: Add configure option --with-system-tzdata to use operating system - Mailing list pgsql-hackers

From Tom Lane
Subject Re: [COMMITTERS] pgsql: Add configure option --with-system-tzdata to use operating system
Date
Msg-id 12298.1187820982@sss.pgh.pa.us
Whole thread Raw
Responses Re: [COMMITTERS] pgsql: Add configure option --with-system-tzdata to use operating system
Re: [COMMITTERS] pgsql: Add configure option --with-system-tzdata to use operating system
List pgsql-hackers
petere@postgresql.org (Peter Eisentraut) writes:
> Log Message:
> -----------
> Add configure option --with-system-tzdata to use operating system time zone
> database.

While this looked like a reasonable idea in the abstract, it turns out
that it was probably a waste of time.  Red Hat distributions, at least,
will never be able to use it in the given form.  Allow me to do a brain
dump for the archives' benefit, before I forget the details.

In the first place, it is considered bad form for a package to install
an absolute symlink to /usr/share/zoneinfo:

"symlinks _should_ be relative.  Even if all they have in common is /."
- Jeremy Katz
https://www.redhat.com/archives/fedora-maintainers/2007-August/msg00096.html

Followup arguments in that thread mentioned chroots and NFS mounts as
environments where absolute symlinks are likely to lead to the wrong
place.  While I'm not 100% convinced by those arguments, it's difficult
to go against the advice of people who have far more experience with RPM
packaging than I do.  Fortunately, the standard RPM installation
location for PG's datadir is /usr/share/pgsql, so in practice the
symlink will be "../zoneinfo", which is not so scary as it coulda been.

Unfortunately, "configure --with-system-tzdata=../zoneinfo" ain't
gonna work; the build will not get through "make check", because that
symlink won't work in a temporary installation.  And trying to
relativize the symlink on-the-fly during "make install" is no answer
either, since in an RPM build that step is normally done with a nonempty
DESTDIR prefix.

The other truly nasty thing, which I just wasted most of this afternoon
learning the hard way, is that RPM does not like at all to replace a
directory with a symlink, and don't hold your breath for a fix:
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=61413
I experimented with various ways to get around that, and mostly
succeeded in wiping out my /usr/share/zoneinfo :-( It seems that the
fundamental problem is that RPM doesn't remove files that have vanished
from a package until quite late in an update cycle, and is therefore
capable of removing things indirectly through the already-installed
symlink, while thinking that it is cleaning out the contents of the
former subdirectory.  My ultimate conclusion was that the only
reasonably safe way to do things is to make the symlink be named
something different from the original subdirectory.
https://www.redhat.com/archives/fedora-devel-list/2007-August/msg01622.html

This might be a problem specific to RPM, but I wouldn't really care to
bet on other package managers being entirely free of it.  My advice
to anyone else thinking of using a symlink to a system directory is to
name it something different than the existing PG subdirectory.

In short, then, the patch actually being used (as of today) in Fedora
and ultimately RHEL is as below, and I don't see any prospect of
substituting the mechanism Peter has created.
        regards, tom lane

--------------

PostgreSQL includes its own copy of the zic timezone database, which is great
for ensuring portable results but not so great from a package maintenance
perspective.  Since the data is in the same format as is provided by the
Linux-standard /usr/share/zoneinfo files, we can avoid having to update
postgresql for timezone updates by just symlinking to those files.

It is allegedly desirable for the link in question to be a relative symlink.
I have strong doubts about this, not least because it requires the horrid
install-time kluge seen below --- we can't use a simple relative symlink when
making the temporary installation used for "make check", since that will be at
an indeterminate location compared to /usr/share.  The actual relative link
also depends fundamentally upon knowing where the PG datadir will get
installed, namely /usr/share/pgsql.

And if you thought that was bad, it turns out that RPM has some fundamental
bugs that make it difficult or impossible to replace a directory with a
symlink during RPM upgrade.  Rather than risk getting caught in that quagmire,
we choose to name the symlink something different than its predecessor
subdirectory.  (This part of the hack could perhaps get undone someday, when
there is no longer any danger of someone trying to rpm-upgrade from an
installation that isn't patched this way.)


diff -Naur postgresql-8.2.4.orig/src/timezone/Makefile postgresql-8.2.4/src/timezone/Makefile
--- postgresql-8.2.4.orig/src/timezone/Makefile    2007-03-14 13:38:15.000000000 -0400
+++ postgresql-8.2.4/src/timezone/Makefile    2007-08-22 16:57:41.000000000 -0400
@@ -38,14 +38,18 @@    $(CC) $(CFLAGS) $(ZICOBJS) $(LDFLAGS) $(LIBS) -o $@$(X)install: all installdirs
-    ./zic -d '$(DESTDIR)$(datadir)/timezone' -p '$(POSIXRULES)' $(TZDATAFILES)
+    if [ x'$(DESTDIR)' = x`echo '$(DESTDIR)' | sed 's,tmp_check/install,,'` ] ; then \
+        ln -s '../zoneinfo' '$(DESTDIR)$(datadir)/zoneinfo' ; \
+    else \
+        ln -s '/usr/share/zoneinfo' '$(DESTDIR)$(datadir)/zoneinfo' ; \
+    fi    $(MAKE) -C tznames $@installdirs:    $(mkinstalldirs) '$(DESTDIR)$(datadir)'uninstall:
-    rm -rf '$(DESTDIR)$(datadir)/timezone'
+    rm '$(DESTDIR)$(datadir)/zoneinfo'    $(MAKE) -C tznames $@clean distclean maintainer-clean:
diff -Naur postgresql-8.2.4.orig/src/timezone/pgtz.c postgresql-8.2.4/src/timezone/pgtz.c
--- postgresql-8.2.4.orig/src/timezone/pgtz.c    2006-11-21 18:11:55.000000000 -0500
+++ postgresql-8.2.4/src/timezone/pgtz.c    2007-08-22 16:57:04.000000000 -0400
@@ -52,7 +52,7 @@        return tzdir;    get_share_path(my_exec_path, tzdir);
-    strlcpy(tzdir + strlen(tzdir), "/timezone", MAXPGPATH - strlen(tzdir));
+    strlcpy(tzdir + strlen(tzdir), "/zoneinfo", MAXPGPATH - strlen(tzdir));    done_tzdir = true;    return tzdir;


pgsql-hackers by date:

Previous
From: Josh Berkus
Date:
Subject: Power outage on Sun buildfarm machines
Next
From: Gregory Stark
Date:
Subject: Re: [COMMITTERS] pgsql: Add configure option --with-system-tzdata to use operating system