20200517のLinuxに関する記事は5件です。

SlaxのVirtualbox上のHDDインストール

はじめに 

Lightweight LinuxのひとつであるSlaxをVirtualboxへインストールした。

サイト

本家サイトからISOファイルをダウンロードする。

Virtualboxでの起動

ライブCD(ISOファイル)を指定して起動。RAMは512MBとした。

Virtaulboxでのあとしまつ

ライブCDを取り除く。

Terminalでの作業

  1. fdisk
    image.png
    PartitionにBootable flagをつける。

  2. mkfs
    image.png

  3. HDDにPathわりあて
    image.png

  4. SlaxのISOファイルをこのVM内にコピー
    今回、別マシンからscpでもってきました。

  5. SlaxのISOファイルのマウント
    image.png

  6. ファイルのHDDへのコピー
    image.png

  7. HDDブートの設定
    image.png
    image.png

  8. Shutdown
    image.png

  9. あとしまつ(ライブCDの除去)
    image.png

  10. 起動
    略。

感想

たしかに軽い気がする。

参考サイト

Slax 9.6.3 VirtualBox Install

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

arch/arm/boot/compressed/Makefileをもうちょっと読もう

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/compressed/Makefile?h=master

Makefileの中身を読み解いていく。興味のないfdtの部分は省略します。

TEXT領域の設定などなど。

arch/arm/boot/compressed/Makefile
# SPDX-License-Identifier: GPL-2.0
#
# linux/arch/arm/boot/compressed/Makefile
#
# create a compressed vmlinuz image from the original vmlinux
#

OBJS        =
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)

head.oを作るときに、TEXT_OFFSETのオプションを追加しますという意味。

TEXT_OFFSET

$(TEXT_OFFSET)は、arch/arm/Makefile内で定義。

arch/arm/Makefile
# Text offset. This list is sorted numerically by address in order to
# provide a means to avoid/resolve conflicts in multi-arch kernels.
textofs-y   := 0x00008000
# We don't want the htc bootloader to corrupt kernel during resume
textofs-$(CONFIG_PM_H1940)      := 0x00108000
# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000
endif
textofs-$(CONFIG_ARCH_IPQ40XX) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
textofs-$(CONFIG_ARCH_MESON) := 0x00208000
textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000

(略)

TEXT_OFFSET := $(textofs-y)

kernelとして実処理するコード(head./misc./decompress.*)

arch/arm/boot/compressed/Makefile
HEAD    = head.o
OBJS    += misc.o decompress.o

head.S

ここは、圧縮Linux Kernel展開部そのもののロジック。

色々やるが、decompress_kernelを呼び出す。

arch/arm/boot/compressed/head.S
/*
 * The C runtime environment should now be setup sufficiently.
 * Set up some pointers, and start decompressing.
 *   r4  = kernel execution address
 *   r7  = architecture ID
 *   r8  = atags pointer
 */
        mov r0, r4
        mov r1, sp          @ malloc space above stack
        add r2, sp, #0x10000    @ 64k max
        mov r3, r7
        bl  decompress_kernel

misc.S

decompress_kernel()本体などが記載されている。

実際にはこの中から、do_decompress()が呼ばれる。

arch/arm/boot/compressed/misc.c
void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
        unsigned long free_mem_ptr_end_p,
        int arch_id)
{
    int ret;

    output_data     = (unsigned char *)output_start;
    free_mem_ptr        = free_mem_ptr_p;
    free_mem_end_ptr    = free_mem_ptr_end_p;
    __machine_arch_type = arch_id;

    arch_decomp_setup();

    putstr("Uncompressing Linux...");
    ret = do_decompress(input_data, input_data_end - input_data,
                output_data, error);
    if (ret)
        error("decompressor returned an error");
    else
        putstr(" done, booting the kernel.\n");
}

decompress.S

各圧縮モジュールの__decompress()を呼び出して解凍する部分。

arch/arm/boot/compressed/decompress.c
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif

#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif

#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif

#ifdef CONFIG_KERNEL_XZ
#define memmove memmove
#define memcpy memcpy
#include "../../../../lib/decompress_unxz.c"
#endif

#ifdef CONFIG_KERNEL_LZ4
#include "../../../../lib/decompress_unlz4.c"
#endif

int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
{
    return __decompress(input, len, NULL, NULL, output, 0, NULL, error);
}

