mirror of
https://github.com/systemd/systemd.git
synced 2026-08-04 15:10:33 +00:00
systemd-growfs: remove dependency on udev symlinks
systemd-growfs currently requires that udev ran first to work (because /dev/block/ symlinks must exist) but that is not what happens when we're not using initrd and systemd is PID1.
This commit is contained in:
committed by
Luca Boccassi
parent
782c6e5c90
commit
aa181897cf
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "chase-symlinks.h"
|
||||
#include "devnum-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -57,6 +58,53 @@ int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_path_make_major_minor_sysfs(mode_t mode, dev_t devnum, char **ret) {
|
||||
_cleanup_free_ char *syspath = NULL, *link = NULL, *fname = NULL;
|
||||
_cleanup_free_ char *devpath = NULL;
|
||||
const char *t;
|
||||
int r;
|
||||
|
||||
/* Generates the /dev/... path given a dev_t. What makes this different
|
||||
* from device_path_make_major_minor is that it works even when udev
|
||||
* hasn't yet run */
|
||||
|
||||
if (S_ISCHR(mode))
|
||||
t = "char";
|
||||
else if (S_ISBLK(mode))
|
||||
t = "block";
|
||||
else
|
||||
return -ENODEV;
|
||||
|
||||
if (asprintf(&syspath, "/sys/dev/%s/" DEVNUM_FORMAT_STR, t, DEVNUM_FORMAT_VAL(devnum)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = readlink_malloc(syspath, &link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = path_extract_filename(link, &fname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
devpath = path_join("/dev", fname);
|
||||
if (!devpath)
|
||||
return -ENOMEM;
|
||||
|
||||
struct stat st;
|
||||
if (stat(devpath, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (((st.st_mode ^ mode) & S_IFMT) != 0)
|
||||
return S_ISBLK(mode) ? -ENOTBLK : -ENODEV;
|
||||
|
||||
if (st.st_rdev != devnum)
|
||||
return -ENXIO;
|
||||
|
||||
*ret = TAKE_PTR(devpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_path_make_canonical(mode_t mode, dev_t devnum, char **ret) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
@@ -29,6 +29,7 @@ int parse_devnum(const char *s, dev_t *ret);
|
||||
})
|
||||
|
||||
int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret);
|
||||
int device_path_make_major_minor_sysfs(mode_t mode, dev_t devnum, char **ret);
|
||||
int device_path_make_canonical(mode_t mode, dev_t devnum, char **ret);
|
||||
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devnum);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Cannot resize LUKS device: %m");
|
||||
|
||||
r = device_path_make_major_minor(S_IFBLK, main_devno, &main_devpath);
|
||||
r = device_path_make_major_minor_sysfs(S_IFBLK, main_devno, &main_devpath);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to format device major/minor path: %m");
|
||||
|
||||
@@ -54,7 +54,7 @@ static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_
|
||||
main_devpath);
|
||||
|
||||
log_debug("%s is %"PRIu64" bytes", main_devpath, size);
|
||||
r = device_path_make_major_minor(S_IFBLK, devno, &devpath);
|
||||
r = device_path_make_major_minor_sysfs(S_IFBLK, devno, &devpath);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to format major/minor path: %m");
|
||||
|
||||
@@ -115,7 +115,7 @@ static int maybe_resize_underlying_device(
|
||||
if (devno == main_devno)
|
||||
return 0;
|
||||
|
||||
r = device_path_make_major_minor(S_IFBLK, devno, &devpath);
|
||||
r = device_path_make_major_minor_sysfs(S_IFBLK, devno, &devpath);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to format device major/minor path: %m");
|
||||
|
||||
@@ -237,7 +237,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Unable to resize underlying device of \"%s\", proceeding anyway: %m", arg_target);
|
||||
|
||||
r = device_path_make_major_minor(S_IFBLK, devno, &devpath);
|
||||
r = device_path_make_major_minor_sysfs(S_IFBLK, devno, &devpath);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to format device major/minor path: %m");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user