mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
Merge pull request #7237 from keszybz/growfs
Create and grow filesystems
This commit is contained in:
@@ -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',
|
||||
|
||||
120
man/systemd-makefs@.service.xml
Normal file
120
man/systemd-makefs@.service.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
19
meson.build
19
meson.build
@@ -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,
|
||||
|
||||
@@ -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
27
src/basic/crypt-util.c
Normal 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
34
src/basic/crypt-util.h
Normal 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
|
||||
@@ -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))
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user