varlinkctl: add --timeout= switch to tweak time-out behaviour
Fixes: #33772
This commit is contained in:
committed by
Yu Watanabe
parent
925095a6db
commit
39ce86d19c
+33
-5
@@ -199,18 +199,35 @@
|
||||
<varlistentry>
|
||||
<term><option>--more</option></term>
|
||||
|
||||
<listitem><para>When used with <command>call</command>: expect multiple method replies. If this flag is
|
||||
set the method call is sent with the <constant>more</constant> flag set, which tells the service to
|
||||
generate multiple replies, if needed. The command remains running until the service sends a reply
|
||||
message that indicates it is the last in the series. This flag should be set only for method calls
|
||||
that support this mechanism.</para>
|
||||
<listitem><para>When used with <command>call</command>: expect multiple method replies. If this flag
|
||||
is set the method call is sent with the <constant>more</constant> flag set, which tells the service
|
||||
to generate multiple replies, if needed. The command remains running until the service sends a reply
|
||||
message that indicates it is the last in the series (or if the configured time-out is reached, see
|
||||
below). This flag should be set only for method calls that support this mechanism.</para>
|
||||
|
||||
<para>If this mode is enabled output is automatically switched to JSON-SEQ mode, so that individual
|
||||
reply objects can be easily discerned.</para>
|
||||
|
||||
<para>This switch has no effect on the method call time-out applied by default: regardless if
|
||||
<option>--more</option> is specified or not, the default time-out will be 45s. Use
|
||||
<option>--timeout=</option> (see below) to change or disable the time-out. When invoking a method
|
||||
call that continously returns updates it is typically desirable to disable the time-out with
|
||||
<option>--timeout=infinity</option>. On the other hand, when invoking a <option>--more</option>
|
||||
method call for the purpose of enumerating objects (which likely will complete quickly) it is
|
||||
typically beneficial to leave the time-out logic enabled, for robustness reasons.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-E</option></term>
|
||||
|
||||
<listitem><para>A shortcut for <option>--more --timeout=infinity</option>. This switch is
|
||||
useful for method calls that implement subscription to a continious stream of updates.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--collect</option></term>
|
||||
|
||||
@@ -279,6 +296,17 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--timeout=</option></term>
|
||||
|
||||
<listitem>
|
||||
<para>Expects a time-out in seconds as parameter. By default a time-out of 45s is enforced. To turn
|
||||
off the time-out specify <literal>infinity</literal> or an empty string.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
|
||||
+46
-17
@@ -26,6 +26,7 @@ static sd_varlink_method_flags_t arg_method_flags = 0;
|
||||
static bool arg_collect = false;
|
||||
static bool arg_quiet = false;
|
||||
static char **arg_graceful = NULL;
|
||||
static usec_t arg_timeout = 0;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_graceful, strv_freep);
|
||||
|
||||
@@ -65,6 +66,8 @@ static int help(void) {
|
||||
" -j Same as --json=pretty on tty, --json=short otherwise\n"
|
||||
" -q --quiet Do not output method reply\n"
|
||||
" --graceful=ERROR Treat specified Varlink error as success\n"
|
||||
" --timeout=SECS Maximum time to wait for method call completion\n"
|
||||
" -E Short for --more --timeout=infinity\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
@@ -90,6 +93,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_JSON,
|
||||
ARG_COLLECT,
|
||||
ARG_GRACEFUL,
|
||||
ARG_TIMEOUT,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -102,6 +106,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "collect", no_argument, NULL, ARG_COLLECT },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "graceful", required_argument, NULL, ARG_GRACEFUL },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{},
|
||||
};
|
||||
|
||||
@@ -110,7 +115,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hjq", options, NULL)) >= 0)
|
||||
while ((c = getopt_long(argc, argv, "hjqE", options, NULL)) >= 0)
|
||||
|
||||
switch (c) {
|
||||
|
||||
@@ -124,6 +129,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_pager_flags |= PAGER_DISABLE;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
arg_timeout = USEC_INFINITY;
|
||||
_fallthrough_;
|
||||
|
||||
case ARG_MORE:
|
||||
arg_method_flags = (arg_method_flags & ~SD_VARLINK_METHOD_ONEWAY) | SD_VARLINK_METHOD_MORE;
|
||||
break;
|
||||
@@ -163,6 +172,21 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case ARG_TIMEOUT:
|
||||
if (isempty(optarg)) {
|
||||
arg_timeout = USEC_INFINITY;
|
||||
break;
|
||||
}
|
||||
|
||||
r = parse_sec(optarg, &arg_timeout);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse --timeout= parameter '%s': %m", optarg);
|
||||
|
||||
if (arg_timeout == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Timeout cannot be zero.");
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@@ -185,6 +209,8 @@ static int varlink_connect_auto(sd_varlink **ret, const char *where) {
|
||||
assert(ret);
|
||||
assert(where);
|
||||
|
||||
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||
|
||||
if (STARTSWITH_SET(where, "/", "./")) { /* If the string starts with a slash or dot slash we use it as a file system path */
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct stat st;
|
||||
@@ -196,32 +222,35 @@ static int varlink_connect_auto(sd_varlink **ret, const char *where) {
|
||||
if (fstat(fd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat '%s': %m", where);
|
||||
|
||||
/* Is this a socket in the fs? Then connect() to it. */
|
||||
if (S_ISSOCK(st.st_mode)) {
|
||||
r = sd_varlink_connect_address(ret, FORMAT_PROC_FD_PATH(fd));
|
||||
/* Is this a socket in the fs? Then connect() to it. */
|
||||
|
||||
r = sd_varlink_connect_address(&vl, FORMAT_PROC_FD_PATH(fd));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to '%s': %m", where);
|
||||
|
||||
return 0;
|
||||
}
|
||||
} else if (S_ISREG(st.st_mode) && (st.st_mode & 0111)) {
|
||||
/* Is this an executable binary? Then fork it off. */
|
||||
|
||||
/* Is this an executable binary? Then fork it off. */
|
||||
if (S_ISREG(st.st_mode) && (st.st_mode & 0111)) {
|
||||
r = sd_varlink_connect_exec(ret, where, STRV_MAKE(where)); /* Ideally we'd use FORMAT_PROC_FD_PATH(fd) here too, but that breaks the #! logic */
|
||||
r = sd_varlink_connect_exec(&vl, where, STRV_MAKE(where)); /* Ideally we'd use FORMAT_PROC_FD_PATH(fd) here too, but that breaks the #! logic */
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to spawn '%s' process: %m", where);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unrecognized path '%s' is neither an AF_UNIX socket, nor an executable binary.", where);
|
||||
} else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unrecognized path '%s' is neither an AF_UNIX socket, nor an executable binary.", where);
|
||||
} else {
|
||||
/* Otherwise assume this is an URL */
|
||||
r = sd_varlink_connect_url(&vl, where);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to URL '%s': %m", where);
|
||||
}
|
||||
|
||||
/* Otherwise assume this is an URL */
|
||||
r = sd_varlink_connect_url(ret, where);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to URL '%s': %m", where);
|
||||
if (arg_timeout != 0) {
|
||||
r = sd_varlink_set_relative_timeout(vl, arg_timeout);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to set Varlink timeout: %m");
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(vl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user