例えば、lz4ならば以下。

lib/decompress_unlz4.c
#ifdef PREBOOT
STATIC int INIT __decompress(unsigned char *buf, long in_len,
                  long (*fill)(void*, unsigned long),
                  long (*flush)(void*, unsigned long),
                  unsigned char *output, long out_len,
                  long *posp,
                  void (*error)(char *x)
    )
{
    return unlz4(buf, in_len - 4, fill, flush, output, posp, error);
}
#endif

debug用の文字出力

arch/arm/boot/compressed/Makefile
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS    += debug.o
endif
FONTC   = $(srctree)/lib/fonts/font_acorn_8x8.c

font_acorn_8x8.c ってacorn以外使ってないんじゃないかなあ……

DEBUG_UNCOMPRESS

DEBUG_UNCOMPRESSは、KConfig.debugの中で定義。

このオプションでは、multiplatform kernelでdecompressorの出力に関する。
通常、multiplatform kernelsではdecompressorのすることはよくない。
なぜならば、どうやってdecompressorの出力をどこに送ればいいのかわからないから。

このオプションが設定されたら、DEBUG_LL output 手段によって、再利用される。

ということで、デバッグできますと。

arch/arm/Kconfig.debug
config DEBUG_UNCOMPRESS
    bool "Enable decompressor debugging via DEBUG_LL output"
    depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
    depends on DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
             (!DEBUG_TEGRA_UART || !ZBOOT_ROM) && \
             !DEBUG_BRCMSTB_UART
    help
      This option influences the normal decompressor output for
      multiplatform kernels.  Normally, multiplatform kernels disable
      decompressor output because it is not possible to know where to
      send the decompressor output.

      When this option is set, the selected DEBUG_LL output method
      will be re-used for normal decompressor output on multiplatform
      kernels.

debug.S

debug.sは、putc()の実装のための使う。CONFIG_DEBUG_SEMIHOSTINGが無効化されている場合には、adduart/waituart/senduart/busyuart で文字をコンソールへ出力する。

arm/boot/compressed/debug.S
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/assembler.h>

#ifndef CONFIG_DEBUG_SEMIHOSTING

#include CONFIG_DEBUG_LL_INCLUDE

ENTRY(putc)
    addruart r1, r2, r3
    waituart r3, r1
    senduart r0, r1
    busyuart r3, r1
    mov  pc, lr
ENDPROC(putc)

#else
(略)

string library

string.c は、memcpu/memmove/strlen/strnlenなどのサブセット。
decompressorが動くときに単独で動かせるように組み込まれていると推定。

arch/arm/boot/compressed/Makefile
# string library code (-Os is enforced to keep it much smaller)
OBJS        += string.o
CFLAGS_string.o := -Os

string.c

中身は、string.hの中で定義されている関数の簡易版の実装。

arch/arm/boot/compressed/string.c
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
    int i = 0;
    unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;

    for (i = __n >> 3; i > 0; i--) {
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
    }

    if (__n & 1 << 2) {
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
    }

    if (__n & 1 << 1) {
        *d++ = *s++;
        *d++ = *s++;
    }

    if (__n & 1)
        *d++ = *s++;

    return __dest;
}

VIRT_EXT

arch/arm/boot/compressed/Makefile
ifeq ($(CONFIG_ARM_VIRT_EXT),y)
OBJS        += hyp-stub.o
endif

ARM_VIRT_EXT

arch/arm/mm/Kconfig
config ARM_VIRT_EXT
    bool
    default y if CPU_V7
    help
      Enable the kernel to make use of the ARM Virtualization
      Extensions to install hypervisors without run-time firmware
      assistance.

      A compliant bootloader is required in order to make maximum
      use of this feature.  Refer to Documentation/arm/booting.rst for
      details.

GCOV/KCOV

デバッグ用の機能は無効化されている。

arch/arm/boot/compressed/Makefile
GCOV_PROFILE        := n

# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
KCOV_INSTRUMENT     := n

機種依存部

このあたりは機種依存部なので省略。

arch/arm/boot/compressed/Makefile
#
# Architecture dependencies
#
ifeq ($(CONFIG_ARCH_ACORN),y)
OBJS        += ll_char_wr.o font.o
endif

<略>

