20201206のLinuxに関する記事は7件です。

PingでLinuxサーバの死活監視をするべきではないという話

はじめに

最近仕事で監視関係の設計・構築をやったため、過去の自分が作ってしまったイケてない監視への自戒を込めて、この小ネタを投稿します。

なぜPingで死活監視をするべきではないのか

ICMPパケットを処理するのは、ユーザープロセスではなくカーネルのネットワークスタックです。
ユーザプロセスが全滅してもICMP Replyは返ってくるので、死活監視用途には向きません。

検証

環境

ホスト名 IP OS
vm-1 192.168.100.3 CentOS 8.2.2004
vm-2 192.168.100.143 CentOS 8.2.2004

作業ログ

正常な状態ではvm-1からvm-2にPingを打つと下のように問題なく通ります。

[centos@vm-1 ~]$ ping -c5 192.168.100.143
PING 192.168.100.143 (192.168.100.143) 56(84) bytes of data.
64 bytes from 192.168.100.143: icmp_seq=1 ttl=64 time=0.388 ms
64 bytes from 192.168.100.143: icmp_seq=2 ttl=64 time=0.573 ms
64 bytes from 192.168.100.143: icmp_seq=3 ttl=64 time=0.604 ms
64 bytes from 192.168.100.143: icmp_seq=4 ttl=64 time=1.36 ms
64 bytes from 192.168.100.143: icmp_seq=5 ttl=64 time=0.573 ms

--- 192.168.100.143 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 40ms
rtt min/avg/max/mdev = 0.388/0.699/1.357/0.337 ms

vm-2へのsshも可能です。

$ ssh 192.168.100.143 -lcentos
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Sun Dec  6 10:52:50 2020 from 192.168.11.16
[centos@vm-2 ~]$

ここでvm-2のユーザプロセスをすべてkillしてみます。

[centos@vm-2 ~]$ sudo sh -c "echo i>/proc/sysrq-trigger"

Pingは打てます。

[centos@vm-1 ~]$ ping -c5 192.168.100.143
PING 192.168.100.143 (192.168.100.143) 56(84) bytes of data.
64 bytes from 192.168.100.143: icmp_seq=1 ttl=64 time=0.748 ms
64 bytes from 192.168.100.143: icmp_seq=2 ttl=64 time=0.680 ms
64 bytes from 192.168.100.143: icmp_seq=3 ttl=64 time=0.564 ms
64 bytes from 192.168.100.143: icmp_seq=4 ttl=64 time=0.563 ms
64 bytes from 192.168.100.143: icmp_seq=5 ttl=64 time=0.905 ms

--- 192.168.100.143 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 134ms
rtt min/avg/max/mdev = 0.563/0.692/0.905/0.127 ms

sshはできなくなりました。

$ ssh 192.168.100.143 -lcentos
ssh: connect to host 192.168.100.143 port 22: Connection refused

もちろんwebサーバ等も同様にレスポンスが返ってこなくなります。

解決方法

監視エージェントを入れるべきだと思っています。

下はPrometheusでの例で、node_exporterからのメトリクスが5分間取れなければアラートを出します。

groups:
- name: example
  rules:
  - alert: Server down
    expr: up{job="metrix_by_node_exporter"} == 0
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: Server down

まとめ

Pingでの監視でわかることは疎通可能かどうかだけであり、Linuxサーバが正常に使える状態であったかを見ることはできません。
他の方法で監視することをおすすめします。

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

Linuxって何?【初学者がまとめてみた】

こんにちは、うったむです。今日はLinuxについてまとめてみました。よくわかっていなかったので、記事にしてみました。初学者の方の役に立ったら嬉しいです☺️

Linuxとは

オープンソースとして無料で利用でき、ウイルスやマルウェアの影響を受けにくいオペレーティングシステムのこと。

ユーザーが変更をほどこし、独自の商品として再配布することが可能。

CUIとGUIの違いやシェルについて

GUI(Graphical User Interface)

マウスで操作するスタイル。

基本的にはLinuxはCUIを使って操作するが、GUIだけで操作することも可能。

CUI(Character User Interface)

キーボードにて黒い画面にコマンドを打って操作するスタイル

なぜCUIが必要なの?

①CUIでしか操作できないPCがあるから

サーバー用PCはLinuxというOS。ほとんどの場合コマンドでしか操作できない。昔PCができた当初はCUIでしかパソコンは操作できなかった。

LinuxというOSは無料で使える。マウス(GUI)をつけて使いやすくしたものがWindowsやMac。GUIは有料...。プログラマーは必然的にコマンドを使って操作する必要がある。

②プログラム化ができるから

一つ一つを手動で作業する必要なし。自動化できる。1時間かかるものを数秒で終えられる。

DosとLinuxコマンド

  • Windowsは、Dosコマンド(rmdir)を使う
  • Mac/Linuxは、Linuxコマンド(rm)を使う

MacはLinuxと親和性があるのでプログラマーはMacを使うことが多い。Googleで検索する際、DosコマンドとLinuxコマンドは異なるので注意すべし。

シェルの種類

シェルは「OSのインタフェースを受け持つソフトウェア」のこと。OSの中心部分を覆う「殻(shell)」をイメージさせるのでシェルと呼ばれる。

シェルはサーバーにアクセスした時やコマンドでしかできない操作をする時に利用する。

