[LINUX] Notes d'apprentissage pour le mappeur de périphériques

Qu'est-ce que le mappeur de périphériques

Consultez les liens ci-dessous pour découvrir ce qu'est le mappeur de périphériques http://lc.linux.or.jp/lc2009/slide/T-02-slide.pdf https://en.wikipedia.org/wiki/Device_mapper

Personnellement, je comprends que Filesystem avait besoin de couper et de fournir des fonctionnalités qui devraient être intégrées dans Filesystem, comme ZFS, sous Linux, qui est plus diversifié que les autres Unix.

Construisons une cible de mappeur de périphérique errante

J'ai commencé par choisir un simple code cible de mappeur de périphériques, en le construisant et en l'utilisant.

L'environnement est le suivant CentOS Linux release 7.7.1908 (Core)  Une machine virtuelle sur une VirtualBox construite avec Vagrant. clone git https://github.com/huwan/dm-target

$ git clone https://github.com/huwan/dm-target.git

Allez dans le dossier cloné

$ make 
make -C /lib/modules/3.10.0-957.12.2.el7.x86_64/build M=/home/vagrant/dm-target modules
make[1]:annuaire`/usr/src/kernels/3.10.0-957.12.2.el7.x86_64'Entrer
  CC [M]  /home/vagrant/dm-target/mapper.o
(Omission)
include/linux/device-mapper.h:160:5:Remarques: expected ‘struct dm_dev **’ but argument is of type ‘sector_t’
 int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
     ^
/home/vagrant/dm-target/mapper.c:85:13:Erreur:Fonction «dm_get_Trop d'arguments pour l'appareil »
             dm_table_get_mode(target->table), &mdt->dev)) {
             ^
In file included from /home/vagrant/dm-target/mapper.c:15:0:
include/linux/device-mapper.h:160:5:Remarques:Déclaré ici
 int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
     ^
(Omis)

Avec ce sentiment, le problème est qu'une erreur se produit sur la ligne 85 et que la construction ne passe pas. La partie applicable est

 84    if (dm_get_device(target, argv[0], start, target->len,
 85                      dm_table_get_mode(target->table), &mdt->dev)) {
 86        target->error = "Device lookup failed";
 87        goto out;
 88    }

dm_get_device est appelé dans l'instruction if, mais je suis en colère quand il y a trop d'arguments.

Vérifiez device-mapper.h. (Est-il plus facile de voir le code en ligne?)

Tout d'abord, vérifiez la version du noyau

$ uname -a 
Linux localhost.localdomain 3.10.0-957.12.2.el7.x86_64 #1 SMP Tue May 14 21:24:32 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Rechercher device-mapper.h

$ sudo find / -name  device-mapper.h
/usr/src/kernels/3.10.0-957.12.2.el7.x86_64/include/linux/device-mapper.h
/usr/src/kernels/3.10.0-1062.18.1.el7.x86_64/include/linux/device-mapper.h

Il semble qu'il se réfère à l'en-tête de 3.10.0-957. Vérifiez le contenu de l'en-tête

[device-mapper.h]

/*                                                                                                                                                                      
 * Constructors should call these functions to ensure destination devices                                                                                               
 * are opened/closed correctly.                                                                                                                                         
 */
int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
                  struct dm_dev **result);
void dm_put_device(struct dm_target *ti, struct dm_dev *d);

Le commentaire dit que c'est un constructeur. J'ai lu l'implémentation ci-dessous (c'est plus facile sur le net) https://elixir.bootlin.com/linux/v3.10.95/source/drivers/md/dm-table.c#L462

/*
 * Add a device to the list, or just increment the usage count if
 * it's already present.
 */
int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
		  struct dm_dev **result)

Apparemment, il ajoute un nouveau périphérique de bloc à la liste des périphériques de bloc cibles (et autorise les doublons ??). Eh bien, je ne sais pas. En cas d'échec, il renvoie autre chose que 0 et semble être dans l'instruction if de mapper.c.

La construction a échoué probablement parce que start et target-> len étaient des arguments supplémentaires lorsque dm_get_device a été appelé. Puisque start est un type long long et target-> len est un type sector_t, il n'est pas dans la déclaration de fonction. target est la structure dm_target, qui est déclarée dans device-mapper.h.

Modifier mapper.c

/*
 * Add a device to the list, or just increment the usage count if
 * it's already present.
 */
int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
		  struct dm_dev **result)

Refaire

$ make
make -C /lib/modules/3.10.0-957.12.2.el7.x86_64/build M=/home/vagrant/dm-target modules
 make [1]: Entrez le répertoire `/usr/src/kernels/3.10.0-957.12.2.el7.x86_64 '
  CC [M]  /home/vagrant/dm-target/mapper.o
 /home/vagrant/dm-target/mapper.c:122:5: AVERTISSEMENT: Initialisation à partir d'un type de pointeur incompatible [Activé par défaut]
     .map = hello_target_map,
     ^
 /home/vagrant/dm-target/mapper.c:122:5: AVERTISSEMENT: (proche de l’initialisation pour ‘hello_target.map’) [Activé par défaut]
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/vagrant/dm-target/mapper.mod.o
  LD [M]  /home/vagrant/dm-target/mapper.ko
 make [1]: Quitter le répertoire `/usr/src/kernels/3.10.0-957.12.2.el7.x86_64 '
$ ls
mapper.c#  Makefile  Module.symvers  README.md  mapper.c  mapper.ko  mapper.mod.c  mapper.mod.o  mapper.o  modules.order  run-dmtarget.sh

La construction a réussi.

Un script shell pour l'installation est inclus, alors essayez de l'utiliser.

$ sudo ./run-dmtarget.sh -s
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 0.1957 s, 686 MB/s
 /home/vagrant/dm-target/mapper.c:122:5: AVERTISSEMENT: Initialisation à partir d'un type de pointeur incompatible [Activé par défaut]
     .map = hello_target_map,
     ^
 /home/vagrant/dm-target/mapper.c:122:5: AVERTISSEMENT: (proche de l’initialisation pour ‘hello_target.map’) [Activé par défaut]
$ sudo dmsetup targets
 hello_target v1.0.0 <-ceci
striped          v1.6.0
linear           v1.3.0
error            v1.5.0
$ lsblk 
NAME               MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                  8:0    0   40G  0 disk 
└─sda1               8:1    0   40G  0 part /
loop0                7:0    0  128M  0 loop 
 └─my_device_mapper 253: 0 0 128M 0 dm <-c'est

Il serait utile pour les débutants d'avoir un script shell pour de telles expériences. En regardant le contenu, ...

dd if=/dev/zero of=/tmp/mydisk bs=1M count=128 # 128MB file                                                                                             
losetup /dev/loop0 /tmp/mydisk # losetup -f                                                                                                             
make -s
insmod ./mapper.ko
 echo <starting logical sector number> <logical size of device in terms of sector> <target name> <device path> <unsed paramter> | dmsetup create <mapper  name>                                                                                                                                                               
echo 0 262144 hello_target /dev/loop0 0 | dmsetup create my_device_mapper
  1. Créez un fichier image avec dd
  2. Créez un périphérique de bouclage (bien que je ne sache pas ce que c'est) et attribuez-le au fichier image / tmp / mydisk
  3. faire
  4. Installation du module (insmod)
  5. Créez my_device_mapper avec hello_target avec dmsetup

Ensuite, essayez un test d'écriture avec dd

sudo ./run-dmtarget.sh -d
16+0 records in
16+0 records out
16384 bytes (16 kB) copied, 0.0399802 s, 410 kB/s

Que fait le processus ici

dd if=/dev/urandom of=/dev/mapper/my_device_mapper  bs=1K count=16

Il semble que 16 Ko de données aléatoires soient en cours d'écriture.

Ensuite, essayez de formater le périphérique bloc créé avec ext4.

$ sudo ./run-dmtarget.sh -f 
copy.txt  lost+found  test.txt

Alors, qu'est ce que tu fais ici?

if [ ! -d /mnt/mapper ]
then
   mkdir -p /mnt/mapper
fi
modprobe ext4
mkfs.ext4 -q /dev/mapper/my_device_mapper
mount /dev/mapper/my_device_mapper /mnt/mapper
cd /mnt/mapper
touch test.txt
cp test.txt copy.txt
ls

Vérifiez s'il est monté

$ lsblk 
NAME               MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                  8:0    0   40G  0 disk 
└─sda1               8:1    0   40G  0 part /
loop0                7:0    0  128M  0 loop 
 └─ my_device_mapper 253: 0 0 128M 0 dm / mnt / mapper <-Monté sur / mnt / mapper
$ ls /mnt/mapper/
copy.txt  lost+found  test.txt
$ cd /mnt/mapper/
$ du -sh 
 du: impossible de lire le répertoire «./lost+found»: aucune autorisation
15K	.
$ sudo touch hoge
$ ls
copy.txt  hoge  lost+found  test.txt

Il peut être utilisé normalement comme un dossier de 16 Ko.

Essayez de lire le code de la cible du mappeur de périphériques

C'est une cible de mappage de périphériques très simple, donc c'est simple.

Les membres de l'instance hello_target de la structure target_type sont initialisés comme suit.

static struct target_type hello_target = {
    .name = "hello_target",
    .version = {1,0,0},
    .module = THIS_MODULE,
    .ctr = hello_target_ctr,
    .dtr = hello_target_dtr,
    .map = hello_target_map,
};

La définition de cette structure est déclarée dans device-mapper.h. Le pointeur de fonction pour gérer les E / S de bloc (bio) est affecté à la variable membre de mappage, et le constructeur et le destructeur sont affectés respectivement à ctr et dtr. c'est tout.

Les résultats de la lecture de code suivante seront ajoutés.

Recommended Posts

Notes d'apprentissage pour le mappeur de périphériques
Notes d'apprentissage Python
notes d'apprentissage python
Mémo d'apprentissage O'Reilly python3 Primer
go Apprentissage des langues notes diverses 1
Notes d'apprentissage sur l'analyse des données Python
Remarques sur la grammaire Python de l'apprentissage automatique PyQ
Notes d'apprentissage depuis le début de Python 1
Remarques sur l'exécution locale d'Azure Machine Learning
Notes personnelles et liens sur l'apprentissage automatique ① (Machine learning)
Notes d'apprentissage depuis le début de Python 2