Whamcloud - gitweb
LU-2061 hsm: get list of HSM actions
authorAurelien Degremont <aurelien.degremont@cea.fr>
Wed, 18 Apr 2012 15:05:59 +0000 (17:05 +0200)
committerOleg Drokin <green@whamcloud.com>
Wed, 30 Jan 2013 22:51:33 +0000 (17:51 -0500)
This patch implements a MDS RPC to get
the list of registered and running hsm actions on files

It implements:
- lfs hsm_action

The matching llapi call:
- llapi_hsm_current_action()

The matching MDS function:
- mdt_hsm_action()

and MDS RPC:
- MDS_HSM_ACTION

Signed-off-by: JC Lafoucriere <jacques-charles.lafoucriere@cea.fr>
Change-Id: If4b00949ca8c94c8572cc81a7f7b8db32914542c
Reviewed-on: http://review.whamcloud.com/5029
Reviewed-by: Johann Lombardi <johann.lombardi@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
21 files changed:
lustre/doc/lfs-hsm.1
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre/lustreapi.h
lustre/include/lustre_req_layout.h
lustre/include/obd_support.h
lustre/llite/file.c
lustre/lmv/lmv_obd.c
lustre/mdc/mdc_request.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_hsm.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_mds.c
lustre/ptlrpc/layout.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/wiretest.c
lustre/utils/lfs.c
lustre/utils/liblustreapi_hsm.c
lustre/utils/req-layout.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 72e2d76..580d921 100644 (file)
@@ -6,6 +6,9 @@ lfs commands used to interact with HSM features
 .B lfs hsm_state
 .RB <FILE> ...
 .br
+.B  lfs hsm_action
+.RI file
+.br
 .B  lfs hsm_set|hsm_clear
 .RB [ --norelease ]
 .RB [ --noarchive ]
@@ -26,6 +29,9 @@ Set provided HSM flags on file list.
 .TP
 .B lfs hsm_clear <FILE>...
 Clear the HSM related flags on file list.
+.TP
+.B lfs hsm_action <FILE>...
+Display the in-progress HSM actions for provided files.
 .PP
 Non-privileged user can only change the following flags:
 .B norelease
index 4cf77c8..e75d288 100644 (file)
@@ -3333,6 +3333,8 @@ struct hsm_progress_kernel {
        __u64                   hpk_padding2;
 } __attribute__((packed));
 
+extern void lustre_swab_hsm_user_state(struct hsm_user_state *hus);
+extern void lustre_swab_hsm_current_action(struct hsm_current_action *action);
 extern void lustre_swab_hsm_progress_kernel(struct hsm_progress_kernel *hpk);
 extern void lustre_swab_hsm_user_state(struct hsm_user_state *hus);
 extern void lustre_swab_hsm_user_item(struct hsm_user_item *hui);
index 1e8ecca..b98c6ed 100644 (file)
@@ -163,6 +163,10 @@ struct obd_statfs {
 #define LL_IOC_HSM_PROGRESS            _IOW('f', 216, struct hsm_user_request)
 #define LL_IOC_HSM_REQUEST             _IOW('f', 217, struct hsm_user_request)
 #define LL_IOC_DATA_VERSION            _IOR('f', 218, struct ioc_data_version)
+/*     219 is reserved for swap layouts */
+#define LL_IOC_HSM_ACTION              _IOR('f', 220, \
+                                               struct hsm_current_action)
+/* see <lustre_lib.h> for ioctl numbers 221-232 */
 
 #define LL_STATFS_LMV           1
 #define LL_STATFS_LOV           2
@@ -814,6 +818,19 @@ struct hsm_state_set_ioc {
        __u64           hssi_clearmask;
 };
 
+/*
+ * This structure describes the current in-progress action for a file.
+ * it is retuned to user space and send over the wire
+ */
+struct hsm_current_action {
+       /**  The current undergoing action, if there is one */
+       /* state is one of hsm_progress_states */
+       __u32                   hca_state;
+       /* action is one of hsm_user_action */
+       __u32                   hca_action;
+       struct hsm_extent       hca_location;
+};
+
 /***** HSM user requests ******/
 /* User-generated (lfs/ioctl) request types */
 enum hsm_user_action {
index 15ace62..1d10f7f 100644 (file)
@@ -286,7 +286,9 @@ extern int llapi_hsm_import(const char *dst, int archive, struct stat *st,
                            unsigned long long stripe_size, int stripe_offset,
                            int stripe_count, int stripe_pattern,
                            char *pool_name, lustre_fid *newfid);
-
+/* HSM user interface */
+extern int llapi_hsm_current_action(const char *path,
+                                   struct hsm_current_action *hca);
 /** @} llapi */
 
 #endif
index 7e3c55d..9d1d2be 100644 (file)
@@ -189,6 +189,7 @@ extern struct req_format RQF_QUOTA_DQACQ;
 /* MDS hsm formats */
 extern struct req_format RQF_MDS_HSM_STATE_GET;
 extern struct req_format RQF_MDS_HSM_STATE_SET;
+extern struct req_format RQF_MDS_HSM_ACTION;
 extern struct req_format RQF_MDS_HSM_PROGRESS;
 extern struct req_format RQF_MDS_HSM_CT_REGISTER;
 extern struct req_format RQF_MDS_HSM_CT_UNREGISTER;
@@ -284,6 +285,7 @@ extern struct req_msg_field RMF_MDS_HSM_USER_ITEM;
 extern struct req_msg_field RMF_MDS_HSM_ARCHIVE;
 extern struct req_msg_field RMF_HSM_USER_STATE;
 extern struct req_msg_field RMF_HSM_STATE_SET;
+extern struct req_msg_field RMF_MDS_HSM_CURRENT_ACTION;
 
 /* seq-mgr fields */
 extern struct req_msg_field RMF_SEQ_OPC;
index e59a41b..76838f0 100644 (file)
@@ -239,6 +239,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 #define OBD_FAIL_MDS_HSM_REQUEST_NET           0x14c
 #define OBD_FAIL_MDS_HSM_CT_REGISTER_NET       0x14d
 #define OBD_FAIL_MDS_HSM_CT_UNREGISTER_NET     0x14e
+#define OBD_FAIL_MDS_HSM_ACTION_NET            0x150
 
 /* layout lock */
 #define OBD_FAIL_MDS_NO_LL_GETATTR      0x170
index 8d04d4e..067261b 100644 (file)
@@ -2009,12 +2009,37 @@ long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                OBD_FREE_PTR(hss);
                RETURN(rc);
        }