OSに対して命令を出す「黒い画面(ターミナル)」に二種類のプログラム(シェル)がある。

  • Bash(バッシュ)
  • zsh(ゼットシェル。

最近のMacはzshに設定されている。zshの方がカスタムすると色々なことができるので便利。保存するファイルの場所がBashとzshが異なるので注意。

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

OpenChainの2020年と25日間の振り返り Look back on OpenChain's 2020

You can access the English version in the lower part of the page.

1. はじめに

メリークリスマス!
4日、6日、13日に続いて4度目登場の遠藤です。
本日はこの1年のOpenChainを振り返ると共に、25日間のまとめをしていきたいと思います。

2. CESではじまった2020

CES2020.png

2020年のOpenChain JWGの活動はラスベガスではじまりました。
自動車向けのLinuxであるAGLのコミュニティ及びOpenChain Automotive WGとコラボレーションし、
CES2020にOpenChainのミニブースの出展を行いました。
主な実施事項は以下の3点でした。

JWGで作成したリーフレットを配布し自動車業界の皆様にOSSライセンスコンプライアンスの重要性の周知
・OpenChainプロジェクトの紹介
・JWGが提案したOSS情報共有フォーマットSPDX Liteのツールを使った作成デモ
 (ちなみにSPDX Liteは本年SPDX2.2で正式に標準フォーマットの一つとして認定されました)

その結果、多くの来場者の方に興味を持って頂き、別会場で行ったワークショップにも足を運んでいただけました。

3. コロナ禍での活動のオンライン化

COVID-19の脅威は私たちの活動にもダイレクトに影響を与えました。
2月に開催予定だったDeNAでの全体会合は、急遽中止になり、Linux Foundationのイベントも次々とキャンセルになりました。

そこで私たちはWGの活動がオンラインで完結できるように、様々な取り組みをしてまいりました。
例えば、全体会合もZoomで実施して、録画はYouTubeで公開するようにしています。

OpenChain Japan Work Group Meeting #15
OpenChain Japan Work Group Meeting #16

その結果、首都圏・関西圏中心であった本活動が徐々に全国に拡大したというメリットがありました。
もちろん、私たちはF2Fの重要性も十分に認識していますので、将来的には再開していこうと考えています。

JapnWG#16.png
<11月のオンライン全体会合の模様>

4. ISO化

こうしてオンラインでの活動が定着した来たころビックニュースが飛び込んできました。
そう、OpenChain SpecのISO化です。
これに伴い、日本国内では本アドベントカレンダーだけでなく、様々な取り組みが行われています。

例えば、ShaneがLine Developer DayでISO化についての講演をしたり
渡邊さんが全体会合で標準の内容の解説を行ったりしています。

また、12月に行われたThe Linux Foundationのイベントでは下記のようにOpenChainに関連する講演やパネルディスカッションが数多く行われました。

Open Compliance Summit 2020
The Template OpenChain Policy: One Year On - Andrew Katz, Orcro Limited
Test Driven Open Source Compliance Automation: A New Initiative hosted at Open Chain - Karsten Reincke, Deutsche Telekom AG
OSS Compliance Audit - What to Expect In and From an Audit - Marcel Scholze & Julian Schauder, PwC GmbH
Regional Work Group Update: The Ultimate Panel - Moderated by SZ Lin, Moxa Inc; Masato Endo, Toyota Motor Corporation; Ayumi Watanabe, Hitachi Solutions, Ltd.; Miriam Ballhausen, Two Birds; Kris Feng, OPPO & Haksung Jang, SK Telecom
Extending OpenChain: Beyond Compliance - Andrew Katz, Orcro Limited & Anthony Decicco, GTC

Open Source Summit Japan + Automotive Linux Summit 2020
Ask the Experts Session with Shane Coughlan, General Manager, OpenChain, The Linux Foundation - Topic: Open Source License Compliance
Panel Discussion: OSS License Simple Viewer - New Tips to Make Your Compliance Work Simple - Ayumi Watanabe & Akira Shirai, Hitachi Solutions; Miyu Tanaka & Masato Endo, Toyota Motor Corporation
The Way Forward to Obtaining the OpenChain Certification - Tadayuki Osaki, Fujitsu; Miyu Tanaka & Masato Endo, Toyota Motor Corporation
OpenChain Panel in Japan - How to Promote OSS Community? - Moderated by Masato Endo, Toyota Motor Corporation
Keynote: OpenChain: The ISO Standard for Open Source Compliance - Shane Coughlan, OpenChain General Manager, The Linux Foundation
OSSJ.png

そしてついに12月15日から16日にかけてOpenChain Spec 2.1がISO/IEC 5230:2020が国際規格として承認されたことが、
6ヶ国語で発表されました!
Linux Foundationのオープン標準がISOになったのは14年の歴史ではじめてのことです。
オープンソース コンプライアンスの国際規格 ISO/IEC 5230:2020

それから数日、数々のトピックのプレスリリースが立て続けに行われ、ISO化に花を添えました。
トヨタ自動車株式会社がオープンソースコンプライアンスの世界標準であるISO/IEC 5230適合を発表した初めての企業に
NCSOFT Is The Second Company To Announce Adoption Of ISO/IEC 5230, The International Standard For Open Source Compliance
OpenChain Welcomes OSADL As An Official Partner
Cisco Announces Conformance To OpenChain 2.1 (ISO/IEC 5230)
Ericsson Joins The OpenChain Governing Board
OpenChain Welcomes Hitachi Solutions As An Official Partner

5. 25日間を振り返って

激動の2020年でしたが、OpenChainの活動はほぼオンライン化され、より参加しやすくなっています!
また、今回のアドベントカレンダーでも紹介しましたが、ISO化以外にも論文作成のプロジェクトが立ち上がったり、
Tooling SGの活動が活発になったり話題に事欠きません。
来年はISO化に伴いより多くの方々に関心を持っていただけると思うので、より忙しい一年になりそうです。

OepnChainはOSSコミュニティですので、誰でも自由に参加できます。
少しでも関心ある方は、MLに登録して、Zoom等で行われている全体会合に気軽に参加してみてください!

最後に、この企画の中心的役割を担っていただいた渡邊さん、執筆者の皆様ありがとうございました。
良いお年を!

1. Introduction

Merry Christmas!
This is Endo, who appeared for the fourth time following the 4th, 6th, and 13th.
Today, I would like to look back on 2020 of Open Chain and summarize the 25 days.

2.2020 started with CES

CES2020.png

The activities of the Open Chain JWG in 2020 began in Las Vegas.
In collaboration with AGL community and OpenChain Automotive WG,
we exhibited a mini booth of OpenChain at CES2020.
The main implementation items were the following three points.

-Distribute leaflets created by JWG to inform everyone in the automobile industry of the importance of OSS license compliance.
-Introduction of OpenChain project
-Demo created using the tools of the OSS information sharing format SPDX Lite proposed by JWG
(By the way, SPDX Lite was officially certified as one of the standard formats in SPDX2.2 this year)

As a result, many visitors were interested and visited the workshop held at another venue.

3. Online activities in the COVID-19 situation.

The threat of COVID-19 also directly affected our activities.
The all members meeting at DeNA, which was scheduled to be held in February, was suddenly canceled, and the Linux Foundation events were also canceled one after another.

Therefore, we have made various efforts so that the activities of the WG can be completed online.
For example, we also hold plenary meetings on Zoom and publish recordings on YouTube.

OpenChain Japan Work Group Meeting #15
OpenChain Japan Work Group Meeting #16

As a result, this activity has been expanding nationwide.
Of course, we are fully aware of the importance of F2F, and we plan to resume it in the future.

JapnWG#16.png

4. Published as an ISO

Big news jumped in when online activities became established in this way.
Yes, it is the ISO conversion of OpenChain Spec.
Along with this, various efforts are being made in Japan in addition to this Advent calendar.

For example, Shane gave a Lecture on ISO conversion on Line Developer Day.
Watanabe-san was doing Explanation of standard contents at the all members meeting.

Also, at the event of The Linux Foundation held in December, it is related to OpenChain as follows.
Many lectures and panel discussions were held.

In addition, at the event of The Linux Foundation held in December, many lectures and panel discussions related to OpenChain were held as follows.

Open Compliance Summit 2020
The Template OpenChain Policy: One Year On - Andrew Katz, Orcro Limited
Test Driven Open Source Compliance Automation: A New Initiative hosted at Open Chain - Karsten Reincke, Deutsche Telekom AG
OSS Compliance Audit - What to Expect In and From an Audit - Marcel Scholze & Julian Schauder, PwC GmbH
Regional Work Group Update: The Ultimate Panel - Moderated by SZ Lin, Moxa Inc; Masato Endo, Toyota Motor Corporation; Ayumi Watanabe, Hitachi Solutions, Ltd.; Miriam Ballhausen, Two Birds; Kris Feng, OPPO & Haksung Jang, SK Telecom
Extending OpenChain: Beyond Compliance - Andrew Katz, Orcro Limited & Anthony Decicco, GTC

Open Source Summit Japan + Automotive Linux Summit 2020
Ask the Experts Session with Shane Coughlan, General Manager, OpenChain, The Linux Foundation - Topic: Open Source License Compliance
Panel Discussion: OSS License Simple Viewer - New Tips to Make Your Compliance Work Simple - Ayumi Watanabe & Akira Shirai, Hitachi Solutions; Miyu Tanaka & Masato Endo, Toyota Motor Corporation
The Way Forward to Obtaining the OpenChain Certification - Tadayuki Osaki, Fujitsu; Miyu Tanaka & Masato Endo, Toyota Motor Corporation
OpenChain Panel in Japan - How to Promote OSS Community? - Moderated by Masato Endo, Toyota Motor Corporation
Keynote: OpenChain: The ISO Standard for Open Source Compliance - Shane Coughlan, OpenChain General Manager, The Linux Foundation
OSSJ.png

And after 15th Dec, many PRs related OpenChain were released!!
In the 14-year history of the inux Foundation, it is the first time that the open standard has become ISO.
ISO/IEC 5230:2020 Is The International Standard For Open Source Compliance
Toyota Is The First Company To Announce Adoption Of ISO/IEC 5230, The International Standard For Open Source Compliance
NCSOFT Is The Second Company To Announce Adoption Of ISO/IEC 5230, The International Standard For Open Source Compliance
OpenChain Welcomes OSADL As An Official Partner
Cisco Announces Conformance To OpenChain 2.1 (ISO/IEC 5230)
Ericsson Joins The OpenChain Governing Board
OpenChain Welcomes Hitachi Solutions As An Official Partner

5. Looking back on 25 days

It was a turbulent 2020, but OpenChain's activities are almost online, making it easier to participate!
Also, as I introduced in this Advent calendar, a academic project was launched in addition to ISO conversion.
The activity of Tooling SG becomes active and there is no shortage of topics.
Next year will be a busier year as we expect more people to be interested in the ISO.

OepnChain is an OSS community, so anyone is free to join.
If you are interested in it, please register with ML Please feel free to join the plenary meeting held at Zoom!

Thanks so much for reading our articles. And, a happy new year!!

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

MBRもGPTも無い世界もあるんですよ(blkdevpartsの紹介)

この記事はLinuxその2 Advent Calendar 2020の6日目です。

TL;DR

  • linux kernelのcommand lineにblkdevparts=... という記載をすると、パーティション情報をloaderから直接渡せるよ!
bootargs::
  blkdevparts=mmcblk0:1G(data0),1G(data1),-;mmcblk0boot0:1m(boot),-(kernel)

はじめに:どうやってパーティションは管理されているのか?

「ありがたいことに私の狂気(パーティション)は君達の神(MBR/GPT)が保証してくれるというわけだ(パン) 」

現代コンピュータにおけるパーティション管理

そもそも、パーティションとは、ハードディスクの記憶領域を論理的に分割する事を意味していた。現在主流の技術を中心に見ていく。

  • 過去には、SASIのハードディスクのように40MBと20MB x 2に切り替えられるようなものもありましたけどね!!
  • UNIXはVTOC(Volume Table of Contents)ですね……

MBR (Master Boot Record )

IBM機のBIOS制限を継承したもの。

  • ハードディスクの先頭セクタに、基本パーティションもしくは拡張パーティションを4つ記憶。
    • 拡張パーティションの中に、論理パーティションを作る事ができる。
    • CHS方式で管理するが、容量制限厳しい(後述のLBA方式に移行済み)。(C : Cylinder, シリンダ ( 0~1023)/H : Head, ヘッド (0~254)/S : Sector ( 1~ 63))

GPT (GUID Partition Table)

パーティション管理方式をMBRから置き換える技術。

  • 後方互換のためにMBR情報を含む。
    • 基本的には「1パーティション」という情報を入れる。
    • だが、ハイブリッドMBRとして、GPT/MBRで同じ情報を入れる場合も(やっかいな)
LBA 情報 備考
0 MBR *ここがややこしい
1 GPTパーティションテーブル・ヘッダー 128 エントリまで
2~33 GPTパーティションエントリ
34~ パーティション
---- 第2GPTパーティションエントリ
---- 第2GPTパーティションテーブル・ヘッダー
---- 第2MBR

LVM(Logical Volume Manager, おまけ)

LVM(Logical Volume Manager)も一応言及しておく。

  • 物理パーティションを、LVMに登録しておく。
  • LVMはパーティションを登録済み物理パーティションから割り当てる。
  • これであとからディスクを追加するとかも、サイズを大きくするとか、やりたい放題!

という夢のような技術ですが…… 今回の話では見なかったことに。

本題:MBR/GPTも無しにパーティションをマウント

「よろしい ならば私も問おう。君らの神(MBR/GPT)の正気(Integrity)は一体どこの誰が保障してくれるのだね?」

MBR/GPTの正当性確認をするのは、いわゆるLoaderですね。

だが、ちょっと待ってほしい…… 組み込み技術において、本当にMBR/GPTは必要なのだろうか? 例えば、こういう構成がある。

  • 内蔵ストレージ容量は固定。128 GBとか決まっている。
  • ストレージはボード上にEmbeddedされており、交換不可能。
  • 組み込み技術では「可用性(問題なく利用できること)が重要視される。

極端なことを言えば、 交換できないストレージの管理情報だったら、むしろROM上のloaderが固定保持する方がセキュアである

loaderからkernelへパーティション情報を引き渡すblkdevparts

Embedded device command line partition parsing に、loaderからkernelへパーティション情報を引き渡す手段についての記載がある。

少し、邦訳しつつ説明をする。

The “blkdevparts” command line option adds support for reading the block device partition table from the kernel command line.
It is typically used for fixed block (eMMC) embedded devices. It has no MBR, so saves storage space. Bootloader can be easily accessed by absolute address of data on the block device. Users can easily change the partition.

"blkdevparts" command line optionは、kernel command lineから、block device partition tableを読み出すことを実現する。
これは一般的にはdeviceに組み込まれる固定ディスク(eMMC)に用いられる。これらはMBRを持たず、ストレージ空間しか保持しない。Bootloaderはblock device上のデータの絶対的なアドレスに簡単にアクセスできる。Userは簡単にパーティションを変更できる。

つまり、「いきなりMBRなしで、パーティションを配置してもよい」ということですね!

使い方

もうちょっと使い方についても補足をする。

Example:

    eMMC disk names are "mmcblk0" and "mmcblk0boot0".

  bootargs::

    'blkdevparts=mmcblk0:1G(data0),1G(data1),-;mmcblk0boot0:1m(boot),-(kernel)'

  dmesg::

    mmcblk0: p1(data0) p2(data1) p3()
    mmcblk0boot0: p1(boot) p2(kernel)

ここで、1Gと書いているのは容量1G、"-"と書いているのは残り全部の容量など。よって以下のようなパーティションが指定されたことになる。

◯ディスクブロックデバイス(mmcblk0)
 ├ 1G(data0) -> mmbclk0p1
 ├ 1G(data1) -> mmbclk0p2
 └ 残り全部 -> mmbclk0p3() 

◯ディスクブロックデバイス(mmcblk0boot)
 ├ 1m(boot) -> mmbclk0boot0p1
 └ 残り全部 -> mmbclk0boot0p2

ソースコード拝見

blkdevparts= で指定されたオプションはファイルローカルな変数cmdlineに保持。

block/partitions/cmdline.c
static int __init cmdline_parts_setup(char *s)
{
    cmdline = s;
    return 1;
}
__setup("blkdevparts=", cmdline_parts_setup);

パーティション認識時に、コマンドライン文字列解析も呼ばれる。

このあたりのコードで、他のディスクパーティション管理方式を横並びに、コマンドライン解析も行われる。

block/partitions/core.c
static int (*check_part[])(struct parsed_partitions *) = {
    /*
     * Probe partition formats with tables at disk address 0
     * that also have an ADFS boot block at 0xdc0.
     */

#ifdef CONFIG_ACORN_PARTITION_ADFS
    adfspart_check_ADFS,
#endif

#ifdef CONFIG_CMDLINE_PARTITION
    cmdline_partition, ★これが今回
#endif
#ifdef CONFIG_EFI_PARTITION
    efi_partition,      /* this must come before msdos */
#endif
#ifdef CONFIG_SGI_PARTITION
    sgi_partition,
#endif
#ifdef CONFIG_LDM_PARTITION
    ldm_partition,      /* this must come before msdos */
#endif
#ifdef CONFIG_MSDOS_PARTITION
    msdos_partition, ★これがMBR
#endif
#ifdef CONFIG_OSF_PARTITION
    osf_partition,
#endif

コマンドライン文字列解析して、parse成功したらこれで追加。

block/partitions/cmdline.c
/*
 * Purpose: allocate cmdline partitions.
 * Returns:
 * -1 if unable to read the partition table
 *  0 if this isn't our partition table
 *  1 if successful
 */
int cmdline_partition(struct parsed_partitions *state)
{
    sector_t disk_size;
    char bdev[BDEVNAME_SIZE];
    struct cmdline_parts *parts;

    if (cmdline) { ★これは一回しか実行されない
        if (bdev_parts)
            cmdline_parts_free(&bdev_parts);

        if (cmdline_parts_parse(&bdev_parts, cmdline)) {
            cmdline = NULL;
            return -1;
        }
        cmdline = NULL;
    }

    if (!bdev_parts)
        return 0;

    bdevname(state->bdev, bdev);
    parts = cmdline_parts_find(bdev_parts, bdev);
    if (!parts)
        return 0;

    disk_size = get_capacity(state->bdev->bd_disk) << 9;

    cmdline_parts_set(parts, disk_size, 1, add_part, (void *)state);
    cmdline_parts_verifier(1, state);

    strlcat(state->pp_buf, "\n", PAGE_SIZE);

    return 1;
}

blkdevpartsによってできる事。

(MBRを使っていても) パーティション情報が破損していても、マウントできる、かなあ…?

例えば、外付けハードディスクだった場合を考える。この場合ならば、別のPCに接続してディスクコピーして、更にMBR情報を書き直せば、もしかすると中のデータを読み出せる「かも」しれない。

では、オンボードのeMMCだったら? まず、ディスクコピーができない。起動もしないのだから。そして、MBR情報を書き直せるのか?なかなか難しい課題に直面する。

そこで、blkdevpartsですよ!これらならば、起動時にloaderまで動けば、うまくするとMBR情報が壊れていても起動できる"かも"しれません。

この話の例外(外付けストレージ)

例1)PS4のように、内蔵ストレージを交換できるものは、当然交換するストレージ側にパーティション情報があった方がよい場合もある。ただし、どうせ暗号化などをしていて中身を見せるつもりが無いのであれば、最初からパーティション情報は入れないことも選択できる。

例2)USBストレージ(USBメモリやUSB HDD、USB SSD)に関しても、交換された先でも使えるように、ストレージ側にパーティション情報があった方がよい。ただこれも良かったり、悪かったり…。

