Merge pull request #6324 from keszybz/generator-add-symlink

Add helper function for creation of unit symlinks in generators
This commit is contained in:
Lennart Poettering 2017-07-17 10:02:54 +02:00 committed by GitHub
commit 981778e212
8 changed files with 76 additions and 148 deletions

View file

@ -58,11 +58,11 @@ static int create_disk(
const char *password,
const char *options) {
_cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *to = NULL, *e = NULL,
_cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL,
*filtered = NULL;
_cleanup_fclose_ FILE *f = NULL;
const char *dmname;
bool noauto, nofail, tmp, swap;
char *from;
int r;
assert(name);
@ -121,7 +121,7 @@ static int create_disk(
if (password) {
if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random"))
fputs("After=systemd-random-seed.service\n", f);
else if (!streq(password, "-") && !streq(password, "none")) {
else if (!STR_IN_SET(password, "-", "none")) {
_cleanup_free_ char *uu;
uu = fstab_node_to_udev_node(password);
@ -187,46 +187,23 @@ static int create_disk(
if (r < 0)
return log_error_errno(r, "Failed to write file %s: %m", p);
from = strjoina("../", n);
if (!noauto) {
r = generator_add_symlink(arg_dest, d, "wants", n);
if (r < 0)
return r;
to = strjoin(arg_dest, "/", d, ".wants/", n);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
free(to);
if (!nofail)
to = strjoin(arg_dest, "/cryptsetup.target.requires/", n);
else
to = strjoin(arg_dest, "/cryptsetup.target.wants/", n);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
r = generator_add_symlink(arg_dest, "cryptsetup.target",
nofail ? "wants" : "requires", n);
if (r < 0)
return r;
}
free(to);
to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
dmname = strjoina("dev-mapper-", e, ".device");
r = generator_add_symlink(arg_dest, dmname, "requires", n);
if (r < 0)
return r;
if (!noauto && !nofail) {
_cleanup_free_ char *dmname;
dmname = strjoin("dev-mapper-", e, ".device");
if (!dmname)
return log_oom();
r = write_drop_in(arg_dest, dmname, 90, "device-timeout",
"# Automatically generated by systemd-cryptsetup-generator \n\n"
"[Unit]\nJobTimeoutSec=0");

View file

@ -92,7 +92,7 @@ static int add_swap(
bool noauto,
bool nofail) {
_cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
_cleanup_free_ char *name = NULL, *unit = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -149,14 +149,10 @@ static int add_swap(
return r;
if (!noauto) {
lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET,
nofail ? ".wants/" : ".requires/", name, NULL);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(unit, lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
nofail ? "wants" : "requires", name);
if (r < 0)
return r;
}
return 0;
@ -302,7 +298,7 @@ static int add_mount(
const char *source) {
_cleanup_free_ char
*name = NULL, *unit = NULL, *lnk = NULL,
*name = NULL, *unit = NULL,
*automount_name = NULL, *automount_unit = NULL,
*filtered = NULL;
_cleanup_fclose_ FILE *f = NULL;
@ -431,13 +427,10 @@ static int add_mount(
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
if (!noauto && !automount) {
lnk = strjoin(dest, "/", post, nofail ? ".wants/" : ".requires/", name);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(unit, lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
r = generator_add_symlink(dest, post,
nofail ? "wants" : "requires", name);
if (r < 0)
return r;
}
if (automount) {
@ -492,14 +485,10 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
free(lnk);
lnk = strjoin(dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(automount_unit, lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
r = generator_add_symlink(dest, post,
nofail ? "wants" : "requires", automount_name);
if (r < 0)
return r;
}
return 0;

View file

@ -58,7 +58,7 @@ static bool arg_root_rw = false;
static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
_cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
_cleanup_fclose_ FILE *f = NULL;
char *from, *ret;
char *ret;
int r;
assert(id);
@ -109,35 +109,21 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
if (r < 0)
return log_error_errno(r, "Failed to write file %s: %m", p);
from = strjoina("../", n);
to = strjoin(arg_dest, "/", d, ".wants/", n);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
r = generator_add_symlink(arg_dest, d, "wants", n);
if (r < 0)
return r;
if (require) {
free(to);
const char *dmname;
to = strjoin(arg_dest, "/cryptsetup.target.requires/", n);
if (!to)
return log_oom();
r = generator_add_symlink(arg_dest, "cryptsetup.target", "requires", n);
if (r < 0)
return r;
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
free(to);
to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
dmname = strjoina("dev-mapper-", e, ".device");
r = generator_add_symlink(arg_dest, dmname, "requires", n);
if (r < 0)
return r;
}
free(p);
@ -173,7 +159,7 @@ static int add_mount(
const char *description,
const char *post) {
_cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
_cleanup_free_ char *unit = NULL, *crypto_what = NULL, *p = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -239,16 +225,8 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", p);
if (post) {
lnk = strjoin(arg_dest, "/", post, ".requires/", unit);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(p, lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
}
if (post)
return generator_add_symlink(arg_dest, post, "requires", unit);
return 0;
}
@ -299,7 +277,7 @@ static int add_partition_mount(
}
static int add_swap(const char *path) {
_cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
_cleanup_free_ char *name = NULL, *unit = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -341,15 +319,7 @@ static int add_swap(const char *path) {
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(unit, lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
return 0;
return generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET, "wants", name);
}
#ifdef ENABLE_EFI
@ -363,7 +333,7 @@ static int add_automount(
const char *description,
usec_t timeout) {
_cleanup_free_ char *unit = NULL, *lnk = NULL;
_cleanup_free_ char *unit = NULL;
_cleanup_free_ char *opt, *p = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -418,15 +388,7 @@ static int add_automount(
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", p);
lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(p, lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
return 0;
return generator_add_symlink(arg_dest, SPECIAL_LOCAL_FS_TARGET, "wants", unit);
}
static int add_esp(DissectedPartition *p) {

View file

@ -37,6 +37,22 @@
#include "unit-name.h"
#include "util.h"
int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src) {
/* Adds a symlink from <dst>.<dep_type>.d/ to ../<src> */
const char *from, *to;
from = strjoina("../", src);
to = strjoina(root, "/", dst, ".", dep_type, "/", src);
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
if (errno != EEXIST)
return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to);
return 0;
}
static int write_fsck_sysroot_service(const char *dir, const char *what) {
_cleanup_free_ char *device = NULL, *escaped = NULL;
_cleanup_fclose_ FILE *f = NULL;

View file

@ -21,6 +21,8 @@
#include <stdio.h>
int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src);
int generator_write_fsck_deps(
FILE *f,
const char *dir,

View file

@ -28,6 +28,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
#include "generator.h"
#include "hashmap.h"
#include "hexdecoct.h"
#include "install.h"
@ -101,29 +102,6 @@ static void free_sysvstub_hashmapp(Hashmap **h) {
hashmap_free(*h);
}
static int add_symlink(const char *service, const char *where) {
const char *from, *to;
int r;
assert(service);
assert(where);
from = strjoina(arg_dest, "/", service);
to = strjoina(arg_dest, "/", where, ".wants/", service);
mkdir_parents_label(to, 0755);
r = symlink(from, to);
if (r < 0) {
if (errno == EEXIST)
return 0;
return -errno;
}
return 1;
}
static int add_alias(const char *service, const char *alias) {
const char *link;
int r;
@ -219,11 +197,8 @@ static int generate_unit_file(SysvStub *s) {
if (r < 0)
return log_error_errno(r, "Failed to write unit %s: %m", unit);
STRV_FOREACH(p, s->wanted_by) {
r = add_symlink(s->name, *p);
if (r < 0)
log_warning_errno(r, "Failed to create 'Wants' symlink to %s, ignoring: %m", *p);
}
STRV_FOREACH(p, s->wanted_by)
(void) generator_add_symlink(arg_dest, *p, "wants", s->name);
return 1;
}

View file

@ -165,3 +165,9 @@ if install_tests
install_dir : testsdir + '/testdata/' + subdir)
endforeach
endif
############################################################
sysv_generator_test_py = find_program('sysv-generator-test.py')
test('sysv-generator-test',
sysv_generator_test_py)

View file

@ -153,7 +153,8 @@ class SysvGeneratorTest(unittest.TestCase):
link = os.path.join(self.out_dir, '%s.target.wants' % target, unit)
if target in targets:
unit_file = os.readlink(link)
self.assertTrue(os.path.exists(unit_file))
# os.path.exists() will fail on a dangling symlink
self.assertTrue(os.path.exists(link))
self.assertEqual(os.path.basename(unit_file), unit)
else:
self.assertFalse(os.path.exists(link),