アドレスの指定(ZTEXTADDR/ZBSSADDR)

  • decompressor 実装はPIC(アドレス非依存実装)になっている。
  • DecompressorをRAM上で動かす場合には、ZTEXTADDRを指定してはいけない。
  • DecompressorをROM/Flashで動かす場合には、指定が必要。
arch/arm/boot/compressed/Makefile
#
# We now have a PIC decompressor implementation.  Decompressors running
# from RAM should not define ZTEXTADDR.  Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR   := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR    := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR   := 0
ZBSSADDR    := ALIGN(8)
endif

CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"

圧縮方式の確定

KConfigで指定した圧縮形式の指定。

arch/arm/boot/compressed/Makefile
compress-$(CONFIG_KERNEL_GZIP) = gzip
compress-$(CONFIG_KERNEL_LZO)  = lzo
compress-$(CONFIG_KERNEL_LZMA) = lzma
compress-$(CONFIG_KERNEL_XZ)   = xzkern
compress-$(CONFIG_KERNEL_LZ4)  = lz4

fdt部(省略)

arch/arm/boot/compressed/Makefile
# Borrowed libfdt files for the ATAG compatibility mode
<略>

Make用のtarget/clean-files設定

arch/arm/boot/compressed/Makefile
targets       := vmlinux vmlinux.lds piggy_data piggy.o \
         lib1funcs.o ashldi3.o bswapsdi2.o \
         head.o $(OBJS)

clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \
        $(libfdt) $(libfdt_hdrs) hyp-stub.S

KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING

ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif

fdt部2(省略)

stack-protector-strongを使うにはまだ早いらしい。

arch/arm/boot/compressed/Makefile
# -fstack-protector-strong triggers protection checks in this code,
# but it is being used too early to link to meaningful stack_chk logic.
nossp-flags-$(CONFIG_CC_HAS_STACKPROTECTOR_NONE) := -fno-stack-protector
CFLAGS_atags_to_fdt.o := $(nossp-flags-y)
<略>

BSSサイズの指定。

__bss_startと__bss_stopの間を使って計算しているっぽい。それが、Linkerへのオプションとして伝達される。

arch/arm/boot/compressed/Makefile
# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
        sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
               -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
endif

vmlinuxリンク時の他の設定

  • BigEndian対応
  • 未解決参照はダメ
  • 一時的なローカルシンボルの削除
  • -Tオプションはlinker script用だよ、かな?
arch/arm/boot/compressed/Makefile
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux += --be8
endif
# Report unresolved symbol references
LDFLAGS_vmlinux += --no-undefined
# Delete all temporary local symbols
LDFLAGS_vmlinux += -X
# Next argument is a linker script
LDFLAGS_vmlinux += -T

存在しない命令のための対応。

存在しない関数をごにょごにょするために用意されたコードの配備。

arch/arm/boot/compressed/Makefile
# For __aeabi_uidivmod
lib1funcs = $(obj)/lib1funcs.o

$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
    $(call cmd,shipped)

# For __aeabi_llsl
ashldi3 = $(obj)/ashldi3.o

$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
    $(call cmd,shipped)

# For __bswapsi2, __bswapdi2
bswapsdi2 = $(obj)/bswapsdi2.o

$(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S
    $(call cmd,shipped)

lib1funcs.S

除算の最適化ルーチンらしい。

https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html

下記の関数などなどが含まれている。

Runtime Function: int __divsi3 (int a, int b)
Runtime Function: long __divdi3 (long a, long b)
Runtime Function: long long __divti3 (long long a, long long b)
  These functions return the quotient of the signed division of a and b.

arch/arm/lib/lib1funcs.S
/*
 * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
 *
 * Author: Nicolas Pitre <nico@fluxnic.net>
 *   - contributed to gcc-3.4 on Sep 30, 2003
 *   - adapted for the Linux kernel on Oct 2, 2003
 */

ashldi3.S/bswapsdi2.S

https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html

ここら辺に何の関数か記載がある。

Runtime Function: int _ashlsi3 (int a, int b)
Runtime Function: long __ashldi3 (long a, int b)
Runtime Function: long long _
ashlti3 (long long a, int b)
  These functions return the result of shifting a left by b bits.

Runtime Function: int32_t _bswapsi2 (int32_t a)
Runtime Function: int64_t __bswapdi2 (int64
t a)
  These functions return the a byteswapped.

シンボルのチェック。

「以下のsymbolは、local/private scopeにあってはいけません」とのこと。

arch/arm/boot/compressed/Makefile
# We need to prevent any GOTOFF relocs being used with references
# to symbols in the .bss section since we cannot relocate them
# independently from the rest at run time.  This can be achieved by
# ensuring that no private .bss symbols exist, as global symbols
# always have a GOT entry which is what we need.
# The .data section is already discarded by the linker script so no need
# to bother about it here.
check_for_bad_syms = \
bad_syms=$$($(NM) $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
[ -z "$$bad_syms" ] || \
  ( echo "following symbols must have non local/private scope:" >&2; \
    echo "$$bad_syms" >&2; false )

ZRELADDR関係のチェック

ZRELADDRが設定されず、AUTO_ZRELADDRが設定もされてなかったら怒られる、かな?

arch/arm/boot/compressed/Makefile
check_for_multiple_zreladdr = \
if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
    echo 'multiple zreladdrs: $(ZRELADDR)'; \
    echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
    false; \
fi

EFI対応

(興味なしで省略)

arch/arm/boot/compressed/Makefile
efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a

vmlinuxの作り方!!(ここが最終ライン)

arch/arm/boot/compressed/Makefile
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
        $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
        $(bswapsdi2) $(efi-obj-y) FORCE
    @$(check_for_multiple_zreladdr)
    $(call if_changed,ld)
    @$(check_for_bad_syms)

Imageを圧縮する

compress-y は、 compress-$(CONFIG_KERNEL_XXXX) = CMD の形で指定した圧縮プログラムが入る。これを使って、Imageをpiggy_dataに亜ssy九

arch/arm/boot/compressed/Makefile
$(obj)/piggy_data: $(obj)/../Image FORCE
    $(call if_changed,$(compress-y))

$(obj)/piggy.o: $(obj)/piggy_data

piggy.S

piggy_dataをバイナリデータとして取り込んでおしまい。

arch/arm/boot/compressed/piggy.S
/* SPDX-License-Identifier: GPL-2.0 */
    .section .piggydata, "a"
    .globl  input_data
input_data:
    .incbin "arch/arm/boot/compressed/piggy_data"
    .globl  input_data_end
input_data_end:

あとは各種オプションの指定

arch/arm/boot/compressed/Makefile
CFLAGS_font.o := -Dstatic=

$(obj)/font.c: $(FONTC)
    $(call cmd,shipped)

AFLAGS_hyp-stub.o := -Wa,-march=armv7-a

$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
    $(call cmd,shipped)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

brew doctorコマンドを実行した時に発生したwarningを1個ずつ解決していきます!

はじめに

Homebrewに問題がないかbrew doctorコマンドでチェックしたところ、問題が溢れ出てきたので一個ずつ解決していきました。

エラー時の環境

macOS Catalina バージョン 10.15.4
Xcode バージョン11.4

エラー内容

$ brew doctor
 Please note that these warnings are just used to help the Homebrew  maintainers
 with debugging if you file an issue. If everything you use Homebrew for is
 working fine: please don't worry or file an issue; just ignore this. Thanks!

#1つ目のエラー
 Warning: A newer Command Line Tools release is available.
 Update them from Software Update in System Preferences or run:
   softwareupdate --all --install --force

#2つ目のエラー
 Warning: You have unlinked kegs in your Cellar.
 Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
 those kegs to fail to run properly once built. Run `brew link` on these:
   node

#3つ目のエラー
 Warning: Your Xcode (11.4) is outdated.
 Please update to Xcode 11.4.1 (or delete it).
 Xcode can be updated from the App Store.

1つ目のエラー

Warning: A newer Command Line Tools release is available.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

 →$ softwareupdate --all --install --forceコマンドを実行せよとの指示が出ているので実行します。

$ softwareupdate --all --install --force

 →これで解決しない場合はApp Developerで最新版をインストールすれば解決できました。

2つ目のエラー

Warning: You have unlinked kegs in your Cellar.
Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
   node

 →こちらも$ brew linknodeへ実行しろとのことなので、指示に従いコマンドを実行。

$ brew link node
Error: Could not symlink share/doc/node/gdbinit
Target /usr/local/share/doc/node/gdbinit
already exists. You may want to remove it:
    rm '/usr/local/share/doc/node/gdbinit'

To force the link and overwrite all conflicting files:
    brew link --overwrite node

To list all files that would be deleted:
    brew link --overwrite --dry-run node

 →しかし、上記のようなエラーが出てしまいました。
 →share/doc/node/gdbinitファイルにsymlink(シンボリックリンク)を作成できないから、そのターゲットのファイルを削除もしくは強制的に上書きするよう指示が出されました。(シンボリックリンクとは何ぞやという方はこちらの記事が大変参考になるかと思います。)
 →では指示通りに$ brew link --overwrite nodeコマンドを実行してみます。

$ brew link --overwrite node
Error: Could not symlink share/doc/node/gdbinit
/usr/local/share/doc/node is not writable.

 →そして再びエラー。/usr/local/share/doc/node ディレクトリがis not writableつまり書き込み権限がないと言われているので、このディレクトリの書き込み出来るようにユーザー権限を、現アカウントに委譲します。
 →書き込み可能にするには、以下のようにコマンドを実行していきます。

$ cd /usr/local/share/doc
$ sudo chown -R $USER node
Password:

 →まずnodeディレクトリがあるdocディレクトリに移動します。
 →chownコマンドで、ユーザー権限を現アカウントに委譲することで、ディレクトリへ対する書き込みの権限が与えられます(chownコマンドについてはこちらの記事が参考になります)。
 →上記のようにパスワードの入力を求められる場合は、PCにログインするときに設定しているパスワードを入力する。
 →これで書き込み可能になったので、再び$ brew linkコマンドを実行します。

$ brew link --overwrite node
Linking /usr/local/Cellar/node/14.2.0... 
Error: Could not symlink share/systemtap/tapset/node.stp
/usr/local/share/systemtap/tapset is not writable.

 →しかし、今度はまた別のファイルの書き込み権限がないとのエラーが出てしまいました。
 →これも書き込み可能にしたいので、先ほどの手順と同様に書き込みの権限を与えます。

$ cd /usr/local/share/systemtap
$ sudo chown -R $USER tapset

 →tapsetディレクトリがあるsystemtapディレクトリに移動する。
 →chownコマンドでユーザー権限を現アカウントに委譲して書き込みできるようにします。
 →そして$ brew linkコマンドを実行します。

$ brew link --overwrite node
Linking /usr/local/Cellar/node/14.2.0... 
Error: Could not symlink lib/dtrace/node.d
/usr/local/lib/dtrace is not writable.

 →再び、上記2つのエラー同様書き込み権限がないという旨のエラーが出ました。
 →同じくディレクトリに対しての書き込み権限を与えます。

$ cd /usr/local/lib
$ sudo chown -R $USER dtrace

 →distraceディレクトリがあるlibディレクトリに移動する。
 →chownコマンドでユーザー権限を現アカウントに委譲。
 →そして$ brew linkコマンドを実行します。

$ brew link --overwrite node
Linking /usr/local/Cellar/node/14.2.0... 7 symlinks created

 →今度は上手くリンクが張れたみたいです(よかった…)。

ちなみに

 ※chownコマンド実行時、「Operation not permitted」というエラーが出てしまう場合があるので、もしそうなってしまった場合は以下を参考にしてみてください。(自分はこの状況に直面しました)

解決策

 これは、ターミナルの環境設定自体を変更してあげれば解決できますので、手順を説明していきます。

 1.Macの「システム環境設定を開く」
  スクリーンショット 2020-05-17 10.58.29.png
 2.右にある「プライバシー」タブを開く。
 3.左側をスクロールして、「フルディスクアクセス」を開く。
 4.「+」マークを押して、「ターミナル」を検索し、ターミナルを選択しチェックを付ける(変更できない場合は、左下の鍵マークをクリックすれば変更できるようになります)。
スクリーンショット 2020-05-17 10.59.51.png

話が脱線しましたが、3つ目のエラー修正。

Warning: Your Xcode (11.4) is outdated.
Please update to Xcode 11.4.1 (or delete it).
Xcode can be updated from the App Store.

 →Xcodeを11.4.1へアップデートしてくださいとの指示なので、それに従います。
 →App DeveloperでXcode 11.4.1をダウンロードしてインストールします。
 →インストールしたXcodeファイルはApplicationsディレクトリ配下に移動します。
 →もし、上記ではXcodeアップデートのエラーが直らなかったという場合は、以下の方法を試してみてください。

 1.Xcode.appを開きます。
 2.Xcodeタブから、Preferencesを選択して開きます。
  スクリーンショット 2020-05-17 16.51.02.png
 3.Locationタブを開いて、Command Line Toolsの欄を新しくインストールしたXcodeのバージョンに変更します。
スクリーンショット 2020-05-17 16.49.45.png

 以上でエラー修正が完了したかと思うので、$ brew doctorコマンドで確認してみます。

$ brew doctor
Your system is ready to brew.

 →上手く行きました!

参考

 https://wtnvenga.hatenablog.com/entry/2017/11/15/125430
  →symlink関連でのエラーにとても参考になりました。

 https://gori.me/mac/mac-tips/112082
  →ターミナルの設定で参考になりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【LifeKeeper×Linux】HAクラスター構築後のインタフェースダウンの挙動がおかしい場合

はじめに

仕事でLifeKeeperの検証~構築手順書への落とし込みを担当しておりました。
今回は、LifeKeeperの検証を行っていた際のトラブルシューティングの内容になります。
LifeKeeper構築後の試験の際にインターフェースダウンの挙動がおかしくなる事象がありました。
こちらの原因と対処について解説していきます。

環境

こちらの環境になります。

図.JPG

  • HyperVisor(今回は省略)
    vSphere6.7(ESXi6.7)

  • VM(「サーバー」の部分)
    RHEL6.9

  • NIC
    Service用NIC × 1
    コミュニケーションパス用NIC × 2

  • 共有ディスク/Quorumディスク#1,#2
    VMDK

起きた事象

片系ずつサービスNICを落とした挙動についてテストしました。

実行したコマンド

# ifdown eth0
  • サーバー#1でのインタフェースダウン

サーバー#1.JPG

  • サーバー#2でのインタフェースダウン

サーバー#2.JPG

こちらの試験を実施したところ、結果に差異がありました。

サーバー#1のサービスNIC
→数秒後に自動復旧

サーバー#2のサービスNIC
→DOWN状態のまま

疑問に思ったので調査をしました。

原因

サーバー#2の「NetworkManager」が立ち上がっていた。
※サーバー1の「NetworkManager」はオフの状態

対策

サーバー#2の「NetworkManager」のサービス停止/自動起動停止を実施

# service NetworkManager stop
# chkconfig  NetworkManager off

再度テストを実施したところ、サーバー#1と同じ挙動であることを確認

最後に

いかがでしたでしょうか?
今回、初めてLifeKeeperについての記事を上げました。
LifeKeeperのHAクラスターの設計・構築をしている方に参考になる記事になると思います。

今回の内容はミドルウェア(LifeKeeper)から疑って調査した結果になります。
一つでも参考になれば幸いです。

よろしければTwitterのフォローも宜しくお願いします!
https://twitter.com/satton6987

主にインフラエンジニアのキャリアハックや技術について呟いています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vlocks for Bare-Metal Mutual Exclusion(2/2)

https://www.kernel.org/doc/html/latest/arm/vlocks.html

vlocks for Bare-Metal Mutual Exclusion

ARM implementation

The current ARM implementation [2] contains some optimisations beyond the basic algorithm:

現在のARMでの実装[2]には、基本的なアルゴリズム以外にもいくつかの最適化が含まれています。

・By packing the members of the currently_voting array close together, we can read the whole array in one transaction (providing the number of CPUs potentially contending the lock is small enough). This reduces the number of round-trips required to external memory.

・currently_voting配列のmember変数をpackすることで、1つのトランザクションで配列全体を読み取ることができます(ロックを競合する可能性のあるCPUの数が十分に少ない場合)。 これにより、外部メモリで必要なround-tripsの数を削減できます。

In the ARM implementation, this means that we can use a single load and comparison:

ARM実装では、単一のロードと比較で使用できることを意味します。

LDR     Rt, [Rn]  // Rtに、Rn番地の内容32bitを読み出す
CMP     Rt, #0      // Rtが0と一致するかを判定する

…in place of code equivalent to:

LDRB    Rt, [Rn]     // Rtに、Rn番地の内容8bitを読み出す
CMP     Rt, #0       // Rtが0と一致するかを判定する
LDRBEQ  Rt, [Rn, #1] // Rtに、Rn+1番地の内容8bitを読み出す
CMPEQ   Rt, #0       // Rtが0と一致するかを判定する
LDRBEQ  Rt, [Rn, #2] // Rtに、Rn+2番地の内容8bitを読み出す
CMPEQ   Rt, #0       // Rtが0と一致するかを判定する
LDRBEQ  Rt, [Rn, #3] // Rtに、Rn+3番地の内容8bitを読み出す
CMPEQ   Rt, #0       // Rtが0と一致するかを判定する

This cuts down on the fast-path latency, as well as potentially reducing bus contention in contended cases.

これにより、fast-pathのレイテンシーを削減でき、競合するケースでの、潜在的なバス競合を減らす事ができます。

The optimisation relies on the fact that the ARM memory system guarantees coherency between overlapping memory accesses of different sizes, similarly to many other architectures. Note that we do not care which element of currently_voting appears in which bits of Rt, so there is no need to worry about endianness in this optimisation.

最適化は、ARM memory systemが異なるサイズで重複するメモリアクセス間のcoherencyを保証するという事実に依存しています。他の多くのアーキテクチャと同様に。 Rtのどのビットにcurrent_votingのどの要素が現れるかは関係ないので、この最適化でエンディアンについて心配する必要はない。

If there are too many CPUs to read the currently_voting array in one transaction then multiple transations are still required. The implementation uses a simple loop of word-sized loads for this case. The number of transactions is still fewer than would be required if bytes were loaded individually.

CPUの数が非常に多く、currently_voting 配列を1回のトランザクションで読み取れないならば、複数回のトランザクションが必要になります。この実装では、word-sizeのloadを単純に繰り返します。トランザクションの数は、byte単位で個別に読み出したのに比べれば、少なくなります。

In principle, we could aggregate further by using LDRD or LDM, but to keep the code simple this was not attempted in the initial implementation.

根本的には、LDRDやLDMを使う事で、更に集約する事ができました。しかし、初期実装においては、コードを簡潔にするために採用されませんでした。

・vlocks are currently only used to coordinate between CPUs which are unable to enable their caches yet. This means that the implementation removes many of the barriers which would be required when executing the algorithm in cached memory.

・vlockは現在、まだキャッシュを有効にできないCPU間の調整にのみ使用されています。 キャッシュされたメモリでアルゴリズムを実行するには、実装では多くの障壁を取り除く必要があることを意味します。

packing of the currently_voting array does not work with cached memory unless all CPUs contending the lock are cache-coherent, due to cache writebacks from one CPU clobbering values written by other CPUs. (Though if all the CPUs are cache-coherent, you should be probably be using proper spinlocks instead anyway).

他のCPUから書き込まれた値を別のCPUからキャッシュに書き戻すことに起因して、すべてのCPUでのlockが、cache-coherentで競合しない限り、currently_voting配列のpackingはキャッシュされたメモリでは動作できません。(全てのCPUがcache-coherentである場合でも、適切なスピンロックを使用しているはずである)。

・The “no votes yet” value used for the last_vote variable is 0 (not -1 as in the pseudocode). This allows statically-allocated vlocks to be implicitly initialised to an unlocked state simply by putting them in .bss.

last_vote 変数に対して利用される、"投票なし(no votes yet)"の値は0です(疑似コードのように-1ではありません)。これにより、静的に配置されたvlockによって, .bssに置かれただけで暗黙的にunlockされた初期状態にします。

An offset is added to each CPU’s ID for the purpose of setting this variable, so that no CPU uses the value 0 for its ID.

オフセットが、この変数を設定するために、各CPUのIDに追加されるため、CPUはIDに値0を使用しません。

Colophon

Originally created and documented by Dave Martin for Linaro Limited, for use in ARM-based big.LITTLE platforms, with review and input gratefully received from Nicolas Pitre and Achin Gupta. Thanks to Nicolas for grabbing most of this text out of the relevant mail thread and writing up the pseudocode.

Copyright (C) 2012-2013 Linaro Limited Distributed under the terms of Version 2 of the GNU General Public License, as defined in linux/COPYING.

References

[1] Lamport, L. “A New Solution of Dijkstra’s Concurrent Programming Problem”, Communications of the ACM 17, 8 (August 1974), 453-455. https://en.wikipedia.org/wiki/Lamport%27s_bakery_algorithm

[2] linux/arch/arm/common/vlock.S, www.kernel.org.


もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる(はずの認識)。

https://www.kernel.org/doc/html/latest/index.html

Licensing documentation

The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.

https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む