Hello all,

a little while ago, Jon Severinsson wrote a sysv generator
optimization to not go through all the parsing of init.d scripts and
creation of units if there already is a native unit for that name. As
they are put into generator.late they would be ignored anyway.

This is particularly relevant if you have lots of init.d scripts, like
we have on Debian. Other than that it's not a behaviour change AFAICS.

I cleaned it up a bit and added a test case.

One thing I wonder about is whether native_unit_exists() should
perhaps be moved into src/shared/? It might be useful for other stuff.

Thanks,

Martin
-- 
Martin Pitt                        | http://www.piware.de
Ubuntu Developer (www.ubuntu.com)  | Debian Developer  (www.debian.org)
From ae066ed5d5b7312eb8debc30970f6e56919fa7c7 Mon Sep 17 00:00:00 2001
From: Jon Severinsson <j...@severinsson.net>
Date: Wed, 2 Jul 2014 22:00:00 +0200
Subject: [PATCH] sysv-generator: Skip init scripts for existing native
 services

There's no need to do all the parsing and creation of service files if we
already have a native systemd unit for the processed SysV init script.
---
 src/sysv-generator/sysv-generator.c | 30 +++++++++++++++++++++++++++++-
 test/sysv-generator-test.py         | 12 ++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 673f04d..3052326 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -723,6 +723,25 @@ static int fix_order(SysvStub *s, Hashmap *all_services) {
         return 0;
 }
 
+static int native_unit_exists(LookupPaths lp, char *name) {
+        char **p;
+
+        STRV_FOREACH(p, lp.unit_path) {
+                struct stat st;
+                _cleanup_free_ char *path = NULL;
+
+                path = strjoin(*p, "/", name, NULL);
+                if (!path)
+                        return -ENOMEM;
+
+                if (lstat(path, &st) < 0)
+                        continue;
+
+                return 1;
+        }
+        return 0;
+}
+
 static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
         char **path;
 
@@ -768,6 +787,14 @@ static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
                         if (!fpath)
                                 return log_oom();
 
+                        r = native_unit_exists(lp, name);
+                        if (r < 0)
+                                return log_oom();
+                        if (r > 0) {
+                                log_debug("Native unit for %s already exists, skipping", *path);
+                                continue;
+                        }
+
                         service = new0(SysvStub, 1);
                         if (!service)
                                 return log_oom();
@@ -852,7 +879,8 @@ static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) {
 
                                 service = hashmap_get(all_services, name);
                                 if (!service){
-                                        log_warning("Could not find init script for %s", name);
+                                        log_debug("Ignoring %s symlink in %s, not generating %s.",
+                                                  de->d_name, rcnd_table[i].path, name);
                                         continue;
                                 }
 
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
index 5098519..89df72a 100644
--- a/test/sysv-generator-test.py
+++ b/test/sysv-generator-test.py
@@ -367,6 +367,18 @@ class SysvGeneratorTest(unittest.TestCase):
         self.assert_enabled('foo.bak.service', [])
         self.assert_enabled('foo.old.service', [])
 
+    def test_existing_native_unit(self):
+        '''existing native unit'''
+
+        with open(os.path.join(self.unit_dir, 'foo.service'), 'w') as f:
+            f.write('[Unit]\n')
+
+        self.add_sysv('foo.sh', {'Provides': 'foo bar'}, enable=True)
+        err, results = self.run_generator()
+        self.assertEqual(list(results), [])
+        # no enablement or alias links
+        self.assertEqual(os.listdir(self.out_dir), [])
+
 
 if __name__ == '__main__':
     unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
-- 
2.1.4

Attachment: signature.asc
Description: Digital signature

_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to