[PATCH] Use tiny, fast and thread-safe ntplib module instead of ntpdate
Vratislav Podzimek
vpodzime at redhat.com
Fri Jul 26 11:41:04 UTC 2013
ntpdate is quite a big and slow binary that is not further developed and
basically nobody but us uses it. ntplib is a tiny, fast and thread-safe module
provided by the python-ntplib package containing only the tiny module.
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
anaconda.spec.in | 2 +-
pyanaconda/isys/__init__.py | 11 +++++++++++
pyanaconda/isys/isys.c | 19 +++++++++++++++++++
pyanaconda/ntp.py | 38 ++++++++++++++++++++++++++------------
4 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/anaconda.spec.in b/anaconda.spec.in
index d8be92a..bebeef4 100644
--- a/anaconda.spec.in
+++ b/anaconda.spec.in
@@ -124,7 +124,7 @@ Requires: anaconda-yum-plugins
Requires: libselinux-python >= %{libselinuxver}
Requires: kbd
Requires: chrony
-Requires: ntpdate
+Requires: python-ntplib
Requires: rsync
Requires: hostname
%ifnarch s390 s390x
diff --git a/pyanaconda/isys/__init__.py b/pyanaconda/isys/__init__.py
index 6953793..a320bf9 100755
--- a/pyanaconda/isys/__init__.py
+++ b/pyanaconda/isys/__init__.py
@@ -111,6 +111,17 @@ def isPaeAvailable():
def getAnacondaVersion():
return _isys.getAnacondaVersion()
+def set_system_time(secs):
+ """
+ Set system time to time given as a number of seconds since the Epoch.
+
+ :param secs: a number of seconds since the Epoch to set system time to
+ :type secs: int
+
+ """
+
+ return _isys.set_system_time(secs)
+
auditDaemon = _isys.auditdaemon
handleSegv = _isys.handleSegv
diff --git a/pyanaconda/isys/isys.c b/pyanaconda/isys/isys.c
index c99cb19..688695d 100644
--- a/pyanaconda/isys/isys.c
+++ b/pyanaconda/isys/isys.c
@@ -88,6 +88,7 @@ static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args);
static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args);
static PyObject * doInitLog(PyObject * s);
static PyObject * doTotalMemory(PyObject * s);
+static PyObject * doSetSystemTime(PyObject *s, PyObject *args);
static PyMethodDef isysModuleMethods[] = {
{ "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL },
@@ -103,6 +104,7 @@ static PyMethodDef isysModuleMethods[] = {
{ "getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, NULL },
{ "initLog", (PyCFunction) doInitLog, METH_VARARGS, NULL },
{ "total_memory", (PyCFunction) doTotalMemory, METH_NOARGS, NULL },
+ { "set_system_time", (PyCFunction) doSetSystemTime, METH_VARARGS, NULL},
{ NULL, NULL, 0, NULL }
} ;
@@ -274,4 +276,21 @@ static PyObject * doTotalMemory(PyObject * s) {
return PyLong_FromUnsignedLongLong(tm);
}
+static PyObject * doSetSystemTime(PyObject *s, PyObject *args) {
+ int int_secs;
+ struct timeval tv;
+
+ if (!PyArg_ParseTuple(args, "i", &int_secs))
+ return NULL;
+
+ tv.tv_sec = (time_t) int_secs;
+ tv.tv_usec = 0;
+
+ settimeofday(&tv, NULL);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/pyanaconda/ntp.py b/pyanaconda/ntp.py
index 0014a9d..ca0bbc8 100644
--- a/pyanaconda/ntp.py
+++ b/pyanaconda/ntp.py
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2012 Red Hat, Inc.
+# Copyright (C) 2012-2013 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
@@ -27,8 +27,10 @@ import re
import os
import tempfile
import shutil
+import ntplib
+import socket
-from pyanaconda import iutil
+from pyanaconda import isys
from pyanaconda.threads import threadMgr, AnacondaThread
from pyanaconda.constants import THREAD_SYNC_TIME_BASENAME
@@ -44,19 +46,25 @@ class NTPconfigError(Exception):
def ntp_server_working(server):
"""
- Runs ntpdate to try to connect to the $server (timeout may take some time).
+ Tries to do an NTP request to the $server (timeout may take some time).
+ :param server: hostname or IP address of an NTP server
+ :type server: string
:return: True if the given server is reachable and working, False otherwise
+ :rtype: bool
"""
- #FIXME: It would be nice to use execWithRedirect here, but it is not
- # thread-safe and hangs if this function is called from threads.
- # By using tee (and block-buffered pipes) it is also much slower.
- #we just need to know the exit status
- retc = os.system("ntpdate -q %s &>/dev/null" % server)
+ client = ntplib.NTPClient()
- return retc == 0
+ try:
+ client.request(server)
+ except ntplib.NTPException:
+ return False
+ except socket.gaierror:
+ return False
+
+ return True
def get_servers_from_config(conf_file_path=NTP_CONFIG_FILE,
srv_regexp=SRV_LINE_REGEXP):
@@ -164,9 +172,15 @@ def one_time_sync(server, callback=None):
"""
- ret = iutil.execWithRedirect("ntpdate", [server])
-
- success = ret == 0
+ client = ntplib.NTPClient()
+ try:
+ results = client.request(server)
+ isys.set_system_time(int(results.tx_time))
+ success = True
+ except ntplib.NTPException:
+ success = False
+ except socket.gaierror:
+ success = False
if callback is not None:
callback(success)
--
1.7.11.7
More information about the anaconda-patches
mailing list