Merge pull request #7237 from keszybz/growfs

Create and grow filesystems
This commit is contained in:
Lennart Poettering
2017-12-01 17:58:58 +01:00
committed by GitHub
34 changed files with 1339 additions and 341 deletions

View File

@@ -569,6 +569,13 @@ manpages = [
['systemd-machine-id-commit.service', '8', [], ''],
['systemd-machine-id-setup', '1', [], ''],
['systemd-machined.service', '8', ['systemd-machined'], 'ENABLE_MACHINED'],
['systemd-makefs@.service',
'8',
['systemd-growfs',
'systemd-growfs@.service',
'systemd-makefs',
'systemd-makeswap@.service'],
''],
['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
['systemd-mount', '1', ['systemd-umount'], ''],
['systemd-networkd-wait-online.service',

View File

@@ -0,0 +1,120 @@
<?xml version="1.0"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: LGPL-2.1+
This file is part of systemd.
Copyright 2017 Zbigniew Jędrzejewski-Szmek
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
<refentry id="systemd-makefs@.service">
<refentryinfo>
<title>systemd-makefs@.service</title>
<productname>systemd</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Zbigniew</firstname>
<surname>Jędrzejewski-Szmek</surname>
<email>zbyszek@in.waw.pl</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>systemd-makefs@.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-makefs@.service</refname>
<refname>systemd-makeswap@.service</refname>
<refname>systemd-growfs@.service</refname>
<refname>systemd-makefs</refname>
<refname>systemd-growfs</refname>
<refpurpose>Creating and growing file systems on demand</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>systemd-makefs@<replaceable>device</replaceable>.service</filename></para>
<para><filename>systemd-makeswap@<replaceable>device</replaceable>.service</filename></para>
<para><filename>systemd-growfs@<replaceable>mountpoint</replaceable>.service</filename></para>
<para><filename>/usr/lib/systemd/systemd-makefs</filename></para>
<para><filename>/usr/lib/systemd/systemd-growfs</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><filename>systemd-makefs@.service</filename>,
<filename>systemd-makeswap@.service</filename>, and
<filename>systemd-growfs@.service</filename> are used to implement the
<option>x-systemd.makefs</option> and <option>x-systemd.growfs</option> options
in <citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
see <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
They are instantiated for each device for which the file system or swap structure
needs to be initalized, and for each mount point where the file system needs to
be grown.</para>
<para>These services are started at boot, either right before or right after the
mount point or swap device are used.</para>
<para><filename>systemd-makefs</filename> knows very little about specific file
systems and swap devices, and after checking that the block device does not already
contain a file system or other content, it will execute binaries specific to
each filesystem type (<filename>/sbin/mkfs.*</filename>).</para>
<para><filename>systemd-growfs</filename> knows very little about specific file
systems and swap devices, and will instruct the kernel to grow the mounted
filesystem to full size of the underlying block device. Nevertheless, it needs
to know the
<citerefentry project='man-pages'><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
number specific to each file system, so only certain types are supported.
Currently:
<citerefentry project='man-pages'><refentrytitle>ext4</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
btrfs (see
<citerefentry project='man-pages'><refentrytitle>btrfs-man5</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
<!-- yes, that's what the man page is called. -->
and dm-crypt partitions (see
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>).
</para>
<para>If the creation of a file system or swap device fails, the mount point or
swap is failed too. If the growing of a file system fails, a warning is emitted.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.cramfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.ext4</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.fat</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.hfsplus</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.minix</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.ntfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkfs.xfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@@ -318,6 +318,44 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>x-systemd.makefs</option></term>
<listitem><para>The file system or swap structure will be intialized
on the device. If the device is not "empty", i.e. it contains any signature,
the operation will be skipped. It is hence expected that this option
remains set even after the device has been initalized.</para>
<para>Note that this option can only be used in
<filename>/etc/fstab</filename>, and will be ignored when part of the
<varname>Options=</varname> setting in a unit file.</para>
<para>See
<citerefentry><refentrytitle>systemd-makefs@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
<para><citerefentry project='man-pages'><refentrytitle>wipefs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
may be used to remove any signatures from a block device to force
<option>x-systemd.makefs</option> to reinitialize the device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>x-systemd.growfs</option></term>
<listitem><para>The file system will be grown to occupy the full block
device. If the file system is already at maximum size, no action will
be performed. It is hence expected that this option remains set even after
the file system has been grown. Only certain file system types are supported,
see
<citerefentry><refentrytitle>systemd-makefs@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for details.</para>
<para>Note that this option can only be used in
<filename>/etc/fstab</filename>, and will be ignored when part of the
<varname>Options=</varname> setting in a unit file.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>_netdev</option></term>

View File

@@ -182,6 +182,8 @@ conf.set_quoted('CATALOG_DATABASE', join_paths(catalog
conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
conf.set_quoted('SYSTEMD_BINARY_PATH', join_paths(rootlibexecdir, 'systemd'))
conf.set_quoted('SYSTEMD_FSCK_PATH', join_paths(rootlibexecdir, 'systemd-fsck'))
conf.set_quoted('SYSTEMD_MAKEFS_PATH', join_paths(rootlibexecdir, 'systemd-makefs'))
conf.set_quoted('SYSTEMD_GROWFS_PATH', join_paths(rootlibexecdir, 'systemd-growfs'))
conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-shutdown'))
conf.set_quoted('SYSTEMD_SLEEP_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-sleep'))
conf.set_quoted('SYSTEMCTL_BINARY_PATH', join_paths(rootbindir, 'systemctl'))
@@ -1936,6 +1938,23 @@ executable('systemd-fsck',
install : true,
install_dir : rootlibexecdir)
executable('systemd-growfs',
'src/partition/growfs.c',
include_directories : includes,
link_with : [libshared],
dependencies : [libcryptsetup],
install_rpath : rootlibexecdir,
install : true,
install_dir : rootlibexecdir)
executable('systemd-makefs',
'src/partition/makefs.c',
include_directories : includes,
link_with : [libshared],
install_rpath : rootlibexecdir,
install : true,
install_dir : rootlibexecdir)
executable('systemd-sleep',
'src/sleep/sleep.c',
include_directories : includes,

View File

@@ -42,6 +42,7 @@
#include "btrfs-util.h"
#include "chattr-util.h"
#include "copy.h"
#include "device-nodes.h"
#include "fd-util.h"
#include "fileio.h"
#include "io-util.h"
@@ -910,7 +911,8 @@ int btrfs_subvol_set_subtree_quota_limit(const char *path, uint64_t subvol_id, u
int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
struct btrfs_ioctl_vol_args args = {};
_cleanup_free_ char *p = NULL, *loop = NULL, *backing = NULL;
char p[SYS_BLOCK_PATH_MAX("/loop/backing_file")];
_cleanup_free_ char *backing = NULL;
_cleanup_close_ int loop_fd = -1, backing_fd = -1;
struct stat st;
dev_t dev = 0;
@@ -930,8 +932,7 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
if (r == 0)
return -ENODEV;
if (asprintf(&p, "/sys/dev/block/%u:%u/loop/backing_file", major(dev), minor(dev)) < 0)
return -ENOMEM;
xsprintf_sys_block_path(p, "/loop/backing_file", dev);
r = read_one_line_file(p, &backing);
if (r == -ENOENT)
return -ENODEV;
@@ -955,9 +956,8 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
if (grow_only && new_size < (uint64_t) st.st_size)
return -EINVAL;
if (asprintf(&loop, "/dev/block/%u:%u", major(dev), minor(dev)) < 0)
return -ENOMEM;
loop_fd = open(loop, O_RDWR|O_CLOEXEC|O_NOCTTY);
xsprintf_sys_block_path(p, NULL, dev);
loop_fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY);
if (loop_fd < 0)
return -errno;

27
src/basic/crypt-util.c Normal file
View File

@@ -0,0 +1,27 @@
/***
This file is part of systemd.
Copyright 2017 Zbigniew Jędrzejewski-Szmek
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#if HAVE_LIBCRYPTSETUP
#include "crypt-util.h"
#include "log.h"
void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
log_debug("%s", msg);
}
#endif

34
src/basic/crypt-util.h Normal file
View File

@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
Copyright 2017 Zbigniew Jędrzejewski-Szmek
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#if HAVE_LIBCRYPTSETUP
#include <libcryptsetup.h>
#include "macro.h"
/* libcryptsetup define for any LUKS version, compatible with libcryptsetup 1.x */
#ifndef CRYPT_LUKS
#define CRYPT_LUKS NULL
#endif
DEFINE_TRIVIAL_CLEANUP_FUNC(struct crypt_device *, crypt_free);
void cryptsetup_log_glue(int level, const char *msg, void *usrptr);
#endif

View File

@@ -23,5 +23,18 @@
#include <stddef.h>
#include <sys/types.h>
#include "macro.h"
#include "stdio-util.h"
int encode_devnode_name(const char *str, char *str_enc, size_t len);
int whitelisted_char_for_devnode(char c, const char *additional);
#define SYS_BLOCK_PATH_MAX(suffix) \
(strlen("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen_ptr(suffix))
#define xsprintf_sys_block_path(buf, suffix, devno) \
xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix))
#define DEV_NUM_PATH_MAX \
(strlen("/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t))
#define xsprintf_dev_num_path(buf, type, devno) \
xsprintf(buf, "/dev/%s/%u:%u", type, major(devno), minor(devno))

View File

@@ -661,10 +661,19 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
todo += m;
/* Just a single slash? Then we reached the end. */
if (isempty(first) || path_equal(first, "/"))
/* Empty? Then we reached the end. */
if (isempty(first))
break;
/* Just a single slash? Then we reached the end. */
if (path_equal(first, "/")) {
/* Preserve the trailing slash */
if (!strextend(&done, "/", NULL))
return -ENOMEM;
break;
}
/* Just a dot? Then let's eat this up. */
if (path_equal(first, "/."))
continue;
@@ -726,7 +735,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
if (fstat(child, &st) < 0)
return -errno;
if ((flags & CHASE_NO_AUTOFS) &&
fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
return -EREMOTE;
if (S_ISLNK(st.st_mode)) {

View File

@@ -61,6 +61,8 @@ basic_sources_plain = files('''
copy.h
cpu-set-util.c
cpu-set-util.h
crypt-util.c
crypt-util.h
def.h
device-nodes.c
device-nodes.h

View File

@@ -1271,4 +1271,8 @@ struct fib_rule_uid_range {
#define AF_VSOCK 40
#endif
#ifndef EXT4_IOC_RESIZE_FS
# define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
#endif
#include "missing_syscall.h"

View File

@@ -278,6 +278,7 @@ int path_is_mount_point(const char *t, const char *root, int flags) {
int r;
assert(t);
assert((flags & ~AT_SYMLINK_FOLLOW) == 0);
if (path_equal(t, "/"))
return 1;
@@ -302,7 +303,7 @@ int path_is_mount_point(const char *t, const char *root, int flags) {
if (fd < 0)
return -errno;
return fd_is_mount_point(fd, basename(t), flags);
return fd_is_mount_point(fd, last_path_component(t), flags);
}
int path_get_mnt_id(const char *path, int *ret) {

View File

@@ -703,6 +703,37 @@ char* dirname_malloc(const char *path) {
return dir2;
}
const char *last_path_component(const char *path) {
/* Finds the last component of the path, preserving the
* optional trailing slash that signifies a directory.
* a/b/c → c
* a/b/c/ → c/
* / → /
* // → /
* /foo/a → a
* /foo/a/ → a/
* This is different than basename, which returns "" when
* a trailing slash is present.
*/
unsigned l, k;
l = k = strlen(path);
if (l == 0) /* special case — an empty string */
return path;
while (k > 0 && path[k-1] == '/')
k--;
if (k == 0) /* the root directory */
return path + l - 1;
while (k > 0 && path[k-1] != '/')
k--;
return path + k;
}
bool filename_is_valid(const char *p) {
const char *e;

View File

@@ -130,6 +130,7 @@ char *prefix_root(const char *root, const char *path);
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg);
char* dirname_malloc(const char *path);
const char *last_path_component(const char *path);
bool filename_is_valid(const char *p) _pure_;
bool path_is_normalized(const char *p) _pure_;

View File

@@ -193,7 +193,7 @@ bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
return F_TYPE_EQUAL(s->f_type, magic_value);
}
int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
int fd_is_fs_type(int fd, statfs_f_type_t magic_value) {
struct statfs s;
if (fstatfs(fd, &s) < 0)
@@ -202,14 +202,14 @@ int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
return is_fs_type(&s, magic_value);
}
int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
int path_is_fs_type(const char *path, statfs_f_type_t magic_value) {
_cleanup_close_ int fd = -1;
fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
if (fd < 0)
return -errno;
return fd_check_fstype(fd, magic_value);
return fd_is_fs_type(fd, magic_value);
}
bool is_temporary_fs(const struct statfs *s) {

View File

@@ -57,8 +57,8 @@ int files_same(const char *filea, const char *fileb, int flags);
typedef typeof(((struct statfs*)NULL)->f_type) statfs_f_type_t;
bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_;
int fd_check_fstype(int fd, statfs_f_type_t magic_value);
int path_check_fstype(const char *path, statfs_f_type_t magic_value);
int fd_is_fs_type(int fd, statfs_f_type_t magic_value);
int path_is_fs_type(const char *path, statfs_f_type_t magic_value);
bool is_temporary_fs(const struct statfs *s) _pure_;
int fd_is_temporary_fs(int fd);

View File

@@ -39,6 +39,7 @@
#include "build.h"
#include "cgroup-util.h"
#include "def.h"
#include "device-nodes.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -118,63 +119,42 @@ int socket_from_display(const char *display, char **path) {
}
int block_get_whole_disk(dev_t d, dev_t *ret) {
char *p, *s;
char p[SYS_BLOCK_PATH_MAX("/partition")];
_cleanup_free_ char *s = NULL;
int r;
unsigned n, m;
assert(ret);
/* If it has a queue this is good enough for us */
if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
return -ENOMEM;
r = access(p, F_OK);
free(p);
if (r >= 0) {
xsprintf_sys_block_path(p, "/queue", d);
if (access(p, F_OK) >= 0) {
*ret = d;
return 0;
}
/* If it is a partition find the originating device */
if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
return -ENOMEM;
r = access(p, F_OK);
free(p);
if (r < 0)
xsprintf_sys_block_path(p, "/partition", d);
if (access(p, F_OK) < 0)
return -ENOENT;
/* Get parent dev_t */
if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
return -ENOMEM;
xsprintf_sys_block_path(p, "/../dev", d);
r = read_one_line_file(p, &s);
free(p);
if (r < 0)
return r;
r = sscanf(s, "%u:%u", &m, &n);
free(s);
if (r != 2)
return -EINVAL;
/* Only return this if it is really good enough for us. */
if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
return -ENOMEM;
xsprintf_sys_block_path(p, "/queue", makedev(m, n));
if (access(p, F_OK) < 0)
return -ENOENT;
r = access(p, F_OK);
free(p);
if (r >= 0) {
*ret = makedev(m, n);
return 0;
}
return -ENOENT;
*ret = makedev(m, n);
return 0;
}
bool kexec_loaded(void) {
@@ -749,7 +729,8 @@ int get_block_device(const char *path, dev_t *dev) {
int get_block_device_harder(const char *path, dev_t *dev) {
_cleanup_closedir_ DIR *d = NULL;
_cleanup_free_ char *p = NULL, *t = NULL;
_cleanup_free_ char *t = NULL;
char p[SYS_BLOCK_PATH_MAX("/slaves")];
struct dirent *de, *found = NULL;
const char *q;
unsigned maj, min;
@@ -767,9 +748,7 @@ int get_block_device_harder(const char *path, dev_t *dev) {
if (r <= 0)
return r;
if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
return -ENOMEM;
xsprintf_sys_block_path(p, "/slaves", dt);
d = opendir(p);
if (!d) {
if (errno == ENOENT)

View File

@@ -19,7 +19,6 @@
***/
#include <errno.h>
#include <libcryptsetup.h>
#include <mntent.h>
#include <string.h>
#include <sys/mman.h>
@@ -28,6 +27,7 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "crypt-util.h"
#include "device-util.h"
#include "escape.h"
#include "fileio.h"
@@ -39,11 +39,6 @@
#include "strv.h"
#include "util.h"
/* libcryptsetup define for any LUKS version, compatible with libcryptsetup 1.x */
#ifndef CRYPT_LUKS
#define CRYPT_LUKS NULL
#endif
/* internal helper */
#define ANY_LUKS "LUKS"
@@ -254,10 +249,6 @@ static int parse_options(const char *options) {
return 0;
}
static void log_glue(int level, const char *msg, void *usrptr) {
log_debug("%s", msg);
}
static int disk_major_minor(const char *path, char **ret) {
struct stat st;
@@ -604,7 +595,7 @@ static int help(void) {
}
int main(int argc, char *argv[]) {
struct crypt_device *cd = NULL;
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
int r = -EINVAL;
if (argc <= 1) {
@@ -666,7 +657,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
crypt_set_log_callback(cd, log_glue, NULL);
crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
status = crypt_status(cd, argv[2]);
if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
@@ -750,7 +741,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
crypt_set_log_callback(cd, log_glue, NULL);
crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
r = crypt_deactivate(cd, argv[2]);
if (r < 0) {
@@ -766,9 +757,6 @@ int main(int argc, char *argv[]) {
r = 0;
finish:
if (cd)
crypt_free(cd);
free(arg_cipher);
free(arg_hash);
free(arg_header);

View File

@@ -47,6 +47,14 @@
#include "virt.h"
#include "volatile-util.h"
typedef enum MountpointFlags {
NOAUTO = 1 << 0,
NOFAIL = 1 << 1,
AUTOMOUNT = 1 << 2,
MAKEFS = 1 << 3,
GROWFS = 1 << 4,
} MountpointFlags;
static const char *arg_dest = "/tmp";
static const char *arg_dest_late = "/tmp";
static bool arg_fstab_enabled = true;
@@ -91,8 +99,7 @@ static int write_what(FILE *f, const char *what) {
static int add_swap(
const char *what,
struct mntent *me,
bool noauto,
bool nofail) {
MountpointFlags flags) {
_cleanup_free_ char *name = NULL, *unit = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -150,9 +157,19 @@ static int add_swap(
if (r < 0)
return r;
if (!noauto) {
if (flags & MAKEFS) {
r = generator_hook_up_mkswap(arg_dest, what);
if (r < 0)
return r;
}
if (flags & GROWFS)
/* TODO: swap devices must be wiped and recreated */
log_warning("%s: growing swap devices is currently unsupported.", what);
if (!(flags & NOAUTO)) {
r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
nofail ? "wants" : "requires", name);
(flags & NOFAIL) ? "wants" : "requires", name);
if (r < 0)
return r;
}
@@ -297,17 +314,16 @@ static int add_mount(
const char *fstype,
const char *opts,
int passno,
bool noauto,
bool nofail,
bool automount,
MountpointFlags flags,
const char *post,
const char *source) {
_cleanup_free_ char
*name = NULL, *unit = NULL,
*name = NULL,
*automount_name = NULL, *automount_unit = NULL,
*filtered = NULL,
*where_escaped = NULL;
const char *unit;
_cleanup_fclose_ FILE *f = NULL;
int r;
@@ -330,23 +346,21 @@ static int add_mount(
return 0;
if (path_equal(where, "/")) {
if (noauto)
if (flags & NOAUTO)
log_warning("Ignoring \"noauto\" for root device");
if (nofail)
if (flags & NOFAIL)
log_warning("Ignoring \"nofail\" for root device");
if (automount)
if (flags & AUTOMOUNT)
log_warning("Ignoring automount option for root device");
noauto = nofail = automount = false;
SET_FLAG(flags, NOAUTO | NOFAIL | AUTOMOUNT, false);
}
r = unit_name_from_path(where, ".mount", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
unit = strjoin(dest, "/", name);
if (!unit)
return log_oom();
unit = strjoina(dest, "/", name);
f = fopen(unit, "wxe");
if (!f)
@@ -363,7 +377,7 @@ static int add_mount(
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
source);
if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !automount &&
if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) &&
fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
/* The default retry timeout that mount.nfs uses for 'bg' mounts
* is 10000 minutes, where as it uses 2 minutes for 'fg' mounts.
@@ -374,13 +388,13 @@ static int add_mount(
* By placing these options first, they can be over-ridden by
* settings in /etc/fstab. */
opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,", opts, ",fg");
nofail = true;
SET_FLAG(flags, NOFAIL, true);
}
if (!nofail && !automount)
if (!(flags & NOFAIL) && !(flags & AUTOMOUNT))
fprintf(f, "Before=%s\n", post);
if (!automount && opts) {
if (!(flags & AUTOMOUNT) && opts) {
r = write_after(f, opts);
if (r < 0)
return r;
@@ -444,14 +458,26 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
if (!noauto && !automount) {
r = generator_add_symlink(dest, post,
nofail ? "wants" : "requires", name);
if (flags & MAKEFS) {
r = generator_hook_up_mkfs(dest, what, where, fstype);
if (r < 0)
return r;
}
if (automount) {
if (flags & GROWFS) {
r = generator_hook_up_growfs(dest, where, post);
if (r < 0)
return r;
}
if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) {
r = generator_add_symlink(dest, post,
(flags & NOFAIL) ? "wants" : "requires", name);
if (r < 0)
return r;
}
if (flags & AUTOMOUNT) {
r = unit_name_from_path(where, ".automount", &automount_name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@@ -504,7 +530,7 @@ static int add_mount(
return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
r = generator_add_symlink(dest, post,
nofail ? "wants" : "requires", automount_name);
(flags & NOFAIL) ? "wants" : "requires", automount_name);
if (r < 0)
return r;
}
@@ -529,7 +555,7 @@ static int parse_fstab(bool initrd) {
while ((me = getmntent(f))) {
_cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
bool noauto, nofail;
bool makefs, growfs, noauto, nofail;
int k;
if (initrd && !mount_in_initrd(me))
@@ -571,14 +597,18 @@ static int parse_fstab(bool initrd) {
}
}
makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\0");
noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
log_debug("Found entry what=%s where=%s type=%s nofail=%s noauto=%s",
log_debug("Found entry what=%s where=%s type=%s makefs=%s nofail=%s noauto=%s",
what, where, me->mnt_type,
yes_no(makefs),
yes_no(noauto), yes_no(nofail));
if (streq(me->mnt_type, "swap"))
k = add_swap(what, me, noauto, nofail);
k = add_swap(what, me,
makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL);
else {
bool automount;
const char *post;
@@ -600,14 +630,12 @@ static int parse_fstab(bool initrd) {
me->mnt_type,
me->mnt_opts,
me->mnt_passno,
noauto,
nofail,
automount,
makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
post,
fstab_path);
}
if (k < 0)
if (r >= 0 && k < 0)
r = k;
}
@@ -663,9 +691,7 @@ static int add_sysroot_mount(void) {
arg_root_fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
false, /* noauto off */
false, /* nofail off */
false, /* automount off */
0, /* makefs off, growfs off, noauto off, nofail off, automount off */
SPECIAL_INITRD_ROOT_FS_TARGET,
"/proc/cmdline");
}
@@ -718,9 +744,7 @@ static int add_sysroot_usr_mount(void) {
arg_usr_fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
false, /* noauto off */
false, /* nofail off */
false, /* automount off */
0,
SPECIAL_INITRD_FS_TARGET,
"/proc/cmdline");
}
@@ -759,9 +783,7 @@ static int add_volatile_var(void) {
"tmpfs",
"mode=0755",
0,
false,
false,
false,
0,
SPECIAL_LOCAL_FS_TARGET,
"/proc/cmdline");
}

View File

@@ -405,7 +405,7 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
unsigned long extra_flags = 0;
top = prefix_roota(dest, "/sys");
r = path_check_fstype(top, SYSFS_MAGIC);
r = path_is_fs_type(top, SYSFS_MAGIC);
if (r < 0)
return log_error_errno(r, "Failed to determine filesystem type of %s: %m", top);
/* /sys might already be mounted as sysfs by the outer child in the

Some files were not shown because too many files have changed in this diff Show More