!551 systemd: avoid calling manager_status_printf to reduce the size of systemd-shutdown
From: @ship_harbour Reviewed-by: @licunlong Signed-off-by: @licunlong
This commit is contained in:
commit
fed1f3cbfb
@ -4,7 +4,7 @@ Date: Thu, 2 Sep 2021 12:14:19 +0800
|
||||
Subject: [PATCH] print process status to console when shutdown
|
||||
|
||||
---
|
||||
meson.build | 6 +-
|
||||
meson.build | 2 +-
|
||||
src/basic/process-util.c | 58 ++++
|
||||
src/basic/process-util.h | 2 +
|
||||
src/core/fuser.c | 506 +++++++++++++++++++++++++++++++++
|
||||
@ -16,14 +16,14 @@ Subject: [PATCH] print process status to console when shutdown
|
||||
src/core/meson.build | 2 +
|
||||
src/core/system.conf.in | 1 +
|
||||
src/shutdown/meson.build | 10 +-
|
||||
src/shutdown/process-status.c | 143 ++++++++++
|
||||
src/shutdown/process-status.h | 24 ++
|
||||
src/shutdown/shutdown.c | 45 +++
|
||||
src/shutdown/umount.c | 8 +-
|
||||
src/shutdown/process-status.c | 131 +++++++++
|
||||
src/shutdown/process-status.h | 22 ++
|
||||
src/shutdown/shutdown.c | 50 ++++
|
||||
src/shutdown/umount.c | 5 +-
|
||||
src/test/meson.build | 17 ++
|
||||
src/test/test-fuser.c | 14 +
|
||||
src/test/test-process-status.c | 10 +
|
||||
19 files changed, 945 insertions(+), 8 deletions(-)
|
||||
19 files changed, 930 insertions(+), 7 deletions(-)
|
||||
create mode 100644 src/core/fuser.c
|
||||
create mode 100644 src/core/fuser.h
|
||||
create mode 100644 src/shutdown/process-status.c
|
||||
@ -32,27 +32,23 @@ Subject: [PATCH] print process status to console when shutdown
|
||||
create mode 100644 src/test/test-process-status.c
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 1c088ba..278e264 100644
|
||||
index b04551f..32e8aeb 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -3211,8 +3211,10 @@ public_programs += executable(
|
||||
@@ -3211,7 +3211,7 @@ public_programs += executable(
|
||||
executable(
|
||||
'systemd-shutdown',
|
||||
systemd_shutdown_sources,
|
||||
- include_directories : includes,
|
||||
- link_with : [libshared],
|
||||
+ include_directories : [includes,
|
||||
+ core_includes],
|
||||
+ link_with : [libcore,
|
||||
+ libshared],
|
||||
+ include_directories : [includes],
|
||||
link_with : [libshared],
|
||||
dependencies : [libmount],
|
||||
install_rpath : rootlibexecdir,
|
||||
install : true,
|
||||
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
|
||||
index 14259ea..e28412a 100644
|
||||
index 10651a4..018cbb5 100644
|
||||
--- a/src/basic/process-util.c
|
||||
+++ b/src/basic/process-util.c
|
||||
@@ -1729,3 +1729,61 @@ static const char* const sched_policy_table[] = {
|
||||
@@ -1733,3 +1733,61 @@ static const char* const sched_policy_table[] = {
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
|
||||
@ -126,7 +122,7 @@ index 0e064de..6f9b577 100644
|
||||
+unsigned int read_cmdline(char *restrict const dst, unsigned sz, const char* whom, const char *what, char sep);
|
||||
diff --git a/src/core/fuser.c b/src/core/fuser.c
|
||||
new file mode 100644
|
||||
index 0000000..0a0c791
|
||||
index 0000000..afb0e9b
|
||||
--- /dev/null
|
||||
+++ b/src/core/fuser.c
|
||||
@@ -0,0 +1,506 @@
|
||||
@ -698,7 +694,7 @@ index 0000000..b74b879
|
||||
+
|
||||
+int fuser(const char *dir);
|
||||
diff --git a/src/core/job.c b/src/core/job.c
|
||||
index eb6728a..3645c11 100644
|
||||
index afdc394..444f270 100644
|
||||
--- a/src/core/job.c
|
||||
+++ b/src/core/job.c
|
||||
@@ -27,6 +27,9 @@
|
||||
@ -759,7 +755,7 @@ index eb6728a..3645c11 100644
|
||||
|
||||
static int job_perform_on_unit(Job **j) {
|
||||
diff --git a/src/core/main.c b/src/core/main.c
|
||||
index 8de32a7..2a6b9b8 100644
|
||||
index 801e64b..6fe696c 100644
|
||||
--- a/src/core/main.c
|
||||
+++ b/src/core/main.c
|
||||
@@ -114,6 +114,7 @@ static bool arg_dump_core;
|
||||
@ -770,7 +766,7 @@ index 8de32a7..2a6b9b8 100644
|
||||
static char *arg_confirm_spawn;
|
||||
static ShowStatus arg_show_status;
|
||||
static StatusUnitFormat arg_status_unit_format;
|
||||
@@ -645,6 +646,7 @@ static int parse_config_file(void) {
|
||||
@@ -654,6 +655,7 @@ static int parse_config_file(void) {
|
||||
{ "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt },
|
||||
{ "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
|
||||
{ "Manager", "CrashReboot", config_parse_bool, 0, &arg_crash_reboot },
|
||||
@ -778,7 +774,7 @@ index 8de32a7..2a6b9b8 100644
|
||||
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
|
||||
{ "Manager", "StatusUnitFormat", config_parse_status_unit_format, 0, &arg_status_unit_format },
|
||||
{ "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity },
|
||||
@@ -756,6 +758,7 @@ static void set_manager_defaults(Manager *m) {
|
||||
@@ -765,6 +767,7 @@ static void set_manager_defaults(Manager *m) {
|
||||
m->default_restart_usec = arg_default_restart_usec;
|
||||
m->default_start_limit_interval = arg_default_start_limit_interval;
|
||||
m->default_start_limit_burst = arg_default_start_limit_burst;
|
||||
@ -786,7 +782,7 @@ index 8de32a7..2a6b9b8 100644
|
||||
|
||||
/* On 4.15+ with unified hierarchy, CPU accounting is essentially free as it doesn't require the CPU
|
||||
* controller to be enabled, so the default is to enable it unless we got told otherwise. */
|
||||
@@ -1473,18 +1476,20 @@ static int become_shutdown(
|
||||
@@ -1482,18 +1485,20 @@ static int become_shutdown(
|
||||
|
||||
char log_level[DECIMAL_STR_MAX(int) + 1],
|
||||
exit_code[DECIMAL_STR_MAX(uint8_t) + 1],
|
||||
@ -810,7 +806,7 @@ index 8de32a7..2a6b9b8 100644
|
||||
int r;
|
||||
usec_t watchdog_timer = 0;
|
||||
|
||||
@@ -1494,6 +1499,7 @@ static int become_shutdown(
|
||||
@@ -1503,6 +1508,7 @@ static int become_shutdown(
|
||||
|
||||
xsprintf(log_level, "%d", log_get_max_level());
|
||||
xsprintf(timeout, "%" PRI_USEC "us", arg_default_timeout_stop_usec);
|
||||
@ -818,7 +814,7 @@ index 8de32a7..2a6b9b8 100644
|
||||
|
||||
switch (log_get_target()) {
|
||||
|
||||
@@ -2325,6 +2331,7 @@ static void reset_arguments(void) {
|
||||
@@ -2381,6 +2387,7 @@ static void reset_arguments(void) {
|
||||
arg_crash_chvt = -1;
|
||||
arg_crash_shell = false;
|
||||
arg_crash_reboot = false;
|
||||
@ -827,10 +823,10 @@ index 8de32a7..2a6b9b8 100644
|
||||
arg_show_status = _SHOW_STATUS_INVALID;
|
||||
arg_status_unit_format = STATUS_UNIT_FORMAT_DEFAULT;
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index 3a12d6d..29ef96b 100644
|
||||
index 5196619..65ae8bb 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -771,6 +771,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
||||
@@ -740,6 +740,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
||||
*m = (Manager) {
|
||||
.unit_file_scope = scope,
|
||||
.objective = _MANAGER_OBJECTIVE_INVALID,
|
||||
@ -839,7 +835,7 @@ index 3a12d6d..29ef96b 100644
|
||||
.status_unit_format = STATUS_UNIT_FORMAT_DEFAULT,
|
||||
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||
index dada79c..c20abd5 100644
|
||||
index 92190c8..6dd18a4 100644
|
||||
--- a/src/core/manager.h
|
||||
+++ b/src/core/manager.h
|
||||
@@ -335,6 +335,8 @@ struct Manager {
|
||||
@ -852,7 +848,7 @@ index dada79c..c20abd5 100644
|
||||
|
||||
/* If non-zero, exit with the following value when the systemd
|
||||
diff --git a/src/core/meson.build b/src/core/meson.build
|
||||
index f0d2c6f..825eede 100644
|
||||
index 367c085..e98c980 100644
|
||||
--- a/src/core/meson.build
|
||||
+++ b/src/core/meson.build
|
||||
@@ -127,6 +127,8 @@ libcore_sources = '''
|
||||
@ -903,10 +899,10 @@ index e1348d9..12fbef3 100644
|
||||
]
|
||||
diff --git a/src/shutdown/process-status.c b/src/shutdown/process-status.c
|
||||
new file mode 100644
|
||||
index 0000000..11837a2
|
||||
index 0000000..f5a3293
|
||||
--- /dev/null
|
||||
+++ b/src/shutdown/process-status.c
|
||||
@@ -0,0 +1,143 @@
|
||||
@@ -0,0 +1,131 @@
|
||||
+#include "process-status.h"
|
||||
+#include "process-util.h"
|
||||
+
|
||||
@ -932,14 +928,12 @@ index 0000000..11837a2
|
||||
+
|
||||
+ r = snprintf(pathname, sizeof(pathname), "/proc/%d", pid);
|
||||
+ if (r <= 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Can't snprintf /proc/%d.", pid);
|
||||
+ log_error("[systemd-shutdown] Can't snprintf /proc/%d.", pid);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (stat(pathname, &st) != 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Can't stat %s.", pathname);
|
||||
+ log_error("[systemd-shutdown] Can't stat %s.", pathname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
@ -947,30 +941,26 @@ index 0000000..11837a2
|
||||
+
|
||||
+ r = snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
|
||||
+ if (r <= 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Can't snprintf /proc/%d/stat.", pid);
|
||||
+ log_error("[systemd-shutdown] Can't snprintf /proc/%d/stat.", pid);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fd = open(buf, O_RDONLY, 0);
|
||||
+ if (fd == -1) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Can't open %s.", buf);
|
||||
+ log_error("Can't open %s.", buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ r = read(fd, buf, sizeof(buf) - 1);
|
||||
+ if (r < 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Can't read /proc/%d/stat.", pid);
|
||||
+ log_error("[systemd-shutdown] Can't read /proc/%d/stat.", pid);
|
||||
+ close(fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ r = sscanf(buf, "%d %s %s %d", &P_pid, P_cmd_short, P_stat, &P_ppid);
|
||||
+ if (r < 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Can't run sscanf.");
|
||||
+ log_error("[systemd-shutdown] Can't run sscanf.");
|
||||
+ close(fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
@ -982,7 +972,7 @@ index 0000000..11837a2
|
||||
+
|
||||
+ r = snprintf(cmd_path, sizeof(cmd_path), "/proc/%d", pid);
|
||||
+ if (r <= 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Can't snprintf /proc/%d.", pid);
|
||||
+ log_error("[systemd-shutdown] Can't snprintf /proc/%d.", pid);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
@ -1006,28 +996,23 @@ index 0000000..11837a2
|
||||
+static void print_proc(void) {
|
||||
+ if ((P_ppid != KTHREADD) && (strcmp(P_cmd_short, "(kthreadd)") != 0)) {
|
||||
+ if (strlen(P_cmd_long) != 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL,"systemd-shutdown",
|
||||
+ "%-s\t%-d\t%-d\t%-s", P_user, P_pid, P_ppid, P_cmd_long);
|
||||
+ log_info("[systemd-shutdown] %-s\t%-d\t%-d\t%-s", P_user, P_pid, P_ppid, P_cmd_long);
|
||||
+ } else {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL,"systemd-shutdown",
|
||||
+ "%-s\t%-d\t%-d\t%-s", P_user, P_pid, P_ppid, P_cmd_short);
|
||||
+ log_info("[systemd-shutdown] %-s\t%-d\t%-d\t%-s", P_user, P_pid, P_ppid, P_cmd_short);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int process_status(void) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL,"systemd-shutdown",
|
||||
+ "%s", "-----------------------------------------------------------------");
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL,"systemd-shutdown",
|
||||
+ "%s", "USER\tPID\tPPID\tCMD");
|
||||
+ log_info("[systemd-shutdown] -----------------------------------------------------------------");
|
||||
+ log_info("[systemd-shutdown] USER\tPID\tPPID\tCMD");
|
||||
+
|
||||
+ struct dirent *ent = NULL;
|
||||
+ DIR *dir = NULL;
|
||||
+
|
||||
+ dir = opendir("/proc");
|
||||
+ if (dir == NULL) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL,"systemd-shutdown",
|
||||
+ "%s", "can't open /proc");
|
||||
+ log_error("[systemd-shutdown] can't open /proc");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
@ -1045,17 +1030,16 @@ index 0000000..11837a2
|
||||
+
|
||||
+ closedir(dir);
|
||||
+
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL,"systemd-shutdown",
|
||||
+ "%s", "------------------------------------------------------------------");
|
||||
+ log_info("[systemd-shutdown] -----------------------------------------------------------------");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/shutdown/process-status.h b/src/shutdown/process-status.h
|
||||
new file mode 100644
|
||||
index 0000000..2f4333d
|
||||
index 0000000..c0b4835
|
||||
--- /dev/null
|
||||
+++ b/src/shutdown/process-status.h
|
||||
@@ -0,0 +1,24 @@
|
||||
@@ -0,0 +1,22 @@
|
||||
+#pragma once
|
||||
+
|
||||
+#include <fcntl.h>
|
||||
@ -1069,8 +1053,6 @@ index 0000000..2f4333d
|
||||
+#include <limits.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "manager.h"
|
||||
+
|
||||
+#define COMM_LEN 512
|
||||
+
|
||||
+#ifndef PATH_MAX
|
||||
@ -1081,7 +1063,7 @@ index 0000000..2f4333d
|
||||
+
|
||||
+int process_status(void);
|
||||
diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c
|
||||
index a98cfc4..1ad6fa0 100644
|
||||
index a98cfc4..1c17fe1 100644
|
||||
--- a/src/shutdown/shutdown.c
|
||||
+++ b/src/shutdown/shutdown.c
|
||||
@@ -38,13 +38,17 @@
|
||||
@ -1142,7 +1124,7 @@ index a98cfc4..1ad6fa0 100644
|
||||
|
||||
/* The log target defaults to console, but the original systemd process will pass its log target in through a
|
||||
* command line argument, which will override this default. Also, ensure we'll never log to the journal or
|
||||
@@ -405,8 +421,37 @@ int main(int argc, char *argv[]) {
|
||||
@@ -405,8 +421,42 @@ int main(int argc, char *argv[]) {
|
||||
need_md_detach = !in_container;
|
||||
can_initrd = !in_container && !in_initrd() && access("/run/initramfs/shutdown", X_OK) == 0;
|
||||
|
||||
@ -1151,16 +1133,19 @@ index a98cfc4..1ad6fa0 100644
|
||||
/* Unmount all mountpoints, swaps, and loopback devices */
|
||||
for (;;) {
|
||||
+ if (dfx_reboot && (now(CLOCK_MONOTONIC) >= now_time + time_interval)) {
|
||||
+ LogTarget origin_target = log_get_target();
|
||||
+ log_set_target(LOG_TARGET_CONSOLE);
|
||||
+ log_open();
|
||||
+
|
||||
+ r = safe_fork("(process_status)", FORK_RESET_SIGNALS, &pid);
|
||||
+ if (r < 0) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
|
||||
+ "Failed to fork for process_status!");
|
||||
+ log_error("Failed to fork for process_status!");
|
||||
+ fork_failed = true;
|
||||
+ }
|
||||
+ if (r == 0) {
|
||||
+ r = process_status();
|
||||
+ if (r < 0)
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Can't run ps.");
|
||||
+ log_error("Can't run ps.");
|
||||
+
|
||||
+ _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
+ }
|
||||
@ -1171,54 +1156,39 @@ index a98cfc4..1ad6fa0 100644
|
||||
+ if (!fork_failed) {
|
||||
+ r = wait_for_terminate_with_timeout(pid, 3 * USEC_PER_SEC);
|
||||
+ if (r == -ETIMEDOUT) {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Timeout to run (process_status).");
|
||||
+ log_error("Timeout to run (process_status).");
|
||||
+ (void) kill(pid, SIGKILL);
|
||||
+ }
|
||||
+ }
|
||||
+ log_set_target(origin_target);
|
||||
+ log_open();
|
||||
+ }
|
||||
+
|
||||
bool changed = false;
|
||||
|
||||
if (use_watchdog)
|
||||
diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
|
||||
index c2a2624..1541bcc 100644
|
||||
index 1f945b7..5681078 100644
|
||||
--- a/src/shutdown/umount.c
|
||||
+++ b/src/shutdown/umount.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "umount.h"
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
+#include "manager.h"
|
||||
|
||||
static void mount_point_free(MountPoint **head, MountPoint *m) {
|
||||
assert(head);
|
||||
@@ -553,6 +554,7 @@ static int umount_with_timeout(MountPoint *m, int umount_log_level) {
|
||||
return r;
|
||||
if (r == 0) {
|
||||
log_info("Unmounting '%s'.", m->path);
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Unmounting '%s'.", m->path);
|
||||
|
||||
/* Start the mount operation here in the child Using MNT_FORCE
|
||||
* causes some filesystems (e.g. FUSE and NFS and other network
|
||||
@@ -562,8 +564,12 @@ static int umount_with_timeout(MountPoint *m, int umount_log_level) {
|
||||
@@ -574,8 +574,11 @@ static int umount_with_timeout(MountPoint *m, int umount_log_level) {
|
||||
* filesystem less busy so the unmount might succeed (rather
|
||||
* than return EBUSY). */
|
||||
r = umount2(m->path, MNT_FORCE);
|
||||
- if (r < 0)
|
||||
+ if (r < 0) {
|
||||
log_full_errno(umount_log_level, errno, "Failed to unmount %s: %m", m->path);
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Failed to unmount '%s'.", m->path);
|
||||
+ } else {
|
||||
+ manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Unmounted '%s'.", m->path);
|
||||
+ log_info("Unmounted '%s'.", m->path);
|
||||
+ }
|
||||
|
||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
diff --git a/src/test/meson.build b/src/test/meson.build
|
||||
index 561386d..09c5298 100644
|
||||
index 870649a..67a31e1 100644
|
||||
--- a/src/test/meson.build
|
||||
+++ b/src/test/meson.build
|
||||
@@ -616,6 +616,23 @@ tests += [
|
||||
@@ -619,6 +619,23 @@ tests += [
|
||||
libshared],
|
||||
[],
|
||||
core_includes],
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
Name: systemd
|
||||
Url: https://www.freedesktop.org/wiki/Software/systemd
|
||||
Version: 249
|
||||
Release: 67
|
||||
Release: 68
|
||||
License: MIT and LGPLv2+ and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
|
||||
@ -2131,6 +2131,9 @@ grep -q -E '^KEYMAP="?fi-latin[19]"?' /etc/vconsole.conf 2>/dev/null &&
|
||||
%{_libdir}/security/pam_systemd.so
|
||||
|
||||
%changelog
|
||||
* Mon Feb 26 2024 jiangchuangang <jiangchuangang@huawei.com> - 249-68
|
||||
- avoid calling manager_status_printf to reduce the size of systemd-shutdown
|
||||
|
||||
* Thu Feb 22 2024 wangyuhang <wangyuhang27@huawei.com> - 249-67
|
||||
- backport: sync patches from systemd community
|
||||
add backport-journal-recalculate-line_max-when-stdout-stream-stat.patch
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user