Skip to content

Commit 6eacec5

Browse files
committed
exmdb: add unique per-process identifier for eml object filenames
Cure a case of E-5310 appearing in log messages which can happen if lib/ruleproc.cpp processes a OP_MOVE/OP_COPY rule. E-5310: link /var/lib/gromox/user/horio/eml/1753728954.1.a4.inai.de -> /var/lib/gromox/user/horio/eml/1753728954.1.a4.inai.de: File exists exmdb's copy_eml_ext() is prone to derive a new_name that is equal to old_name. gromox-delivery creates e.g. 1234567890.1.hostname, and exmdb can too if their sequence number lines up.
1 parent a982690 commit 6eacec5

File tree

9 files changed

+37
-13
lines changed

9 files changed

+37
-13
lines changed

Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ libgxm_alias_resolve_la_LIBADD = -lpthread ${libHX_LIBS} ${mysql_LIBS} libgromox
103103
EXTRA_libgxm_alias_resolve_la_DEPENDENCIES = default.sym
104104
libgxm_exmdb_local_la_SOURCES = lib/bounce_mda.cpp mda/exmdb_local/auto_response.cpp mda/exmdb_local/bounce_audit.cpp mda/exmdb_local/bounce_producer.cpp mda/exmdb_local/cache_queue.cpp mda/exmdb_local/exmdb_local.cpp mda/exmdb_local/exmdb_local.hpp
105105
libgxm_exmdb_local_la_LDFLAGS = ${default_SYFLAGS}
106-
libgxm_exmdb_local_la_LIBADD = -lpthread ${libHX_LIBS} ${jsoncpp_LIBS} libgromox_common.la libgromox_exrpc.la libgromox_mapi.la libgxs_mysql_adaptor.la
106+
libgxm_exmdb_local_la_LIBADD = -lpthread ${fmt_LIBS} ${libHX_LIBS} ${jsoncpp_LIBS} libgromox_common.la libgromox_exrpc.la libgromox_mapi.la libgxs_mysql_adaptor.la
107107
EXTRA_libgxm_exmdb_local_la_DEPENDENCIES = default.sym
108108

109109
pop3_SOURCES = mra/pop3/cmd.cpp mra/pop3/main.cpp mra/pop3/parser.cpp mra/pop3/pop3.hpp mra/pop3/resource.cpp

exch/exmdb/common_util.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4696,7 +4696,7 @@ BOOL common_util_check_message_owner(sqlite3 *psqlite,
46964696
static errno_t copy_eml_ext(const char *old_midstr, std::string &new_midstr) try
46974697
{
46984698
auto basedir = exmdb_server::get_dir();
4699-
new_midstr = fmt::format("{}.{}.{}", time(nullptr), common_util_sequence_ID(), get_host_ID());
4699+
new_midstr = fmt::format("{}.x{}.{}", time(nullptr), common_util_sequence_ID(), get_host_ID());
47004700
auto old_eml = fmt::format("{}/eml/{}", basedir, old_midstr);
47014701
auto new_eml = fmt::format("{}/eml/{}", basedir, new_midstr);
47024702
/*

exch/exmdb/message.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3099,9 +3099,8 @@ static ec_error_t op_delegate(const rulexec_in &rp, seen_list &seen,
30993099
tmp_path1, eaddr.c_str());
31003100
continue;
31013101
}
3102-
auto mid_string = std::to_string(time(nullptr)) + "." +
3103-
std::to_string(common_util_sequence_ID()) + "." +
3104-
get_host_ID();
3102+
auto mid_string = fmt::format("{}.x{}.{}", time(nullptr),
3103+
common_util_sequence_ID(), get_host_ID());
31053104
auto eml_path = maildir + "/eml/"s + mid_string;
31063105
auto ret = HX_copy_file(tmp_path1, eml_path.c_str(), 0);
31073106
if (ret < 0) {
@@ -3406,9 +3405,8 @@ static ec_error_t opx_delegate(const rulexec_in &rp, const rule_node &rule,
34063405
if (mysql_adaptor_meta(eaddr.c_str(), WANTPRIV_METAONLY, mres) != 0)
34073406
continue;
34083407
auto maildir = mres.maildir.c_str();
3409-
auto mid_string = std::to_string(time(nullptr)) + "." +
3410-
std::to_string(common_util_sequence_ID()) + "." +
3411-
get_host_ID();
3408+
auto mid_string = fmt::format("{}.x{}.{}", time(nullptr),
3409+
common_util_sequence_ID(), get_host_ID());
34123410
auto eml_path = maildir + "/eml/"s + mid_string;
34133411
auto ret = HX_copy_file(tmp_path1, eml_path.c_str(), 0);
34143412
if (ret < 0) {

exch/midb/mail_engine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ static void me_insert_message(xstmt &stm_insert, uint32_t *puidnext,
13681368
return;
13691369
digest["file"] = "";
13701370
djson = json_to_str(digest);
1371-
e.midstr = std::to_string(time(nullptr)) + "." + std::to_string(++g_sequence_id) + ".midb";
1371+
e.midstr = fmt::format("{}.m{}.{}", time(nullptr), ++g_sequence_id, g_host_id);
13721372
if (!exmdb_client->imapfile_write(dir, "ext", e.midstr, djson)) {
13731373
mlog(LV_ERR, "E-1770: imapfile_write %s/ext/%s incomplete", dir, e.midstr.c_str());
13741374
return;

exch/midb/mail_engine.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ extern void me_stop();
1212

1313
extern unsigned int g_midb_schema_upgrades;
1414
extern unsigned int g_midb_cache_interval, g_midb_reload_interval;
15+
extern std::string g_host_id;

exch/midb/main.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void (*system_services_broadcast_event)(const char*);
5353

5454
static gromox::atomic_bool g_main_notify_stop, g_listener_notify_stop;
5555
std::shared_ptr<CONFIG_FILE> g_config_file;
56+
std::string g_host_id;
5657
static char *opt_config_file;
5758
static unsigned int opt_show_version;
5859
static gromox::atomic_bool g_hup_signalled;
@@ -307,6 +308,18 @@ int main(int argc, char **argv)
307308
if (!midb_reload_config(gxconfig, pconfig))
308309
return EXIT_FAILURE;
309310

311+
auto str_val = g_config_file->get_value("host_id");
312+
if (str_val == nullptr) {
313+
std::string hn;
314+
auto ret = canonical_hostname(hn);
315+
if (ret != 0)
316+
return EXIT_FAILURE;
317+
g_config_file->set_value("host_id", hn.c_str());
318+
g_host_id = std::move(hn);
319+
} else {
320+
g_host_id = str_val;
321+
}
322+
310323
int proxy_num = pconfig->get_ll("rpc_proxy_connection_num");
311324
mlog(LV_INFO, "system: exmdb proxy connection number is %d", proxy_num);
312325

mda/exmdb_local/exmdb_local.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <string>
1515
#include <unistd.h>
1616
#include <vector>
17+
#include <fmt/core.h>
1718
#include <libHX/string.h>
1819
#include <sys/stat.h>
1920
#include <gromox/bounce_gen.hpp>
@@ -286,8 +287,7 @@ delivery_status exmdb_local_deliverquota(MESSAGE_CONTEXT *pcontext,
286287
else
287288
hostname[std::size(hostname)-1] = '\0';
288289
}
289-
auto mid_string = std::to_string(time(nullptr)) + "." +
290-
std::to_string(sequence_ID) + "." + hostname;
290+
auto mid_string = fmt::format("{}.l{}.{}", time(nullptr), sequence_ID, hostname);
291291
auto eml_path = mres.maildir + "/eml/" + mid_string;
292292
wrapfd fd = open(eml_path.c_str(), O_CREAT | O_RDWR | O_TRUNC, FMODE_PRIVATE);
293293
if (fd.get() < 0) {

mra/imap/cmd.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2113,7 +2113,7 @@ static int icp_long_append_begin2(int argc, char **argv, imap_context &ctx) try
21132113
return 1800 | DISPATCH_BREAK;
21142114
}
21152115
auto pcontext = &ctx;
2116-
pcontext->mid = fmt::format("{}.{}.{}",
2116+
pcontext->mid = fmt::format("{}.i{}.{}",
21172117
time(nullptr), imap_parser_get_sequence_ID(),
21182118
znul(g_config_file->get_value("host_id")));
21192119
ctx.append_stream.clear();

tools/mbsize.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ static double ratio_sav(double old, double nu)
8888
return 100 * (1 - nu / old);
8989
}
9090

91+
static bool looks_like_midb_generated(const char *name)
92+
{
93+
auto dot = strchr(name, '.');
94+
if (dot == nullptr)
95+
return false;
96+
if (dot[1] == 'm' && strtoul(&dot[2], nullptr, 10) != 0)
97+
return true;
98+
if (class_match_suffix(name, ".midb") == 0)
99+
return true;
100+
return false;
101+
}
102+
91103
static struct rfc_stat rfc_count(const std::string &dirname)
92104
{
93105
struct rfc_stat out;
@@ -111,7 +123,7 @@ static struct rfc_stat rfc_count(const std::string &dirname)
111123
if (fstatat(dfd, name, &sb, 0) != 0 ||
112124
!S_ISREG(sb.st_mode))
113125
continue;
114-
if (class_match_suffix(name, ".midb") == 0)
126+
if (looks_like_midb_generated(name))
115127
out.sent += sb;
116128
else
117129
out.recv += sb;

0 commit comments

Comments
 (0)