Couple fixes for 'walmgr restore' from -stable:
authorMarko Kreen <markokr@gmail.com>
Fri, 4 Apr 2008 09:11:01 +0000 (09:11 +0000)
committerMarko Kreen <markokr@gmail.com>
Fri, 4 Apr 2008 09:11:01 +0000 (09:11 +0000)
- Make sure pg_tblspc exists, 8.3 seems to require it
- Copy config files/symlinks from old data dir over

Original patch by Zoltán Böszörményi, applied with minor rework

python/walmgr.py

index a26472f521d6825d1618ca3202664c22ae431f63..63c1bf265740dacffd383e417a026afbebd19066 100755 (executable)
@@ -52,7 +52,7 @@ Additional features:
 """
 
 import os, sys, skytools, re, signal, time, traceback
-import errno, glob, ConfigParser
+import errno, glob, ConfigParser, shutil
 
 MASTER = 1
 SLAVE = 0
@@ -85,6 +85,23 @@ def yesno(prompt):
             return False
         sys.stderr.write("Please answer yes or no.\n")
 
+def copy_conf(src, dst):
+    """Copy config file or symlink.
+    Does _not_ overwrite target.
+    """
+    if os.path.isdir(dst):
+        dst = os.path.join(dst, os.path.basename(src))
+    if os.path.exists(dst):
+        return False
+    if os.path.islink(src):
+        linkdst = os.readlink(src)
+        os.symlink(linkdst, listdst)
+    elif os.path.isfile(src):
+        shutil.copy2(src, dst)
+    else:
+        raise Exception("Unsupported file type: %s" % src)
+    return True
+
 class WalChunk:
     def __init__(self,filename,pos=0,bytes=0):
         self.filename = filename
@@ -816,13 +833,14 @@ class WalMgr(skytools.DBScript):
         if self.wtype == MASTER:
             self.master_xrestore(srcname, dstpath)
         else:
-            self.slave_xrestore_unsafe(srcname, dstpath)
+            self.slave_xrestore_unsafe(srcname, dstpath, os.getppid())
 
     def slave_xrestore(self, srcname, dstpath):
         loop = 1
+        ppid = os.getppid()
         while loop:
             try:
-                self.slave_xrestore_unsafe(srcname, dstpath)
+                self.slave_xrestore_unsafe(srcname, dstpath, ppid)
                 loop = 0
             except SystemExit, d:
                 sys.exit(1)
@@ -849,7 +867,12 @@ class WalMgr(skytools.DBScript):
                 return
         self.log.warning("Could not restore file %s" % srcname)
 
-    def slave_xrestore_unsafe(self, srcname, dstpath):
+    def is_parent_alive(self, parent_pid):
+        if os.getppid() != parent_pid or parent_pid <= 1:
+            return False
+        return True
+
+    def slave_xrestore_unsafe(self, srcname, dstpath, parent_pid):
         srcdir = self.cf.get("completed_wals")
         partdir = self.cf.get("partial_wals")
         pausefile = os.path.join(srcdir, "PAUSE")
@@ -891,13 +914,9 @@ class WalMgr(skytools.DBScript):
                     sys.exit(1)
 
             # nothing to do, just in case check if parent is alive
-            try:
-                os.kill(os.getppid(), 0)
-            except OSError, ex:
-                if ex.errno == errno.ESRCH:
-                    self.log.info("%s: not found, stopping" % srcname)
-                    sys.exit(1)
-                self.log.warning("Parent aliveness check failed: "+str(ex))
+            if not self.is_parent_alive(parent_pid):
+                self.log.warning("Parent dead, quitting")
+                sys.exit(1)
 
             # nothing to do, sleep
             self.log.debug("%s: not found, sleeping" % srcname)
@@ -1016,10 +1035,24 @@ class WalMgr(skytools.DBScript):
         else:
             data_dir = full_dir
 
+        if createbackup and os.path.isdir(bak):
+            for cf in ('postgresql.conf', 'pg_hba.conf', 'pg_ident.conf'):
+                cfsrc = os.path.join(bak, cf)
+                cfdst = os.path.join(data_dir, cf)
+                if os.path.exists(cfdst):
+                    self.log.info("Already exists: %s" % cfdst)
+                elif os.path.exists(cfsrc):
+                    self.log.info("Copy %s to %s" % (cfsrc, cfdst))
+                    if not self.not_really:
+                        copy_conf(cfsrc, cfdst)
+
         # re-link tablespaces
         spc_dir = os.path.join(data_dir, "pg_tblspc")
         tmp_dir = os.path.join(data_dir, "tmpspc")
-        if os.path.isdir(spc_dir) and os.path.isdir(tmp_dir):
+        if not os.path.isdir(spc_dir):
+            # 8.3 requires its existence
+            os.mkdir(spc_dir)
+        if os.path.isdir(tmp_dir):
             self.log.info("Linking tablespaces to temporary location")
             
             # don't look into spc_dir, thus allowing