+       case LL_IOC_HSM_ACTION: {
+               struct md_op_data               *op_data;
+               struct hsm_current_action       *hca;
+               int                              rc;
 
+               OBD_ALLOC_PTR(hca);
+               if (hca == NULL)
+                       RETURN(-ENOMEM);
+
+               op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+                                            LUSTRE_OPC_ANY, hca);
+               if (op_data == NULL) {
+                       OBD_FREE_PTR(hca);
+                       RETURN(-ENOMEM);
+               }
+
+               rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
+                                  op_data, NULL);
+
+               if (cfs_copy_to_user((char *)arg, hca, sizeof(*hca)))
+                       rc = -EFAULT;
+
+               ll_finish_md_op_data(op_data);
+               OBD_FREE_PTR(hca);
+               RETURN(rc);
+       }
        default: {
                int err;
 
                if (LLIOC_STOP ==
-                       ll_iocontrol_call(inode, file, cmd, arg, &err))
+                    ll_iocontrol_call(inode, file, cmd, arg, &err))
                        RETURN(err);
 
                RETURN(obd_iocontrol(cmd, ll_i2dtexp(inode), 0, NULL,
index 8a79475..8fa6a3e 100644 (file)
@@ -865,7 +865,8 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
                break;
        }
        case LL_IOC_HSM_STATE_GET:
-       case LL_IOC_HSM_STATE_SET: {
+       case LL_IOC_HSM_STATE_SET:
+       case LL_IOC_HSM_ACTION: {
                struct md_op_data       *op_data = karg;
                struct lmv_tgt_desc     *tgt;
 
index dd4339c..2853268 100644 (file)
@@ -1253,6 +1253,50 @@ out:
        return rc;
 }
 
+static int mdc_ioc_hsm_current_action(struct obd_export *exp,
+                                     struct md_op_data *op_data)
+{
+       struct hsm_current_action       *hca = op_data->op_data;
+       struct hsm_current_action       *req_hca;
+       struct ptlrpc_request           *req;
+       int                              rc;
+       ENTRY;
+
+       req = ptlrpc_request_alloc(class_exp2cliimp(exp),
+                                  &RQF_MDS_HSM_ACTION);
+       if (req == NULL)
+               RETURN(-ENOMEM);
+
+       mdc_set_capa_size(req, &RMF_CAPA1, op_data->op_capa1);
+
+       rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_HSM_ACTION);
+       if (rc) {
+               ptlrpc_request_free(req);
+               RETURN(rc);
+       }
+
+       mdc_pack_body(req, &op_data->op_fid1, op_data->op_capa1,
+                     OBD_MD_FLRMTPERM, 0, op_data->op_suppgids[0], 0);
+
+       ptlrpc_request_set_replen(req);
+
+       rc = ptlrpc_queue_wait(req);
+       if (rc)
+               GOTO(out, rc);
+
+       req_hca = req_capsule_server_get(&req->rq_pill,
+                                        &RMF_MDS_HSM_CURRENT_ACTION);
+       if (req_hca == NULL)
+               GOTO(out, rc = -EPROTO);
+
+       *hca = *req_hca;
+
+       EXIT;
+out:
+       ptlrpc_req_finished(req);
+       return rc;
+}
+
 static int mdc_ioc_hsm_ct_unregister(struct obd_import *imp)
 {
        struct ptlrpc_request   *req;
@@ -1656,6 +1700,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                GOTO(out, rc);
        case LL_IOC_HSM_STATE_SET:
                rc = mdc_ioc_hsm_state_set(exp, karg);
+       case LL_IOC_HSM_ACTION:
+               rc = mdc_ioc_hsm_current_action(exp, karg);
                GOTO(out, rc);
         case OBD_IOC_CLIENT_RECOVER:
                 rc = ptlrpc_recover_import(imp, data->ioc_inlbuf1, 0);
index 236b94c..7f10bc4 100644 (file)
@@ -3106,6 +3106,7 @@ static int mdt_msg_check_version(struct lustre_msg *msg)
        case MDS_HSM_CT_UNREGISTER:
        case MDS_HSM_STATE_GET:
        case MDS_HSM_STATE_SET:
+       case MDS_HSM_ACTION:
         case MDS_QUOTACHECK:
         case MDS_QUOTACTL:
         case QUOTA_DQACQ:
index 7a21ccb..3dc19b9 100644 (file)
@@ -69,6 +69,12 @@ static int mdt_hsm_agent_unregister(struct mdt_thread_info *info,
        return 0;
 }
 
+static int mdt_hsm_coordinator_get_actions(struct mdt_thread_info *mti,
+                                          struct hsm_action_list *hal)
+{
+       return 0;
+}
+
 /**
  * Update on-disk HSM attributes.
  */
@@ -305,3 +311,96 @@ out_obj:
        mdt_object_unlock(info, obj, lh, 1);
        return rc;
 }
+
+/**
+ * Retrieve undergoing HSM requests for the fid provided in RPC body.
+ * Current requests are read from coordinator states.
+ *
+ * This is MDS_HSM_ACTION RPC handler.
+ */
+int mdt_hsm_action(struct mdt_thread_info *info)
+{
+       struct hsm_current_action       *hca;
+       struct hsm_action_list          *hal = NULL;
+       struct hsm_action_item          *hai;
+       int                              rc, len;
+       ENTRY;
+
+       /* Only valid if client is remote */
+       rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
+       if (rc)
+               RETURN(rc = err_serious(rc));
+
+       if (req_capsule_get_size(info->mti_pill, &RMF_CAPA1, RCL_CLIENT))
+               mdt_set_capainfo(info, 0, &info->mti_body->fid1,
+                                req_capsule_client_get(info->mti_pill,
+                                                       &RMF_CAPA1));
+
+       hca = req_capsule_server_get(info->mti_pill,
+                                    &RMF_MDS_HSM_CURRENT_ACTION);
+       LASSERT(hca);
+
+       /* Coordinator information */
+       len = sizeof(*hal) + MTI_NAME_MAXLEN /* fsname */ +
+               cfs_size_round(sizeof(*hai));
+
+       OBD_ALLOC(hal, len);
+       if (hal == NULL)
+               GOTO(out_ucred, -ENOMEM);
+
+       hal->hal_version = HAL_VERSION;
+       hal->hal_archive_num = 0;
+       hal->hal_flags = 0;
+       obd_uuid2fsname(hal->hal_fsname, mdt2obd_dev(info->mti_mdt)->obd_name,
+                       MTI_NAME_MAXLEN);
+       hal->hal_count = 1;
+       hai = hai_zero(hal);
+       hai->hai_action = HSMA_NONE;
+       hai->hai_cookie = 0;
+       hai->hai_gid = 0;
+       hai->hai_fid = info->mti_body->fid1;
+       hai->hai_len = sizeof(*hai);
+
+       rc = mdt_hsm_coordinator_get_actions(info, hal);
+       if (rc)
+               GOTO(out_free, rc);
+
+       /* cookie is used to give back request status */
+       if (hai->hai_cookie == 0)
+               hca->hca_state = HPS_WAITING;
+       else
+               hca->hca_state = HPS_RUNNING;
+
+       switch (hai->hai_action) {
+       case HSMA_NONE:
+               hca->hca_action = HUA_NONE;
+               break;
+       case HSMA_ARCHIVE:
+               hca->hca_action = HUA_ARCHIVE;
+               break;
+       case HSMA_RESTORE:
+               hca->hca_action = HUA_RESTORE;
+               break;
+       case HSMA_REMOVE:
+               hca->hca_action = HUA_REMOVE;
+               break;
+       case HSMA_CANCEL:
+               hca->hca_action = HUA_CANCEL;
+               break;
+       default:
+               hca->hca_action = HUA_NONE;
+               CERROR("%s: Unknown hsm action: %d on "DFID"\n",
+                      mdt2obd_dev(info->mti_mdt)->obd_name,
+                      hai->hai_action, PFID(&hai->hai_fid));
+               break;
+       }
+
+       hca->hca_location = hai->hai_extent;
+
+       EXIT;
+out_free:
+       OBD_FREE(hal, len);
+out_ucred:
+       mdt_exit_ucred(info);
+       return rc;
+}
index a612392..19e92bb 100644 (file)
@@ -773,14 +773,13 @@ __u32 mdt_identity_get_perm(struct md_identity *, __u32, lnet_nid_t);
 int mdt_pack_remote_perm(struct mdt_thread_info *, struct mdt_object *, void *);
 
 /* mdt/mdt_hsm.c */
+int mdt_hsm_state_get(struct mdt_thread_info *info);
+int mdt_hsm_state_set(struct mdt_thread_info *info);
+int mdt_hsm_action(struct mdt_thread_info *info);
 int mdt_hsm_progress(struct mdt_thread_info *info);
 int mdt_hsm_ct_register(struct mdt_thread_info *info);
 int mdt_hsm_ct_unregister(struct mdt_thread_info *info);
 
-/* mdt/mdt_hsm.c */
-int mdt_hsm_state_get(struct mdt_thread_info *info);
-int mdt_hsm_state_set(struct mdt_thread_info *info);
-
 extern struct lu_context_key       mdt_thread_key;
 /* debug issues helper starts here*/
 static inline int mdt_fail_write(const struct lu_env *env,
index 49a87dd..8bef043 100644 (file)
@@ -151,6 +151,8 @@ DEF_MDT_HDL(HABEO_CORPUS| HABEO_REFERO, MDS_HSM_STATE_GET,
                                                mdt_hsm_state_get),
 DEF_MDT_HDL(HABEO_CORPUS| HABEO_REFERO, MDS_HSM_STATE_SET,
                                                mdt_hsm_state_set),
+DEF_MDT_HDL(HABEO_CORPUS| HABEO_REFERO, MDS_HSM_ACTION,
+                                               mdt_hsm_action),
 };
 
 #define DEF_OBD_HDL(flags, name, fn)                                   \
index 0af7276..2044bab 100644 (file)
@@ -596,6 +596,11 @@ static const struct req_msg_field *mdt_hsm_ct_register[] = {
        &RMF_MDS_HSM_ARCHIVE,
 };
 
+static const struct req_msg_field *mdt_hsm_action_server[] = {
+       &RMF_PTLRPC_BODY,
+       &RMF_MDS_HSM_CURRENT_ACTION,
+};
+
 static const struct req_msg_field *mdt_hsm_state_get_server[] = {
        &RMF_PTLRPC_BODY,
        &RMF_HSM_USER_STATE,
@@ -652,6 +657,7 @@ static struct req_format *req_formats[] = {
        &RQF_MDS_HSM_CT_UNREGISTER,
        &RQF_MDS_HSM_STATE_GET,
        &RQF_MDS_HSM_STATE_SET,
+       &RQF_MDS_HSM_ACTION,
         &RQF_QC_CALLBACK,
         &RQF_OST_CONNECT,
         &RQF_OST_DISCONNECT,
@@ -1045,6 +1051,11 @@ struct req_msg_field RMF_MDS_HSM_PROGRESS =
                    lustre_swab_hsm_progress_kernel, NULL);
 EXPORT_SYMBOL(RMF_MDS_HSM_PROGRESS);
 
+struct req_msg_field RMF_MDS_HSM_CURRENT_ACTION =
+       DEFINE_MSGF("hsm_current_action", 0, sizeof(struct hsm_current_action),
+                   lustre_swab_hsm_current_action, NULL);
+EXPORT_SYMBOL(RMF_MDS_HSM_CURRENT_ACTION);
+
 struct req_msg_field RMF_MDS_HSM_USER_ITEM =
        DEFINE_MSGF("hsm_user_item", RMF_F_STRUCT_ARRAY,
                    sizeof(struct hsm_user_item), lustre_swab_hsm_user_item,
@@ -1355,6 +1366,10 @@ struct req_format RQF_MDS_READPAGE =
                         mdt_body_capa, mdt_body_only);
 EXPORT_SYMBOL(RQF_MDS_READPAGE);
 
+struct req_format RQF_MDS_HSM_ACTION =
+       DEFINE_REQ_FMT0("MDS_HSM_ACTION", mdt_body_capa, mdt_hsm_action_server);
+EXPORT_SYMBOL(RQF_MDS_HSM_ACTION);
+
 struct req_format RQF_MDS_HSM_PROGRESS =
        DEFINE_REQ_FMT0("MDS_HSM_PROGRESS", mdt_hsm_progress, empty);
 EXPORT_SYMBOL(RQF_MDS_HSM_PROGRESS);
index f814abe..05d422d 100644 (file)
@@ -2499,6 +2499,14 @@ void lustre_swab_hsm_extent(struct hsm_extent *extent)
        __swab64s(&extent->length);
 }
 
+void lustre_swab_hsm_current_action(struct hsm_current_action *action)
+{
+       __swab32s(&action->hca_state);
+       __swab32s(&action->hca_action);
+       lustre_swab_hsm_extent(&action->hca_location);
+}
+EXPORT_SYMBOL(lustre_swab_hsm_current_action);
+
 void lustre_swab_hsm_user_item(struct hsm_user_item *hui)
 {
        lustre_swab_lu_fid(&hui->hui_fid);
index a4e2dcd..67f4304 100644 (file)
@@ -4366,5 +4366,21 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct hsm_state_set, hss_clearmask));
        LASSERTF((int)sizeof(((struct hsm_state_set *)0)->hss_clearmask) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct hsm_state_set *)0)->hss_clearmask));
+
+       /* Checks for struct hsm_current_action */
+       LASSERTF((int)sizeof(struct hsm_current_action) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_current_action));
+       LASSERTF((int)offsetof(struct hsm_current_action, hca_state) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_current_action, hca_state));
+       LASSERTF((int)sizeof(((struct hsm_current_action *)0)->hca_state) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_current_action *)0)->hca_state));
+       LASSERTF((int)offsetof(struct hsm_current_action, hca_action) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_current_action, hca_action));
+       LASSERTF((int)sizeof(((struct hsm_current_action *)0)->hca_action) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_current_action *)0)->hca_action));
+       LASSERTF((int)offsetof(struct hsm_current_action, hca_location) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_current_action, hca_location));
+       LASSERTF((int)sizeof(((struct hsm_current_action *)0)->hca_location) == 16, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_current_action *)0)->hca_location));
 }
 
index ef99892..5c6f1ca 100644 (file)
@@ -107,6 +107,7 @@ static int lfs_data_version(int argc, char **argv);
 static int lfs_hsm_state(int argc, char **argv);
 static int lfs_hsm_set(int argc, char **argv);
 static int lfs_hsm_clear(int argc, char **argv);
+static int lfs_hsm_action(int argc, char **argv);
 
 /* all avaialable commands */
 command_t cmdlist[] = {
@@ -250,6 +251,8 @@ command_t cmdlist[] = {
         "files.\n"
         "usage: hsm_clear [--norelease] [--noarchive] [--dirty] [--exists] "
         "[--archived] [--lost] <file> ..."},
+       {"hsm_action", lfs_hsm_action, 0, "Display current HSM request for "
+        "given files.\n" "usage: hsm_action <file> ..."},
         {"help", Parser_help, 0, "help"},
         {"exit", Parser_quit, 0, "quit"},
         {"quit", Parser_quit, 0, "quit"},
@@ -2739,7 +2742,7 @@ static int lfs_hsm_state(int argc, char **argv)
                if (rc) {
                        fprintf(stderr, "can't get hsm state for %s: %s\n",
                                path, strerror(errno = -rc));
-                       return rc;
+                       return rc;
                }
 
                /* Display path name and status flags */
@@ -2854,6 +2857,56 @@ static int lfs_hsm_change_flags(int argc, char **argv, int mode)
        return 0;
 }
 
+static int lfs_hsm_action(int argc, char **argv)
+{
+       int                              rc;
+       int                              i = 1;
+       char                            *path;
+       struct hsm_current_action        hca;
+       struct hsm_extent                he;
+       enum hsm_user_action             hua;
+       enum hsm_progress_states         hps;
+
+       if (argc < 2)
+               return CMD_HELP;
+
+       do {
+               path = argv[i];
+
+               rc = llapi_hsm_current_action(path, &hca);
+               if (rc) {
+                       fprintf(stderr, "can't get hsm action for %s: %s\n",
+                               path, strerror(errno = -rc));
+                       return rc;
+               }
+               he = hca.hca_location;
+               hua = hca.hca_action;
+               hps = hca.hca_state;
+
+               printf("%s: %s", path, hsm_user_action2name(hua));
+
+               /* Skip file without action */
+               if (hca.hca_action == HUA_NONE) {
+                       printf("\n");
+                       continue;
+               }
+
+               printf(" %s ", hsm_progress_state2name(hps));
+
+               if ((hps == HPS_RUNNING) &&
+                   (hua == HUA_ARCHIVE || hua == HUA_RESTORE))
+                       printf("("LPX64 " bytes moved)\n", he.length);
+               else if ((he.offset + he.length) == OBD_OBJECT_EOF)
+                       printf("(from "LPX64 " to EOF)\n", he.offset);
+               else
+                       printf("(from "LPX64 " to "LPX64")\n",
+                              he.offset, he.offset + he.length);
+
+       } while (++i < argc);
+
+       return 0;
+}
+
 static int lfs_hsm_set(int argc, char **argv)
 {
        return lfs_hsm_change_flags(argc, argv, LFS_HSM_SET);
index f065359..3bf8cfa 100644 (file)
@@ -443,7 +443,6 @@ out_unlink:
        return rc;
 }
 
-
 /**
  * Return the current HSM states and HSM requests related to file pointed by \a
  * path.
@@ -513,3 +512,30 @@ int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
        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;
+}
+
index da0f131..c45eb2a 100644 (file)
@@ -87,6 +87,7 @@
 #define lustre_swab_hsm_user_item NULL
 #define lustre_swab_hsm_user_state NULL
 #define lustre_swab_hsm_state_set NULL
+#define lustre_swab_hsm_current_action NULL
 #define dump_rniobuf NULL
 #define dump_ioo NULL
 #define dump_obdo NULL
index 99de60b..913f72b 100644 (file)
@@ -1967,6 +1967,16 @@ check_hsm_state_set(void)
 }
 
 static void
+check_hsm_current_action(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(hsm_current_action);
+       CHECK_MEMBER(hsm_current_action, hca_state);
+       CHECK_MEMBER(hsm_current_action, hca_action);
+       CHECK_MEMBER(hsm_current_action, hca_location);
+}
+
+static void
 system_string (char *cmdline, char *str, int len)
 {
        int   fds[2];
@@ -2333,6 +2343,7 @@ main(int argc, char **argv)
        check_hsm_user_item();
        check_hsm_user_state();
        check_hsm_state_set();
+       check_hsm_current_action();
 
        printf("}\n\n");
 
index 2ac64cd..95a32d5 100644 (file)
@@ -4374,5 +4374,21 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct hsm_state_set, hss_clearmask));
        LASSERTF((int)sizeof(((struct hsm_state_set *)0)->hss_clearmask) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct hsm_state_set *)0)->hss_clearmask));
+
+       /* Checks for struct hsm_current_action */
+       LASSERTF((int)sizeof(struct hsm_current_action) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_current_action));
+       LASSERTF((int)offsetof(struct hsm_current_action, hca_state) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_current_action, hca_state));
+       LASSERTF((int)sizeof(((struct hsm_current_action *)0)->hca_state) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_current_action *)0)->hca_state));
+       LASSERTF((int)offsetof(struct hsm_current_action, hca_action) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_current_action, hca_action));
+       LASSERTF((int)sizeof(((struct hsm_current_action *)0)->hca_action) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_current_action *)0)->hca_action));
+       LASSERTF((int)offsetof(struct hsm_current_action, hca_location) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_current_action, hca_location));
+       LASSERTF((int)sizeof(((struct hsm_current_action *)0)->hca_location) == 16, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_current_action *)0)->hca_location));
 }