diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index e16bfef3c3..e568c70684 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -8,8 +8,10 @@ #include #include "alloc-util.h" +#include "blockdev-util.h" #include "dirent-util.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "locale-util.h" #include "log.h" @@ -1488,3 +1490,26 @@ int open_parent(const char *path, int flags, mode_t mode) { return fd; } + +int path_is_encrypted(const char *path) { + _cleanup_free_ char *uuids = NULL; + char p[SYS_BLOCK_PATH_MAX("/dm/uuid")]; + dev_t devt; + int r; + + r = get_block_device(path, &devt); + if (r < 0) + return r; + if (r == 0) /* doesn't have a block device */ + return false; + + xsprintf_sys_block_path(p, "/dm/uuid", devt); + r = read_one_line_file(p, &uuids); + if (r == -ENOENT) + return false; + if (r < 0) + return r; + + /* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */ + return !!startswith(uuids, "CRYPT-"); +} diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index c2c39c4315..0889239829 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -122,3 +122,5 @@ int fsync_path_at(int at_fd, const char *path); int syncfs_path(int atfd, const char *path); int open_parent(const char *path, int flags, mode_t mode); + +int path_is_encrypted(const char *path); diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index d97ccfda3b..d005b3e8e5 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -846,6 +846,28 @@ static void test_chmod_and_chown_unsafe(void) { assert_se(S_ISLNK(st.st_mode)); } +static void test_path_is_encrypted_one(const char *p, int expect) { + int r; + + r = path_is_encrypted(p); + assert_se(r >= 0); + + printf("%s encrypted: %s\n", p, yes_no(r)); + + assert_se(expect < 0 || ((r > 0) == (expect > 0))); +} + +static void test_path_is_encrypted(void) { + log_info("/* %s */", __func__); + + test_path_is_encrypted_one("/home", -1); + test_path_is_encrypted_one("/var", -1); + test_path_is_encrypted_one("/", -1); + test_path_is_encrypted_one("/proc", false); + test_path_is_encrypted_one("/sys", false); + test_path_is_encrypted_one("/dev", false); +} + int main(int argc, char *argv[]) { test_setup_logging(LOG_INFO); @@ -864,6 +886,7 @@ int main(int argc, char *argv[]) { test_rename_noreplace(); test_chmod_and_chown(); test_chmod_and_chown_unsafe(); + test_path_is_encrypted(); return 0; }