diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index a5e4de00b0..ceba7d0ff8 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -979,53 +979,56 @@ int get_ctty_devnr(pid_t pid, dev_t *d) { return 0; } -int get_ctty(pid_t pid, dev_t *_devnr, char **r) { - char fn[STRLEN("/dev/char/") + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL; - _cleanup_free_ char *s = NULL; - const char *p; +int get_ctty(pid_t pid, dev_t *ret_devnr, char **ret) { + _cleanup_free_ char *fn = NULL, *b = NULL; dev_t devnr; - int k; + int r; - assert(r); + r = get_ctty_devnr(pid, &devnr); + if (r < 0) + return r; - k = get_ctty_devnr(pid, &devnr); - if (k < 0) - return k; + r = device_path_make_canonical(S_IFCHR, devnr, &fn); + if (r < 0) { + if (r != -ENOENT) /* No symlink for this in /dev/char/? */ + return r; - sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr)); - - k = readlink_malloc(fn, &s); - if (k < 0) { - - if (k != -ENOENT) - return k; - - /* This is an ugly hack */ if (major(devnr) == 136) { + /* This is an ugly hack: PTY devices are not listed in /dev/char/, as they don't follow the + * Linux device model. This means we have no nice way to match them up against their actual + * device node. Let's hence do the check by the fixed, assigned major number. Normally we try + * to avoid such fixed major/minor matches, but there appears to nother nice way to handle + * this. */ + if (asprintf(&b, "pts/%u", minor(devnr)) < 0) return -ENOMEM; } else { - /* Probably something like the ptys which have no - * symlink in /dev/char. Let's return something - * vaguely useful. */ + /* Probably something similar to the ptys which have no symlink in /dev/char/. Let's return + * something vaguely useful. */ - b = strdup(fn + 5); - if (!b) - return -ENOMEM; + r = device_path_make_major_minor(S_IFCHR, devnr, &fn); + if (r < 0) + return r; } - } else { - p = PATH_STARTSWITH_SET(s, "/dev/", "../"); - if (!p) - p = s; - - b = strdup(p); - if (!b) - return -ENOMEM; } - *r = b; - if (_devnr) - *_devnr = devnr; + if (!b) { + const char *w; + + w = path_startswith(fn, "/dev/"); + if (w) { + b = strdup(w); + if (!b) + return -ENOMEM; + } else + b = TAKE_PTR(fn); + } + + if (ret) + *ret = TAKE_PTR(b); + + if (ret_devnr) + *ret_devnr = devnr; return 0; } diff --git a/src/partition/growfs.c b/src/partition/growfs.c index 8e04eb3c23..b8dc9f2e93 100644 --- a/src/partition/growfs.c +++ b/src/partition/growfs.c @@ -23,6 +23,7 @@ #include "parse-util.h" #include "path-util.h" #include "pretty-print.h" +#include "stat-util.h" #include "strv.h" static const char *arg_target = NULL; @@ -69,13 +70,16 @@ static int resize_btrfs(const char *path, int mountfd, int devfd, uint64_t numbl #if HAVE_LIBCRYPTSETUP static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_devno) { - char devpath[DEV_NUM_PATH_MAX], main_devpath[DEV_NUM_PATH_MAX]; - _cleanup_close_ int main_devfd = -1; + _cleanup_free_ char *devpath = NULL, *main_devpath = NULL; _cleanup_(crypt_freep) struct crypt_device *cd = NULL; + _cleanup_close_ int main_devfd = -1; uint64_t size; int r; - xsprintf_dev_num_path(main_devpath, "block", main_devno); + r = device_path_make_major_minor(S_IFBLK, main_devno, &main_devpath); + if (r < 0) + return log_error_errno(r, "Failed to format device major/minor path: %m"); + main_devfd = open(main_devpath, O_RDONLY|O_CLOEXEC); if (main_devfd < 0) return log_error_errno(errno, "Failed to open \"%s\": %m", main_devpath); @@ -85,8 +89,10 @@ 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); + if (r < 0) + return log_error_errno(r, "Failed to format major/minor path: %m"); - xsprintf_dev_num_path(devpath, "block", devno); r = crypt_init(&cd, devpath); if (r < 0) return log_error_errno(r, "crypt_init(\"%s\") failed: %m", devpath); @@ -115,9 +121,8 @@ static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_ #endif static int maybe_resize_slave_device(const char *mountpath, dev_t main_devno) { + _cleanup_free_ char *fstype = NULL, *devpath = NULL; dev_t devno; - char devpath[DEV_NUM_PATH_MAX]; - _cleanup_free_ char *fstype = NULL; int r; #if HAVE_LIBCRYPTSETUP @@ -137,7 +142,10 @@ static int maybe_resize_slave_device(const char *mountpath, dev_t main_devno) { if (devno == main_devno) return 0; - xsprintf_dev_num_path(devpath, "block", devno); + r = device_path_make_major_minor(S_IFBLK, devno, &devpath); + if (r < 0) + return log_error_errno(r, "Failed to format device major/minor path: %m"); + r = probe_filesystem(devpath, &fstype); if (r == -EUCLEAN) return log_warning_errno(r, "Cannot reliably determine probe \"%s\", refusing to proceed.", devpath); @@ -222,12 +230,13 @@ static int parse_argv(int argc, char *argv[]) { } int main(int argc, char *argv[]) { - dev_t devno; _cleanup_close_ int mountfd = -1, devfd = -1; - int blocksize; + _cleanup_free_ char *devpath = NULL; uint64_t size, numblocks; - char devpath[DEV_NUM_PATH_MAX], fb[FORMAT_BYTES_MAX]; + char fb[FORMAT_BYTES_MAX]; struct statfs sfs; + dev_t devno; + int blocksize; int r; log_setup_service(); @@ -264,7 +273,12 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - xsprintf_dev_num_path(devpath, "block", devno); + r = device_path_make_major_minor(S_IFBLK, devno, &devpath); + if (r < 0) { + log_error_errno(r, "Failed to format device major/minor path: %m"); + return EXIT_FAILURE; + } + devfd = open(devpath, O_RDONLY|O_CLOEXEC); if (devfd < 0) { log_error_errno(errno, "Failed to open \"%s\": %m", devpath); diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index db4fd411e2..7e276f1edf 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -405,7 +405,7 @@ static int verify_esp( sd_id128_t *ret_uuid) { #if HAVE_BLKID _cleanup_(blkid_free_probep) blkid_probe b = NULL; - char t[DEV_NUM_PATH_MAX]; + _cleanup_free_ char *node = NULL; const char *v; #endif uint64_t pstart = 0, psize = 0; @@ -469,9 +469,11 @@ static int verify_esp( goto finish; #if HAVE_BLKID - xsprintf_dev_num_path(t, "block", st.st_dev); + r = device_path_make_major_minor(S_IFBLK, st.st_dev, &node); + if (r < 0) + return log_error_errno(r, "Failed to format major/minor device path: %m"); errno = 0; - b = blkid_new_probe_from_filename(t); + b = blkid_new_probe_from_filename(node); if (!b) return log_error_errno(errno ?: ENOMEM, "Failed to open file system \"%s\": %m", p); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 18620a3b19..01b06dbc0b 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -219,8 +219,9 @@ int dissect_image( return -ENOMEM; } - if (asprintf(&n, "/dev/block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) - return -ENOMEM; + r = device_path_make_major_minor(st.st_mode, st.st_rdev, &n); + if (r < 0) + return r; m->partitions[PARTITION_ROOT] = (DissectedPartition) { .found = true,