/* temporary for testing */ static int mdc_wr_kuc(struct file *file, const char *buffer, unsigned long count, void *data) { struct obd_device *obd = data; struct kuc_hdr *lh; struct hsm_action_list *hal; struct hsm_action_item *hai; int len; int fd, rc; ENTRY; rc = lprocfs_write_helper(buffer, count, &fd); if (rc) RETURN(rc); if (fd < 0) RETURN(-ERANGE); CWARN("message to fd %d\n", fd); len = sizeof(*lh) + sizeof(*hal) + MTI_NAME_MAXLEN + /* for mockup below */ 2 * cfs_size_round(sizeof(*hai)); OBD_ALLOC(lh, len); lh->kuc_magic = KUC_MAGIC; lh->kuc_transport = KUC_TRANSPORT_HSM; lh->kuc_msgtype = HMT_ACTION_LIST; lh->kuc_msglen = len; hal = (struct hsm_action_list *)(lh + 1); hal->hal_version = HAL_VERSION; hal->hal_archive_id = 1; hal->hal_flags = 0; obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN); /* mock up an action list */ hal->hal_count = 2; hai = hai_zero(hal); hai->hai_action = HSMA_ARCHIVE; hai->hai_fid.f_oid = 5; hai->hai_len = sizeof(*hai); hai = hai_next(hai); hai->hai_action = HSMA_RESTORE; hai->hai_fid.f_oid = 10; hai->hai_len = sizeof(*hai); /* This works for either broadcast or unicast to a single fd */ if (fd == 0) { rc = libcfs_kkuc_group_put(KUC_GRP_HSM, lh); } else { cfs_file_t *fp = cfs_get_fd(fd); rc = libcfs_kkuc_msg_put(fp, lh); cfs_put_file(fp); } OBD_FREE(lh, len); if (rc < 0) RETURN(rc); RETURN(count); }
/** * 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 tgt_session_info *tsi) { struct mdt_thread_info *info; struct hsm_current_action *hca; struct hsm_action_list *hal = NULL; struct hsm_action_item *hai; int hal_size; int rc; ENTRY; hca = req_capsule_server_get(tsi->tsi_pill, &RMF_MDS_HSM_CURRENT_ACTION); if (hca == NULL) RETURN(err_serious(-EPROTO)); if (tsi->tsi_mdt_body == NULL) RETURN(-EPROTO); info = tsi2mdt_info(tsi); /* Only valid if client is remote */ rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body); if (rc) GOTO(out, rc = err_serious(rc)); /* Coordinator information */ hal_size = sizeof(*hal) + cfs_size_round(MTI_NAME_MAXLEN) /* fsname */ + cfs_size_round(sizeof(*hai)); MDT_HSM_ALLOC(hal, hal_size); if (hal == NULL) GOTO(out_ucred, rc = -ENOMEM); hal->hal_version = HAL_VERSION; hal->hal_archive_id = 0; hal->hal_flags = 0; obd_uuid2fsname(hal->hal_fsname, mdt_obd_name(info->mti_mdt), MTI_NAME_MAXLEN); hal->hal_count = 1; hai = hai_first(hal); hai->hai_action = HSMA_NONE; hai->hai_cookie = 0; hai->hai_gid = 0; hai->hai_fid = info->mti_body->mbo_fid1; hai->hai_len = sizeof(*hai); rc = mdt_hsm_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", mdt_obd_name(info->mti_mdt), hai->hai_action, PFID(&hai->hai_fid)); break; } hca->hca_location = hai->hai_extent; EXIT; out_free: MDT_HSM_FREE(hal, hal_size); out_ucred: mdt_exit_ucred(info); out: mdt_thread_info_fini(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 tgt_session_info *tsi) { struct mdt_thread_info *info; struct req_capsule *pill = tsi->tsi_pill; struct hsm_request *hr; struct hsm_user_item *hui; struct hsm_action_list *hal; struct hsm_action_item *hai; const void *data; int hui_list_size; int data_size; enum hsm_copytool_action action = HSMA_NONE; __u64 compound_id; int hal_size, i, rc; ENTRY; hr = req_capsule_client_get(pill, &RMF_MDS_HSM_REQUEST); hui = req_capsule_client_get(pill, &RMF_MDS_HSM_USER_ITEM); data = req_capsule_client_get(pill, &RMF_GENERIC_DATA); if (tsi->tsi_mdt_body == NULL || hr == NULL || hui == NULL || data == NULL) RETURN(-EPROTO); /* Sanity check. Nothing to do with an empty list */ if (hr->hr_itemcount == 0) RETURN(0); hui_list_size = req_capsule_get_size(pill, &RMF_MDS_HSM_USER_ITEM, RCL_CLIENT); if (hui_list_size < hr->hr_itemcount * sizeof(*hui)) RETURN(-EPROTO); data_size = req_capsule_get_size(pill, &RMF_GENERIC_DATA, RCL_CLIENT); if (data_size != hr->hr_data_len) RETURN(-EPROTO); info = tsi2mdt_info(tsi); /* Only valid if client is remote */ rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body); if (rc) GOTO(out, 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); } hal_size = sizeof(*hal) + cfs_size_round(MTI_NAME_MAXLEN) /* fsname */ + (sizeof(*hai) + cfs_size_round(hr->hr_data_len)) * hr->hr_itemcount; MDT_HSM_ALLOC(hal, hal_size); 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, mdt_obd_name(info->mti_mdt), MTI_NAME_MAXLEN); hal->hal_count = 0; hai = hai_first(hal); for (i = 0; i < hr->hr_itemcount; i++, hai = hai_next(hai)) { /* Get rid of duplicate entries. Otherwise we get * duplicated work in the llog. */ if (is_fid_in_hal(hal, &hui[i].hui_fid)) continue; 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, data, hr->hr_data_len); hai->hai_len = sizeof(*hai) + hr->hr_data_len; hal->hal_count++; } rc = mdt_hsm_add_actions(info, hal, &compound_id); MDT_HSM_FREE(hal, hal_size); GOTO(out_ucred, rc); out_ucred: mdt_exit_ucred(info); out: mdt_thread_info_fini(info); return rc; }
/* temporary for testing */ static ssize_t mdc_kuc_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct obd_device *obd = ((struct seq_file *)file->private_data)->private; struct kuc_hdr *lh; struct hsm_action_list *hal; struct hsm_action_item *hai; int len; int fd, rc; rc = lprocfs_write_helper(buffer, count, &fd); if (rc) return rc; if (fd < 0) return -ERANGE; CWARN("message to fd %d\n", fd); len = sizeof(*lh) + sizeof(*hal) + MTI_NAME_MAXLEN + /* for mockup below */ 2 * cfs_size_round(sizeof(*hai)); OBD_ALLOC(lh, len); if (!lh) return -ENOMEM; lh->kuc_magic = KUC_MAGIC; lh->kuc_transport = KUC_TRANSPORT_HSM; lh->kuc_msgtype = HMT_ACTION_LIST; lh->kuc_msglen = len; hal = (struct hsm_action_list *)(lh + 1); hal->hal_version = HAL_VERSION; hal->hal_archive_id = 1; hal->hal_flags = 0; obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN); /* mock up an action list */ hal->hal_count = 2; hai = hai_zero(hal); hai->hai_action = HSMA_ARCHIVE; hai->hai_fid.f_oid = 5; hai->hai_len = sizeof(*hai); hai = hai_next(hai); hai->hai_action = HSMA_RESTORE; hai->hai_fid.f_oid = 10; hai->hai_len = sizeof(*hai); /* This works for either broadcast or unicast to a single fd */ if (fd == 0) { rc = libcfs_kkuc_group_put(KUC_GRP_HSM, lh); } else { struct file *fp = fget(fd); rc = libcfs_kkuc_msg_put(fp, lh); fput(fp); } OBD_FREE(lh, len); if (rc < 0) return rc; return count; }