1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-27 10:25:06 +03:00

gpt-auto-generator: properly handle LUKS partitions

This commit is contained in:
Lennart Poettering 2014-03-06 04:05:13 +01:00
parent 58d081428a
commit 1af7211984

View File

@ -30,18 +30,19 @@
#include <linux/btrfs.h> #include <linux/btrfs.h>
#endif #endif
#include "sd-id128.h"
#include "libudev.h"
#include "path-util.h" #include "path-util.h"
#include "util.h" #include "util.h"
#include "mkdir.h" #include "mkdir.h"
#include "missing.h" #include "missing.h"
#include "sd-id128.h"
#include "libudev.h"
#include "udev-util.h" #include "udev-util.h"
#include "special.h" #include "special.h"
#include "unit-name.h" #include "unit-name.h"
#include "virt.h" #include "virt.h"
#include "generator.h" #include "generator.h"
#include "gpt.h" #include "gpt.h"
#include "fileio.h"
static const char *arg_dest = "/tmp"; static const char *arg_dest = "/tmp";
@ -166,11 +167,134 @@ static int add_swap(const char *path, const char *fstype) {
return 0; return 0;
} }
static int add_mount(const char *what, const char *where, const char *fstype, const char *description) { static int add_cryptsetup(const char *id, const char *what, char **device) {
_cleanup_free_ char *unit = NULL, *lnk = NULL, *p = NULL; _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
_cleanup_fclose_ FILE *f = NULL;
char *from, *ret;
int r;
assert(id);
assert(what);
assert(device);
d = unit_name_from_path(what, ".device");
if (!d)
return log_oom();
e = unit_name_escape(id);
if (!e)
return log_oom();
n = unit_name_build("systemd-cryptsetup", e, ".service");
if (!n)
return log_oom();
p = strjoin(arg_dest, "/", n, NULL);
if (!n)
return log_oom();
f = fopen(p, "wxe");
if (!f) {
log_error("Failed to create unit file %s: %m", p);
return -errno;
}
fprintf(f,
"# Automatically generated by systemd-gpt-auto-generator\n\n"
"[Unit]\n"
"Description=Cryptography Setup for %%I\n"
"Documentation=man:systemd-cryptsetup@.service(8)\n"
"DefaultDependencies=no\n"
"Conflicts=umount.target\n"
"BindsTo=dev-mapper-%%i.device %s\n"
"Before=umount.target cryptsetup.target\n"
"After=%s\n"
"IgnoreOnIsolate=true\n"
"After=systemd-readahead-collect.service systemd-readahead-replay.service\n\n"
"[Service]\n"
"Type=oneshot\n"
"RemainAfterExit=yes\n"
"TimeoutSec=0\n" /* the binary handles timeouts anyway */
"ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s'\n"
"ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
d, d,
id, what,
id);
fflush(f);
if (ferror(f)) {
log_error("Failed to write file %s: %m", p);
return -errno;
}
from = strappenda("../", n);
to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0) {
log_error("Failed to create symlink %s: %m", to);
return -errno;
}
free(to);
to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0) {
log_error("Failed to create symlink %s: %m", to);
return -errno;
}
free(to);
to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
if (!to)
return log_oom();
mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0) {
log_error("Failed to create symlink %s: %m", to);
return -errno;
}
free(p);
p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
if (!p)
return log_oom();
mkdir_parents_label(p, 0755);
r = write_string_file(p,
"# Automatically generated by systemd-gpt-auto-generator\n\n"
"[Unit]\n"
"JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
if (r < 0) {
log_error("Failed to write device drop-in: %s", strerror(-r));
return r;
}
ret = strappend("/dev/mapper/", id);
if (!ret)
return log_oom();
*device = ret;
return 0;
}
static int add_mount(const char *id, const char *what, const char *where, const char *fstype, const char *description) {
_cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
int r; int r;
assert(id);
assert(what);
assert(where);
assert(fstype);
assert(description);
if (dir_is_empty(where) <= 0) { if (dir_is_empty(where) <= 0) {
log_debug("%s already populated, ignoring.", where); log_debug("%s already populated, ignoring.", where);
return 0; return 0;
@ -178,6 +302,16 @@ static int add_mount(const char *what, const char *where, const char *fstype, co
log_debug("Adding %s: %s %s", where, what, fstype); log_debug("Adding %s: %s %s", where, what, fstype);
if (streq(fstype, "crypto_LUKS")) {
r = add_cryptsetup(id, what, &crypto_what);
if (r < 0)
return r;
what = crypto_what;
fstype = NULL;
}
unit = unit_name_from_path(where, ".mount"); unit = unit_name_from_path(where, ".mount");
if (!unit) if (!unit)
return log_oom(); return log_oom();
@ -206,9 +340,14 @@ static int add_mount(const char *what, const char *where, const char *fstype, co
"\n" "\n"
"[Mount]\n" "[Mount]\n"
"What=%s\n" "What=%s\n"
"Where=%s\n" "Where=%s\n",
"Type=%s\n", what, where);
what, where, fstype);
if (fstype) {
fprintf(f,
"Type=%s\n",
fstype);
}
fflush(f); fflush(f);
if (ferror(f)) { if (ferror(f)) {
@ -337,10 +476,10 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) {
} }
if (home && home_fstype) if (home && home_fstype)
add_mount(home, "/home", home_fstype, "Home Partition"); add_mount("home", home, "/home", home_fstype, "Home Partition");
if (srv && srv_fstype) if (srv && srv_fstype)
add_mount(srv, "/srv", srv_fstype, "Server Data Partition"); add_mount("srv", srv, "/srv", srv_fstype, "Server Data Partition");
return r; return r;
} }