このあたりは種々の条件にもよるので、まあ、そういう世界もありますよー、ぐらいの軽い気持ちで。

まとめ(再掲)

お忙しい中、ご精読ありがとうございました!

  • linux kernelのcommand lineにblkdevparts=... という記載をすると、パーティション情報をloaderから直接渡せるよ!
bootargs::
  blkdevparts=mmcblk0:1G(data0),1G(data1),-;mmcblk0boot0:1m(boot),-(kernel)

以上となります。

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

行番号のセパレータを変更するnlコマンドのsオプション

nlコマンドはsオプションを指定することで、行番号と入力行のセパレータ文字列を変更することができます。

sオプションの使い方

まずはマニュアルを参照してみましょう。説明の差はほとんどありません。-sの後に文字列を指定することで、セパレータを変更できるようです。そしてデフォルトはタブです。

info nl (GNU coreutils)

‘-s STRING’
‘--number-separator=STRING’
     Separate the line number from the text line in the output with
     STRING (default is the TAB character).

man nl (BSD)

     -s sep       Specify the characters used in separating the line number and
                  the corresponding text line.  The default sep setting is a sin-
                  gle tab character.

busybox nl --help

    -s STRING   Use STRING as line number separator

POSIX

-s sep
Specify the characters used in separating the line number and the corresponding text line. The default sep shall be a <tab>.

出典:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html

sオプションを試す

それでは最初の記事で使用したテキストファイル「utl-kita」で実際に試してみましょう。
まずは、セパレータをタブから,カンマに変更して出力をCSVにしてみます。-wオプションで駅ナンバリング表示したときのコマンド入力を流用します。

$ nl -n rz -w 2 -s , utl-kita | sed 's/^/JU/'
JU01,東京
JU02,上野
JU03,尾久
JU04,赤羽
JU05,浦和
JU06,さいたま新都心
JU07,大宮

これで駅ナンバリング表示のCSVデータを作成することができました。元からあるCSVデータに通し番号のIDを振るときにとても便利なオプションです。

さらに、-sに指定できるのは文字(character)ではなく文字列(string)となっているため、長い文字列を挿入することもできます。

$ nl -n rz -w 2 -s ',宇都宮線・高崎線,' utl-kita | sed 's/^/JU/'
JU01,宇都宮線・高崎線,東京
JU02,宇都宮線・高崎線,上野
JU03,宇都宮線・高崎線,尾久
JU04,宇都宮線・高崎線,赤羽
JU05,宇都宮線・高崎線,浦和
JU06,宇都宮線・高崎線,さいたま新都心
JU07,宇都宮線・高崎線,大宮

路線名の列を簡単に付加することができました。


余談

オプションのデフォルトがタブというのは以外にありがたいことのようにな気がしてきました。というのは、echo -eのように、nl -s '\t'としても残念ながらタブと識別されません。

$ nl -s '\t' utl-kita 
     1\t東京
     2\t上野
     3\t尾久
     4\t赤羽
     5\t浦和
     6\tさいたま新都心
     7\t大宮

ターミナルではCtrl+v Tabなどと入力すればタブがそのまま入力できるのですが、めったに使わないのでいつも忘れてしまいます。

$ nl -s '     ' utl-kita 
     1  東京
     2  上野
     3  尾久
     4  赤羽
     5  浦和
     6  さいたま新都心
     7  大宮

「難読化シェル芸」勢の方々は、もっとおもしろいタブの入力をやりそうです。なにかあればまた追記したいと思います。

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

Arch Linux インストール〜基本的な環境設定まで(UEFI/GPT/LVM/無線LAN)

前置き

特別定額給付金の使い道をどうしようかと考えていた折にYouTubeで以下の動画を見て、自作PCを組むことにしました。

前々からLinuxマシンが欲しかったのもあり、OSはLinuxを選択。
せっかくPCを組むならOSも自作感溢れるものが良かろうと、ディストリビューションはArch Linuxにすることにしました。
(Gentooはさすがに勇気が出ず。。あとはNixOSも面白そうで迷いました。)
使い始めてまだ数ヶ月ですが、とても快適で楽しいです。Arch Linuxを弄っているだけで無限に時間が溶けていく。。

Arch Linuxは公式Wikiがしっかりしていますし、調べればいっぱい情報は出てきます。
ただ、それでも自分の環境に合わせるためには、相当調べ回って色々と試行錯誤しました。
自分の備忘録としても、これから同じような環境でArch Linuxのインストールに挑む人のためにも、ここに手順を残しておくことにします。

Arch Linux インストール

主に以下の記事を参考にしました。
本記事の章立ては基本的にArchWikiのインストールガイドに沿って作成しています。

インストールの準備

インストールメディアの作成

まずはArch Linuxをダウンロードし、USBに書き込む。
自分はWindowsだったので、Rufasを使用。パーティション構成はGPTを選択。

Live環境を起動

USBメモリからArch LinuxのLive環境を起動。この時点では有線LANで接続しておくのが良いかも。
本当はこの時点から無線LANで作業できれば良かったのですが、自分の場合はドライバの問題で接続できず。。

キーボードレイアウト

デフォルトはUS配列になっているため、使用しているキーボードによって設定変更を行う。

# ls /usr/share/kbd/keymaps/**/*.map.gz
# loadkeys jp106

起動モードの確認

UEFIで起動していることを確認

# ls /sys/firmware/
acpi  devicetree  dmi  efi  memmap
#

# efivar -l

インターネットへの接続

ネットワークインタフェースが有効になっていることを確認。

# ip link show
# ping -c 3 archlinux.jp

無線LANの設定

ドライバの確認。
自分の場合はerrorとなっていて、この時点ではWiFiが使用できませんでした。。
(Intel CPUの第10世代が出た直後だったためマザーボードが新しく、Live環境用のパッケージはまだ対応できていなかったのかもしれません)

# lspci -k | grep wifi
    Kernel driver in use: iwlwifi
    Kernel modules: iwlwifi, wl
#

# dmesg | grep firmware
[    5.206241] i915 0000:00:02.0: [drm] Finished loading DMC firmware i915/kbl_dmc_ver1_04.bin (v1.4)
[   10.440517] iwlwifi 0000:01:00.0: loaded firmware version 29.163394017.0 3168-29.ucode op_mode iwlmvm
[   10.441105] iwlwifi 0000:01:00.0: Direct firmware load for iwl-debug-yoyo.bin failed with error -2
#

# dmesg | grep iwlwifi
[   10.363189] iwlwifi 0000:01:00.0: enabling device (0000 -> 0002)
[   10.440517] iwlwifi 0000:01:00.0: loaded firmware version 29.163394017.0 3168-29.ucode op_mode iwlmvm
[   10.441105] iwlwifi 0000:01:00.0: Direct firmware load for iwl-debug-yoyo.bin failed with error -2
[   10.597903] iwlwifi 0000:01:00.0: Detected Intel(R) Dual Band Wireless AC 3168, REV=0x220
[   10.615568] iwlwifi 0000:01:00.0: base HW address: cc:f9:e4:36:9b:9c
#

ドライバに問題なければ、以下で接続できるはず。

# ip link show
# iw dev wlan0 link
# iw dev wlan0 scan | grep SSID
# wpa_supplicant -B -i wlan0 -c <(wpa_passphrase <ESSID> <password>)
# dhcpcd wlan0
# ip addr show

SSHの起動

リモートログインできるようにSSHを起動。rootパスワードも設定しておく。

# systemctl start sshd
# systemctl status sshd
# passwd root
# ip link show
# ip addr show

これで別の端末からTeraTermなどを使用して、リモートログイン可能となります。
コマンドをコピペで打てたり、作業ログが取得できたり。色々と便利!

システムクロックの更新

システムクロックを合わせておく。

# timedatectl set-ntp true
# timedatectl status
# systemctl is-active systemd-timesyncd
active
#

パーティション

自分は以下のようにしてみました。

パーティション VG LV サイズ ファイルシステム マウントポイント
/dev/nvme0n1p1 - - 512 MB FAT32 /boot/efi
/dev/nvme0n1p2 vg_main lv_swap 8 GB swap -
/dev/nvme0n1p2 vg_main lv_root 50 GB XFS /
/dev/nvme0n1p2 vg_main lv_var 50 GB XFS /var
/dev/nvme0n1p2 vg_main lv_home 残り全て XFS /home

事前に現在の状態を確認。

# fdisk -l
# lsblk
# blkid
# df -Th

gdiskコマンドでディスクをパーティショニング。

# gdisk -l /dev/nvme0n1

# gdisk /dev/nvme0n1
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): o 
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-976773134, default = 2048) or {+-}size{KMGTP}: (何もせずにEnter)
Last sector (2048-976773134, default = 976773134) or {+-}size{KMGTP}: +512M
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to 'EFI system partition'

Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-976773134, default = 1050624) or {+-}size{KMGTP}: (何もせずにEnter)
Last sector (1050624-976773134, default = 976773134) or {+-}size{KMGTP}: (何もせずにEnter)
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): (何もせずにEnter)
Changed type of partition to 'Linux filesystem'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/nvme0n1.
The operation has completed successfully.
#

# gdisk -l /dev/nvme0n1
# lsblk

LVMでPV/VG/LVの作成。

# pvcreate /dev/nvme0n1p2
# pvs
# pvscan
# pvdisplay
# vgcreate vg_main /dev/nvme0n1p2
# vgs
# vgscan
# vgdisplay
# lvcreate -L 8G -n lv_swap vg_main
# lvcreate -L 50G -n lv_root vg_main
# lvcreate -L 50G -n lv_var vg_main
# lvcreate -l 100%FREE -n lv_home vg_main
# lvs
# lvscan
# lvdisplay

パーティションのフォーマット

それぞれ任意のファイルシステムでフォーマット。

# mkfs.vfat -F 32 /dev/nvme0n1p1
# mkswap /dev/vg_main/lv_swap
# swapon /dev/vg_main/lv_swap
# swapon -s

# mkfs.xfs /dev/vg_main/lv_root
# mkfs.xfs /dev/vg_main/lv_var
# mkfs.xfs /dev/vg_main/lv_home

ファイルシステムのマウント

それぞれマウントポイントを作成して、マウントする。

# mount /dev/vg_main/lv_root /mnt
# mkdir -p /mnt/boot/efi
# mkdir -p /mnt/var
# mkdir -p /mnt/home
# mount /dev/nvme0n1p1 /mnt/boot/efi
# mount /dev/vg_main/lv_var /mnt/var
# mount /dev/vg_main/lv_home /mnt/home

# df -Th
# mount

インストール

ミラーの選択

日本のリポジトリを上に持ってくるように編集する記事が多いですが、今はデフォルトでjpのリポジトリがなさそうなので特に何もしなくて良いかと。

# ls -l /etc/pacman.d/mirrorlist
# cat /etc/pacman.d/mirrorlist | grep jp

ベースシステムのインストール

Arch Linuxの必須パッケージをインストール。

# pacstrap /mnt base base-devel linux linux-firmware

システムの設定

fstab の生成

再起動時にマウントしてくれるようにfstabを作成。

# genfstab -U /mnt >> /mnt/etc/fstab
# cat /mnt/etc/fstab

chroot

Arch Linuxをインストールした領域にchrootし、併せて作業に必要なパッケージを導入。

# arch-chroot /mnt
# pacman -S xfsprogs vim git

タイムゾーン

日本のタイムゾーンに設定し、ハードウェアクロックも合わせておく。

# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# hwclock --systohc --utc
# timedatectl status

ロケール

システムロケールの設定を行う。後ほど日本語フォントを入れるので、一旦英語(en_US.UTF-8)にしておく。

# ls -l /etc/locale.gen
# cat /etc/locale.gen | grep -vE "^#|^$"
# vim /etc/locale.gen
/etc/locale.gen
### 以下のコメントアウトを解除する

en_US.UTF-8 UTF-8
ja_JP.UTF-8 UTF-8
# cat /etc/locale.gen | grep -vE "^#|^$"
# locale-gen
# echo "LANG=en_US.UTF-8" > /etc/locale.conf
# cat /etc/locale.conf

キーボードレイアウトはUS配列になっているため、使用しているキーボードによって設定をしておく。

# echo "KEYMAP=jp106" > /etc/vconsole.conf
# cat /etc/vconsole.conf

ネットワーク設定

ホスト名を設定する。

# echo myhostname > /etc/hostname
# vim /etc/hosts
/etc/hosts
127.0.0.1   localhost
::1     localhost
127.0.1.1   myhostname.localdomain  myhostname

ネットワーク関連で必要なパッケージを導入。

# pacman -S dhcpcd iw networkmanager wireless_tools wpa_supplicant
# systemctl enable NetworkManager

Initramfs

自分の場合はLVMにしているので、OS起動のために対応が必須。初回はここでだいぶハマりました。。

# pacman -S lvm2
# ls -l /etc/mkinitcpio.conf*
# cp -p /etc/mkinitcpio.conf{,.org}
# cat /etc/mkinitcpio.conf | grep -vE "^#|^$"
# vim /etc/mkinitcpio.conf
/etc/mkinitcpio.conf
# HOOKSに systemd と sd-lvm2 を追加

HOOKS=(base systemd udev autodetect modconf block sd-lvm2 filesystems keyboard fsck)
# cat /etc/mkinitcpio.conf | grep -vE "^#|^$"
# mkinitcpio -P

Root パスワード

rootユーザのパスワードを変更。

# passwd root

ついでに一般ユーザの作成とsudoの設定をしておく。

# useradd -m -g users -G wheel -s /bin/bash myusername
# passwd myusername

# cat /etc/sudoers | grep -vE "^#|^$"
# visudo
/etc/sudoers
### どちらかのコメントアウトを解除する(sudo実行時にパスワード入力するかしないかの違い)

## Uncomment to allow members of group wheel to execute any command
# %wheel ALL=(ALL) ALL

## Same thing without a password
# %wheel ALL=(ALL) NOPASSWS: ALL

viコマンドがないとvisudoコマンドを実行したときにエラーとなってしまう。以下で回避する。

# pacman -S vi

または

# ln -s /usr/bin/vim /usr/bin/vi

ブートローダー

使用しているCPUに合わせて、マイクロコードのアップデートを有効にする。

### Intel CPUの場合
# pacman -S intel-ucode

### AMD CPUの場合
# pacman -S amd-ucode

ブートローダはGRUBを使用する。

