diff options
| author | Sebastien Bacher <seb128@ubuntu.com> | 2019-05-10 15:07:08 +0200 |
|---|---|---|
| committer | Sebastien Bacher <seb128@ubuntu.com> | 2019-05-22 13:41:30 +0200 |
| commit | d57a1dd26f8e9859252b0983c2d2ec3b95eb5714 (patch) | |
| tree | 46f1146e87af8cc7b58b751f7e575bd0abb2f59d /shared/nm-glib-aux/nm-time-utils.c | |
| parent | ad9ed8bfb963266b4eea524131845f406cfc55d7 (diff) | |
| parent | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff) | |
Import Debian changes 1.18.0-1ubuntu1
network-manager (1.18.0-1ubuntu1) eoan; urgency=medium
* Update to 1.18, merge on Debian, new version includes nwe support for
policy routing rules and for VLAN filtering for Linux bridge.
* Remaining Ubuntu changes
- Use systemd-resolved instead of dnsmasq
- debian/control:
+ Depend on isc-dhcp-client instead of recommends
+ Recommend network-manager-pptp
+ Suggest avahi-autoipd for IPv4LL support
- debian/rules, debian/network-manager.postinst:
+ Don't restart NetworkManager on upgrade but recommend restarting
the computer
- debian/rules, debian/network-manager.postinst:
+ Don't install sysvinit scripts or migrate from sysvinit
- debian/network-manager.postinst:
+ Don't add the netdev group.
+ drop in an empty override file for NetworkManager to manage all
devices for upgrade from any version, as long as there is no
netplan configuration yet.
- debian/default-wifi-powersave-on.conf, debian/rules:
+ Install a config file to enable WiFi powersave
- Enable build tests
- Add autopkgtests
- debian/source_network-manager.py, debian/network-manager.install,
debian/network-manager.links: Add apport hook
- Add network-manager-config-connectivity-ubuntu package
- NetworkManager.conf: disable MAC randomization feature. There is no
easy way for desktop users to disable this feature yet. And there are
reports that it doesn't work well with some systems.
- Update Vcs links to point to Ubuntu branch
- Add patches. See patch descriptions for more details:
+ Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+ Update-dnsmasq-parameters.patch
+ Disable-general-with-expect.patch
+ libnm-Check-self-still-NMManager-or-not.patch
+ dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+ Read-system-connections-from-run.patch
- debian/tests/urfkill-integration - don't stop/start network manager
- Revert "Add Conflicts to network-manager-dev against deprecated libraries"
This reverts commit b4acc5e03e2b821e1cccc69529bb70826c741942. We're still
building libnm-glib for now, so these packages have a use in Ubuntu.
* Removed delta, not needed anymore
- debian/network-manager.maintscript
+ Remove /etc/dbus-1/system.d/nm-ofono.conf
Diffstat (limited to 'shared/nm-glib-aux/nm-time-utils.c')
| -rw-r--r-- | shared/nm-glib-aux/nm-time-utils.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/shared/nm-glib-aux/nm-time-utils.c b/shared/nm-glib-aux/nm-time-utils.c new file mode 100644 index 00000000..ae526c34 --- /dev/null +++ b/shared/nm-glib-aux/nm-time-utils.c @@ -0,0 +1,273 @@ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2018 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-time-utils.h" + +/*****************************************************************************/ + +typedef struct { + /* the offset to the native clock, in seconds. */ + gint64 offset_sec; + clockid_t clk_id; +} GlobalState; + +static const GlobalState *volatile p_global_state; + +static const GlobalState * +_t_init_global_state (void) +{ + static GlobalState global_state = { }; + static gsize init_once = 0; + const GlobalState *p; + clockid_t clk_id; + struct timespec tp; + gint64 offset_sec; + int r; + + clk_id = CLOCK_BOOTTIME; + r = clock_gettime (clk_id, &tp); + if (r == -1 && errno == EINVAL) { + clk_id = CLOCK_MONOTONIC; + r = clock_gettime (clk_id, &tp); + } + + /* The only failure we tolerate is that CLOCK_BOOTTIME is not supported. + * Other than that, we rely on kernel to not fail on this. */ + g_assert (r == 0); + g_assert (tp.tv_nsec >= 0 && tp.tv_nsec < NM_UTILS_NS_PER_SECOND); + + /* Calculate an offset for the time stamp. + * + * We always want positive values, because then we can initialize + * a timestamp with 0 and be sure, that it will be less then any + * value nm_utils_get_monotonic_timestamp_*() might return. + * For this to be true also for nm_utils_get_monotonic_timestamp_s() at + * early boot, we have to shift the timestamp to start counting at + * least from 1 second onward. + * + * Another advantage of shifting is, that this way we make use of the whole 31 bit + * range of signed int, before the time stamp for nm_utils_get_monotonic_timestamp_s() + * wraps (~68 years). + **/ + offset_sec = (- ((gint64) tp.tv_sec)) + 1; + + if (!g_once_init_enter (&init_once)) { + /* there was a race. We expect the pointer to be fully initialized now. */ + p = g_atomic_pointer_get (&p_global_state); + g_assert (p); + return p; + } + + global_state.offset_sec = offset_sec; + global_state.clk_id = clk_id; + p = &global_state; + g_atomic_pointer_set (&p_global_state, p); + g_once_init_leave (&init_once, 1); + + _nm_utils_monotonic_timestamp_initialized (&tp, + p->offset_sec, + p->clk_id == CLOCK_BOOTTIME); + + return p; +} + +#define _t_get_global_state() \ + ({ \ + const GlobalState *_p; \ + \ + _p = g_atomic_pointer_get (&p_global_state); \ + (G_LIKELY (_p) ? _p : _t_init_global_state ()); \ + }) + +#define _t_clock_gettime_eval(p, tp) \ + ({ \ + struct timespec *const _tp = (tp); \ + const GlobalState *const _p2 = (p); \ + int _r; \ + \ + nm_assert (_tp); \ + \ + _r = clock_gettime (_p2->clk_id, _tp); \ + \ + nm_assert (_r == 0); \ + nm_assert (_tp->tv_nsec >= 0 && _tp->tv_nsec < NM_UTILS_NS_PER_SECOND); \ + \ + _p2; \ + }) + +#define _t_clock_gettime(tp) \ + _t_clock_gettime_eval (_t_get_global_state (), tp); + +/*****************************************************************************/ + +/** + * nm_utils_get_monotonic_timestamp_ns: + * + * Returns: a monotonically increasing time stamp in nanoseconds, + * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. + * + * The returned value will start counting at an undefined point + * in the past and will always be positive. + * + * All the nm_utils_get_monotonic_timestamp_*s functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint64 +nm_utils_get_monotonic_timestamp_ns (void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime (&tp); + + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * NM_UTILS_NS_PER_SECOND + + tp.tv_nsec; +} + +/** + * nm_utils_get_monotonic_timestamp_us: + * + * Returns: a monotonically increasing time stamp in microseconds, + * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. + * + * The returned value will start counting at an undefined point + * in the past and will always be positive. + * + * All the nm_utils_get_monotonic_timestamp_*s functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint64 +nm_utils_get_monotonic_timestamp_us (void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime (&tp); + + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) G_USEC_PER_SEC) + + (tp.tv_nsec / (NM_UTILS_NS_PER_SECOND/G_USEC_PER_SEC)); +} + +/** + * nm_utils_get_monotonic_timestamp_ms: + * + * Returns: a monotonically increasing time stamp in milliseconds, + * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. + * + * The returned value will start counting at an undefined point + * in the past and will always be positive. + * + * All the nm_utils_get_monotonic_timestamp_*s functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint64 +nm_utils_get_monotonic_timestamp_ms (void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime (&tp); + + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) 1000) + + (tp.tv_nsec / (NM_UTILS_NS_PER_SECOND/1000)); +} + +/** + * nm_utils_get_monotonic_timestamp_s: + * + * Returns: nm_utils_get_monotonic_timestamp_ms() in seconds (throwing + * away sub second parts). The returned value will always be positive. + * + * This value wraps after roughly 68 years which should be fine for any + * practical purpose. + * + * All the nm_utils_get_monotonic_timestamp_*s functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint32 +nm_utils_get_monotonic_timestamp_s (void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime (&tp); + + return (((gint64) tp.tv_sec) + p->offset_sec); +} + +/** + * nm_utils_monotonic_timestamp_as_boottime: + * @timestamp: the monotonic-timestamp that should be converted into CLOCK_BOOTTIME. + * @timestamp_ns_per_tick: How many nano seconds make one unit of @timestamp? E.g. if + * @timestamp is in unit seconds, pass %NM_UTILS_NS_PER_SECOND; @timestamp in nano + * seconds, pass 1; @timestamp in milli seconds, pass %NM_UTILS_NS_PER_SECOND/1000; etc. + * + * Returns: the monotonic-timestamp as CLOCK_BOOTTIME, as returned by clock_gettime(). + * The unit is the same as the passed in @timestamp basd on @timestamp_ns_per_tick. + * E.g. if you passed @timestamp in as seconds, it will return boottime in seconds. + * If @timestamp is a non-positive, it returns -1. Note that a (valid) monotonic-timestamp + * is always positive. + * + * On older kernels that don't support CLOCK_BOOTTIME, the returned time is instead CLOCK_MONOTONIC. + **/ +gint64 +nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timestamp_ns_per_tick) +{ + const GlobalState *p; + gint64 offset; + + /* only support ns-per-tick being a multiple of 10. */ + g_return_val_if_fail (timestamp_ns_per_tick == 1 + || (timestamp_ns_per_tick > 0 && + timestamp_ns_per_tick <= NM_UTILS_NS_PER_SECOND && + timestamp_ns_per_tick % 10 == 0), + -1); + + /* Check that the timestamp is in a valid range. */ + g_return_val_if_fail (timestamp >= 0, -1); + + /* if the caller didn't yet ever fetch a monotonic-timestamp, he cannot pass any meaningful + * value (because he has no idea what these timestamps would be). That would be a bug. */ + nm_assert (g_atomic_pointer_get (&p_global_state)); + + p = _t_get_global_state (); + + /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ + offset = p->offset_sec * (NM_UTILS_NS_PER_SECOND / timestamp_ns_per_tick); + + /* check for overflow. */ + g_return_val_if_fail (offset > 0 || timestamp < G_MAXINT64 + offset, G_MAXINT64); + + return timestamp - offset; +} |