Allow MessageQueueMessageSize= to accept IEC size suffixes in socket unit files.
Support the same syntax for transient property assignments.
Keep MessageQueueMaxMessages= as a plain message count.
- merge unit_kill_common() and unit_kill_context()
-- MessageQueueMessageSize= (and suchlike) should use parse_iec_size().
-
- mount /tmp/ and /var/tmp with a uidmap applied that blocks out "nobody" user
among other things such as dynamic uid ranges for containers and so on. That
way no one can create files there with these uids and we enforce they are only
<varlistentry>
<term><varname>MessageQueueMaxMessages=</varname>,
<varname>MessageQueueMessageSize=</varname></term>
- <listitem><para>These two settings take integer values and
- control the mq_maxmsg field or the mq_msgsize field,
- respectively, when creating the message queue. Note that
- either none or both of these variables need to be set. See
+ <listitem><para>These two settings control the mq_maxmsg field or
+ the mq_msgsize field, respectively, when creating the message queue.
+ <varname>MessageQueueMaxMessages=</varname> takes an integer value.
+ <varname>MessageQueueMessageSize=</varname> takes a size in bytes, and
+ the usual suffixes K, M, G are supported and understood to the base of
+ 1024. Note that either none or both of these variables need to be set. See
<citerefentry project='die-net'><refentrytitle>mq_setattr</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for details.</para></listitem>
</varlistentry>
return (size_t) t == t;
}
+static bool check_long_truncation(int64_t t) {
+ return (int64_t) (long) t == t;
+}
+
static const char* socket_protocol_to_string(int32_t i) {
if (i == IPPROTO_IP)
return "";
}
static BUS_DEFINE_SET_TRANSIENT(int, "i", int32_t, int, "%" PRIi32);
-static BUS_DEFINE_SET_TRANSIENT(message_queue, "x", int64_t, long, "%" PRIi64);
+static BUS_DEFINE_SET_TRANSIENT_IS_VALID(message_queue, "x", int64_t, long, "%" PRIi64, check_long_truncation);
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(size_t_check_truncation, "t", uint64_t, size_t, "%" PRIu64, check_size_t_truncation);
static BUS_DEFINE_SET_TRANSIENT_PARSE(bind_ipv6_only, SocketAddressBindIPv6Only, socket_address_bind_ipv6_only_or_bool_from_string);
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(fdname, fdname_is_valid);
Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion)
Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port)
Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg)
-Socket.MessageQueueMessageSize, config_parse_long, 0, offsetof(Socket, mq_msgsize)
+Socket.MessageQueueMessageSize, config_parse_iec_size_long, 0, offsetof(Socket, mq_msgsize)
Socket.RemoveOnStop, config_parse_bool, 0, offsetof(Socket, remove_on_stop)
Socket.Symlinks, config_parse_unit_path_strv_printf, 0, offsetof(Socket, symlinks)
Socket.FileDescriptorName, config_parse_fdname, 0, 0
return 1;
}
+static int bus_append_parse_size_i64(sd_bus_message *m, const char *field, const char *eq) {
+ uint64_t v;
+ int r;
+
+ r = parse_size(eq, /* base= */ 1024, &v);
+ if (r < 0)
+ return parse_log_error(r, field, eq);
+ if (v > INT64_MAX)
+ return parse_log_error(SYNTHETIC_ERRNO(ERANGE), field, eq);
+
+ r = sd_bus_message_append(m, "(sv)", field, "x", (int64_t) v);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ return 1;
+}
+
static int bus_append_parse_permyriad(sd_bus_message *m, const char *field, const char *eq) {
int r;
{ "SocketMode", bus_append_parse_mode },
{ "DirectoryMode", bus_append_parse_mode },
{ "MessageQueueMaxMessages", bus_append_safe_atoi64 },
- { "MessageQueueMessageSize", bus_append_safe_atoi64 },
{ "TimeoutSec", bus_append_parse_sec_rename },
{ "KeepAliveTimeSec", bus_append_parse_sec_rename },
{ "KeepAliveIntervalSec", bus_append_parse_sec_rename },
{ "ReceiveBuffer", bus_append_parse_size },
{ "SendBuffer", bus_append_parse_size },
{ "PipeSize", bus_append_parse_size },
+ { "MessageQueueMessageSize", bus_append_parse_size_i64 },
{ "ExecStartPre", bus_append_exec_command },
{ "ExecStartPost", bus_append_exec_command },
{ "ExecReload", bus_append_exec_command },
return 1;
}
+int config_parse_iec_size_long(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ long *sz = ASSERT_PTR(data);
+ uint64_t v;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = parse_size(rvalue, 1024, &v);
+ if (r >= 0 && v > LONG_MAX)
+ r = -ERANGE;
+ if (r < 0)
+ return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
+
+ *sz = (long) v;
+ return 1;
+}
+
int config_parse_si_uint64(
const char *unit,
const char *filename,
CONFIG_PARSER_PROTOTYPE(config_parse_uint64);
CONFIG_PARSER_PROTOTYPE(config_parse_double);
CONFIG_PARSER_PROTOTYPE(config_parse_iec_size);
+CONFIG_PARSER_PROTOTYPE(config_parse_iec_size_long);
CONFIG_PARSER_PROTOTYPE(config_parse_si_uint64);
CONFIG_PARSER_PROTOTYPE(config_parse_iec_uint64);
CONFIG_PARSER_PROTOTYPE(config_parse_iec_uint64_infinity);
/* 64-bit integer properties */
"MessageQueueMaxMessages=10",
- "MessageQueueMessageSize=8192",
/* Timespan properties */
"TimeoutSec=90s",
"ReceiveBuffer=512K",
"SendBuffer=1.M", // TODO: should this accept multiple components?
"PipeSize=512K",
+ "MessageQueueMessageSize=8K",
/* Exec command properties */
"ExecStartPre=true",
ASSERT_EQ(expected, iec_size);
}
+static void test_config_parse_iec_size_long_one(const char *rvalue, long expected) {
+ long iec_size = 0;
+
+ ASSERT_OK(config_parse_iec_size_long(
+ "unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &iec_size, NULL));
+ ASSERT_EQ(expected, iec_size);
+}
+
static void test_config_parse_si_uint64_one(const char *rvalue, uint64_t expected) {
uint64_t si_uint64 = 0;
test_config_parse_iec_size_one("garbage", 0);
}
+TEST(config_parse_iec_size_long) {
+ test_config_parse_iec_size_long_one("1024", 1024);
+ test_config_parse_iec_size_long_one("2K", 2048);
+ test_config_parse_iec_size_long_one("10M", 10 * 1024 * 1024);
+ test_config_parse_iec_size_long_one("1G", 1L * 1024 * 1024 * 1024);
+ test_config_parse_iec_size_long_one("0G", 0);
+ test_config_parse_iec_size_long_one("0", 0);
+
+ test_config_parse_iec_size_long_one("-982", 0);
+ test_config_parse_iec_size_long_one("49874444198739873000000G", 0);
+ test_config_parse_iec_size_long_one("garbage", 0);
+}
+
TEST(config_parse_si_uint64) {
test_config_parse_si_uint64_one("1024", 1024);
test_config_parse_si_uint64_one("2K", 2000);