Initial commit
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
From d48ec5e1a5fb7907520dee71b1d94045486a0c29 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Kamensky <alexander.kamensky42@gmail.com>
|
||||
Date: Thu, 12 Nov 2020 12:56:46 -0800
|
||||
Subject: [PATCH] arm64: kexec: disabled check if kaslr-seed dtb property was
|
||||
wiped
|
||||
|
||||
Kexec when loading arm64 kernel checks if chosen/kaslr-seed dtb property is
|
||||
wiped. It's a good assertion to verify proper behavior of kernel. However,
|
||||
if bootloader creates and fills kaslr-seed property and kernel is not
|
||||
configured with CONFIG_RANDOMIZE_BASE then logic of reading and wiping
|
||||
kaslr-seed does not run. As a result kaslr-seed property is not zero and when
|
||||
kexec tries to load secondary kernel it fails with the following message:
|
||||
|
||||
setup_2nd_dtb: kaslr-seed is not wiped to 0.
|
||||
kexec: setup_2nd_dtb failed.
|
||||
kexec: load failed.
|
||||
|
||||
This was observed on Yocto Project on qemuarm64 machine with 5.8 kernel,
|
||||
qemu 5.1.0. Qemu created kaslr-seed property but kernel was not configured
|
||||
with CONFIG_RANDOMIZE_BASE.
|
||||
|
||||
Although check has some value, there is a use-case where it breaks kexec,
|
||||
this patch removes it.
|
||||
|
||||
Note in described use-case the fact that kaslr-seed is not wiped and user
|
||||
readable through /sys/firmware/fdt or
|
||||
/sys/firmware/devicetree/base/chosen/kaslr-seed is not a security problem
|
||||
as kaslr is disabled anyway.
|
||||
|
||||
Signed-off-by: Alexander Kamensky <alexander.kamensky42@gmail.com>
|
||||
Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2020-November/021740.html]
|
||||
---
|
||||
kexec/arch/arm64/kexec-arm64.c | 14 +-------------
|
||||
1 file changed, 1 insertion(+), 13 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||
index ec6df4b..10238d9 100644
|
||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||
@@ -503,7 +503,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
||||
int len, range_len;
|
||||
int nodeoffset;
|
||||
int new_size;
|
||||
- int i, result, kaslr_seed;
|
||||
+ int i, result;
|
||||
|
||||
result = fdt_check_header(dtb->buf);
|
||||
|
||||
@@ -576,18 +576,6 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
- kaslr_seed = fdt64_to_cpu(*prop);
|
||||
-
|
||||
- /* kaslr_seed must be wiped clean by primary
|
||||
- * kernel during boot
|
||||
- */
|
||||
- if (kaslr_seed != 0) {
|
||||
- dbgprintf("%s: kaslr-seed is not wiped to 0.\n",
|
||||
- __func__);
|
||||
- result = -EINVAL;
|
||||
- goto on_error;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* Invoke the getrandom system call with
|
||||
* GRND_NONBLOCK, to make sure we
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
From 211cae4b6a02a4d9d37bfcd76f3702696e095fc3 Mon Sep 17 00:00:00 2001
|
||||
From: Quanyang Wang <quanyang.wang@windriver.com>
|
||||
Date: Tue, 16 Jun 2015 12:59:57 +0800
|
||||
Subject: [PATCH] powerpc: change the memory size limit
|
||||
|
||||
When run "kexec" in powerpc board, the kexec has a limit that
|
||||
the kernel text and bss size must be less than 24M. But now
|
||||
some kernel size exceed the limit. So we need to change the limit,
|
||||
else will get the error log as below:
|
||||
|
||||
my_load:669: do
|
||||
Could not find a free area of memory of 0x12400 bytes...
|
||||
Could not find a free area of memory of 0x13000 bytes...
|
||||
locate_hole failed
|
||||
|
||||
Upstream-Status: Pending
|
||||
|
||||
Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com>
|
||||
---
|
||||
kexec/arch/ppc/kexec-ppc.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kexec/arch/ppc/kexec-ppc.h b/kexec/arch/ppc/kexec-ppc.h
|
||||
index 04e728e..6bae9ec 100644
|
||||
--- a/kexec/arch/ppc/kexec-ppc.h
|
||||
+++ b/kexec/arch/ppc/kexec-ppc.h
|
||||
@@ -44,7 +44,7 @@ void dol_ppc_usage(void);
|
||||
* During inital setup the kernel does not map the whole memory but a part of
|
||||
* it. On Book-E that is 64MiB, 601 24MiB or 256MiB (if possible).
|
||||
*/
|
||||
-#define KERNEL_ACCESS_TOP (24 * 1024 * 1024)
|
||||
+#define KERNEL_ACCESS_TOP (36 * 1024 * 1024)
|
||||
|
||||
/* boot block version 17 as defined by the linux kernel */
|
||||
struct bootblock {
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
From a04bcf8f683c1a5a7d015920124457ad56fb7cf0 Mon Sep 17 00:00:00 2001
|
||||
From: Khem Raj <raj.khem@gmail.com>
|
||||
Date: Mon, 7 Sep 2015 07:59:45 +0000
|
||||
Subject: [PATCH] purgatory: Pass -r directly to linker
|
||||
|
||||
This helps compiling with clang since -r is not a known option for clang
|
||||
where as gcc knows how to deal with it and passes it down to linker
|
||||
unfiltered
|
||||
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
|
||||
Upstream-Status: Pending
|
||||
---
|
||||
purgatory/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/purgatory/Makefile b/purgatory/Makefile
|
||||
index 2dd6c47..416e6b9 100644
|
||||
--- a/purgatory/Makefile
|
||||
+++ b/purgatory/Makefile
|
||||
@@ -60,7 +60,7 @@ $(PURGATORY): CPPFLAGS=$($(ARCH)_PURGATORY_EXTRA_CFLAGS) \
|
||||
-I$(shell $(CC) -print-file-name=include)
|
||||
$(PURGATORY): LDFLAGS=$($(ARCH)_PURGATORY_EXTRA_CFLAGS)\
|
||||
-Wl,--no-undefined -nostartfiles -nostdlib \
|
||||
- -nodefaultlibs -e purgatory_start -r \
|
||||
+ -nodefaultlibs -e purgatory_start -Wl,-r \
|
||||
-Wl,-Map=$(PURGATORY_MAP)
|
||||
|
||||
$(PURGATORY): $(PURGATORY_OBJS)
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
From 55e583d20651e829afbbc8dba0f8ec3017cda2d5 Mon Sep 17 00:00:00 2001
|
||||
From: Haiqing Bai <Haiqing.Bai@windriver.com>
|
||||
Date: Mon, 9 Jan 2017 15:26:29 +0800
|
||||
Subject: [PATCH] kexec: ARM: Fix add_buffer_phys_virt() align issue
|
||||
|
||||
When "CONFIG_ARM_LPAE" is enabled,3 level page table
|
||||
is used by MMU, the "SECTION_SIZE" is defined with
|
||||
(1 << 21), but 'add_buffer_phys_virt()' hardcode this
|
||||
to (1 << 20).
|
||||
|
||||
Upstream-Status: Pending
|
||||
|
||||
Suggested-By:fredrik.markstrom@gmail.com
|
||||
Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com>
|
||||
---
|
||||
kexec/arch/arm/crashdump-arm.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kexec/arch/arm/crashdump-arm.c b/kexec/arch/arm/crashdump-arm.c
|
||||
index daa4788..3f72b38 100644
|
||||
--- a/kexec/arch/arm/crashdump-arm.c
|
||||
+++ b/kexec/arch/arm/crashdump-arm.c
|
||||
@@ -240,6 +240,7 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
|
||||
void *buf;
|
||||
int err;
|
||||
int last_ranges;
|
||||
+ unsigned short align_bit_shift = 20;
|
||||
|
||||
/*
|
||||
* First fetch all the memory (RAM) ranges that we are going to pass to
|
||||
@@ -281,6 +282,7 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
|
||||
|
||||
/* for support LPAE enabled kernel*/
|
||||
elf_info.class = ELFCLASS64;
|
||||
+ align_bit_shift = 21;
|
||||
|
||||
err = crash_create_elf64_headers(info, &elf_info,
|
||||
usablemem_rgns.ranges,
|
||||
@@ -302,8 +304,9 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
|
||||
* 1MB) so that available memory passed in kernel command line will be
|
||||
* aligned to 1MB. This is because kernel create_mapping() wants memory
|
||||
* regions to be aligned to SECTION_SIZE.
|
||||
+ * The SECTION_SIZE of LPAE kernel is '1UL << 21' defined in pgtable-3level.h
|
||||
*/
|
||||
- elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << 20,
|
||||
+ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << align_bit_shift,
|
||||
crash_kernel_mem.start,
|
||||
crash_kernel_mem.end, -1, 0);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
From c54488ad5fd657e0f154d76d7456d9080be24836 Mon Sep 17 00:00:00 2001
|
||||
From: Khem Raj <raj.khem@gmail.com>
|
||||
Date: Sat, 10 Jun 2017 11:18:49 -0700
|
||||
Subject: [PATCH] Disable PIE during link
|
||||
|
||||
We have explcitly disabled PIE during compile so we
|
||||
just need to match it with linker flags
|
||||
|
||||
Upstream-Status: Pending
|
||||
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
---
|
||||
purgatory/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/purgatory/Makefile b/purgatory/Makefile
|
||||
index 416e6b9..f00edb4 100644
|
||||
--- a/purgatory/Makefile
|
||||
+++ b/purgatory/Makefile
|
||||
@@ -59,7 +59,7 @@ $(PURGATORY): CPPFLAGS=$($(ARCH)_PURGATORY_EXTRA_CFLAGS) \
|
||||
-Iinclude \
|
||||
-I$(shell $(CC) -print-file-name=include)
|
||||
$(PURGATORY): LDFLAGS=$($(ARCH)_PURGATORY_EXTRA_CFLAGS)\
|
||||
- -Wl,--no-undefined -nostartfiles -nostdlib \
|
||||
+ -Wl,--no-undefined -no-pie -nostartfiles -nostdlib \
|
||||
-nodefaultlibs -e purgatory_start -Wl,-r \
|
||||
-Wl,-Map=$(PURGATORY_MAP)
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# kdump
|
||||
#
|
||||
# Description: The kdump script provides the support:
|
||||
# 1. Load a kdump kernel image into memory;
|
||||
# 2. Copy away vmcore when system panic.
|
||||
#
|
||||
|
||||
#default
|
||||
KEXEC=/usr/sbin/kexec
|
||||
KEXEC_ARGS="-p"
|
||||
|
||||
MAKEDUMPFILE=/usr/bin/makedumpfile
|
||||
MAKEDUMPFILE_ARGS="-E -d 1"
|
||||
|
||||
LOGGER="logger -p info -t kdump"
|
||||
|
||||
if [ -f /etc/sysconfig/kdump.conf ]; then
|
||||
. /etc/sysconfig/kdump.conf
|
||||
else
|
||||
echo "no /etc/sysconfig/kdump.conf"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
do_check()
|
||||
{
|
||||
#check makedumpfile
|
||||
if [ ! -e ${MAKEDUMPFILE} -o ! -x ${MAKEDUMPFILE} ] ;then
|
||||
echo "No makedumpfile found."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#check kexec
|
||||
if [ ! -e ${KEXEC} -o ! -x ${KEXEC} ] ;then
|
||||
echo "No kexec found."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#check whether kdump kernel image exists on the system
|
||||
if [ -z "${KDUMP_KIMAGE}" -o ! -f "${KDUMP_KIMAGE}" ]; then
|
||||
echo "No kdump kernel image found."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${KDUMP_CMDLINE}"x = "x" ] ; then
|
||||
echo "KDUMP_CMDLINE is not configured"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
do_save_vmcore()
|
||||
{
|
||||
if [ ${KDUMP_VMCORE_PATH}x = x ]; then
|
||||
KDUMP_VMCORE_PATH="/var/crash/`date +"%Y-%m-%d"`"
|
||||
fi
|
||||
|
||||
mkdir -p ${KDUMP_VMCORE_PATH}
|
||||
echo "Saving a vmcore to ${KDUMP_VMCORE_PATH}."
|
||||
|
||||
${MAKEDUMPFILE} ${MAKEDUMPFILE_ARGS} /proc/vmcore ${KDUMP_VMCORE_PATH}/vmcore-"`date +"%H:%M:%S"`"
|
||||
# cp --sparse=always /proc/vmcore ${KDUMP_VMCORE_PATH}/vmcore-"`date +"%H:%M:%S"`"
|
||||
rc=$?
|
||||
if [ ${rc} == 0 ]; then
|
||||
${LOGGER} "Saved a vmcore to ${KDUMP_VMCORE_PATH}."
|
||||
else
|
||||
${LOGGER} "Failed to save vmcore!"
|
||||
fi
|
||||
return ${rc}
|
||||
}
|
||||
|
||||
do_start()
|
||||
{
|
||||
#check file
|
||||
do_check
|
||||
|
||||
#check whether the running kernel supports kdump.
|
||||
if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
|
||||
echo "Kdump isn't supported on the running kernel!!!"
|
||||
${LOGGER} "Kdump isn't supported on the running kernel!!!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
#check whether kdump kernel image has been loaded
|
||||
rc=`cat /sys/kernel/kexec_crash_loaded`
|
||||
if [ ${rc} != 0 ]; then
|
||||
echo "Kdump is already running.";
|
||||
${LOGGER} "Kdump is already running."
|
||||
return 0
|
||||
fi
|
||||
|
||||
#check the running kernel cmdline option,insure "crashkernel=" always set.
|
||||
grep -q crashkernel= /proc/cmdline
|
||||
if [ $? != 0 ]; then
|
||||
echo "Kdump isn't supported on the running kernel,please check boot option!!!"
|
||||
${LOGGER} "Kdump isn't supported on the running kernel,please check boot option!!!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
#Load the kdump kernel image
|
||||
${KEXEC} ${KEXEC_ARGS} "${KDUMP_KIMAGE}" --append="${KDUMP_CMDLINE}"
|
||||
if [ $? != 0 ]; then
|
||||
echo "Failed to load kdump kernel!"
|
||||
${LOGGER} "Failed to load kdump kernel!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Kdump started up."
|
||||
${LOGGER} "Kdump started up."
|
||||
}
|
||||
|
||||
do_stop()
|
||||
{
|
||||
${KEXEC} -p -u 2>/dev/null
|
||||
if [ $? == 0 ]; then
|
||||
echo "Kdump has been stopped."
|
||||
${LOGGER} "Kdump has been stopped."
|
||||
else
|
||||
echo "Failed to stop kdump!"
|
||||
${LOGGER} "Failed to stop kdump!"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
if [ -s /proc/vmcore ]; then
|
||||
do_save_vmcore
|
||||
reboot
|
||||
else
|
||||
do_start
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
do_stop
|
||||
do_start
|
||||
;;
|
||||
stop)
|
||||
do_stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $?
|
||||
@@ -0,0 +1,14 @@
|
||||
#the kdump kernel version string.
|
||||
#KDUMP_KVER="`uname -r`"
|
||||
|
||||
#this will be passed to the kdump kernel as kdump kernel command line
|
||||
#KDUMP_CMDLINE="`cat /proc/cmdline`"
|
||||
|
||||
#the kernel image for kdump
|
||||
#KDUMP_KIMAGE="/boot/bzImage-${KDUMP_KVER}"
|
||||
|
||||
#Where to save the vmcore
|
||||
#KDUMP_VMCORE_PATH="/var/crash/`date +"%Y-%m-%d"`"
|
||||
|
||||
#the arguments to makedumpfile
|
||||
MAKEDUMPFILE_ARGS="--dump-dmesg -x /boot/vmlinux-`uname -r`"
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Reboot and dump vmcore via kexec
|
||||
DefaultDependencies=no
|
||||
Requires=sysinit.target
|
||||
After=sysinit.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=@LIBEXECDIR@/kdump-helper start
|
||||
ExecStop=@LIBEXECDIR@/kdump-helper stop
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
SUMMARY = "Kexec fast reboot tools"
|
||||
DESCRIPTION = "Kexec is a fast reboot feature that lets you reboot to a new Linux kernel"
|
||||
AUTHOR = "Eric Biederman"
|
||||
HOMEPAGE = "http://kernel.org/pub/linux/utils/kernel/kexec/"
|
||||
SECTION = "kernel/userland"
|
||||
LICENSE = "GPL-2.0-only"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=ea5bed2f60d357618ca161ad539f7c0a \
|
||||
file://kexec/kexec.c;beginline=1;endline=20;md5=af10f6ae4a8715965e648aa687ad3e09"
|
||||
DEPENDS = "zlib xz"
|
||||
|
||||
SRC_URI = "${KERNELORG_MIRROR}/linux/utils/kernel/kexec/kexec-tools-${PV}.tar.gz \
|
||||
file://kdump \
|
||||
file://kdump.conf \
|
||||
file://kdump.service \
|
||||
file://0001-powerpc-change-the-memory-size-limit.patch \
|
||||
file://0002-purgatory-Pass-r-directly-to-linker.patch \
|
||||
file://0003-kexec-ARM-Fix-add_buffer_phys_virt-align-issue.patch \
|
||||
file://0005-Disable-PIE-during-link.patch \
|
||||
file://0001-arm64-kexec-disabled-check-if-kaslr-seed-dtb-propert.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "89bdd941542c64fec16311858df304ed3a3908c1a60874d69df5d9bf1611e062"
|
||||
|
||||
inherit autotools update-rc.d systemd
|
||||
|
||||
export LDFLAGS = "-L${STAGING_LIBDIR}"
|
||||
EXTRA_OECONF = " --with-zlib=yes"
|
||||
|
||||
do_compile:prepend() {
|
||||
# Remove the prepackaged config.h from the source tree as it overrides
|
||||
# the same file generated by configure and placed in the build tree
|
||||
rm -f ${S}/include/config.h
|
||||
|
||||
# Remove the '*.d' file to make sure the recompile is OK
|
||||
for dep in `find ${B} -type f -name '*.d'`; do
|
||||
dep_no_d="`echo $dep | sed 's#.d$##'`"
|
||||
# Remove file.d when there is a file.o
|
||||
if [ -f "$dep_no_d.o" ]; then
|
||||
rm -f $dep
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
do_install:append () {
|
||||
install -d ${D}${sysconfdir}/sysconfig
|
||||
install -m 0644 ${WORKDIR}/kdump.conf ${D}${sysconfdir}/sysconfig
|
||||
|
||||
if ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'true', 'false', d)}; then
|
||||
install -D -m 0755 ${WORKDIR}/kdump ${D}${sysconfdir}/init.d/kdump
|
||||
fi
|
||||
|
||||
if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
|
||||
install -D -m 0755 ${WORKDIR}/kdump ${D}${libexecdir}/kdump-helper
|
||||
install -D -m 0644 ${WORKDIR}/kdump.service ${D}${systemd_system_unitdir}/kdump.service
|
||||
sed -i -e 's,@LIBEXECDIR@,${libexecdir},g' ${D}${systemd_system_unitdir}/kdump.service
|
||||
fi
|
||||
}
|
||||
|
||||
PACKAGES =+ "kexec kdump vmcore-dmesg"
|
||||
|
||||
ALLOW_EMPTY:${PN} = "1"
|
||||
RRECOMMENDS:${PN} = "kexec kdump vmcore-dmesg"
|
||||
|
||||
FILES:kexec = "${sbindir}/kexec"
|
||||
FILES:kdump = "${sbindir}/kdump \
|
||||
${sysconfdir}/sysconfig/kdump.conf \
|
||||
${sysconfdir}/init.d/kdump \
|
||||
${libexecdir}/kdump-helper \
|
||||
${systemd_system_unitdir}/kdump.service \
|
||||
"
|
||||
|
||||
FILES:vmcore-dmesg = "${sbindir}/vmcore-dmesg"
|
||||
|
||||
INITSCRIPT_PACKAGES = "kdump"
|
||||
INITSCRIPT_NAME:kdump = "kdump"
|
||||
INITSCRIPT_PARAMS:kdump = "start 56 2 3 4 5 . stop 56 0 1 6 ."
|
||||
|
||||
SYSTEMD_PACKAGES = "kdump"
|
||||
SYSTEMD_SERVICE:kdump = "kdump.service"
|
||||
|
||||
SECURITY_PIE_CFLAGS:remove = "-fPIE -pie"
|
||||
|
||||
COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|aarch64.*|powerpc.*|mips.*)-(linux|freebsd.*)'
|
||||
|
||||
INSANE_SKIP:${PN} = "arch"
|
||||
Reference in New Issue
Block a user