# pacman -S grub dosfstools efibootmgr
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch --recheck --debug
# grub-mkconfig -o /boot/grub/grub.cfg
# mkdir /boot/efi/EFI/boot
# cp -p /boot/efi/EFI/arch/grubx64.efi /boot/efi/EFI/boot/bootx64.efi

再起動

OSを再起動して、インストールを完了。

# exit
# umount -R /mnt
# reboot

環境設定

ここから先は主に以下を参考にしています。

ネットワーク

無線LANに接続する。
自分の場合はlinux-firmware導入前はドライバでエラーが起きていたので、解消されたかを確認しています。

$ su -
# lspci -k | grep wifi
# dmesg | grep firmware
# dmesg | grep iwlwifi

# ip link show
# iw dev wlp1s0 link
# iw dev wlp1s0 scan | grep SSID
# wpa_supplicant -B -i wlp1s0 -c <(wpa_passphrase <ESSID> <password>)

DHCPでIPアドレスを割り振る。
dhcpcdは/etc/resolv.conf自動で上書きするため、気にする場合は事前にバックアップしておく。

# cp -p /etc/resolv.conf{,.org}
# dhcpcd wlp1s0
# ip addr show

OS起動時に自動でIPアドレスを取得するよう設定する。
設定後にOSを再起動して設定が上手くいっているか確認。

# wpa_passphrase <ESSID> <password> > /etc/wpa_supplicant/wpa_supplicant-wlp1s0.conf
# systemctl enable wpa_supplicant@wlp1s0
# systemctl enable dhcpcd@wlp1s0
# reboot

$ iw dev wlp1s0 link
$ ip addr show

ミラーリスト

日本のリポジトリを設定しておく。

$ sudo cp -p /etc/pacman.d/mirrorlist{,.org}
$ sudo curl -o /etc/pacman.d/mirrorlist https://www.archlinux.org/mirrorlist/?country=JP&protocol=http&protocol=https&ip_version=4
$ sudo vim /etc/pacman.d/mirrorlist
/etc/pacman.d/mirrorlist
### Server行のコメントアウトを解除する。httpsのものを上に寄せておくといい感じ。

## Japan
#Server = http://mirrors.cat.net/archlinux/$repo/os/$arch
#Server = https://mirrors.cat.net/archlinux/$repo/os/$arch
#Server = http://ftp.tsukuba.wide.ad.jp/Linux/archlinux/$repo/os/$arch
#Server = http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch
#Server = https://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch

AURヘルパー

色々便利なものを導入できるようにAURヘルパーを導入しておく。調べた感じだとyayが人気みたい。

$ git clone https://aur.archlinux.org/yay
$ cd yay && makepkg -si --noconfirm && cd .. && rm -rf yay

Bash

入力補完の強化のためにパッケージを導入しておく。(すぐにzshやfishにする人の方が多そうではあるけど。。)

$ sudo pacman -S bash-completion

デスクトップ環境

GUIのデスクトップ環境を導入する。何となくBudgie Desktopにしてみた。
そのうちawesomeやxmonadなどのタイル型ウィンドウマネージャにしてみたい。。
あとはX Serverにしてしまっているけど、本当はWaylandの方がいいのかもしれないなとか思っていたり。。

まずはX Serverを導入。
CPUによってインストールするドライバが違うため、詳細は Xorg#ドライバーのインストール - ArchWiki を参照。
自分の場合はIntel CPUのため、以下を導入。

$ lspci | grep -E "VGA|3D"
$ sudo pacman -S xorg-server xf86-video-fbdev xf86-video-vesa xf86-video-intel mesa xorg-xinit
$ sudo pacman -S xorg-twm xorg-xclock xterm
$ sudo startx

### exit で X を抜ける

Budgie Desktopを導入。GNOMEが必要なので一緒に入れる。

$ sudo pacman -S budgie-desktop gnome
$ sudo systemctl enable gdm
$ vim ~/.xinitrc
~/.xinitrc
export XDG_CURRENT_DESKTOP=Budgie:GNOME
exec budgie-desktop
sudo reboot now

ユーザ選択後のパスワード入力画面で、右下の歯車(セッション設定)からBudgie Desktopを選択する。
(最初これがわからずドハマりしました。。。)

日本語環境

日本語フォントにはIPAフォントを導入。

$ sudo pacman -S otf-ipafont

インプットメソッドにはfcitxを導入。

$ sudo pacman -S fcitx-im fcitx-mozc fcitx-configtool
$ vim ~/.xprofile
~/.xprofile
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
fcitx

システムロケールを日本語(ja_JP.UTF-8)に変更する。
GNOMEだと以下のgsettingsコマンドを打たないとfcitxが有効にならなかった

$ sudo localectl set-locale LANG=ja_JP.UTF-8
$ gsettings set org.gnome.settings-daemon.plugins.xsettings overrides "{'Gtk/IMModule':<'fcitx'>}"
$ sudo reboot now

時刻同期

時刻同期にはChronyを選択。

$ sudo pacman -S chrony
$ sudo cp -p /etc/chrony.conf{,.org}
$ sudo vim /etc/chrony.conf
/etc/chrony.conf
### SPECIFY YOUR NTP SERVER に server を追加
server 0.jp.pool.ntp.org iburst
server 1.jp.pool.ntp.org iburst
server 2.jp.pool.ntp.org iburst
server 3.jp.pool.ntp.org iburst

### 以下はデフォルトで有効なはず
driftfile /var/lib/chrony/drift
rtconutc
rtcsync
$ cat /etc/chrony.conf | grep -vE "^[#;%\!]|^$"
$ sudo systemctl is-active systemd-timesyncd
inactive
$

$ sudo systemctl start chronyd
$ sudo systemctl enable chronyd
$ chronyc sources

ファイアウォール

ファイアウォールにはnftablesを選択。そのままで大丈夫そうなので特に設定は弄ってない。
(SSHのポート22が空いてるので、必要に応じて閉じた方が良いかも)

$ sudo pacman -S nftables
$ sudo systemctl is-active nftables
$ sudo systemctl start nftables
$ sudo systemctl enable nftables
$ sudo nft list ruleset

アンチウィルス

ClamAVを入れてみた。

$ sudo pacman -S clamav
$ sudo systemctl start clamav-daemon
$ sudo systemctl enable clamav-daemon
$ su -
# freshclam

$ sudo systemctl start clamav-freshclam
$ sudo systemctl enable clamav-freshclam
$ curl https://www.eicar.org/download/eicar.com.txt | clamscan -

ブラウザ

ウェブブラウザ - ArchWiki

Firefox、Chromium、Vivaldiなどをお好みで。

### Firefox
$ sudo pacman -S firefox firefox-i18n-ja

### Chromium
$ sudo pacman -S chromium

### Vivaldi
$ sudo pacman -S vivaldi

DNSローカルキャッシュ

LinuxはDNSのキャッシュをローカルで持たないので、
pdnsdはBINDやdnsmasqなど違って、OS再起動後もキャッシュを保持するらしいので選択してみた。
設定ファイルは正直かなり適当にしているので、見直さないといけない気がしている。。

$ sudo pacman -S pdnsd
$ sudo cp -p /usr/share/doc/pdnsd/pdnsd.conf /etc/pdnsd.conf
$ sudo vim /etc/pdnsd.conf
/etc/pdnsd.conf
global {
    perm_cache=1024;
    cache_dir="/var/cache/pdnsd";
#   pid_file = /var/run/pdnsd.pid;
    run_as="pdnsd";
    server_ip = 127.0.0.1;  # Use eth0 here if you want to allow other
                # machines on your network to query pdnsd.
    status_ctl = on;
#   paranoid=on;       # This option reduces the chance of cache poisoning
                       # but may make pdnsd less efficient, unfortunately.
    query_method=udp_tcp;
    min_ttl=15m;       # Retain cached entries at least 15 minutes.
    max_ttl=1w;        # One week.
    timeout=10;        # Global timeout option (10 seconds).
    neg_domain_pol=on;
    udpbufsize=1024;   # Upper limit on the size of UDP messages.
}

server {
    label= "google";
    ip = 8.8.8.8,8.8.4.4;  # Put your ISP's DNS-server address(es) here.
 #  proxy_only=on;     # Do not query any name servers beside your ISP's.
                       # This may be necessary if you are behind some
                       # kind of firewall and cannot receive replies
                       # from outside name servers.
    timeout=4;         # Server timeout; this may be much shorter
               # that the global timeout option.
    uptest=if;         # Test if the network interface is active.
    interface=wlp1s0;    # The name of the interface to check.
    interval=10m;      # Check every 10 minutes.
    purge_cache=off;   # Keep stale cache entries in case the ISP's
               # DNS servers go offline.
    edns_query=yes;    # Use EDNS for outgoing queries to allow UDP messages
               # larger than 512 bytes. May cause trouble with some
               # legacy systems.
 }

server {
    label= "myisp";
    ip = 192.168.1.1;  # Put your ISP's DNS-server address(es) here.
#   proxy_only=on;     # Do not query any name servers beside your ISP's.
                       # This may be necessary if you are behind some
                       # kind of firewall and cannot receive replies
                       # from outside name servers.
    timeout=4;         # Server timeout; this may be much shorter
               # that the global timeout option.
    uptest=if;         # Test if the network interface is active.
    interface=wlp1s0;    # The name of the interface to check.
    interval=10m;      # Check every 10 minutes.
    purge_cache=off;   # Keep stale cache entries in case the ISP's
               # DNS servers go offline.
    edns_query=yes;    # Use EDNS for outgoing queries to allow UDP messages
               # larger than 512 bytes. May cause trouble with some
               # legacy systems.
}
$ sudo systemctl start pdnsd
$ sudo systemctl enable pdnsd
$ sudo systemctl status pdnsd

dhcpcdが/etc/resolv.confを上書きするので、設定を変えておく。

$ sudo cp -p /etc/dhcpcd.conf{,.org}
$ sudo vim /etc/dhcpcd.conf
/etc/dhcpcd.conf
### ファイル末尾に追加

nohook resolv.conf

man

manコマンドでコマンドオプションや設定ファイルについて調べようとしたら、なんとデフォルトでは入っていなかった…!

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

ZRAM について軽く調べてみた

初めに

久しぶりに Fedora (fedora 33) を触ったところ、swap が swap-on-zram という見慣れない形式に変わっていたので zram について調べてみました


サマリー

  • メモリ上にブロックデバイスを構成し、そこに書き込むデータを圧縮することにより高速な I/O とメモリ領域の有効活用を行う技術

要は圧縮機能付き RAM Disk です。 swap や /tmp, /var の一部キャッシュなどの用途に使われることが想定されているようです。
「swap をメモリ上に置く」と聞くと本末転倒な印象を受けますが、メモリ上のあまり使われていないブロックを圧縮する、というとすんなり理解ができると思います。(ただしこれは正確な表現ではありません)
また、圧縮する際に中間データなどを Disk 上に置かないようにすることにより、Disk I/O を排除し高速化が図られています。
Disk 上の swap 領域との I/O よりも、メモリ上の圧縮/展開の方が高速なため、「メモリ上の swap 領域」というものが実現されます。

イメージとしてはこんな感じです ↓
20201205_01.png

メモリを大量に使い swap まで含めた処理を行うような場合、Disk に swap out するよりも zram 上に swap out する方が(圧縮処理の時間はかかるものの)速いうえに、圧縮することにより swap も含めた仮想メモリ全体の容量も増えることになります。

以下、swap からは離れて、zram 自体について、zram: Compressed RAM based block devices に沿ってみていきたいと思います。

環境

fedora 33 ( on KVM )
4GB メモリ

lsmem
# lsmem
RANGE                                 SIZE      STATE REMOVABLE BLOCK
0x0000000000000000-0x000000007fffffff   2G オンライン       yes  0-15
0x0000000100000000-0x000000017fffffff   2G オンライン       yes 32-47

メモリブロックサイズ  128M
Total online memory:       4G
Total offline memory:      0B
zramctl
# zramctl --output-all
NAME       DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT
/dev/zram0     1.9G   4K   74B lzo-rle         2          0   12K        0B      12K       0B [SWAP]


# zramctl -h    (※抜粋)

利用可能な出力の列:
        NAME  zram デバイス名
    DISKSIZE  圧縮前のデータ容量による制限
        DATA  圧縮前の格納されたデータのサイズ
       COMPR  圧縮後の格納されたデータのサイズ
   ALGORITHM  選択された圧縮アルゴリズム
     STREAMS  並行して実行される圧縮オペレーションの数
  ZERO-PAGES  empty pages with no allocated memory
       TOTAL  all memory including allocator fragmentation and metadata overhead
   MEM-LIMIT  memory limit used to store compressed data
    MEM-USED  memory zram have been consumed to store compressed data
    MIGRATED  number of objects migrated by compaction
  MOUNTPOINT  マウントされている場所

※ zramctl は util-linux パッケージに含まれています

free状況
# free -m
              total        used        free      shared  buff/cache   available
Mem:           3928         165        2705           0        1057        3538
Swap:          1963           0        1963

zram 試してみた

free -m を見る限り、 メモリ量としては 4GB と認識されているようです。
また、 vmstat 1 1 を見ても、 おおよそ 4GB ありそうです。
そのため、正確な根拠はありませんが、OS から見たメモリ量としては 4GB のままのようです。
(なお、zram を削除しても free -m の total 値は変わりませんでした)

zram の作成(zramctl)

swap は操作が面倒なので、ファイルシステムとして作成してみます。
下記の例の zram0 は swap on zram で利用されています。

zramctl コマンドで追加することができます。

zram追加
# zramctl -f -s 500M
/dev/zram1

zram の構成概要確認

zram の各種内容は zramctl --output-all で確認できます。

zram確認
# zramctl --output-all
NAME       DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT
/dev/zram1     500M   0B    0B lzo-rle         2          0    0B        0B       0B       0B
/dev/zram0     1.9G   4K   74B lzo-rle         2          0   12K        0B      12K       0B [SWAP]

まだどこにもマウントしていないので、 MOUNT-POINT はブランクです。
また、ドキュメントによると、メモリブロックサイズの倍数に切り上げられるそうです。

ファイルシステムの作成

mkfs コマンド等でファイルシステムを作成すると、圧縮 RAM Disk として利用可能です。

xfs作成
# mkfs.xfs /dev/zram1
meta-data=/dev/zram1             isize=512    agcount=4, agsize=32000 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=128000, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=1221, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
Discarding blocks...Done.

ファイルシステムのマウント

マウント
# mkdir /data/zram1
# mount /dev/zram1 /data/zram1
# df -h
ファイルシス                    サイズ  使用  残り 使用% マウント位置
/dev/zram1                        496M   29M  467M    6% /data/zram1

zram ファイルシステムを埋めてみる

dd コマンドを使って、ファイルシステムをデータで埋めてみます。

dd
# pwd
/data/zram1

# dd if=/dev/urandom of=/data/zram1/randfile bs=1M count=1024
dd: '/data/zram1/randfile' の書き込みエラー: デバイスに空き領域がありません
467+0 レコード入力
466+0 レコード出力
488701952 bytes (489 MB, 466 MiB) copied, 3.4548 s, 141 MB/s

# df -h .
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/zram1       496M  495M  428K  100% /data/zram1

# zramctl
NAME       ALGORITHM DISKSIZE  DATA  COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram1 lzo-rle       500M  469M 466.1M 466.3M       2 /data/zram1
/dev/zram0 lzo-rle       1.9G    4K    74B    12K       2 [SWAP]

zramctl で見る限り、 データは 469MiB あり、 圧縮して 466.1MiB のようです。
urandom でランダム文字列を作成しているため、圧縮効率は低いです。

いったん削除してから zero で書き込みしてみます。

まず、ファイルを削除します。

rm
# rm randfile
rm: 通常ファイル 'randfile' を削除しますか? y

# df -h .
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/zram1       496M   29M  467M    6% /data/zram1

