20190330のLinuxに関する記事は4件です。

馬鹿の一つ覚え: systemd

非推奨 /etc/rc.d/rc.local

まずは非推奨ではあるが、CentOS 7では /etc/rc.d/rc.local が利用できるので、動作確認を行ってみる。

# cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core) 
# ls -ld /etc/rc*    # シンボリックリンクが張られている
drwxr-xr-x. 10 root root 118 Mar 11 15:32 /etc/rc.d
lrwxrwxrwx.  1 root root  13 Mar 11 15:32 /etc/rc.local -> rc.d/rc.local
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc0.d -> rc.d/rc0.d
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc1.d -> rc.d/rc1.d
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc2.d -> rc.d/rc2.d
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc3.d -> rc.d/rc3.d
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc4.d -> rc.d/rc4.d
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc5.d -> rc.d/rc5.d
lrwxrwxrwx.  1 root root  10 Mar 11 15:30 /etc/rc6.d -> rc.d/rc6.d
# cd /etc/rc.d/    # 実際にはこのディレクトリの中に
# ls -l
total 8
drwxr-xr-x. 2 root root 4096 Mar 12 16:06 init.d
-rw-r--r--. 1 root root  473 Oct 31 08:31 rc.local
drwxr-xr-x. 2 root root   74 Mar 12 16:07 rc0.d
drwxr-xr-x. 2 root root   74 Mar 12 16:07 rc1.d
drwxr-xr-x. 2 root root   74 Mar 13 10:25 rc2.d
drwxr-xr-x. 2 root root   74 Mar 13 10:25 rc3.d
drwxr-xr-x. 2 root root   74 Mar 13 10:25 rc4.d
drwxr-xr-x. 2 root root   74 Mar 13 10:25 rc5.d
drwxr-xr-x. 2 root root   74 Mar 12 16:07 rc6.d
# cat rc.local    # /etc/rc.d/rc.local ではなくsystemdを使うようにと書かれている
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.

touch /var/lock/subsys/local
# vi rc.local    # 最終行にコマンドを書き込んでみる
# tail -n1 rc.local 
date > /tmp/date.txt
# chmod +x /etc/rc.d/rc.local
# sync
# shutdown -r now    # 再起動
# ls -l /tmp/date.txt    # /etc/rc.d/rc.localに書き込んだコマンドが動いていた
-rw-r--r-- 1 root root 29 Mar 30 19:46 /tmp/date.txt
# cat /tmp/date.txt 
Sat Mar 30 19:46:24 JST 2019
# vi /etc/rc.d/rc.local 
# chmod -x /etc/rc.d/rc.local
# ls -l /etc/rc.d/rc.local
-rw-r--r-- 1 root root 473 Mar 30 20:01 /etc/rc.d/rc.local
# rm -f /tmp/date.txt 

systemdの使い方

シェルスクリプトを用意し、Unit定義ファイルを作成、自動起動設定をする。

# ls -l /usr/local/tmp/foo.sh 
-rwxr-xr-x 1 root root 66 Mar 30 21:07 /usr/local/tmp/foo.sh
# cat /usr/local/tmp/foo.sh
#!/bin/sh
while true
do
  date >> /tmp/date.txt
  sleep 2000
done
# vi /etc/systemd/system/foo.service    # Unit定義ファイルを作成
# ls -l /etc/systemd/system/foo.service
-rw-r--r-- 1 root root 183 Mar 30 21:15 /etc/systemd/system/foo.service
# cat /etc/systemd/system/foo.service    # フォーマットやスペリングを間違えないように
[Unit]
Description = test systemd with date
After = network.target

[Service]
ExecStart = /usr/local/tmp/foo.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
# systemctl list-unit-files --type=service |grep foo    # disabled 表示
foo.service                                   disabled
# systemctl enable foo    # 自動起動設定
Created symlink from /etc/systemd/system/multi-user.target.wants/foo.service to /etc/systemd/system/foo.service.
# systemctl start foo
# ls -l /tmp/date.txt 
-rw-r--r-- 1 root root 29 Mar 30 23:28 /tmp/date.txt
# ps -ef | grep foo | grep sh
root     27352     1  0 23:28 ?        00:00:00 /bin/sh /usr/local/tmp/foo.sh
# systemctl stop foo
# ps -ef | grep foo | grep sh
# sync
# shutdown -r now
# ls -l /tmp/date.txt
-rw-r--r-- 1 root root 58 Mar 30 23:32 /tmp/date.txt
# ps -ef | grep foo | grep sh    # 自動起動を確認
root     20644     1  0 23:32 ?        00:00:00 /bin/sh /usr/local/tmp/foo.sh
# kill 20644    # Restart = always なのでkillしても起動
# ls -l /tmp/date.txt
-rw-r--r-- 1 root root 87 Mar 30 23:34 /tmp/date.txt
# ps -ef | grep foo | grep sh
root     26807     1  0 23:34 ?        00:00:00 /bin/sh /usr/local/tmp/foo.sh
# systemctl stop foo
# ps -ef | grep foo | grep sh    # 停止
# systemctl status foo
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS

はじめに

linux kernel configの一つ、CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSについて掘り下げてみる。
主に参考にしたlinux kernelは、v4.15

TL;DR

CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSはdefconfigで結構無効にされてしまっているけど、使えるgdbのバージョンが6.7以降なら有効にしておこう。

CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSとは何か

core dump生成時、Disk I/Oやストレージ容量への負荷を減らすため、テキスト領域のように変更されないメモリはデフォルトで保存しない。
デバッグ時に、必要に応じて実行ファイルを読みこめばいいからだ。
実行ファイルのELFヘッダもその部類に入る。
つまりメモリにロードされてから変更されることは基本的にない。
ただ、CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSが有効な場合は、デフォルトでクラッシュしたプログラムのELFヘッダもcoreファイル中に保存するようになる。

ELFヘッダにはビルドID等の情報が含まれるため、解析時に対応させるべきデバッグシンボルを特定する際などに有益な場合があるからだ。

CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSはあくまでもデフォルト値を変更するだけで、起動後にprocfs経由で変更することもできる。
/proc/PID/coredump_filterの"(bit 4) ELF header pages in file-backed private memory areas"を立てればよい。

実装

CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSが使われているのは下記の一箇所。
有効なときはMMF_DUMP_FILTER_DEFAULTにMMF_DUMP_ELF_HEADERSビットが立つ。

include/linux/sched/coredump.h
#define MMF_DUMP_FILTER_DEFAULT \
        ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\
         (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF)

#ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS
# define MMF_DUMP_MASK_DEFAULT_ELF      (1 << MMF_DUMP_ELF_HEADERS)
#else
# define MMF_DUMP_MASK_DEFAULT_ELF      0
#endif

MMF_DUMP_ELF_HEADERSをチェックしているのは、vma_dump_size関数。
マクロを使っているため単純なgrepではヒットしないので注意。
その名のとおり、core dump生成時vmaごとにダンプすべきサイズを算出している。
vmaの先頭がELFヘッダを示すマジックワード(0x7f, 'E' ,'L', 'F')と一致したら、PAGE_SIZEを返す。
(=ELFヘッダが含まれると見られる領域を1ページ分ダンプする)

