tree-wide: stop using canonicalize_file_name(), use chase_symlinks() instead
Let's use chase_symlinks() everywhere, and stop using GNU canonicalize_file_name() everywhere. For most cases this should not change behaviour, however increase exposure of our function to get better tested. Most importantly in a few cases (most notably nspawn) it can take the correct root directory into account when chasing symlinks.
This commit is contained in:
+13
-13
@@ -224,25 +224,25 @@ int readlink_and_make_absolute(const char *p, char **r) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int readlink_and_canonicalize(const char *p, char **r) {
|
||||
int readlink_and_canonicalize(const char *p, const char *root, char **ret) {
|
||||
char *t, *s;
|
||||
int j;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
assert(r);
|
||||
assert(ret);
|
||||
|
||||
j = readlink_and_make_absolute(p, &t);
|
||||
if (j < 0)
|
||||
return j;
|
||||
r = readlink_and_make_absolute(p, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
s = canonicalize_file_name(t);
|
||||
if (s) {
|
||||
r = chase_symlinks(t, root, &s);
|
||||
if (r < 0)
|
||||
/* If we can't follow up, then let's return the original string, slightly cleaned up. */
|
||||
*ret = path_kill_slashes(t);
|
||||
else {
|
||||
*ret = s;
|
||||
free(t);
|
||||
*r = s;
|
||||
} else
|
||||
*r = t;
|
||||
|
||||
path_kill_slashes(*r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ int readlinkat_malloc(int fd, const char *p, char **ret);
|
||||
int readlink_malloc(const char *p, char **r);
|
||||
int readlink_value(const char *p, char **ret);
|
||||
int readlink_and_make_absolute(const char *p, char **r);
|
||||
int readlink_and_canonicalize(const char *p, char **r);
|
||||
int readlink_and_canonicalize(const char *p, const char *root, char **r);
|
||||
int readlink_and_make_absolute_root(const char *root, const char *path, char **ret);
|
||||
|
||||
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "mount-util.h"
|
||||
#include "parse-util.h"
|
||||
@@ -205,9 +206,10 @@ fallback_fstat:
|
||||
}
|
||||
|
||||
/* flags can be AT_SYMLINK_FOLLOW or 0 */
|
||||
int path_is_mount_point(const char *t, int flags) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
int path_is_mount_point(const char *t, const char *root, int flags) {
|
||||
_cleanup_free_ char *canonical = NULL, *parent = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
|
||||
@@ -219,9 +221,9 @@ int path_is_mount_point(const char *t, int flags) {
|
||||
* /bin -> /usr/bin/ and /usr is a mount point, then the parent that we
|
||||
* look at needs to be /usr, not /. */
|
||||
if (flags & AT_SYMLINK_FOLLOW) {
|
||||
canonical = canonicalize_file_name(t);
|
||||
if (!canonical)
|
||||
return -errno;
|
||||
r = chase_symlinks(t, root, &canonical);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
t = canonical;
|
||||
}
|
||||
@@ -473,7 +475,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
|
||||
return r;
|
||||
|
||||
/* Deal with mount points that are obstructed by a later mount */
|
||||
r = path_is_mount_point(x, 0);
|
||||
r = path_is_mount_point(x, NULL, 0);
|
||||
if (r == -ENOENT || r == 0)
|
||||
continue;
|
||||
if (r < 0)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "missing.h"
|
||||
|
||||
int fd_is_mount_point(int fd, const char *filename, int flags);
|
||||
int path_is_mount_point(const char *path, int flags);
|
||||
int path_is_mount_point(const char *path, const char *root, int flags);
|
||||
|
||||
int repeat_unmount(const char *path, int flags);
|
||||
|
||||
|
||||
+22
-23
@@ -220,10 +220,11 @@ int path_strv_make_absolute_cwd(char **l) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **path_strv_resolve(char **l, const char *prefix) {
|
||||
char **path_strv_resolve(char **l, const char *root) {
|
||||
char **s;
|
||||
unsigned k = 0;
|
||||
bool enomem = false;
|
||||
int r;
|
||||
|
||||
if (strv_isempty(l))
|
||||
return l;
|
||||
@@ -233,17 +234,17 @@ char **path_strv_resolve(char **l, const char *prefix) {
|
||||
* changes on failure. */
|
||||
|
||||
STRV_FOREACH(s, l) {
|
||||
char *t, *u;
|
||||
_cleanup_free_ char *orig = NULL;
|
||||
char *t, *u;
|
||||
|
||||
if (!path_is_absolute(*s)) {
|
||||
free(*s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
if (root) {
|
||||
orig = *s;
|
||||
t = strappend(prefix, orig);
|
||||
t = prefix_root(root, orig);
|
||||
if (!t) {
|
||||
enomem = true;
|
||||
continue;
|
||||
@@ -251,28 +252,26 @@ char **path_strv_resolve(char **l, const char *prefix) {
|
||||
} else
|
||||
t = *s;
|
||||
|
||||
errno = 0;
|
||||
u = canonicalize_file_name(t);
|
||||
if (!u) {
|
||||
if (errno == ENOENT) {
|
||||
if (prefix) {
|
||||
u = orig;
|
||||
orig = NULL;
|
||||
free(t);
|
||||
} else
|
||||
u = t;
|
||||
} else {
|
||||
r = chase_symlinks(t, root, &u);
|
||||
if (r == -ENOENT) {
|
||||
if (root) {
|
||||
u = orig;
|
||||
orig = NULL;
|
||||
free(t);
|
||||
if (errno == ENOMEM || errno == 0)
|
||||
enomem = true;
|
||||
} else
|
||||
u = t;
|
||||
} else if (r < 0) {
|
||||
free(t);
|
||||
|
||||
continue;
|
||||
}
|
||||
} else if (prefix) {
|
||||
if (r == -ENOMEM)
|
||||
enomem = true;
|
||||
|
||||
continue;
|
||||
} else if (root) {
|
||||
char *x;
|
||||
|
||||
free(t);
|
||||
x = path_startswith(u, prefix);
|
||||
x = path_startswith(u, root);
|
||||
if (x) {
|
||||
/* restore the slash if it was lost */
|
||||
if (!startswith(x, "/"))
|
||||
@@ -304,12 +303,12 @@ char **path_strv_resolve(char **l, const char *prefix) {
|
||||
return l;
|
||||
}
|
||||
|
||||
char **path_strv_resolve_uniq(char **l, const char *prefix) {
|
||||
char **path_strv_resolve_uniq(char **l, const char *root) {
|
||||
|
||||
if (strv_isempty(l))
|
||||
return l;
|
||||
|
||||
if (!path_strv_resolve(l, prefix))
|
||||
if (!path_strv_resolve(l, root))
|
||||
return NULL;
|
||||
|
||||
return strv_uniq(l);
|
||||
|
||||
@@ -66,8 +66,8 @@ static inline bool path_equal_ptr(const char *a, const char *b) {
|
||||
})
|
||||
|
||||
int path_strv_make_absolute_cwd(char **l);
|
||||
char** path_strv_resolve(char **l, const char *prefix);
|
||||
char** path_strv_resolve_uniq(char **l, const char *prefix);
|
||||
char** path_strv_resolve(char **l, const char *root);
|
||||
char** path_strv_resolve_uniq(char **l, const char *root);
|
||||
|
||||
int find_binary(const char *name, char **filename);
|
||||
|
||||
|
||||
@@ -783,7 +783,7 @@ static int automount_start(Unit *u) {
|
||||
assert(a);
|
||||
assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
|
||||
|
||||
if (path_is_mount_point(a->where, 0) > 0) {
|
||||
if (path_is_mount_point(a->where, NULL, 0) > 0) {
|
||||
log_unit_error(u, "Path %s is already a mount point, refusing start.", a->where);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ int machine_id_commit(const char *root) {
|
||||
|
||||
etc_machine_id = prefix_roota(root, "/etc/machine-id");
|
||||
|
||||
r = path_is_mount_point(etc_machine_id, 0);
|
||||
r = path_is_mount_point(etc_machine_id, NULL, 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine whether %s is a mount point: %m", etc_machine_id);
|
||||
if (r == 0) {
|
||||
|
||||
@@ -159,7 +159,7 @@ static int mount_one(const MountPoint *p, bool relabel) {
|
||||
if (relabel)
|
||||
(void) label_fix(p->where, true, true);
|
||||
|
||||
r = path_is_mount_point(p->where, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(p->where, NULL, AT_SYMLINK_FOLLOW);
|
||||
if (r < 0 && r != -ENOENT) {
|
||||
log_full_errno((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, r, "Failed to determine whether %s is a mount point: %m", p->where);
|
||||
return (p->mode & MNT_FATAL) ? r : 0;
|
||||
|
||||
@@ -596,7 +596,7 @@ static int apply_mount(
|
||||
case READONLY:
|
||||
case READWRITE:
|
||||
|
||||
r = path_is_mount_point(bind_mount_path(m), 0);
|
||||
r = path_is_mount_point(bind_mount_path(m), NULL, 0);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to determine whether %s is already a mount point: %m", bind_mount_path(m));
|
||||
if (r > 0) /* Nothing to do here, it is already a mount. We just later toggle the MS_RDONLY bit for the mount point if needed. */
|
||||
@@ -860,7 +860,7 @@ int setup_namespace(
|
||||
|
||||
if (root_directory) {
|
||||
/* Turn directory into bind mount, if it isn't one yet */
|
||||
r = path_is_mount_point(root_directory, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(root_directory, NULL, AT_SYMLINK_FOLLOW);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (r == 0) {
|
||||
|
||||
+7
-6
@@ -87,14 +87,15 @@ static enum {
|
||||
|
||||
static int equivalent(const char *a, const char *b) {
|
||||
_cleanup_free_ char *x = NULL, *y = NULL;
|
||||
int r;
|
||||
|
||||
x = canonicalize_file_name(a);
|
||||
if (!x)
|
||||
return -errno;
|
||||
r = chase_symlinks(a, NULL, &x);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
y = canonicalize_file_name(b);
|
||||
if (!y)
|
||||
return -errno;
|
||||
r = chase_symlinks(b, NULL, &y);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return path_equal(x, y);
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ static bool path_is_busy(const char *where) {
|
||||
int r;
|
||||
|
||||
/* already a mountpoint; generators run during reload */
|
||||
r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(where, NULL, AT_SYMLINK_FOLLOW);
|
||||
if (r > 0)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -938,21 +938,21 @@ static int add_matches(sd_journal *j, char **args) {
|
||||
have_term = false;
|
||||
|
||||
} else if (path_is_absolute(*i)) {
|
||||
_cleanup_free_ char *p, *t = NULL, *t2 = NULL, *interpreter = NULL;
|
||||
const char *path;
|
||||
_cleanup_free_ char *p = NULL, *t = NULL, *t2 = NULL, *interpreter = NULL;
|
||||
struct stat st;
|
||||
|
||||
p = canonicalize_file_name(*i);
|
||||
path = p ?: *i;
|
||||
r = chase_symlinks(*i, NULL, &p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Couldn't canonicalize path: %m");
|
||||
|
||||
if (lstat(path, &st) < 0)
|
||||
if (lstat(p, &st) < 0)
|
||||
return log_error_errno(errno, "Couldn't stat file: %m");
|
||||
|
||||
if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
|
||||
if (executable_is_script(path, &interpreter) > 0) {
|
||||
if (executable_is_script(p, &interpreter) > 0) {
|
||||
_cleanup_free_ char *comm;
|
||||
|
||||
comm = strndup(basename(path), 15);
|
||||
comm = strndup(basename(p), 15);
|
||||
if (!comm)
|
||||
return log_oom();
|
||||
|
||||
@@ -968,7 +968,7 @@ static int add_matches(sd_journal *j, char **args) {
|
||||
return log_oom();
|
||||
}
|
||||
} else {
|
||||
t = strappend("_EXE=", path);
|
||||
t = strappend("_EXE=", p);
|
||||
if (!t)
|
||||
return log_oom();
|
||||
}
|
||||
@@ -979,7 +979,7 @@ static int add_matches(sd_journal *j, char **args) {
|
||||
r = sd_journal_add_match(j, t2, 0);
|
||||
|
||||
} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
|
||||
r = add_matches_for_device(j, path);
|
||||
r = add_matches_for_device(j, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
|
||||
@@ -164,7 +164,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
r = readlink_and_canonicalize(_syspath, &syspath);
|
||||
r = readlink_and_canonicalize(_syspath, NULL, &syspath);
|
||||
if (r == -ENOENT)
|
||||
/* the device does not exist (any more?) */
|
||||
return -ENODEV;
|
||||
|
||||
@@ -338,7 +338,7 @@ static int user_mkdir_runtime_path(User *u) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create /run/user: %m");
|
||||
|
||||
if (path_is_mount_point(u->runtime_path, 0) <= 0) {
|
||||
if (path_is_mount_point(u->runtime_path, NULL, 0) <= 0) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
(void) mkdir_label(u->runtime_path, 0700);
|
||||
|
||||
+28
-12
@@ -418,7 +418,7 @@ int mount_all(const char *dest,
|
||||
if (!where)
|
||||
return log_oom();
|
||||
|
||||
r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(where, dest, AT_SYMLINK_FOLLOW);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to detect whether %s is a mount point: %m", where);
|
||||
|
||||
@@ -726,14 +726,19 @@ static int get_controllers(Set *subsystems) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controller, const char *hierarchy,
|
||||
CGroupUnified unified_requested, bool read_only) {
|
||||
static int mount_legacy_cgroup_hierarchy(
|
||||
const char *dest,
|
||||
const char *controller,
|
||||
const char *hierarchy,
|
||||
CGroupUnified unified_requested,
|
||||
bool read_only) {
|
||||
|
||||
const char *to, *fstype, *opts;
|
||||
int r;
|
||||
|
||||
to = strjoina(strempty(dest), "/sys/fs/cgroup/", hierarchy);
|
||||
|
||||
r = path_is_mount_point(to, 0);
|
||||
r = path_is_mount_point(to, dest, 0);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to determine if %s is mounted already: %m", to);
|
||||
if (r > 0)
|
||||
@@ -773,8 +778,13 @@ static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controlle
|
||||
|
||||
/* Mount a legacy cgroup hierarchy when cgroup namespaces are supported. */
|
||||
static int mount_legacy_cgns_supported(
|
||||
CGroupUnified unified_requested, bool userns, uid_t uid_shift,
|
||||
uid_t uid_range, const char *selinux_apifs_context) {
|
||||
const char *dest,
|
||||
CGroupUnified unified_requested,
|
||||
bool userns,
|
||||
uid_t uid_shift,
|
||||
uid_t uid_range,
|
||||
const char *selinux_apifs_context) {
|
||||
|
||||
_cleanup_set_free_free_ Set *controllers = NULL;
|
||||
const char *cgroup_root = "/sys/fs/cgroup", *c;
|
||||
int r;
|
||||
@@ -782,7 +792,7 @@ static int mount_legacy_cgns_supported(
|
||||
(void) mkdir_p(cgroup_root, 0755);
|
||||
|
||||
/* Mount a tmpfs to /sys/fs/cgroup if it's not mounted there yet. */
|
||||
r = path_is_mount_point(cgroup_root, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(cgroup_root, dest, AT_SYMLINK_FOLLOW);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine if /sys/fs/cgroup is already mounted: %m");
|
||||
if (r == 0) {
|
||||
@@ -871,8 +881,12 @@ skip_controllers:
|
||||
/* Mount legacy cgroup hierarchy when cgroup namespaces are unsupported. */
|
||||
static int mount_legacy_cgns_unsupported(
|
||||
const char *dest,
|
||||
CGroupUnified unified_requested, bool userns, uid_t uid_shift, uid_t uid_range,
|
||||
CGroupUnified unified_requested,
|
||||
bool userns,
|
||||
uid_t uid_shift,
|
||||
uid_t uid_range,
|
||||
const char *selinux_apifs_context) {
|
||||
|
||||
_cleanup_set_free_free_ Set *controllers = NULL;
|
||||
const char *cgroup_root;
|
||||
int r;
|
||||
@@ -882,7 +896,7 @@ static int mount_legacy_cgns_unsupported(
|
||||
(void) mkdir_p(cgroup_root, 0755);
|
||||
|
||||
/* Mount a tmpfs to /sys/fs/cgroup if it's not mounted there yet. */
|
||||
r = path_is_mount_point(cgroup_root, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(cgroup_root, dest, AT_SYMLINK_FOLLOW);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine if /sys/fs/cgroup is already mounted: %m");
|
||||
if (r == 0) {
|
||||
@@ -975,7 +989,7 @@ static int mount_unified_cgroups(const char *dest) {
|
||||
|
||||
(void) mkdir_p(p, 0755);
|
||||
|
||||
r = path_is_mount_point(p, AT_SYMLINK_FOLLOW);
|
||||
r = path_is_mount_point(p, dest, AT_SYMLINK_FOLLOW);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine if %s is mounted already: %m", p);
|
||||
if (r > 0) {
|
||||
@@ -995,14 +1009,16 @@ static int mount_unified_cgroups(const char *dest) {
|
||||
int mount_cgroups(
|
||||
const char *dest,
|
||||
CGroupUnified unified_requested,
|
||||
bool userns, uid_t uid_shift, uid_t uid_range,
|
||||
bool userns,
|
||||
uid_t uid_shift,
|
||||
uid_t uid_range,
|
||||
const char *selinux_apifs_context,
|
||||
bool use_cgns) {
|
||||
|
||||
if (unified_requested >= CGROUP_UNIFIED_ALL)
|
||||
return mount_unified_cgroups(dest);
|
||||
else if (use_cgns)
|
||||
return mount_legacy_cgns_supported(unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
|
||||
return mount_legacy_cgns_supported(dest, unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
|
||||
|
||||
return mount_legacy_cgns_unsupported(dest, unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
|
||||
}
|
||||
|
||||
+3
-3
@@ -1666,7 +1666,7 @@ static int setup_journal(const char *directory) {
|
||||
p = strjoina("/var/log/journal/", id);
|
||||
q = prefix_roota(directory, p);
|
||||
|
||||
if (path_is_mount_point(p, 0) > 0) {
|
||||
if (path_is_mount_point(p, NULL, 0) > 0) {
|
||||
if (try)
|
||||
return 0;
|
||||
|
||||
@@ -1674,7 +1674,7 @@ static int setup_journal(const char *directory) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (path_is_mount_point(q, 0) > 0) {
|
||||
if (path_is_mount_point(q, NULL, 0) > 0) {
|
||||
if (try)
|
||||
return 0;
|
||||
|
||||
@@ -4132,7 +4132,7 @@ int main(int argc, char *argv[]) {
|
||||
* the specified is not a mount point we
|
||||
* create the new snapshot in the parent
|
||||
* directory, just next to it. */
|
||||
r = path_is_mount_point(arg_directory, 0);
|
||||
r = path_is_mount_point(arg_directory, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to determine whether directory %s is mount point: %m", arg_directory);
|
||||
goto finish;
|
||||
|
||||
@@ -399,7 +399,7 @@ static int condition_test_path_is_mount_point(Condition *c) {
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_IS_MOUNT_POINT);
|
||||
|
||||
return path_is_mount_point(c->parameter, AT_SYMLINK_FOLLOW) > 0;
|
||||
return path_is_mount_point(c->parameter, NULL, AT_SYMLINK_FOLLOW) > 0;
|
||||
}
|
||||
|
||||
static int condition_test_path_is_read_write(Condition *c) {
|
||||
|
||||
@@ -225,7 +225,7 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0) {
|
||||
if (path_is_mount_point("/var/lib/machines", NULL, AT_SYMLINK_FOLLOW) > 0) {
|
||||
log_debug("/var/lib/machines is already a mount point, not creating loopback file for it.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ static void test_copy_tree(void) {
|
||||
assert_se((f = strjoin(original_dir, *p)));
|
||||
assert_se((l = strjoin(copy_dir, *link)));
|
||||
|
||||
assert_se(readlink_and_canonicalize(l, &target) == 0);
|
||||
assert_se(readlink_and_canonicalize(l, NULL, &target) == 0);
|
||||
assert_se(path_equal(f, target));
|
||||
}
|
||||
|
||||
|
||||
+30
-30
@@ -337,17 +337,17 @@ static void test_path_is_mount_point(void) {
|
||||
_cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL;
|
||||
_cleanup_free_ char *dir2 = NULL, *dir2file = NULL;
|
||||
|
||||
assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0);
|
||||
assert_se(path_is_mount_point("/", 0) > 0);
|
||||
assert_se(path_is_mount_point("/", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
assert_se(path_is_mount_point("/", NULL, 0) > 0);
|
||||
|
||||
assert_se(path_is_mount_point("/proc", AT_SYMLINK_FOLLOW) > 0);
|
||||
assert_se(path_is_mount_point("/proc", 0) > 0);
|
||||
assert_se(path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
assert_se(path_is_mount_point("/proc", NULL, 0) > 0);
|
||||
|
||||
assert_se(path_is_mount_point("/proc/1", AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point("/proc/1", 0) == 0);
|
||||
assert_se(path_is_mount_point("/proc/1", NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point("/proc/1", NULL, 0) == 0);
|
||||
|
||||
assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0);
|
||||
assert_se(path_is_mount_point("/sys", 0) > 0);
|
||||
assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
|
||||
|
||||
/* we'll create a hierarchy of different kinds of dir/file/link
|
||||
* layouts:
|
||||
@@ -381,10 +381,10 @@ static void test_path_is_mount_point(void) {
|
||||
assert_se(link1);
|
||||
assert_se(symlink("file2", link2) == 0);
|
||||
|
||||
assert_se(path_is_mount_point(file1, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(file1, 0) == 0);
|
||||
assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(link1, 0) == 0);
|
||||
assert_se(path_is_mount_point(file1, NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(file1, NULL, 0) == 0);
|
||||
assert_se(path_is_mount_point(link1, NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(link1, NULL, 0) == 0);
|
||||
|
||||
/* directory mountpoints */
|
||||
dir1 = path_join(NULL, tmp_dir, "dir1");
|
||||
@@ -400,10 +400,10 @@ static void test_path_is_mount_point(void) {
|
||||
assert_se(dir2);
|
||||
assert_se(mkdir(dir2, 0755) == 0);
|
||||
|
||||
assert_se(path_is_mount_point(dir1, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dir1, 0) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1, 0) == 0);
|
||||
assert_se(path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dir1, NULL, 0) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1, NULL, 0) == 0);
|
||||
|
||||
/* file in subdirectory mountpoints */
|
||||
dir1file = path_join(NULL, dir1, "file");
|
||||
@@ -412,10 +412,10 @@ static void test_path_is_mount_point(void) {
|
||||
assert_se(fd > 0);
|
||||
close(fd);
|
||||
|
||||
assert_se(path_is_mount_point(dir1file, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dir1file, 0) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1file, 0) == 0);
|
||||
assert_se(path_is_mount_point(dir1file, NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dir1file, NULL, 0) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point(dirlink1file, NULL, 0) == 0);
|
||||
|
||||
/* these tests will only work as root */
|
||||
if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
|
||||
@@ -423,10 +423,10 @@ static void test_path_is_mount_point(void) {
|
||||
|
||||
/* files */
|
||||
/* capture results in vars, to avoid dangling mounts on failure */
|
||||
rf = path_is_mount_point(file2, 0);
|
||||
rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW);
|
||||
rlf = path_is_mount_point(link2, 0);
|
||||
rlt = path_is_mount_point(link2, AT_SYMLINK_FOLLOW);
|
||||
rf = path_is_mount_point(file2, NULL, 0);
|
||||
rt = path_is_mount_point(file2, NULL, AT_SYMLINK_FOLLOW);
|
||||
rlf = path_is_mount_point(link2, NULL, 0);
|
||||
rlt = path_is_mount_point(link2, NULL, AT_SYMLINK_FOLLOW);
|
||||
|
||||
assert_se(umount(file2) == 0);
|
||||
|
||||
@@ -444,13 +444,13 @@ static void test_path_is_mount_point(void) {
|
||||
|
||||
assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0);
|
||||
|
||||
rf = path_is_mount_point(dir1, 0);
|
||||
rt = path_is_mount_point(dir1, AT_SYMLINK_FOLLOW);
|
||||
rlf = path_is_mount_point(dirlink1, 0);
|
||||
rlt = path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW);
|
||||
rf = path_is_mount_point(dir1, NULL, 0);
|
||||
rt = path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW);
|
||||
rlf = path_is_mount_point(dirlink1, NULL, 0);
|
||||
rlt = path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW);
|
||||
/* its parent is a mount point, but not /file itself */
|
||||
rl1f = path_is_mount_point(dirlink1file, 0);
|
||||
rl1t = path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW);
|
||||
rl1f = path_is_mount_point(dirlink1file, NULL, 0);
|
||||
rl1t = path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW);
|
||||
|
||||
assert_se(umount(dir1) == 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user