Exemple #1
0
/* 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);
}
Exemple #2
0
/**
 * 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;
}
Exemple #3
0
/**
 * 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;
}
Exemple #4
0
/* 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;
}