linux/fs/binfmt_elf.c
static unsigned long vma_dump_size(struct vm_area_struct *vma,
                                   unsigned long mm_flags)
{
#define FILTER(type)    (mm_flags & (1UL << MMF_DUMP_##type))

(中略)

        if (FILTER(ELF_HEADERS) &&
            vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
                u32 __user *header = (u32 __user *) vma->vm_start;
                u32 word;
                mm_segment_t fs = get_fs();
                /*                                                                                                                                
                 * Doing it this way gets the constant folded by GCC.                                                                             
                 */
                union {
                        u32 cmp;
                        char elfmag[SELFMAG];
                } magic;
                BUILD_BUG_ON(SELFMAG != sizeof word);
                magic.elfmag[EI_MAG0] = ELFMAG0;
                magic.elfmag[EI_MAG1] = ELFMAG1;
                magic.elfmag[EI_MAG2] = ELFMAG2;
                magic.elfmag[EI_MAG3] = ELFMAG3;
                /*                                                                                                                                
                 * Switch to the user "segment" for get_user(),                                                                                   
                 * then put back what elf_core_dump() had in place.                                                                               
                 */
                set_fs(USER_DS);
                if (unlikely(get_user(word, header)))
                        word = 0;
                set_fs(fs);
                if (word == magic.cmp)
                        return PAGE_SIZE;
        }

#undef  FILTER

        return 0;

実験

ELFヘッダありのcoreダンプとELFヘッダなしのcoreダンプを実際に取得して比較してみる。

準備

事前にcoreファイルを出力できるよう、resoure limitをなくしておく。
また、出力先もわかりやすくするため、core_patternも変更しておく。

$ ulimit -c unlimited
$ sudo su
# echo 'core.%p' > /proc/sys/kernel/core_pattern
# exit

ELFヘッダなし

coredump_filterで"(bit 4) ELF header pages in file-backed private memory areas"を落とした状態でcoreファイルを生成する。

$ echo 0x23 > /proc/self/coredump_filter
$ sleep 100 &
$ kill -SEGV $!
$ mv core.$! core.no_elf_header

ELFヘッダあり

今度は"(bit 4) ELF header pages in file-backed private memory areas"を立てた状態でcoreファイルを生成する。

$ echo 0x33 > /proc/self/coredump_filter
$ sleep 100 &
$ kill -SEGV $!
$ mv core.$! core.with_elf_header

比較

それぞれのcoreファイルのセクション情報を比較して、PIDの違いやオフセットの違いを除いたものが下記。
load1セクションがload1aload1bに、分かれていることがわかる。
同様にload6load11も分かれている。
load1はSizeが0だったのに対して、load1aは00001000(=PAGE_SIZE)となっている。
確かに追加でデータが保存されてそうだ。

$ objdump -h core.no_elf_header > sections.no_elf_header
$ objdump -h core.with_elf_header > sections.with_elf_header
$ diff -u sections.no_elf_header sections.with_elf_header
--- sections.no_elf_header  2019-03-30 11:11:08.051431648 +0900
+++ sections.with_elf_header    2019-03-30 11:11:28.923522648 +0900

 Sections:
 Idx Name          Size      VMA               LMA               File off  Algn

(中略)

- 12 load1         00000000  0000000000400000  0000000000000000  00002000  2**12
+ 12 load1a        00001000  0000000000400000  0000000000000000  00002000  2**12
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 13 load1b        00000000  0000000000401000  0000000000001000  00003000  2**12
                   ALLOC, READONLY, CODE

(中略)

- 17 load6         00000000  00007f136b94f000  0000000000000000  00025000  2**12
+ 18 load6a        00001000  00007fae7829d000  0000000000000000  00026000  2**12
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 19 load6b        00000000  00007fae7829e000  0000000000001000  00027000  2**12
                   ALLOC, READONLY, CODE

(中略)

- 22 load11        00000000  00007f136bd19000  0000000000000000  0002f000  2**12
+ 24 load11a       00001000  00007fae78667000  0000000000000000  00031000  2**12
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 25 load11b       00000000  00007fae78668000  0000000000001000  00032000  2**12
                   ALLOC, READONLY, CODE

追加された領域の中身を見てみる

追加されたセクションのオフセット、サイズはわかったので、中身を確認してみる。

load1aセクションを取り出し、readelfコマンドに食わせると、1ページ分しかないためか少しエラーが出たが、ちゃんとELFとして解釈し、BUILD_IDも取り出せている。
また、最初のテキスト領域ということで実行ファイルそのもの(今回はsleepコマンド)の先頭1ページと一致することも確認できた。

(本当はobjcopyコマンドでスマートに取り出したかったが、coreファイルだからかエラーになってしまったので、ddコマンドで取り出している。)

$ dd if=core.with_elf_header of=core.with_elf_header.load1a bs=4096 skip=2 count=1
$ readelf --notes core.with_elf_header.load1a
readelf: Error: Reading 0x740 bytes extends past end of file for section headers
readelf: Error: the dynamic segment offset + size exceeds the size of the file

Displaying notes found at file offset 0x00000254 with length 0x00000044:
  Owner                 Data size       Description
  GNU                  0x00000010       NT_GNU_ABI_TAG (ABI version tag)
    OS: Linux, ABI: 2.6.32
  GNU                  0x00000014       NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 5ff67ba1f7dc0370081f7f6aad5c173d1825c087


$ dd if=/bin/sleep of=sleep.head bs=4096 count=1
$ diff sleep.head core.with_elf_header.load1a

では、同様にELFヘッダが追加されたload6, load11は何者か?
gdbinfo sharelibraryを見てみるとload6aの直後に/lib/x86_64-linux-gnu/libc.so.6が、load11aの直後に/lib64/ld-linux-x86-64.so.2がロードされている。
これらのsharedlibrayもELFファイルなので、そのヘッダが保存されたのだろう。
ただ、ローダが書き換えているのか、ライブラリそのもののヘッダとは中身が異なっていた。
そのためこれらのELFヘッダがどういうときに役に立つのかはわからなかった。
(ご存知の方はぜひ教えてください。)

(gdb) target core core.with_elf_header
[New LWP 12138]
Core was generated by `sleep 100'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fae783692f0 in ?? ()
(gdb) info files
Local core dump file:
        `/home/kondo/work/190330_linux_kernel/core.with_elf_header', file type elf64-x86-64.
        0x0000000000400000 - 0x0000000000401000 is load1a
        0x0000000000401000 - 0x0000000000401000 is load1b
        0x0000000000606000 - 0x0000000000607000 is load2
        0x0000000000607000 - 0x0000000000608000 is load3
        0x0000000000ab4000 - 0x0000000000ad5000 is load4
        0x00007fae77ec8000 - 0x00007fae77ec8000 is load5
        0x00007fae7829d000 - 0x00007fae7829e000 is load6a
        0x00007fae7829e000 - 0x00007fae7829e000 is load6b
        0x00007fae7845d000 - 0x00007fae7845d000 is load7
        0x00007fae7865d000 - 0x00007fae78661000 is load8
        0x00007fae78661000 - 0x00007fae78663000 is load9
        0x00007fae78663000 - 0x00007fae78667000 is load10
        0x00007fae78667000 - 0x00007fae78668000 is load11a
        0x00007fae78668000 - 0x00007fae78668000 is load11b
        0x00007fae78869000 - 0x00007fae7886c000 is load12
        0x00007fae7888c000 - 0x00007fae7888d000 is load13
        0x00007fae7888d000 - 0x00007fae7888e000 is load14
        0x00007fae7888e000 - 0x00007fae7888f000 is load15
        0x00007fff0efcf000 - 0x00007fff0eff0000 is load16
        0x00007fff0eff7000 - 0x00007fff0effa000 is load17
        0x00007fff0effa000 - 0x00007fff0effc000 is load18
        0xffffffffff600000 - 0xffffffffff601000 is load19
Local exec file:
        <no file loaded>
(gdb) info sharedlibrary
From                To                  Syms Read   Shared Object Library
0x00007fae782bc8b0  0x00007fae7840fb04  No          /lib/x86_64-linux-gnu/libc.so.6
0x00007fae78667ac0  0x00007fae78685850  No          /lib64/ld-linux-x86-64.so.2

CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSの歴史

通常、coreファイル自体もELFフォーマットで出力されるので少し混乱するかも知れないが、この場合coreファイルの中にさらにELFヘッダがあることになる。
実際、このことにより6.7より古いgdbでは、ELFの解釈に失敗してしまったらしい。

そのことはCONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSの説明にも書かれている。

fs/Kconfig.binfmt
config CORE_DUMP_DEFAULT_ELF_HEADERS
        bool "Write ELF core dumps with partial segments"
        default y
        depends on BINFMT_ELF && ELF_CORE
        help
          ELF core dump files describe each memory mapping of the crashed
          process, and can contain or omit the memory contents of each one.
          The contents of an unmodified text mapping are omitted by default.

          For an unmodified text mapping of an ELF object, including just
          the first page of the file in a core dump makes it possible to
          identify the build ID bits in the file, without paying the i/o
          cost and disk space to dump all the text.  However, versions of
          GDB before 6.7 are confused by ELF core dump files in this format.

          The core dump behavior can be controlled per process using
          the /proc/PID/coredump_filter pseudo-file; this setting is
          inherited.  See Documentation/filesystems/proc.txt for details.

          This config option changes the default setting of coredump_filter
          seen at boot time.  If unsure, say Y.

実はこのgdbでただしく解釈できないという課題があったため、2008年の導入当初(v2.6.28)CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERSはデフォルト無効だった。

ただ、環境が追いついたこともあり、2010年デフォルト有効にするパッチが投稿され、v2.6.37でマージされたようだ。

ここからは推測だが、そのデフォルト無効時に作成されたdefconfigがそのままだったり参考にされたりして、結構無効になっているarchがある。
coreファイルのサイズも数ページ分しか増えないし、最悪ツールが対応していなかったとしてもELFから該当のセクションを取り除けばいいだけなので、特別な理由がない限り有効にしておきたい。

参考

proc (Linux Documentation)
default CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y (LKML)

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

Linuxで既存の単一ドライブを新しいドライブとミラーリングする

概要

はじめに

本稿では、Linux(筆者環境ではopenSUSE)環境にて既存HDD/SSDのデータを保ったまま新しいHDD/SSDとRAID1(ミラーリング)を行う際の方法を紹介します。
作成するRAIDアレイからブートする場合は追加の手順が必要になるのでご注意ください(末尾のURL参照)。
※必要に応じてバックアップを取った上で、自己責任で実行してください。

この記事での前提

  • 起動用SSD:/dev/nvme0n1
  • 既存のHDD:/dev/sda
    • 既存のパーティション:/dev/sda1
  • 新しいHDD:/dev/sdb
    • 中身は空(後に/dev/sdb1を作成)
  • 作成するRAIDアレイ:/dev/md0
    • /dev/sda1/dev/sdb1でRAID1

必要に応じて読み替えてください。

大まかな流れ

  1. /dev/sdb1だけで(ペアが存在しない状態で)、2台で構成されるRAID1アレイ(/dev/md0)を作る

  2. /dev/sda1の中身を/dev/md0にコピーする

  3. アレイに/dev/sda1を追加(して再構築)

本題

空のドライブにパーティションを作る

まず、空のドライブにパーティションを作成します。
lsblkコマンドで対象のドライブを確認しておくと安心です。

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0   2.7T  0 disk
└─sda1        8:1    0   2.7T  0 part /srv/samba
sdb           8:16   0   2.7T  0 disk
nvme0n1     259:0    0 119.2G  0 disk
├─nvme0n1p1 259:1    0   100G  0 part /
├─nvme0n1p2 259:2    0    10G  0 part [SWAP]
└─nvme0n1p3 259:3    0   9.3G  0 part /boot/efi

/dev/sdbが空のドライブなので、今回はここにパーティションを作成します。
今回はgdiskコマンドを用います。パーティションタイプがLinux RAID(FD00)になるようにしてください。

 # gdisk
GPT fdisk (gdisk) version 1.0.1

Type device filename, or press <Enter> to exit: /dev/sdb
Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): n
Partition number (1-128, default 1):
First sector (34-5860533134, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-5860533134, default = 5860533134) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): FD00
Changed type of partition to 'Linux RAID'

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/sdb.
The operation has completed successfully.

