1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,114 @@ |
0 |
+From 4ebd0c4191c6073cc8a7c5fdcf1d182c4719bcbb Mon Sep 17 00:00:00 2001 |
|
1 |
+From: Aurelien Jarno <aurelien@aurel32.net> |
|
2 |
+Date: Sat, 30 Dec 2017 10:54:23 +0100 |
|
3 |
+Subject: [PATCH] elf: Check for empty tokens before dynamic string token |
|
4 |
+ expansion [BZ #22625] |
|
5 |
+ |
|
6 |
+The fillin_rpath function in elf/dl-load.c loops over each RPATH or |
|
7 |
+RUNPATH tokens and interprets empty tokens as the current directory |
|
8 |
+("./"). In practice the check for empty token is done *after* the |
|
9 |
+dynamic string token expansion. The expansion process can return an |
|
10 |
+empty string for the $ORIGIN token if __libc_enable_secure is set |
|
11 |
+or if the path of the binary can not be determined (/proc not mounted). |
|
12 |
+ |
|
13 |
+Fix that by moving the check for empty tokens before the dynamic string |
|
14 |
+token expansion. In addition, check for NULL pointer or empty strings |
|
15 |
+return by expand_dynamic_string_token. |
|
16 |
+ |
|
17 |
+The above changes highlighted a bug in decompose_rpath, an empty array |
|
18 |
+is represented by the first element being NULL at the fillin_rpath |
|
19 |
+level, but by using a -1 pointer in decompose_rpath and other functions. |
|
20 |
+ |
|
21 |
+Changelog: |
|
22 |
+ [BZ #22625] |
|
23 |
+ * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic |
|
24 |
+ string token expansion. Check for NULL pointer or empty string possibly |
|
25 |
+ returned by expand_dynamic_string_token. |
|
26 |
+ (decompose_rpath): Check for empty path after dynamic string |
|
27 |
+ token expansion. |
|
28 |
+(cherry picked from commit 3e3c904daef69b8bf7d5cc07f793c9f07c3553ef) |
|
29 |
+--- |
|
30 |
+ ChangeLog | 10 ++++++++++ |
|
31 |
+ NEWS | 4 ++++ |
|
32 |
+ elf/dl-load.c | 49 +++++++++++++++++++++++++++++++++---------------- |
|
33 |
+ 3 files changed, 47 insertions(+), 16 deletions(-) |
|
34 |
+ |
|
35 |
+diff --git a/elf/dl-load.c b/elf/dl-load.c |
|
36 |
+index 50996e2..7397c18 100644 |
|
37 |
+--- a/elf/dl-load.c |
|
38 |
+@@ -434,31 +434,40 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, |
|
39 |
+ { |
|
40 |
+ char *cp; |
|
41 |
+ size_t nelems = 0; |
|
42 |
+- char *to_free; |
|
43 |
+ |
|
44 |
+ while ((cp = __strsep (&rpath, sep)) != NULL) |
|
45 |
+ { |
|
46 |
+ struct r_search_path_elem *dirp; |
|
47 |
++ char *to_free = NULL; |
|
48 |
++ size_t len = 0; |
|
49 |
+ |
|
50 |
+- to_free = cp = expand_dynamic_string_token (l, cp, 1); |
|
51 |
++ /* `strsep' can pass an empty string. */ |
|
52 |
++ if (*cp != '\0') |
|
53 |
++ { |
|
54 |
++ to_free = cp = expand_dynamic_string_token (l, cp, 1); |
|
55 |
+ |
|
56 |
+- size_t len = strlen (cp); |
|
57 |
++ /* expand_dynamic_string_token can return NULL in case of empty |
|
58 |
++ path or memory allocation failure. */ |
|
59 |
++ if (cp == NULL) |
|
60 |
++ continue; |
|
61 |
+ |
|
62 |
+- /* `strsep' can pass an empty string. This has to be |
|
63 |
+- interpreted as `use the current directory'. */ |
|
64 |
+- if (len == 0) |
|
65 |
+- { |
|
66 |
+- static const char curwd[] = "./"; |
|
67 |
+- cp = (char *) curwd; |
|
68 |
+- } |
|
69 |
++ /* Compute the length after dynamic string token expansion and |
|
70 |
++ ignore empty paths. */ |
|
71 |
++ len = strlen (cp); |
|
72 |
++ if (len == 0) |
|
73 |
++ { |
|
74 |
++ free (to_free); |
|
75 |
++ continue; |
|
76 |
++ } |
|
77 |
+ |
|
78 |
+- /* Remove trailing slashes (except for "/"). */ |
|
79 |
+- while (len > 1 && cp[len - 1] == '/') |
|
80 |
+- --len; |
|
81 |
++ /* Remove trailing slashes (except for "/"). */ |
|
82 |
++ while (len > 1 && cp[len - 1] == '/') |
|
83 |
++ --len; |
|
84 |
+ |
|
85 |
+- /* Now add one if there is none so far. */ |
|
86 |
+- if (len > 0 && cp[len - 1] != '/') |
|
87 |
+- cp[len++] = '/'; |
|
88 |
++ /* Now add one if there is none so far. */ |
|
89 |
++ if (len > 0 && cp[len - 1] != '/') |
|
90 |
++ cp[len++] = '/'; |
|
91 |
++ } |
|
92 |
+ |
|
93 |
+ /* Make sure we don't use untrusted directories if we run SUID. */ |
|
94 |
+ if (__glibc_unlikely (check_trusted) && !is_trusted_path (cp, len)) |
|
95 |
+@@ -622,6 +631,14 @@ decompose_rpath (struct r_search_path_struct *sps, |
|
96 |
+ necessary. */ |
|
97 |
+ free (copy); |
|
98 |
+ |
|
99 |
++ /* There is no path after expansion. */ |
|
100 |
++ if (result[0] == NULL) |
|
101 |
++ { |
|
102 |
++ free (result); |
|
103 |
++ sps->dirs = (struct r_search_path_elem **) -1; |
|
104 |
++ return false; |
|
105 |
++ } |
|
106 |
++ |
|
107 |
+ sps->dirs = result; |
|
108 |
+ /* The caller will change this value if we haven't used a real malloc. */ |
|
109 |
+ sps->malloced = 1; |
|
110 |
+-- |
|
111 |
+2.9.3 |
|
112 |
+ |
... | ... |
@@ -4,7 +4,7 @@ |
4 | 4 |
Summary: Main C library |
5 | 5 |
Name: glibc |
6 | 6 |
Version: 2.26 |
7 |
-Release: 8%{?dist} |
|
7 |
+Release: 9%{?dist} |
|
8 | 8 |
License: LGPLv2+ |
9 | 9 |
URL: http://www.gnu.org/software/libc |
10 | 10 |
Group: Applications/System |
... | ... |
@@ -21,6 +21,7 @@ Patch3: 0002-malloc-arena-fix.patch |
21 | 21 |
Patch4: glibc-fix-CVE-2017-15670.patch |
22 | 22 |
Patch5: glibc-fix-CVE-2017-15804.patch |
23 | 23 |
Patch6: glibc-fix-CVE-2017-17426.patch |
24 |
+Patch7: glibc-fix-CVE-2017-16997.patch |
|
24 | 25 |
Provides: rtld(GNU_HASH) |
25 | 26 |
Requires: filesystem |
26 | 27 |
%description |
... | ... |
@@ -81,6 +82,7 @@ sed -i 's/\\$$(pwd)/`pwd`/' timezone/Makefile |
81 | 81 |
%patch4 -p1 |
82 | 82 |
%patch5 -p1 |
83 | 83 |
%patch6 -p1 |
84 |
+%patch7 -p1 |
|
84 | 85 |
install -vdm 755 %{_builddir}/%{name}-build |
85 | 86 |
# do not try to explicitly provide GLIBC_PRIVATE versioned libraries |
86 | 87 |
%define __find_provides %{_builddir}/%{name}-%{version}/find_provides.sh |
... | ... |
@@ -285,6 +287,8 @@ grep "^FAIL: nptl/tst-eintr1" tests.sum >/dev/null && n=$((n+1)) ||: |
285 | 285 |
|
286 | 286 |
|
287 | 287 |
%changelog |
288 |
+* Mon Jan 08 2018 Xiaolin Li <xiaolinl@vmware.com> 2.26-9 |
|
289 |
+- Fix CVE-2017-16997 |
|
288 | 290 |
* Thu Dec 21 2017 Xiaolin Li <xiaolinl@vmware.com> 2.26-8 |
289 | 291 |
- Fix CVE-2017-17426 |
290 | 292 |
* Tue Nov 14 2017 Alexey Makhalov <amakhalov@vmware.com> 2.26-7 |
291 | 293 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,65 @@ |
0 |
+%{!?python3_sitelib: %define python3_sitelib %(python3 -c "from distutils.sysconfig import get_python_lib;print(get_python_lib())")} |
|
1 |
+ |
|
2 |
+Name: meson |
|
3 |
+Summary: Extremely fast and user friendly build system |
|
4 |
+Version: 0.44.0 |
|
5 |
+Release: 1%{?dist} |
|
6 |
+License: ASL 2.0 |
|
7 |
+URL: https://mesonbuild.com/ |
|
8 |
+Vendor: VMware, Inc. |
|
9 |
+Distribution: Photon |
|
10 |
+Source0: https://github.com/mesonbuild/meson/archive/%{version}/%{name}-%{version}.tar.gz |
|
11 |
+%define sha1 meson=4a5aa56f81fc1350a5c501ef6046eef8a13467c7 |
|
12 |
+BuildArch: noarch |
|
13 |
+BuildRequires: gcc |
|
14 |
+BuildRequires: python3-devel |
|
15 |
+BuildRequires: python3-libs |
|
16 |
+BuildRequires: python3-setuptools |
|
17 |
+BuildRequires: ninja-build |
|
18 |
+BuildRequires: gtest-devel |
|
19 |
+BuildRequires: gmock-devel |
|
20 |
+BuildRequires: gettext |
|
21 |
+ |
|
22 |
+Requires: ninja-build |
|
23 |
+Requires: python3 |
|
24 |
+ |
|
25 |
+%description |
|
26 |
+Meson is an open source build system meant to be both extremely fast, |
|
27 |
+and, even more importantly, as user friendly as possible. |
|
28 |
+The main design point of Meson is that every moment a developer spends |
|
29 |
+writing or debugging build definitions is a second wasted. |
|
30 |
+So is every second spent waiting for the build system to actually start compiling code. |
|
31 |
+ |
|
32 |
+%prep |
|
33 |
+%setup |
|
34 |
+ |
|
35 |
+%build |
|
36 |
+ |
|
37 |
+%install |
|
38 |
+python3 setup.py install --root=%{buildroot}/ |
|
39 |
+install -Dpm0644 data/macros.%{name} %{buildroot}%{_libdir}/rpm/macros.d/macros.%{name} |
|
40 |
+ |
|
41 |
+%check |
|
42 |
+export MESON_PRINT_TEST_OUTPUT=1 |
|
43 |
+python3 ./run_tests.py |
|
44 |
+ |
|
45 |
+%files |
|
46 |
+%license COPYING |
|
47 |
+%{_bindir}/%{name} |
|
48 |
+%{_bindir}/%{name}conf |
|
49 |
+%{_bindir}/%{name}introspect |
|
50 |
+%{_bindir}/%{name}test |
|
51 |
+%{_bindir}/wraptool |
|
52 |
+%{python3_sitelib}/mesonbuild |
|
53 |
+%{python3_sitelib}/%{name}-*.egg-info |
|
54 |
+%{_mandir}/man1/%{name}.1* |
|
55 |
+%{_mandir}/man1/%{name}conf.1* |
|
56 |
+%{_mandir}/man1/%{name}introspect.1* |
|
57 |
+%{_mandir}/man1/%{name}test.1* |
|
58 |
+%{_mandir}/man1/wraptool.1* |
|
59 |
+%{_libdir}/rpm/macros.d/macros.%{name} |
|
60 |
+ |
|
61 |
+%changelog |
|
62 |
+* Wed Dec 27 2017 Anish Swaminathan <anishs@vmware.com> 0.44.0-1 |
|
63 |
+- Initial packaging |
|
64 |
+ |
0 | 65 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,8 @@ |
0 |
+%__ninja %{_bindir}/ninja |
|
1 |
+%__ninja_common_opts -v %{?_smp_mflags} |
|
2 |
+%ninja_build \ |
|
3 |
+ %{__ninja} %{__ninja_common_opts} |
|
4 |
+%ninja_install \ |
|
5 |
+ DESTDIR=%{buildroot} %{__ninja} install %{__ninja_common_opts} |
|
6 |
+%ninja_test \ |
|
7 |
+ %{__ninja} test %{__ninja_common_opts} |
0 | 8 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,48 @@ |
0 |
+Name: ninja-build |
|
1 |
+Summary: Small build system with focus on speed |
|
2 |
+Version: 1.8.2 |
|
3 |
+Release: 1%{?dist} |
|
4 |
+License: ASL 2.0 |
|
5 |
+URL: https://ninja-build.org |
|
6 |
+Vendor: VMware, Inc. |
|
7 |
+Distribution: Photon |
|
8 |
+Source0: https://github.com/ninja-build/ninja/archive/%{name}-%{version}.tar.gz |
|
9 |
+%define sha1 ninja-build=17219deb34dd816363e37470f77ff7231509143a |
|
10 |
+Source1: macros.ninja |
|
11 |
+BuildRequires: gcc |
|
12 |
+BuildRequires: python3-devel |
|
13 |
+BuildRequires: gtest-devel |
|
14 |
+ |
|
15 |
+%description |
|
16 |
+Ninja is a small build system with a focus on speed. |
|
17 |
+It differs from other build systems in two major respects: |
|
18 |
+it is designed to have its input files generated by a higher-level build system, |
|
19 |
+and it is designed to run builds as fast as possible. |
|
20 |
+ |
|
21 |
+%prep |
|
22 |
+%setup -n ninja-%{version} |
|
23 |
+ |
|
24 |
+%build |
|
25 |
+python3 configure.py --bootstrap --verbose |
|
26 |
+./ninja -v all |
|
27 |
+ |
|
28 |
+%install |
|
29 |
+install -Dpm0755 ninja -t %{buildroot}%{_bindir}/ |
|
30 |
+install -Dpm0644 misc/bash-completion %{buildroot}%{_datadir}/bash-completion/completions/ninja |
|
31 |
+ln -s ninja %{buildroot}%{_bindir}/ninja-build |
|
32 |
+install -Dpm0644 %{SOURCE1} %{buildroot}%{_libdir}/rpm/macros.d/macros.ninja |
|
33 |
+ |
|
34 |
+%check |
|
35 |
+./ninja_test --gtest_filter=-SubprocessTest.SetWithLots |
|
36 |
+ |
|
37 |
+%files |
|
38 |
+%license COPYING |
|
39 |
+%doc HACKING.md README |
|
40 |
+%{_bindir}/ninja |
|
41 |
+%{_bindir}/ninja-build |
|
42 |
+%{_datadir}/bash-completion/completions/ninja |
|
43 |
+%{_libdir}/rpm/macros.d/macros.ninja |
|
44 |
+ |
|
45 |
+%changelog |
|
46 |
+* Wed Dec 27 2017 Anish Swaminathan <anishs@vmware.com> 1.8.2-1 |
|
47 |
+- Initial packaging |
... | ... |
@@ -1,14 +1,14 @@ |
1 | 1 |
Summary: Ruby |
2 | 2 |
Name: ruby |
3 |
-Version: 2.4.2 |
|
3 |
+Version: 2.4.3 |
|
4 | 4 |
Release: 1%{?dist} |
5 | 5 |
License: BSDL |
6 | 6 |
URL: https://www.ruby-lang.org/en/ |
7 | 7 |
Group: System Environment/Security |
8 | 8 |
Vendor: VMware, Inc. |
9 | 9 |
Distribution: Photon |
10 |
-Source0: http://cache.ruby-lang.org/pub/ruby/%{name}-%{version}.tar.xz |
|
11 |
-%define sha1 ruby=8373e32c63bba2180799da091b572664aa9faf6f |
|
10 |
+Source0: http://cache.ruby-lang.org/pub/ruby/2.4/%{name}-%{version}.tar.bz2 |
|
11 |
+%define sha1 ruby=3ca96536320b915762d57fe1ee540df6810bf631 |
|
12 | 12 |
Patch0: ruby-CVE-2017-9224.patch |
13 | 13 |
Patch1: ruby-CVE-2017-9226.patch |
14 | 14 |
Patch2: ruby-CVE-2017-9227.patch |
... | ... |
@@ -63,6 +63,8 @@ rm -rf %{buildroot}/* |
63 | 63 |
%{_docdir}/%{name}-%{version} |
64 | 64 |
%{_mandir}/man1/* |
65 | 65 |
%changelog |
66 |
+* Wed Jan 03 2018 Xiaolin Li <xiaolinl@vmware.com> 2.4.3-1 |
|
67 |
+- Update to version 2.4.3, fix CVE-2017-17405 |
|
66 | 68 |
* Fri Sep 29 2017 Xiaolin Li <xiaolinl@vmware.com> 2.4.2-1 |
67 | 69 |
- Update to version 2.4.2 |
68 | 70 |
* Fri Sep 15 2017 Xiaolin Li <xiaolinl@vmware.com> 2.4.1-5 |
... | ... |
@@ -1,28 +1,18 @@ |
1 |
-diff -Naur a/Makefile.am b/Makefile.am |
|
2 |
-+++ b/Makefile.am 2016-08-29 13:42:31.472636829 -0700 |
|
3 |
-@@ -309,7 +309,7 @@ |
|
4 |
- set -- $(USER_UNIT_ALIASES) && \ |
|
5 |
- dir=$(userunitdir) && $(install-relative-aliases) |
|
6 |
- set -- $(GENERAL_ALIASES) && \ |
|
7 |
-- dir= && $(install-relative-aliases) |
|
8 |
-+ dir= && $(install-general-aliases) |
|
1 |
+diff -rup systemd-236/units/meson-add-wants.sh systemd-236-new/units/meson-add-wants.sh |
|
2 |
+--- systemd-236/units/meson-add-wants.sh 2017-12-14 14:09:57.000000000 -0800 |
|
3 |
+@@ -13,8 +13,6 @@ case "$target" in |
|
4 |
+ ;; |
|
5 |
+ esac |
|
9 | 6 |
|
10 |
- define install-aliases |
|
11 |
- while [ -n "$$1" ]; do \ |
|
12 |
-@@ -328,6 +328,15 @@ |
|
13 |
- shift 2 || exit $$?; \ |
|
14 |
- done |
|
15 |
- endef |
|
16 |
-+ |
|
17 |
-+define install-general-aliases |
|
18 |
-+ while [ -n "$$1" ]; do \ |
|
19 |
-+ $(MKDIR_P) `dirname $(DESTDIR)$$dir/$$2` && \ |
|
20 |
-+ rm -f $(DESTDIR)$$dir/$$2 && \ |
|
21 |
-+ $(LN_S) /usr$$1 $(DESTDIR)$$dir/$$2 && \ |
|
22 |
-+ shift 2 || exit $$?; \ |
|
23 |
-+ done |
|
24 |
-+endef |
|
7 |
+-unitpath="${DESTDIR:-}${unitdir}/${unit}" |
|
8 |
+- |
|
9 |
+ case "$target" in |
|
10 |
+ */) |
|
11 |
+ mkdir -p -m 0755 "$dir" |
|
12 |
+@@ -24,4 +22,4 @@ case "$target" in |
|
13 |
+ ;; |
|
14 |
+ esac |
|
25 | 15 |
|
26 |
- install-touch-usr-hook: |
|
27 |
- touch -c $(DESTDIR)/$(prefix) |
|
16 |
+-ln -vfs --relative "$unitpath" "$dir" |
|
17 |
++ln -vfs "${unitdir}/${unit}" "$dir" |
28 | 18 |
deleted file mode 100644 |
... | ... |
@@ -1,36 +0,0 @@ |
1 |
-From 9f939335a07085aa9a9663efd1dca06ef6405d62 Mon Sep 17 00:00:00 2001 |
|
2 |
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> |
|
3 |
-Date: Wed, 25 Oct 2017 11:19:19 +0200 |
|
4 |
-Subject: [PATCH] resolved: fix loop on packets with pseudo dns types |
|
5 |
- |
|
6 |
-Reported by Karim Hossen & Thomas Imbert from Sogeti ESEC R&D. |
|
7 |
- |
|
8 |
-https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1725351 |
|
9 |
- src/resolve/resolved-dns-packet.c | 6 +----- |
|
10 |
- 1 file changed, 1 insertion(+), 5 deletions(-) |
|
11 |
- |
|
12 |
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c |
|
13 |
-index e2f227bfc6..35f4d0689b 100644 |
|
14 |
-+++ b/src/resolve/resolved-dns-packet.c |
|
15 |
-@@ -1514,7 +1514,7 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta |
|
16 |
- |
|
17 |
- found = true; |
|
18 |
- |
|
19 |
-- while (bitmask) { |
|
20 |
-+ for (; bitmask; bit++, bitmask >>= 1) |
|
21 |
- if (bitmap[i] & bitmask) { |
|
22 |
- uint16_t n; |
|
23 |
- |
|
24 |
-@@ -1528,10 +1528,6 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta |
|
25 |
- if (r < 0) |
|
26 |
- return r; |
|
27 |
- } |
|
28 |
-- |
|
29 |
-- bit++; |
|
30 |
-- bitmask >>= 1; |
|
31 |
-- } |
|
32 |
- } |
|
33 |
- |
|
34 |
- if (!found) |
35 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,305 +0,0 @@ |
1 |
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c |
|
2 |
-index 6a6dadda2b..49a5c53f96 100644 |
|
3 |
-+++ b/src/core/load-fragment.c |
|
4 |
-@@ -636,26 +636,36 @@ int config_parse_exec( |
|
5 |
- |
|
6 |
- r = unit_full_printf(u, f, &path); |
|
7 |
- if (r < 0) { |
|
8 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f); |
|
9 |
-- return 0; |
|
10 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
11 |
-+ "Failed to resolve unit specifiers on %s%s: %m", |
|
12 |
-+ f, ignore ? ", ignoring" : ""); |
|
13 |
-+ return ignore ? 0 : -ENOEXEC; |
|
14 |
- } |
|
15 |
- |
|
16 |
- if (isempty(path)) { |
|
17 |
- /* First word is either "-" or "@" with no command. */ |
|
18 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue); |
|
19 |
-- return 0; |
|
20 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
21 |
-+ "Empty path in command line%s: \"%s\"", |
|
22 |
-+ ignore ? ", ignoring" : "", rvalue); |
|
23 |
-+ return ignore ? 0 : -ENOEXEC; |
|
24 |
- } |
|
25 |
- if (!string_is_safe(path)) { |
|
26 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue); |
|
27 |
-- return 0; |
|
28 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
29 |
-+ "Executable path contains special characters%s: %s", |
|
30 |
-+ ignore ? ", ignoring" : "", rvalue); |
|
31 |
-+ return ignore ? 0 : -ENOEXEC; |
|
32 |
- } |
|
33 |
- if (!path_is_absolute(path)) { |
|
34 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue); |
|
35 |
-- return 0; |
|
36 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
37 |
-+ "Executable path is not absolute%s: %s", |
|
38 |
-+ ignore ? ", ignoring" : "", rvalue); |
|
39 |
-+ return ignore ? 0 : -ENOEXEC; |
|
40 |
- } |
|
41 |
- if (endswith(path, "/")) { |
|
42 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue); |
|
43 |
-- return 0; |
|
44 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
45 |
-+ "Executable path specifies a directory%s: %s", |
|
46 |
-+ ignore ? ", ignoring" : "", rvalue); |
|
47 |
-+ return ignore ? 0 : -ENOEXEC; |
|
48 |
- } |
|
49 |
- |
|
50 |
- if (!separate_argv0) { |
|
51 |
-@@ -708,12 +718,14 @@ int config_parse_exec( |
|
52 |
- if (r == 0) |
|
53 |
- break; |
|
54 |
- if (r < 0) |
|
55 |
-- return 0; |
|
56 |
-+ return ignore ? 0 : -ENOEXEC; |
|
57 |
- |
|
58 |
- r = unit_full_printf(u, word, &resolved); |
|
59 |
- if (r < 0) { |
|
60 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word); |
|
61 |
-- return 0; |
|
62 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
63 |
-+ "Failed to resolve unit specifiers on %s%s: %m", |
|
64 |
-+ word, ignore ? ", ignoring" : ""); |
|
65 |
-+ return ignore ? 0 : -ENOEXEC; |
|
66 |
- } |
|
67 |
- |
|
68 |
- if (!GREEDY_REALLOC(n, nbufsize, nlen + 2)) |
|
69 |
-@@ -724,8 +736,10 @@ int config_parse_exec( |
|
70 |
- } |
|
71 |
- |
|
72 |
- if (!n || !n[0]) { |
|
73 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Empty executable name or zeroeth argument, ignoring: %s", rvalue); |
|
74 |
-- return 0; |
|
75 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
76 |
-+ "Empty executable name or zeroeth argument%s: %s", |
|
77 |
-+ ignore ? ", ignoring" : "", rvalue); |
|
78 |
-+ return ignore ? 0 : -ENOEXEC; |
|
79 |
- } |
|
80 |
- |
|
81 |
- nce = new0(ExecCommand, 1); |
|
82 |
-@@ -1332,8 +1346,10 @@ int config_parse_exec_selinux_context( |
|
83 |
- |
|
84 |
- r = unit_full_printf(u, rvalue, &k); |
|
85 |
- if (r < 0) { |
|
86 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); |
|
87 |
-- return 0; |
|
88 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
89 |
-+ "Failed to resolve specifiers%s: %m", |
|
90 |
-+ ignore ? ", ignoring" : ""); |
|
91 |
-+ return ignore ? 0 : -ENOEXEC; |
|
92 |
- } |
|
93 |
- |
|
94 |
- free(c->selinux_context); |
|
95 |
-@@ -1380,8 +1396,10 @@ int config_parse_exec_apparmor_profile( |
|
96 |
- |
|
97 |
- r = unit_full_printf(u, rvalue, &k); |
|
98 |
- if (r < 0) { |
|
99 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); |
|
100 |
-- return 0; |
|
101 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
102 |
-+ "Failed to resolve specifiers%s: %m", |
|
103 |
-+ ignore ? ", ignoring" : ""); |
|
104 |
-+ return ignore ? 0 : -ENOEXEC; |
|
105 |
- } |
|
106 |
- |
|
107 |
- free(c->apparmor_profile); |
|
108 |
-@@ -1428,8 +1446,10 @@ int config_parse_exec_smack_process_label( |
|
109 |
- |
|
110 |
- r = unit_full_printf(u, rvalue, &k); |
|
111 |
- if (r < 0) { |
|
112 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); |
|
113 |
-- return 0; |
|
114 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
115 |
-+ "Failed to resolve specifiers%s: %m", |
|
116 |
-+ ignore ? ", ignoring" : ""); |
|
117 |
-+ return ignore ? 0 : -ENOEXEC; |
|
118 |
- } |
|
119 |
- |
|
120 |
- free(c->smack_process_label); |
|
121 |
-@@ -1647,19 +1667,19 @@ int config_parse_socket_service( |
|
122 |
- |
|
123 |
- r = unit_name_printf(UNIT(s), rvalue, &p); |
|
124 |
- if (r < 0) { |
|
125 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); |
|
126 |
-- return 0; |
|
127 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", rvalue); |
|
128 |
-+ return -ENOEXEC; |
|
129 |
- } |
|
130 |
- |
|
131 |
- if (!endswith(p, ".service")) { |
|
132 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue); |
|
133 |
-- return 0; |
|
134 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service: %s", rvalue); |
|
135 |
-+ return -ENOEXEC; |
|
136 |
- } |
|
137 |
- |
|
138 |
- r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x); |
|
139 |
- if (r < 0) { |
|
140 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r)); |
|
141 |
-- return 0; |
|
142 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s: %s", rvalue, bus_error_message(&error, r)); |
|
143 |
-+ return -ENOEXEC; |
|
144 |
- } |
|
145 |
- |
|
146 |
- unit_ref_set(&s->service, x); |
|
147 |
-@@ -1907,13 +1927,13 @@ int config_parse_user_group( |
|
148 |
- |
|
149 |
- r = unit_full_printf(u, rvalue, &k); |
|
150 |
- if (r < 0) { |
|
151 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue); |
|
152 |
-- return 0; |
|
153 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue); |
|
154 |
-+ return -ENOEXEC; |
|
155 |
- } |
|
156 |
- |
|
157 |
- if (!valid_user_group_name_or_id(k)) { |
|
158 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k); |
|
159 |
-- return 0; |
|
160 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k); |
|
161 |
-+ return -ENOEXEC; |
|
162 |
- } |
|
163 |
- |
|
164 |
- n = k; |
|
165 |
-@@ -1971,19 +1991,19 @@ int config_parse_user_group_strv( |
|
166 |
- if (r == -ENOMEM) |
|
167 |
- return log_oom(); |
|
168 |
- if (r < 0) { |
|
169 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); |
|
170 |
-- break; |
|
171 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax: %s", rvalue); |
|
172 |
-+ return -ENOEXEC; |
|
173 |
- } |
|
174 |
- |
|
175 |
- r = unit_full_printf(u, word, &k); |
|
176 |
- if (r < 0) { |
|
177 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", word); |
|
178 |
-- continue; |
|
179 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", word); |
|
180 |
-+ return -ENOEXEC; |
|
181 |
- } |
|
182 |
- |
|
183 |
- if (!valid_user_group_name_or_id(k)) { |
|
184 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k); |
|
185 |
-- continue; |
|
186 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k); |
|
187 |
-+ return -ENOEXEC; |
|
188 |
- } |
|
189 |
- |
|
190 |
- r = strv_push(users, k); |
|
191 |
-@@ -2142,25 +2162,28 @@ int config_parse_working_directory( |
|
192 |
- |
|
193 |
- r = unit_full_printf(u, rvalue, &k); |
|
194 |
- if (r < 0) { |
|
195 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue); |
|
196 |
-- return 0; |
|
197 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
198 |
-+ "Failed to resolve unit specifiers in working directory path '%s'%s: %m", |
|
199 |
-+ rvalue, missing_ok ? ", ignoring" : ""); |
|
200 |
-+ return missing_ok ? 0 : -ENOEXEC; |
|
201 |
- } |
|
202 |
- |
|
203 |
- path_kill_slashes(k); |
|
204 |
- |
|
205 |
- if (!utf8_is_valid(k)) { |
|
206 |
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue); |
|
207 |
-- return 0; |
|
208 |
-+ return missing_ok ? 0 : -ENOEXEC; |
|
209 |
- } |
|
210 |
- |
|
211 |
- if (!path_is_absolute(k)) { |
|
212 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue); |
|
213 |
-- return 0; |
|
214 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
215 |
-+ "Working directory path '%s' is not absolute%s.", |
|
216 |
-+ rvalue, missing_ok ? ", ignoring" : ""); |
|
217 |
-+ return missing_ok ? 0 : -ENOEXEC; |
|
218 |
- } |
|
219 |
- |
|
220 |
-- free_and_replace(c->working_directory, k); |
|
221 |
-- |
|
222 |
- c->working_directory_home = false; |
|
223 |
-+ free_and_replace(c->working_directory, k); |
|
224 |
- } |
|
225 |
- |
|
226 |
- c->working_directory_missing_ok = missing_ok; |
|
227 |
-@@ -4456,8 +4479,11 @@ int unit_load_fragment(Unit *u) { |
|
228 |
- return r; |
|
229 |
- |
|
230 |
- r = load_from_path(u, k); |
|
231 |
-- if (r < 0) |
|
232 |
-+ if (r < 0) { |
|
233 |
-+ if (r == -ENOEXEC) |
|
234 |
-+ log_unit_notice(u, "Unit configuration has fatal error, unit will not be started."); |
|
235 |
- return r; |
|
236 |
-+ } |
|
237 |
- |
|
238 |
- if (u->load_state == UNIT_STUB) { |
|
239 |
- SET_FOREACH(t, u->names, i) { |
|
240 |
-diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c |
|
241 |
-index 12f48bf435..fd797b587e 100644 |
|
242 |
-+++ b/src/test/test-unit-file.c |
|
243 |
-@@ -146,7 +146,7 @@ static void test_config_parse_exec(void) { |
|
244 |
- r = config_parse_exec(NULL, "fake", 4, "section", 1, |
|
245 |
- "LValue", 0, "/RValue/ argv0 r1", |
|
246 |
- &c, u); |
|
247 |
-- assert_se(r == 0); |
|
248 |
-+ assert_se(r == -ENOEXEC); |
|
249 |
- assert_se(c1->command_next == NULL); |
|
250 |
- |
|
251 |
- log_info("/* honour_argv0 */"); |
|
252 |
-@@ -161,7 +161,7 @@ static void test_config_parse_exec(void) { |
|
253 |
- r = config_parse_exec(NULL, "fake", 3, "section", 1, |
|
254 |
- "LValue", 0, "@/RValue", |
|
255 |
- &c, u); |
|
256 |
-- assert_se(r == 0); |
|
257 |
-+ assert_se(r == -ENOEXEC); |
|
258 |
- assert_se(c1->command_next == NULL); |
|
259 |
- |
|
260 |
- log_info("/* no command, whitespace only, reset */"); |
|
261 |
-@@ -220,7 +220,7 @@ static void test_config_parse_exec(void) { |
|
262 |
- "-@/RValue argv0 r1 ; ; " |
|
263 |
- "/goo/goo boo", |
|
264 |
- &c, u); |
|
265 |
-- assert_se(r >= 0); |
|
266 |
-+ assert_se(r == -ENOEXEC); |
|
267 |
- c1 = c1->command_next; |
|
268 |
- check_execcommand(c1, "/RValue", "argv0", "r1", NULL, true); |
|
269 |
- |
|
270 |
-@@ -374,7 +374,7 @@ static void test_config_parse_exec(void) { |
|
271 |
- r = config_parse_exec(NULL, "fake", 4, "section", 1, |
|
272 |
- "LValue", 0, path, |
|
273 |
- &c, u); |
|
274 |
-- assert_se(r == 0); |
|
275 |
-+ assert_se(r == -ENOEXEC); |
|
276 |
- assert_se(c1->command_next == NULL); |
|
277 |
- } |
|
278 |
- |
|
279 |
-@@ -401,21 +401,21 @@ static void test_config_parse_exec(void) { |
|
280 |
- r = config_parse_exec(NULL, "fake", 4, "section", 1, |
|
281 |
- "LValue", 0, "/path\\", |
|
282 |
- &c, u); |
|
283 |
-- assert_se(r == 0); |
|
284 |
-+ assert_se(r == -ENOEXEC); |
|
285 |
- assert_se(c1->command_next == NULL); |
|
286 |
- |
|
287 |
- log_info("/* missing ending ' */"); |
|
288 |
- r = config_parse_exec(NULL, "fake", 4, "section", 1, |
|
289 |
- "LValue", 0, "/path 'foo", |
|
290 |
- &c, u); |
|
291 |
-- assert_se(r == 0); |
|
292 |
-+ assert_se(r == -ENOEXEC); |
|
293 |
- assert_se(c1->command_next == NULL); |
|
294 |
- |
|
295 |
- log_info("/* missing ending ' with trailing backslash */"); |
|
296 |
- r = config_parse_exec(NULL, "fake", 4, "section", 1, |
|
297 |
- "LValue", 0, "/path 'foo\\", |
|
298 |
- &c, u); |
|
299 |
-- assert_se(r == 0); |
|
300 |
-+ assert_se(r == -ENOEXEC); |
|
301 |
- assert_se(c1->command_next == NULL); |
|
302 |
- |
|
303 |
- log_info("/* invalid space between modifiers */"); |
304 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,100 +0,0 @@ |
1 |
-diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 |
|
2 |
-index c43b7885be..5b5a86250e 100644 |
|
3 |
-+++ b/src/core/load-fragment-gperf.gperf.m4 |
|
4 |
-@@ -18,8 +18,8 @@ struct ConfigPerfItem; |
|
5 |
- m4_dnl Define the context options only once |
|
6 |
- m4_define(`EXEC_CONTEXT_CONFIG_ITEMS', |
|
7 |
- `$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context) |
|
8 |
--$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory) |
|
9 |
--$1.RootImage, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_image) |
|
10 |
-+$1.RootDirectory, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_directory) |
|
11 |
-+$1.RootImage, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_image) |
|
12 |
- $1.User, config_parse_user_group, 0, offsetof($1, exec_context.user) |
|
13 |
- $1.Group, config_parse_user_group, 0, offsetof($1, exec_context.group) |
|
14 |
- $1.SupplementaryGroups, config_parse_user_group_strv, 0, offsetof($1, exec_context.supplementary_groups) |
|
15 |
-@@ -35,7 +35,7 @@ $1.UMask, config_parse_mode, 0, |
|
16 |
- $1.Environment, config_parse_environ, 0, offsetof($1, exec_context.environment) |
|
17 |
- $1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files) |
|
18 |
- $1.PassEnvironment, config_parse_pass_environ, 0, offsetof($1, exec_context.pass_environment) |
|
19 |
--$1.DynamicUser, config_parse_bool, 0, offsetof($1, exec_context.dynamic_user) |
|
20 |
-+$1.DynamicUser, config_parse_bool, true, offsetof($1, exec_context.dynamic_user) |
|
21 |
- $1.StandardInput, config_parse_exec_input, 0, offsetof($1, exec_context) |
|
22 |
- $1.StandardOutput, config_parse_exec_output, 0, offsetof($1, exec_context) |
|
23 |
- $1.StandardError, config_parse_exec_output, 0, offsetof($1, exec_context) |
|
24 |
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c |
|
25 |
-index 49a5c53f96..9d5c39b3dd 100644 |
|
26 |
-+++ b/src/core/load-fragment.c |
|
27 |
-@@ -242,6 +242,7 @@ int config_parse_unit_path_printf( |
|
28 |
- _cleanup_free_ char *k = NULL; |
|
29 |
- Unit *u = userdata; |
|
30 |
- int r; |
|
31 |
-+ bool fatal = ltype; |
|
32 |
- |
|
33 |
- assert(filename); |
|
34 |
- assert(lvalue); |
|
35 |
-@@ -250,8 +251,10 @@ int config_parse_unit_path_printf( |
|
36 |
- |
|
37 |
- r = unit_full_printf(u, rvalue, &k); |
|
38 |
- if (r < 0) { |
|
39 |
-- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue); |
|
40 |
-- return 0; |
|
41 |
-+ log_syntax(unit, LOG_ERR, filename, line, r, |
|
42 |
-+ "Failed to resolve unit specifiers on %s%s: %m", |
|
43 |
-+ fatal ? "" : ", ignoring", rvalue); |
|
44 |
-+ return fatal ? -ENOEXEC : 0; |
|
45 |
- } |
|
46 |
- |
|
47 |
- return config_parse_path(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata); |
|
48 |
-diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c |
|
49 |
-index 44df7493e2..e08402e3d2 100644 |
|
50 |
-+++ b/src/shared/conf-parser.c |
|
51 |
-@@ -615,6 +615,7 @@ int config_parse_bool(const char* unit, |
|
52 |
- |
|
53 |
- int k; |
|
54 |
- bool *b = data; |
|
55 |
-+ bool fatal = ltype; |
|
56 |
- |
|
57 |
- assert(filename); |
|
58 |
- assert(lvalue); |
|
59 |
-@@ -623,8 +624,10 @@ int config_parse_bool(const char* unit, |
|
60 |
- |
|
61 |
- k = parse_boolean(rvalue); |
|
62 |
- if (k < 0) { |
|
63 |
-- log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue); |
|
64 |
-- return 0; |
|
65 |
-+ log_syntax(unit, LOG_ERR, filename, line, k, |
|
66 |
-+ "Failed to parse boolean value%s: %s", |
|
67 |
-+ fatal ? "" : ", ignoring", rvalue); |
|
68 |
-+ return fatal ? -ENOEXEC : 0; |
|
69 |
- } |
|
70 |
- |
|
71 |
- *b = !!k; |
|
72 |
-@@ -715,6 +718,7 @@ int config_parse_path( |
|
73 |
- void *userdata) { |
|
74 |
- |
|
75 |
- char **s = data, *n; |
|
76 |
-+ bool fatal = ltype; |
|
77 |
- |
|
78 |
- assert(filename); |
|
79 |
- assert(lvalue); |
|
80 |
-@@ -723,12 +727,14 @@ int config_parse_path( |
|
81 |
- |
|
82 |
- if (!utf8_is_valid(rvalue)) { |
|
83 |
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue); |
|
84 |
-- return 0; |
|
85 |
-+ return fatal ? -ENOEXEC : 0; |
|
86 |
- } |
|
87 |
- |
|
88 |
- if (!path_is_absolute(rvalue)) { |
|
89 |
-- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", rvalue); |
|
90 |
-- return 0; |
|
91 |
-+ log_syntax(unit, LOG_ERR, filename, line, 0, |
|
92 |
-+ "Not an absolute path%s: %s", |
|
93 |
-+ fatal ? "" : ", ignoring", rvalue); |
|
94 |
-+ return fatal ? -ENOEXEC : 0; |
|
95 |
- } |
|
96 |
- |
|
97 |
- n = strdup(rvalue); |
98 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,25 +0,0 @@ |
1 |
-From a924f43f30f9c4acaf70618dd2a055f8b0f166be Mon Sep 17 00:00:00 2001 |
|
2 |
-From: Evgeny Vereshchagin <evvers@ya.ru> |
|
3 |
-Date: Wed, 24 May 2017 08:56:48 +0300 |
|
4 |
-Subject: [PATCH] resolved: bugfix of null pointer p->question dereferencing |
|
5 |
- (#6020) |
|
6 |
- |
|
7 |
-See https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1621396 |
|
8 |
- src/resolve/resolved-dns-packet.c | 3 +++ |
|
9 |
- 1 file changed, 3 insertions(+) |
|
10 |
- |
|
11 |
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c |
|
12 |
-index 652970284e..240ee448f4 100644 |
|
13 |
-+++ b/src/resolve/resolved-dns-packet.c |
|
14 |
-@@ -2269,6 +2269,9 @@ int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) { |
|
15 |
- if (r < 0) |
|
16 |
- return r; |
|
17 |
- |
|
18 |
-+ if (!p->question) |
|
19 |
-+ return 0; |
|
20 |
-+ |
|
21 |
- if (p->question->n_keys != 1) |
|
22 |
- return 0; |
|
23 |
- |
24 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,48 +0,0 @@ |
1 |
-From 8587c3351003b1613ad2e439cebbb20fbae07e70 Mon Sep 17 00:00:00 2001 |
|
2 |
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek () in waw pl> |
|
3 |
-Date: Sun, 18 Jun 2017 16:07:57 -0400 |
|
4 |
-Subject: [PATCH 2/2] resolved: simplify alloc size calculation |
|
5 |
- |
|
6 |
-The allocation size was calculated in a complicated way, and for values |
|
7 |
-close to the page size we would actually allocate less than requested. |
|
8 |
- |
|
9 |
-Reported by Chris Coulson <chris.coulson () canonical com>. |
|
10 |
- src/resolve/resolved-dns-packet.c | 8 +------- |
|
11 |
- src/resolve/resolved-dns-packet.h | 2 -- |
|
12 |
- 2 files changed, 1 insertion(+), 9 deletions(-) |
|
13 |
- |
|
14 |
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c |
|
15 |
-index 240ee448f4..821b66e266 100644 |
|
16 |
-+++ b/src/resolve/resolved-dns-packet.c |
|
17 |
-@@ -47,13 +47,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { |
|
18 |
- |
|
19 |
- assert(ret); |
|
20 |
- |
|
21 |
-- if (mtu <= UDP_PACKET_HEADER_SIZE) |
|
22 |
-- a = DNS_PACKET_SIZE_START; |
|
23 |
-- else |
|
24 |
-- a = mtu - UDP_PACKET_HEADER_SIZE; |
|
25 |
-- |
|
26 |
-- if (a < DNS_PACKET_HEADER_SIZE) |
|
27 |
-- a = DNS_PACKET_HEADER_SIZE; |
|
28 |
-+ a = MAX(mtu, DNS_PACKET_HEADER_SIZE); |
|
29 |
- |
|
30 |
- /* round up to next page size */ |
|
31 |
- a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket)); |
|
32 |
-diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h |
|
33 |
-index 2c92392e4d..3abcaf8cf3 100644 |
|
34 |
-+++ b/src/resolve/resolved-dns-packet.h |
|
35 |
-@@ -66,8 +66,6 @@ struct DnsPacketHeader { |
|
36 |
- /* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */ |
|
37 |
- #define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096 |
|
38 |
- |
|
39 |
--#define DNS_PACKET_SIZE_START 512 |
|
40 |
-- |
|
41 |
- struct DnsPacket { |
|
42 |
- int n_ref; |
|
43 |
- DnsProtocol protocol; |
|
44 |
-2.13.0 |
45 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,23 +0,0 @@ |
1 |
-diff -uNr systemd-233/src/resolve/resolved-conf.c systemd-233-new/src/resolve/resolved-conf.c |
|
2 |
-+++ systemd-233-new/src/resolve/resolved-conf.c 2017-07-07 03:29:00.130502439 +0000 |
|
3 |
-@@ -229,6 +229,7 @@ |
|
4 |
- |
|
5 |
- int manager_parse_config_file(Manager *m) { |
|
6 |
- int r; |
|
7 |
-+ char *default_dns_servers; |
|
8 |
- |
|
9 |
- assert(m); |
|
10 |
- |
|
11 |
-@@ -241,7 +242,10 @@ |
|
12 |
- return r; |
|
13 |
- |
|
14 |
- if (m->need_builtin_fallbacks) { |
|
15 |
-- r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS); |
|
16 |
-+ default_dns_servers = secure_getenv("DEFAULT_DNS_SERVERS"); |
|
17 |
-+ if (default_dns_servers == NULL) |
|
18 |
-+ default_dns_servers = DNS_SERVERS; |
|
19 |
-+ r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, default_dns_servers); |
|
20 |
- if (r < 0) |
|
21 |
- return r; |
|
22 |
- } |
23 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,39 +0,0 @@ |
1 |
-diff -rup systemd-232/src/network/networkd-link.c systemd-232-new/src/network/networkd-link.c |
|
2 |
-+++ systemd-232-new/src/network/networkd-link.c 2016-11-18 11:19:04.687209642 -0800 |
|
3 |
-@@ -199,6 +199,26 @@ static bool link_proxy_arp_enabled(Link |
|
4 |
- return true; |
|
5 |
- } |
|
6 |
- |
|
7 |
-+static bool link_ipv6_disabled(Link *link) { |
|
8 |
-+ const char *p = NULL; |
|
9 |
-+ int r; |
|
10 |
-+ if (link->flags & IFF_LOOPBACK) |
|
11 |
-+ return true; |
|
12 |
-+ /* Make this a NOP if IPv6 is not available */ |
|
13 |
-+ if (!socket_ipv6_is_supported()) |
|
14 |
-+ return true; |
|
15 |
-+ |
|
16 |
-+ p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6"); |
|
17 |
-+ _cleanup_free_ char *val = NULL; |
|
18 |
-+ r = read_one_line_file(p, &val); |
|
19 |
-+ if (r < 0) |
|
20 |
-+ log_link_warning_errno(link, r, "Cannot read ipv6 state for interface: %m"); |
|
21 |
-+ if (streq(val, "0")) |
|
22 |
-+ return false; |
|
23 |
-+ |
|
24 |
-+ return true; |
|
25 |
-+} |
|
26 |
-+ |
|
27 |
- static bool link_ipv6_accept_ra_enabled(Link *link) { |
|
28 |
- assert(link); |
|
29 |
- |
|
30 |
-@@ -720,7 +740,7 @@ void link_check_ready(Link *link) { |
|
31 |
- !link->ipv4ll_route) |
|
32 |
- return; |
|
33 |
- |
|
34 |
-- if (link_ipv6ll_enabled(link)) |
|
35 |
-+ if (!link_ipv6_disabled(link) && link_ipv6ll_enabled(link)) |
|
36 |
- if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0) |
|
37 |
- return; |
|
38 |
- |
39 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,15 +0,0 @@ |
1 |
-diff -uNr systemd-233/src/network/networkd-link.c systemd-233-new/src/network/networkd-link.c |
|
2 |
-+++ systemd-233-new/src/network/networkd-link.c 2017-11-07 21:02:26.532914705 +0000 |
|
3 |
-@@ -213,8 +213,10 @@ |
|
4 |
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6"); |
|
5 |
- _cleanup_free_ char *val = NULL; |
|
6 |
- r = read_one_line_file(p, &val); |
|
7 |
-- if (r < 0) |
|
8 |
-+ if (r < 0) { |
|
9 |
- log_link_warning_errno(link, r, "Cannot read ipv6 state for interface: %m"); |
|
10 |
-+ return false; |
|
11 |
-+ } |
|
12 |
- if (streq(val, "0")) |
|
13 |
- return false; |
|
14 |
- |
15 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,1452 +0,0 @@ |
1 |
-Backports the following commits from systemd 234: |
|
2 |
- |
|
3 |
-ce905cb44620e979862e63743133d354c90d28df icmp6-util: Bind Router Advertisement socket |
|
4 |
-9dab3e066bb5dfeefa28854ab7f95648eaf0d75d sd-radv: Receive Router Solicitations |
|
5 |
-d0d6045f658ac3e043235aee68a540650e0f98e0 sd-radv: Send Router Advertisments |
|
6 |
-dd39628ac19c691917aeeb01babaef411f146039 sd-radv: Implement Router Advertisement timeout handling |
|
7 |
-938c9ff7d374086b996d6a9a484f88ebd94731a3 sd-radv: Add Router Advertisement functionality |
|
8 |
-b076a89bb331b91a7cafcd77fb3c13484805b24f sd-radv: Add Router Advertisement prefix handling |
|
9 |
-1e4a54de3a79a0ba764e482122e381398eaf3e25 icmp6-util: Move multicast address definitions |
|
10 |
-42a7accc3dec5350f0e88ffa145a55293b6fd0e9 sd-ndisc.c: Move Router Solicitation sending after timer computaion |
|
11 |
-7b72b034e7c406209dfc55643b79ec0cb2636e4f sd-ndisc: Implement Router Solicitation backoff method |
|
12 |
-33261358b2a16d895d7beb5b34ebdacadb56cb56 sd-ndisc: Reset counter for sent Router Solicitations (#5874) |
|
13 |
-b40e6a51d55531314666e866d7f9813fce385023 networkd: RFC compliant autonomous prefix handling (#5636) |
|
14 |
- |
|
15 |
- Makefile.am | 3 + |
|
16 |
- src/libsystemd-network/icmp6-util.c | 117 ++++++++++- |
|
17 |
- src/libsystemd-network/icmp6-util.h | 13 ++ |
|
18 |
- src/libsystemd-network/ndisc-internal.h | 7 +- |
|
19 |
- src/libsystemd-network/radv-internal.h | 88 +++++++++ |
|
20 |
- src/libsystemd-network/sd-ndisc.c | 184 ++++++++--------- |
|
21 |
- src/libsystemd-network/sd-radv.c | 653 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
22 |
- src/libsystemd-network/test-ndisc-rs.c | 15 ++ |
|
23 |
- src/network/networkd-ndisc.c | 30 ++- |
|
24 |
- src/systemd/sd-radv.h | 81 ++++++++ |
|
25 |
- 10 files changed, 1086 insertions(+), 105 deletions(-) |
|
26 |
- create mode 100644 src/libsystemd-network/radv-internal.h |
|
27 |
- create mode 100644 src/libsystemd-network/sd-radv.c |
|
28 |
- create mode 100644 src/systemd/sd-radv.h |
|
29 |
- |
|
30 |
-diff -rupN systemd-base/Makefile.am systemd/Makefile.am |
|
31 |
-+++ systemd/Makefile.am 2017-09-18 14:58:25.561666434 -0700 |
|
32 |
-@@ -3629,6 +3629,7 @@ libsystemd_network_la_SOURCES = \ |
|
33 |
- src/systemd/sd-ipv4ll.h \ |
|
34 |
- src/systemd/sd-ipv4acd.h \ |
|
35 |
- src/systemd/sd-ndisc.h \ |
|
36 |
-+ src/systemd/sd-radv.h \ |
|
37 |
- src/systemd/sd-dhcp6-client.h \ |
|
38 |
- src/systemd/sd-dhcp6-lease.h \ |
|
39 |
- src/systemd/sd-lldp.h \ |
|
40 |
-@@ -3652,6 +3653,8 @@ libsystemd_network_la_SOURCES = \ |
|
41 |
- src/libsystemd-network/ndisc-internal.h \ |
|
42 |
- src/libsystemd-network/ndisc-router.h \ |
|
43 |
- src/libsystemd-network/ndisc-router.c \ |
|
44 |
-+ src/libsystemd-network/sd-radv.c \ |
|
45 |
-+ src/libsystemd-network/radv-internal.h \ |
|
46 |
- src/libsystemd-network/icmp6-util.h \ |
|
47 |
- src/libsystemd-network/icmp6-util.c \ |
|
48 |
- src/libsystemd-network/sd-dhcp6-client.c \ |
|
49 |
-diff -rupN systemd-base/src/libsystemd-network/icmp6-util.c systemd/src/libsystemd-network/icmp6-util.c |
|
50 |
-+++ systemd/src/libsystemd-network/icmp6-util.c 2017-09-18 15:06:31.020575497 -0700 |
|
51 |
-@@ -32,6 +32,7 @@ |
|
52 |
- #include "fd-util.h" |
|
53 |
- #include "icmp6-util.h" |
|
54 |
- #include "socket-util.h" |
|
55 |
-+#include "in-addr-util.h" |
|
56 |
- |
|
57 |
- #define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \ |
|
58 |
- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ |
|
59 |
-@@ -41,12 +42,9 @@ |
|
60 |
- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ |
|
61 |
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } |
|
62 |
- |
|
63 |
--int icmp6_bind_router_solicitation(int index) { |
|
64 |
-- struct icmp6_filter filter = { }; |
|
65 |
-- struct ipv6_mreq mreq = { |
|
66 |
-- .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT, |
|
67 |
-- .ipv6mr_interface = index, |
|
68 |
-- }; |
|
69 |
-+static int icmp6_bind_router_message(const struct icmp6_filter *filter, |
|
70 |
-+ const struct ipv6_mreq *mreq) { |
|
71 |
-+ int index = mreq->ipv6mr_interface; |
|
72 |
- _cleanup_close_ int s = -1; |
|
73 |
- char ifname[IF_NAMESIZE] = ""; |
|
74 |
- static const int zero = 0, one = 1, hops = 255; |
|
75 |
-@@ -56,9 +54,11 @@ int icmp6_bind_router_solicitation(int i |
|
76 |
- if (s < 0) |
|
77 |
- return -errno; |
|
78 |
- |
|
79 |
-- ICMP6_FILTER_SETBLOCKALL(&filter); |
|
80 |
-- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); |
|
81 |
-- r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)); |
|
82 |
-+ r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, filter, sizeof(*filter)); |
|
83 |
-+ if (r < 0) |
|
84 |
-+ return -errno; |
|
85 |
-+ |
|
86 |
-+ r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq, sizeof(*mreq)); |
|
87 |
- if (r < 0) |
|
88 |
- return -errno; |
|
89 |
- |
|
90 |
-@@ -78,7 +78,7 @@ int icmp6_bind_router_solicitation(int i |
|
91 |
- if (r < 0) |
|
92 |
- return -errno; |
|
93 |
- |
|
94 |
-- r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); |
|
95 |
-+ r = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops)); |
|
96 |
- if (r < 0) |
|
97 |
- return -errno; |
|
98 |
- |
|
99 |
-@@ -102,6 +102,32 @@ int icmp6_bind_router_solicitation(int i |
|
100 |
- return r; |
|
101 |
- } |
|
102 |
- |
|
103 |
-+int icmp6_bind_router_solicitation(int index) { |
|
104 |
-+ struct icmp6_filter filter = {}; |
|
105 |
-+ struct ipv6_mreq mreq = { |
|
106 |
-+ .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT, |
|
107 |
-+ .ipv6mr_interface = index, |
|
108 |
-+ }; |
|
109 |
-+ |
|
110 |
-+ ICMP6_FILTER_SETBLOCKALL(&filter); |
|
111 |
-+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); |
|
112 |
-+ |
|
113 |
-+ return icmp6_bind_router_message(&filter, &mreq); |
|
114 |
-+} |
|
115 |
-+ |
|
116 |
-+int icmp6_bind_router_advertisement(int index) { |
|
117 |
-+ struct icmp6_filter filter = {}; |
|
118 |
-+ struct ipv6_mreq mreq = { |
|
119 |
-+ .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT, |
|
120 |
-+ .ipv6mr_interface = index, |
|
121 |
-+ }; |
|
122 |
-+ |
|
123 |
-+ ICMP6_FILTER_SETBLOCKALL(&filter); |
|
124 |
-+ ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter); |
|
125 |
-+ |
|
126 |
-+ return icmp6_bind_router_message(&filter, &mreq); |
|
127 |
-+} |
|
128 |
-+ |
|
129 |
- int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { |
|
130 |
- struct sockaddr_in6 dst = { |
|
131 |
- .sin6_family = AF_INET6, |
|
132 |
-@@ -139,3 +165,74 @@ int icmp6_send_router_solicitation(int s |
|
133 |
- |
|
134 |
- return 0; |
|
135 |
- } |
|
136 |
-+ |
|
137 |
-+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, |
|
138 |
-+ triple_timestamp *timestamp) { |
|
139 |
-+ union { |
|
140 |
-+ struct cmsghdr cmsghdr; |
|
141 |
-+ uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */ |
|
142 |
-+ CMSG_SPACE(sizeof(struct timeval))]; |
|
143 |
-+ } control = {}; |
|
144 |
-+ struct iovec iov = {}; |
|
145 |
-+ union sockaddr_union sa = {}; |
|
146 |
-+ struct msghdr msg = { |
|
147 |
-+ .msg_name = &sa.sa, |
|
148 |
-+ .msg_namelen = sizeof(sa), |
|
149 |
-+ .msg_iov = &iov, |
|
150 |
-+ .msg_iovlen = 1, |
|
151 |
-+ .msg_control = &control, |
|
152 |
-+ .msg_controllen = sizeof(control), |
|
153 |
-+ }; |
|
154 |
-+ struct cmsghdr *cmsg; |
|
155 |
-+ ssize_t len; |
|
156 |
-+ |
|
157 |
-+ iov.iov_base = buffer; |
|
158 |
-+ iov.iov_len = size; |
|
159 |
-+ |
|
160 |
-+ len = recvmsg(fd, &msg, MSG_DONTWAIT); |
|
161 |
-+ if (len < 0) { |
|
162 |
-+ if (errno == EAGAIN || errno == EINTR) |
|
163 |
-+ return 0; |
|
164 |
-+ |
|
165 |
-+ return -errno; |
|
166 |
-+ } |
|
167 |
-+ |
|
168 |
-+ if ((size_t) len != size) |
|
169 |
-+ return -EINVAL; |
|
170 |
-+ |
|
171 |
-+ if (msg.msg_namelen == sizeof(struct sockaddr_in6) && |
|
172 |
-+ sa.in6.sin6_family == AF_INET6) { |
|
173 |
-+ |
|
174 |
-+ *dst = sa.in6.sin6_addr; |
|
175 |
-+ if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0) |
|
176 |
-+ return -EADDRNOTAVAIL; |
|
177 |
-+ |
|
178 |
-+ } else if (msg.msg_namelen > 0) |
|
179 |
-+ return -EPFNOSUPPORT; |
|
180 |
-+ |
|
181 |
-+ /* namelen == 0 only happens when running the test-suite over a socketpair */ |
|
182 |
-+ |
|
183 |
-+ assert(!(msg.msg_flags & MSG_CTRUNC)); |
|
184 |
-+ assert(!(msg.msg_flags & MSG_TRUNC)); |
|
185 |
-+ |
|
186 |
-+ CMSG_FOREACH(cmsg, &msg) { |
|
187 |
-+ if (cmsg->cmsg_level == SOL_IPV6 && |
|
188 |
-+ cmsg->cmsg_type == IPV6_HOPLIMIT && |
|
189 |
-+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { |
|
190 |
-+ int hops = *(int*) CMSG_DATA(cmsg); |
|
191 |
-+ |
|
192 |
-+ if (hops != 255) |
|
193 |
-+ return -EMULTIHOP; |
|
194 |
-+ } |
|
195 |
-+ |
|
196 |
-+ if (cmsg->cmsg_level == SOL_SOCKET && |
|
197 |
-+ cmsg->cmsg_type == SO_TIMESTAMP && |
|
198 |
-+ cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) |
|
199 |
-+ triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg))); |
|
200 |
-+ } |
|
201 |
-+ |
|
202 |
-+ if (!triple_timestamp_is_set(timestamp)) |
|
203 |
-+ triple_timestamp_get(timestamp); |
|
204 |
-+ |
|
205 |
-+ return 0; |
|
206 |
-+} |
|
207 |
-diff -rupN systemd-base/src/libsystemd-network/icmp6-util.h systemd/src/libsystemd-network/icmp6-util.h |
|
208 |
-+++ systemd/src/libsystemd-network/icmp6-util.h 2017-09-18 15:06:31.020575497 -0700 |
|
209 |
-@@ -21,5 +21,18 @@ |
|
210 |
- |
|
211 |
- #include <net/ethernet.h> |
|
212 |
- |
|
213 |
-+#include "time-util.h" |
|
214 |
-+ |
|
215 |
-+#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \ |
|
216 |
-+ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ |
|
217 |
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } } |
|
218 |
-+ |
|
219 |
-+#define IN6ADDR_ALL_NODES_MULTICAST_INIT \ |
|
220 |
-+ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ |
|
221 |
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } |
|
222 |
-+ |
|
223 |
- int icmp6_bind_router_solicitation(int index); |
|
224 |
-+int icmp6_bind_router_advertisement(int index); |
|
225 |
- int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); |
|
226 |
-+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, |
|
227 |
-+ triple_timestamp *timestamp); |
|
228 |
-diff -rupN systemd-base/src/libsystemd-network/ndisc-internal.h systemd/src/libsystemd-network/ndisc-internal.h |
|
229 |
-+++ systemd/src/libsystemd-network/ndisc-internal.h 2017-09-18 14:55:04.905317356 -0700 |
|
230 |
-@@ -23,6 +23,10 @@ |
|
231 |
- |
|
232 |
- #include "sd-ndisc.h" |
|
233 |
- |
|
234 |
-+#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC) |
|
235 |
-+#define NDISC_MAX_ROUTER_SOLICITATION_INTERVAL (3600U * USEC_PER_SEC) |
|
236 |
-+#define NDISC_MAX_ROUTER_SOLICITATIONS 3U |
|
237 |
-+ |
|
238 |
- struct sd_ndisc { |
|
239 |
- unsigned n_ref; |
|
240 |
- |
|
241 |
-@@ -38,8 +42,9 @@ struct sd_ndisc { |
|
242 |
- |
|
243 |
- sd_event_source *recv_event_source; |
|
244 |
- sd_event_source *timeout_event_source; |
|
245 |
-+ sd_event_source *timeout_no_ra; |
|
246 |
- |
|
247 |
-- unsigned nd_sent; |
|
248 |
-+ usec_t retransmit_time; |
|
249 |
- |
|
250 |
- sd_ndisc_callback_t callback; |
|
251 |
- void *userdata; |
|
252 |
-diff -rupN systemd-base/src/libsystemd-network/radv-internal.h systemd/src/libsystemd-network/radv-internal.h |
|
253 |
-+++ systemd/src/libsystemd-network/radv-internal.h 2017-09-18 15:00:40.022354604 -0700 |
|
254 |
-@@ -0,0 +1,88 @@ |
|
255 |
-+#pragma once |
|
256 |
-+ |
|
257 |
-+/*** |
|
258 |
-+ This file is part of systemd. |
|
259 |
-+ |
|
260 |
-+ Copyright (C) 2017 Intel Corporation. All rights reserved. |
|
261 |
-+ |
|
262 |
-+ systemd is free software; you can redistribute it and/or modify it |
|
263 |
-+ under the terms of the GNU Lesser General Public License as published by |
|
264 |
-+ the Free Software Foundation; either version 2.1 of the License, or |
|
265 |
-+ (at your option) any later version. |
|
266 |
-+ |
|
267 |
-+ systemd is distributed in the hope that it will be useful, but |
|
268 |
-+ WITHOUT ANY WARRANTY; without even the implied warranty of |
|
269 |
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
270 |
-+ Lesser General Public License for more details. |
|
271 |
-+ |
|
272 |
-+ You should have received a copy of the GNU Lesser General Public License |
|
273 |
-+ along with systemd; If not, see <http://www.gnu.org/licenses/>. |
|
274 |
-+***/ |
|
275 |
-+ |
|
276 |
-+#include "sd-radv.h" |
|
277 |
-+ |
|
278 |
-+#include "log.h" |
|
279 |
-+#include "list.h" |
|
280 |
-+#include "sparse-endian.h" |
|
281 |
-+ |
|
282 |
-+#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC (200*USEC_PER_SEC) |
|
283 |
-+#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC (600*USEC_PER_SEC) |
|
284 |
-+assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC) |
|
285 |
-+ |
|
286 |
-+#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC) |
|
287 |
-+#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS 3 |
|
288 |
-+#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS 3 |
|
289 |
-+#define SD_RADV_MIN_DELAY_BETWEEN_RAS 3 |
|
290 |
-+#define SD_RADV_MAX_RA_DELAY_TIME_USEC (500*USEC_PER_MSEC) |
|
291 |
-+ |
|
292 |
-+enum RAdvState { |
|
293 |
-+ SD_RADV_STATE_IDLE = 0, |
|
294 |
-+ SD_RADV_STATE_ADVERTISING = 1, |
|
295 |
-+}; |
|
296 |
-+typedef enum RAdvState RAdvState; |
|
297 |
-+ |
|
298 |
-+struct sd_radv { |
|
299 |
-+ unsigned n_ref; |
|
300 |
-+ RAdvState state; |
|
301 |
-+ |
|
302 |
-+ int ifindex; |
|
303 |
-+ |
|
304 |
-+ sd_event *event; |
|
305 |
-+ int event_priority; |
|
306 |
-+ |
|
307 |
-+ struct ether_addr mac_addr; |
|
308 |
-+ uint8_t hop_limit; |
|
309 |
-+ uint8_t flags; |
|
310 |
-+ uint32_t mtu; |
|
311 |
-+ uint16_t lifetime; |
|
312 |
-+ |
|
313 |
-+ int fd; |
|
314 |
-+ unsigned ra_sent; |
|
315 |
-+ sd_event_source *recv_event_source; |
|
316 |
-+ sd_event_source *timeout_event_source; |
|
317 |
-+ |
|
318 |
-+ unsigned n_prefixes; |
|
319 |
-+ LIST_HEAD(sd_radv_prefix, prefixes); |
|
320 |
-+}; |
|
321 |
-+ |
|
322 |
-+struct sd_radv_prefix { |
|
323 |
-+ unsigned n_ref; |
|
324 |
-+ |
|
325 |
-+ struct { |
|
326 |
-+ uint8_t type; |
|
327 |
-+ uint8_t length; |
|
328 |
-+ uint8_t prefixlen; |
|
329 |
-+ uint8_t flags; |
|
330 |
-+ be32_t valid_lifetime; |
|
331 |
-+ be32_t preferred_lifetime; |
|
332 |
-+ uint32_t reserved; |
|
333 |
-+ struct in6_addr in6_addr; |
|
334 |
-+ } _packed_ opt; |
|
335 |
-+ |
|
336 |
-+ LIST_FIELDS(struct sd_radv_prefix, prefix); |
|
337 |
-+}; |
|
338 |
-+ |
|
339 |
-+#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__) |
|
340 |
-+#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__) |
|
341 |
-+#define log_radv_warning_errno(error, fmt, ...) log_radv_full(LOG_WARNING, error, fmt, ##__VA_ARGS__) |
|
342 |
-+#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__) |
|
343 |
-diff -rupN systemd-base/src/libsystemd-network/sd-ndisc.c systemd/src/libsystemd-network/sd-ndisc.c |
|
344 |
-+++ systemd/src/libsystemd-network/sd-ndisc.c 2017-09-18 15:00:40.038396204 -0700 |
|
345 |
-@@ -28,12 +28,12 @@ |
|
346 |
- #include "in-addr-util.h" |
|
347 |
- #include "ndisc-internal.h" |
|
348 |
- #include "ndisc-router.h" |
|
349 |
-+#include "random-util.h" |
|
350 |
- #include "socket-util.h" |
|
351 |
- #include "string-util.h" |
|
352 |
- #include "util.h" |
|
353 |
- |
|
354 |
--#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC) |
|
355 |
--#define NDISC_MAX_ROUTER_SOLICITATIONS 3U |
|
356 |
-+#define NDISC_TIMEOUT_NO_RA_USEC (NDISC_ROUTER_SOLICITATION_INTERVAL * NDISC_MAX_ROUTER_SOLICITATIONS) |
|
357 |
- |
|
358 |
- static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event event, sd_ndisc_router *rt) { |
|
359 |
- assert(ndisc); |
|
360 |
-@@ -129,6 +129,8 @@ static int ndisc_reset(sd_ndisc *nd) { |
|
361 |
- assert(nd); |
|
362 |
- |
|
363 |
- nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); |
|
364 |
-+ nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra); |
|
365 |
-+ nd->retransmit_time = 0; |
|
366 |
- nd->recv_event_source = sd_event_source_unref(nd->recv_event_source); |
|
367 |
- nd->fd = safe_close(nd->fd); |
|
368 |
- |
|
369 |
-@@ -221,23 +223,9 @@ static int ndisc_handle_datagram(sd_ndis |
|
370 |
- static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { |
|
371 |
- _cleanup_(sd_ndisc_router_unrefp) sd_ndisc_router *rt = NULL; |
|
372 |
- sd_ndisc *nd = userdata; |
|
373 |
-- union { |
|
374 |
-- struct cmsghdr cmsghdr; |
|
375 |
-- uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */ |
|
376 |
-- CMSG_SPACE(sizeof(struct timeval))]; |
|
377 |
-- } control = {}; |
|
378 |
-- struct iovec iov = {}; |
|
379 |
-- union sockaddr_union sa = {}; |
|
380 |
-- struct msghdr msg = { |
|
381 |
-- .msg_name = &sa.sa, |
|
382 |
-- .msg_namelen = sizeof(sa), |
|
383 |
-- .msg_iov = &iov, |
|
384 |
-- .msg_iovlen = 1, |
|
385 |
-- .msg_control = &control, |
|
386 |
-- .msg_controllen = sizeof(control), |
|
387 |
-- }; |
|
388 |
-- struct cmsghdr *cmsg; |
|
389 |
-- ssize_t len, buflen; |
|
390 |
-+ ssize_t buflen; |
|
391 |
-+ int r; |
|
392 |
-+ _cleanup_free_ char *addr = NULL; |
|
393 |
- |
|
394 |
- assert(s); |
|
395 |
- assert(nd); |
|
396 |
-@@ -251,110 +239,90 @@ static int ndisc_recv(sd_event_source *s |
|
397 |
- if (!rt) |
|
398 |
- return -ENOMEM; |
|
399 |
- |
|
400 |
-- iov.iov_base = NDISC_ROUTER_RAW(rt); |
|
401 |
-- iov.iov_len = rt->raw_size; |
|
402 |
-- |
|
403 |
-- len = recvmsg(fd, &msg, MSG_DONTWAIT); |
|
404 |
-- if (len < 0) { |
|
405 |
-- if (errno == EAGAIN || errno == EINTR) |
|
406 |
-- return 0; |
|
407 |
-- |
|
408 |
-- return log_ndisc_errno(errno, "Could not receive message from ICMPv6 socket: %m"); |
|
409 |
-- } |
|
410 |
-- |
|
411 |
-- if ((size_t) len != rt->raw_size) { |
|
412 |
-- log_ndisc("Packet size mismatch."); |
|
413 |
-- return -EINVAL; |
|
414 |
-- } |
|
415 |
-- |
|
416 |
-- if (msg.msg_namelen == sizeof(struct sockaddr_in6) && |
|
417 |
-- sa.in6.sin6_family == AF_INET6) { |
|
418 |
-- |
|
419 |
-- if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr) <= 0) { |
|
420 |
-- _cleanup_free_ char *addr = NULL; |
|
421 |
-- |
|
422 |
-- (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr, &addr); |
|
423 |
-- log_ndisc("Received RA from non-link-local address %s. Ignoring.", strna(addr)); |
|
424 |
-- return 0; |
|
425 |
-- } |
|
426 |
-- |
|
427 |
-- rt->address = sa.in6.sin6_addr; |
|
428 |
-- |
|
429 |
-- } else if (msg.msg_namelen > 0) { |
|
430 |
-- log_ndisc("Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t) msg.msg_namelen); |
|
431 |
-- return -EINVAL; |
|
432 |
-- } |
|
433 |
-- |
|
434 |
-- /* namelen == 0 only happens when running the test-suite over a socketpair */ |
|
435 |
-- |
|
436 |
-- assert(!(msg.msg_flags & MSG_CTRUNC)); |
|
437 |
-- assert(!(msg.msg_flags & MSG_TRUNC)); |
|
438 |
-- |
|
439 |
-- CMSG_FOREACH(cmsg, &msg) { |
|
440 |
-- if (cmsg->cmsg_level == SOL_IPV6 && |
|
441 |
-- cmsg->cmsg_type == IPV6_HOPLIMIT && |
|
442 |
-- cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { |
|
443 |
-- int hops = *(int*) CMSG_DATA(cmsg); |
|
444 |
-- |
|
445 |
-- if (hops != 255) { |
|
446 |
-- log_ndisc("Received RA with invalid hop limit %d. Ignoring.", hops); |
|
447 |
-- return 0; |
|
448 |
-- } |
|
449 |
-+ r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address, |
|
450 |
-+ &rt->timestamp); |
|
451 |
-+ if (r < 0) { |
|
452 |
-+ switch (r) { |
|
453 |
-+ case -EADDRNOTAVAIL: |
|
454 |
-+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &rt->address, &addr); |
|
455 |
-+ log_ndisc("Received RA from non-link-local address %s. Ignoring", addr); |
|
456 |
-+ break; |
|
457 |
-+ |
|
458 |
-+ case -EMULTIHOP: |
|
459 |
-+ log_ndisc("Received RA with invalid hop limit. Ignoring."); |
|
460 |
-+ break; |
|
461 |
-+ |
|
462 |
-+ case -EPFNOSUPPORT: |
|
463 |
-+ log_ndisc("Received invalid source address from ICMPv6 socket."); |
|
464 |
-+ break; |
|
465 |
- } |
|
466 |
- |
|
467 |
-- if (cmsg->cmsg_level == SOL_SOCKET && |
|
468 |
-- cmsg->cmsg_type == SO_TIMESTAMP && |
|
469 |
-- cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) |
|
470 |
-- triple_timestamp_from_realtime(&rt->timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg))); |
|
471 |
-+ return 0; |
|
472 |
- } |
|
473 |
- |
|
474 |
-- if (!triple_timestamp_is_set(&rt->timestamp)) |
|
475 |
-- triple_timestamp_get(&rt->timestamp); |
|
476 |
-- |
|
477 |
- nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); |
|
478 |
- |
|
479 |
- return ndisc_handle_datagram(nd, rt); |
|
480 |
- } |
|
481 |
- |
|
482 |
-+static usec_t ndisc_timeout_compute_random(usec_t val) { |
|
483 |
-+ /* compute a time that is random within ±10% of the given value */ |
|
484 |
-+ return val - val / 10 + |
|
485 |
-+ (random_u64() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC; |
|
486 |
-+} |
|
487 |
-+ |
|
488 |
- static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) { |
|
489 |
- sd_ndisc *nd = userdata; |
|
490 |
-- usec_t time_now, next_timeout; |
|
491 |
-+ usec_t time_now; |
|
492 |
- int r; |
|
493 |
-+ char time_string[FORMAT_TIMESPAN_MAX]; |
|
494 |
- |
|
495 |
- assert(s); |
|
496 |
- assert(nd); |
|
497 |
- assert(nd->event); |
|
498 |
- |
|
499 |
-- if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) { |
|
500 |
-- nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); |
|
501 |
-- ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL); |
|
502 |
-- return 0; |
|
503 |
-+ assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0); |
|
504 |
-+ |
|
505 |
-+ nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); |
|
506 |
-+ |
|
507 |
-+ if (!nd->retransmit_time) |
|
508 |
-+ nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL); |
|
509 |
-+ else { |
|
510 |
-+ if (nd->retransmit_time > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 2) |
|
511 |
-+ nd->retransmit_time = ndisc_timeout_compute_random(NDISC_MAX_ROUTER_SOLICITATION_INTERVAL); |
|
512 |
-+ else |
|
513 |
-+ nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time); |
|
514 |
- } |
|
515 |
- |
|
516 |
-- r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr); |
|
517 |
-- if (r < 0) { |
|
518 |
-- log_ndisc_errno(r, "Error sending Router Solicitation: %m"); |
|
519 |
-+ r = sd_event_add_time(nd->event, &nd->timeout_event_source, |
|
520 |
-+ clock_boottime_or_monotonic(), |
|
521 |
-+ time_now + nd->retransmit_time, |
|
522 |
-+ 10 * USEC_PER_MSEC, ndisc_timeout, nd); |
|
523 |
-+ if (r < 0) |
|
524 |
- goto fail; |
|
525 |
-- } |
|
526 |
- |
|
527 |
-- log_ndisc("Sent Router Solicitation"); |
|
528 |
-- nd->nd_sent++; |
|
529 |
-+ r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority); |
|
530 |
-+ if (r < 0) |
|
531 |
-+ goto fail; |
|
532 |
- |
|
533 |
-- assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0); |
|
534 |
-- next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL; |
|
535 |
-+ (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout-no-ra"); |
|
536 |
- |
|
537 |
-- r = sd_event_source_set_time(nd->timeout_event_source, next_timeout); |
|
538 |
-+ r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT); |
|
539 |
- if (r < 0) { |
|
540 |
-- log_ndisc_errno(r, "Error updating timer: %m"); |
|
541 |
-+ log_ndisc_errno(r, "Error reenabling timer: %m"); |
|
542 |
- goto fail; |
|
543 |
- } |
|
544 |
- |
|
545 |
-- r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT); |
|
546 |
-+ r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr); |
|
547 |
- if (r < 0) { |
|
548 |
-- log_ndisc_errno(r, "Error reenabling timer: %m"); |
|
549 |
-+ log_ndisc_errno(r, "Error sending Router Solicitation: %m"); |
|
550 |
- goto fail; |
|
551 |
- } |
|
552 |
- |
|
553 |
-+ log_ndisc("Sent Router Solicitation, next solicitation in %s", |
|
554 |
-+ format_timespan(time_string, FORMAT_TIMESPAN_MAX, |
|
555 |
-+ nd->retransmit_time, USEC_PER_SEC)); |
|
556 |
-+ |
|
557 |
- return 0; |
|
558 |
- |
|
559 |
- fail: |
|
560 |
-@@ -362,6 +330,20 @@ fail: |
|
561 |
- return 0; |
|
562 |
- } |
|
563 |
- |
|
564 |
-+static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata) { |
|
565 |
-+ sd_ndisc *nd = userdata; |
|
566 |
-+ |
|
567 |
-+ assert(s); |
|
568 |
-+ assert(nd); |
|
569 |
-+ |
|
570 |
-+ log_ndisc("No RA received before link confirmation timeout"); |
|
571 |
-+ |
|
572 |
-+ nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra); |
|
573 |
-+ ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL); |
|
574 |
-+ |
|
575 |
-+ return 0; |
|
576 |
-+} |
|
577 |
-+ |
|
578 |
- _public_ int sd_ndisc_stop(sd_ndisc *nd) { |
|
579 |
- assert_return(nd, -EINVAL); |
|
580 |
- |
|
581 |
-@@ -376,6 +358,7 @@ _public_ int sd_ndisc_stop(sd_ndisc *nd) |
|
582 |
- |
|
583 |
- _public_ int sd_ndisc_start(sd_ndisc *nd) { |
|
584 |
- int r; |
|
585 |
-+ usec_t time_now; |
|
586 |
- |
|
587 |
- assert_return(nd, -EINVAL); |
|
588 |
- assert_return(nd->event, -EINVAL); |
|
589 |
-@@ -387,6 +370,10 @@ _public_ int sd_ndisc_start(sd_ndisc *nd |
|
590 |
- assert(!nd->recv_event_source); |
|
591 |
- assert(!nd->timeout_event_source); |
|
592 |
- |
|
593 |
-+ r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); |
|
594 |
-+ if (r < 0) |
|
595 |
-+ goto fail; |
|
596 |
-+ |
|
597 |
- nd->fd = icmp6_bind_router_solicitation(nd->ifindex); |
|
598 |
- if (nd->fd < 0) |
|
599 |
- return nd->fd; |
|
600 |
-@@ -411,6 +398,19 @@ _public_ int sd_ndisc_start(sd_ndisc *nd |
|
601 |
- |
|
602 |
- (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout"); |
|
603 |
- |
|
604 |
-+ r = sd_event_add_time(nd->event, &nd->timeout_no_ra, |
|
605 |
-+ clock_boottime_or_monotonic(), |
|
606 |
-+ time_now + NDISC_TIMEOUT_NO_RA_USEC, |
|
607 |
-+ 10 * USEC_PER_MSEC, ndisc_timeout_no_ra, nd); |
|
608 |
-+ if (r < 0) |
|
609 |
-+ goto fail; |
|
610 |
-+ |
|
611 |
-+ r = sd_event_source_set_priority(nd->timeout_no_ra, nd->event_priority); |
|
612 |
-+ if (r < 0) |
|
613 |
-+ goto fail; |
|
614 |
-+ |
|
615 |
-+ (void) sd_event_source_set_description(nd->timeout_no_ra, "ndisc-timeout-no-ra"); |
|
616 |
-+ |
|
617 |
- log_ndisc("Started IPv6 Router Solicitation client"); |
|
618 |
- return 1; |
|
619 |
- |
|
620 |
-diff -rupN systemd-base/src/libsystemd-network/sd-radv.c systemd/src/libsystemd-network/sd-radv.c |
|
621 |
-+++ systemd/src/libsystemd-network/sd-radv.c 2017-09-18 15:00:40.022354604 -0700 |
|
622 |
-@@ -0,0 +1,653 @@ |
|
623 |
-+/*** |
|
624 |
-+ This file is part of systemd. |
|
625 |
-+ |
|
626 |
-+ Copyright (C) 2017 Intel Corporation. All rights reserved. |
|
627 |
-+ |
|
628 |
-+ systemd is free software; you can redistribute it and/or modify it |
|
629 |
-+ under the terms of the GNU Lesser General Public License as published by |
|
630 |
-+ the Free Software Foundation; either version 2.1 of the License, or |
|
631 |
-+ (at your option) any later version. |
|
632 |
-+ |
|
633 |
-+ systemd is distributed in the hope that it will be useful, but |
|
634 |
-+ WITHOUT ANY WARRANTY; without even the implied warranty of |
|
635 |
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
636 |
-+ Lesser General Public License for more details. |
|
637 |
-+ |
|
638 |
-+ You should have received a copy of the GNU Lesser General Public License |
|
639 |
-+ along with systemd; If not, see <http://www.gnu.org/licenses/>. |
|
640 |
-+***/ |
|
641 |
-+ |
|
642 |
-+#include <netinet/icmp6.h> |
|
643 |
-+#include <netinet/in.h> |
|
644 |
-+#include <arpa/inet.h> |
|
645 |
-+#include <linux/in6.h> |
|
646 |
-+ |
|
647 |
-+#include "sd-radv.h" |
|
648 |
-+ |
|
649 |
-+#include "macro.h" |
|
650 |
-+#include "alloc-util.h" |
|
651 |
-+#include "fd-util.h" |
|
652 |
-+#include "icmp6-util.h" |
|
653 |
-+#include "in-addr-util.h" |
|
654 |
-+#include "radv-internal.h" |
|
655 |
-+#include "socket-util.h" |
|
656 |
-+#include "string-util.h" |
|
657 |
-+#include "util.h" |
|
658 |
-+#include "random-util.h" |
|
659 |
-+ |
|
660 |
-+_public_ int sd_radv_new(sd_radv **ret) { |
|
661 |
-+ _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL; |
|
662 |
-+ |
|
663 |
-+ assert_return(ret, -EINVAL); |
|
664 |
-+ |
|
665 |
-+ ra = new0(sd_radv, 1); |
|
666 |
-+ if (!ra) |
|
667 |
-+ return -ENOMEM; |
|
668 |
-+ |
|
669 |
-+ ra->n_ref = 1; |
|
670 |
-+ ra->fd = -1; |
|
671 |
-+ |
|
672 |
-+ LIST_HEAD_INIT(ra->prefixes); |
|
673 |
-+ |
|
674 |
-+ *ret = ra; |
|
675 |
-+ ra = NULL; |
|
676 |
-+ |
|
677 |
-+ return 0; |
|
678 |
-+} |
|
679 |
-+ |
|
680 |
-+_public_ int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority) { |
|
681 |
-+ int r; |
|
682 |
-+ |
|
683 |
-+ assert_return(ra, -EINVAL); |
|
684 |
-+ assert_return(!ra->event, -EBUSY); |
|
685 |
-+ |
|
686 |
-+ if (event) |
|
687 |
-+ ra->event = sd_event_ref(event); |
|
688 |
-+ else { |
|
689 |
-+ r = sd_event_default(&ra->event); |
|
690 |
-+ if (r < 0) |
|
691 |
-+ return 0; |
|
692 |
-+ } |
|
693 |
-+ |
|
694 |
-+ ra->event_priority = priority; |
|
695 |
-+ |
|
696 |
-+ return 0; |
|
697 |
-+} |
|
698 |
-+ |
|
699 |
-+_public_ int sd_radv_detach_event(sd_radv *ra) { |
|
700 |
-+ |
|
701 |
-+ assert_return(ra, -EINVAL); |
|
702 |
-+ |
|
703 |
-+ ra->event = sd_event_unref(ra->event); |
|
704 |
-+ return 0; |
|
705 |
-+} |
|
706 |
-+ |
|
707 |
-+_public_ sd_event *sd_radv_get_event(sd_radv *ra) { |
|
708 |
-+ assert_return(ra, NULL); |
|
709 |
-+ |
|
710 |
-+ return ra->event; |
|
711 |
-+} |
|
712 |
-+ |
|
713 |
-+static void radv_reset(sd_radv *ra) { |
|
714 |
-+ |
|
715 |
-+ ra->timeout_event_source = |
|
716 |
-+ sd_event_source_unref(ra->timeout_event_source); |
|
717 |
-+ |
|
718 |
-+ ra->recv_event_source = |
|
719 |
-+ sd_event_source_unref(ra->recv_event_source); |
|
720 |
-+ |
|
721 |
-+ ra->ra_sent = 0; |
|
722 |
-+} |
|
723 |
-+ |
|
724 |
-+_public_ sd_radv *sd_radv_ref(sd_radv *ra) { |
|
725 |
-+ if (!ra) |
|
726 |
-+ return NULL; |
|
727 |
-+ |
|
728 |
-+ assert(ra->n_ref > 0); |
|
729 |
-+ ra->n_ref++; |
|
730 |
-+ |
|
731 |
-+ return ra; |
|
732 |
-+} |
|
733 |
-+ |
|
734 |
-+_public_ sd_radv *sd_radv_unref(sd_radv *ra) { |
|
735 |
-+ if (!ra) |
|
736 |
-+ return NULL; |
|
737 |
-+ |
|
738 |
-+ assert(ra->n_ref > 0); |
|
739 |
-+ ra->n_ref--; |
|
740 |
-+ |
|
741 |
-+ if (ra->n_ref > 0) |
|
742 |
-+ return NULL; |
|
743 |
-+ |
|
744 |
-+ while (ra->prefixes) { |
|
745 |
-+ sd_radv_prefix *p = ra->prefixes; |
|
746 |
-+ |
|
747 |
-+ LIST_REMOVE(prefix, ra->prefixes, p); |
|
748 |
-+ sd_radv_prefix_unref(p); |
|
749 |
-+ } |
|
750 |
-+ |
|
751 |
-+ radv_reset(ra); |
|
752 |
-+ |
|
753 |
-+ sd_radv_detach_event(ra); |
|
754 |
-+ return mfree(ra); |
|
755 |
-+} |
|
756 |
-+ |
|
757 |
-+static int radv_send(sd_radv *ra, const struct in6_addr *dst, |
|
758 |
-+ const uint32_t router_lifetime) { |
|
759 |
-+ static const struct ether_addr mac_zero = {}; |
|
760 |
-+ sd_radv_prefix *p; |
|
761 |
-+ struct sockaddr_in6 dst_addr = { |
|
762 |
-+ .sin6_family = AF_INET6, |
|
763 |
-+ .sin6_addr = IN6ADDR_ALL_NODES_MULTICAST_INIT, |
|
764 |
-+ }; |
|
765 |
-+ struct nd_router_advert adv = {}; |
|
766 |
-+ struct { |
|
767 |
-+ struct nd_opt_hdr opthdr; |
|
768 |
-+ struct ether_addr slladdr; |
|
769 |
-+ } _packed_ opt_mac = { |
|
770 |
-+ .opthdr = { |
|
771 |
-+ .nd_opt_type = ND_OPT_SOURCE_LINKADDR, |
|
772 |
-+ .nd_opt_len = (sizeof(struct nd_opt_hdr) + |
|
773 |
-+ sizeof(struct ether_addr) - 1) /8 + 1, |
|
774 |
-+ }, |
|
775 |
-+ }; |
|
776 |
-+ struct nd_opt_mtu opt_mtu = { |
|
777 |
-+ .nd_opt_mtu_type = ND_OPT_MTU, |
|
778 |
-+ .nd_opt_mtu_len = 1, |
|
779 |
-+ }; |
|
780 |
-+ /* Reserve iov space for RA header, linkaddr, MTU + N prefixes */ |
|
781 |
-+ struct iovec iov[3 + ra->n_prefixes]; |
|
782 |
-+ struct msghdr msg = { |
|
783 |
-+ .msg_name = &dst_addr, |
|
784 |
-+ .msg_namelen = sizeof(dst_addr), |
|
785 |
-+ .msg_iov = iov, |
|
786 |
-+ }; |
|
787 |
-+ |
|
788 |
-+ if (dst && !in_addr_is_null(AF_INET6, (union in_addr_union*) dst)) |
|
789 |
-+ dst_addr.sin6_addr = *dst; |
|
790 |
-+ |
|
791 |
-+ adv.nd_ra_type = ND_ROUTER_ADVERT; |
|
792 |
-+ adv.nd_ra_curhoplimit = ra->hop_limit; |
|
793 |
-+ adv.nd_ra_flags_reserved = ra->flags; |
|
794 |
-+ adv.nd_ra_router_lifetime = htobe16(router_lifetime); |
|
795 |
-+ iov[msg.msg_iovlen].iov_base = &adv; |
|
796 |
-+ iov[msg.msg_iovlen].iov_len = sizeof(adv); |
|
797 |
-+ msg.msg_iovlen++; |
|
798 |
-+ |
|
799 |
-+ /* MAC address is optional, either because the link does not use L2 |
|
800 |
-+ addresses or load sharing is desired. See RFC 4861, Section 4.2 */ |
|
801 |
-+ if (memcmp(&mac_zero, &ra->mac_addr, sizeof(mac_zero))) { |
|
802 |
-+ opt_mac.slladdr = ra->mac_addr; |
|
803 |
-+ iov[msg.msg_iovlen].iov_base = &opt_mac; |
|
804 |
-+ iov[msg.msg_iovlen].iov_len = sizeof(opt_mac); |
|
805 |
-+ msg.msg_iovlen++; |
|
806 |
-+ } |
|
807 |
-+ |
|
808 |
-+ if (ra->mtu) { |
|
809 |
-+ opt_mtu.nd_opt_mtu_mtu = htobe32(ra->mtu); |
|
810 |
-+ iov[msg.msg_iovlen].iov_base = &opt_mtu; |
|
811 |
-+ iov[msg.msg_iovlen].iov_len = sizeof(opt_mtu); |
|
812 |
-+ msg.msg_iovlen++; |
|
813 |
-+ } |
|
814 |
-+ |
|
815 |
-+ LIST_FOREACH(prefix, p, ra->prefixes) { |
|
816 |
-+ iov[msg.msg_iovlen].iov_base = &p->opt; |
|
817 |
-+ iov[msg.msg_iovlen].iov_len = sizeof(p->opt); |
|
818 |
-+ msg.msg_iovlen++; |
|
819 |
-+ } |
|
820 |
-+ |
|
821 |
-+ if (sendmsg(ra->fd, &msg, 0) < 0) |
|
822 |
-+ return -errno; |
|
823 |
-+ |
|
824 |
-+ return 0; |
|
825 |
-+} |
|
826 |
-+ |
|
827 |
-+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { |
|
828 |
-+ sd_radv *ra = userdata; |
|
829 |
-+ _cleanup_free_ char *addr = NULL; |
|
830 |
-+ struct in6_addr src; |
|
831 |
-+ triple_timestamp timestamp; |
|
832 |
-+ int r; |
|
833 |
-+ ssize_t buflen; |
|
834 |
-+ _cleanup_free_ char *buf = NULL; |
|
835 |
-+ |
|
836 |
-+ assert(s); |
|
837 |
-+ assert(ra); |
|
838 |
-+ assert(ra->event); |
|
839 |
-+ |
|
840 |
-+ buflen = next_datagram_size_fd(fd); |
|
841 |
-+ |
|
842 |
-+ if ((unsigned) buflen < sizeof(struct nd_router_solicit)) |
|
843 |
-+ return log_radv("Too short packet received"); |
|
844 |
-+ |
|
845 |
-+ buf = new0(char, buflen); |
|
846 |
-+ if (!buf) |
|
847 |
-+ return 0; |
|
848 |
-+ |
|
849 |
-+ r = icmp6_receive(fd, buf, buflen, &src, ×tamp); |
|
850 |
-+ if (r < 0) { |
|
851 |
-+ switch (r) { |
|
852 |
-+ case -EADDRNOTAVAIL: |
|
853 |
-+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr); |
|
854 |
-+ log_radv("Received RS from non-link-local address %s. Ignoring", addr); |
|
855 |
-+ break; |
|
856 |
-+ |
|
857 |
-+ case -EMULTIHOP: |
|
858 |
-+ log_radv("Received RS with invalid hop limit. Ignoring."); |
|
859 |
-+ break; |
|
860 |
-+ |
|
861 |
-+ case -EPFNOSUPPORT: |
|
862 |
-+ log_radv("Received invalid source address from ICMPv6 socket. Ignoring."); |
|
863 |
-+ break; |
|
864 |
-+ |
|
865 |
-+ default: |
|
866 |
-+ log_radv_warning_errno(r, "Error receiving from ICMPv6 socket: %m"); |
|
867 |
-+ break; |
|
868 |
-+ } |
|
869 |
-+ |
|
870 |
-+ return 0; |
|
871 |
-+ } |
|
872 |
-+ |
|
873 |
-+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr); |
|
874 |
-+ |
|
875 |
-+ r = radv_send(ra, &src, ra->lifetime); |
|
876 |
-+ if (r < 0) |
|
877 |
-+ log_radv_warning_errno(r, "Unable to send solicited Router Advertisment to %s: %m", addr); |
|
878 |
-+ else |
|
879 |
-+ log_radv("Sent solicited Router Advertisement to %s", addr); |
|
880 |
-+ |
|
881 |
-+ return 0; |
|
882 |
-+} |
|
883 |
-+ |
|
884 |
-+static usec_t radv_compute_timeout(usec_t min, usec_t max) { |
|
885 |
-+ assert_return(min <= max, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC); |
|
886 |
-+ |
|
887 |
-+ return min + (random_u32() % (max - min)); |
|
888 |
-+} |
|
889 |
-+ |
|
890 |
-+static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) { |
|
891 |
-+ int r; |
|
892 |
-+ sd_radv *ra = userdata; |
|
893 |
-+ usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC; |
|
894 |
-+ usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC; |
|
895 |
-+ usec_t time_now, timeout; |
|
896 |
-+ char time_string[FORMAT_TIMESPAN_MAX]; |
|
897 |
-+ |
|
898 |
-+ assert(s); |
|
899 |
-+ assert(ra); |
|
900 |
-+ assert(ra->event); |
|
901 |
-+ |
|
902 |
-+ ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source); |
|
903 |
-+ |
|
904 |
-+ r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now); |
|
905 |
-+ if (r < 0) |
|
906 |
-+ goto fail; |
|
907 |
-+ |
|
908 |
-+ r = radv_send(ra, NULL, ra->lifetime); |
|
909 |
-+ if (r < 0) |
|
910 |
-+ log_radv_warning_errno(r, "Unable to send Router Advertisement: %m"); |
|
911 |
-+ |
|
912 |
-+ /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */ |
|
913 |
-+ if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) { |
|
914 |
-+ max_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC; |
|
915 |
-+ min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3; |
|
916 |
-+ } |
|
917 |
-+ |
|
918 |
-+ timeout = radv_compute_timeout(min_timeout, max_timeout); |
|
919 |
-+ |
|
920 |
-+ log_radv("Next Router Advertisement in %s", |
|
921 |
-+ format_timespan(time_string, FORMAT_TIMESPAN_MAX, |
|
922 |
-+ timeout, USEC_PER_SEC)); |
|
923 |
-+ |
|
924 |
-+ r = sd_event_add_time(ra->event, &ra->timeout_event_source, |
|
925 |
-+ clock_boottime_or_monotonic(), |
|
926 |
-+ time_now + timeout, MSEC_PER_SEC, |
|
927 |
-+ radv_timeout, ra); |
|
928 |
-+ if (r < 0) |
|
929 |
-+ goto fail; |
|
930 |
-+ |
|
931 |
-+ r = sd_event_source_set_priority(ra->timeout_event_source, |
|
932 |
-+ ra->event_priority); |
|
933 |
-+ if (r < 0) |
|
934 |
-+ goto fail; |
|
935 |
-+ |
|
936 |
-+ r = sd_event_source_set_description(ra->timeout_event_source, |
|
937 |
-+ "radv-timeout"); |
|
938 |
-+ if (r < 0) |
|
939 |
-+ goto fail; |
|
940 |
-+ |
|
941 |
-+ ra->ra_sent++; |
|
942 |
-+ |
|
943 |
-+fail: |
|
944 |
-+ if (r < 0) |
|
945 |
-+ sd_radv_stop(ra); |
|
946 |
-+ |
|
947 |
-+ return 0; |
|
948 |
-+} |
|
949 |
-+ |
|
950 |
-+_public_ int sd_radv_stop(sd_radv *ra) { |
|
951 |
-+ int r; |
|
952 |
-+ |
|
953 |
-+ assert_return(ra, -EINVAL); |
|
954 |
-+ |
|
955 |
-+ log_radv("Stopping IPv6 Router Advertisement daemon"); |
|
956 |
-+ |
|
957 |
-+ /* RFC 4861, Section 6.2.5, send at least one Router Advertisement |
|
958 |
-+ with zero lifetime */ |
|
959 |
-+ r = radv_send(ra, NULL, 0); |
|
960 |
-+ if (r < 0) |
|
961 |
-+ log_radv_warning_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m"); |
|
962 |
-+ |
|
963 |
-+ radv_reset(ra); |
|
964 |
-+ ra->fd = safe_close(ra->fd); |
|
965 |
-+ ra->state = SD_RADV_STATE_IDLE; |
|
966 |
-+ |
|
967 |
-+ return 0; |
|
968 |
-+} |
|
969 |
-+ |
|
970 |
-+_public_ int sd_radv_start(sd_radv *ra) { |
|
971 |
-+ int r = 0; |
|
972 |
-+ |
|
973 |
-+ assert_return(ra, -EINVAL); |
|
974 |
-+ assert_return(ra->event, -EINVAL); |
|
975 |
-+ assert_return(ra->ifindex > 0, -EINVAL); |
|
976 |
-+ |
|
977 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
978 |
-+ return 0; |
|
979 |
-+ |
|
980 |
-+ r = sd_event_add_time(ra->event, &ra->timeout_event_source, |
|
981 |
-+ clock_boottime_or_monotonic(), 0, 0, |
|
982 |
-+ radv_timeout, ra); |
|
983 |
-+ if (r < 0) |
|
984 |
-+ goto fail; |
|
985 |
-+ |
|
986 |
-+ r = sd_event_source_set_priority(ra->timeout_event_source, |
|
987 |
-+ ra->event_priority); |
|
988 |
-+ if (r < 0) |
|
989 |
-+ goto fail; |
|
990 |
-+ |
|
991 |
-+ (void) sd_event_source_set_description(ra->timeout_event_source, |
|
992 |
-+ "radv-timeout"); |
|
993 |
-+ |
|
994 |
-+ r = icmp6_bind_router_advertisement(ra->ifindex); |
|
995 |
-+ if (r < 0) |
|
996 |
-+ goto fail; |
|
997 |
-+ |
|
998 |
-+ ra->fd = r; |
|
999 |
-+ |
|
1000 |
-+ r = sd_event_add_io(ra->event, &ra->recv_event_source, ra->fd, EPOLLIN, radv_recv, ra); |
|
1001 |
-+ if (r < 0) |
|
1002 |
-+ goto fail; |
|
1003 |
-+ |
|
1004 |
-+ r = sd_event_source_set_priority(ra->recv_event_source, ra->event_priority); |
|
1005 |
-+ if (r < 0) |
|
1006 |
-+ goto fail; |
|
1007 |
-+ |
|
1008 |
-+ (void) sd_event_source_set_description(ra->recv_event_source, "radv-receive-message"); |
|
1009 |
-+ |
|
1010 |
-+ ra->state = SD_RADV_STATE_ADVERTISING; |
|
1011 |
-+ |
|
1012 |
-+ log_radv("Started IPv6 Router Advertisement daemon"); |
|
1013 |
-+ |
|
1014 |
-+ return 0; |
|
1015 |
-+ |
|
1016 |
-+ fail: |
|
1017 |
-+ radv_reset(ra); |
|
1018 |
-+ |
|
1019 |
-+ return r; |
|
1020 |
-+} |
|
1021 |
-+ |
|
1022 |
-+_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) { |
|
1023 |
-+ assert_return(ra, -EINVAL); |
|
1024 |
-+ assert_return(ifindex >= -1, -EINVAL); |
|
1025 |
-+ |
|
1026 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1027 |
-+ return -EBUSY; |
|
1028 |
-+ |
|
1029 |
-+ ra->ifindex = ifindex; |
|
1030 |
-+ |
|
1031 |
-+ return 0; |
|
1032 |
-+} |
|
1033 |
-+ |
|
1034 |
-+_public_ int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) { |
|
1035 |
-+ assert_return(ra, -EINVAL); |
|
1036 |
-+ |
|
1037 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1038 |
-+ return -EBUSY; |
|
1039 |
-+ |
|
1040 |
-+ if (mac_addr) |
|
1041 |
-+ ra->mac_addr = *mac_addr; |
|
1042 |
-+ else |
|
1043 |
-+ zero(ra->mac_addr); |
|
1044 |
-+ |
|
1045 |
-+ return 0; |
|
1046 |
-+} |
|
1047 |
-+ |
|
1048 |
-+_public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) { |
|
1049 |
-+ assert_return(ra, -EINVAL); |
|
1050 |
-+ assert_return(mtu >= 1280, -EINVAL); |
|
1051 |
-+ |
|
1052 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1053 |
-+ return -EBUSY; |
|
1054 |
-+ |
|
1055 |
-+ ra->mtu = mtu; |
|
1056 |
-+ |
|
1057 |
-+ return 0; |
|
1058 |
-+} |
|
1059 |
-+ |
|
1060 |
-+_public_ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) { |
|
1061 |
-+ assert_return(ra, -EINVAL); |
|
1062 |
-+ |
|
1063 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1064 |
-+ return -EBUSY; |
|
1065 |
-+ |
|
1066 |
-+ ra->hop_limit = hop_limit; |
|
1067 |
-+ |
|
1068 |
-+ return 0; |
|
1069 |
-+} |
|
1070 |
-+ |
|
1071 |
-+_public_ int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime) { |
|
1072 |
-+ assert_return(ra, -EINVAL); |
|
1073 |
-+ |
|
1074 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1075 |
-+ return -EBUSY; |
|
1076 |
-+ |
|
1077 |
-+ /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the |
|
1078 |
-+ preference value MUST be set to (00) by the sender..." */ |
|
1079 |
-+ if (router_lifetime == 0 && |
|
1080 |
-+ (ra->flags & (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM << 3)) |
|
1081 |
-+ return -ETIME; |
|
1082 |
-+ |
|
1083 |
-+ ra->lifetime = router_lifetime; |
|
1084 |
-+ |
|
1085 |
-+ return 0; |
|
1086 |
-+} |
|
1087 |
-+ |
|
1088 |
-+_public_ int sd_radv_set_managed_information(sd_radv *ra, int managed) { |
|
1089 |
-+ assert_return(ra, -EINVAL); |
|
1090 |
-+ |
|
1091 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1092 |
-+ return -EBUSY; |
|
1093 |
-+ |
|
1094 |
-+ SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, managed); |
|
1095 |
-+ |
|
1096 |
-+ return 0; |
|
1097 |
-+} |
|
1098 |
-+ |
|
1099 |
-+_public_ int sd_radv_set_other_information(sd_radv *ra, int other) { |
|
1100 |
-+ assert_return(ra, -EINVAL); |
|
1101 |
-+ |
|
1102 |
-+ if (ra->state != SD_RADV_STATE_IDLE) |
|
1103 |
-+ return -EBUSY; |
|
1104 |
-+ |
|
1105 |
-+ SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, other); |
|
1106 |
-+ |
|
1107 |
-+ return 0; |
|
1108 |
-+} |
|
1109 |
-+ |
|
1110 |
-+_public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) { |
|
1111 |
-+ int r = 0; |
|
1112 |
-+ |
|
1113 |
-+ assert_return(ra, -EINVAL); |
|
1114 |
-+ assert_return(IN_SET(preference, |
|
1115 |
-+ SD_NDISC_PREFERENCE_LOW, |
|
1116 |
-+ SD_NDISC_PREFERENCE_MEDIUM, |
|
1117 |
-+ SD_NDISC_PREFERENCE_HIGH), -EINVAL); |
|
1118 |
-+ |
|
1119 |
-+ ra->flags = (ra->flags & ~(0x3 << 3)) | (preference << 3); |
|
1120 |
-+ |
|
1121 |
-+ return r; |
|
1122 |
-+} |
|
1123 |
-+ |
|
1124 |
-+_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { |
|
1125 |
-+ sd_radv_prefix *cur; |
|
1126 |
-+ _cleanup_free_ char *addr_p = NULL; |
|
1127 |
-+ |
|
1128 |
-+ assert_return(ra, -EINVAL); |
|
1129 |
-+ |
|
1130 |
-+ if (!p) |
|
1131 |
-+ return -EINVAL; |
|
1132 |
-+ |
|
1133 |
-+ LIST_FOREACH(prefix, cur, ra->prefixes) { |
|
1134 |
-+ int r; |
|
1135 |
-+ |
|
1136 |
-+ r = in_addr_prefix_intersect(AF_INET6, |
|
1137 |
-+ (union in_addr_union*) &cur->opt.in6_addr, |
|
1138 |
-+ cur->opt.prefixlen, |
|
1139 |
-+ (union in_addr_union*) &p->opt.in6_addr, |
|
1140 |
-+ p->opt.prefixlen); |
|
1141 |
-+ if (r > 0) { |
|
1142 |
-+ _cleanup_free_ char *addr_cur = NULL; |
|
1143 |
-+ |
|
1144 |
-+ (void) in_addr_to_string(AF_INET6, |
|
1145 |
-+ (union in_addr_union*) &cur->opt.in6_addr, |
|
1146 |
-+ &addr_cur); |
|
1147 |
-+ (void) in_addr_to_string(AF_INET6, |
|
1148 |
-+ (union in_addr_union*) &p->opt.in6_addr, |
|
1149 |
-+ &addr_p); |
|
1150 |
-+ |
|
1151 |
-+ log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u", |
|
1152 |
-+ addr_cur, cur->opt.prefixlen, |
|
1153 |
-+ addr_p, p->opt.prefixlen); |
|
1154 |
-+ |
|
1155 |
-+ return -EEXIST; |
|
1156 |
-+ } |
|
1157 |
-+ } |
|
1158 |
-+ |
|
1159 |
-+ p = sd_radv_prefix_ref(p); |
|
1160 |
-+ |
|
1161 |
-+ LIST_APPEND(prefix, ra->prefixes, p); |
|
1162 |
-+ |
|
1163 |
-+ ra->n_prefixes++; |
|
1164 |
-+ |
|
1165 |
-+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p); |
|
1166 |
-+ log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen); |
|
1167 |
-+ |
|
1168 |
-+ return 0; |
|
1169 |
-+} |
|
1170 |
-+ |
|
1171 |
-+_public_ int sd_radv_prefix_new(sd_radv_prefix **ret) { |
|
1172 |
-+ _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL; |
|
1173 |
-+ |
|
1174 |
-+ assert_return(ret, -EINVAL); |
|
1175 |
-+ |
|
1176 |
-+ p = new0(sd_radv_prefix, 1); |
|
1177 |
-+ if (!p) |
|
1178 |
-+ return -ENOMEM; |
|
1179 |
-+ |
|
1180 |
-+ p->n_ref = 1; |
|
1181 |
-+ |
|
1182 |
-+ p->opt.type = ND_OPT_PREFIX_INFORMATION; |
|
1183 |
-+ p->opt.length = (sizeof(p->opt) - 1) /8 + 1; |
|
1184 |
-+ |
|
1185 |
-+ p->opt.prefixlen = 64; |
|
1186 |
-+ |
|
1187 |
-+ /* RFC 4861, Section 6.2.1 */ |
|
1188 |
-+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, true); |
|
1189 |
-+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, true); |
|
1190 |
-+ p->opt.preferred_lifetime = htobe32(604800); |
|
1191 |
-+ p->opt.valid_lifetime = htobe32(2592000); |
|
1192 |
-+ |
|
1193 |
-+ LIST_INIT(prefix, p); |
|
1194 |
-+ |
|
1195 |
-+ *ret = p; |
|
1196 |
-+ p = NULL; |
|
1197 |
-+ |
|
1198 |
-+ return 0; |
|
1199 |
-+} |
|
1200 |
-+ |
|
1201 |
-+_public_ sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *p) { |
|
1202 |
-+ if (!p) |
|
1203 |
-+ return NULL; |
|
1204 |
-+ |
|
1205 |
-+ assert(p->n_ref > 0); |
|
1206 |
-+ p->n_ref++; |
|
1207 |
-+ |
|
1208 |
-+ return p; |
|
1209 |
-+} |
|
1210 |
-+ |
|
1211 |
-+_public_ sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *p) { |
|
1212 |
-+ if (!p) |
|
1213 |
-+ return NULL; |
|
1214 |
-+ |
|
1215 |
-+ assert(p->n_ref > 0); |
|
1216 |
-+ p->n_ref--; |
|
1217 |
-+ |
|
1218 |
-+ if (p->n_ref > 0) |
|
1219 |
-+ return NULL; |
|
1220 |
-+ |
|
1221 |
-+ return mfree(p); |
|
1222 |
-+} |
|
1223 |
-+ |
|
1224 |
-+_public_ int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr, |
|
1225 |
-+ unsigned char prefixlen) { |
|
1226 |
-+ assert_return(p, -EINVAL); |
|
1227 |
-+ assert_return(in6_addr, -EINVAL); |
|
1228 |
-+ |
|
1229 |
-+ if (prefixlen < 3 || prefixlen > 128) |
|
1230 |
-+ return -EINVAL; |
|
1231 |
-+ |
|
1232 |
-+ if (prefixlen > 64) |
|
1233 |
-+ /* unusual but allowed, log it */ |
|
1234 |
-+ log_radv("Unusual prefix length %d greater than 64", prefixlen); |
|
1235 |
-+ |
|
1236 |
-+ p->opt.in6_addr = *in6_addr; |
|
1237 |
-+ p->opt.prefixlen = prefixlen; |
|
1238 |
-+ |
|
1239 |
-+ return 0; |
|
1240 |
-+} |
|
1241 |
-+ |
|
1242 |
-+_public_ int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink) { |
|
1243 |
-+ assert_return(p, -EINVAL); |
|
1244 |
-+ |
|
1245 |
-+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, onlink); |
|
1246 |
-+ |
|
1247 |
-+ return 0; |
|
1248 |
-+} |
|
1249 |
-+ |
|
1250 |
-+_public_ int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p, |
|
1251 |
-+ int address_autoconfiguration) { |
|
1252 |
-+ assert_return(p, -EINVAL); |
|
1253 |
-+ |
|
1254 |
-+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, address_autoconfiguration); |
|
1255 |
-+ |
|
1256 |
-+ return 0; |
|
1257 |
-+} |
|
1258 |
-+ |
|
1259 |
-+_public_ int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p, |
|
1260 |
-+ uint32_t valid_lifetime) { |
|
1261 |
-+ assert_return(p, -EINVAL); |
|
1262 |
-+ |
|
1263 |
-+ p->opt.valid_lifetime = htobe32(valid_lifetime); |
|
1264 |
-+ |
|
1265 |
-+ return 0; |
|
1266 |
-+} |
|
1267 |
-+ |
|
1268 |
-+_public_ int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p, |
|
1269 |
-+ uint32_t preferred_lifetime) { |
|
1270 |
-+ assert_return(p, -EINVAL); |
|
1271 |
-+ |
|
1272 |
-+ p->opt.preferred_lifetime = htobe32(preferred_lifetime); |
|
1273 |
-+ |
|
1274 |
-+ return 0; |
|
1275 |
-+} |
|
1276 |
-diff -rupN systemd-base/src/libsystemd-network/test-ndisc-rs.c systemd/src/libsystemd-network/test-ndisc-rs.c |
|
1277 |
-+++ systemd/src/libsystemd-network/test-ndisc-rs.c 2017-09-18 15:07:09.099322638 -0700 |
|
1278 |
-@@ -193,6 +193,21 @@ int icmp6_bind_router_solicitation(int i |
|
1279 |
- return test_fd[0]; |
|
1280 |
- } |
|
1281 |
- |
|
1282 |
-+int icmp6_bind_router_advertisement(int index) { |
|
1283 |
-+ |
|
1284 |
-+ return -ENOSYS; |
|
1285 |
-+} |
|
1286 |
-+ |
|
1287 |
-+int icmp6_receive(int fd, void *iov_base, size_t iov_len, |
|
1288 |
-+ struct in6_addr *dst, triple_timestamp *timestamp) { |
|
1289 |
-+ assert (read (fd, iov_base, iov_len) == (ssize_t)iov_len); |
|
1290 |
-+ |
|
1291 |
-+ if (timestamp) |
|
1292 |
-+ triple_timestamp_get(timestamp); |
|
1293 |
-+ |
|
1294 |
-+ return 0; |
|
1295 |
-+} |
|
1296 |
-+ |
|
1297 |
- static int send_ra(uint8_t flags) { |
|
1298 |
- uint8_t advertisement[] = { |
|
1299 |
- 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4, |
|
1300 |
-diff -rupN systemd-base/src/network/networkd-ndisc.c systemd/src/network/networkd-ndisc.c |
|
1301 |
-+++ systemd/src/network/networkd-ndisc.c 2017-09-18 14:39:40.690643380 -0700 |
|
1302 |
-@@ -27,6 +27,7 @@ |
|
1303 |
- |
|
1304 |
- #define NDISC_DNSSL_MAX 64U |
|
1305 |
- #define NDISC_RDNSS_MAX 64U |
|
1306 |
-+#define NDISC_PREFIX_LFT_MIN 7200U |
|
1307 |
- |
|
1308 |
- static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { |
|
1309 |
- _cleanup_link_unref_ Link *link = userdata; |
|
1310 |
-@@ -152,13 +153,21 @@ static void ndisc_router_process_default |
|
1311 |
- |
|
1312 |
- static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) { |
|
1313 |
- _cleanup_address_free_ Address *address = NULL; |
|
1314 |
-- uint32_t lifetime_valid, lifetime_preferred; |
|
1315 |
-+ Address *existing_address; |
|
1316 |
-+ uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining; |
|
1317 |
-+ usec_t time_now; |
|
1318 |
- unsigned prefixlen; |
|
1319 |
- int r; |
|
1320 |
- |
|
1321 |
- assert(link); |
|
1322 |
- assert(rt); |
|
1323 |
- |
|
1324 |
-+ r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); |
|
1325 |
-+ if (r < 0) { |
|
1326 |
-+ log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); |
|
1327 |
-+ return; |
|
1328 |
-+ } |
|
1329 |
-+ |
|
1330 |
- r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen); |
|
1331 |
- if (r < 0) { |
|
1332 |
- log_link_error_errno(link, r, "Failed to get prefix length: %m"); |
|
1333 |
-@@ -207,7 +216,24 @@ static void ndisc_router_process_autonom |
|
1334 |
- address->prefixlen = prefixlen; |
|
1335 |
- address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR; |
|
1336 |
- address->cinfo.ifa_prefered = lifetime_preferred; |
|
1337 |
-- address->cinfo.ifa_valid = lifetime_valid; |
|
1338 |
-+ |
|
1339 |
-+ /* see RFC4862 section 5.5.3.e */ |
|
1340 |
-+ r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address); |
|
1341 |
-+ if (r > 0) { |
|
1342 |
-+ lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC; |
|
1343 |
-+ if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining) |
|
1344 |
-+ address->cinfo.ifa_valid = lifetime_valid; |
|
1345 |
-+ else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN) |
|
1346 |
-+ address->cinfo.ifa_valid = lifetime_remaining; |
|
1347 |
-+ else |
|
1348 |
-+ address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN; |
|
1349 |
-+ } else if (lifetime_valid > 0) |
|
1350 |
-+ address->cinfo.ifa_valid = lifetime_valid; |
|
1351 |
-+ else |
|
1352 |
-+ return; /* see RFC4862 section 5.5.3.d */ |
|
1353 |
-+ |
|
1354 |
-+ if (address->cinfo.ifa_valid == 0) |
|
1355 |
-+ return; |
|
1356 |
- |
|
1357 |
- r = address_configure(address, link, ndisc_netlink_handler, true); |
|
1358 |
- if (r < 0) { |
|
1359 |
-diff -rupN systemd-base/src/systemd/sd-radv.h systemd/src/systemd/sd-radv.h |
|
1360 |
-+++ systemd/src/systemd/sd-radv.h 2017-09-18 14:58:44.807575602 -0700 |
|
1361 |
-@@ -0,0 +1,81 @@ |
|
1362 |
-+#ifndef foosdradvfoo |
|
1363 |
-+#define foosdradvfoo |
|
1364 |
-+ |
|
1365 |
-+/*** |
|
1366 |
-+ This file is part of systemd. |
|
1367 |
-+ |
|
1368 |
-+ Copyright (C) 2017 Intel Corporation. All rights reserved. |
|
1369 |
-+ |
|
1370 |
-+ systemd is free software; you can redistribute it and/or modify it |
|
1371 |
-+ under the terms of the GNU Lesser General Public License as published by |
|
1372 |
-+ the Free Software Foundation; either version 2.1 of the License, or |
|
1373 |
-+ (at your option) any later version. |
|
1374 |
-+ |
|
1375 |
-+ systemd is distributed in the hope that it will be useful, but |
|
1376 |
-+ WITHOUT ANY WARRANTY; without even the implied warranty of |
|
1377 |
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
1378 |
-+ Lesser General Public License for more details. |
|
1379 |
-+ |
|
1380 |
-+ You should have received a copy of the GNU Lesser General Public License |
|
1381 |
-+ along with systemd; If not, see <http://www.gnu.org/licenses/>. |
|
1382 |
-+***/ |
|
1383 |
-+ |
|
1384 |
-+#include <inttypes.h> |
|
1385 |
-+#include <net/ethernet.h> |
|
1386 |
-+#include <netinet/in.h> |
|
1387 |
-+#include <sys/types.h> |
|
1388 |
-+ |
|
1389 |
-+#include "sd-ndisc.h" |
|
1390 |
-+ |
|
1391 |
-+#include "sd-event.h" |
|
1392 |
-+ |
|
1393 |
-+#include "_sd-common.h" |
|
1394 |
-+ |
|
1395 |
-+_SD_BEGIN_DECLARATIONS; |
|
1396 |
-+ |
|
1397 |
-+typedef struct sd_radv sd_radv; |
|
1398 |
-+typedef struct sd_radv_prefix sd_radv_prefix; |
|
1399 |
-+ |
|
1400 |
-+/* Router Advertisment */ |
|
1401 |
-+int sd_radv_new(sd_radv **ret); |
|
1402 |
-+sd_radv *sd_radv_ref(sd_radv *ra); |
|
1403 |
-+sd_radv *sd_radv_unref(sd_radv *ra); |
|
1404 |
-+ |
|
1405 |
-+int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority); |
|
1406 |
-+int sd_radv_detach_event(sd_radv *nd); |
|
1407 |
-+sd_event *sd_radv_get_event(sd_radv *ra); |
|
1408 |
-+ |
|
1409 |
-+int sd_radv_start(sd_radv *ra); |
|
1410 |
-+int sd_radv_stop(sd_radv *ra); |
|
1411 |
-+ |
|
1412 |
-+int sd_radv_set_ifindex(sd_radv *ra, int interface_index); |
|
1413 |
-+int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr); |
|
1414 |
-+int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu); |
|
1415 |
-+int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit); |
|
1416 |
-+int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime); |
|
1417 |
-+int sd_radv_set_managed_information(sd_radv *ra, int managed); |
|
1418 |
-+int sd_radv_set_other_information(sd_radv *ra, int other); |
|
1419 |
-+int sd_radv_set_preference(sd_radv *ra, unsigned preference); |
|
1420 |
-+int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p); |
|
1421 |
-+ |
|
1422 |
-+/* Advertised prefixes */ |
|
1423 |
-+int sd_radv_prefix_new(sd_radv_prefix **ret); |
|
1424 |
-+sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *ra); |
|
1425 |
-+sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *ra); |
|
1426 |
-+ |
|
1427 |
-+int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr, |
|
1428 |
-+ unsigned char prefixlen); |
|
1429 |
-+int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink); |
|
1430 |
-+int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p, |
|
1431 |
-+ int address_autoconfiguration); |
|
1432 |
-+int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p, |
|
1433 |
-+ uint32_t valid_lifetime); |
|
1434 |
-+int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p, |
|
1435 |
-+ uint32_t preferred_lifetime); |
|
1436 |
-+ |
|
1437 |
-+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref); |
|
1438 |
-+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_prefix, sd_radv_prefix_unref); |
|
1439 |
-+ |
|
1440 |
-+_SD_END_DECLARATIONS; |
|
1441 |
-+ |
|
1442 |
-+#endif |
1443 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,12 +0,0 @@ |
1 |
-diff -rup systemd-232/tmpfiles.d/etc.conf.m4 systemd-232-new/tmpfiles.d/etc.conf.m4 |
|
2 |
-+++ systemd-232-new/tmpfiles.d/etc.conf.m4 2016-11-23 16:39:04.837676446 -0800 |
|
3 |
-@@ -14,7 +14,7 @@ m4_ifdef(`HAVE_SMACK_RUN_LABEL', |
|
4 |
- t /etc/mtab - - - - security.SMACK64=_ |
|
5 |
- )m4_dnl |
|
6 |
- m4_ifdef(`ENABLE_RESOLVED', |
|
7 |
--L! /etc/resolv.conf - - - - ../usr/lib/systemd/resolv.conf |
|
8 |
-+L! /etc/resolv.conf - - - - ../run/systemd/resolve/resolv.conf |
|
9 |
- )m4_dnl |
|
10 |
- C /etc/nsswitch.conf - - - - |
|
11 |
- m4_ifdef(`HAVE_PAM', |
12 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,23 @@ |
0 |
+diff -uNr systemd-233/src/resolve/resolved-conf.c systemd-233-new/src/resolve/resolved-conf.c |
|
1 |
+--- systemd-233/src/resolve/resolved-conf.c 2017-03-01 21:43:06.000000000 +0000 |
|
2 |
+@@ -229,6 +229,7 @@ |
|
3 |
+ |
|
4 |
+ int manager_parse_config_file(Manager *m) { |
|
5 |
+ int r; |
|
6 |
++ char *default_dns_servers; |
|
7 |
+ |
|
8 |
+ assert(m); |
|
9 |
+ |
|
10 |
+@@ -241,7 +242,10 @@ |
|
11 |
+ return r; |
|
12 |
+ |
|
13 |
+ if (m->need_builtin_fallbacks) { |
|
14 |
+- r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS); |
|
15 |
++ default_dns_servers = secure_getenv("DEFAULT_DNS_SERVERS"); |
|
16 |
++ if (default_dns_servers == NULL) |
|
17 |
++ default_dns_servers = DNS_SERVERS; |
|
18 |
++ r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, default_dns_servers); |
|
19 |
+ if (r < 0) |
|
20 |
+ return r; |
|
21 |
+ } |
... | ... |
@@ -1,14 +1,14 @@ |
1 |
-Summary: Systemd-233 |
|
1 |
+Summary: Systemd-236 |
|
2 | 2 |
Name: systemd |
3 |
-Version: 233 |
|
4 |
-Release: 11%{?dist} |
|
3 |
+Version: 236 |
|
4 |
+Release: 1%{?dist} |
|
5 | 5 |
License: LGPLv2+ and GPLv2+ and MIT |
6 | 6 |
URL: http://www.freedesktop.org/wiki/Software/systemd/ |
7 | 7 |
Group: System Environment/Security |
8 | 8 |
Vendor: VMware, Inc. |
9 | 9 |
Distribution: Photon |
10 | 10 |
Source0: %{name}-%{version}.tar.gz |
11 |
-%define sha1 systemd=432ec4ce665f65d1d616558358fb7e7cba953930 |
|
11 |
+%define sha1 systemd=eab372a3441997dfba1dfa41183918764c31a7df |
|
12 | 12 |
Source1: 99-vmware-hotplug.rules |
13 | 13 |
Source2: 50-security-hardening.conf |
14 | 14 |
Source3: systemd.cfg |
... | ... |
@@ -16,24 +16,18 @@ Source4: 99-dhcp-en.network |
16 | 16 |
|
17 | 17 |
Patch0: 01-enoX-uses-instance-number-for-vmware-hv.patch |
18 | 18 |
Patch1: 02-install-general-aliases.patch |
19 |
-Patch2: systemd-233-query-duid.patch |
|
20 |
-Patch3: systemd-233-ipv6-disabled-fix.patch |
|
21 |
-Patch4: systemd-233-default-dns-from-env.patch |
|
22 |
-Patch5: systemd-macros.patch |
|
23 |
-Patch6: systemd-233-resolv-conf-symlink.patch |
|
24 |
-Patch7: systemd-233-CVE-2017-9217.patch |
|
25 |
-Patch8: systemd-233-CVE-2017-9445-dns-oob.patch |
|
26 |
-Patch9: systemd-233-CVE-2017-1000082-1.patch |
|
27 |
-Patch10: systemd-233-CVE-2017-1000082-2.patch |
|
28 |
-Patch11: systemd-233-ra-improvements.patch |
|
29 |
-Patch12: systemd-233-link-disabled-nullptr-fix.patch |
|
30 |
-Patch13: systemd-228-CVE-2017-15908-dns-pkt-loop-fix.patch |
|
19 |
+Patch2: systemd-236-default-dns-from-env.patch |
|
20 |
+Patch3: systemd-macros.patch |
|
21 |
+ |
|
22 |
+#TODO: Verify this patch is necessary or not |
|
23 |
+#Patch4: systemd-233-query-duid.patch |
|
31 | 24 |
|
32 | 25 |
Requires: Linux-PAM |
33 | 26 |
Requires: libcap |
34 | 27 |
Requires: xz |
35 | 28 |
Requires: kmod |
36 | 29 |
Requires: glib |
30 |
+Requires: libgcrypt |
|
37 | 31 |
Requires: filesystem >= 1.1 |
38 | 32 |
BuildRequires: intltool |
39 | 33 |
BuildRequires: gperf |
... | ... |
@@ -43,11 +37,15 @@ BuildRequires: Linux-PAM-devel |
43 | 43 |
BuildRequires: XML-Parser |
44 | 44 |
BuildRequires: kbd |
45 | 45 |
BuildRequires: kmod-devel |
46 |
-BuildRequires: util-linux-devel |
|
46 |
+BuildRequires: util-linux-devel >= 2.30 |
|
47 | 47 |
BuildRequires: libxslt |
48 | 48 |
BuildRequires: docbook-xsl |
49 | 49 |
BuildRequires: docbook-xml |
50 | 50 |
BuildRequires: glib-devel |
51 |
+BuildRequires: meson |
|
52 |
+BuildRequires: gettext |
|
53 |
+BuildRequires: shadow |
|
54 |
+BuildRequires: libgcrypt-devel |
|
51 | 55 |
|
52 | 56 |
%description |
53 | 57 |
Systemd is an init replacement with better process control and security |
... | ... |
@@ -75,57 +73,44 @@ BLKID_LIBS="-lblkid" |
75 | 75 |
BLKID_CFLAGS="-I/usr/include/blkid" |
76 | 76 |
cc_cv_CFLAGS__flto=no |
77 | 77 |
EOF |
78 |
-sed -i "s:blkid/::" $(grep -rl "blkid/blkid.h") |
|
79 |
-# xlocale.h has been removed from glibc 2.26 |
|
80 |
-# The above include of locale.h is sufficient |
|
81 |
-# Further details: https://sourceware.org/git/?p=glibc.git;a=commit;h=f0be25b6336db7492e47d2e8e72eb8af53b5506d */ |
|
82 |
-sed -i "/xlocale.h/d" src/basic/parse-util.c |
|
83 | 78 |
|
84 | 79 |
%patch0 -p1 |
85 | 80 |
%patch1 -p1 |
86 | 81 |
%patch2 -p1 |
87 | 82 |
%patch3 -p1 |
88 |
-%patch4 -p1 |
|
89 |
-%patch5 -p1 |
|
90 |
-%patch6 -p1 |
|
91 |
-%patch7 -p1 |
|
92 |
-%patch8 -p1 |
|
93 |
-%patch9 -p1 |
|
94 |
-%patch10 -p1 |
|
95 |
-%patch11 -p1 |
|
96 |
-%patch12 -p1 |
|
97 |
-%patch13 -p1 |
|
98 | 83 |
|
99 | 84 |
sed -i "s#\#DefaultTasksMax=512#DefaultTasksMax=infinity#g" src/core/system.conf |
100 | 85 |
|
101 | 86 |
%build |
102 |
-./autogen.sh |
|
103 |
-./configure --prefix=%{_prefix} \ |
|
104 |
- --sysconfdir=/etc \ |
|
105 |
- --localstatedir=/var \ |
|
106 |
- --config-cache \ |
|
107 |
- --with-rootprefix= \ |
|
108 |
- --with-rootlibdir=/usr/lib \ |
|
109 |
- --enable-split-usr \ |
|
110 |
- --disable-firstboot \ |
|
111 |
- --disable-ldconfig \ |
|
112 |
- --disable-sysusers \ |
|
113 |
- --without-python \ |
|
114 |
- --enable-pam \ |
|
115 |
- --docdir=%{_prefix}/share/doc/systemd-228 \ |
|
116 |
- --with-dbuspolicydir=/etc/dbus-1/system.d \ |
|
117 |
- --with-dbusinterfacedir=%{_prefix}/share/dbus-1/interfaces \ |
|
118 |
- --with-dbussessionservicedir=%{_prefix}/share/dbus-1/services \ |
|
119 |
- --with-dbussystemservicedir=%{_prefix}/share/dbus-1/system-services \ |
|
120 |
- --enable-compat-libs \ |
|
121 |
- --disable-elfutils \ |
|
122 |
- --with-sysvinit-path=/etc/rc.d/init.d \ |
|
123 |
- --with-rc-local-script-path-start=/etc/rc.d/rc.local |
|
87 |
+export LANG=en_US.UTF-8 |
|
88 |
+export LC_ALL=en_US.UTF-8 |
|
89 |
+meson --prefix %{_prefix} \ |
|
90 |
+ --sysconfdir /etc \ |
|
91 |
+ --localstatedir /var \ |
|
92 |
+ -Dblkid=true \ |
|
93 |
+ -Dbuildtype=release \ |
|
94 |
+ -Ddefault-dnssec=no \ |
|
95 |
+ -Dfirstboot=false \ |
|
96 |
+ -Dinstall-tests=false \ |
|
97 |
+ -Dldconfig=false \ |
|
98 |
+ -Drootprefix= \ |
|
99 |
+ -Drootlibdir=/lib \ |
|
100 |
+ -Dsplit-usr=true \ |
|
101 |
+ -Dsysusers=false \ |
|
102 |
+ -Dpam=true \ |
|
103 |
+ -Dpolkit=true \ |
|
104 |
+ -Ddbuspolicydir=/etc/dbus-1/system.d \ |
|
105 |
+ -Ddbussessionservicedir=%{_prefix}/share/dbus-1/services \ |
|
106 |
+ -Ddbussystemservicedir=%{_prefix}/share/dbus-1/system-services \ |
|
107 |
+ -Dsysvinit-path=/etc/rc.d/init.d \ |
|
108 |
+ -Drc-local=/etc/rc.d/rc.local \ |
|
109 |
+ $PWD build && |
|
110 |
+ cd build && |
|
111 |
+ %ninja_build |
|
124 | 112 |
|
125 |
-make %{?_smp_mflags} |
|
126 | 113 |
%install |
127 |
-[ %{buildroot} != "/"] && rm -rf %{buildroot}/* |
|
128 |
-make DESTDIR=%{buildroot} install |
|
114 |
+cd build && %ninja_install |
|
115 |
+ |
|
129 | 116 |
install -vdm 755 %{buildroot}/sbin |
130 | 117 |
for tool in runlevel reboot shutdown poweroff halt telinit; do |
131 | 118 |
ln -sfv ../bin/systemctl %{buildroot}/sbin/${tool} |
... | ... |
@@ -147,7 +132,7 @@ rm %{buildroot}/lib/systemd/system/default.target |
147 | 147 |
ln -sfv multi-user.target %{buildroot}/lib/systemd/system/default.target |
148 | 148 |
install -dm 0755 %{buildroot}/%{_sysconfdir}/systemd/network |
149 | 149 |
install -m 0644 %{SOURCE4} %{buildroot}/%{_sysconfdir}/systemd/network |
150 |
-%find_lang %{name} |
|
150 |
+%find_lang %{name} ../%{name}.lang |
|
151 | 151 |
|
152 | 152 |
%post |
153 | 153 |
/sbin/ldconfig |
... | ... |
@@ -203,18 +188,18 @@ rm -rf %{buildroot}/* |
203 | 203 |
/lib/systemd/resolv.conf |
204 | 204 |
%config(noreplace) /lib/systemd/network/99-default.link |
205 | 205 |
%{_libdir}/environment.d/99-environment.conf |
206 |
-/var/lib/polkit-1/localauthority/10-vendor.d/systemd-networkd.pkla |
|
207 | 206 |
%exclude %{_libdir}/debug |
208 | 207 |
%exclude %{_datadir}/locale |
209 | 208 |
%{_libdir}/binfmt.d |
210 | 209 |
%{_libdir}/kernel |
211 | 210 |
%{_libdir}/modules-load.d |
212 | 211 |
%{_libdir}/rpm |
213 |
-%{_libdir}/security |
|
212 |
+/lib/security |
|
214 | 213 |
%{_libdir}/sysctl.d |
215 | 214 |
%{_libdir}/systemd |
216 | 215 |
%{_libdir}/tmpfiles.d |
217 |
-%{_libdir}/*.so* |
|
216 |
+/lib/*.so* |
|
217 |
+/lib/modprobe.d/systemd.conf |
|
218 | 218 |
%{_bindir}/* |
219 | 219 |
/bin/* |
220 | 220 |
/sbin/* |
... | ... |
@@ -230,8 +215,8 @@ rm -rf %{buildroot}/* |
230 | 230 |
|
231 | 231 |
%files devel |
232 | 232 |
%dir %{_includedir}/systemd |
233 |
-%{_libdir}/libudev.so |
|
234 |
-%{_libdir}/libsystemd.so |
|
233 |
+/lib/libudev.so |
|
234 |
+/lib/libsystemd.so |
|
235 | 235 |
%{_includedir}/systemd/*.h |
236 | 236 |
%{_includedir}/libudev.h |
237 | 237 |
%{_libdir}/pkgconfig/libudev.pc |
... | ... |
@@ -243,6 +228,8 @@ rm -rf %{buildroot}/* |
243 | 243 |
%files lang -f %{name}.lang |
244 | 244 |
|
245 | 245 |
%changelog |
246 |
+* Fri Dec 29 2017 Anish Swaminathan <anishs@vmware.com> 236-1 |
|
247 |
+- Update systemd to 236 |
|
246 | 248 |
* Thu Nov 09 2017 Vinay Kulkarni <kulkarniv@vmware.com> 233-11 |
247 | 249 |
- Fix CVE-2017-15908 dns packet loop fix. |
248 | 250 |
* Tue Nov 07 2017 Vinay Kulkarni <kulkarniv@vmware.com> 233-10 |
... | ... |
@@ -1,14 +1,14 @@ |
1 | 1 |
Summary: Utilities for file systems, consoles, partitions, and messages |
2 | 2 |
Name: util-linux |
3 |
-Version: 2.29.2 |
|
4 |
-Release: 5%{?dist} |
|
3 |
+Version: 2.31.1 |
|
4 |
+Release: 1%{?dist} |
|
5 | 5 |
URL: http://www.kernel.org/pub/linux/utils/util-linux |
6 | 6 |
License: GPLv2+ |
7 | 7 |
Group: Applications/System |
8 | 8 |
Vendor: VMware, Inc. |
9 | 9 |
Distribution: Photon |
10 | 10 |
Source0: %{name}-%{version}.tar.xz |
11 |
-%define sha1 util-linux=b488f185e74187a63b55baef9d3f48d5b1780118 |
|
11 |
+%define sha1 util-linux=66e1eaeedfb3137b1e583d038a4a3f404474ded1 |
|
12 | 12 |
BuildRequires: ncurses-devel |
13 | 13 |
%if %{with_check} |
14 | 14 |
BuildRequires: ncurses-terminfo |
... | ... |
@@ -97,6 +97,8 @@ rm -rf %{buildroot}/lib/systemd/system |
97 | 97 |
%{_mandir}/man3/* |
98 | 98 |
|
99 | 99 |
%changelog |
100 |
+* Wed Dec 27 2017 Anish Swaminathan <anishs@vmware.com> 2.31.1-1 |
|
101 |
+- Upgrade to version 2.31.1. |
|
100 | 102 |
* Mon Oct 02 2017 Alexey Makhalov <amakhalov@vmware.com> 2.29.2-5 |
101 | 103 |
- Added conflicts toybox |
102 | 104 |
* Fri Sep 15 2017 Bo Gan <ganb@vmware.com> 2.29.2-4 |
... | ... |
@@ -3,7 +3,6 @@ |
3 | 3 |
# Author: Mahmoud Bassiouny <mbassiouny@vmware.com> |
4 | 4 |
|
5 | 5 |
import subprocess |
6 |
-import curses |
|
7 | 6 |
import os |
8 | 7 |
import shutil |
9 | 8 |
import signal |
... | ... |
@@ -34,7 +33,7 @@ class Installer(object): |
34 | 34 |
else: |
35 | 35 |
self.working_directory = "/mnt/photon-root" |
36 | 36 |
self.photon_root = self.working_directory + "/photon-chroot" |
37 |
- |
|
37 |
+ self.rpms_tobeinstalled = None |
|
38 | 38 |
self.restart_command = "shutdown" |
39 | 39 |
|
40 | 40 |
if self.iso_installer: |
... | ... |
@@ -62,7 +61,9 @@ class Installer(object): |
62 | 62 |
signal.signal(signal.SIGINT, self.exit_gracefully) |
63 | 63 |
|
64 | 64 |
# This will be called if the installer interrupted by Ctrl+C or exception |
65 |
- def exit_gracefully(self, signal, frame): |
|
65 |
+ def exit_gracefully(self, signal1, frame1): |
|
66 |
+ del signal1 |
|
67 |
+ del frame1 |
|
66 | 68 |
if self.iso_installer: |
67 | 69 |
self.progress_bar.hide() |
68 | 70 |
self.window.addstr(0, 0, 'Oops, Installer got interrupted.\n\n' + |
... | ... |
@@ -73,8 +74,9 @@ class Installer(object): |
73 | 73 |
sys.exit(1) |
74 | 74 |
|
75 | 75 |
def install(self, params): |
76 |
+ del params |
|
76 | 77 |
try: |
77 |
- return self.unsafe_install(params) |
|
78 |
+ return self.unsafe_install() |
|
78 | 79 |
except Exception as inst: |
79 | 80 |
if self.iso_installer: |
80 | 81 |
modules.commons.log(modules.commons.LOG_ERROR, repr(inst)) |
... | ... |
@@ -82,105 +84,13 @@ class Installer(object): |
82 | 82 |
else: |
83 | 83 |
raise |
84 | 84 |
|
85 |
- def unsafe_install(self, params): |
|
86 |
- |
|
87 |
- if self.iso_installer: |
|
88 |
- self.window.show_window() |
|
89 |
- self.progress_bar.initialize('Initializing installation...') |
|
90 |
- self.progress_bar.show() |
|
91 |
- #self.rpm_path = "https://dl.bintray.com/vmware/photon_release_1.0_TP2_x86_64" |
|
92 |
- if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"): |
|
93 |
- cmdoption = 's/baseurl.*/baseurl={}/g'.format(self.rpm_path.replace('/', '\/')) |
|
94 |
- process = subprocess.Popen(['sed', '-i', cmdoption, |
|
95 |
- '/etc/yum.repos.d/photon-iso.repo']) |
|
96 |
- retval = process.wait() |
|
97 |
- if retval != 0: |
|
98 |
- modules.commons.log(modules.commons.LOG_INFO, "Failed to reset repo") |
|
99 |
- self.exit_gracefully(None, None) |
|
100 |
- |
|
101 |
- cmdoption = ('s/cachedir=\/var/cachedir={}/g' |
|
102 |
- .format(self.photon_root.replace('/', '\/'))) |
|
103 |
- process = subprocess.Popen(['sed', '-i', cmdoption, '/etc/tdnf/tdnf.conf']) |
|
104 |
- retval = process.wait() |
|
105 |
- if retval != 0: |
|
106 |
- modules.commons.log(modules.commons.LOG_INFO, "Failed to reset tdnf cachedir") |
|
107 |
- self.exit_gracefully(None, None) |
|
85 |
+ def unsafe_install(self): |
|
86 |
+ self.setup_install_repo() |
|
108 | 87 |
self.execute_modules(modules.commons.PRE_INSTALL) |
109 | 88 |
|
110 | 89 |
self.initialize_system() |
111 |
- |
|
112 |
- if self.iso_installer: |
|
113 |
- self.adjust_packages_for_vmware_virt() |
|
114 |
- selected_packages = self.install_config['packages'] |
|
115 |
- state = 0 |
|
116 |
- packages_to_install = {} |
|
117 |
- total_size = 0 |
|
118 |
- with open(modules.commons.TDNF_CMDLINE_FILE_NAME, "w") as tdnf_cmdline_file: |
|
119 |
- tdnf_cmdline_file.write("tdnf install --installroot {0} --nogpgcheck {1}" |
|
120 |
- .format(self.photon_root, " ".join(selected_packages))) |
|
121 |
- with open(modules.commons.TDNF_LOG_FILE_NAME, "w") as tdnf_errlog: |
|
122 |
- process = subprocess.Popen(['tdnf', 'install'] + selected_packages + |
|
123 |
- ['--installroot', self.photon_root, '--nogpgcheck', |
|
124 |
- '--assumeyes'], stdout=subprocess.PIPE, |
|
125 |
- stderr=tdnf_errlog) |
|
126 |
- while True: |
|
127 |
- output = process.stdout.readline().decode() |
|
128 |
- if output == '': |
|
129 |
- retval = process.poll() |
|
130 |
- if retval is not None: |
|
131 |
- break |
|
132 |
- if state == 0: |
|
133 |
- if output == 'Installing:\n': |
|
134 |
- state = 1 |
|
135 |
- elif state == 1: #N A EVR Size(readable) Size(in bytes) |
|
136 |
- if output == '\n': |
|
137 |
- state = 2 |
|
138 |
- self.progress_bar.update_num_items(total_size) |
|
139 |
- else: |
|
140 |
- info = output.split() |
|
141 |
- package = '{0}-{1}.{2}'.format(info[0], info[2], info[1]) |
|
142 |
- packages_to_install[package] = int(info[5]) |
|
143 |
- total_size += int(info[5]) |
|
144 |
- elif state == 2: |
|
145 |
- if output == 'Downloading:\n': |
|
146 |
- self.progress_bar.update_message('Preparing ...') |
|
147 |
- state = 3 |
|
148 |
- elif state == 3: |
|
149 |
- self.progress_bar.update_message(output) |
|
150 |
- if output == 'Running transaction\n': |
|
151 |
- state = 4 |
|
152 |
- else: |
|
153 |
- modules.commons.log(modules.commons.LOG_INFO, "[tdnf] {0}".format(output)) |
|
154 |
- prefix = 'Installing/Updating: ' |
|
155 |
- if output.startswith(prefix): |
|
156 |
- package = output[len(prefix):].rstrip('\n') |
|
157 |
- self.progress_bar.increment(packages_to_install[package]) |
|
158 |
- |
|
159 |
- self.progress_bar.update_message(output) |
|
160 |
- # 0 : succeed; 137 : package already installed; 65 : package not found in repo. |
|
161 |
- if retval != 0 and retval != 137: |
|
162 |
- modules.commons.log(modules.commons.LOG_ERROR, |
|
163 |
- "Failed to install some packages, refer to {0}" |
|
164 |
- .format(modules.commons.TDNF_LOG_FILE_NAME)) |
|
165 |
- self.exit_gracefully(None, None) |
|
166 |
- else: |
|
167 |
- #install packages |
|
168 |
- rpms = [] |
|
169 |
- for rpm in self.rpms_tobeinstalled: |
|
170 |
- # We already installed the filesystem in the preparation |
|
171 |
- if rpm['package'] == 'filesystem': |
|
172 |
- continue |
|
173 |
- rpms.append(rpm['filename']) |
|
174 |
- return_value = self.install_package(rpms) |
|
175 |
- if return_value != 0: |
|
176 |
- self.exit_gracefully(None, None) |
|
177 |
- |
|
178 |
- |
|
179 |
- if self.iso_installer: |
|
180 |
- self.progress_bar.show_loading('Finalizing installation') |
|
181 |
- |
|
182 |
- if os.path.exists("/etc/resolv.conf"): |
|
183 |
- shutil.copy("/etc/resolv.conf", self.photon_root + '/etc/.') |
|
90 |
+ self.install_packages() |
|
91 |
+ self.enable_network_in_chroot() |
|
184 | 92 |
self.finalize_system() |
185 | 93 |
|
186 | 94 |
if not self.install_config['iso_system']: |
... | ... |
@@ -228,9 +138,7 @@ class Installer(object): |
228 | 228 |
retval = process.wait() |
229 | 229 |
|
230 | 230 |
self.update_fstab() |
231 |
- |
|
232 |
- if os.path.exists(self.photon_root + '/etc/resolv.conf'): |
|
233 |
- os.remove(self.photon_root + '/etc/resolv.conf') |
|
231 |
+ self.disable_network_in_chroot() |
|
234 | 232 |
|
235 | 233 |
command = [self.unmount_disk_command, '-w', self.photon_root] |
236 | 234 |
if not self.install_config['iso_system']: |
... | ... |
@@ -240,17 +148,10 @@ class Installer(object): |
240 | 240 |
|
241 | 241 |
if self.iso_installer: |
242 | 242 |
self.progress_bar.hide() |
243 |
- self.window.addstr(0, 0, 'Congratulations, Photon has been installed in {0} secs.\n\n' + |
|
243 |
+ self.window.addstr(0, 0, 'Congratulations, Photon has been installed in {0} secs.\n\n' |
|
244 | 244 |
'Press any key to continue to boot...' |
245 | 245 |
.format(self.progress_bar.time_elapsed)) |
246 |
- eject_cdrom = True |
|
247 |
- if 'ui_install' in self.install_config: |
|
248 |
- self.window.content_window().getch() |
|
249 |
- if 'eject_cdrom' in self.install_config and not self.install_config['eject_cdrom']: |
|
250 |
- eject_cdrom = False |
|
251 |
- if eject_cdrom: |
|
252 |
- process = subprocess.Popen(['eject', '-r'], stdout=self.output) |
|
253 |
- process.wait() |
|
246 |
+ self.eject_cdrom() |
|
254 | 247 |
return ActionResult(True, None) |
255 | 248 |
|
256 | 249 |
def copy_rpms(self): |
... | ... |
@@ -263,7 +164,7 @@ class Installer(object): |
263 | 263 |
|
264 | 264 |
for pkg in selected_packages: |
265 | 265 |
if pkg in pkg_to_rpm_map: |
266 |
- if not pkg_to_rpm_map[pkg]['rpm'] is None: |
|
266 |
+ if pkg_to_rpm_map[pkg]['rpm'] is not None: |
|
267 | 267 |
name = pkg_to_rpm_map[pkg]['rpm'] |
268 | 268 |
basename = os.path.basename(name) |
269 | 269 |
self.rpms_tobeinstalled.append({'filename': basename, 'path': name, |
... | ... |
@@ -421,7 +322,7 @@ class Installer(object): |
421 | 421 |
|
422 | 422 |
rpms = set(rpm_file_names) |
423 | 423 |
rpm_paths = [] |
424 |
- for root, dirs, files in os.walk(self.rpm_path): |
|
424 |
+ for root, _, files in os.walk(self.rpm_path): |
|
425 | 425 |
for f in files: |
426 | 426 |
if f in rpms: |
427 | 427 |
rpm_paths.append(os.path.join(root, f)) |
... | ... |
@@ -457,7 +358,7 @@ class Installer(object): |
457 | 457 |
continue |
458 | 458 |
|
459 | 459 |
# the module default is disabled |
460 |
- if not hasattr(mod, 'enabled') or mod.enabled == False: |
|
460 |
+ if not hasattr(mod, 'enabled') or mod.enabled is False: |
|
461 | 461 |
modules.commons.log(modules.commons.LOG_INFO, |
462 | 462 |
"module {} is not enabled".format(module)) |
463 | 463 |
continue |
... | ... |
@@ -475,7 +376,7 @@ class Installer(object): |
475 | 475 |
"Error: not able to execute module {}".format(module)) |
476 | 476 |
continue |
477 | 477 |
|
478 |
- mod.execute(module, self.install_config, self.photon_root) |
|
478 |
+ mod.execute(self.install_config, self.photon_root) |
|
479 | 479 |
|
480 | 480 |
def adjust_packages_for_vmware_virt(self): |
481 | 481 |
try: |
... | ... |
@@ -492,3 +393,115 @@ class Installer(object): |
492 | 492 |
selected_packages.append('linux-esx') |
493 | 493 |
except KeyError: |
494 | 494 |
pass |
495 |
+ |
|
496 |
+ def setup_install_repo(self): |
|
497 |
+ if self.iso_installer: |
|
498 |
+ self.window.show_window() |
|
499 |
+ self.progress_bar.initialize('Initializing installation...') |
|
500 |
+ self.progress_bar.show() |
|
501 |
+ #self.rpm_path = "https://dl.bintray.com/vmware/photon_release_1.0_TP2_x86_64" |
|
502 |
+ if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"): |
|
503 |
+ cmdoption = 's/baseurl.*/baseurl={}/g'.format(self.rpm_path.replace('/', '\/')) |
|
504 |
+ process = subprocess.Popen(['sed', '-i', cmdoption, |
|
505 |
+ '/etc/yum.repos.d/photon-iso.repo']) |
|
506 |
+ retval = process.wait() |
|
507 |
+ if retval != 0: |
|
508 |
+ modules.commons.log(modules.commons.LOG_INFO, "Failed to reset repo") |
|
509 |
+ self.exit_gracefully(None, None) |
|
510 |
+ |
|
511 |
+ cmdoption = ('s/cachedir=\/var/cachedir={}/g' |
|
512 |
+ .format(self.photon_root.replace('/', '\/'))) |
|
513 |
+ process = subprocess.Popen(['sed', '-i', cmdoption, '/etc/tdnf/tdnf.conf']) |
|
514 |
+ retval = process.wait() |
|
515 |
+ if retval != 0: |
|
516 |
+ modules.commons.log(modules.commons.LOG_INFO, "Failed to reset tdnf cachedir") |
|
517 |
+ self.exit_gracefully(None, None) |
|
518 |
+ |
|
519 |
+ def install_packages(self): |
|
520 |
+ if self.iso_installer: |
|
521 |
+ self.tdnf_install_packages() |
|
522 |
+ else: |
|
523 |
+ #install packages |
|
524 |
+ rpms = [] |
|
525 |
+ for rpm in self.rpms_tobeinstalled: |
|
526 |
+ # We already installed the filesystem in the preparation |
|
527 |
+ if rpm['package'] == 'filesystem': |
|
528 |
+ continue |
|
529 |
+ rpms.append(rpm['filename']) |
|
530 |
+ return_value = self.install_package(rpms) |
|
531 |
+ if return_value != 0: |
|
532 |
+ self.exit_gracefully(None, None) |
|
533 |
+ |
|
534 |
+ def tdnf_install_packages(self): |
|
535 |
+ self.adjust_packages_for_vmware_virt() |
|
536 |
+ selected_packages = self.install_config['packages'] |
|
537 |
+ state = 0 |
|
538 |
+ packages_to_install = {} |
|
539 |
+ total_size = 0 |
|
540 |
+ with open(modules.commons.TDNF_CMDLINE_FILE_NAME, "w") as tdnf_cmdline_file: |
|
541 |
+ tdnf_cmdline_file.write("tdnf install --installroot {0} --nogpgcheck {1}" |
|
542 |
+ .format(self.photon_root, " ".join(selected_packages))) |
|
543 |
+ with open(modules.commons.TDNF_LOG_FILE_NAME, "w") as tdnf_errlog: |
|
544 |
+ process = subprocess.Popen(['tdnf', 'install'] + selected_packages + |
|
545 |
+ ['--installroot', self.photon_root, '--nogpgcheck', |
|
546 |
+ '--assumeyes'], stdout=subprocess.PIPE, |
|
547 |
+ stderr=tdnf_errlog) |
|
548 |
+ while True: |
|
549 |
+ output = process.stdout.readline().decode() |
|
550 |
+ if output == '': |
|
551 |
+ retval = process.poll() |
|
552 |
+ if retval is not None: |
|
553 |
+ break |
|
554 |
+ if state == 0: |
|
555 |
+ if output == 'Installing:\n': |
|
556 |
+ state = 1 |
|
557 |
+ elif state == 1: #N A EVR Size(readable) Size(in bytes) |
|
558 |
+ if output == '\n': |
|
559 |
+ state = 2 |
|
560 |
+ self.progress_bar.update_num_items(total_size) |
|
561 |
+ else: |
|
562 |
+ info = output.split() |
|
563 |
+ package = '{0}-{1}.{2}'.format(info[0], info[2], info[1]) |
|
564 |
+ packages_to_install[package] = int(info[5]) |
|
565 |
+ total_size += int(info[5]) |
|
566 |
+ elif state == 2: |
|
567 |
+ if output == 'Downloading:\n': |
|
568 |
+ self.progress_bar.update_message('Preparing ...') |
|
569 |
+ state = 3 |
|
570 |
+ elif state == 3: |
|
571 |
+ self.progress_bar.update_message(output) |
|
572 |
+ if output == 'Running transaction\n': |
|
573 |
+ state = 4 |
|
574 |
+ else: |
|
575 |
+ modules.commons.log(modules.commons.LOG_INFO, "[tdnf] {0}".format(output)) |
|
576 |
+ prefix = 'Installing/Updating: ' |
|
577 |
+ if output.startswith(prefix): |
|
578 |
+ package = output[len(prefix):].rstrip('\n') |
|
579 |
+ self.progress_bar.increment(packages_to_install[package]) |
|
580 |
+ |
|
581 |
+ self.progress_bar.update_message(output) |
|
582 |
+ # 0 : succeed; 137 : package already installed; 65 : package not found in repo. |
|
583 |
+ if retval != 0 and retval != 137: |
|
584 |
+ modules.commons.log(modules.commons.LOG_ERROR, |
|
585 |
+ "Failed to install some packages, refer to {0}" |
|
586 |
+ .format(modules.commons.TDNF_LOG_FILE_NAME)) |
|
587 |
+ self.exit_gracefully(None, None) |
|
588 |
+ self.progress_bar.show_loading('Finalizing installation') |
|
589 |
+ |
|
590 |
+ def eject_cdrom(self): |
|
591 |
+ eject_cdrom = True |
|
592 |
+ if 'ui_install' in self.install_config: |
|
593 |
+ self.window.content_window().getch() |
|
594 |
+ if 'eject_cdrom' in self.install_config and not self.install_config['eject_cdrom']: |
|
595 |
+ eject_cdrom = False |
|
596 |
+ if eject_cdrom: |
|
597 |
+ process = subprocess.Popen(['eject', '-r'], stdout=self.output) |
|
598 |
+ process.wait() |
|
599 |
+ |
|
600 |
+ def enable_network_in_chroot(self): |
|
601 |
+ if os.path.exists("/etc/resolv.conf"): |
|
602 |
+ shutil.copy("/etc/resolv.conf", self.photon_root + '/etc/.') |
|
603 |
+ |
|
604 |
+ def disable_network_in_chroot(self): |
|
605 |
+ if os.path.exists(self.photon_root + '/etc/resolv.conf'): |
|
606 |
+ os.remove(self.photon_root + '/etc/resolv.conf') |
... | ... |
@@ -18,24 +18,35 @@ from license import License |
18 | 18 |
from linuxselector import LinuxSelector |
19 | 19 |
|
20 | 20 |
class IsoConfig(object): |
21 |
- def Configure(self,options_file, maxy, maxx): |
|
21 |
+ """This class handles iso installer configuration.""" |
|
22 |
+ def __init__(self): |
|
22 | 23 |
self.cd_path = None |
24 |
+ self.alpha_chars = list(range(65, 91)) |
|
25 |
+ self.alpha_chars.extend(range(97, 123)) |
|
26 |
+ self.hostname_accepted_chars = self.alpha_chars |
|
27 |
+ # Adding the numeric chars |
|
28 |
+ self.hostname_accepted_chars.extend(range(48, 58)) |
|
29 |
+ # Adding the . and - |
|
30 |
+ self.hostname_accepted_chars.extend([ord('.'), ord('-')]) |
|
31 |
+ self.random_id = '%12x' % random.randrange(16**12) |
|
32 |
+ self.random_hostname = "photon-" + self.random_id.strip() |
|
23 | 33 |
|
34 |
+ def Configure(self, options_file, maxy, maxx): |
|
24 | 35 |
kernel_params = subprocess.check_output(['cat', '/proc/cmdline']) |
25 | 36 |
|
26 | 37 |
# check for the repo param |
27 | 38 |
m = re.match(r".*repo=(\S+)\s*.*\s*", kernel_params.decode()) |
28 |
- if m != None: |
|
39 |
+ if m is not None: |
|
29 | 40 |
rpm_path = m.group(1) |
30 | 41 |
else: |
31 | 42 |
# the rpms should be in the cd |
32 |
- self.mount_RPMS_cd() |
|
43 |
+ self.mount_cd() |
|
33 | 44 |
rpm_path = os.path.join(self.cd_path, "RPMS") |
34 | 45 |
|
35 | 46 |
# check the kickstart param |
36 | 47 |
ks_config = None |
37 | 48 |
m = re.match(r".*ks=(\S+)\s*.*\s*", kernel_params.decode()) |
38 |
- if m != None: |
|
49 |
+ if m is not None: |
|
39 | 50 |
ks_config = self.get_config(m.group(1)) |
40 | 51 |
|
41 | 52 |
install_config = None |
... | ... |
@@ -45,21 +56,23 @@ class IsoConfig(object): |
45 | 45 |
install_config = self.ui_config(options_file, maxy, maxx) |
46 | 46 |
return rpm_path, install_config |
47 | 47 |
|
48 |
- def is_vmware_virtualization(self): |
|
48 |
+ @staticmethod |
|
49 |
+ def is_vmware_virtualization(): |
|
50 |
+ """Detect vmware vm""" |
|
49 | 51 |
process = subprocess.Popen(['systemd-detect-virt'], stdout=subprocess.PIPE) |
50 | 52 |
out, err = process.communicate() |
51 | 53 |
if err is not None and err != 0: |
52 | 54 |
return False |
53 |
- else: |
|
54 |
- return out == 'vmware\n' |
|
55 |
+ return out == 'vmware\n' |
|
55 | 56 |
|
56 | 57 |
def get_config(self, path): |
58 |
+ """kick start configuration""" |
|
57 | 59 |
if path.startswith("http://"): |
58 | 60 |
# Do 5 trials to get the kick start |
59 | 61 |
# TODO: make sure the installer run after network is up |
60 | 62 |
ks_file_error = "Failed to get the kickstart file at {0}".format(path) |
61 | 63 |
wait = 1 |
62 |
- for x in range(0, 5): |
|
64 |
+ for _ in range(0, 5): |
|
63 | 65 |
err_msg = "" |
64 | 66 |
try: |
65 | 67 |
response = requests.get(path, timeout=3) |
... | ... |
@@ -70,9 +83,9 @@ class IsoConfig(object): |
70 | 70 |
err_msg = e |
71 | 71 |
|
72 | 72 |
modules.commons.log(modules.commons.LOG_ERROR, |
73 |
- ks_file_error) |
|
73 |
+ ks_file_error) |
|
74 | 74 |
modules.commons.log(modules.commons.LOG_ERROR, |
75 |
- "error msg: {0}".format(err_msg)) |
|
75 |
+ "error msg: {0}".format(err_msg)) |
|
76 | 76 |
print(ks_file_error) |
77 | 77 |
print("retry in a second") |
78 | 78 |
time.sleep(wait) |
... | ... |
@@ -84,11 +97,12 @@ class IsoConfig(object): |
84 | 84 |
raise Exception(err_msg) |
85 | 85 |
else: |
86 | 86 |
if path.startswith("cdrom:/"): |
87 |
- self.mount_RPMS_cd() |
|
87 |
+ self.mount_cd() |
|
88 | 88 |
path = os.path.join(self.cd_path, path.replace("cdrom:/", "", 1)) |
89 | 89 |
return (JsonWrapper(path)).read() |
90 | 90 |
|
91 |
- def mount_RPMS_cd(self): |
|
91 |
+ def mount_cd(self): |
|
92 |
+ """Mount the cd with RPMS""" |
|
92 | 93 |
# check if the cd is already mounted |
93 | 94 |
if self.cd_path: |
94 | 95 |
return |
... | ... |
@@ -98,7 +112,7 @@ class IsoConfig(object): |
98 | 98 |
retval = process.wait() |
99 | 99 |
|
100 | 100 |
# Retry mount the CD |
101 |
- for i in range(0, 3): |
|
101 |
+ for _ in range(0, 3): |
|
102 | 102 |
process = subprocess.Popen(['mount', '/dev/cdrom', '/mnt/cdrom']) |
103 | 103 |
retval = process.wait() |
104 | 104 |
if retval == 0: |
... | ... |
@@ -111,6 +125,8 @@ class IsoConfig(object): |
111 | 111 |
raise Exception("Can not mount the cd") |
112 | 112 |
|
113 | 113 |
def ks_config(self, options_file, ks_config): |
114 |
+ """Load configuration from file""" |
|
115 |
+ del options_file |
|
114 | 116 |
install_config = ks_config |
115 | 117 |
install_config['iso_system'] = False |
116 | 118 |
if self.is_vmware_virtualization() and 'install_linux_esx' not in install_config: |
... | ... |
@@ -123,7 +139,9 @@ class IsoConfig(object): |
123 | 123 |
base_path = os.path.dirname("build_install_options_all.json") |
124 | 124 |
package_list = [] |
125 | 125 |
|
126 |
- package_list = PackageSelector.get_packages_to_install(options_sorted, install_config['type'], base_path) |
|
126 |
+ package_list = PackageSelector.get_packages_to_install(options_sorted, |
|
127 |
+ install_config['type'], |
|
128 |
+ base_path) |
|
127 | 129 |
if 'additional_packages' in install_config: |
128 | 130 |
package_list.extend(install_config['additional_packages']) |
129 | 131 |
install_config['packages'] = package_list |
... | ... |
@@ -139,77 +157,103 @@ class IsoConfig(object): |
139 | 139 |
evalhostname = os.popen('printf ' + install_config["hostname"].strip(" ")).readlines() |
140 | 140 |
install_config['hostname'] = evalhostname[0] |
141 | 141 |
if "hostname" not in install_config or install_config['hostname'] == "": |
142 |
- random_id = '%12x' % random.randrange(16**12) |
|
143 |
- install_config['hostname'] = "photon-" + random_id.strip() |
|
142 |
+ install_config['hostname'] = "photon-" + self.random_id.strip() |
|
144 | 143 |
|
145 | 144 |
# crypt the password if needed |
146 | 145 |
if install_config['password']['crypted']: |
147 | 146 |
install_config['password'] = install_config['password']['text'] |
148 | 147 |
else: |
149 |
- install_config['password'] = crypt.crypt(install_config['password']['text'], |
|
150 |
- "$6$" + "".join([random.choice(string.ascii_letters + string.digits) for _ in range(16)])) |
|
148 |
+ install_config['password'] = crypt.crypt( |
|
149 |
+ install_config['password']['text'], |
|
150 |
+ "$6$" + "".join([random.choice( |
|
151 |
+ string.ascii_letters + string.digits) for _ in range(16)])) |
|
151 | 152 |
return install_config |
152 | 153 |
|
153 |
- def validate_hostname(self, hostname): |
|
154 |
+ @staticmethod |
|
155 |
+ def validate_hostname(hostname): |
|
156 |
+ """A valid hostname must start with a letter""" |
|
154 | 157 |
error_empty = "Empty hostname or domain is not allowed" |
155 | 158 |
error_dash = "Hostname or domain should not start or end with '-'" |
156 | 159 |
error_hostname = "Hostname should start with alpha char and <= 64 chars" |
157 | 160 |
|
158 |
- if hostname is None or len(hostname) == 0: |
|
161 |
+ if hostname is None or not hostname: |
|
159 | 162 |
return False, error_empty |
160 | 163 |
|
161 | 164 |
fields = hostname.split('.') |
162 | 165 |
for field in fields: |
163 |
- if len(field) == 0: |
|
166 |
+ if not field: |
|
164 | 167 |
return False, error_empty |
165 | 168 |
if field[0] == '-' or field[-1] == '-': |
166 | 169 |
return False, error_dash |
167 | 170 |
|
168 | 171 |
machinename = fields[0] |
169 |
- return (len(machinename) <= 64) and (ord(machinename[0]) in self.alpha_chars), error_hostname |
|
172 |
+ return (len(machinename) <= 64 and |
|
173 |
+ machinename[0].isalpha(), error_hostname) |
|
170 | 174 |
|
171 | 175 |
@staticmethod |
172 | 176 |
def validate_password(text): |
177 |
+ """Validate password with cracklib""" |
|
173 | 178 |
try: |
174 |
- p = cracklib.VeryFascistCheck(text) |
|
179 |
+ password = cracklib.VeryFascistCheck(text) |
|
175 | 180 |
except ValueError as message: |
176 |
- p = str(message) |
|
177 |
- return p == text, "Error: " + p |
|
181 |
+ password = str(message) |
|
182 |
+ return password == text, "Error: " + password |
|
178 | 183 |
|
179 | 184 |
@staticmethod |
180 | 185 |
def generate_password_hash(password): |
181 |
- shadow_password = crypt.crypt(password, "$6$" + "".join([random.choice(string.ascii_letters + string.digits) for _ in range(16)])) |
|
186 |
+ """Generate hash for the password""" |
|
187 |
+ shadow_password = crypt.crypt( |
|
188 |
+ password, "$6$" + "".join( |
|
189 |
+ [random.choice( |
|
190 |
+ string.ascii_letters + string.digits) for _ in range(16)])) |
|
182 | 191 |
return shadow_password |
183 | 192 |
|
184 | 193 |
def ui_config(self, options_file, maxy, maxx): |
185 |
- # This represents the installer screen, the bool indicated if I can go back to this window or not |
|
186 |
- items = [] |
|
187 |
- random_id = '%12x' % random.randrange(16**12) |
|
188 |
- random_hostname = "photon-" + random_id.strip() |
|
194 |
+ """Configuration through UI""" |
|
195 |
+ # This represents the installer screen, the bool indicated if |
|
196 |
+ # I can go back to this window or not |
|
189 | 197 |
install_config = {'iso_system': False} |
190 | 198 |
install_config['ui_install'] = True |
199 |
+ items, select_linux_index = self.add_ui_pages(options_file, maxy, maxx, |
|
200 |
+ install_config) |
|
201 |
+ index = 0 |
|
202 |
+ while True: |
|
203 |
+ result = items[index][0](None) |
|
204 |
+ if result.success: |
|
205 |
+ index += 1 |
|
206 |
+ if index == len(items): |
|
207 |
+ break |
|
208 |
+ #Skip linux select screen for ostree installation. |
|
209 |
+ if index == select_linux_index: |
|
210 |
+ if install_config['type'] == 'ostree_server': |
|
211 |
+ index += 1 |
|
212 |
+ else: |
|
213 |
+ index -= 1 |
|
214 |
+ while index >= 0 and items[index][1] is False: |
|
215 |
+ index -= 1 |
|
216 |
+ if index < 0: |
|
217 |
+ index = 0 |
|
218 |
+ #Skip linux select screen for ostree installation. |
|
219 |
+ if index == select_linux_index: |
|
220 |
+ if install_config['type'] == 'ostree_server': |
|
221 |
+ index -= 1 |
|
222 |
+ return install_config |
|
223 |
+ def add_ui_pages(self, options_file, maxy, maxx, install_config): |
|
224 |
+ items = [] |
|
191 | 225 |
license_agreement = License(maxy, maxx) |
192 | 226 |
select_disk = SelectDisk(maxy, maxx, install_config) |
193 | 227 |
select_partition = PartitionISO(maxy, maxx, install_config) |
194 | 228 |
package_selector = PackageSelector(maxy, maxx, install_config, options_file) |
195 |
- self.alpha_chars = list(range(65, 91)) |
|
196 |
- self.alpha_chars.extend(range(97, 123)) |
|
197 |
- hostname_accepted_chars = self.alpha_chars |
|
198 |
- # Adding the numeric chars |
|
199 |
- hostname_accepted_chars.extend(range(48, 58)) |
|
200 |
- # Adding the . and - |
|
201 |
- hostname_accepted_chars.extend([ord('.'), ord('-')]) |
|
202 |
- |
|
203 | 229 |
hostname_reader = WindowStringReader( |
204 | 230 |
maxy, maxx, 10, 70, |
205 | 231 |
'hostname', |
206 | 232 |
None, # confirmation error msg if it's a confirmation text |
207 | 233 |
None, # echo char |
208 |
- hostname_accepted_chars, # set of accepted chars |
|
209 |
- self.validate_hostname, # validation function of the input |
|
234 |
+ self.hostname_accepted_chars, # set of accepted chars |
|
235 |
+ IsoConfig.validate_hostname, # validation function of the input |
|
210 | 236 |
None, # post processing of the input field |
211 | 237 |
'Choose the hostname for your system', 'Hostname:', 2, install_config, |
212 |
- random_hostname, |
|
238 |
+ self.random_hostname, |
|
213 | 239 |
True) |
214 | 240 |
root_password_reader = WindowStringReader( |
215 | 241 |
maxy, maxx, 10, 70, |
... | ... |
@@ -223,7 +267,8 @@ class IsoConfig(object): |
223 | 223 |
confirm_password_reader = WindowStringReader( |
224 | 224 |
maxy, maxx, 10, 70, |
225 | 225 |
'password', |
226 |
- "Passwords don't match, please try again.", # confirmation error msg if it's a confirmation text |
|
226 |
+ # confirmation error msg if it's a confirmation text |
|
227 |
+ "Passwords don't match, please try again.", |
|
227 | 228 |
'*', # echo char |
228 | 229 |
None, # set of accepted chars |
229 | 230 |
None, # validation function of the input |
... | ... |
@@ -243,27 +288,4 @@ class IsoConfig(object): |
243 | 243 |
items.append((hostname_reader.get_user_string, True)) |
244 | 244 |
items.append((root_password_reader.get_user_string, True)) |
245 | 245 |
items.append((confirm_password_reader.get_user_string, False)) |
246 |
- index = 0 |
|
247 |
- params = None |
|
248 |
- while True: |
|
249 |
- result = items[index][0](params) |
|
250 |
- if result.success: |
|
251 |
- index += 1 |
|
252 |
- params = result.result |
|
253 |
- if index == len(items): |
|
254 |
- break |
|
255 |
- #Skip linux select screen for ostree installation. |
|
256 |
- if index == select_linux_index: |
|
257 |
- if install_config['type'] == 'ostree_server': |
|
258 |
- index += 1 |
|
259 |
- else: |
|
260 |
- index -= 1 |
|
261 |
- while index >= 0 and items[index][1] is False: |
|
262 |
- index -= 1 |
|
263 |
- if index < 0: |
|
264 |
- index = 0 |
|
265 |
- #Skip linux select screen for ostree installation. |
|
266 |
- if index == select_linux_index: |
|
267 |
- if install_config['type'] == 'ostree_server': |
|
268 |
- index -= 1 |
|
269 |
- return install_config |
|
246 |
+ return items, select_linux_index |
... | ... |
@@ -6,8 +6,8 @@ PRE_INSTALL = "pre-install" |
6 | 6 |
POST_INSTALL = "post-install" |
7 | 7 |
|
8 | 8 |
LOG_LEVEL_DESC = ["emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"] |
9 |
-LOG_FILE_NAME = "/var/log/installer.log" |
|
10 |
-TDNF_LOG_FILE_NAME = "/var/log/tdnf.log" |
|
9 |
+LOG_FILE_NAME = "/var/log/installer.log" |
|
10 |
+TDNF_LOG_FILE_NAME = "/var/log/tdnf.log" |
|
11 | 11 |
TDNF_CMDLINE_FILE_NAME = "/var/log/tdnf.cmdline" |
12 | 12 |
KS_POST_INSTALL_LOG_FILE_NAME = "/var/log/installer-kickstart.log" |
13 | 13 |
SIGNATURE = "localhost echo" |
... | ... |
@@ -21,8 +21,8 @@ LOG_INFO = 6 |
21 | 21 |
LOG_DEBUG = 7 |
22 | 22 |
|
23 | 23 |
default_partitions = [ |
24 |
- {"mountpoint": "/", "size": 0, "filesystem": "ext4"}, |
|
25 |
- ] |
|
24 |
+ {"mountpoint": "/", "size": 0, "filesystem": "ext4"}, |
|
25 |
+ ] |
|
26 | 26 |
|
27 | 27 |
def partition_compare(p): |
28 | 28 |
if 'mountpoint' in p: |
... | ... |
@@ -36,7 +36,7 @@ def partition_disk(disk, partitions): |
36 | 36 |
output = open(os.devnull, 'w') |
37 | 37 |
|
38 | 38 |
# Clear the disk |
39 |
- process = subprocess.Popen(['sgdisk', '-o', '-g', disk], stderr = output, stdout = output) |
|
39 |
+ process = subprocess.Popen(['sgdisk', '-o', '-g', disk], stderr=output, stdout=output) |
|
40 | 40 |
retval = process.wait() |
41 | 41 |
if retval != 0: |
42 | 42 |
log(LOG_ERROR, "Failed clearing disk {0}".format(disk)) |
... | ... |
@@ -58,7 +58,7 @@ def partition_disk(disk, partitions): |
58 | 58 |
# Adding the known size partitions |
59 | 59 |
for partition in partitions: |
60 | 60 |
if partition['size'] == 0: |
61 |
- # Can not have more than 1 extensible partition |
|
61 |
+ # Can not have more than 1 extensible partition |
|
62 | 62 |
if extensible_partition != None: |
63 | 63 |
log(LOG_ERROR, "Can not have more than 1 extensible partition") |
64 | 64 |
return None |
... | ... |
@@ -80,13 +80,13 @@ def partition_disk(disk, partitions): |
80 | 80 |
partition_cmd.extend(['-p', disk]) |
81 | 81 |
|
82 | 82 |
# Run the partitioning command |
83 |
- process = subprocess.Popen(partition_cmd, stderr = output, stdout = output) |
|
83 |
+ process = subprocess.Popen(partition_cmd, stderr=output, stdout=output) |
|
84 | 84 |
retval = process.wait() |
85 | 85 |
if retval != 0: |
86 | 86 |
log(LOG_ERROR, "Faild partition disk, command: {0}". format(partition_cmd)) |
87 | 87 |
return None |
88 | 88 |
|
89 |
- process = subprocess.Popen(['sgdisk', '-t1' + grub_flag, disk], stderr = output, stdout = output) |
|
89 |
+ process = subprocess.Popen(['sgdisk', '-t1' + grub_flag, disk], stderr=output, stdout=output) |
|
90 | 90 |
retval = process.wait() |
91 | 91 |
if retval != 0: |
92 | 92 |
log(LOG_ERROR, "Failed to setup grub partition") |
... | ... |
@@ -103,25 +103,27 @@ def partition_disk(disk, partitions): |
103 | 103 |
partitions_data['boot_partition_number'] = partition['partition_number'] |
104 | 104 |
partitions_data['bootdirectory'] = '/' |
105 | 105 |
if partition['filesystem'] == "swap": |
106 |
- process = subprocess.Popen(['mkswap', partition['path']], stderr = output, stdout = output) |
|
106 |
+ process = subprocess.Popen(['mkswap', partition['path']], stderr=output, stdout=output) |
|
107 | 107 |
retval = process.wait() |
108 | 108 |
if retval != 0: |
109 | 109 |
log(LOG_ERROR, "Failed to create swap partition @ {}".format(partition['path'])) |
110 | 110 |
return None |
111 | 111 |
else: |
112 | 112 |
mkfs_cmd = ['mkfs', '-t', partition['filesystem'], partition['path']] |
113 |
- process = subprocess.Popen(mkfs_cmd, stderr = output, stdout = output) |
|
113 |
+ process = subprocess.Popen(mkfs_cmd, stderr=output, stdout=output) |
|
114 | 114 |
retval = process.wait() |
115 | 115 |
if retval != 0: |
116 |
- log(LOG_ERROR, "Failed to format {} partition @ {}".format(partition['filesystem'], partition['path'])) |
|
116 |
+ log(LOG_ERROR, |
|
117 |
+ "Failed to format {} partition @ {}".format(partition['filesystem'], |
|
118 |
+ partition['path'])) |
|
117 | 119 |
return None |
118 | 120 |
|
119 | 121 |
# Check if there is no root partition |
120 |
- if not 'root' in partitions_data: |
|
122 |
+ if 'root' not in partitions_data: |
|
121 | 123 |
log(LOG_ERROR, "There is no partition assigned to root '/'") |
122 | 124 |
return None |
123 | 125 |
|
124 |
- if not 'boot' in partitions_data: |
|
126 |
+ if 'boot' not in partitions_data: |
|
125 | 127 |
partitions_data['boot'] = partitions_data['root'] |
126 | 128 |
partitions_data['boot_partition_number'] = partitions_data['root_partition_number'] |
127 | 129 |
partitions_data['bootdirectory'] = '/boot/' |
... | ... |
@@ -130,9 +132,9 @@ def partition_disk(disk, partitions): |
130 | 130 |
|
131 | 131 |
return partitions_data |
132 | 132 |
|
133 |
-def replace_string_in_file(filename, search_string, replace_string): |
|
133 |
+def replace_string_in_file(filename, search_string, replace_string): |
|
134 | 134 |
with open(filename, "r") as source: |
135 |
- lines=source.readlines() |
|
135 |
+ lines = source.readlines() |
|
136 | 136 |
|
137 | 137 |
with open(filename, "w") as destination: |
138 | 138 |
for line in lines: |
... | ... |
@@ -145,7 +147,8 @@ def log(type, message): |
145 | 145 |
return retval |
146 | 146 |
|
147 | 147 |
def dump(type, filename): |
148 |
- command = "journalctl -p {0} | grep --line-buffered \"{1}\" > {2}".format(LOG_LEVEL_DESC[type], SIGNATURE, filename) |
|
148 |
+ command = ("journalctl -p {0} | grep --line-buffered \"{1}\" > {2}" |
|
149 |
+ .format(LOG_LEVEL_DESC[type], SIGNATURE, filename)) |
|
149 | 150 |
process = subprocess.Popen([command], shell=True) |
150 | 151 |
retval = process.wait() |
151 | 152 |
return retval |
... | ... |
@@ -153,5 +156,5 @@ def dump(type, filename): |
153 | 153 |
def dump(filename): |
154 | 154 |
command = "journalctl | grep --line-buffered \"{0}\" > {1}".format(SIGNATURE, filename) |
155 | 155 |
process = subprocess.Popen([command], shell=True) |
156 |
- retval = process.wait() |
|
156 |
+ retval = process.wait() |
|
157 | 157 |
return retval |
... | ... |
@@ -5,7 +5,7 @@ import commons |
5 | 5 |
install_phase = commons.POST_INSTALL |
6 | 6 |
enabled = True |
7 | 7 |
|
8 |
-def execute(name, config, root): |
|
8 |
+def execute(config, root): |
|
9 | 9 |
if 'postinstall' not in config: |
10 | 10 |
return |
11 | 11 |
# run the script in the chroot environment |
... | ... |
@@ -13,14 +13,15 @@ def execute(name, config, root): |
13 | 13 |
|
14 | 14 |
script_file = os.path.join(root, 'etc/tmpfiles.d/postinstall.sh') |
15 | 15 |
|
16 |
- with open(script_file, 'wb') as outfile: |
|
16 |
+ with open(script_file, 'wb') as outfile: |
|
17 | 17 |
outfile.write("\n".join(script).encode()) |
18 | 18 |
|
19 |
- os.chmod(script_file, 0o700); |
|
20 |
- with open(commons.KS_POST_INSTALL_LOG_FILE_NAME,"w") as logfile: |
|
21 |
- process = subprocess.Popen(["./mk-run-chroot.sh", '-w', root, "/etc/tmpfiles.d/postinstall.sh"], |
|
22 |
- stdout=logfile,stderr=logfile) |
|
19 |
+ os.chmod(script_file, 0o700) |
|
20 |
+ with open(commons.KS_POST_INSTALL_LOG_FILE_NAME, "w") as logfile: |
|
21 |
+ process = subprocess.Popen(["./mk-run-chroot.sh", '-w', root, |
|
22 |
+ "/etc/tmpfiles.d/postinstall.sh"], |
|
23 |
+ stdout=logfile, stderr=logfile) |
|
23 | 24 |
retval = process.wait() |
24 |
- if retval==0: |
|
25 |
+ if retval == 0: |
|
25 | 26 |
return True |
26 | 27 |
return False |
... | ... |
@@ -1,11 +1,11 @@ |
1 | 1 |
import os |
2 |
-import commons |
|
3 | 2 |
import random |
3 |
+import commons |
|
4 | 4 |
|
5 | 5 |
install_phase = commons.POST_INSTALL |
6 | 6 |
enabled = True |
7 | 7 |
|
8 |
-def execute(name, config, root): |
|
8 |
+def execute(config, root): |
|
9 | 9 |
hostname = config['hostname'] |
10 | 10 |
|
11 | 11 |
hostname_file = os.path.join(root, 'etc/hostname') |
... | ... |
@@ -1,26 +1,25 @@ |
1 | 1 |
import os |
2 |
-import commons |
|
3 | 2 |
import crypt |
4 | 3 |
import random |
5 | 4 |
import string |
5 |
+import commons |
|
6 | 6 |
|
7 | 7 |
install_phase = commons.POST_INSTALL |
8 | 8 |
enabled = True |
9 | 9 |
|
10 |
-def execute(name, config, root): |
|
10 |
+def execute(config, root): |
|
11 | 11 |
shadow_password = config['password'] |
12 | 12 |
|
13 | 13 |
passwd_filename = os.path.join(root, 'etc/passwd') |
14 | 14 |
shadow_filename = os.path.join(root, 'etc/shadow') |
15 |
- |
|
15 |
+ |
|
16 | 16 |
#replace root blank password in passwd file to point to shadow file |
17 |
- commons.replace_string_in_file(passwd_filename, "root::", "root:x:") |
|
17 |
+ commons.replace_string_in_file(passwd_filename, "root::", "root:x:") |
|
18 | 18 |
|
19 | 19 |
if os.path.isfile(shadow_filename) == False: |
20 | 20 |
with open(shadow_filename, "w") as destination: |
21 |
- destination.write("root:"+shadow_password+":") |
|
21 |
+ destination.write("root:" + shadow_password + ":") |
|
22 | 22 |
else: |
23 | 23 |
#add password hash in shadow file |
24 | 24 |
commons.replace_string_in_file(shadow_filename, "root::", "root:"+shadow_password+":") |
25 | 25 |
commons.replace_string_in_file(shadow_filename, "root:x:", "root:"+shadow_password+":") |
26 |
- |
... | ... |
@@ -5,7 +5,7 @@ import commons |
5 | 5 |
install_phase = commons.POST_INSTALL |
6 | 6 |
enabled = True |
7 | 7 |
|
8 |
-def execute(name, config, root): |
|
8 |
+def execute(config, root): |
|
9 | 9 |
if 'public_key' not in config: |
10 | 10 |
return |
11 | 11 |
|
... | ... |
@@ -21,5 +21,6 @@ def execute(name, config, root): |
21 | 21 |
os.chmod(authorized_keys_filename, 0o600) |
22 | 22 |
|
23 | 23 |
# Change the sshd config to allow root login |
24 |
- process = subprocess.Popen(["sed", "-i", "s/^\\s*PermitRootLogin\s\+no/PermitRootLogin yes/", sshd_config_filename]) |
|
24 |
+ process = subprocess.Popen(["sed", "-i", "s/^\\s*PermitRootLogin\s\+no/PermitRootLogin yes/", |
|
25 |
+ sshd_config_filename]) |
|
25 | 26 |
return process.wait() |
... | ... |
@@ -1,13 +1,13 @@ |
1 |
-#!/usr/bin/python2 |
|
1 |
+#!/usr/bin/python3 |
|
2 | 2 |
|
3 | 3 |
import os |
4 | 4 |
import re |
5 | 5 |
import shutil |
6 | 6 |
import tarfile |
7 | 7 |
import fileinput |
8 |
-from optparse import OptionParser |
|
9 |
-from utils import Utils |
|
8 |
+from argparse import ArgumentParser |
|
10 | 9 |
import json |
10 |
+from utils import Utils |
|
11 | 11 |
|
12 | 12 |
def create_ova_image(raw_image_name, tools_path, build_scripts_path, config): |
13 | 13 |
output_path = os.path.dirname(os.path.realpath(raw_image_name)) |
... | ... |
@@ -19,15 +19,23 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config): |
19 | 19 |
os.remove(os.path.join(output_path, file)) |
20 | 20 |
|
21 | 21 |
vmx_path = output_path + '/photon-ova.vmx' |
22 |
- utils.replaceandsaveasnewfile(build_scripts_path + '/vmx-template', vmx_path, 'VMDK_IMAGE', output_path + '/photon-ova.vmdk') |
|
22 |
+ utils.replaceandsaveasnewfile(build_scripts_path + '/vmx-template', |
|
23 |
+ vmx_path, 'VMDK_IMAGE', |
|
24 |
+ output_path + '/photon-ova.vmdk') |
|
23 | 25 |
vixdiskutil_path = tools_path + 'vixdiskutil' |
24 | 26 |
vmdk_path = output_path + '/photon-ova.vmdk' |
25 | 27 |
ovf_path = output_path + '/photon-ova.ovf' |
26 | 28 |
mf_path = output_path + '/photon-ova.mf' |
27 | 29 |
ovfinfo_path = build_scripts_path + '/ovfinfo.txt' |
28 |
- vmdk_capacity = (int(config['size']['root']) + int(config['size']['swap'])) * 1024 |
|
29 |
- utils.runshellcommand("{} -convert {} -cap {} {}".format(vixdiskutil_path, raw_image_name, vmdk_capacity, vmdk_path)) |
|
30 |
- utils.runshellcommand("{} -wmeta toolsVersion 2147483647 {}".format(vixdiskutil_path, vmdk_path)) |
|
30 |
+ vmdk_capacity = (int(config['size']['root']) + |
|
31 |
+ int(config['size']['swap'])) * 1024 |
|
32 |
+ utils.runshellcommand( |
|
33 |
+ "{} -convert {} -cap {} {}".format(vixdiskutil_path, |
|
34 |
+ raw_image_name, |
|
35 |
+ vmdk_capacity, |
|
36 |
+ vmdk_path)) |
|
37 |
+ utils.runshellcommand( |
|
38 |
+ "{} -wmeta toolsVersion 2147483647 {}".format(vixdiskutil_path, vmdk_path)) |
|
31 | 39 |
|
32 | 40 |
utils.runshellcommand("ovftool {} {}".format(vmx_path, ovf_path)) |
33 | 41 |
utils.replaceinfile(ovf_path, 'otherGuest', 'other3xLinux64Guest') |
... | ... |
@@ -39,9 +47,9 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config): |
39 | 39 |
for line in fileinput.input(ovf_path, inplace=True): |
40 | 40 |
if line.strip() == '</VirtualHardwareSection>': |
41 | 41 |
for ovfinfoline in lines: |
42 |
- print ovfinfoline, |
|
42 |
+ print(ovfinfoline) |
|
43 | 43 |
else: |
44 |
- print line, |
|
44 |
+ print(line) |
|
45 | 45 |
|
46 | 46 |
if os.path.exists(mf_path): |
47 | 47 |
os.remove(mf_path) |
... | ... |
@@ -54,7 +62,7 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config): |
54 | 54 |
rawsplit = os.path.splitext(raw_image_name) |
55 | 55 |
ova_name = rawsplit[0] + '.ova' |
56 | 56 |
|
57 |
- ovatar = tarfile.open(ova_name, "w", format = tarfile.USTAR_FORMAT) |
|
57 |
+ ovatar = tarfile.open(ova_name, "w", format=tarfile.USTAR_FORMAT) |
|
58 | 58 |
for name in ["photon-ova.ovf", "photon-ova.mf", "photon-ova-disk1.vmdk"]: |
59 | 59 |
ovatar.add(name, arcname=os.path.basename(name)) |
60 | 60 |
ovatar.close() |
... | ... |
@@ -65,15 +73,17 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config): |
65 | 65 |
for addlversion in config['additionalhwversion']: |
66 | 66 |
new_ovf_path = output_path + "/photon-ova-hw{}.ovf".format(addlversion) |
67 | 67 |
mf_path = output_path + "/photon-ova-hw{}.mf".format(addlversion) |
68 |
- utils.replaceandsaveasnewfile(ovf_path, new_ovf_path, "vmx-.*<", "vmx-{}<".format(addlversion)) |
|
69 |
- out = utils.runshellcommand("openssl sha1 photon-ova-disk1.vmdk photon-ova-hw{}.ovf".format(addlversion)) |
|
68 |
+ utils.replaceandsaveasnewfile( |
|
69 |
+ ovf_path, new_ovf_path, "vmx-.*<", "vmx-{}<".format(addlversion)) |
|
70 |
+ out = utils.runshellcommand("openssl sha1 photon-ova-disk1.vmdk " |
|
71 |
+ "photon-ova-hw{}.ovf".format(addlversion)) |
|
70 | 72 |
with open(mf_path, "w") as source: |
71 | 73 |
source.write(out) |
72 | 74 |
temp_name_list = os.path.basename(ova_name).split('-') |
73 | 75 |
temp_name_list = temp_name_list[:2] + ["hw{}".format(addlversion)] + temp_name_list[2:] |
74 | 76 |
new_ova_name = '-'.join(temp_name_list) |
75 | 77 |
new_ova_path = output_path + '/' + new_ova_name |
76 |
- ovatar = tarfile.open(new_ova_path, "w", format = tarfile.USTAR_FORMAT) |
|
78 |
+ ovatar = tarfile.open(new_ova_path, "w", format=tarfile.USTAR_FORMAT) |
|
77 | 79 |
for name in [new_ovf_path, mf_path, "photon-ova-disk1.vmdk"]: |
78 | 80 |
ovatar.add(name, arcname=os.path.basename(name)) |
79 | 81 |
ovatar.close() |
... | ... |
@@ -91,70 +101,81 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config): |
91 | 91 |
|
92 | 92 |
if __name__ == '__main__': |
93 | 93 |
usage = "Usage: %prog [options]" |
94 |
- parser = OptionParser(usage) |
|
95 |
- |
|
96 |
- parser.add_option("-r", "--raw-image-path", dest="raw_image_path") |
|
97 |
- parser.add_option("-c", "--vmdk-config-path", dest="vmdk_config_path") |
|
98 |
- parser.add_option("-w", "--working-directory", dest="working_directory") |
|
99 |
- parser.add_option("-m", "--mount-path", dest="mount_path") |
|
100 |
- parser.add_option("-a", "--additional-rpms-path", dest="additional_rpms_path") |
|
101 |
- parser.add_option("-i", "--image-name", dest="image_name") |
|
102 |
- parser.add_option("-t", "--tools-bin-path", dest="tools_bin_path") |
|
103 |
- parser.add_option("-b", "--build-scripts-path", dest="build_scripts_path") |
|
104 |
- parser.add_option("-s", "--src-root", dest="src_root") |
|
105 |
- |
|
106 |
- (options, args) = parser.parse_args() |
|
94 |
+ parser = ArgumentParser(usage) |
|
95 |
+ |
|
96 |
+ parser.add_argument("-r", "--raw-image-path", dest="raw_image_path") |
|
97 |
+ parser.add_argument("-c", "--vmdk-config-path", dest="vmdk_config_path") |
|
98 |
+ parser.add_argument("-w", "--working-directory", dest="working_directory") |
|
99 |
+ parser.add_argument("-m", "--mount-path", dest="mount_path") |
|
100 |
+ parser.add_argument("-a", "--additional-rpms-path", dest="additional_rpms_path") |
|
101 |
+ parser.add_argument("-i", "--image-name", dest="image_name") |
|
102 |
+ parser.add_argument("-t", "--tools-bin-path", dest="tools_bin_path") |
|
103 |
+ parser.add_argument("-b", "--build-scripts-path", dest="build_scripts_path") |
|
104 |
+ parser.add_argument("-s", "--src-root", dest="src_root") |
|
105 |
+ |
|
106 |
+ options = parser.parse_args() |
|
107 | 107 |
utils = Utils() |
108 | 108 |
config = utils.jsonread(options.vmdk_config_path) |
109 |
- print options |
|
109 |
+ print(options) |
|
110 | 110 |
|
111 |
- disk_device = (utils.runshellcommand("losetup --show -f {}".format(options.raw_image_path))).rstrip('\n') |
|
111 |
+ disk_device = (utils.runshellcommand( |
|
112 |
+ "losetup --show -f {}".format(options.raw_image_path))).rstrip('\n') |
|
112 | 113 |
disk_partitions = utils.runshellcommand("kpartx -as {}".format(disk_device)) |
113 | 114 |
device_name = disk_device.split('/')[2] |
114 | 115 |
|
115 | 116 |
if not os.path.exists(options.mount_path): |
116 | 117 |
os.mkdir(options.mount_path) |
117 |
- loop_device_path = "/dev/mapper/{}p2".format(device_name) |
|
118 |
+ loop_device_path = "/dev/mapper/{}p2".format(device_name) |
|
118 | 119 |
|
119 | 120 |
try: |
120 |
- print "Generating PARTUUID for the loop device ..." |
|
121 |
- partuuidval = (utils.runshellcommand("blkid -s PARTUUID -o value {}".format(loop_device_path))).rstrip('\n') |
|
122 |
- uuidval = (utils.runshellcommand("blkid -s UUID -o value {}".format(loop_device_path))).rstrip('\n') |
|
123 |
- if (partuuidval == ''): |
|
124 |
- sgdiskout = utils.runshellcommand("sgdisk -i 2 {} ".format(disk_device)) |
|
125 |
- partuuidval = (re.findall(r'Partition unique GUID.*', sgdiskout))[0].split(':')[1].strip(' ').lower() |
|
126 |
- |
|
127 |
- if (partuuidval == ''): |
|
121 |
+ print("Generating PARTUUID for the loop device ...") |
|
122 |
+ partuuidval = (utils.runshellcommand( |
|
123 |
+ "blkid -s PARTUUID -o value {}".format(loop_device_path))).rstrip('\n') |
|
124 |
+ uuidval = (utils.runshellcommand( |
|
125 |
+ "blkid -s UUID -o value {}".format(loop_device_path))).rstrip('\n') |
|
126 |
+ if partuuidval == '': |
|
127 |
+ sgdiskout = utils.runshellcommand( |
|
128 |
+ "sgdisk -i 2 {} ".format(disk_device)) |
|
129 |
+ partuuidval = (re.findall(r'Partition unique GUID.*', |
|
130 |
+ sgdiskout))[0].split(':')[1].strip(' ').lower() |
|
131 |
+ |
|
132 |
+ if partuuidval == '': |
|
128 | 133 |
raise RuntimeError("Cannot generate partuuid") |
129 | 134 |
|
130 | 135 |
# Mount the loop device |
131 |
- print "Mounting the loop device for customization ..." |
|
132 |
- utils.runshellcommand("mount -t ext4 {} {}".format(loop_device_path, options.mount_path)) |
|
136 |
+ print("Mounting the loop device for customization ...") |
|
137 |
+ utils.runshellcommand( |
|
138 |
+ "mount -t ext4 {} {}".format(loop_device_path, options.mount_path)) |
|
133 | 139 |
shutil.rmtree(options.mount_path + "/installer", ignore_errors=True) |
134 | 140 |
shutil.rmtree(options.mount_path + "/LOGS", ignore_errors=True) |
135 | 141 |
# Clear the root password if not set explicitly from the config file |
136 |
- if (config['password']['text'] != 'PASSWORD'): |
|
137 |
- utils.replaceinfile(options.mount_path + "/etc/shadow",'root:.*?:','root:*:') |
|
142 |
+ if config['password']['text'] != 'PASSWORD': |
|
143 |
+ utils.replaceinfile(options.mount_path + "/etc/shadow", |
|
144 |
+ 'root:.*?:', 'root:*:') |
|
138 | 145 |
# Clear machine-id so it gets regenerated on boot |
139 | 146 |
open(options.mount_path + "/etc/machine-id", "w").close() |
140 | 147 |
os.remove(options.mount_path + "/etc/fstab") |
141 | 148 |
|
142 | 149 |
f = open(options.mount_path + "/etc/fstab", "w") |
143 |
- if (uuidval != ''): |
|
150 |
+ if uuidval != '': |
|
144 | 151 |
f.write("UUID={} / ext4 defaults 1 1\n".format(uuidval)) |
145 | 152 |
else: |
146 | 153 |
f.write("PARTUUID={} / ext4 defaults 1 1\n".format(partuuidval)) |
147 | 154 |
f.close() |
148 |
- utils.replaceinfile(options.mount_path + "/boot/grub/grub.cfg", "rootpartition=PARTUUID=.*$", "rootpartition=PARTUUID={}".format(partuuidval)) |
|
155 |
+ utils.replaceinfile(options.mount_path + "/boot/grub/grub.cfg", |
|
156 |
+ "rootpartition=PARTUUID=.*$", |
|
157 |
+ "rootpartition=PARTUUID={}".format(partuuidval)) |
|
149 | 158 |
|
150 | 159 |
if os.path.exists(options.additional_rpms_path): |
151 |
- print "Installing additional rpms" |
|
160 |
+ print("Installing additional rpms") |
|
152 | 161 |
os.mkdir(options.mount_path + "/additional_rpms") |
153 | 162 |
os.mkdir(options.mount_path + "/var/run") |
154 |
- utils.copyallfiles(additional_rpms_path, options.mount_path + "/additional_rpms") |
|
155 |
- utils.runshellcommand("chroot {} /bin/bash -c 'rpm -i /additional_rpms/*'".format(options.mount_path)) |
|
163 |
+ utils.copyallfiles(options.additional_rpms_path, |
|
164 |
+ options.mount_path + "/additional_rpms") |
|
165 |
+ utils.runshellcommand( |
|
166 |
+ "chroot {} /bin/bash -c 'rpm -i /additional_rpms/*'".format(options.mount_path)) |
|
156 | 167 |
shutil.rmtree(options.mount_path + "/additional_rpms", ignore_errors=True) |
157 |
- shutil.rmtree(additional_rpms_path, ignore_errors=True) |
|
168 |
+ shutil.rmtree(options.additional_rpms_path, ignore_errors=True) |
|
158 | 169 |
|
159 | 170 |
utils.runshellcommand("mount -o bind /proc {}".format(options.mount_path + "/proc")) |
160 | 171 |
utils.runshellcommand("mount -o bind /dev {}".format(options.mount_path + "/dev")) |
... | ... |
@@ -162,28 +183,36 @@ if __name__ == '__main__': |
162 | 162 |
utils.runshellcommand("mount -o bind /sys {}".format(options.mount_path + "/sys")) |
163 | 163 |
|
164 | 164 |
if 'additionalfiles' in config: |
165 |
- print " Copying additional files into the raw image ..." |
|
165 |
+ print(" Copying additional files into the raw image ...") |
|
166 | 166 |
for filetuples in config['additionalfiles']: |
167 |
- for src,dest in filetuples.iteritems(): |
|
168 |
- if (os.path.isdir(options.build_scripts_path + '/' + options.image_name + '/' + src)): |
|
169 |
- shutil.copytree(options.build_scripts_path + '/' + options.image_name + '/' + src, options.mount_path + dest, True) |
|
167 |
+ for src, dest in filetuples.items(): |
|
168 |
+ if (os.path.isdir(options.build_scripts_path + '/' + |
|
169 |
+ options.image_name + '/' + src)): |
|
170 |
+ shutil.copytree(options.build_scripts_path + '/' + |
|
171 |
+ options.image_name + '/' + src, |
|
172 |
+ options.mount_path + dest, True) |
|
170 | 173 |
else: |
171 |
- shutil.copyfile(options.build_scripts_path + '/' + options.image_name + '/' + src, options.mount_path + dest) |
|
174 |
+ shutil.copyfile(options.build_scripts_path + '/' + |
|
175 |
+ options.image_name + '/' + src, |
|
176 |
+ options.mount_path + dest) |
|
172 | 177 |
|
173 | 178 |
|
174 | 179 |
if 'postinstallscripts' in config: |
175 |
- print " Running post install scripts ..." |
|
180 |
+ print(" Running post install scripts ...") |
|
176 | 181 |
if not os.path.exists(options.mount_path + "/tempscripts"): |
177 | 182 |
os.mkdir(options.mount_path + "/tempscripts") |
178 | 183 |
for script in config['postinstallscripts']: |
179 |
- shutil.copy(options.build_scripts_path + '/' + options.image_name + '/' + script, options.mount_path + "/tempscripts") |
|
184 |
+ shutil.copy(options.build_scripts_path + '/' + |
|
185 |
+ options.image_name + '/' + script, |
|
186 |
+ options.mount_path + "/tempscripts") |
|
180 | 187 |
for script in os.listdir(options.mount_path + "/tempscripts"): |
181 |
- print " ...running script {}".format(script) |
|
182 |
- utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'".format(options.mount_path, script)) |
|
188 |
+ print(" ...running script {}".format(script)) |
|
189 |
+ utils.runshellcommand( |
|
190 |
+ "chroot {} /bin/bash -c '/tempscripts/{}'".format(options.mount_path, script)) |
|
183 | 191 |
shutil.rmtree(options.mount_path + "/tempscripts", ignore_errors=True) |
184 | 192 |
|
185 | 193 |
except Exception as e: |
186 |
- print e |
|
194 |
+ print(e) |
|
187 | 195 |
|
188 | 196 |
finally: |
189 | 197 |
utils.runshellcommand("umount -l {}".format(options.mount_path + "/sys")) |
... | ... |
@@ -195,8 +224,8 @@ if __name__ == '__main__': |
195 | 195 |
utils.runshellcommand("umount -l {}".format(options.mount_path)) |
196 | 196 |
|
197 | 197 |
mount_out = utils.runshellcommand("mount") |
198 |
- print "List of mounted devices:" |
|
199 |
- print mount_out |
|
198 |
+ print("List of mounted devices:") |
|
199 |
+ print(mount_out) |
|
200 | 200 |
|
201 | 201 |
utils.runshellcommand("kpartx -d {}".format(disk_device)) |
202 | 202 |
utils.runshellcommand("losetup -d {}".format(disk_device)) |
... | ... |
@@ -210,39 +239,56 @@ if __name__ == '__main__': |
210 | 210 |
img_path = os.path.dirname(os.path.realpath(raw_image)) |
211 | 211 |
# Rename gce image to disk.raw |
212 | 212 |
if options.image_name == "gce": |
213 |
- print "Renaming the raw file to disk.raw ..." |
|
213 |
+ print("Renaming the raw file to disk.raw ...") |
|
214 | 214 |
new_name = img_path + '/disk.raw' |
215 | 215 |
|
216 | 216 |
else: |
217 |
- new_name = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.raw' |
|
217 |
+ new_name = (img_path + '/photon-' + options.image_name + |
|
218 |
+ '-' + photon_release_ver + '-' + |
|
219 |
+ photon_build_num + '.raw') |
|
218 | 220 |
|
219 | 221 |
shutil.move(raw_image, new_name) |
220 | 222 |
raw_image = new_name |
221 | 223 |
|
222 | 224 |
if config['artifacttype'] == 'tgz': |
223 |
- print "Generating the tar.gz artifact ..." |
|
224 |
- tarname = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.tar.gz' |
|
225 |
+ print("Generating the tar.gz artifact ...") |
|
226 |
+ tarname = (img_path + '/photon-' + options.image_name + |
|
227 |
+ '-' + photon_release_ver + '-' + |
|
228 |
+ photon_build_num + '.tar.gz') |
|
229 |
+ |
|
225 | 230 |
tgzout = tarfile.open(tarname, "w:gz") |
226 | 231 |
tgzout.add(raw_image, arcname=os.path.basename(raw_image)) |
227 | 232 |
tgzout.close() |
228 | 233 |
elif config['artifacttype'] == 'xz': |
229 |
- print "Generating the xz artifact ..." |
|
234 |
+ print("Generating the xz artifact ...") |
|
230 | 235 |
utils.runshellcommand("xz -z -k {}".format(raw_image)) |
231 |
-# tarname = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.xz' |
|
236 |
+# tarname = img_path + '/photon-' + options.image_name + |
|
237 |
+# '-' + photon_release_ver + '-' + photon_build_num + |
|
238 |
+# '.xz' |
|
232 | 239 |
# tgzout = tarfile.open(tarname, "w:xz") |
233 | 240 |
# tgzout.add(raw_image, arcname=os.path.basename(raw_image)) |
234 | 241 |
# tgzout.close() |
235 | 242 |
elif config['artifacttype'] == 'vhd': |
236 | 243 |
relrawpath = os.path.relpath(raw_image, options.src_root) |
237 |
- vhdname = os.path.dirname(relrawpath) + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.vhd' |
|
238 |
- print "Converting raw disk to vhd ..." |
|
239 |
- info_output=utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img info -f raw --output json {}".format(options.src_root, '/mnt/' + relrawpath)) |
|
244 |
+ vhdname = (os.path.dirname(relrawpath) + '/photon-' + |
|
245 |
+ options.image_name + '-' + photon_release_ver + '-' + |
|
246 |
+ photon_build_num + '.vhd') |
|
247 |
+ print("Converting raw disk to vhd ...") |
|
248 |
+ info_output = utils.runshellcommand( |
|
249 |
+ "docker run -v {}:/mnt:rw anishs/qemu-img info -f raw --output json {}" |
|
250 |
+ .format(options.src_root, '/mnt/' + relrawpath)) |
|
240 | 251 |
mbsize = 1024 * 1024 |
241 | 252 |
mbroundedsize = ((int(json.loads(info_output)["virtual-size"])/mbsize + 1) * mbsize) |
242 |
- utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img resize -f raw {} {}".format(options.src_root, '/mnt/' + relrawpath, mbroundedsize)) |
|
243 |
- utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img convert {} -O vpc -o subformat=fixed,force_size {}".format(options.src_root, '/mnt/' + relrawpath, '/mnt/' + vhdname)) |
|
253 |
+ utils.runshellcommand( |
|
254 |
+ "docker run -v {}:/mnt:rw anishs/qemu-img resize -f raw {} {}" |
|
255 |
+ .format(options.src_root, '/mnt/' + relrawpath, mbroundedsize)) |
|
256 |
+ utils.runshellcommand( |
|
257 |
+ "docker run -v {}:/mnt:rw anishs/qemu-img convert {} -O " |
|
258 |
+ "vpc -o subformat=fixed,force_size {}" |
|
259 |
+ .format(options.src_root, '/mnt/' + relrawpath, '/mnt/' + vhdname)) |
|
244 | 260 |
elif config['artifacttype'] == 'ova': |
245 |
- create_ova_image(raw_image, options.tools_bin_path, options.build_scripts_path + '/' + options.image_name, config) |
|
261 |
+ create_ova_image(raw_image, options.tools_bin_path, |
|
262 |
+ options.build_scripts_path + '/' + options.image_name, config) |
|
246 | 263 |
if 'customartifacts' in config: |
247 | 264 |
if 'postinstallscripts' in config['customartifacts']: |
248 | 265 |
custom_path = img_path + '/photon-custom' |
... | ... |
@@ -250,34 +296,46 @@ if __name__ == '__main__': |
250 | 250 |
os.mkdir(custom_path) |
251 | 251 |
index = 1 |
252 | 252 |
for script in config['customartifacts']['postinstallscripts']: |
253 |
- print "Creating custom ova {}...".format(index) |
|
253 |
+ print("Creating custom ova {}...".format(index)) |
|
254 | 254 |
if index > 1: |
255 |
- raw_image_custom = img_path + "/photon-custom-{}".format(index) + photon_release_ver + '-' + photon_build_num + '.raw' |
|
255 |
+ raw_image_custom = (img_path + "/photon-custom-{}".format(index) + |
|
256 |
+ photon_release_ver + '-' + |
|
257 |
+ photon_build_num + '.raw') |
|
256 | 258 |
else: |
257 |
- raw_image_custom = img_path + "/photon-custom-" + photon_release_ver + '-' + photon_build_num + '.raw' |
|
259 |
+ raw_image_custom = (img_path + "/photon-custom-" + |
|
260 |
+ photon_release_ver + '-' + |
|
261 |
+ photon_build_num + '.raw') |
|
258 | 262 |
shutil.move(raw_image, raw_image_custom) |
259 |
- disk_device = (utils.runshellcommand("losetup --show -f {}".format(raw_image_custom))).rstrip('\n') |
|
260 |
- disk_partitions = utils.runshellcommand("kpartx -as {}".format(disk_device)) |
|
263 |
+ disk_device = ( |
|
264 |
+ utils.runshellcommand( |
|
265 |
+ "losetup --show -f {}".format(raw_image_custom))).rstrip('\n') |
|
266 |
+ disk_partitions = utils.runshellcommand( |
|
267 |
+ "kpartx -as {}".format(disk_device)) |
|
261 | 268 |
device_name = disk_device.split('/')[2] |
262 |
- loop_device_path = "/dev/mapper/{}p2".format(device_name) |
|
269 |
+ loop_device_path = "/dev/mapper/{}p2".format(device_name) |
|
263 | 270 |
|
264 |
- print "Mounting the loop device for ova customization ..." |
|
265 |
- utils.runshellcommand("mount -t ext4 {} {}".format(loop_device_path, custom_path)) |
|
271 |
+ print("Mounting the loop device for ova customization ...") |
|
272 |
+ utils.runshellcommand( |
|
273 |
+ "mount -t ext4 {} {}".format(loop_device_path, custom_path)) |
|
266 | 274 |
if not os.path.exists(custom_path + "/tempscripts"): |
267 | 275 |
os.mkdir(custom_path + "/tempscripts") |
268 |
- shutil.copy(options.build_scripts_path + '/' + options.image_name + '/' + script, custom_path + "/tempscripts") |
|
269 |
- print "Running custom ova script {}".format(script) |
|
270 |
- utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'".format(custom_path, script)) |
|
276 |
+ shutil.copy(options.build_scripts_path + '/' + options.image_name + |
|
277 |
+ '/' + script, custom_path + "/tempscripts") |
|
278 |
+ print("Running custom ova script {}".format(script)) |
|
279 |
+ utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'" |
|
280 |
+ .format(custom_path, script)) |
|
271 | 281 |
shutil.rmtree(custom_path + "/tempscripts", ignore_errors=True) |
272 | 282 |
utils.runshellcommand("umount -l {}".format(custom_path)) |
273 | 283 |
|
274 | 284 |
mount_out = utils.runshellcommand("mount") |
275 |
- print "List of mounted devices:" |
|
276 |
- print mount_out |
|
285 |
+ print("List of mounted devices:") |
|
286 |
+ print(mount_out) |
|
277 | 287 |
|
278 | 288 |
utils.runshellcommand("kpartx -d {}".format(disk_device)) |
279 | 289 |
utils.runshellcommand("losetup -d {}".format(disk_device)) |
280 |
- create_ova_image(raw_image_custom, options.tools_bin_path, options.build_scripts_path + '/' + options.image_name, config) |
|
290 |
+ create_ova_image(raw_image_custom, options.tools_bin_path, |
|
291 |
+ options.build_scripts_path + '/' + options.image_name, |
|
292 |
+ config) |
|
281 | 293 |
raw_image = raw_image_custom |
282 | 294 |
index = index + 1 |
283 | 295 |
|
... | ... |
@@ -1,5 +1,3 @@ |
1 |
-#!/usr/bin/python2 |
|
2 |
- |
|
3 | 1 |
import os |
4 | 2 |
import ctypes |
5 | 3 |
import ctypes.util |
... | ... |
@@ -8,6 +6,7 @@ import collections |
8 | 8 |
import subprocess |
9 | 9 |
import fileinput |
10 | 10 |
import re |
11 |
+import shutil |
|
11 | 12 |
|
12 | 13 |
class Utils(object): |
13 | 14 |
def __init__(self): |
... | ... |
@@ -33,45 +32,51 @@ class Utils(object): |
33 | 33 |
ctypes.c_char_p(flags), |
34 | 34 |
0) |
35 | 35 |
if ret != 0: |
36 |
- raise RuntimeError("Cannot mount {} : {}".format(source, os.strerror(ctypes.get_errno()))) |
|
36 |
+ raise RuntimeError( |
|
37 |
+ "Cannot mount {} : {}".format(source, os.strerror(ctypes.get_errno()))) |
|
37 | 38 |
|
38 | 39 |
def umount(self, destination): |
39 | 40 |
ret = self.libcloader.umount(ctypes.c_char_p(destination)) |
40 | 41 |
if ret != 0: |
41 |
- raise RuntimeError("Cannot umount {} : {}".format(destination, os.strerror(ctypes.get_errno()))) |
|
42 |
- |
|
43 |
- def jsonread(self, filename): |
|
42 |
+ raise RuntimeError( |
|
43 |
+ "Cannot umount {} : {}".format(destination, os.strerror(ctypes.get_errno()))) |
|
44 |
+ @staticmethod |
|
45 |
+ def jsonread(filename): |
|
44 | 46 |
json_data = open(filename) |
45 | 47 |
data = json.load(json_data, object_pairs_hook=collections.OrderedDict) |
46 | 48 |
json_data.close() |
47 | 49 |
return data |
48 | 50 |
|
49 |
- def runshellcommand(self, cmd, ignore_errors=False): |
|
50 |
- print cmd |
|
51 |
- command=cmd.split() |
|
51 |
+ @staticmethod |
|
52 |
+ def runshellcommand(cmd, ignore_errors=False): |
|
53 |
+ print(cmd) |
|
54 |
+ command = cmd.split() |
|
52 | 55 |
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
53 | 56 |
output, err = p.communicate() |
54 | 57 |
rc = p.returncode |
55 | 58 |
if not ignore_errors: |
56 | 59 |
if rc != 0: |
57 |
- print err |
|
60 |
+ print(err) |
|
58 | 61 |
raise RuntimeError("Cannot run command {}".format(cmd)) |
59 |
- return output |
|
62 |
+ return output.decode() |
|
60 | 63 |
|
61 |
- def replaceinfile(self, filename, pattern, sub): |
|
64 |
+ @staticmethod |
|
65 |
+ def replaceinfile(filename, pattern, sub): |
|
62 | 66 |
for line in fileinput.input(filename, inplace=True): |
63 | 67 |
line = re.sub(pattern, sub, line) |
64 |
- print line, |
|
68 |
+ print(line) |
|
65 | 69 |
|
66 |
- def replaceandsaveasnewfile(self, old_file, new_file, pattern, sub): |
|
70 |
+ @staticmethod |
|
71 |
+ def replaceandsaveasnewfile(old_file, new_file, pattern, sub): |
|
67 | 72 |
with open(old_file, "r") as old, open(new_file, "w") as new: |
68 | 73 |
for line in old: |
69 | 74 |
line = re.sub(pattern, sub, line) |
70 | 75 |
new.write(line) |
71 | 76 |
|
72 |
- def copyallfiles(self, src, target): |
|
77 |
+ @staticmethod |
|
78 |
+ def copyallfiles(src, target): |
|
73 | 79 |
files = os.listdir(src) |
74 | 80 |
for file in files: |
75 | 81 |
filename = os.path.join(src, file) |
76 |
- if (os.path.isfile(filename)): |
|
82 |
+ if os.path.isfile(filename): |
|
77 | 83 |
shutil.copy(filename, target) |
... | ... |
@@ -5,9 +5,7 @@ |
5 | 5 |
# Author: Harish Udaiya Kumar <hudaiyakumar@vmware.com> |
6 | 6 |
import sys |
7 | 7 |
import os |
8 |
-from optparse import OptionParser |
|
9 |
-from SpecUtils import Specutils |
|
10 |
-from SpecData import SerializableSpecObject |
|
8 |
+from argparse import ArgumentParser |
|
11 | 9 |
from SpecData import SerializedSpecObjects |
12 | 10 |
from jsonwrapper import JsonWrapper |
13 | 11 |
|
... | ... |
@@ -17,19 +15,17 @@ SPEC_FILE_DIR = "../../SPECS" |
17 | 17 |
LOG_FILE_DIR = "../../stage/LOGS" |
18 | 18 |
|
19 | 19 |
def main(): |
20 |
- usage = (os.path.basename(__file__) + |
|
21 |
- "--input-type=[json/pkg/who-needs/who-needs-build] " + |
|
22 |
- "--pkg=[pkg_name] --file=<JSON_FILE_NAME> --disp=[tree/list/json]") |
|
23 |
- parser = OptionParser(usage) |
|
24 |
- parser.add_option("-i", "--input-type", dest="input_type", default=DEFAULT_INPUT_TYPE) |
|
25 |
- parser.add_option("-p", "--pkg", dest="pkg") |
|
26 |
- parser.add_option("-f", "--file", dest="json_file", default="packages_minimal.json") |
|
27 |
- parser.add_option("-d", "--disp", dest="display_option", default=DEFAULT_DISPLAY_OPTION) |
|
28 |
- parser.add_option("-s", "--spec-dir", dest="spec_dir", default=SPEC_FILE_DIR) |
|
29 |
- parser.add_option("-t", "--stage-dir", dest="stage_dir", default="../../stage") |
|
30 |
- parser.add_option("-a", "--input-data-dir", dest="input_data_dir", |
|
31 |
- default="../../common/data/") |
|
32 |
- (options, args) = parser.parse_args() |
|
20 |
+ usage = "Usage: %prog [options]" |
|
21 |
+ parser = ArgumentParser(usage) |
|
22 |
+ parser.add_argument("-i", "--input-type", dest="input_type", default=DEFAULT_INPUT_TYPE) |
|
23 |
+ parser.add_argument("-p", "--pkg", dest="pkg") |
|
24 |
+ parser.add_argument("-f", "--file", dest="json_file", default="packages_minimal.json") |
|
25 |
+ parser.add_argument("-d", "--disp", dest="display_option", default=DEFAULT_DISPLAY_OPTION) |
|
26 |
+ parser.add_argument("-s", "--spec-dir", dest="spec_dir", default=SPEC_FILE_DIR) |
|
27 |
+ parser.add_argument("-t", "--stage-dir", dest="stage_dir", default="../../stage") |
|
28 |
+ parser.add_argument("-a", "--input-data-dir", dest="input_data_dir", |
|
29 |
+ default="../../common/data/") |
|
30 |
+ options = parser.parse_args() |
|
33 | 31 |
|
34 | 32 |
if not options.input_data_dir.endswith('/'): |
35 | 33 |
options.input_data_dir += '/' |
... | ... |
@@ -42,13 +38,13 @@ def main(): |
42 | 42 |
|
43 | 43 |
# To display/print package dependencies on console |
44 | 44 |
if(options.input_type == "pkg" or |
45 |
- options.input_type == "who-needs" or |
|
46 |
- options.input_type == "who-needs-build"): |
|
45 |
+ options.input_type == "who-needs" or |
|
46 |
+ options.input_type == "who-needs-build"): |
|
47 | 47 |
targetName = options.pkg |
48 | 48 |
specDeps.readSpecsAndConvertToSerializableObjects(options.spec_dir, |
49 | 49 |
options.input_type, |
50 | 50 |
targetName, displayOption) |
51 |
- elif(options.input_type == "json"): |
|
51 |
+ elif options.input_type == "json": |
|
52 | 52 |
# Generate the expanded package dependencies json file based on package_list_file |
53 | 53 |
json_wrapper_option_list = JsonWrapper(options.json_file) |
54 | 54 |
option_list_json = json_wrapper_option_list.read() |
... | ... |
@@ -60,7 +56,7 @@ def main(): |
60 | 60 |
options.spec_dir, |
61 | 61 |
options.input_type, install_option[1]["file"], |
62 | 62 |
displayOption) |
63 |
- except Exception as error: |
|
63 |
+ except Exception as _: |
|
64 | 64 |
sys.stderr.write("Failed to generate dependency lists from spec files\n") |
65 | 65 |
sys.exit(1) |
66 | 66 |
|