From 159ccd46747f91f6236c99b6d24edaf6a1351ced Mon Sep 17 00:00:00 2001 From: frank zago Date: Tue, 27 Feb 2018 11:12:16 -0500 Subject: [PATCH] LU-6081 user: adding llapi_create_volatile_param() This new function is similar to the existing llapi_create_volatile_idx() function, but takes 2 additional parameters: a stripe information, and a file mode. llapi_create_volatile_idx() is changed to use llapi_create_volatile_param(). Include a new man page for llapi_create_volatile_param(), llapi_create_volatile_idx() and llapi_create_volatile_param(). Signed-off-by: frank zago Change-Id: Ia50750d68b8cfa335b53b114a20fccaed49c75cd Reviewed-on: https://review.whamcloud.com/13242 Tested-by: Jenkins Reviewed-by: John L. Hammond Reviewed-by: Patrick Farrell Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/doc/Makefile.am | 1 + lustre/doc/llapi_create_volatile_param.3 | 54 ++++++++++++++ lustre/include/lustre/lustreapi.h | 10 ++- lustre/utils/liblustreapi.c | 123 +++++++++++++++++++++---------- 4 files changed, 146 insertions(+), 42 deletions(-) create mode 100644 lustre/doc/llapi_create_volatile_param.3 diff --git a/lustre/doc/Makefile.am b/lustre/doc/Makefile.am index b446a29..812adbd 100644 --- a/lustre/doc/Makefile.am +++ b/lustre/doc/Makefile.am @@ -59,6 +59,7 @@ MANFILES = \ l_getidentity.8 \ lgss_sk.8 \ lhbadm.8 \ + llapi_create_volatile_param.3 \ llapi_fd2parent.3 \ llapi_file_create.3 \ llapi_file_get_stripe.3 \ diff --git a/lustre/doc/llapi_create_volatile_param.3 b/lustre/doc/llapi_create_volatile_param.3 new file mode 100644 index 0000000..7ba2fdf --- /dev/null +++ b/lustre/doc/llapi_create_volatile_param.3 @@ -0,0 +1,54 @@ +.TH llapi_create_volatile_param 3 "2015-01-14" "" "Lustre User API" +.SH NAME +llapi_create_volatile_param \- Lustre API file management +.SH SYNOPSIS +.sp +\fB#include \fP +.sp +\fBint llapi_create_volatile_param(const char *\fPdirectory\fB, +int\fP mdt_idx\fB, int\fP open_flags\fB, mode_t\fP mode\fB, const +struct llapi_stripe_param *\fPstripe_param\fB)\fP +.sp +\fBint llapi_create_volatile_idx(char *\fPdirectory\fB, int\fP idx\fB, int\fP open_flags\fB)\fP +.sp +\fBint llapi_create_volatile(char *\fPdirectory\fB, int\fP mode\fB)\fP +.SH DESCRIPTION +.sp +These three functions create an anonymous, temporary, volatile file on +a Lustre filesystem. The created file is not visible with +\fBls(1)\fP\&. Once the file is closed, or the owning process dies, the +file is permanently removed from the filesystem. +.sp +These functions will also work on a non\-Lustre filesystem, where the +file is created then unlinked, leaving only the file descriptor to +access the file. This is not strictly equivalent because there is a +small window during which the file is visible to users (provided they +have access to the \fIdirectory\fP). +.sp +The \fIdirectory\fP parameter indicates where to create the file on the +Lustre filesystem. +.sp +\fImdt_idx\fP is the MDT index onto which to create the file. To use a +default MDT, set mdt_idx to \-1. +.sp +\fIopen_flags\fP and \fImode\fP are the same as \fBopen(2)\fP\&. +.sp +\fIstripe_param\fP describes the striping information. If it is NULL, then +the default for the directory is used. +.SH RETURN VALUE +.sp +\fBllapi_create_volatile_param\fP, \fBllapi_create_volatile_idx\fP and +\fBllapi_create_volatile\fP return a file descriptor on success. They +all return a negative errno on failure. +.SH ERRORS +.sp +The negative errno can be, but is not limited to: +.sp +\fB\-EINVAL\fP An invalid value was passed. +.sp +\fB\-ENOMEM\fP Not enough memory to allocate a resource. +.SH SEE ALSO +.sp +\fBlustreapi\fP(7) +.SH AUTHOR +Frank Zago for Cray Inc. diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index aa9a290..b593f7f 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -404,11 +404,15 @@ void llapi_hsm_log_error(enum llapi_message_level level, int _rc, const char *fmt, va_list args); int llapi_get_agent_uuid(char *path, char *buf, size_t bufsize); -int llapi_create_volatile_idx(char *directory, int idx, int mode); +int llapi_create_volatile_idx(const char *directory, int mdt_idx, + int open_flags); +int llapi_create_volatile_param(const char *directory, int mdt_idx, + int open_flags, mode_t mode, + const struct llapi_stripe_param *stripe_param); -static inline int llapi_create_volatile(char *directory, int mode) +static inline int llapi_create_volatile(char *directory, int open_flags) { - return llapi_create_volatile_idx(directory, -1, mode); + return llapi_create_volatile_idx(directory, -1, open_flags); } diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index f37dca0..77ab9e7 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -5252,75 +5252,120 @@ int llapi_get_ost_layout_version(int fd, __u32 *layout_version) } /* - * Create a file without any name open it for read/write + * Create a file without any name and open it for read/write * * - file is created as if it were a standard file in the given \a directory * - file does not appear in \a directory and mtime does not change because * the filename is handled specially by the Lustre MDS. - * - file is removed at final close - * - file modes are rw------- since it doesn't make sense to have a read-only - * or write-only file that cannot be opened again. - * - if user wants another mode it must use fchmod() on the open file, no - * security problems arise because it cannot be opened by another process. + * - file is destroyed at final close * * \param[in] directory directory from which to inherit layout/MDT idx - * \param[in] idx MDT index on which the file is created, + * \param[in] mdt_idx MDT index on which the file is created, * \a idx == -1 means no specific MDT is requested - * \param[in] open_flags standard open(2) flags + * \param[in] mode standard open(2) mode + * \param[in] stripe_param stripe parameters. May be NULL. * - * \retval 0 on success. + * \retval a file descriptor on success. * \retval -errno on error. */ -int llapi_create_volatile_idx(char *directory, int idx, int open_flags) +int llapi_create_volatile_param(const char *directory, int mdt_idx, + int open_flags, mode_t mode, + const struct llapi_stripe_param *stripe_param) { - char file_path[PATH_MAX]; - char filename[PATH_MAX]; - int saved_errno = errno; - int fd; - int rnumber; - int rc; + char file_path[PATH_MAX]; + int saved_errno = errno; + int fd; + unsigned int rnumber; + int rc; do { rnumber = random(); - if (idx == -1) - snprintf(filename, sizeof(filename), - LUSTRE_VOLATILE_HDR"::%.4X", rnumber); + if (mdt_idx == -1) + rc = snprintf(file_path, sizeof(file_path), + "%s/" LUSTRE_VOLATILE_HDR "::%.4X", + directory, rnumber); else - snprintf(filename, sizeof(filename), - LUSTRE_VOLATILE_HDR":%.4X:%.4X", idx, rnumber); + rc = snprintf(file_path, sizeof(file_path), + "%s/" LUSTRE_VOLATILE_HDR ":%.4X:%.4X", + directory, mdt_idx, rnumber); + + if (rc < 0 || rc >= sizeof(file_path)) + return -ENAMETOOLONG; - rc = snprintf(file_path, sizeof(file_path), - "%s/%s", directory, filename); - if (rc >= sizeof(file_path)) - return -E2BIG; + /* + * 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); - fd = open(file_path, - O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | open_flags, - S_IRUSR | S_IWUSR); - } while (fd < 0 && errno == EEXIST); + open_flags |= O_CREAT | O_EXCL | O_NOFOLLOW; + + if (stripe_param != NULL) { + fd = llapi_file_open_param(file_path, open_flags, + mode, stripe_param); + if (fd < 0) + rc = fd; + } else { + fd = open(file_path, open_flags, mode); + if (fd < 0) + rc = -errno; + } + } while (fd < 0 && rc == -EEXIST); if (fd < 0) { - llapi_error(LLAPI_MSG_ERROR, errno, + llapi_error(LLAPI_MSG_ERROR, rc, "Cannot create volatile file '%s' in '%s'", - filename + LUSTRE_VOLATILE_HDR_LEN, + file_path + strlen(directory) + 1 + + LUSTRE_VOLATILE_HDR_LEN, directory); - return -errno; + return rc; } - /* Unlink file in case this wasn't a Lustre filesystem and the - * magic volatile filename wasn't handled as intended. The - * effect is the same. If volatile open was supported then we - * expect unlink() to return -ENOENT. */ + /* + * Unlink file in case this wasn't a Lustre filesystem and the magic + * volatile filename wasn't handled as intended. The effect is the + * same. If volatile open was supported then we expect unlink() to + * return -ENOENT. + */ (void)unlink(file_path); - /* Since we are returning successfully we restore errno (and - * mask out possible EEXIST from open() and ENOENT from - * unlink(). */ + /* + * Since we are returning successfully we restore errno (and + * mask out possible EEXIST from open() and ENOENT from unlink(). + */ errno = saved_errno; return fd; } +/* + * Create a file without any name open it for read/write + * + * - file is created as if it were a standard file in the given \a directory + * - file does not appear in \a directory and mtime does not change because + * the filename is handled specially by the Lustre MDS. + * - file is removed at final close + * - file modes are rw------- since it doesn't make sense to have a read-only + * or write-only file that cannot be opened again. + * - if user wants another mode it must use fchmod() on the open file, no + * security problems arise because it cannot be opened by another process. + * + * \param[in] directory directory from which to inherit layout/MDT idx + * \param[in] idx MDT index on which the file is created, + * \a idx == -1 means no specific MDT is requested + * \param[in] open_flags standard open(2) flags + * + * \retval a file descriptor on success. + * \retval -errno on error. + */ +int llapi_create_volatile_idx(const char *directory, int mdt_idx, + int open_flags) +{ + return llapi_create_volatile_param(directory, mdt_idx, open_flags, + S_IRUSR | S_IWUSR, NULL); +} + /** * Swap the layouts between 2 file descriptors * the 2 files must be open for writing -- 1.8.3.1