/run/user/1000
,который, конечно, не существует до тех пор, пока пользователь #1000 не войдет в систему или явно не запустит xyr для управления пользовательскими службами -, является отвлекающим маневром. Весь механизм, который его использует, не должен быть там.
Ошибка #215 этой программы гораздо глубже, чем вы думаете. Этот файл сервисного модуля очень неверен, , как и работа самой программы . Существует много карго-культового программирования, основанного на непонимании основ сервисных единиц systemd.
ExecStart
здесь вызывает запуск служебной программы с некоторыми дополнительными аргументами, 2>&1>
и /dev/null
. main()
является также ненужным мусором, основанным на ошибке демонизации. fork()
ing, а механизм готовности службы не должен указываться как Type=forking
. Как и многие другие программы в реальном мире, эта программа не использует протокол готовности к разветвлению. User=root
не требуется, и действительно, служба должна быть переработана так, чтобы не не требовалось запускать с привилегиями суперпользователя, а скорее запускать под эгидой выделенной непривилегированной учетной записи службы. std::clog
. fork()
до перенаправления стандартной ошибки не должен использоваться. Управление службами обрабатывает все из этого, от руководства сеансом через рабочий каталог и umask до стандартного ввода-вывода, и делает это должным образом. Эта программа этого не делает и не должна пытаться сделать что-либо из этого для себя при использовании под диспетчером служб.Все, что вы взяли из Boost, было неверным.
After
, и их можно просто объединить в один. SuccessExitStatus=SIGKILL
заблуждается. Нормальное завершение должно быть изящным через SIGTERM
, а SIGKILL
следует считать ненормальным. (Конечно, весь output
файловый механизм представляет собой плохо реализованный доморощенный -механизм ведения журнала, который не следует использовать при управлении службами, как уже объяснялось. )Это значение по умолчанию для systemd. main()
с exit()
. Программа-демон, правильно реализованная для работы под менеджером служб, будь то из daemontools, runit, s6, nosh, systemd или чего-то еще, намного короче:
… // the same until this point void pvo_upload(void) { std::clog << "Starting Daemon..." << std::endl; CommonServiceCode(); std::clog << "Stopping Daemon..." << std::endl; } int main(int argc, char *argv[]) { int c; const char *config_file = ""; /* parse commandline */ while(1) { static struct option long_options[] = { { "config-file", required_argument, 0, 'c' }, { 0, 0, 0, 0 } }; int option_index = 0; c = getopt_long (argc, argv, "c:", long_options, &option_index); if (c == -1) break; switch (c) { case 'c': config_file = optarg; break; default: return EXIT_FAILURE; break; } } if (cfg.readSettings(argv[0], config_file) != Configuration::CFG_OK) return EXIT_FAILURE; std::clog << "Starting SBFspotUploadDaemon Version " << VERSION << std::endl; // Check if DB is accessible db_SQL_Base db = db_SQL_Base(); db.open(cfg.getSqlHostname(), cfg.getSqlUsername(), cfg.getSqlPassword(), cfg.getSqlDatabase()); if (!db.isopen()) { std::clog << "Unable to open database. Check configuration." << std::endl; return EXIT_FAILURE; } // Check DB Version int schema_version = 0; db.get_config(SQL_SCHEMAVERSION, schema_version); db.close(); if (schema_version < SQL_MINIMUM_SCHEMA_VERSION) { std::clog << "Upgrade your database to version " << SQL_MINIMUM_SCHEMA_VERSION << std::endl; return EXIT_FAILURE; } // Install our signal handler. // This responds to the service manager signalling the service to stop. signal(SIGTERM, handler); // Start daemon loop pvo_upload(); return EXIT_SUCCESS; }
И служебный блок тоже короче:
[Unit] Description=SBFspot upload daemon After=mysql.service mariadb.service network.target [Service] Type=simple TimeoutStopSec=10 ExecStart=/usr/local/bin/sbfspot.3/SBFspotUploadDaemon Restart=on-success [Install] WantedBy=multi-user.target
Вывод журнала можно просмотреть с помощью systemctl status
иjournalctl
(с опцией -u
и именем службы, если необходимо ).
logrotate
или newsyslog
в этом столетии.. Часто задаваемые ответы. Так как я мог видеть входящие пакеты, я заглянул в гостевые iptables, чтобы увидеть, что происходит, и оказалось, что весь трафик сбрасывался. Добавил к нему простое правило, и теперь я могу использовать ssh, надеюсь, это поможет кому-то еще.
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT