Whamcloud - gitweb
LU-3363 api: HSM import uses new released pattern
[fs/lustre-release.git] / lustre / utils / liblustreapi_hsm.c
index f065359..5d08949 100644 (file)
@@ -76,8 +76,8 @@ struct hsm_copytool_private {
  * \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;
@@ -128,18 +128,18 @@ int llapi_hsm_copytool_start(void **priv, char *fsname, int flags,
        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);
@@ -152,11 +152,11 @@ out_err:
  * 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;
 
@@ -174,21 +174,19 @@ int llapi_hsm_copytool_fini(void **priv)
 }
 
 /** 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)
@@ -235,12 +233,12 @@ int llapi_hsm_copytool_recv(void *priv, struct hsm_action_list **halh,
        /* 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;
@@ -291,6 +289,8 @@ int llapi_hsm_copy_start(char *mnt, struct hsm_copy *copy,
                return rc;
 
        rc = ioctl(fd, LL_IOC_HSM_COPY_START, copy);
+       /* If error, return errno value */
+       rc = rc ? -errno : 0;
        close(fd);
 
        return rc;
@@ -340,12 +340,17 @@ int llapi_hsm_copy_end(char *mnt, struct hsm_copy *copy,
        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:
@@ -392,58 +397,62 @@ int llapi_hsm_progress(char *mnt, struct hsm_progress *hp)
  *                 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;
 }
 
-
 /**
  * Return the current HSM states and HSM requests related to file pointed by \a
  * path.
@@ -454,6 +463,23 @@ out_unlink:
  * \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;
@@ -463,16 +489,14 @@ int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
        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
@@ -485,16 +509,11 @@ int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
  * \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;
@@ -509,6 +528,95 @@ int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
        /* If error, save errno value */
        rc = rc ? -errno : 0;
 
+       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.
+ *
+ * \param hca  Should be allocated by caller. Will be filled with current file
+ *             actions.
+ *
+ * \retval 0 on success.
+ * \retval -errno on error.
+ */
+int llapi_hsm_current_action(const char *path, struct hsm_current_action *hca)
+{
+       int fd;
+       int rc;
+
+       fd = open(path, O_RDONLY | O_NONBLOCK);
+       if (fd < 0)
+               return -errno;
+
+       rc = ioctl(fd, LL_IOC_HSM_ACTION, hca);
+       /* If error, save errno value */
+       rc = rc ? -errno : 0;
+
+       close(fd);
+       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;
 }