[systemd-commits] 2 commits - src/shared src/systemctl

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Wed Apr 16 20:13:13 PDT 2014


 src/shared/install.c      |    4 +++-
 src/systemctl/systemctl.c |    4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

New commits:
commit af7fce1cdb6c0d6ce56bcddccbc31dd3d64a8cd8
Author: Djalal Harouni <tixxdz at opendz.org>
Date:   Thu Apr 17 01:47:11 2014 +0100

    install: create_symlink() check unlink() return value
    
    create_symlink() do not check the return value of unlink(), this may
    confuse the user.
    
    Before the unlink() call we check the 'force' argument. If it is not set
    we fail with -EEXIST, otherwise we unlink() the file, therefore the next
    symlink() should not fail with -EEXIST (do not count races...).
    
    However since callers may not have appropriate privileges to unlink()
    the file we lose the -EPERM or any other errno code of unlink(), and
    return the -EEXIST of the next symlink(). Fix this by checking unlink()
    results.
    
    Before:
    $ systemctl --force --root=~/container-03 set-default multi-user.target
    Failed to set default target: File exists
    
    After:
    $ systemctl --force --root=~/container-03 set-default multi-user.target
    Failed to set default target: Permission denied

diff --git a/src/shared/install.c b/src/shared/install.c
index 7409046..6334833 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1170,7 +1170,9 @@ static int create_symlink(
         if (!force)
                 return -EEXIST;
 
-        unlink(new_path);
+        r = unlink(new_path);
+        if (r < 0 && errno != ENOENT)
+                return -errno;
 
         if (symlink(old_path, new_path) >= 0) {
                 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);

commit a1484a216e79da1fa7e2323095fb1b7203fb7a17
Author: Djalal Harouni <tixxdz at opendz.org>
Date:   Mon Apr 14 01:07:52 2014 +0100

    systemctl: allow to change the default target without the --force switch
    
    Currently "systemctl set-default" will fail to change the default target
    due to the 'default.target' being a symlink which is always the case.
    
    To work around this, the user must specify the "--force" switch to be
    able to overwrite the existing symlink.
    
    This is clearly a regression that was introduced by commit  718db96199e
    since it worked before without the "--force" switch and the man pages do
    not mention that you need to specify it. It is expected that this is a
    symlink.
    
    So just explicity set the force flag to make it work again.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=76623
    
    Reported-by: <code at progandy.de>

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index ee0938f..1b381f7 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1968,7 +1968,7 @@ static int set_default(sd_bus *bus, char **args) {
                 return log_oom();
 
         if (!bus || avoid_bus()) {
-                r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
+                r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
                 if (r < 0) {
                         log_error("Failed to set default target: %s", strerror(-r));
                         return r;
@@ -1990,7 +1990,7 @@ static int set_default(sd_bus *bus, char **args) {
                                 "SetDefaultTarget",
                                 &error,
                                 &reply,
-                                "sb", unit, arg_force);
+                                "sb", unit, true);
                 if (r < 0) {
                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
                         return r;



More information about the systemd-commits mailing list