| 267 | |
| 268 | |
| 269 | BlockIO InterpreterSystemQuery::execute() |
| 270 | { |
| 271 | auto & query = query_ptr->as<ASTSystemQuery &>(); |
| 272 | |
| 273 | if (!query.cluster.empty()) |
| 274 | return executeDDLQueryOnCluster(query_ptr, getContext(), getRequiredAccessForDDLOnCluster()); |
| 275 | |
| 276 | using Type = ASTSystemQuery::Type; |
| 277 | |
| 278 | /// Use global context with fresh system profile settings |
| 279 | auto system_context = Context::createCopy(getContext()->getGlobalContext()); |
| 280 | system_context->setSetting("profile", getContext()->getSystemProfileName()); |
| 281 | |
| 282 | /// Make canonical query for simpler processing |
| 283 | if (query.type == Type::RELOAD_DICTIONARY) |
| 284 | { |
| 285 | if (!query.database.empty()) |
| 286 | query.table = query.database + "." + query.table; |
| 287 | } |
| 288 | else if (!query.table.empty()) |
| 289 | { |
| 290 | table_id = getContext()->resolveStorageID(StorageID(query.database, query.table), Context::ResolveOrdinary); |
| 291 | } |
| 292 | |
| 293 | |
| 294 | volume_ptr = {}; |
| 295 | if (!query.storage_policy.empty() && !query.volume.empty()) |
| 296 | volume_ptr = getContext()->getStoragePolicy(query.storage_policy)->getVolumeByName(query.volume, true); |
| 297 | |
| 298 | /// Common system command |
| 299 | switch (query.type) |
| 300 | { |
| 301 | case Type::SHUTDOWN: |
| 302 | { |
| 303 | getContext()->checkAccess(AccessType::SYSTEM_SHUTDOWN); |
| 304 | if (kill(0, SIGTERM)) |
| 305 | throwFromErrno("System call kill(0, SIGTERM) failed", ErrorCodes::CANNOT_KILL); |
| 306 | break; |
| 307 | } |
| 308 | case Type::KILL: |
| 309 | { |
| 310 | getContext()->checkAccess(AccessType::SYSTEM_SHUTDOWN); |
| 311 | /// Exit with the same code as it is usually set by shell when process is terminated by SIGKILL. |
| 312 | /// It's better than doing 'raise' or 'kill', because they have no effect for 'init' process (with pid = 0, usually in Docker). |
| 313 | LOG_INFO(log, "Exit immediately as the SYSTEM KILL command has been issued."); |
| 314 | _exit(128 + SIGKILL); |
| 315 | // break; /// unreachable |
| 316 | } |
| 317 | case Type::SUSPEND: |
| 318 | { |
| 319 | auto command = fmt::format("kill -STOP {0} && sleep {1} && kill -CONT {0}", getpid(), query.seconds); |
| 320 | LOG_DEBUG(log, "Will run {}", command); |
| 321 | auto res = ShellCommand::execute(command); |
| 322 | res->in.close(); |
| 323 | WriteBufferFromOwnString out; |
| 324 | copyData(res->out, out); |
| 325 | copyData(res->err, out); |
| 326 | if (!out.str().empty()) |
nothing calls this directly
no test coverage detected