これで/dev/sdb上に/dev/sdb1が作成されます。

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0   2.7T  0 disk
└─sda1        8:1    0   2.7T  0 part /srv/samba
sdb           8:16   0   2.7T  0 disk
└─sdb1        8:17   0   2.7T  0 part
nvme0n1     259:0    0 119.2G  0 disk
├─nvme0n1p1 259:1    0   100G  0 part /
├─nvme0n1p2 259:2    0    10G  0 part [SWAP]
└─nvme0n1p3 259:3    0   9.3G  0 part /boot/efi

RAIDアレイの作成

先程作成した/dev/sdb1のみで2台を前提とするRAIDアレイを作成します。

# mdadm --create /dev/md0 --level=1 --raid-devices=2 missing /dev/sdb1

起動ドライブ(/bootのあるパーティション)に対して行う場合は…という趣旨のメッセージが表示されますが、今回は当てはまらないので無視します。

また、RAIDアレイが正常に作成されたことを確認するため/proc/mdstatの内容をチェックしておくと良いでしょう。

$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[1]
      2930133440 blocks super 1.2 [2/1] [_U]
      bitmap: 22/22 pages [88KB], 65536KB chunk

unused devices: <none>

作成した/dev/md0にファイルシステムを作成します。以下はext4での例です。

# mke2fs -t ext4 /dev/md0

既存のドライブの内容をコピーする

まず、/dev/md0をマウントします。今回は/mnt/md0にマウントします。

# mkdir /mnt/md0
# mount /dev/md0 /mnt/md0

次に、rsyncコマンドを用いて既存のドライブの内容をコピーします。
既存のドライブ(/dev/sda上のパーティション/dev/sda1)が/mnt/sda1にマウントされている場合は以下のようにします。

# rsync -aAXv /mnt/sda1 /mnt/md0

終わったら、それぞれをアンマウントします。

# umount /dev/md0 /dev/sda1

問題なくアンマウントできたら、新しいドライブのパーティションテーブルを既存のドライブにコピーして同じレイアウトになるようにします。

# sfdisk -d /dev/sdb | sfdisk /dev/sda
Checking that no-one is using this disk right now ... OK

Disk /dev/sda: 2.7 TiB, 3000592982016 bytes, 5860533168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: FB0EFFBE-DF23-4332-BF9E-4057533D2DB1

Old situation:

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 5860532223 5860530176  2.7T Microsoft basic data

>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Created a new GPT disklabel (GUID: 781FB817-61D9-4452-BE5C-3D176B1F5EB7).
/dev/sda1: Created a new partition 1 of type 'Linux RAID' and of size 2.7 TiB.
Partition #1 contains a ext4 signature.
/dev/sda2: Done.

