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.
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
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.
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