From e3d02dd42781778b80855ac399b061f5c97972d3 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Mon, 14 Nov 2022 17:28:36 +0100 Subject: [PATCH] LU-16310 sec: Lustre/HSM on enc file with enc key Support for Lustre/HSM on encrypted files when the encryption key is available requires similar attention as with file migration. The volatile file used for HSM restore must have the same encryption context as the Lustre file being restored, so that file content remains accessible after the layout swap at the end of the restore procedure. Please note that using Lustre/HSM with the encryption key creates clear text copies of encrypted files on the HSM backend storage. Lustre-change: https://review.whamcloud.com/49153 Lustre-commit: df7a8d92d2378e236ee83b559e7a1158f84e63f4 Signed-off-by: Sebastien Buisson Change-Id: I99cba202cd2c7c747bbe5c4ec7d9208c7f6baf4b Reviewed-by: Andreas Dilger Reviewed-by: Etienne AUJAMES Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/49899 Tested-by: jenkins Tested-by: Maloo --- lustre/llite/crypto.c | 11 +++++++- lustre/utils/liblustreapi_hsm.c | 57 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index cd7fef5..ad719b6 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -252,7 +252,16 @@ int ll_setup_filename(struct inode *dir, const struct qstr *iname, fid->f_oid = 0; fid->f_ver = 0; } - rc = llcrypt_setup_filename(dir, &dname, lookup, fname); + if (unlikely(filename_is_volatile(iname->name, + iname->len, NULL))) { + /* keep volatile name as-is, matters for server side */ + memset(fname, 0, sizeof(struct llcrypt_name)); + fname->disk_name.name = (unsigned char *)iname->name; + fname->disk_name.len = iname->len; + rc = 0; + } else { + rc = llcrypt_setup_filename(dir, &dname, lookup, fname); + } if (rc == -ENOENT && lookup) { if (((dir == dir->i_sb->s_root->d_inode && iname->len == strlen(dot_fscrypt_name) && diff --git a/lustre/utils/liblustreapi_hsm.c b/lustre/utils/liblustreapi_hsm.c index 975bfed..fccba91 100644 --- a/lustre/utils/liblustreapi_hsm.c +++ b/lustre/utils/liblustreapi_hsm.c @@ -1052,7 +1052,44 @@ static int create_restore_volatile(struct hsm_copyaction_private *hcp, snprintf(parent, sizeof(parent), "%s", ct->mnt); } - fd = llapi_create_volatile_idx(parent, mdt_index, open_flags); + if (hcp->source_fd < 0) { + fd = llapi_create_volatile_idx(parent, mdt_index, open_flags); + } else { + /* We need to insert source_fd in volatile file name, so open + * it manually. + */ + char file_path[PATH_MAX]; + unsigned int rnumber; + + do { + rnumber = random(); + if (mdt_index == -1) + rc = snprintf(file_path, sizeof(file_path), + "%s/"LUSTRE_VOLATILE_HDR"::%.4X:fd=%.2d", + parent, rnumber, hcp->source_fd); + else + rc = snprintf(file_path, sizeof(file_path), + "%s/"LUSTRE_VOLATILE_HDR":%.4X:%.4X:fd=%.2d", + parent, mdt_index, rnumber, hcp->source_fd); + if (rc < 0 || rc >= sizeof(file_path)) { + fd = -ENAMETOOLONG; + break; + } + + /* + * Either open O_WRONLY or O_RDWR, creating RDONLY + * is non-sensical here. + */ + if ((open_flags & O_ACCMODE) == O_RDONLY) + open_flags = O_RDWR | (open_flags & ~O_ACCMODE); + open_flags |= O_CREAT | O_EXCL | O_NOFOLLOW; + fd = open(file_path, open_flags, S_IRUSR | S_IWUSR); + if (fd < 0) + rc = -errno; + else + (void)unlink(file_path); + } while (fd < 0 && rc == -EEXIST); + } if (fd < 0) return fd; @@ -1130,8 +1167,26 @@ int llapi_hsm_action_begin(struct hsm_copyaction_private **phcp, if (rc < 0) goto err_out; + /* Use source_fd to store fd of Lustre file identified by fid. + * This fd is appended to volatile file name, useful in case + * of encrypted file in order to copy encryption context. + */ + hcp->source_fd = ct_open_by_fid(hcp->ct_priv, &hai->hai_dfid, + O_RDONLY | O_NOATIME | O_NOFOLLOW | O_NONBLOCK); + if (hcp->source_fd < 0) { + rc = hcp->source_fd; + goto err_out; + } + rc = create_restore_volatile(hcp, restore_mdt_index, restore_open_flags); + /* Now that volatile file has been created, + * source_fd can be closed. + */ + if (hcp->source_fd >= 0) { + close(hcp->source_fd); + hcp->source_fd = -1; + } if (rc < 0) goto err_out; } else if (hai->hai_action == HSMA_REMOVE) { -- 1.8.3.1