|
|
1abbee |
From 72b3ff75e786efa2c9b2fdfb50e46597434c5420 Mon Sep 17 00:00:00 2001
|
|
|
1abbee |
From: Lukas Nykryn <lnykryn@redhat.com>
|
|
|
1abbee |
Date: Wed, 20 Jan 2016 15:16:32 +0100
|
|
|
1abbee |
Subject: [PATCH] sysv-generator: do not join dependencies on one line, split
|
|
|
1abbee |
them
|
|
|
1abbee |
|
|
|
1abbee |
If there is a lot of initscripts and dependencies between them we might
|
|
|
1abbee |
end generating After= (and similar) lines which are longer then LINE_MAX
|
|
|
1abbee |
and thus rejected by parser in systemd.
|
|
|
1abbee |
|
|
|
1abbee |
Fixes #2099
|
|
|
1abbee |
|
|
|
1abbee |
Cherry-picked from: c584ffc0b75d4b9e9229bf1d8edb7d89562be3c1
|
|
|
1abbee |
Resolves: #1288600
|
|
|
1abbee |
---
|
|
|
23b3cf |
src/sysv-generator/sysv-generator.c | 44 ++++++++---------------------
|
|
|
23b3cf |
test/sysv-generator-test.py | 18 ++++++++++--
|
|
|
1abbee |
2 files changed, 28 insertions(+), 34 deletions(-)
|
|
|
1abbee |
|
|
|
1abbee |
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
|
|
|
181b3f |
index 0a8a528bd..d60e75a06 100644
|
|
|
1abbee |
--- a/src/sysv-generator/sysv-generator.c
|
|
|
1abbee |
+++ b/src/sysv-generator/sysv-generator.c
|
|
|
1abbee |
@@ -134,34 +134,14 @@ static int add_alias(const char *service, const char *alias) {
|
|
|
1abbee |
}
|
|
|
1abbee |
|
|
|
1abbee |
static int generate_unit_file(SysvStub *s) {
|
|
|
1abbee |
- char **p;
|
|
|
1abbee |
_cleanup_fclose_ FILE *f = NULL;
|
|
|
1abbee |
- _cleanup_free_ char *unit = NULL;
|
|
|
1abbee |
- _cleanup_free_ char *before = NULL;
|
|
|
1abbee |
- _cleanup_free_ char *after = NULL;
|
|
|
1abbee |
- _cleanup_free_ char *wants = NULL;
|
|
|
1abbee |
- _cleanup_free_ char *conflicts = NULL;
|
|
|
1abbee |
+ const char *unit;
|
|
|
1abbee |
+ char **p;
|
|
|
1abbee |
int r;
|
|
|
1abbee |
|
|
|
1abbee |
- before = strv_join(s->before, " ");
|
|
|
1abbee |
- if (!before)
|
|
|
1abbee |
- return log_oom();
|
|
|
1abbee |
-
|
|
|
1abbee |
- after = strv_join(s->after, " ");
|
|
|
1abbee |
- if (!after)
|
|
|
1abbee |
- return log_oom();
|
|
|
1abbee |
-
|
|
|
1abbee |
- wants = strv_join(s->wants, " ");
|
|
|
1abbee |
- if (!wants)
|
|
|
1abbee |
- return log_oom();
|
|
|
1abbee |
-
|
|
|
1abbee |
- conflicts = strv_join(s->conflicts, " ");
|
|
|
1abbee |
- if (!conflicts)
|
|
|
1abbee |
- return log_oom();
|
|
|
1abbee |
+ assert(s);
|
|
|
1abbee |
|
|
|
1abbee |
- unit = strjoin(arg_dest, "/", s->name, NULL);
|
|
|
1abbee |
- if (!unit)
|
|
|
1abbee |
- return log_oom();
|
|
|
1abbee |
+ unit = strjoina(arg_dest, "/", s->name);
|
|
|
1abbee |
|
|
|
1abbee |
/* We might already have a symlink with the same name from a Provides:,
|
|
|
1abbee |
* or from backup files like /etc/init.d/foo.bak. Real scripts always win,
|
|
|
1abbee |
@@ -183,14 +163,14 @@ static int generate_unit_file(SysvStub *s) {
|
|
|
1abbee |
"Description=%s\n",
|
|
|
1abbee |
s->path, s->description);
|
|
|
1abbee |
|
|
|
1abbee |
- if (!isempty(before))
|
|
|
1abbee |
- fprintf(f, "Before=%s\n", before);
|
|
|
1abbee |
- if (!isempty(after))
|
|
|
1abbee |
- fprintf(f, "After=%s\n", after);
|
|
|
1abbee |
- if (!isempty(wants))
|
|
|
1abbee |
- fprintf(f, "Wants=%s\n", wants);
|
|
|
1abbee |
- if (!isempty(conflicts))
|
|
|
1abbee |
- fprintf(f, "Conflicts=%s\n", conflicts);
|
|
|
1abbee |
+ STRV_FOREACH(p, s->before)
|
|
|
1abbee |
+ fprintf(f, "Before=%s\n", *p);
|
|
|
1abbee |
+ STRV_FOREACH(p, s->after)
|
|
|
1abbee |
+ fprintf(f, "After=%s\n", *p);
|
|
|
1abbee |
+ STRV_FOREACH(p, s->wants)
|
|
|
1abbee |
+ fprintf(f, "Wants=%s\n", *p);
|
|
|
1abbee |
+ STRV_FOREACH(p, s->conflicts)
|
|
|
1abbee |
+ fprintf(f, "Conflicts=%s\n", *p);
|
|
|
1abbee |
|
|
|
1abbee |
fprintf(f,
|
|
|
1abbee |
"\n[Service]\n"
|
|
|
1abbee |
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
|
|
|
181b3f |
index 2060ad754..25a35da47 100644
|
|
|
1abbee |
--- a/test/sysv-generator-test.py
|
|
|
1abbee |
+++ b/test/sysv-generator-test.py
|
|
|
1abbee |
@@ -23,6 +23,7 @@ import subprocess
|
|
|
1abbee |
import tempfile
|
|
|
1abbee |
import shutil
|
|
|
1abbee |
from glob import glob
|
|
|
1abbee |
+import collections
|
|
|
1abbee |
|
|
|
1abbee |
try:
|
|
|
1abbee |
from configparser import RawConfigParser
|
|
|
1abbee |
@@ -32,6 +33,12 @@ except ImportError:
|
|
|
1abbee |
|
|
|
1abbee |
sysv_generator = os.path.join(os.environ.get('builddir', '.'), 'systemd-sysv-generator')
|
|
|
1abbee |
|
|
|
1abbee |
+class MultiDict(collections.OrderedDict):
|
|
|
1abbee |
+ def __setitem__(self, key, value):
|
|
|
1abbee |
+ if isinstance(value, list) and key in self:
|
|
|
1abbee |
+ self[key].extend(value)
|
|
|
1abbee |
+ else:
|
|
|
1abbee |
+ super(MultiDict, self).__setitem__(key, value)
|
|
|
1abbee |
|
|
|
1abbee |
class SysvGeneratorTest(unittest.TestCase):
|
|
|
1abbee |
def setUp(self):
|
|
|
1abbee |
@@ -77,7 +84,14 @@ class SysvGeneratorTest(unittest.TestCase):
|
|
|
1abbee |
for service in glob(self.out_dir + '/*.service'):
|
|
|
1abbee |
if os.path.islink(service):
|
|
|
1abbee |
continue
|
|
|
1abbee |
- cp = RawConfigParser()
|
|
|
1abbee |
+ try:
|
|
|
1abbee |
+ # for python3 we need here strict=False to parse multiple
|
|
|
1abbee |
+ # lines with the same key
|
|
|
1abbee |
+ cp = RawConfigParser(dict_type=MultiDict, strict=False)
|
|
|
1abbee |
+ except TypeError:
|
|
|
1abbee |
+ # RawConfigParser in python2 does not have the strict option
|
|
|
1abbee |
+ # but it allows multiple lines with the same key by default
|
|
|
1abbee |
+ cp = RawConfigParser(dict_type=MultiDict)
|
|
|
1abbee |
cp.optionxform = lambda o: o # don't lower-case option names
|
|
|
1abbee |
with open(service) as f:
|
|
|
1abbee |
cp.readfp(f)
|
|
|
1abbee |
@@ -215,7 +229,7 @@ class SysvGeneratorTest(unittest.TestCase):
|
|
|
1abbee |
s = self.run_generator()[1]['foo.service']
|
|
|
1abbee |
self.assertEqual(set(s.options('Unit')),
|
|
|
1abbee |
set(['Documentation', 'SourcePath', 'Description', 'After']))
|
|
|
1abbee |
- self.assertEqual(s.get('Unit', 'After'), 'nss-lookup.target rpcbind.target')
|
|
|
1abbee |
+ self.assertEqual(s.get('Unit', 'After').split(), ['nss-lookup.target', 'rpcbind.target'])
|
|
|
1abbee |
|
|
|
1abbee |
def test_lsb_deps(self):
|
|
|
1abbee |
'''LSB header dependencies to other services'''
|