+ * prepare cancel request
+ * \param hal [IN] pointer to allocate memory
+ * \param car [IN] coordinator agent request
+ * \param mdt_obd_name [IN] mdt object device name
+ * \param hal_sz [IN, OUT] old size of hal_sz buffer
+ */
+static struct hsm_action_list *
+hsm_create_cancel_request(struct hsm_action_list *hal,
+ struct cdt_agent_req *car,
+ char *mdt_obd_name, int *hal_sz)
+{
+ struct hsm_action_item *hai;
+ int hal_sz_needed;
+
+ /* needed size */
+ hal_sz_needed = sizeof(*hal) + cfs_size_round(MTI_NAME_MAXLEN + 1) +
+ cfs_size_round(car->car_hai->hai_len);
+
+ if (hal_sz_needed > *hal_sz) {
+ /* not enough room, free old buffer */
+ if (hal != NULL)
+ OBD_FREE(hal, *hal_sz);
+ *hal_sz = hal_sz_needed;
+ OBD_ALLOC(hal, *hal_sz);
+ if (hal == NULL) {
+ CERROR("Cannot allocate memory for hal\n");
+ RETURN(NULL);
+ }
+ }
+
+ hal->hal_version = HAL_VERSION;
+ obd_uuid2fsname(hal->hal_fsname, mdt_obd_name,
+ MTI_NAME_MAXLEN);
+ hal->hal_fsname[MTI_NAME_MAXLEN] = '\0';
+ hal->hal_compound_id = car->car_compound_id;
+ hal->hal_archive_id = car->car_archive_id;
+ hal->hal_flags = car->car_flags;
+ hal->hal_count = 0;
+
+ hai = hai_first(hal);
+ memcpy(hai, car->car_hai, car->car_hai->hai_len);
+ hai->hai_action = HSMA_CANCEL;
+ hal->hal_count = 1;
+
+ RETURN(hal);
+}
+
+/**
+ * cancel actions running on a agent
+ * \param mdt [IN] MDT device
+ * \param uuid [IN] the obd_uuid of the agent whose requests are to be canceled
+ */
+int hsm_cancel_agent_requests(struct mdt_device *mdt,
+ const struct obd_uuid *uuid)
+{
+ struct mdt_thread_info *mti;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+ struct cdt_agent_req *car;
+ int rc = 0;
+ enum cdt_states save_state;
+ struct hsm_record_update update;
+ ENTRY;
+
+ /* retrieve coordinator context */
+ mti = lu_context_key_get(&cdt->cdt_env.le_ctx, &mdt_thread_key);
+
+ /* disable coordinator */
+ save_state = cdt->cdt_state;
+ cdt->cdt_state = CDT_DISABLE;
+
+ down_read(&cdt->cdt_request_lock);
+ list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) {
+ mdt_cdt_get_request(car);
+ /* request is not yet removed from list, it will be done
+ * when copytool will return progress
+ */
+ if (!obd_uuid_equals(&car->car_uuid, uuid)) {
+ mdt_cdt_put_request(car);
+ continue;
+ }
+
+ if (car->car_hai->hai_action == HSMA_CANCEL) {
+ mdt_cdt_put_request(car);
+ continue;
+ }
+
+ update.cookie = car->car_hai->hai_cookie;
+ update.status = ARS_CANCELED;
+
+ rc = mdt_agent_record_update(mti->mti_env, mti->mti_mdt,
+ &update, 1);
+
+ if (rc == 0)
+ car->car_canceled = 1;
+ else
+ CERROR("%s: mdt_agent_record_update() failed, "
+ "rc=%d, cannot update status to %s "
+ "for cookie %#llx\n",
+ mdt_obd_name(mdt), rc,
+ agent_req_status2name(ARS_CANCELED),
+ car->car_hai->hai_cookie);
+
+ mdt_cdt_put_request(car);
+ }
+ up_read(&cdt->cdt_request_lock);
+
+ /* enable coordinator */
+ cdt->cdt_state = save_state;
+
+ RETURN(rc);
+}
+
+/**