Merge branch 'configurable-ring-size'
* configurable-ring-size: qrexec: add qrexec-client-vm --buffer-size option
This commit is contained in:
commit
f8c40aa0f7
@ -8,7 +8,7 @@ qrexec-client-vm - call Qubes RPC service
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
========
|
========
|
||||||
| qrexec-client-vm *target_vmname* *service* [*local_program* [*local program arguments*]]
|
| qrexec-client-vm [--buffer-size=*BUFFER_SIZE*] *target_vmname* *service* [*local_program* [*local program arguments*]]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
===========
|
===========
|
||||||
@ -27,6 +27,12 @@ stdin/stdout is connected to those of ``qrexec-client-vm``.
|
|||||||
OPTIONS
|
OPTIONS
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
--buffer-size=*BUFFER_SIZE*
|
||||||
|
|
||||||
|
Optional buffer size for vchan connection. This size is used as minimum
|
||||||
|
size for a buffer in each connection direction (read and write).
|
||||||
|
Default: 64KiB.
|
||||||
|
|
||||||
*target_vmname*
|
*target_vmname*
|
||||||
|
|
||||||
Name of target VM to which service is requested. Qubes RPC policy may
|
Name of target VM to which service is requested. Qubes RPC policy may
|
||||||
|
@ -490,10 +490,14 @@ int process_child_io(libvchan_t *data_vchan,
|
|||||||
* MSG_EXEC_CMDLINE - connect to vchan server, fork+exec process given by
|
* MSG_EXEC_CMDLINE - connect to vchan server, fork+exec process given by
|
||||||
* cmdline parameter, pass the data to/from that process, then return local
|
* cmdline parameter, pass the data to/from that process, then return local
|
||||||
* process exit code
|
* process exit code
|
||||||
|
*
|
||||||
|
* buffer_size is about vchan buffer allocated (only for vchan server cases),
|
||||||
|
* use 0 to use built-in default (64k); needs to be power of 2
|
||||||
*/
|
*/
|
||||||
int handle_new_process_common(int type, int connect_domain, int connect_port,
|
int handle_new_process_common(int type, int connect_domain, int connect_port,
|
||||||
char *cmdline, int cmdline_len, /* MSG_JUST_EXEC and MSG_EXEC_CMDLINE */
|
char *cmdline, int cmdline_len, /* MSG_JUST_EXEC and MSG_EXEC_CMDLINE */
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd /* MSG_SERVICE_CONNECT */)
|
int stdin_fd, int stdout_fd, int stderr_fd /* MSG_SERVICE_CONNECT */,
|
||||||
|
int buffer_size)
|
||||||
{
|
{
|
||||||
libvchan_t *data_vchan;
|
libvchan_t *data_vchan;
|
||||||
int exit_code = 0;
|
int exit_code = 0;
|
||||||
@ -504,9 +508,12 @@ int handle_new_process_common(int type, int connect_domain, int connect_port,
|
|||||||
cmdline[cmdline_len-1] = 0;
|
cmdline[cmdline_len-1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buffer_size == 0)
|
||||||
|
buffer_size = VCHAN_BUFFER_SIZE;
|
||||||
|
|
||||||
if (type == MSG_SERVICE_CONNECT) {
|
if (type == MSG_SERVICE_CONNECT) {
|
||||||
data_vchan = libvchan_server_init(connect_domain, connect_port,
|
data_vchan = libvchan_server_init(connect_domain, connect_port,
|
||||||
VCHAN_BUFFER_SIZE, VCHAN_BUFFER_SIZE);
|
buffer_size, buffer_size);
|
||||||
if (data_vchan)
|
if (data_vchan)
|
||||||
libvchan_wait(data_vchan);
|
libvchan_wait(data_vchan);
|
||||||
} else {
|
} else {
|
||||||
@ -563,7 +570,7 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
|
|||||||
/* child process */
|
/* child process */
|
||||||
exit_code = handle_new_process_common(type, connect_domain, connect_port,
|
exit_code = handle_new_process_common(type, connect_domain, connect_port,
|
||||||
cmdline, cmdline_len,
|
cmdline, cmdline_len,
|
||||||
-1, -1, -1);
|
-1, -1, -1, 0);
|
||||||
|
|
||||||
exit(exit_code);
|
exit(exit_code);
|
||||||
/* suppress warning */
|
/* suppress warning */
|
||||||
@ -572,13 +579,13 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
|
|||||||
|
|
||||||
/* Returns exit code of remote process */
|
/* Returns exit code of remote process */
|
||||||
int handle_data_client(int type, int connect_domain, int connect_port,
|
int handle_data_client(int type, int connect_domain, int connect_port,
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd)
|
int stdin_fd, int stdout_fd, int stderr_fd, int buffer_size)
|
||||||
{
|
{
|
||||||
int exit_code;
|
int exit_code;
|
||||||
|
|
||||||
assert(type == MSG_SERVICE_CONNECT);
|
assert(type == MSG_SERVICE_CONNECT);
|
||||||
|
|
||||||
exit_code = handle_new_process_common(type, connect_domain, connect_port,
|
exit_code = handle_new_process_common(type, connect_domain, connect_port,
|
||||||
NULL, 0, stdin_fd, stdout_fd, stderr_fd);
|
NULL, 0, stdin_fd, stdout_fd, stderr_fd, buffer_size);
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,8 @@ pid_t handle_new_process(int type,
|
|||||||
char *cmdline, int cmdline_len);
|
char *cmdline, int cmdline_len);
|
||||||
int handle_data_client(int type,
|
int handle_data_client(int type,
|
||||||
int connect_domain, int connect_port,
|
int connect_domain, int connect_port,
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd);
|
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||||
|
int buffer_size);
|
||||||
|
|
||||||
|
|
||||||
struct qrexec_cmd_info {
|
struct qrexec_cmd_info {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "libqrexec-utils.h"
|
#include "libqrexec-utils.h"
|
||||||
#include "qrexec.h"
|
#include "qrexec.h"
|
||||||
#include "qrexec-agent.h"
|
#include "qrexec-agent.h"
|
||||||
@ -85,6 +86,19 @@ void convert_target_name_keyword(char *target)
|
|||||||
target[i] = '@';
|
target[i] = '@';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct option longopts[] = {
|
||||||
|
{ "buffer-size", required_argument, 0, 'b' },
|
||||||
|
{ NULL, 0, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
_Noreturn void usage(const char *argv0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"usage: %s [--buffer-size=BUFFER_SIZE] target_vmname program_ident [local_program [local program arguments]]\n",
|
||||||
|
argv0);
|
||||||
|
fprintf(stderr, "BUFFER_SIZE is minimum vchan buffer size (default: 64k)\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int trigger_fd;
|
int trigger_fd;
|
||||||
@ -95,24 +109,36 @@ int main(int argc, char **argv)
|
|||||||
char *abs_exec_path;
|
char *abs_exec_path;
|
||||||
pid_t child_pid = 0;
|
pid_t child_pid = 0;
|
||||||
int inpipe[2], outpipe[2];
|
int inpipe[2], outpipe[2];
|
||||||
|
int buffer_size = 0;
|
||||||
|
int opt;
|
||||||
|
|
||||||
if (argc < 3) {
|
while (1) {
|
||||||
fprintf(stderr,
|
opt = getopt_long(argc, argv, "", longopts, NULL);
|
||||||
"usage: %s target_vmname program_ident [local_program [local program arguments]]\n",
|
if (opt == -1)
|
||||||
argv[0]);
|
break;
|
||||||
exit(1);
|
switch (opt) {
|
||||||
|
case 'b':
|
||||||
|
buffer_size = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (argc > 3) {
|
|
||||||
|
if (argc - optind < 2) {
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
|
if (argc - optind > 2) {
|
||||||
start_local_process = 1;
|
start_local_process = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
|
trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
strncpy(params.service_name, argv[2], sizeof(params.service_name));
|
strncpy(params.service_name, argv[optind + 1], sizeof(params.service_name));
|
||||||
|
|
||||||
convert_target_name_keyword(argv[1]);
|
convert_target_name_keyword(argv[optind]);
|
||||||
strncpy(params.target_domain, argv[1],
|
strncpy(params.target_domain, argv[optind],
|
||||||
sizeof(params.target_domain));
|
sizeof(params.target_domain));
|
||||||
|
|
||||||
snprintf(params.request_id.ident,
|
snprintf(params.request_id.ident,
|
||||||
@ -164,9 +190,9 @@ int main(int argc, char **argv)
|
|||||||
close(inpipe[0]);
|
close(inpipe[0]);
|
||||||
close(outpipe[1]);
|
close(outpipe[1]);
|
||||||
|
|
||||||
abs_exec_path = strdup(argv[3]);
|
abs_exec_path = strdup(argv[optind + 2]);
|
||||||
argv[3] = get_program_name(argv[3]);
|
argv[optind + 2] = get_program_name(argv[optind + 2]);
|
||||||
execv(abs_exec_path, argv + 3);
|
execv(abs_exec_path, argv + optind + 2);
|
||||||
perror("execv");
|
perror("execv");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@ -175,11 +201,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
ret = handle_data_client(MSG_SERVICE_CONNECT,
|
ret = handle_data_client(MSG_SERVICE_CONNECT,
|
||||||
exec_params.connect_domain, exec_params.connect_port,
|
exec_params.connect_domain, exec_params.connect_port,
|
||||||
inpipe[1], outpipe[0], -1);
|
inpipe[1], outpipe[0], -1, buffer_size);
|
||||||
} else {
|
} else {
|
||||||
ret = handle_data_client(MSG_SERVICE_CONNECT,
|
ret = handle_data_client(MSG_SERVICE_CONNECT,
|
||||||
exec_params.connect_domain, exec_params.connect_port,
|
exec_params.connect_domain, exec_params.connect_port,
|
||||||
1, 0, -1);
|
1, 0, -1, buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(trigger_fd);
|
close(trigger_fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user