# zramctl
NAME       ALGORITHM DISKSIZE  DATA  COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram1 lzo-rle       500M  469M 466.1M 466.3M       2 /data/zram1

ファイルを削除すると、 df の空き容量は増えますが、 zramctl の DATA サイズは減りません。
これは rm でファイルの i-node が削除されているだけで実データが残っているからだと思います。

次に、 zero で埋めてみます。

zero埋め
# dd if=/dev/zero of=/data/zram1/zerofile bs=1M count=1024
dd: '/data/zram1/zerofile' の書き込みエラー: デバイスに空き領域がありません
467+0 レコード入力
466+0 レコード出力
488701952 bytes (489 MB, 466 MiB) copied, 0.364888 s, 1.3 GB/s

# df -h .
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/zram1       496M  495M  428K  100% /data/zram1

# zramctl
NAME       ALGORITHM DISKSIZE  DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram1 lzo-rle       500M  469M   89K  256K       2 /data/zram1
/dev/zram0 lzo-rle       1.9G    4K   74B   12K       2 [SWAP]

df コマンドでは 100% になっています。
zramctl で見ると、 Data は 496MiB で urandom パターンと同じですが、圧縮されて 89KiB になっているようです。

結論としては、ブロックデバイスとして確保され、ユーザーとしての利用では指定したサイズとして利用可能ですが
物理的には圧縮されている分消費が少ないようです。

zram削除 (zramctl)

zram の削除は zramctl -r で削除します。 
いきなり打ってエラーを起こしているのは unmount せずに実行したらどうなるのかを見たかっただけで
決して 忘れていた わけではありません。はい。

zram削除
# zramctl -r /dev/zram1
zramctl: /dev/zram1: リセットに失敗しました: デバイスもしくはリソースがビジー状態です

# umount /data/zram1
# zramctl -r /dev/zram1

# zramctl
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lzo-rle       1.9G   4K   74B   12K       2 [SWAP]

zram とOS再起動

これも気になるところですね。 zram 再作成してデータを入れた状態を作ります。

# dd if=/dev/urandom of=/data/zram1/randfile bs=1M count=1024
dd: '/data/zram1/randfile' の書き込みエラー: デバイスに空き領域がありません
467+0 レコード入力
466+0 レコード出力
488701952 bytes (489 MB, 466 MiB) copied, 2.59002 s, 189 MB/s

# df -h .
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/zram1       496M  495M  428K  100% /data/zram1

# ls -l
合計 477248
-rw-r--r-- 1 root root 488701952 12月  5 23:46 randfile

この状態で OS 再起動します。

# shutdown -r now
...(略)

# ls -l /dev/zr*
brw-rw---- 1 root disk 251, 0 12月  5 23:47 /dev/zram0

デバイスレベルで消えているようです。まぁ、当たり前かもしれません。
(正直なところ、デバイスは残っていて中身だけ消えるのか、と思っていました。。)

zram の構成詳細確認

zram の構成については /sys/block/zramX/ 以下のファイルで確認することができます。

zram構成
# cd /sys/block/zram1
# ls
alignment_offset  compact            disksize           ext_range  inflight   max_comp_streams  power      reset   stat
bdi               debug_stat         events             hidden     initstate  mem_limit         queue      ro      subsystem
capability        dev                events_async       holders    integrity  mem_used_max      range      size    trace
comp_algorithm    discard_alignment  events_poll_msecs  idle       io_stat    mm_stat           removable  slaves  uevent

zram: Compressed RAM based block devicesに記載があったのは以下のものです

ファイル RW 概要
disksize RW デバイスのサイズの確認・設定
reset WO デバイスのリセット(消す)
mem_limit WO 圧縮データを格納するのに使えるメモリの最大容量
max_comp_streams RW 圧縮処理の並列実行数
comp_algorithm RW 圧縮アルゴリズムの表示/指定
compact WO メモリコンパクションの実行トリガー
backing_dev RW zram からの書き出し先ストレージデバイス
mm_stat RO メモリの使用状況

cat mm_stat を行った際の表示の内容について補足します。
(下記は zram0 (swap on zram) の例です )

# cat mm_stat
    4096       74    12288        0    12288        0        0        0
項目(左から順) 内容
orig_data_size 非圧縮状態でのサイズ(重複ページを除く) 単位:byte
compr_data_size 圧縮サイズ
mem_used_total アロケートされたメモリサイズ。フラグメンテーションやオーバーヘッドを含む。(よってデータサイズ合計と一致しない)。 スペースの利用効率は compr_data_size と mem_used_total で算出される。単位:byte
mem_limit 圧縮データの格納に利用できるメモリの最大サイズ
mem_used_max データ格納のために消費されたメモリの最大サイズ
same_pages 同じ内容のページの数。(1ページだけ保持され、他は同じなので保持されない)
pages_compacted メモリのコンパクションで解放されたページ数
huge_pages 圧縮が効かないページ数

他にも stat, io_stat, bd_stat などがありいろいろな情報が確認できます。
詳しくは zram: Compressed RAM based block devices をご覧ください。

zram 構成ファイルを用いたデバイスの操作

zram 追加

ここでは、 zram1 を zramctl を使わずに追加します。 /sys/class/zram-control/hot_add を読むだけでデバイスが増えます。
(ある意味恐ろしい)
先程紹介した /sys/block/zramX/ ではなく、追加削除は /sys/class/zram-control/ 以下の hot_add, hot_remove で行います。

hot-add
# ls /dev/zram*
/dev/zram0
# cat /sys/class/zram-control/hot_add
1
# ls /dev/zram*
/dev/zram0  /dev/zram1

zram のサイズ指定

一度デバイスができてからは、 デバイスの関連ファイルで操作します。 /sys/block/zramX/ 以下です。

# cat /sys/block/zram1/disksize
0

# echo 512M > /sys/block/zram1/disksize

# cat /sys/block/zram1/disksize
536870912

zram 圧縮アルゴリズム確認・指定

当記事では記載していませんが zramctl でも指定可能です

ファイルで指定する場合は、一度 reset する必要があるようです。
( zramctl コマンドでの reset はデバイスごと消えますが、 ここでのリセットはデバイスは消えず、
 後で紹介する hot_remove で消えます)

# cat /sys/block/zram1/comp_algorithm
lzo [lzo-rle] lz4 lz4hc 842 zstd

# echo lz4 > /sys/block/zram1/comp_algorithm
-bash: echo: 書き込みエラー: デバイスもしくはリソースがビジー状態です

# echo 1 > /sys/block/zram1/reset

# ls -l /dev/zra*
brw-rw---- 1 root disk 251, 0 12月  5 23:47 /dev/zram0
brw-rw---- 1 root disk 251, 1 12月  6 00:17 /dev/zram1


# echo lz4 > /sys/block/zram1/comp_algorithm

# cat /sys/block/zram1/comp_algorithm
lzo lzo-rle [lz4] lz4hc 842 zstd

[] の位置が変わっているのがわかると思います。あと当然ではありますが、 reset したときにデータは消えますのでご注意ください。

zram 削除

削除は hot_remove を使います。 場所が違いますのでご注意を

# ls -l /dev/zra*
brw-rw---- 1 root disk 251, 0 12月  5 23:47 /dev/zram0
brw-rw---- 1 root disk 251, 1 12月  6 00:17 /dev/zram1

# echo 1 > /sys/class/zram-control/hot_remove

# ls -l /dev/zra*
brw-rw---- 1 root disk 251, 0 12月  5 23:47 /dev/zram0

この記事では、 swap on zram というところから zram の操作について簡単に調べたことをまとめました。
ここでは確認していませんが、 Backing Device を用意してディスクにデータを吐き出させるようなことも
できるようです。
詳しくは参考のドキュメントをご覧ください。


参考)
■Compcache: in-memory compressed swapping
https://lwn.net/Articles/334649/
■Zram
https://ja.wikipedia.org/wiki/Zram
■zram: Compressed RAM based block devices
https://www.kernel.org/doc/Documentation/blockdev/zram.txt


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