| 507 | namespace |
| 508 | { |
| 509 | int start(const std::string & user, const fs::path & executable, const fs::path & config, const fs::path & pid_file) |
| 510 | { |
| 511 | if (fs::exists(pid_file)) |
| 512 | { |
| 513 | ReadBufferFromFile in(pid_file.string()); |
| 514 | UInt64 pid; |
| 515 | if (tryReadIntText(pid, in)) |
| 516 | { |
| 517 | fmt::print("{} file exists and contains pid = {}.\n", pid_file.string(), pid); |
| 518 | |
| 519 | if (0 == kill(pid, 0)) |
| 520 | { |
| 521 | fmt::print("The process with pid = {} is already running.\n", pid); |
| 522 | return 2; |
| 523 | } |
| 524 | } |
| 525 | else |
| 526 | { |
| 527 | fmt::print("{} file exists but damaged, ignoring.\n", pid_file.string()); |
| 528 | fs::remove(pid_file); |
| 529 | } |
| 530 | } |
| 531 | else |
| 532 | { |
| 533 | /// Create a directory for pid file. |
| 534 | /// It's created by "install" but we also support cases when ClickHouse is already installed different way. |
| 535 | fs::path pid_path = pid_file; |
| 536 | pid_path.remove_filename(); |
| 537 | fs::create_directories(pid_path); |
| 538 | /// All users are allowed to read pid file (for clickhouse status command). |
| 539 | fs::permissions(pid_path, fs::perms::owner_all | fs::perms::group_read | fs::perms::others_read, fs::perm_options::replace); |
| 540 | |
| 541 | { |
| 542 | std::string command = fmt::format("chown --recursive {} '{}'", user, pid_path.string()); |
| 543 | fmt::print(" {}\n", command); |
| 544 | executeScript(command); |
| 545 | } |
| 546 | } |
| 547 | |
| 548 | std::string command = fmt::format("{} --config-file {} --pid-file {} --daemon", |
| 549 | executable.string(), config.string(), pid_file.string()); |
| 550 | |
| 551 | if (!user.empty()) |
| 552 | { |
| 553 | bool may_need_sudo = geteuid() != 0; |
| 554 | if (may_need_sudo) |
| 555 | { |
| 556 | struct passwd *p = getpwuid(geteuid()); |
| 557 | // Only use sudo when we are not the given user |
| 558 | if (p == nullptr || std::string(p->pw_name) != user) |
| 559 | command = fmt::format("sudo -u '{}' {}", user, command); |
| 560 | } |
| 561 | else |
| 562 | command = fmt::format("su -s /bin/sh '{}' -c '{}'", user, command); |
| 563 | } |
| 564 | |
| 565 | fmt::print("Will run {}\n", command); |
| 566 | executeScript(command, true); |
no test coverage detected