* \param archive_count
* \param archives Which archive numbers this copytool is responsible for
*/
-int llapi_hsm_copytool_start(void **priv, char *fsname, int flags,
- int archive_count, int *archives)
+int llapi_hsm_copytool_start(struct hsm_copytool_private **priv, char *fsname,
+ int flags, int archive_count, int *archives)
{
struct hsm_copytool_private *ct;
int rc;
ct->kuc.lk_data = ct->archives;
rc = root_ioctl(ct->fsname, LL_IOC_HSM_CT_START, &(ct->kuc), NULL,
WANT_ERROR);
- /* ignore if it was already registered on coordinator */
- if (rc == -EEXIST)
- rc = 0;
/* Only the kernel reference keeps the write side open */
close(ct->kuc.lk_wfd);
ct->kuc.lk_wfd = 0;
if (rc < 0)
- goto out_err;
+ goto out_kuc;
*priv = ct;
return 0;
+out_kuc:
+ /* cleanup the kuc channel */
+ libcfs_ukuc_stop(&ct->kuc);
out_err:
if (ct->fsname)
free(ct->fsname);
* killed), the libcfs module will be referenced and unremovable,
* even after Lustre services stop.
*/
-int llapi_hsm_copytool_fini(void **priv)
+int llapi_hsm_copytool_fini(struct hsm_copytool_private **priv)
{
struct hsm_copytool_private *ct;
- ct = (struct hsm_copytool_private *)priv;
+ ct = *priv;
if (!ct || (ct->magic != CT_PRIV_MAGIC))
return -EINVAL;
}
/** Wait for the next hsm_action_list
- * \param priv Opaque private control structure
+ * \param ct Opaque private control structure
* \param halh Action list handle, will be allocated here
* \param msgsize Number of bytes in the message, will be set here
* \return 0 valid message received; halh and msgsize are set
* <0 error code
*/
-int llapi_hsm_copytool_recv(void *priv, struct hsm_action_list **halh,
- int *msgsize)
+int llapi_hsm_copytool_recv(struct hsm_copytool_private *ct,
+ struct hsm_action_list **halh, int *msgsize)
{
- struct hsm_copytool_private *ct;
struct kuc_hdr *kuch;
struct hsm_action_list *hal;
int rc = 0;
- ct = (struct hsm_copytool_private *)priv;
if (!ct || (ct->magic != CT_PRIV_MAGIC))
return -EINVAL;
if (halh == NULL || msgsize == NULL)
/* Check that we have registered for this archive #
* if 0 registered, we serve any archive */
if (ct->archives &&
- ((1 << (hal->hal_archive_num - 1)) & ct->archives) == 0) {
+ ((1 << (hal->hal_archive_id - 1)) & ct->archives) == 0) {
llapi_err_noerrno(LLAPI_MSG_INFO,
"This copytool does not service archive #%d,"
" ignoring this request."
" Mask of served archive is 0x%.8X",
- hal->hal_archive_num, ct->archives);
+ hal->hal_archive_id, ct->archives);
rc = -EAGAIN;
goto out_free;
return rc;
rc = ioctl(fd, LL_IOC_HSM_COPY_START, copy);
+ /* If error, return errno value */
+ rc = rc ? -errno : 0;
close(fd);
return rc;
copy->hc_errval = hp->hp_errval;
/* Update hai if it has changed since start */
copy->hc_hai.hai_extent = hp->hp_extent;
+ /* In some cases, like restore, 2 FIDs are used. hp knows the right FID
+ * to use here. */
+ copy->hc_hai.hai_fid = hp->hp_fid;
rc = get_root_path(WANT_FD, NULL, &fd, mnt, -1);
if (rc)
goto out_free;
rc = ioctl(fd, LL_IOC_HSM_COPY_END, copy);
+ /* If error, return errno value */
+ rc = rc ? -errno : 0;
close(fd);
out_free:
* be used.
* \param newfid[out] Filled with new Lustre fid.
*/
-int llapi_hsm_import(const char *dst, int archive, struct stat *st,
+int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
unsigned long long stripe_size, int stripe_offset,
int stripe_count, int stripe_pattern, char *pool_name,
lustre_fid *newfid)
{
- struct utimbuf time;
- int fd;
- int rc = 0;
+ struct hsm_user_import hui;
+ int fd;
+ int rc = 0;
- /* Create a non-striped file */
- fd = open(dst, O_CREAT | O_EXCL | O_LOV_DELAY_CREATE | O_NONBLOCK,
- st->st_mode);
+ if (stripe_pattern == 0)
+ stripe_pattern = LOV_PATTERN_RAID0;
- if (fd < 0)
+ /* Create a non-striped file */
+ fd = llapi_file_open_pool(dst, O_CREAT | O_WRONLY, st->st_mode,
+ stripe_size, stripe_offset, stripe_count,
+ stripe_pattern | LOV_PATTERN_F_RELEASED,
+ pool_name);
+ if (fd < 0) {
+ llapi_error(LLAPI_MSG_ERROR, -errno,
+ "cannot create '%s' for import", dst);
return -errno;
- close(fd);
-
- /* set size on MDT */
- if (truncate(dst, st->st_size) != 0) {
- rc = -errno;
- goto out_unlink;
}
- /* Mark archived */
- rc = llapi_hsm_state_set(dst, HS_EXISTS | HS_RELEASED | HS_ARCHIVED, 0,
- archive);
- if (rc)
- goto out_unlink;
- /* Get the new fid in the archive. Caller needs to use this fid
+ /* Get the new fid in Lustre. Caller needs to use this fid
from now on. */
- rc = llapi_path2fid(dst, newfid);
- if (rc)
+ rc = llapi_fd2fid(fd, newfid);
+ if (rc != 0) {
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "cannot get fid of '%s' for import", dst);
goto out_unlink;
+ }
- /* Copy the file attributes */
- time.actime = st->st_atime;
- time.modtime = st->st_mtime;
- if (utime(dst, &time) == -1 ||
- chmod(dst, st->st_mode) == -1 ||
- chown(dst, st->st_uid, st->st_gid) == -1) {
- /* we might fail here because we change perms/owner */
+ hui.hui_uid = st->st_uid;
+ hui.hui_gid = st->st_gid;
+ hui.hui_mode = st->st_mode;
+ hui.hui_size = st->st_size;
+ hui.hui_archive_id = archive;
+ hui.hui_atime = st->st_atime;
+ hui.hui_atime_ns = st->st_atim.tv_nsec;
+ hui.hui_mtime = st->st_mtime;
+ hui.hui_mtime_ns = st->st_mtim.tv_nsec;
+ rc = ioctl(fd, LL_IOC_HSM_IMPORT, &hui);
+ if (rc != 0) {
+ llapi_error(LLAPI_MSG_ERROR, rc, "cannot import '%s'", dst);
rc = -errno;
goto out_unlink;
}
out_unlink:
+ if (fd >= 0)
+ close(fd);
if (rc)
unlink(dst);
return rc;
* \retval 0 on success.
* \retval -errno on error.
*/
+int llapi_hsm_state_get_fd(int fd, struct hsm_user_state *hus)
+{
+ int rc;
+
+ rc = ioctl(fd, LL_IOC_HSM_STATE_GET, hus);
+ /* If error, save errno value */
+ rc = rc ? -errno : 0;
+
+ return rc;
+}
+
+/**
+ * Return the current HSM states and HSM requests related to file pointed by \a
+ * path.
+ *
+ * see llapi_hsm_state_get_fd() for args use and return
+ */
int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
{
int fd;
if (fd < 0)
return -errno;
- rc = ioctl(fd, LL_IOC_HSM_STATE_GET, hus);
- /* If error, save errno value */
- rc = rc ? -errno : 0;
+ rc = llapi_hsm_state_get_fd(fd, hus);
close(fd);
return rc;
}
/**
- * Set HSM states of file pointed by \a path.
+ * Set HSM states of file pointed by \a fd
*
* Using the provided bitmasks, the current HSM states for this file will be
* changed. \a archive_id could be used to change the archive number also. Set
* \retval 0 on success.
* \retval -errno on error.
*/
-int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
- __u32 archive_id)
+int llapi_hsm_state_set_fd(int fd, __u64 setmask, __u64 clearmask,
+ __u32 archive_id)
{
- struct hsm_state_set hss;
- int fd;
- int rc;
-
- fd = open(path, O_WRONLY | O_LOV_DELAY_CREATE | O_NONBLOCK);
- if (fd < 0)
- return -errno;
+ struct hsm_state_set hss;
+ int rc;
hss.hss_valid = HSS_SETMASK|HSS_CLEARMASK;
hss.hss_setmask = setmask;
/* If error, save errno value */
rc = rc ? -errno : 0;
- close(fd);
return rc;
}
+/**
+ * Set HSM states of file pointed by \a path.
+ *
+ * see llapi_hsm_state_set_fd() for args use and return
+ */
+int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
+ __u32 archive_id)
+{
+ int fd;
+ int rc;
+
+ fd = open(path, O_WRONLY | O_LOV_DELAY_CREATE | O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
+
+ rc = llapi_hsm_state_set_fd(fd, setmask, clearmask, archive_id);
+
+ close(fd);
+ return rc;
+}
/**
* Return the current HSM request related to file pointed by \a path.
return rc;
}
+/**
+ * Allocate a hsm_user_request with the specified carateristics.
+ * This structure should be freed with free().
+ *
+ * \return an allocated structure on success, NULL otherwise.
+ */
+struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
+ int data_len)
+{
+ int len = 0;
+
+ len += sizeof(struct hsm_user_request);
+ len += sizeof(struct hsm_user_item) * itemcount;
+ len += data_len;
+
+ return (struct hsm_user_request *)malloc(len);
+}
+
+/**
+ * Send a HSM request to Lustre, described in \param request.
+ *
+ * This request should be allocated with llapi_hsm_user_request_alloc().
+ *
+ * \param mnt Should be the Lustre moint point.
+ * \return 0 on success, an error code otherwise.
+ */
+int llapi_hsm_request(char *mnt, struct hsm_user_request *request)
+{
+ int rc;
+ int fd;
+
+ rc = get_root_path(WANT_FD, NULL, &fd, mnt, -1);
+ if (rc)
+ return rc;
+
+ rc = ioctl(fd, LL_IOC_HSM_REQUEST, request);
+ /* If error, save errno value */
+ rc = rc ? -errno : 0;
+
+ close(fd);
+ return rc;
+}
+