Pour les systèmes d'exploitation modernes, les systèmes de fichiers virtuels sont une fonctionnalité presque omniprésente. Il est donc inévitable de discuter du mécanisme de fonctionnement des systèmes d'exploitation modernes.
Ce que cet article utilise, c'est qu'il Linux 2.6.x.x
s'agit d'une version révolutionnaire. Qu'il s'agisse de la gestion de la mémoire, de la gestion des processus, de la gestion des fichiers ou de la gestion des périphériques, des changements révolutionnaires ont eu lieu. Il est donc nécessaire d'explorer avec cette version.
Présentation du système de fichiers virtuel
root@huawei linux-version # df [0]
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1967860 0 1967860 0% /dev
tmpfs 402568 1580 400988 1% /run
/dev/vda1 41020640 26749836 12157372 69% /
tmpfs 2012832 0 2012832 0% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
tmpfs 2012832 0 2012832 0% /sys/fs/cgroup
tmpfs 402564 40 402524 1% /run/user/122
tmpfs 402564 0 402564 0% /run/user/0
Comme mentionné ci-dessus, tmpfs
, est un système de fichiers virtuel basé sur la mémoire. Virtuel signifie que les fichiers du système de fichiers ne correspondent à aucun fichier sur le disque dur. (Il y a un dicton appelé système de fichiers logique)
Traditionnellement, les systèmes de fichiers sont utilisés pour le stockage persistant sur les périphériques blocs, mais les systèmes de fichiers peuvent également être utilisés pour organiser, fournir ou échanger des informations qui ne sont pas stockées sur le périphérique bloc et peuvent être générées dynamiquement par le noyau. (D'après cette phrase, proc
il semble que les systèmes de fichiers ordinaires ont une relation égale avec ceux-ci, appelons-les donc systèmes de fichiers logiques pour le moment)
Les plus courants tels que proc
, tmpfs
etsysfs
Ici, nous devons faire attention à la différence entre le système de fichiers logique et le système de fichiers, le système de fichiers sur disque et le système de fichiers en mémoire. Le
système de fichiers virtuel spécifique n'est qu'une couche intermédiaire, et il existe les types suivants :
proc
: Fournit une interface sécurisée pour la communication entre le système d'exploitation lui-même et les applicationsdevfs
: Utilisé avant le noyau 2.6devfs
pour fournir une méthode de type fichier pour gérer/dev
tous les périphériques situés dans un répertoiresysfs
:sysfs
Le système de fichiers organise les périphériques et les bus connectés au système dans un fichier hiérarchique. Les programmes de l'espace utilisateur peuvent également utiliser ces informations pour interagir avec le noyau, généralement en remplacementdevfs
.sysfs
Le système de fichiers est un reflet intuitif de l'arborescence réelle des périphériques sur le système actuel. Ilkobject
construit ces informations via des sous-systèmes. Lorsqu'un sous-systèmekobject
est créé, les fichiers et répertoires correspondants sont également créés.tmpfs
:Linux
Un système de fichiers unique, le point de montage standard est/dev/shm
et la taille par défaut est la moitié de la mémoire réelle.tmpfs
Vous pouvez utiliser la mémoire physique ouswap
l'espace d'échange. Il s'agit d'un système de fichiers virtuel courant pour organiser les fichiers. Avantages : Temporaire ; lecture et écriture rapides et rétrécissement dynamiqueSystèmes de fichiers spécifiques tels que :
minix
,ext3
,ext4
etc.
Système de fichiers disque : le système de fichiers est dans le disque et est plus lent.
Système de fichiers mémoire : le système de fichiers est dans la mémoire et est plus rapide.
Types de systèmes de fichiers : les systèmes de fichiers sur disque Disk-based Filesystem
, les systèmes de fichiers virtuels Virtual Filesystem
sont générés dans le noyau et constituent une méthode permettant aux applications utilisateur de communiquer avec les utilisateurs, et les systèmes de fichiers réseau Network Filesystem
sont un compromis entre les systèmes de fichiers sur disque et les systèmes de fichiers virtuels.
VFS
Il fournit non seulement des méthodes et des abstractions pour le système de fichiers, mais prend également en charge une vue unifiée des objets (ou fichiers) du système de fichiers.
inode
Les membres appartiennent aux catégories suivantes :
- Métadonnées décrivant l'état du fichier. Par exemple, les droits d'accès ou la date de dernière modification.
- Segment de données contenant le contenu réel du fichier
- Le numéro de l'inode où se trouvent les données de cette entrée de répertoire
- Le nom du fichier ou du répertoire
Voici le /usr/bin/emacs
processus de recherche
Tout est un fichier.
La plupart des fonctions exportées par le noyau et utilisées par les programmes utilisateur sontVFS
accessibles via l'interface de fichier définie. Voici quelques-uns des sous-systèmes du noyau qui utilisent les fichiers comme principaux moyens de communication : périphériques de caractères et de blocs, canaux entre les processus, sockets pour tous les protocoles réseau, terminaux pour les entrées et sorties interactives, etc.
VFS
Se compose de deux parties : fichiers et systèmes de fichiers
struct inode {
struct hlist_node i_hash;
struct list_head i_list; // 链接iNode
struct list_head i_sb_list;
struct list_head i_dentry;
unsigned long i_ino; // inode唯一编号
atomic_t i_count; // 引用技术
unsigned int i_nlink; // 硬链接总数
uid_t i_uid; // 用户ID
gid_t i_gid; // 组ID
dev_t i_rdev; // 表示设备特殊文件的专用指针
unsigned long i_version; //
loff_t i_size; // 文件大小
#ifdef __NEED_I_SIZE_ORDERED
seqcount_t i_size_seqcount;
#endif
struct timespec i_atime; // 最后访问的时间
struct timespec i_mtime; // 最后修改的时间
struct timespec i_ctime; // 最后修改iNode的时间
unsigned int i_blkbits;
blkcnt_t i_blocks; // 文件按块计算的长度
unsigned short i_bytes; // 文件按字节计算的长度
umode_t i_mode; // 文件类型
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
struct mutex i_mutex; // 互斥量
struct rw_semaphore i_alloc_sem;
const struct inode_operations *i_op; // inode操作数据结构
const struct file_operations *i_fop; /* inode默认操作结构 */
struct super_block *i_sb;
struct file_lock *i_flock;
struct address_space *i_mapping;
struct address_space i_data;
#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS];
#endif
struct list_head i_devices; // 利用该成员作为链表元素,使得块设备或字符设备可以维护一个inode的链表,每个inode表示一个设备文件,通过设备文件可以访问对应的设备
union {
struct pipe_inode_info *i_pipe; // 于实现管道的inode的相关信息
struct block_device *i_bdev; // 块设备
struct cdev *i_cdev; // 字符设备
};
int i_cindex;
__u32 i_generation;
#ifdef CONFIG_DNOTIFY
unsigned long i_dnotify_mask; /* Directory notify events */
struct dnotify_struct *i_dnotify; /* for directory notifications */
#endif
#ifdef CONFIG_INOTIFY
struct list_head inotify_watches; /* watches on this inode */
struct mutex inotify_mutex; /* protects the watches list */
#endif
unsigned long i_state;
unsigned long dirtied_when; /* jiffies of first dirtying */
unsigned int i_flags;
atomic_t i_writecount;
#ifdef CONFIG_SECURITY
void *i_security;
#endif
void *i_private; /* fs or device private pointer */
};
Pour iNode
les opérations, utilisez i_op
des membres pour spécifier
struct inode_operations {
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,int);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,int,dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char __user *,int);
void * (*follow_link) (struct dentry *, struct nameidata *);
void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
int (*permission) (struct inode *, int, struct nameidata *);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
void (*truncate_range)(struct inode *, loff_t, loff_t);
long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len);
};
Pour proc
un système de fichiers comme celui-ci, son objet de gestion est un processustask_struct
struct task_struct {
// ...
int link_count, total_link_count; // 文件系统信息 查找环形链表时防止无限循环
// ...
struct fs_struct *fs; // 文件系统信息
struct files_struct *files; // 打开文件系统
struct nsproxy *nsproxy; // 命名空间
// ...
};
files
Contient chaque descripteur de fichier du processus en cours
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
struct fdtable *fdt;
struct fdtable fdtab;
/*
* written part on a separate cache line in SMP
*/
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd; // 表示下一次打开新文件时使用的文件描述符
struct embedded_fd_set close_on_exec_init; // 位图
struct embedded_fd_set open_fds_init; // 位图
struct file * fd_array[NR_OPEN_DEFAULT];
};
struct embedded_fd_set {
unsigned long fds_bits[1];
};
Par défaut, le noyau permet à chaque processus d'ouvrir NR_OPEN_DEFAULT
des fichiers. Le nombre initial de fichiers pouvant être ouverts est de 32. Les systèmes 64 bits peuvent gérer 64 fichiers simultanément.
#define BITS_PER_LONG 32
#define NR_OPEN_DEFAULT BITS_PER_LONG
Et pour
struct fdtable {
unsigned int max_fds;
struct file ** fd; // 每个数组项指向一个file结构的实例,管理一个打开文件的所有信息
fd_set *close_on_exec; // 一个指向位域的指针,该位域保存了所有在exec系统调用时将要关闭的文件描述符的信息
fd_set *open_fds; //一个指向位域的指针,该位域管理着当前所有打开文件的描述符。
struct rcu_head rcu;
struct fdtable *next;
};
D'autres ne seront pas résumés pour l'instant
procédure
proc
Il s'agit d'un système de fichiers logique dont les informations ne peuvent pas être lues à partir des périphériques de bloc. Les informations correspondantes sont générées dynamiquement uniquement lorsque le contenu du fichier est lu.
En utilisant proc
le système de fichiers, vous pouvez obtenir des informations sur divers sous-systèmes du noyau (par exemple, l'utilisation de la mémoire, les périphériques connectés, etc.) et vous pouvez modifier le comportement du noyau sans recompiler le code source du noyau ni redémarrer le système.
À cela est associé le mécanisme de contrôle du système sysctl system control mechanism
. Généralement, le système de fichiers de données de processus procfs
est monté sur /proc
, dont l'abréviation est proc FS
, d'où son nom.
Bien que proc
la capacité du système de fichiers varie d'un système à l'autre, il contient toujours de nombreux répertoires, fichiers et liens profondément imbriqués. Mais ces informations peuvent être divisées dans les catégories suivantes : gestion de la mémoire, données caractéristiques des processus système, systèmes de fichiers, pilotes de périphériques, bus système, gestion de l'alimentation, paramètres de contrôle des terminaux et du système.
Les informations sur certains processus peuvent être consultées sous `/proc`
root@huawei 2194 # cat cmdline
/usr/libexec/at-spi-bus-launcher#
root@huawei 2194 # pwd
/proc/2194
Informations générales sur le système
root@huawei /proc # cat stat [0]
cpu 12211193 7303 2174437 538380117 370471 0 21859 0 0 0
cpu0 6128342 3721 1085295 269120499 127141 0 7760 0 0 0
cpu1 6082850 3582 1089142 269259618 243329 0 14099 0 0 0
intr 1278733850 0 9 0 0 2566 0 3 0 0 0 277238 28 15 0 0 0 0 0 0 0 0 0 0 0 0 27 0 4839272 5689436 0 4780 5813 0 18799006 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 2490275942
btime 1663128233
processes 8110805
procs_running 1
procs_blocked 0
softirq 903628053 0 295168408 202239 20129044 18142070 0 22983 280585352 13555 289364402
Structure de données
proc
Chaque élément de données est représenté proc_dir_entry
par
struct proc_dir_entry {
unsigned int low_ino; // inode编号
unsigned short namelen; // 文件名的长度
const char *name; // 指向存储文件名的字符串的指针
mode_t mode; // 文件类型
nlink_t nlink; // 目录中子目录和符号链接的数目
uid_t uid; // 用户ID
gid_t gid; // 组ID
loff_t size; // 大小
const struct inode_operations *proc_iops; // 对iNode的操作
const struct file_operations *proc_fops; // 对文件的操作
get_info_t *get_info; // 相关子系统中返回所需数据的例程
struct module *owner; // 模块拥有者
struct proc_dir_entry *next, *parent, *subdir; // parent指向父目录的指针 subdir和next支持文件和目录的层次化布置
void *data; // 保存的数据
read_proc_t *read_proc; // 支持从/向内核读取/写入数据
write_proc_t *write_proc;
atomic_t count; /* 计数器 */
int pde_users; /* number of callers into module in progress */
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
struct completion *pde_unload_completion;
shadow_proc_t *shadow_proc;
};
Le noyau fournit une structure de données proc_inode
qui prend en charge inode
la visualisation proc
des éléments de données du système de fichiers de manière orientée objet.
union proc_op {
int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
int (*proc_read)(struct task_struct *task, char *page);
};
struct proc_inode {
// 该结构用来将特定于proc的数据与VFS层的inode数据关联起来
struct pid *pid;
int fd;
union proc_op op;
struct proc_dir_entry *pde; // 指针 指向关联的proc_dir_entry实例
struct inode vfs_inode; // 实际数据
};
En d'autres termes, avant que chaque instance de structure ne soit associée au proc
système de fichiers inode
, il y a des données supplémentaires en mémoire appartenant à l' proc_inode
instance correspondante, et sur la base de ces informations, un mécanisme inode
peut être obtenu.container_of
proc_inode
static inline struct proc_inode *PROC_I(const struct inode *inode)
{
return container_of(inode, struct proc_inode, vfs_inode);
}
Initialiser et charger
Monter proc
le système de fichiers
/proc
Le montage est presque identique à un système de fichiers non virtuel. La seule différence est de spécifier un mot-clé approprié (généralement proc
ou none
) comme source de données au lieu d'utiliser un fichier de périphérique.
Informations relatives au processus
La sortie d'informations liées aux processus système est proc
l'une des tâches principales de la conception originale du système de fichiers.
Informations de contrôle du système
Le comportement du noyau peut être modifié au moment de l'exécution via les contrôles système. Les paramètres de contrôle sont transférés de l'espace utilisateur vers le noyau sans redémarrer la machine. La manière traditionnelle de manipuler le comportement du noyau consiste à sysctl
appeler le système.
Système de fichiers Union UnionFS
Linux 3.18
Fonctionnalités du noyau ajoutées pour prendre en charge la technologie des conteneurs du noyau.
UnionFS
Il existe de nombreux systèmes de fichiers Docker
Union actuellement pris en charge, notamment OverlayFS
, AUFS
, Btrfs
, et . VFS
ZFS
Device Mapper
Technologie de montage Union
Dans des circonstances normales, si le contenu est monté sur un point de montage via un certain système de fichiers, le contenu d'origine dans le répertoire du point de montage sera masqué. Union Mount
Au lieu de Consolidez le contenu téléchargé et fournissez une vue unifiée du système de fichiers du contenu fusionné merge
.
Technologie de copie sur écriture COW
COW
Cela signifie qu'il n'écrase jamais le contenu du système de fichiers existant et COW
fusionne les deux systèmes de fichiers via le système de fichiers. Le point de vue de l'utilisateur final est le système de fichiers fusionné contenant tout le contenu (il Linux
peut être distingué du point de vue du noyau, c'est-à-dire , le lower
système de fichiers de l'utilisateur (le contenu dispose d'autorisations de lecture et upper
le contenu du système de fichiers dispose d'autorisations de lecture et d'écriture)
Le contenu expérimental est extrait de : Deep Learning of Docker – Joint File System OverlayFS
# 创建四个文件夹
mkdir upper lower merged work
# 存放内容
echo "I'm from lower!" > lower/in_lower.txt
echo "I'm from upper!" > upper/in_upper.txt
echo "In both. I'm from lower!" > lower/in_both.txt
echo "In both. I'm from upper!" > upper/in_both.txt
# 建立UnionFS
sudo mount -t overlay overlay \
-o lowerdir=./lower, upperdir=./upper,workdir=./work \
./merged
sysfs
sysfs
Il s'agit d'un système de fichiers qui exporte les objets du noyau vers l'espace utilisateur. Il offre non seulement la possibilité de visualiser la structure de données interne du noyau, mais fournit également une représentation de la topologie matérielle du système car tous les périphériques et bus du système sont organisés kobject
via .sysfs
struct kobject
Structure de données
kobject
Contenu dans une organisation hiérarchique. La chose la plus importante est qu'ils peuvent avoir un objet parent et être contenus dans un seul objetkset
. Ceci détermine oùkobject
il apparaît danssysfs
la hiérarchie : si un objet parent existe, une nouvelle entrée est créée dans le répertoire correspondant à l'objet parent. Sinon, placez-le dans le répertoire correspondantkobject
auquel ilkset
appartient.kobject
- Chaque
kobject
entréesysfs
est représentée comme un répertoire. Les fichiers qui apparaissent dans ce répertoire sont des propriétés de l'objet. Les opérations d'exportation et de définition des propriétés sont assurées par le sous-système auquel appartient l'objet - Les bus, périphériques, pilotes et classes sont
kobject
les principaux objets du noyau qui utilisent le mécanisme et représentent doncsysfs
presque tous les éléments de données dans
Chacun sysfs_dirent
représente un sysfs
nœud
struct sysfs_dirent {
atomic_t s_count; // 引用计数
atomic_t s_active; // 活动
struct sysfs_dirent *s_parent; // 父节点
struct sysfs_dirent *s_sibling; // 子节点
const char *s_name; // 文件、目录或符号链接的名称
union {
struct sysfs_elem_dir s_dir;
struct sysfs_elem_symlink s_symlink;
struct sysfs_elem_attr s_attr;
struct sysfs_elem_bin_attr s_bin_attr;
};
unsigned int s_flags; // 设置sysfs数据项的类型
ino_t s_ino;
umode_t s_mode;
struct iattr *s_iattr;
};
objet noyau
C
Il existe de nombreux endroits dans le noyau où les instances de structures du langage doivent être suivies . Bien que l'utilisation de ces objets soit très différente, certaines opérations, telles que le comptage de références, sont très similaires dans les différents sous-systèmes. Cela a entraîné une duplication de code. Comme il s'agissait d'un problème grave, lors du développement de la version 2.5 du noyau, le noyau a adopté une approche générique pour gérer les objets du noyau.
Le mécanisme général des objets du noyau peut être utilisé pour effectuer les opérations sur les objets suivantes :
- nombre de références ;
- Liste chaînée d'objets de gestion (collection) ;
- Serrure de collecte ;
- Exportez les propriétés de l'objet vers l'espace utilisateur (via
sysfs
le système de fichiers).
struct kobject {
const char * k_name; // 对象的文本名称
struct kref kref; // struct kref 简化引用计数的管理
struct list_head entry; // 链表元素
struct kobject * parent; // 指向父对象的指针
struct kset * kset; // kset
struct kobj_type * ktype; // 其他信息
struct sysfs_dirent * sd;
wait_queue_head_t poll;
};
Comptage de références
struct kref {
atomic_t refcount;
};
void kref_init(struct kref *kref);
void kref_get(struct kref *kref);
int kref_put(struct kref *kref, void (*release) (struct kref *kref));
Collections d'objets : dans de nombreux cas, différents objets du noyau doivent être regroupés en collections, par exemple, la collection All Character Devices ou la PCI
collection All Based Devices .
struct kset {
struct kobj_type *ktype; // kset中各个内核对象公用的kobj_type结构
struct list_head list; // 所有属于当前集合的内核对象的链表
spinlock_t list_lock;
struct kobject kobj;
struct kset_uevent_ops *uevent_ops; // 若干函数指针,用于将集合的状态信息传递给用户层
};
extern void kset_init(struct kset * k);
extern int __must_check kset_add(struct kset * k);
extern int __must_check kset_register(struct kset * k);
extern void kset_unregister(struct kset * k);
La différence entre udev et devfs
Ce qui était utilisé avant le noyau 2.6, c'est devfs
que evfs
le montage dans /dev
un répertoire fournit une méthode semblable à un fichier pour gérer tous les périphériques situés dans le répertoire /dev. Nous savons que /dev
chaque fichier du répertoire correspond à un périphérique. Peu importe si le périphérique existe actuellement ou non, et ces fichiers spéciaux sont situés sur le système de fichiers racine. Nous avons déjà créé ces fichiers de périphérique lors de la création du système de fichiers, donc en exploitant ces fichiers spéciaux, nous pouvons établir la communication avec le noyau. Interaction.
Mais devfs
il y a aussi quelques inconvénients, comme
- Mappage de périphérique incertain, parfois le fichier de périphérique mappé par un périphérique peut être différent, par exemple, ma clé USB peut
sda
correspondresdb
; - Il n'y a pas assez de numéros d'appareils primaires/secondaires, ce qui deviendra évidemment un problème lorsqu'il y aura trop d'appareils ;
/dev
Il y a trop de fichiers dans le répertoire et ils ne peuvent pas représenter les périphériques réels du système actuel ;- La dénomination n’est pas assez flexible et ne peut être spécifiée arbitrairement
Par conséquent, précisément à cause des problèmes ci-dessus, le code source du site officiel d’udevudev
a vu le jour :
Après linux2.6
le noyau, un nouveau système de fichiers a été introduit sysfs
, qui est monté dans /sys
un répertoire. Comme devfs, il s'agit également d'un système de fichiers virtuel et est également utilisé pour gérer les périphériques système.
root@huawei /sys # df .
Filesystem 1K-blocks Used Available Use% Mounted on
sysfs 0 0 0 - /sys
Il organise les périphériques et les bus réellement connectés au système dans un fichier hiérarchique. Les programmes de l'espace utilisateur peuvent également utiliser ces informations pour interagir avec le noyau. Ce système de fichiers est un reflet intuitif de l'arborescence réelle des périphériques sur le système actuel.
Il kobject
établit ces informations via des sous-systèmes. Lorsqu'un kobject est créé, les fichiers et répertoires correspondants sont également créés, situés dans les /sys
répertoires correspondants ci-dessous. Puisque chaque appareil sysfs
a un répertoire correspondant unique, il peut ensuite être lu et écrit par l'espace utilisateur.
Les outils de l'espace utilisateur udev
utilisent sysfs
les informations fournies pour implémenter toutes les fonctions devfs.
udev
avantage:
-
Gestion dynamique : lorsqu'un périphérique est ajouté/supprimé,
udev
le processus démon écoute les informations provenant du noyauuevent
et les utilise pour ajouter ou supprimer/dev
des fichiers de périphérique. Par conséquent,udev
les fichiers de périphérique ne sont générés que pour les appareils connectés/dev/
sans générer une grande quantité de néant. Le fichier de périphérique. Lorsque le branchement à chaud se produit, les informations pertinentes sur les modifications du périphérique seront transmises au noyau/sys
(système de fichiers sysfs) et les informations serontudev
utiliséessysfs
pour gérer les nœuds de périphérique correspondants. -
Règles de dénomination personnalisées : via le fichier de règles,
udev
les/dev/
noms de périphériques du noyau sont définis pour tous les périphériques, tels que/dev/sda,/dev/hda,/dev /fd
(ce sont des noms de périphériques définis par la couche pilote) et ainsi de suite. Puisqu'iludev
s'exécute dans l'espace utilisateur,Linux
les utilisateurs peuvent définir leurs propres fichiers de règles et générer des fichiers de périphérique hautement identifiables, tels que/dev /boot_disk,/dev/root_disk,/dev/color_printer
etc. -
Définissez les autorisations de l'appareil et les propriétaires/groupes. Également dans le fichier de règles, vous pouvez définir vous-même les autorisations et les propriétaires/groupes liés aux appareils.
root@huawei tun # pwd
/sys/dev/char/10:1/subsystem/tun
root@huawei tun # ls
dev power subsystem uevent
root@huawei tun # cat dev
10:200
root@huawei tun # cat uevent
MAJOR=10 # 主设备号
MINOR=200 # 副设备号
DEVNAME=net/tun # 对应设备
Groupe C
Enfin, je voudrais mentionner ici qu'en Cgroup
consultant la liste des systèmes de fichiers, vous pouvez voir Cgroup
qu'il représente la moitié des systèmes de fichiers du noyau. Il semble fs
un peu déraisonnable d'en parler.
# ...
cgroup 0 0 0 - /sys/fs/cgroup/cpu,cpuacct
cgroup 0 0 0 - /sys/fs/cgroup/devices
cgroup 0 0 0 - /sys/fs/cgroup/blkio
cgroup 0 0 0 - /sys/fs/cgroup/freezer
cgroup 0 0 0 - /sys/fs/cgroup/memory
cgroup 0 0 0 - /sys/fs/cgroup/net_cls,net_prio
cgroup 0 0 0 - /sys/fs/cgroup/rdma
cgroup 0 0 0 - /sys/fs/cgroup/cpuset
cgroup 0 0 0 - /sys/fs/cgroup/perf_event
cgroup 0 0 0 - /sys/fs/cgroup/pids
cgroup 0 0 0 - /sys/fs/cgroup/hugetlb
# ...
Afficher Cgroup
la structure des données
struct cgroup {
unsigned long flags; // 标识当前cgroup的状态
atomic_t count; // 引用计数器,表示有多少个进程在使用这个cgroup
struct list_head sibling; // 所有的兄弟节点
struct list_head children; // 所有子节点
struct cgroup *parent; // 父节点
struct dentry *dentry; // cgroup是层级的一个目录,该字段用于描述该目录
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; // 提供给各个子系统存放其限制进程组使用资源的统计数据
struct cgroupfs_root *root; // 保存层级的一些数据
struct cgroup *top_cgroup; // 层级的根节点
struct list_head css_sets;
struct list_head release_list;
};
Chaque sous-système possède sa propre structure de statistiques de contrôle des ressources
struct cgroup_subsys_state {
struct cgroup *cgroup; // 指向了这个资源控制统计信息所属的 cgroup
atomic_t refcnt; // 引用计数器
unsigned long flags; // 标志位
};
struct mem_cgroup {
struct cgroup_subsys_state css;
struct res_counter res;
struct mem_cgroup_lru_info info;
int prev_priority;
struct mem_cgroup_stat stat;
};
La légende vient de : légende du système de diagramme de cgroup Puisqu'un processus peut être ajouté à différents processus en même temps (à condition que ceux-ci appartiennent à des niveaux différents) pour le contrôle des ressources, et que ceux-ci sont associés à différents sous-systèmes de contrôle des ressources. Par conséquent, une structure doit être utilisée pour collecter les statistiques de contrôle des ressources de ces sous-systèmes, afin que le processus puisse trouver rapidement les statistiques de contrôle des ressources du sous-système correspondant via le sous-système, et la structure est utilisée pour ce faire.
Cgroup
cgroup
cgroup
cgroup
ID
css_set
struct css_set {
struct kref ref; // 引用计数器,用于计算有多少个进程在使用
struct list_head list; // 用于连接所有 css_set
struct list_head tasks; // 由于可能存在多个进程同时受到相同的 cgroup 控制,所以用此字段把所有使用此 css_set 的进程连接起来
struct list_head cg_links;
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; //用于收集各种子系统的统计信息结构
};
CGroup
Chaque sous-système est exploité via cgroup_subsys
la structure, et chaque sous-système doit mettre en œuvre une telle structure.
struct cgroup_subsys {
struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
struct cgroup *cgrp);
void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
int (*can_attach)(struct cgroup_subsys *ss,
struct cgroup *cgrp, struct task_struct *tsk);
void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct cgroup *old_cgrp, struct task_struct *tsk);
void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
int (*populate)(struct cgroup_subsys *ss,
struct cgroup *cgrp);
void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
int subsys_id; // 表示了子系统的ID
int active; // 子系统是否被激活
int disabled; // 子系统是否被禁止
int early_init;
const char *name; // 子系统名称
struct cgroupfs_root *root; // 被附加到的层级挂载点
struct list_head sibling; // 用于连接被附加到同一个层级的所有子系统
void *private; // 私有数据
};
Le sous-système mémoire définit une structure mem_cgroup_subsys
appeléecgroup_subsys
struct cgroup_subsys mem_cgroup_subsys = {
.name = "memory",
.subsys_id = mem_cgroup_subsys_id,
.create = mem_cgroup_create,
.pre_destroy = mem_cgroup_pre_destroy,
.destroy = mem_cgroup_destroy,
.populate = mem_cgroup_populate,
.attach = mem_cgroup_move_task,
.early_init = 0,
};
De plus, Linux
le noyau définit également un cgroup_subsys
tableau de structures subsys
pour sauvegarder cgroup_subsys
les structures de tous les sous-systèmes.
static struct cgroup_subsys *subsys[]
#ifdef CONFIG_CPUSETS
SUBSYS(cpuset)
#endif
#ifdef CONFIG_CGROUP_DEBUG
SUBSYS(debug)
#endif
#ifdef CONFIG_CGROUP_NS
SUBSYS(ns)
#endif
#ifdef CONFIG_FAIR_CGROUP_SCHED
SUBSYS(cpu_cgroup)
#endif
#ifdef CONFIG_CGROUP_CPUACCT
SUBSYS(cpuacct)
#endif
limite de mémoire
root@huawei memory # ls
cgroup.clone_children memory.failcnt memory.kmem.slabinfo memory.kmem.usage_in_bytes memory.oom_control memory.usage_in_bytes tasks
cgroup.event_control memory.force_empty memory.kmem.tcp.failcnt memory.limit_in_bytes memory.pressure_level memory.use_hierarchy user.slice
cgroup.procs memory.kmem.failcnt memory.kmem.tcp.limit_in_bytes memory.max_usage_in_bytes memory.soft_limit_in_bytes notify_on_release
cgroup.sane_behavior memory.kmem.limit_in_bytes memory.kmem.tcp.max_usage_in_bytes memory.move_charge_at_immigrate memory.stat release_agent
docker memory.kmem.max_usage_in_bytes memory.kmem.tcp.usage_in_bytes memory.numa_stat memory.swappiness system.slice
root@huawei memory # pwd
/sys/fs/cgroup/memory
root@huawei memory # cat memory.limit_in_bytes # 限制使用的内存大小
9223372036854771712 # 9223372036854771712字节
root@huawei memory # head tasks # 限制使用的进程编号
1 2 3 4 6 9 10 112 13
Limite d'utilisation du processeur
root@huawei cpu # ls [0]
cgroup.clone_children cpuacct.stat cpuacct.usage_percpu cpuacct.usage_sys cpu.cfs_quota_us docker system.slice
cgroup.procs cpuacct.usage cpuacct.usage_percpu_sys cpuacct.usage_user cpu.shares notify_on_release tasks
cgroup.sane_behavior cpuacct.usage_all cpuacct.usage_percpu_user cpu.cfs_period_us cpu.stat release_agent user.slice
root@huawei cpu # cat cpuacct.stat
user 12278762
system 2208080
root@huawei cpu # cat cpuacct.usage
154089159888977
root@huawei cpu # cat cpu.stat
nr_periods 0
nr_throttled 0
throttled_time 0
root@huawei cpu # head tasks
1 2 3 4 6 9 10 11 12 13
Enfin, je voudrais signaler ici une difficulté
tty0
: l'alias du terminal virtuel actuel
tty1-ttyn
:tty1-6
c'est une console texte (terminal virtuel),tty7
c'estx-window
une console graphique. (Terminal graphique)
ttyS0
: Terminal série
console
: Terminal console (écran d'ordinateur)
pts
: Pseudo-terminal
Avec qui rivaliser ? Ma génération prend les devants !