diff --git a/src/borg/helpers.py b/src/borg/helpers.py index f880e4ce7..f758ffb89 100644 --- a/src/borg/helpers.py +++ b/src/borg/helpers.py @@ -139,7 +139,7 @@ def check_extension_modules(): raise ExtensionModuleError if borg.crypto.low_level.API_VERSION != '1.1_02': raise ExtensionModuleError - if platform.API_VERSION != platform.OS_API_VERSION != '1.1_02': + if platform.API_VERSION != platform.OS_API_VERSION != '1.1_03': raise ExtensionModuleError if item.API_VERSION != '1.1_02': raise ExtensionModuleError @@ -664,8 +664,8 @@ def format_line(format, data): def replace_placeholders(text): """Replace placeholders in text with their values.""" + from .platform import fqdn current_time = datetime.now() - fqdn = socket.getfqdn() data = { 'pid': os.getpid(), 'fqdn': fqdn, diff --git a/src/borg/platform/__init__.py b/src/borg/platform/__init__.py index 171590b74..9bf79672c 100644 --- a/src/borg/platform/__init__.py +++ b/src/borg/platform/__init__.py @@ -10,12 +10,12 @@ from .base import acl_get, acl_set from .base import set_flags, get_flags from .base import SaveFile, SyncFile, sync_dir, fdatasync, safe_fadvise from .base import swidth, API_VERSION -from .base import process_alive, get_process_id, local_pid_alive +from .base import process_alive, get_process_id, local_pid_alive, fqdn, hostname, hostid OS_API_VERSION = API_VERSION if not sys.platform.startswith(('win32', )): - from .posix import process_alive, get_process_id, local_pid_alive + from .posix import process_alive, local_pid_alive if sys.platform.startswith('linux'): # pragma: linux only from .linux import API_VERSION as OS_API_VERSION diff --git a/src/borg/platform/base.py b/src/borg/platform/base.py index f56c03be4..3e6e60d3e 100644 --- a/src/borg/platform/base.py +++ b/src/borg/platform/base.py @@ -1,5 +1,7 @@ import errno import os +import socket +import uuid from borg.helpers import truncate_and_unlink @@ -15,7 +17,7 @@ platform API: that way platform APIs provided by the platform-specific support m are correctly composed into the base functionality. """ -API_VERSION = '1.1_02' +API_VERSION = '1.1_03' fdatasync = getattr(os, 'fdatasync', os.fsync) @@ -183,12 +185,44 @@ def swidth(s): return len(s) +# patched socket.getfqdn() - see https://bugs.python.org/issue5004 +def getfqdn(name=''): + """Get fully qualified domain name from name. + + An empty argument is interpreted as meaning the local host. + """ + name = name.strip() + if not name or name == '0.0.0.0': + name = socket.gethostname() + try: + addrs = socket.getaddrinfo(name, None, 0, socket.SOCK_DGRAM, 0, socket.AI_CANONNAME) + except socket.error: + pass + else: + for addr in addrs: + if addr[3]: + name = addr[3] + break + return name + + +# for performance reasons, only determine hostname / fqdn / hostid once. +# XXX this sometimes requires live internet access for issuing a DNS query in the background. +hostname = socket.gethostname() +fqdn = getfqdn(hostname) +hostid = '%s@%s' % (fqdn, uuid.getnode()) + + def get_process_id(): """ - Return identification tuple (hostname, pid, thread_id) for 'us'. If this is a FUSE process, then the PID will be - that of the parent, not the forked FUSE child. + Return identification tuple (hostname, pid, thread_id) for 'us'. + This always returns the current pid, which might be different from before, e.g. if daemonize() was used. + + Note: Currently thread_id is *always* zero. """ - raise NotImplementedError + thread_id = 0 + pid = os.getpid() + return hostid, pid, thread_id def process_alive(host, pid, thread): diff --git a/src/borg/platform/darwin.pyx b/src/borg/platform/darwin.pyx index b7e439ab6..eac6ddc9f 100644 --- a/src/borg/platform/darwin.pyx +++ b/src/borg/platform/darwin.pyx @@ -4,7 +4,7 @@ from ..helpers import user2uid, group2gid from ..helpers import safe_decode, safe_encode from .posix import swidth -API_VERSION = '1.1_02' +API_VERSION = '1.1_03' cdef extern from "sys/acl.h": ctypedef struct _acl_t: diff --git a/src/borg/platform/freebsd.pyx b/src/borg/platform/freebsd.pyx index 3344de165..33bcccdb9 100644 --- a/src/borg/platform/freebsd.pyx +++ b/src/borg/platform/freebsd.pyx @@ -4,7 +4,7 @@ from ..helpers import posix_acl_use_stored_uid_gid from ..helpers import safe_encode, safe_decode from .posix import swidth -API_VERSION = '1.1_02' +API_VERSION = '1.1_03' cdef extern from "errno.h": int errno diff --git a/src/borg/platform/linux.pyx b/src/borg/platform/linux.pyx index 25f71fa18..000fa8fdd 100644 --- a/src/borg/platform/linux.pyx +++ b/src/borg/platform/linux.pyx @@ -13,7 +13,7 @@ from .posix import swidth from libc cimport errno from libc.stdint cimport int64_t -API_VERSION = '1.1_02' +API_VERSION = '1.1_03' cdef extern from "sys/types.h": int ACL_TYPE_ACCESS diff --git a/src/borg/platform/posix.pyx b/src/borg/platform/posix.pyx index 0144e1aa3..fe2039f83 100644 --- a/src/borg/platform/posix.pyx +++ b/src/borg/platform/posix.pyx @@ -1,8 +1,5 @@ import errno import os -import uuid -import socket -import subprocess cdef extern from "wchar.h": @@ -18,23 +15,6 @@ def swidth(s): return str_len -# for performance reasons, only determine the hostname once. -# XXX this sometimes requires live internet access for issuing a DNS query in the background. -_hostname = '%s@%s' % (socket.getfqdn(), uuid.getnode()) - - -def get_process_id(): - """ - Return identification tuple (hostname, pid, thread_id) for 'us'. - This always returns the current pid, which might be different from before, e.g. if daemonize() was used. - - Note: Currently thread_id is *always* zero. - """ - thread_id = 0 - pid = os.getpid() - return _hostname, pid, thread_id - - def process_alive(host, pid, thread): """ Check if the (host, pid, thread_id) combination corresponds to a potentially alive process. @@ -43,8 +23,9 @@ def process_alive(host, pid, thread): returns always True, since there is no real way to check. """ from . import local_pid_alive + from . import hostid - if host != _hostname: + if host != hostid: return True if thread != 0: