systemctl enable on linked service: 'Failed to execute operation: Too many levels of symbolic links' #3010

Closed
vladimirze opened this Issue Apr 11, 2016 · 23 comments

Comments

@vladimirze

Submission type

  • Bug report
  • Request for enhancement (RFE)

NOTE: Do not submit anything other than bug reports or RFEs via the issue tracker!

systemd version the issue has been seen with

229
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN

NOTE: Do not submit bug reports about anything but the two most recently released systemd versions upstream!

Used distribution

Ubuntu 16.04, 4.4.0-15-generic

In case of bug report: Expected behaviour you didn't see

After linking service via systemctl link from /home/developer directory and enabling it via systemctl enable I was expecting that the service should start on boot.

In case of bug report: Unexpected behaviour you saw

Enabling linked service causes to: 'Failed to execute operation: Too many levels of symbolic links'

In case of bug report: Steps to reproduce the problem

cat.service
[Unit]
Description=Service for populating desktop with cats.

[Service]
ExecStart=/bin/cat

[Install]
WantedBy=multi-user.target
$ sudo systemctl link /home/developer/cat.service
Created symlink from /etc/systemd/system/cat.service to /home/developer/cat.service.
$ sudo systemctl status cat.service
● cat.service - Service for populating desktop with cats.
   Loaded: loaded (/home/developer/cat.service; linked
   Active: inactive (dead)
$ sudo systemctl start cat.service
$ sudo systemctl is-enabled cat.service
linked
$ sudo systemctl enable cat.service
Failed to execute operation: Too many levels of symbolic links
$ ls -l /etc/systemd/system | grep -i 'cat'
lrwxrwxrwx 1 root root   53 Apr 11 07:44 cat.service -> /home/developer/cat.service
$ ls -l /etc/systemd/system/multi-user.target.wants/ | grep -i 'cat'
(empty)

Looks like systemctl link places symlink in /etc/systemd/system, however if I place cat.service into /lib/systemd/system and then systemctl enable it, symlink will be created in /etc/systemd/system/multi-user.target.wants/.

@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

Related to this: If you directly enable a unit file with full path, it actually creates the symlinks, but then spits out a wrong error message:

# systemctl enable /tmp/foo.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/foo.service to /tmp/foo.service.
Created symlink from /etc/systemd/system/foo.service to /tmp/foo.service.
The unit files have no [Install] section. They are not meant to be enabled
using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
Contributor

martinpitt commented Apr 11, 2016

Related to this: If you directly enable a unit file with full path, it actually creates the symlinks, but then spits out a wrong error message:

# systemctl enable /tmp/foo.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/foo.service to /tmp/foo.service.
Created symlink from /etc/systemd/system/foo.service to /tmp/foo.service.
The unit files have no [Install] section. They are not meant to be enabled
using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

I tried with @poettering 's large patch in PR #2973; it largely behaves the same way with systemctl enable /tmp/foo.service, and it's even worse when using --global:

# systemctl --global enable /tmp/foo.service 
Assertion 'a' failed at src/basic/path-util.c:389, function path_compare(). Aborting.
Aborted (core dumped)

(I'm using --global as that makes it much easier to test modified systemctls without having to patch/install/reexec pid 1)

Contributor

martinpitt commented Apr 11, 2016

I tried with @poettering 's large patch in PR #2973; it largely behaves the same way with systemctl enable /tmp/foo.service, and it's even worse when using --global:

# systemctl --global enable /tmp/foo.service 
Assertion 'a' failed at src/basic/path-util.c:389, function path_compare(). Aborting.
Aborted (core dumped)

(I'm using --global as that makes it much easier to test modified systemctls without having to patch/install/reexec pid 1)

@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

I created https://gist.github.com/martinpitt/d65cf665066056cbf5ba366338b03f23 as a test case to reproduce this.

Contributor

martinpitt commented Apr 11, 2016

I created https://gist.github.com/martinpitt/d65cf665066056cbf5ba366338b03f23 as a test case to reproduce this.

@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

The "too many levels of symbolic links" error in the original report just seems to be a missing flag:

--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1811,7 +1811,7 @@ int unit_file_enable(
                 return r;

         STRV_FOREACH(f, files) {
-                r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_LOAD, &i);
+                r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
                 if (r < 0)
                         return r;
                 if (i->type == UNIT_FILE_TYPE_MASKED)

With that, systemctl enable on a symlinked unit now actually creates the correct symlinks, but later fails with the "The unit files have no [Install] section" bogus error like in my first comment. I. e. this is now exactly equivalent to not doing systemctl link first and doing systemctl enable /some/path/myunit.service directly.

I'm trying to understand the expectations of the code in src/shared/install.c: I think install_info_symlink_wants() is supposed to return the number of units it actually enabled, i. e. 1 if we created one enablement symlink. But it currently returns 0 even after success, which causes the "0" return to propagate back through install_info_apply()install_context_apply()unit_file_enable(), and in the latter carries_install_info == 0 and thus systemctl enable prints that error message. On the other end, create_symlink() always just returns 0 on success (or negative on error), while it seems to me that all callers of create_symlink() expect that to return > 0 if it actually did something.

So apparently, fixing create_symlink() to return 1 if it did something, and continue to return 0 if the link already exists (with the same target) seems to fix it:

 --- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -294,7 +294,7 @@ static int create_symlink(

         if (symlink(old_path, new_path) >= 0) {
                 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
-                return 0;
+                return 1;
         }

         if (errno != EEXIST)
@@ -317,7 +317,7 @@ static int create_symlink(
         unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
         unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);

-        return 0;
+        return 1;
 }

 static int mark_symlink_for_removal(

Am I on the right track here?

Contributor

martinpitt commented Apr 11, 2016

The "too many levels of symbolic links" error in the original report just seems to be a missing flag:

--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1811,7 +1811,7 @@ int unit_file_enable(
                 return r;

         STRV_FOREACH(f, files) {
-                r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_LOAD, &i);
+                r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
                 if (r < 0)
                         return r;
                 if (i->type == UNIT_FILE_TYPE_MASKED)

With that, systemctl enable on a symlinked unit now actually creates the correct symlinks, but later fails with the "The unit files have no [Install] section" bogus error like in my first comment. I. e. this is now exactly equivalent to not doing systemctl link first and doing systemctl enable /some/path/myunit.service directly.

I'm trying to understand the expectations of the code in src/shared/install.c: I think install_info_symlink_wants() is supposed to return the number of units it actually enabled, i. e. 1 if we created one enablement symlink. But it currently returns 0 even after success, which causes the "0" return to propagate back through install_info_apply()install_context_apply()unit_file_enable(), and in the latter carries_install_info == 0 and thus systemctl enable prints that error message. On the other end, create_symlink() always just returns 0 on success (or negative on error), while it seems to me that all callers of create_symlink() expect that to return > 0 if it actually did something.

So apparently, fixing create_symlink() to return 1 if it did something, and continue to return 0 if the link already exists (with the same target) seems to fix it:

 --- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -294,7 +294,7 @@ static int create_symlink(

         if (symlink(old_path, new_path) >= 0) {
                 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
-                return 0;
+                return 1;
         }

         if (errno != EEXIST)
@@ -317,7 +317,7 @@ static int create_symlink(
         unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
         unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);

-        return 0;
+        return 1;
 }

 static int mark_symlink_for_removal(

Am I on the right track here?

@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

I refined the "unit-config" tests to test "link+disable" and "link+enable+disable" separately: https://gist.github.com/martinpitt/dfb97e938f45ce1d079193cd414fb97b.

With the above two changes everything passes now. This breaks one test in ./test-install-root, so I'll look into that and propose a pull request for discussing this further, which is easier with by-line comments.

Contributor

martinpitt commented Apr 11, 2016

I refined the "unit-config" tests to test "link+disable" and "link+enable+disable" separately: https://gist.github.com/martinpitt/dfb97e938f45ce1d079193cd414fb97b.

With the above two changes everything passes now. This breaks one test in ./test-install-root, so I'll look into that and propose a pull request for discussing this further, which is easier with by-line comments.

@martinpitt martinpitt self-assigned this Apr 11, 2016

@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

That test-install-root test case is covering exactly this issue:

         * c) a unit file in /opt, that is linked into
         * /etc/systemd/system, and where "enable" should result in
         * -ELOOP, since using information from /etc to generate
         * information in /etc should not be allowed.

I think this is a typo and was meaning to say "using information from /opt to generate information in /etc", and it does

       assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked3.service"), false, &changes, &n_changes) == -ELOOP);

where /etc/systemd/system/linked3.service → /opt/linked3.service.

So it seems that this is intentionally forbidden (even though the error message there is terrible). If we don't want to support unit symlinks from /etc/ to somewhere else (/opt in test-install-root, /tmp/ in my unit-config test, or /var/ in the bug report that I got), why do we offer systemctl link in the first place?

Depending on the answer, I'll either adjust the test case or add a comprehensible error message. Thanks!

Contributor

martinpitt commented Apr 11, 2016

That test-install-root test case is covering exactly this issue:

         * c) a unit file in /opt, that is linked into
         * /etc/systemd/system, and where "enable" should result in
         * -ELOOP, since using information from /etc to generate
         * information in /etc should not be allowed.

I think this is a typo and was meaning to say "using information from /opt to generate information in /etc", and it does

       assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked3.service"), false, &changes, &n_changes) == -ELOOP);

where /etc/systemd/system/linked3.service → /opt/linked3.service.

So it seems that this is intentionally forbidden (even though the error message there is terrible). If we don't want to support unit symlinks from /etc/ to somewhere else (/opt in test-install-root, /tmp/ in my unit-config test, or /var/ in the bug report that I got), why do we offer systemctl link in the first place?

Depending on the answer, I'll either adjust the test case or add a comprehensible error message. Thanks!

@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

Discussed with @poettering:

  • systemctl enable foo.service should not be allowed if foo.service is a symlink in /etc/. This currently causes the "Too many levels of symbolic links" error message which ought to be improved.
  • systemctl enable or link on a full path should both be allowed.
Contributor

martinpitt commented Apr 11, 2016

Discussed with @poettering:

  • systemctl enable foo.service should not be allowed if foo.service is a symlink in /etc/. This currently causes the "Too many levels of symbolic links" error message which ought to be improved.
  • systemctl enable or link on a full path should both be allowed.

poettering added a commit to poettering/systemd that referenced this issue Apr 11, 2016

core: make sure we generate a nicer error when a linked unit is attem…
…pted to be enabled

We don't allow using config symlinks to enable units, but the error message we
printed was awful. Fix that, and generate a more readable error.

Fixes #3010.
@martinpitt

This comment has been minimized.

Show comment
Hide comment
@martinpitt

martinpitt Apr 11, 2016

Contributor

I fixed the bogus "No [Install] section" warning when enabling a unit with full path in PR #3016 (that also has a link to the now committed unit-test test case).

Let's keep this open for the part that systemctl enable foo.service prints out that bad "too many levels of symbolic links" error; @poettering wanted to fix that in his mega- PR #2973, to avoid touching the same code in two PRs.

Contributor

martinpitt commented Apr 11, 2016

I fixed the bogus "No [Install] section" warning when enabling a unit with full path in PR #3016 (that also has a link to the now committed unit-test test case).

Let's keep this open for the part that systemctl enable foo.service prints out that bad "too many levels of symbolic links" error; @poettering wanted to fix that in his mega- PR #2973, to avoid touching the same code in two PRs.

@markstos

This comment has been minimized.

Show comment
Hide comment
@markstos

markstos May 19, 2016

Contributor

I don't find the error message of "Refusing to operate on linked unit file." to be more more helpful. Symlinks are used in other parts of systemd, why can't I symlink a file into /etc/systemd/system?

The docs in man systemctl only mention that enable works with a name, not a full path. It's also not clear how to enable an instance of a Template Unit of a full path must be provided to sytemctl enable.

Here's my use-case:

  1. I want to manage my project in git repo and have a symlink from some systemd files there into /etc/systemd/system
  2. I expected to be able to do systemctl enable app@instance for the services that had symlinks in /etc/systemd/system

.

It looks the particular case I'm running into is the same as #661. From reading that, I gather that:

  • Support for what I want is desired, but not working currently
    • Lacking another workaround available currently, I should copy my Template Unit file into /etc/systemd/system so I can enable an instance of it.
Contributor

markstos commented May 19, 2016

I don't find the error message of "Refusing to operate on linked unit file." to be more more helpful. Symlinks are used in other parts of systemd, why can't I symlink a file into /etc/systemd/system?

The docs in man systemctl only mention that enable works with a name, not a full path. It's also not clear how to enable an instance of a Template Unit of a full path must be provided to sytemctl enable.

Here's my use-case:

  1. I want to manage my project in git repo and have a symlink from some systemd files there into /etc/systemd/system
  2. I expected to be able to do systemctl enable app@instance for the services that had symlinks in /etc/systemd/system

.

It looks the particular case I'm running into is the same as #661. From reading that, I gather that:

  • Support for what I want is desired, but not working currently
    • Lacking another workaround available currently, I should copy my Template Unit file into /etc/systemd/system so I can enable an instance of it.
@keszybz

This comment has been minimized.

Show comment
Hide comment
@keszybz

keszybz May 20, 2016

Member

It seems that the code added in 51755f2 got broken again:

sudo ./systemctl --root=/ enable cat
Failed to enable: Too many levels of symbolic links.

Damn.

But I think that the whole premise of refusing to operate on linked units is wrong. Since the symlink points outside of our unit directories, it's not configuration by itself, just a way to tell systemd about the unit file. If we allow "status", "start", "stop', etc, on a linked unit file, then we should also allow "enable", "disable", and "preset". Even worse, since we allow enable/disable/preset on the original file, we should also allow it on the symlink.

Member

keszybz commented May 20, 2016

It seems that the code added in 51755f2 got broken again:

sudo ./systemctl --root=/ enable cat
Failed to enable: Too many levels of symbolic links.

Damn.

But I think that the whole premise of refusing to operate on linked units is wrong. Since the symlink points outside of our unit directories, it's not configuration by itself, just a way to tell systemd about the unit file. If we allow "status", "start", "stop', etc, on a linked unit file, then we should also allow "enable", "disable", and "preset". Even worse, since we allow enable/disable/preset on the original file, we should also allow it on the symlink.

@keszybz keszybz reopened this May 20, 2016

@auspex

This comment has been minimized.

Show comment
Hide comment
@auspex

auspex Jul 9, 2016

I completely agree with the two previous comments. Everything in the man pages implies that I can do what @markstos says, and it's exactly what I've been trying to do. Disallowing enabling of symlinks seems arbitrary.

auspex commented Jul 9, 2016

I completely agree with the two previous comments. Everything in the man pages implies that I can do what @markstos says, and it's exactly what I've been trying to do. Disallowing enabling of symlinks seems arbitrary.

keszybz added a commit to keszybz/systemd that referenced this issue Jul 23, 2016

shared/install: add information about refusal to operate on linked fi…
…le to changes

If we don't put the error in the changes array, we get a generic error.
For example, when enabling linked files, "Too many levels of symbolic links".
To get the custom error message, we need to put the error and the path in
*changes.

Before:
Failed to execute operation: Too many levels of symbolic links
Now:
Failed to enable unit, refusing to operate on linked unit file /etc/systemd/system/cat.service

A nicer error message was introduced in 8e20adc, but this got broken
again in af3d811.

Makes #3010 a bit less problematic.

keszybz added a commit to keszybz/systemd that referenced this issue Jul 23, 2016

shared/install: allow "enable" on linked unit files
User expectations are broken when "systemctl enable /some/path/service.service"
behaves differently to "systemctl link ..." followed by "systemctl enable".
From user's POV, "enable" with the full path just combines the two steps into
one.

Fixes #3010.

keszybz added a commit to keszybz/systemd that referenced this issue Jul 24, 2016

shared/install: allow "enable" on linked unit files
User expectations are broken when "systemctl enable /some/path/service.service"
behaves differently to "systemctl link ..." followed by "systemctl enable".
From user's POV, "enable" with the full path just combines the two steps into
one.

Fixes #3010.

@poettering poettering closed this in #3790 Jul 25, 2016

poettering added a commit that referenced this issue Jul 25, 2016

shared/install: allow "enable" on linked unit files (#3790)
User expectations are broken when "systemctl enable /some/path/service.service"
behaves differently to "systemctl link ..." followed by "systemctl enable".
From user's POV, "enable" with the full path just combines the two steps into
one.

Fixes #3010.
@prographo

This comment has been minimized.

Show comment
Hide comment
@prographo

prographo Sep 21, 2016

One symbolic link is "too many levels of symbolic links" -- only developers.

One symbolic link is "too many levels of symbolic links" -- only developers.

@paoloantinori

This comment has been minimized.

Show comment
Hide comment
@paoloantinori

paoloantinori Dec 13, 2016

Hi, I was looking on the internet for some hint to solve an issue that reports the very same error message:

https://bugzilla.redhat.com/show_bug.cgi?id=1399991

Any chance the two are related?

Hi, I was looking on the internet for some hint to solve an issue that reports the very same error message:

https://bugzilla.redhat.com/show_bug.cgi?id=1399991

Any chance the two are related?

Niautanor added a commit to Niautanor/plounge-stats that referenced this issue Jan 11, 2017

made plounge-watcher installable
Installation (so that it automatically starts at boot) of the unit is
actually a bit difficult because systemctl refuses to work on
symlinked unit files (for whatever reason, there is a bit of
discussion about it
[here](systemd/systemd#3010)).

Instead of just symlinking the unit to /etc/systemd/system and then
running systemctl enable ./plounge-watcher.service from the git repo
@Celadora

This comment has been minimized.

Show comment
Hide comment
@Celadora

Celadora Jan 15, 2017

I was able to work around this by using "systemctl daemon-reload" after placing the symbolic link in /etc/systemd/system

The only problem is that when you disable the service (systemctl disable [service]) the symbolic link is removed.

Hope this helps!

I was able to work around this by using "systemctl daemon-reload" after placing the symbolic link in /etc/systemd/system

The only problem is that when you disable the service (systemctl disable [service]) the symbolic link is removed.

Hope this helps!

@dlford

This comment has been minimized.

Show comment
Hide comment
@dlford

dlford Feb 25, 2017

I was here earlier looking for answers and figured it out, thought I'd post here to help anyone else that ends up in my shoes, and although I may have missed it, I haven't seen it anywhere spelled out in simple terms.

systemd works fine with symlinks, I was just using it wrong, and that's the reason I was getting the "too many levels of symlinks" error.

This works:

systemctl enable /var/git/foo/foo.service
systemctl enable /var/git/foo/foo.timer
systemctl start foo.timer

The above example creates all the symlinks needed:

/etc/systemd/system/foo.service -> /var/git/foo/foo.service
/etc/systemd/system/foo.timer -> /var/git/foo/foo.timer
/etc/systemd/system/timers.target.wants/foo.timer -> /var/git/foo/foo.timer

Just remember that if you ever disable the service or timer, all relative symlinks are removed (as @Celadora mentioned above), so you will need to re-enable with the full path as you did in the example above.

If you create the symlinks in /etc/systemd/system manually as in the example below, and then try to enable the timer, systemd tries to make a symlink in /etc/systemd/system/timers.target.wants/ to the timer file in /etc/systemd/system, and fails becuase it's symlinking to a symlink.

This does not work:

ln -s /var/git/foo/foo.service /etc/systemd/system/
ln -s /var/git/foo/foo.timer /etc/systemd/system/
systemctl enable foo.timer

dlford commented Feb 25, 2017

I was here earlier looking for answers and figured it out, thought I'd post here to help anyone else that ends up in my shoes, and although I may have missed it, I haven't seen it anywhere spelled out in simple terms.

systemd works fine with symlinks, I was just using it wrong, and that's the reason I was getting the "too many levels of symlinks" error.

This works:

systemctl enable /var/git/foo/foo.service
systemctl enable /var/git/foo/foo.timer
systemctl start foo.timer

The above example creates all the symlinks needed:

/etc/systemd/system/foo.service -> /var/git/foo/foo.service
/etc/systemd/system/foo.timer -> /var/git/foo/foo.timer
/etc/systemd/system/timers.target.wants/foo.timer -> /var/git/foo/foo.timer

Just remember that if you ever disable the service or timer, all relative symlinks are removed (as @Celadora mentioned above), so you will need to re-enable with the full path as you did in the example above.

If you create the symlinks in /etc/systemd/system manually as in the example below, and then try to enable the timer, systemd tries to make a symlink in /etc/systemd/system/timers.target.wants/ to the timer file in /etc/systemd/system, and fails becuase it's symlinking to a symlink.

This does not work:

ln -s /var/git/foo/foo.service /etc/systemd/system/
ln -s /var/git/foo/foo.timer /etc/systemd/system/
systemctl enable foo.timer
@keszybz

This comment has been minimized.

Show comment
Hide comment
@keszybz

keszybz Feb 27, 2017

Member

https://bugzilla.redhat.com/show_bug.cgi?id=1399991
Any chance the two are related?

That's unrelated. Like @msekletar wrote, it's a known issue (though I cannot find an upstream bug report).

Member

keszybz commented Feb 27, 2017

https://bugzilla.redhat.com/show_bug.cgi?id=1399991
Any chance the two are related?

That's unrelated. Like @msekletar wrote, it's a known issue (though I cannot find an upstream bug report).

@bbkane

This comment has been minimized.

Show comment
Hide comment
@bbkane

bbkane Jan 4, 2018

I can't link / enable template services:

$ systemctl link /home/vagrant/Git/hello_timers/systemd/hello_timers@.service
Failed to execute operation: Unit name hello_timers@.service is missing the instance name.
$ systemctl enable /home/vagrant/Git/hello_timers/systemd/hello_timers@vagrant.service
Failed to execute operation: No such file or directory

Is this a bug? I want to use the @ parameter to inject the user for my services (since systemd --user is disabled in RHEL7 )

bbkane commented Jan 4, 2018

I can't link / enable template services:

$ systemctl link /home/vagrant/Git/hello_timers/systemd/hello_timers@.service
Failed to execute operation: Unit name hello_timers@.service is missing the instance name.
$ systemctl enable /home/vagrant/Git/hello_timers/systemd/hello_timers@vagrant.service
Failed to execute operation: No such file or directory

Is this a bug? I want to use the @ parameter to inject the user for my services (since systemd --user is disabled in RHEL7 )

@markstos

This comment has been minimized.

Show comment
Hide comment
@markstos

markstos Jan 4, 2018

Contributor

@bbkane this issue was about the error "Failed to execute operation: Too many levels of symbolic links", which is not what you are experiencing. According to your errors, you are trying to work with files that don't exist. Your support questions about systemd are better suited to the Unix & Linux StackExchange site. If you tag your question with [systemd], I follow that tag there. But you should check and provide evidence that the referenced files actually exist!

Contributor

markstos commented Jan 4, 2018

@bbkane this issue was about the error "Failed to execute operation: Too many levels of symbolic links", which is not what you are experiencing. According to your errors, you are trying to work with files that don't exist. Your support questions about systemd are better suited to the Unix & Linux StackExchange site. If you tag your question with [systemd], I follow that tag there. But you should check and provide evidence that the referenced files actually exist!

@bbkane

This comment has been minimized.

Show comment
Hide comment
@bbkane

bbkane Jan 4, 2018

@markstos This is a tangent- apologies for that. I posted here because the method used by @dlford here didn't work for template files. I'll create a minimal example, put it on StackExchange, and edit this post with the link. Thanks!

bbkane commented Jan 4, 2018

@markstos This is a tangent- apologies for that. I posted here because the method used by @dlford here didn't work for template files. I'll create a minimal example, put it on StackExchange, and edit this post with the link. Thanks!

@bbkane

This comment has been minimized.

Show comment
Hide comment
@bbkane

bbkane Jan 5, 2018

@markstos so I reproduced the issue, created a question and GitHub repo with code to do it, and, finally, right before posting it, found #661 which says it's fixed in systemd 231. Unfortunately, Centos7 is stuck on systemd 219... I'll just have to cp the files. Thanks for the help.

bbkane commented Jan 5, 2018

@markstos so I reproduced the issue, created a question and GitHub repo with code to do it, and, finally, right before posting it, found #661 which says it's fixed in systemd 231. Unfortunately, Centos7 is stuck on systemd 219... I'll just have to cp the files. Thanks for the help.

@systemd systemd deleted a comment from Keensyst Jan 5, 2018

@markstos

This comment has been minimized.

Show comment
Hide comment
@markstos

markstos Jan 5, 2018

Contributor
Contributor

markstos commented Jan 5, 2018

@bbkane

This comment has been minimized.

Show comment
Hide comment
@bbkane

bbkane Jan 5, 2018

cp the service@.service/timer files into /etc/systemd/system, then enabling them (as opposed to enabling them from my home directory), not systemd libraries or anything. Thanks for the help.

bbkane commented Jan 5, 2018

cp the service@.service/timer files into /etc/systemd/system, then enabling them (as opposed to enabling them from my home directory), not systemd libraries or anything. Thanks for the help.

@aktau

This comment has been minimized.

Show comment
Hide comment
@aktau

aktau Jun 24, 2018

Just in case anyone else reads @bbkane's comment that the bug with templated files is fixed since systemd 231. I'm on Debian Stretch with systemd 232 and it still seems to exist:

gluc-back@.timer is a templated file, which is supposed to be supplied with a username (like aktau) in my case.

Full path enabling doesn't work (because the template instance isn't a path).

# systemctl enable $HOME/homesrv/systemd/gluc-backup@aktau.timer
Failed to enable unit: File /home/aktau/homesrv/systemd/gluc-backup@aktau.timer: No such file or directory

Without the parameter "works", but of course doesn't provide anything that runs.

# systemctl enable $HOME/homesrv/systemd/gluc-backup@.timer
Created symlink /etc/systemd/system/gluc-backup@.timer → /home/aktau/homesrv/systemd/gluc-backup@.timer.
The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
   instance name specified.

Perhaps if I try a regular relative enable afterwards?

# systemctl enable gluc-backup@aktau.timer
Failed to enable unit: Refusing to operate on linked unit file gluc-backup@aktau.timer

No dice.

The only working alternative I've found is to cp the service@.service timer file into /etc/systemd/system as @bbkane says, even on the systemd version where this is supposed to work.

Can anyone tell me if I'm holding this patch wrong?

aktau commented Jun 24, 2018

Just in case anyone else reads @bbkane's comment that the bug with templated files is fixed since systemd 231. I'm on Debian Stretch with systemd 232 and it still seems to exist:

gluc-back@.timer is a templated file, which is supposed to be supplied with a username (like aktau) in my case.

Full path enabling doesn't work (because the template instance isn't a path).

# systemctl enable $HOME/homesrv/systemd/gluc-backup@aktau.timer
Failed to enable unit: File /home/aktau/homesrv/systemd/gluc-backup@aktau.timer: No such file or directory

Without the parameter "works", but of course doesn't provide anything that runs.

# systemctl enable $HOME/homesrv/systemd/gluc-backup@.timer
Created symlink /etc/systemd/system/gluc-backup@.timer → /home/aktau/homesrv/systemd/gluc-backup@.timer.
The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
   instance name specified.

Perhaps if I try a regular relative enable afterwards?

# systemctl enable gluc-backup@aktau.timer
Failed to enable unit: Refusing to operate on linked unit file gluc-backup@aktau.timer

No dice.

The only working alternative I've found is to cp the service@.service timer file into /etc/systemd/system as @bbkane says, even on the systemd version where this is supposed to work.

Can anyone tell me if I'm holding this patch wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment