Whamcloud - gitweb
LU-2061 hsm: send HSM resquest to CDT
authorjcl <jacques-charles.lafoucriere@cea.fr>
Thu, 10 Jan 2013 17:42:12 +0000 (18:42 +0100)
committerOleg Drokin <green@whamcloud.com>
Wed, 30 Jan 2013 23:05:29 +0000 (18:05 -0500)
This patch implements the user interface to ask for hsm requests

It implements:
- lfs hsm_archive
- lfs hsm_restore
- lfs hsm_cancel
- lfs hsm_remove
- lfs hsm_release

The matching llapi call:
- llapi_hsm_user_request_alloc()
- llapi_hsm_request()

related MDS functions:
- mdt_hsm_request()

and the MDS RPC:
- MDS_HSM_REQUEST

Signed-off-by: JC Lafoucriere <jacques-charles.lafoucriere@cea.fr>
Change-Id: I635f6e0518ec12c359dbb528c3a61216650d952d
Reviewed-on: http://review.whamcloud.com/5030
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>
19 files changed:
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre/lustreapi.h
lustre/include/lustre_req_layout.h
lustre/llite/dir.c
lustre/mdc/lproc_mdc.c
lustre/mdc/mdc_request.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/tests/copytool.c
lustre/utils/lfs.c
lustre/utils/liblustreapi_hsm.c
lustre/utils/req-layout.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index e75d288..9b3a848 100644 (file)
@@ -3338,6 +3338,6 @@ 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);
-
+extern void lustre_swab_hsm_request(struct hsm_request *hr);
 #endif
 /** @} lustreidl */
index b98c6ed..686d4e9 100644 (file)
@@ -855,35 +855,52 @@ static inline char *hsm_user_action2name(enum hsm_user_action  a)
         }
 }
 
+/*
+ * List of hr_flags (bit field)
+ */
+#define HSM_FORCE_ACTION 0x0001
+/* used by CT, connot be set by user */
+#define HSM_GHOST_COPY   0x0002
+
+/**
+ * Contains all the fixed part of struct hsm_user_request.
+ *
+ */
+struct hsm_request {
+       __u32 hr_action;        /* enum hsm_user_action */
+       __u32 hr_archive_id;    /* archive id, used only with HUA_ARCHIVE */
+       __u64 hr_flags;         /* request flags */
+       __u32 hr_itemcount;     /* item count in hur_user_item vector */
+       __u32 hr_data_len;
+};
+
 struct hsm_user_item {
        lustre_fid        hui_fid;
        struct hsm_extent hui_extent;
 } __attribute__((packed));
 
 struct hsm_user_request {
-        __u32 hur_action;    /* enum hsm_user_action */
-        __u32 hur_archive_num; /* archive number, used only with HUA_ARCHIVE */
-        __u32 hur_itemcount;
-        __u32 hur_data_len;
-        struct hsm_user_item hur_user_item[0];
-        /* extra data blob at end of struct (after all
-         * hur_user_items), only use helpers to access it
-         */
+       struct hsm_request      hur_request;
+       struct hsm_user_item    hur_user_item[0];
+       /* extra data blob at end of struct (after all
+        * hur_user_items), only use helpers to access it
+        */
 } __attribute__((packed));
 
 /** Return pointer to data field in a hsm user request */
 static inline void *hur_data(struct hsm_user_request *hur)
 {
-        return &(hur->hur_user_item[hur->hur_itemcount]);
+       return &(hur->hur_user_item[hur->hur_request.hr_itemcount]);
 }
 
 /** Compute the current length of the provided hsm_user_request. */
 static inline int hur_len(struct hsm_user_request *hur)
 {
-        int data_offset;
+       int data_offset;
 
-        data_offset = hur_data(hur) - (void *)hur;
-        return (data_offset + hur->hur_data_len);
+       data_offset = hur_data(hur) - (void *)hur;
+       data_offset += hur->hur_request.hr_data_len;
+       return data_offset;
 }
 
 /****** HSM RPCs to copytool *****/
@@ -963,7 +980,7 @@ struct hsm_action_list {
        __u32 hal_count;       /* number of hai's to follow */
        __u64 hal_compound_id; /* returned by coordinator */
        __u64 hal_flags;
-       __u32 hal_archive_num; /* which archive backend */
+       __u32 hal_archive_id; /* which archive backend */
        __u32 padding1;
        char  hal_fsname[0];   /* null-terminated */
        /* struct hsm_action_item[hal_count] follows, aligned on 8-byte
index 1d10f7f..c7a2bb1 100644 (file)
@@ -278,15 +278,16 @@ extern int llapi_hsm_copy_start(char *mnt, struct hsm_copy *copy,
                                const struct hsm_action_item *hai);
 extern int llapi_hsm_copy_end(char *mnt, struct hsm_copy *copy,
                              const struct hsm_progress *hp);
-extern int llapi_hsm_request(char *mnt, struct hsm_user_request *request);
 extern int llapi_hsm_progress(char *mnt, struct hsm_progress *hp);
-extern struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
-                                                            int data_len);
 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 struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
+                                                            int data_len);
+extern int llapi_hsm_request(char *mnt, struct hsm_user_request *request);
 extern int llapi_hsm_current_action(const char *path,
                                    struct hsm_current_action *hca);
 /** @} llapi */
index 9d1d2be..f2d65cc 100644 (file)
@@ -193,6 +193,7 @@ 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;
+extern struct req_format RQF_MDS_HSM_REQUEST;
 /* OST req_format */
 extern struct req_format RQF_OST_CONNECT;
 extern struct req_format RQF_OST_DISCONNECT;
@@ -286,6 +287,7 @@ 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;
+extern struct req_msg_field RMF_MDS_HSM_REQUEST;
 
 /* seq-mgr fields */
 extern struct req_msg_field RMF_SEQ_OPC;
index 1fef702..d0cfb2a 100644 (file)
@@ -1630,6 +1630,40 @@ out_free:
                 RETURN(rc);
         case OBD_IOC_FID2PATH:
                RETURN(ll_fid2path(inode, (void *)arg));
+       case LL_IOC_HSM_REQUEST: {
+               struct hsm_user_request *hur;
+               int                      totalsize;
+
+               OBD_ALLOC_PTR(hur);
+               if (hur == NULL)
+                       RETURN(-ENOMEM);
+
+               /* We don't know the true size yet; copy the fixed-size part */
+               if (cfs_copy_from_user(hur, (void *)arg, sizeof(*hur))) {
+                       OBD_FREE_PTR(hur);
+                       RETURN(-EFAULT);
+               }
+
+               /* Compute the whole struct size */
+               totalsize = hur_len(hur);
+               OBD_FREE_PTR(hur);
+               OBD_ALLOC_LARGE(hur, totalsize);
+               if (hur == NULL)
+                       RETURN(-ENOMEM);
+
+               /* Copy the whole struct */
+               if (cfs_copy_from_user(hur, (void *)arg, totalsize)) {
+                       OBD_FREE_LARGE(hur, totalsize);
+                       RETURN(-EFAULT);
+               }
+
+               rc = obd_iocontrol(cmd, ll_i2mdexp(inode), totalsize,
+                                  hur, NULL);
+
+               OBD_FREE_LARGE(hur, totalsize);
+
+               RETURN(rc);
+       }
        case LL_IOC_HSM_PROGRESS: {
                struct hsm_progress_kernel      hpk;
                struct hsm_progress             hp;
index 509fd59..7d4fa12 100644 (file)
@@ -108,7 +108,7 @@ static int mdc_wr_kuc(struct file *file, const char *buffer,
 
        hal = (struct hsm_action_list *)(lh + 1);
        hal->hal_version = HAL_VERSION;
-       hal->hal_archive_num = 1;
+       hal->hal_archive_id = 1;
        hal->hal_flags = 0;
        obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN);
 
index 2853268..ec9a6d4 100644 (file)
@@ -1322,7 +1322,6 @@ static int mdc_ioc_hsm_state_get(struct obd_export *exp,
                                 struct md_op_data *op_data)
 {
        struct hsm_user_state   *hus = op_data->op_data;
-       struct obd_import       *imp = class_exp2cliimp(exp);
        struct hsm_user_state   *req_hus;
        struct ptlrpc_request   *req;
        int                      rc;
@@ -1347,12 +1346,8 @@ static int mdc_ioc_hsm_state_get(struct obd_export *exp,
        ptlrpc_request_set_replen(req);
 
        rc = ptlrpc_queue_wait(req);
-       if (rc) {
-               /* check connection error first */
-               if (imp->imp_connect_error)
-                       rc = imp->imp_connect_error;
+       if (rc)
                GOTO(out, rc);
-       }
 
        req_hus = req_capsule_server_get(&req->rq_pill, &RMF_HSM_USER_STATE);
        if (req_hus == NULL)
@@ -1370,7 +1365,6 @@ static int mdc_ioc_hsm_state_set(struct obd_export *exp,
                                 struct md_op_data *op_data)
 {
        struct hsm_state_set    *hss = op_data->op_data;
-       struct obd_import       *imp = class_exp2cliimp(exp);
        struct hsm_state_set    *req_hss;
        struct ptlrpc_request   *req;
        int                      rc;
@@ -1400,12 +1394,7 @@ static int mdc_ioc_hsm_state_set(struct obd_export *exp,
        ptlrpc_request_set_replen(req);
 
        rc = ptlrpc_queue_wait(req);
-       if (rc) {
-               /* check connection error first */
-               if (imp->imp_connect_error)
-                       rc = imp->imp_connect_error;
-               GOTO(out, rc);
-       }
+       GOTO(out, rc);
 
        EXIT;
 out:
@@ -1413,6 +1402,60 @@ out:
        return rc;
 }
 
+static int mdc_ioc_hsm_request(struct obd_export *exp,
+                              struct hsm_user_request *hur)
+{
+       struct obd_import       *imp = class_exp2cliimp(exp);
+       struct ptlrpc_request   *req;
+       struct hsm_request      *req_hr;
+       struct hsm_user_item    *req_hui;
+       char                    *req_opaque;
+       int                      rc;
+       ENTRY;
+
+       req = ptlrpc_request_alloc(imp, &RQF_MDS_HSM_REQUEST);
+       if (req == NULL)
+               GOTO(out, rc = -ENOMEM);
+
+       req_capsule_set_size(&req->rq_pill, &RMF_MDS_HSM_USER_ITEM, RCL_CLIENT,
+                            hur->hur_request.hr_itemcount
+                            * sizeof(struct hsm_user_item));
+       req_capsule_set_size(&req->rq_pill, &RMF_GENERIC_DATA, RCL_CLIENT,
+                            hur->hur_request.hr_data_len);
+
+       rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_HSM_REQUEST);
+       if (rc) {
+               ptlrpc_request_free(req);
+               RETURN(rc);
+       }
+
+       mdc_pack_body(req, NULL, NULL, OBD_MD_FLRMTPERM, 0, 0, 0);
+
+       /* Copy hsm_request struct */
+       req_hr = req_capsule_client_get(&req->rq_pill, &RMF_MDS_HSM_REQUEST);
+       LASSERT(req_hr);
+       *req_hr = hur->hur_request;
+
+       /* Copy hsm_user_item structs */
+       req_hui = req_capsule_client_get(&req->rq_pill, &RMF_MDS_HSM_USER_ITEM);
+       LASSERT(req_hui);
+       memcpy(req_hui, hur->hur_user_item,
+              hur->hur_request.hr_itemcount * sizeof(struct hsm_user_item));
+
+       /* Copy opaque field */
+       req_opaque = req_capsule_client_get(&req->rq_pill, &RMF_GENERIC_DATA);
+       LASSERT(req_opaque);
+       memcpy(req_opaque, hur_data(hur), hur->hur_request.hr_data_len);
+
+       ptlrpc_request_set_replen(req);
+
+       rc = ptlrpc_queue_wait(req);
+       GOTO(out, rc);
+
+out:
+       ptlrpc_req_finished(req);
+       return rc;
+}
 
 static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags)
 {
@@ -1703,6 +1746,9 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
        case LL_IOC_HSM_ACTION:
                rc = mdc_ioc_hsm_current_action(exp, karg);
                GOTO(out, rc);
+       case LL_IOC_HSM_REQUEST:
+               rc = mdc_ioc_hsm_request(exp, karg);
+               GOTO(out, rc);
         case OBD_IOC_CLIENT_RECOVER:
                 rc = ptlrpc_recover_import(imp, data->ioc_inlbuf1, 0);
                 if (rc < 0)
@@ -1868,7 +1914,7 @@ static void lustre_swab_hal(struct hsm_action_list *h)
 
        __swab32s(&h->hal_version);
        __swab32s(&h->hal_count);
-       __swab32s(&h->hal_archive_num);
+       __swab32s(&h->hal_archive_id);
        __swab64s(&h->hal_flags);
        hai = hai_zero(h);
        for (i = 0; i < h->hal_count; i++) {
index 3dc19b9..face836 100644 (file)
@@ -75,6 +75,14 @@ static int mdt_hsm_coordinator_get_actions(struct mdt_thread_info *mti,
        return 0;
 }
 
+static int mdt_hsm_coordinator_actions(struct mdt_thread_info *info,
+                                      struct hsm_action_list *hal,
+                                      __u64 *compound_id,
+                                      int mti_attr_is_valid)
+{
+       return 0;
+}
+
 /**
  * Update on-disk HSM attributes.
  */
@@ -349,7 +357,7 @@ int mdt_hsm_action(struct mdt_thread_info *info)
                GOTO(out_ucred, -ENOMEM);
 
        hal->hal_version = HAL_VERSION;
-       hal->hal_archive_num = 0;
+       hal->hal_archive_id = 0;
        hal->hal_flags = 0;
        obd_uuid2fsname(hal->hal_fsname, mdt2obd_dev(info->mti_mdt)->obd_name,
                        MTI_NAME_MAXLEN);
@@ -404,3 +412,110 @@ out_ucred:
        mdt_exit_ucred(info);
        return rc;
 }
+
+/**
+ * Process the HSM actions described in a struct hsm_user_request.
+ *
+ * The action described in hur will be send to coordinator to be saved and
+ * processed later or either handled directly if hur.hur_action is HUA_RELEASE.
+ *
+ * This is MDS_HSM_REQUEST RPC handler.
+ */
+int mdt_hsm_request(struct mdt_thread_info *info)
+{
+       struct req_capsule              *pill = info->mti_pill;
+       struct mdt_body                 *body;
+       struct hsm_request              *hr;
+       struct hsm_user_item            *hui;
+       struct hsm_action_list          *hal;
+       struct hsm_action_item          *hai;
+       char                            *opaque;
+       enum hsm_copytool_action         action = HSMA_NONE;
+       __u64                            compound_id;
+       int                              len, i, rc;
+       ENTRY;
+
+       body = req_capsule_client_get(pill, &RMF_MDT_BODY);
+       LASSERT(body);
+
+       hr = req_capsule_client_get(pill, &RMF_MDS_HSM_REQUEST);
+       LASSERT(hr);
+
+       hui = req_capsule_client_get(pill, &RMF_MDS_HSM_USER_ITEM);
+       LASSERT(hui);
+
+       opaque = req_capsule_client_get(pill, &RMF_GENERIC_DATA);
+       LASSERT(opaque);
+
+       /* Sanity check. Nothing to do with an empty list */
+       if (hr->hr_itemcount == 0)
+               RETURN(0);
+
+       /* Only valid if client is remote */
+       rc = mdt_init_ucred(info, body);
+       if (rc)
+               RETURN(err_serious(rc));
+
+       switch (hr->hr_action) {
+       /* code to be removed in hsm1_merge and final patch */
+       case HUA_RELEASE:
+               CERROR("Release action is not working in hsm1_coord\n");
+               GOTO(out_ucred, rc = -EINVAL);
+               break;
+       /* end of code to be removed */
+       case HUA_ARCHIVE:
+               action = HSMA_ARCHIVE;
+               break;
+       case HUA_RESTORE:
+               action = HSMA_RESTORE;
+               break;
+       case HUA_REMOVE:
+               action = HSMA_REMOVE;
+               break;
+       case HUA_CANCEL:
+               action = HSMA_CANCEL;
+               break;
+       default:
+               CERROR("Unknown hsm action: %d\n", hr->hr_action);
+               GOTO(out_ucred, rc = -EINVAL);
+       }
+
+       len = sizeof(*hal) + MTI_NAME_MAXLEN /* fsname */ +
+               cfs_size_round(sizeof(*hai) * hr->hr_itemcount) +
+               cfs_size_round(hr->hr_data_len * hr->hr_itemcount);
+
+       OBD_ALLOC(hal, len);
+       if (hal == NULL)
+               GOTO(out_ucred, rc = -ENOMEM);
+
+       hal->hal_version = HAL_VERSION;
+       hal->hal_archive_id = hr->hr_archive_id;
+       hal->hal_flags = hr->hr_flags;
+       obd_uuid2fsname(hal->hal_fsname, mdt2obd_dev(info->mti_mdt)->obd_name,
+                       MTI_NAME_MAXLEN);
+
+       hal->hal_count = hr->hr_itemcount;
+       hai = hai_zero(hal);
+       for (i = 0; i < hr->hr_itemcount; i++) {
+               hai->hai_action = action;
+               hai->hai_cookie = 0;
+               hai->hai_gid = 0;
+               hai->hai_fid = hui[i].hui_fid;
+               hai->hai_extent = hui[i].hui_extent;
+               memcpy(hai->hai_data, opaque, hr->hr_data_len);
+               hai->hai_len = sizeof(*hai) + hr->hr_data_len;
+               hai = hai_next(hai);
+       }
+
+       rc = mdt_hsm_coordinator_actions(info, hal, &compound_id, 0);
+       /* ENODATA error code is needed only for implicit requests */
+       if (rc == -ENODATA)
+               rc = 0;
+
+       OBD_FREE(hal, len);
+       EXIT;
+out_ucred:
+       mdt_exit_ucred(info);
+       return rc;
+}
+
index 19e92bb..9abfbe6 100644 (file)
@@ -779,6 +779,7 @@ 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);
+int mdt_hsm_request(struct mdt_thread_info *info);
 
 extern struct lu_context_key       mdt_thread_key;
 /* debug issues helper starts here*/
index 8bef043..0a15bd3 100644 (file)
@@ -151,8 +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),
+DEF_MDT_HDL(HABEO_CORPUS| HABEO_REFERO, MDS_HSM_ACTION, mdt_hsm_action),
+DEF_MDT_HDL(0          | HABEO_REFERO, MDS_HSM_REQUEST, mdt_hsm_request),
 };
 
 #define DEF_OBD_HDL(flags, name, fn)                                   \
index 2044bab..2903d1e 100644 (file)
@@ -613,6 +613,14 @@ static const struct req_msg_field *mdt_hsm_state_set[] = {
        &RMF_HSM_STATE_SET,
 };
 
+static const struct req_msg_field *mdt_hsm_request[] = {
+       &RMF_PTLRPC_BODY,
+       &RMF_MDT_BODY,
+       &RMF_MDS_HSM_REQUEST,
+       &RMF_MDS_HSM_USER_ITEM,
+       &RMF_GENERIC_DATA,
+};
+
 static struct req_format *req_formats[] = {
         &RQF_OBD_PING,
         &RQF_OBD_SET_INFO,
@@ -658,6 +666,7 @@ static struct req_format *req_formats[] = {
        &RQF_MDS_HSM_STATE_GET,
        &RQF_MDS_HSM_STATE_SET,
        &RQF_MDS_HSM_ACTION,
+       &RQF_MDS_HSM_REQUEST,
         &RQF_QC_CALLBACK,
         &RQF_OST_CONNECT,
         &RQF_OST_DISCONNECT,
@@ -1067,6 +1076,11 @@ struct req_msg_field RMF_MDS_HSM_ARCHIVE =
                    sizeof(__u32), lustre_swab_generic_32s, NULL);
 EXPORT_SYMBOL(RMF_MDS_HSM_ARCHIVE);
 
+struct req_msg_field RMF_MDS_HSM_REQUEST =
+       DEFINE_MSGF("hsm_request", 0, sizeof(struct hsm_request),
+                   lustre_swab_hsm_request, NULL);
+EXPORT_SYMBOL(RMF_MDS_HSM_REQUEST);
+
 /*
  * Request formats.
  */
@@ -1391,6 +1405,10 @@ struct req_format RQF_MDS_HSM_STATE_SET =
        DEFINE_REQ_FMT0("MDS_HSM_STATE_SET", mdt_hsm_state_set, empty);
 EXPORT_SYMBOL(RQF_MDS_HSM_STATE_SET);
 
+struct req_format RQF_MDS_HSM_REQUEST =
+       DEFINE_REQ_FMT0("MDS_HSM_REQUEST", mdt_hsm_request, empty);
+EXPORT_SYMBOL(RQF_MDS_HSM_REQUEST);
+
 /* This is for split */
 struct req_format RQF_MDS_WRITEPAGE =
         DEFINE_REQ_FMT0("MDS_WRITEPAGE",
index 05d422d..fb8a810 100644 (file)
@@ -2534,3 +2534,13 @@ void lustre_swab_hsm_progress_kernel(struct hsm_progress_kernel *hpk)
 }
 EXPORT_SYMBOL(lustre_swab_hsm_progress_kernel);
 
+void lustre_swab_hsm_request(struct hsm_request *hr)
+{
+       __swab32s(&hr->hr_action);
+       __swab32s(&hr->hr_archive_id);
+       __swab64s(&hr->hr_flags);
+       __swab32s(&hr->hr_itemcount);
+       __swab32s(&hr->hr_data_len);
+}
+EXPORT_SYMBOL(lustre_swab_hsm_request);
+
index 67f4304..b14eb56 100644 (file)
@@ -4209,10 +4209,10 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct hsm_action_list, hal_flags));
        LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_flags) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_flags));
-       LASSERTF((int)offsetof(struct hsm_action_list, hal_archive_num) == 24, "found %lld\n",
-                (long long)(int)offsetof(struct hsm_action_list, hal_archive_num));
-       LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_archive_num) == 4, "found %lld\n",
-                (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_archive_num));
+       LASSERTF((int)offsetof(struct hsm_action_list, hal_archive_id) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_action_list, hal_archive_id));
+       LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_archive_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_archive_id));
        LASSERTF((int)offsetof(struct hsm_action_list, padding1) == 28, "found %lld\n",
                 (long long)(int)offsetof(struct hsm_action_list, padding1));
        LASSERTF((int)sizeof(((struct hsm_action_list *)0)->padding1) == 4, "found %lld\n",
@@ -4382,5 +4382,45 @@ void lustre_assert_wire_constants(void)
                 (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));
+
+       /* Checks for struct hsm_request */
+       LASSERTF((int)sizeof(struct hsm_request) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_request));
+       LASSERTF((int)offsetof(struct hsm_request, hr_action) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_action));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_action) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_action));
+       LASSERTF((int)offsetof(struct hsm_request, hr_archive_id) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_archive_id));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_archive_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_archive_id));
+       LASSERTF((int)offsetof(struct hsm_request, hr_flags) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_flags));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_flags) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_flags));
+       LASSERTF((int)offsetof(struct hsm_request, hr_itemcount) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_itemcount));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_itemcount) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_itemcount));
+       LASSERTF((int)offsetof(struct hsm_request, hr_data_len) == 20, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_data_len));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_data_len) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_data_len));
+       LASSERTF(HSM_FORCE_ACTION == 0x00000001UL, "found 0x%.8xUL\n",
+               (unsigned)HSM_FORCE_ACTION);
+       LASSERTF(HSM_GHOST_COPY == 0x00000002UL, "found 0x%.8xUL\n",
+               (unsigned)HSM_GHOST_COPY);
+
+       /* Checks for struct hsm_user_request */
+       LASSERTF((int)sizeof(struct hsm_user_request) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_user_request));
+       LASSERTF((int)offsetof(struct hsm_user_request, hur_request) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_request, hur_request));
+       LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_request) == 24, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_request));
+       LASSERTF((int)offsetof(struct hsm_user_request, hur_user_item) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_request, hur_user_item));
+       LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_user_item) == 0, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_user_item));
 }
 
index 1e17584..9f66168 100644 (file)
@@ -110,34 +110,34 @@ int main(int argc, char **argv) {
         signal(SIGINT, handler);
 
         while(1) {
-                struct hsm_action_list *hal;
-                struct hsm_action_item *hai;
-                int msgsize, i = 0;
+               struct hsm_action_list *hal;
+               struct hsm_action_item *hai;
+               int msgsize, i = 0;
 
                rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
-                if (rc == -ESHUTDOWN) {
-                        fprintf(stderr, "shutting down");
-                        break;
-                }
-                if (rc < 0) {
-                        fprintf(stderr, "Message receive: %s", strerror(-rc));
-                        break;
-                }
-                if (msgsize == 0)
-                        continue; /* msg not for us */
-
-                printf("Copytool fs=%s archive#=%d item_count=%d\n",
-                       hal->hal_fsname, hal->hal_archive_num, hal->hal_count);
-
-                hai = hai_zero(hal);
-                while (++i <= hal->hal_count) {
-                        printf("Item %d: action %d reclen %d\n", i,
-                               hai->hai_action, hai->hai_len);
-                        printf(" "DFID" gid="LPU64" cookie="LPU64"\n",
-                               PFID(&hai->hai_fid), hai->hai_gid,
-                               hai->hai_cookie);
-                        hai = hai_next(hai);
-                }
+               if (rc == -ESHUTDOWN) {
+                       fprintf(stderr, "shutting down");
+                       break;
+               }
+               if (rc < 0) {
+                       fprintf(stderr, "Message receive: %s", strerror(-rc));
+                       break;
+               }
+               if (msgsize == 0)
+                       continue; /* msg not for us */
+
+               printf("Copytool fs=%s archive#=%d item_count=%d\n",
+                       hal->hal_fsname, hal->hal_archive_id, hal->hal_count);
+
+               hai = hai_zero(hal);
+               while (++i <= hal->hal_count) {
+                       printf("Item %d: action %d reclen %d\n", i,
+                               hai->hai_action, hai->hai_len);
+                       printf(" "DFID" gid="LPU64" cookie="LPU64"\n",
+                               PFID(&hai->hai_fid), hai->hai_gid,
+                               hai->hai_cookie);
+                       hai = hai_next(hai);
+               }
 
                llapi_hsm_copytool_free(&hal);
         }
index 5c6f1ca..7662063 100644 (file)
@@ -108,6 +108,12 @@ 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);
+static int lfs_hsm_archive(int argc, char **argv);
+static int lfs_hsm_restore(int argc, char **argv);
+static int lfs_hsm_release(int argc, char **argv);
+static int lfs_hsm_remove(int argc, char **argv);
+static int lfs_hsm_cancel(int argc, char **argv);
+
 
 /* all avaialable commands */
 command_t cmdlist[] = {
@@ -253,6 +259,22 @@ command_t cmdlist[] = {
         "[--archived] [--lost] <file> ..."},
        {"hsm_action", lfs_hsm_action, 0, "Display current HSM request for "
         "given files.\n" "usage: hsm_action <file> ..."},
+       {"hsm_archive", lfs_hsm_archive, 0,
+        "Archive file to external storage.\n"
+        "usage: hsm_archive [--filelist FILELIST] [--data DATA] [--archive NUM] "
+        "<file> ..."},
+       {"hsm_restore", lfs_hsm_restore, 0,
+        "Restore file from external storage.\n"
+        "usage: hsm_restore [--filelist FILELIST] [--data DATA] <file> ..."},
+       {"hsm_release", lfs_hsm_release, 0,
+        "Release files from Lustre.\n"
+        "usage: hsm_release [--filelist FILELIST] [--data DATA] <file> ..."},
+       {"hsm_remove", lfs_hsm_remove, 0,
+        "Remove file copy from external storage.\n"
+        "usage: hsm_remove [--filelist FILELIST] [--data DATA] <file> ..."},
+       {"hsm_cancel", lfs_hsm_cancel, 0,
+        "Cancel requests related to specified files.\n"
+        "usage: hsm_cancel [--filelist FILELIST] [--data DATA] <file> ..."},
         {"help", Parser_help, 0, "help"},
         {"exit", Parser_quit, 0, "quit"},
         {"quit", Parser_quit, 0, "quit"},
@@ -2917,6 +2939,240 @@ static int lfs_hsm_clear(int argc, char **argv)
        return lfs_hsm_change_flags(argc, argv, LFS_HSM_CLEAR);
 }
 
+/**
+ * Check file state and return its fid, to be used by lfs_hsm_request().
+ *
+ * \param[in]     file      Path to file to check
+ * \param[in,out] fid       Pointer to allocated lu_fid struct.
+ * \param[in,out] last_dev  Pointer to last device id used.
+ *
+ * \return 0 on success.
+ */
+static int lfs_hsm_prepare_file(char *file, struct lu_fid *fid,
+                               dev_t *last_dev)
+{
+       struct stat     st;
+       int             rc;
+
+       rc = lstat(file, &st);
+       if (rc) {
+               fprintf(stderr, "Cannot stat %s: %s\n", file, strerror(-errno));
+               return -errno;
+       }
+       /* A request should be ... */
+       if (*last_dev != st.st_dev && *last_dev != 0) {
+               fprintf(stderr, "All files should be "
+                       "on the same filesystem: %s\n", file);
+               return -EINVAL;
+       }
+       *last_dev = st.st_dev;
+
+       rc = llapi_path2fid(file, fid);
+       if (rc) {
+               fprintf(stderr, "Cannot read FID of %s: %s\n",
+                       file, strerror(-rc));
+               return rc;
+       }
+       return 0;
+}
+
+static int lfs_hsm_request(int argc, char **argv, int action)
+{
+       struct option            long_opts[] = {
+               {"filelist", 1, 0, 'l'},
+               {"data", 1, 0, 'D'},
+               {"archive", 1, 0, 'a'},
+               {0, 0, 0, 0}
+       };
+       dev_t                    last_dev = 0;
+       char                     short_opts[] = "l:D:a:";
+       struct hsm_user_request *hur, *oldhur;
+       int                      c, i;
+       size_t                   len;
+       int                      nbfile;
+       char                    *line = NULL;
+       char                    *filelist = NULL;
+       char                     fullpath[PATH_MAX];
+       char                    *opaque = NULL;
+       int                      opaque_len = 0;
+       int                      archive_id = 0;
+       FILE                    *fp;
+       int                      nbfile_alloc = 0;
+       char                     some_file[PATH_MAX+1] = "";
+       int                      rc;
+
+       if (argc < 2)
+               return CMD_HELP;
+
+       optind = 0;
+       while ((c = getopt_long(argc, argv, short_opts,
+                               long_opts, NULL)) != -1) {
+               switch (c) {
+               case 'l':
+                       filelist = optarg;
+                       break;
+               case 'D':
+                       opaque = optarg;
+                       break;
+               case 'a':
+                       if (action != HUA_ARCHIVE) {
+                               fprintf(stderr,
+                                       "error: -a is supported only "
+                                       "when archiving\n");
+                               return CMD_HELP;
+                       }
+                       archive_id = atoi(optarg);
+                       break;
+               case '?':
+                       return CMD_HELP;
+               default:
+                       fprintf(stderr, "error: %s: option '%s' unrecognized\n",
+                               argv[0], argv[optind - 1]);
+                       return CMD_HELP;
+               }
+       }
+
+       /* All remaining args are files, so we have at least nbfile */
+       nbfile = argc - optind;
+
+       if ((nbfile == 0) && (filelist == NULL))
+               return CMD_HELP;
+
+       if (opaque != NULL)
+               opaque_len = strlen(opaque);
+
+       /* Alloc the request structure with enough place to store all files
+        * from command line. */
+       hur = llapi_hsm_user_request_alloc(nbfile, opaque_len);
+       if (hur == NULL) {
+               fprintf(stderr, "Cannot create the request: %s\n",
+                       strerror(errno));
+               return errno;
+       }
+       nbfile_alloc = nbfile;
+
+       hur->hur_request.hr_action = action;
+       hur->hur_request.hr_archive_id = archive_id;
+       hur->hur_request.hr_flags = 0;
+
+       /* All remaining args are files, add them */
+       if (nbfile != 0)
+               strcpy(some_file, argv[optind]);
+
+       for (i = 0; i < nbfile; i++) {
+               hur->hur_user_item[i].hui_extent.length = -1;
+               rc = lfs_hsm_prepare_file(argv[optind + i],
+                                         &hur->hur_user_item[i].hui_fid,
+                                         &last_dev);
+               hur->hur_request.hr_itemcount++;
+               if (rc)
+                       goto out_free;
+       }
+
+       /* from here stop using nb_file, use hur->hur_request.hr_itemcount */
+
+       /* If a filelist was specified, read the filelist from it. */
+       if (filelist != NULL) {
+               fp = fopen(filelist, "r");
+               if (fp == NULL) {
+                       fprintf(stderr, "Cannot read the file list %s: %s\n",
+                               filelist, strerror(errno));
+                       rc = -errno;
+                       goto out_free;
+               }
+
+               while ((rc = getline(&line, &len, fp)) != -1) {
+                       struct hsm_user_item *hui;
+
+                       /* If allocated buffer was too small, gets something
+                        * bigger */
+                       if (nbfile_alloc <= hur->hur_request.hr_itemcount) {
+                               nbfile_alloc = nbfile_alloc * 2 + 1;
+                               oldhur = hur;
+                               hur = llapi_hsm_user_request_alloc(nbfile_alloc,
+                                                                  opaque_len);
+                               if (hur == NULL) {
+                                       fprintf(stderr, "Cannot allocate "
+                                               "the request: %s\n",
+                                               strerror(errno));
+                                       hur = oldhur;
+                                       rc = -errno;
+                                       goto out_free;
+                               }
+                               memcpy(hur, oldhur, hur_len(oldhur));
+                               free(oldhur);
+                       }
+
+                       /* Chop CR */
+                       if (line[strlen(line) - 1] == '\n')
+                               line[strlen(line) - 1] = '\0';
+
+                       hui =
+                            &hur->hur_user_item[hur->hur_request.hr_itemcount];
+                       hui->hui_extent.length = -1;
+                       rc = lfs_hsm_prepare_file(line, &hui->hui_fid,
+                                                 &last_dev);
+                       hur->hur_request.hr_itemcount++;
+                       if (rc)
+                               goto out_free;
+
+                       if ((some_file[0] == '\0') &&
+                           (strlen(line) < sizeof(some_file)))
+                               strcpy(some_file, line);
+               }
+
+               rc = fclose(fp);
+               if (line)
+                       free(line);
+       }
+
+       /* If a --data was used, add it to the request */
+       hur->hur_request.hr_data_len = opaque_len;
+       if (opaque != NULL)
+               memcpy(hur_data(hur), opaque, opaque_len);
+
+       /* Send the HSM request */
+       if (realpath(some_file, fullpath) == NULL) {
+               fprintf(stderr, "Could not find path '%s': %s\n",
+                       some_file, strerror(errno));
+       }
+       rc = llapi_hsm_request(fullpath, hur);
+       if (rc) {
+               fprintf(stderr, "Cannot send HSM request (use of %s): %s\n",
+                       some_file, strerror(-rc));
+               goto out_free;
+       }
+
+out_free:
+       free(hur);
+       return rc;
+}
+
+static int lfs_hsm_archive(int argc, char **argv)
+{
+       return lfs_hsm_request(argc, argv, HUA_ARCHIVE);
+}
+
+static int lfs_hsm_restore(int argc, char **argv)
+{
+       return lfs_hsm_request(argc, argv, HUA_RESTORE);
+}
+
+static int lfs_hsm_release(int argc, char **argv)
+{
+       return lfs_hsm_request(argc, argv, HUA_RELEASE);
+}
+
+static int lfs_hsm_remove(int argc, char **argv)
+{
+       return lfs_hsm_request(argc, argv, HUA_REMOVE);
+}
+
+static int lfs_hsm_cancel(int argc, char **argv)
+{
+       return lfs_hsm_request(argc, argv, HUA_CANCEL);
+}
+
 int main(int argc, char **argv)
 {
         int rc;
index 3bf8cfa..814ab2c 100644 (file)
@@ -235,12 +235,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;
@@ -539,3 +539,46 @@ int llapi_hsm_current_action(const char *path, struct hsm_current_action *hca)
        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;
+}
+
index c45eb2a..cf41176 100644 (file)
@@ -88,6 +88,7 @@
 #define lustre_swab_hsm_user_state NULL
 #define lustre_swab_hsm_state_set NULL
 #define lustre_swab_hsm_current_action NULL
+#define lustre_swab_hsm_request NULL
 #define dump_rniobuf NULL
 #define dump_ioo NULL
 #define dump_obdo NULL
index 913f72b..56b9eab 100644 (file)
@@ -1891,7 +1891,7 @@ check_hsm_action_list(void)
        CHECK_MEMBER(hsm_action_list, hal_count);
        CHECK_MEMBER(hsm_action_list, hal_compound_id);
        CHECK_MEMBER(hsm_action_list, hal_flags);
-       CHECK_MEMBER(hsm_action_list, hal_archive_num);
+       CHECK_MEMBER(hsm_action_list, hal_archive_id);
        CHECK_MEMBER(hsm_action_list, padding1);
        CHECK_MEMBER(hsm_action_list, hal_fsname);
 }
@@ -1977,6 +1977,29 @@ check_hsm_current_action(void)
 }
 
 static void
+check_hsm_request(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(hsm_request);
+       CHECK_MEMBER(hsm_request, hr_action);
+       CHECK_MEMBER(hsm_request, hr_archive_id);
+       CHECK_MEMBER(hsm_request, hr_flags);
+       CHECK_MEMBER(hsm_request, hr_itemcount);
+       CHECK_MEMBER(hsm_request, hr_data_len);
+       CHECK_VALUE_X(HSM_FORCE_ACTION);
+       CHECK_VALUE_X(HSM_GHOST_COPY);
+}
+
+static void
+check_hsm_user_request(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(hsm_user_request);
+       CHECK_MEMBER(hsm_user_request, hur_request);
+       CHECK_MEMBER(hsm_user_request, hur_user_item);
+}
+
+static void
 system_string (char *cmdline, char *str, int len)
 {
        int   fds[2];
@@ -2344,6 +2367,8 @@ main(int argc, char **argv)
        check_hsm_user_state();
        check_hsm_state_set();
        check_hsm_current_action();
+       check_hsm_request();
+       check_hsm_user_request();
 
        printf("}\n\n");
 
index 95a32d5..306a444 100644 (file)
@@ -4217,10 +4217,10 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct hsm_action_list, hal_flags));
        LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_flags) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_flags));
-       LASSERTF((int)offsetof(struct hsm_action_list, hal_archive_num) == 24, "found %lld\n",
-                (long long)(int)offsetof(struct hsm_action_list, hal_archive_num));
-       LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_archive_num) == 4, "found %lld\n",
-                (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_archive_num));
+       LASSERTF((int)offsetof(struct hsm_action_list, hal_archive_id) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_action_list, hal_archive_id));
+       LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_archive_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_archive_id));
        LASSERTF((int)offsetof(struct hsm_action_list, padding1) == 28, "found %lld\n",
                 (long long)(int)offsetof(struct hsm_action_list, padding1));
        LASSERTF((int)sizeof(((struct hsm_action_list *)0)->padding1) == 4, "found %lld\n",
@@ -4390,5 +4390,45 @@ void lustre_assert_wire_constants(void)
                 (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));
+
+       /* Checks for struct hsm_request */
+       LASSERTF((int)sizeof(struct hsm_request) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_request));
+       LASSERTF((int)offsetof(struct hsm_request, hr_action) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_action));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_action) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_action));
+       LASSERTF((int)offsetof(struct hsm_request, hr_archive_id) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_archive_id));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_archive_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_archive_id));
+       LASSERTF((int)offsetof(struct hsm_request, hr_flags) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_flags));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_flags) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_flags));
+       LASSERTF((int)offsetof(struct hsm_request, hr_itemcount) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_itemcount));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_itemcount) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_itemcount));
+       LASSERTF((int)offsetof(struct hsm_request, hr_data_len) == 20, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_request, hr_data_len));
+       LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_data_len) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_request *)0)->hr_data_len));
+       LASSERTF(HSM_FORCE_ACTION == 0x00000001UL, "found 0x%.8xUL\n",
+               (unsigned)HSM_FORCE_ACTION);
+       LASSERTF(HSM_GHOST_COPY == 0x00000002UL, "found 0x%.8xUL\n",
+               (unsigned)HSM_GHOST_COPY);
+
+       /* Checks for struct hsm_user_request */
+       LASSERTF((int)sizeof(struct hsm_user_request) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_user_request));
+       LASSERTF((int)offsetof(struct hsm_user_request, hur_request) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_request, hur_request));
+       LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_request) == 24, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_request));
+       LASSERTF((int)offsetof(struct hsm_user_request, hur_user_item) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_request, hur_user_item));
+       LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_user_item) == 0, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_user_item));
 }