core: support upgrading from DynamicUser=0 to DynamicUser=1 for unit directories (#7507)

This makes sure we migrate /var/lib/<foo> if it exists to
/var/lib/private/<foo> if DynamicUser=1 is set. This is useful to allow
turning on DynamicUser= on services that previously didn't use it, and
we can deal with this, and migrate the relevant directories as
necessary.

Note that "downgrading" from DynamicUser=1 backto DynamicUser=0 works
too. However in that case we simply continue to use
/var/lib/private/<foo>, which works because /var/lib/<foo> is a symlink
there after all.
This commit is contained in:
Lennart Poettering 2017-11-30 11:52:39 +01:00 committed by GitHub
parent 191e9ef87d
commit 949befd3f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 4 deletions

View File

@ -98,6 +98,7 @@
#include "signal-util.h"
#include "smack-util.h"
#include "special.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
@ -2077,10 +2078,24 @@ static int setup_exec_directory(
if (r < 0)
goto fail;
/* Finally, create the actual directory for the service */
r = mkdir_label(pp, context->directories[type].mode);
if (r < 0 && r != -EEXIST)
goto fail;
if (is_dir(p, false) > 0 &&
(laccess(pp, F_OK) < 0 && errno == ENOENT)) {
/* Hmm, the private directory doesn't exist yet, but the normal one exists? If so, move
* it over. Most likely the service has been upgraded from one that didn't use
* DynamicUser=1, to one that does. */
if (rename(p, pp) < 0) {
r = -errno;
goto fail;
}
} else {
/* Otherwise, create the actual directory for the service */
r = mkdir_label(pp, context->directories[type].mode);
if (r < 0 && r != -EEXIST)
goto fail;
}
parent = dirname_malloc(p);
if (!parent) {