Exemple #1
0
/*
 * rpmem_ssh_execv -- open ssh connection and run $RPMEMD_CMD with
 * additional NULL-terminated list of arguments.
 */
struct rpmem_ssh *
rpmem_ssh_execv(const struct rpmem_target_info *info, const char **argv)
{
	struct rpmem_ssh *rps = calloc(1, sizeof(*rps));
	if (!rps)
		goto err_zalloc;

	char *user_at_node = get_user_at_node(info);
	if (!user_at_node)
		goto err_user_node;

	rps->cmd = rpmem_cmd_init();
	if (!rps->cmd)
		goto err_cmd_init;

	char *cmd = get_cmd(argv);
	if (!cmd)
		goto err_cmd;

	int ret = rpmem_cmd_push(rps->cmd, get_ssh());
	if (ret)
		goto err_push;

	if (info->flags & RPMEM_HAS_SERVICE) {
		/* port number is optional */
		ret = rpmem_cmd_push(rps->cmd, "-p");
		if (ret)
			goto err_push;
		ret = rpmem_cmd_push(rps->cmd, info->service);
		if (ret)
			goto err_push;
	}

	/*
	 * Disable allocating pseudo-terminal in order to transfer binary
	 * data safely.
	 */
	ret = rpmem_cmd_push(rps->cmd, "-T");
	if (ret)
		goto err_push;

	if (info->flags & RPMEM_FLAGS_USE_IPV4) {
		ret = rpmem_cmd_push(rps->cmd, "-4");
		if (ret)
			goto err_push;
	}

	/* fail if password required for authentication */
	ret = rpmem_cmd_push(rps->cmd, "-oBatchMode=yes");
	if (ret)
		goto err_push;

	ret = rpmem_cmd_push(rps->cmd, user_at_node);
	if (ret)
		goto err_push;

	ret = rpmem_cmd_push(rps->cmd, cmd);
	if (ret)
		goto err_push;

	ret = rpmem_cmd_run(rps->cmd);
	if (ret)
		goto err_run;


	free(user_at_node);
	free(cmd);

	return rps;
err_run:
err_push:
	free(cmd);
err_cmd:
	rpmem_cmd_fini(rps->cmd);
err_cmd_init:
	free(user_at_node);
err_user_node:
	free(rps);
err_zalloc:
	return NULL;
}
Exemple #2
0
/*
 * rpmem_ssh_open -- open ssh connection with specified node
 */
struct rpmem_ssh *
rpmem_ssh_open(const struct rpmem_target_info *info)
{
	struct rpmem_ssh *rps = calloc(1, sizeof(*rps));
	if (!rps)
		goto err_zalloc;


	char *user_at_node = get_user_at_node(info);
	if (!user_at_node)
		goto err_user_node;

	rps->cmd = rpmem_cmd_init();
	if (!rps->cmd)
		goto err_cmd_init;
	int ret = rpmem_cmd_push(rps->cmd, get_ssh());
	if (ret)
		goto err_push;

	if (info->flags & RPMEM_HAS_SERVICE) {
		/* port number is optional */
		ret = rpmem_cmd_push(rps->cmd, "-p");
		if (ret)
			goto err_push;
		ret = rpmem_cmd_push(rps->cmd, info->service);
		if (ret)
			goto err_push;
	}

	/*
	 * Disable allocating pseudo-terminal in order to transfer binary
	 * data safely.
	 */
	ret = rpmem_cmd_push(rps->cmd, "-T");
	if (ret)
		goto err_push;

	if (info->flags & RPMEM_FLAGS_USE_IPV4) {
		ret = rpmem_cmd_push(rps->cmd, "-4");
		if (ret)
			goto err_push;
	}

	/* fail if password required for authentication */
	ret = rpmem_cmd_push(rps->cmd, "-oBatchMode=yes");
	if (ret)
		goto err_push;

	ret = rpmem_cmd_push(rps->cmd, user_at_node);
	if (ret)
		goto err_push;

	ret = rpmem_cmd_push(rps->cmd, rpmem_util_cmd_get());
	if (ret)
		goto err_push;

	ret = rpmem_cmd_run(rps->cmd);
	if (ret)
		goto err_run;

	/*
	 * Read initial status from invoked command.
	 * This is for synchronization purposes and to make it possible
	 * to inform client that command's initialization failed.
	 */
	int32_t status;
	ret = rpmem_ssh_recv(rps, &status, sizeof(status));
	if (ret) {
		if (ret == 1 || errno == ECONNRESET)
			ERR("%s", rpmem_ssh_strerror(rps));
		else
			ERR("!%s", info->node);
		goto err_recv_status;
	}

	if (status) {
		ERR("%s: unexpected status received -- '%d'",
				info->node, status);
		goto err_status;
	}

	RPMEM_LOG(INFO, "received status: %u", status);

	free(user_at_node);

	return rps;
err_status:
err_recv_status:
err_run:
	rpmem_cmd_term(rps->cmd);
	rpmem_cmd_wait(rps->cmd, NULL);
err_push:
	rpmem_cmd_fini(rps->cmd);
err_cmd_init:
	free(user_at_node);
err_user_node:
	free(rps);
err_zalloc:
	return NULL;
}