New situation:
Disklabel type: gpt
Disk identifier: 781FB817-61D9-4452-BE5C-3D176B1F5EB7

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 5860533134 5860531087  2.7T Linux RAID

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

念の為、同じレイアウトになっているか確認しておくと良いでしょう。

SERVER-RYZEN3:/home/takuma327 # fdisk -l
(中略)

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 5860533134 5860531087  2.7T Linux RAID

(中略)

Device     Start        End    Sectors  Size Type
/dev/sdb1   2048 5860533134 5860531087  2.7T Linux RAID

(中略)

次に、RAIDアレイに既存のドライブを追加します。

# mdadm /dev/md0 -a /dev/sda1
mdadm: added /dev/sda1

/proc/mdstatの内容を確認して、再構築が行われていることを確認しましょう。

SERVER-RYZEN3:/home/takuma327 # cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sda1[2] sdb1[1]
      2930133440 blocks super 1.2 [2/1] [_U]
      [>....................]  recovery =  0.1% (3984384/2930133440) finish=342.7min speed=142299K/sec
      bitmap: 22/22 pages [88KB], 65536KB chunk

unused devices: <none>

必要に応じて/dev/md0をマウントすることでアクセスできるようになります。

参考URL

シングルドライブ環境を RAID に変換 - ArchWiki

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

Ansibleで対象ディレクトリ配下のファイルを一括操作するメモ

はじめに

この記事ではAnsibleを使って対象ディレクトリ配下の複数ファイルをまとめて操作する方法を紹介します。

実行環境

Ansible 2.7
クライアント側OS:Linux

概要

  1. findコマンドで対象ディレクトリ配下のファイル名一覧を取得。
  2. Ansibleのwith_linesに一覧を渡してファイル毎に操作。

サンプル

改行コードをCRLFからLFに一括変換してみます。

・クライアント側ディレクトリ構成

/home/user/sample
             |---aaa
             |    |---a.txt
             |    |---bbb
             |         |---b.txt
             |---ccc
                  |---c.txt

・Ansibleのロール

main.yml
- name: convert CRLF to LF
  replace:
    path: '{{ item }}'
    regexp: '\r'
  with_lines: find /home/user/sample/* -type f

・実行結果

TASK [main : replace] 
changed: [localhost] => (item=/home/user/sample/aaa/bbb/b.txt)
changed: [localhost] => (item=/home/user/sample/aaa/a.txt)
changed: [localhost] => (item=/home/user/sample/ccc/c.txt)

with_fileglob: /home/user/sample/* では再帰的に処理してくれないので注意。

参考

https://docs.ansible.com/ansible/latest/plugins/lookup/lines.html

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