Système de fichiers virtuel (système de fichiers sans stockage persistant), en prenant proc et sysfs comme exemples

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

Drainage : principes de gestion de la mémoire des systèmes d'exploitation modernes : prendre Linux2.6.xx comme exemple

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, procil 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, tmpfsetsysfs

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 applications
  • devfs: Utilisé avant le noyau 2.6 devfspour fournir une méthode de type fichier pour gérer /devtous les périphériques situés dans un répertoire
  • sysfs: sysfsLe 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 remplacement devfs. sysfsLe système de fichiers est un reflet intuitif de l'arborescence réelle des périphériques sur le système actuel. Il kobjectconstruit ces informations via des sous-systèmes. Lorsqu'un sous-système kobjectest créé, les fichiers et répertoires correspondants sont également créés.
  • tmpfs: LinuxUn système de fichiers unique, le point de montage standard est /dev/shmet la taille par défaut est la moitié de la mémoire réelle. tmpfsVous pouvez utiliser la mémoire physique ou swapl'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 dynamique

Systèmes de fichiers spécifiques tels que : minix, ext3, ext4etc.
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 Filesystemsont 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 Filesystemsont un compromis entre les systèmes de fichiers sur disque et les systèmes de fichiers virtuels.

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

inodeLes 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/emacsprocessus de recherche
insérer la description de l'image ici

Tout est un fichier.
La plupart des fonctions exportées par le noyau et utilisées par les programmes utilisateur sont VFSaccessibles 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.

VFSSe 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 iNodeles opérations, utilisez i_opdes 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 procun 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;  // 命名空间
	// ...
};

filesContient 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_DEFAULTdes 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

procIl 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 procle 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 procfsest monté sur /proc, dont l'abréviation est proc FS, d'où son nom.

Bien que procla 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

procChaque élément de données est représenté proc_dir_entrypar

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_inodequi prend en charge inodela visualisation procdes é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 procsystème de fichiers inode, il y a des données supplémentaires en mémoire appartenant à l' proc_inodeinstance correspondante, et sur la base de ces informations, un mécanisme inodepeut être obtenu.container_ofproc_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 procle système de fichiers

/procLe 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 procou 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 procl'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 à sysctlappeler le système.

Système de fichiers Union UnionFS

Linux 3.18Fonctionnalités du noyau ajoutées pour prendre en charge la technologie des conteneurs du noyau.

UnionFSIl existe de nombreux systèmes de fichiers Docker Union actuellement pris en charge, notamment OverlayFS, AUFS, Btrfs, et . VFSZFS 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 MountAu 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

COWCela signifie qu'il n'écrase jamais le contenu du système de fichiers existant et COWfusionne 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 Linuxpeut être distingué du point de vue du noyau, c'est-à-dire , le lowersystème de fichiers de l'utilisateur (le contenu dispose d'autorisations de lecture et upperle 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

sysfsIl 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 kobjectvia .sysfs

struct kobjectStructure de données

  • kobjectContenu dans une organisation hiérarchique. La chose la plus importante est qu'ils peuvent avoir un objet parent et être contenus dans un seul objet kset. Ceci détermine où kobjectil apparaît dans sysfsla 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 correspondant kobjectauquel il ksetappartient.kobject
  • Chaque kobjectentrée sysfsest 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 kobjectles principaux objets du noyau qui utilisent le mécanisme et représentent donc sysfspresque tous les éléments de données dans

Chacun sysfs_dirent représente un sysfsnœ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

CIl 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 sysfsle 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 PCIcollection 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 devfsque evfsle montage dans /devun 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 /devchaque 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 devfsil 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 sdacorrespondresdb ;
  • 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 ;
  • /devIl 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.6le noyau, un nouveau système de fichiers a été introduit sysfs, qui est monté dans /sysun 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 /sysrépertoires correspondants ci-dessous. Puisque chaque appareil sysfsa un répertoire correspondant unique, il peut ensuite être lu et écrit par l'espace utilisateur.

Les outils de l'espace utilisateur udevutilisent sysfsles informations fournies pour implémenter toutes les fonctions devfs.

udevavantage:

  • Gestion dynamique : lorsqu'un périphérique est ajouté/supprimé, udevle processus démon écoute les informations provenant du noyau ueventet les utilise pour ajouter ou supprimer /devdes fichiers de périphérique. Par conséquent, udevles 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 seront udevutilisées sysfspour gérer les nœuds de périphérique correspondants.

  • Règles de dénomination personnalisées : via le fichier de règles, udevles/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'il udevs'exécute dans l'espace utilisateur, Linuxles 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_printeretc.

  • 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 Cgroupconsultant la liste des systèmes de fichiers, vous pouvez voir Cgroupqu'il représente la moitié des systèmes de fichiers du noyau. Il semble fsun 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 Cgroupla 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;
};

insérer la description de l'image ici
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.
insérer la description de l'image ici
Cgroup
insérer la description de l'image ici
cgroupcgroup cgroupIDcss_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_subsysappelé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, Linuxle noyau définit également un cgroup_subsystableau de structures subsyspour sauvegarder cgroup_subsysles 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-6c'est une console texte (terminal virtuel), tty7c'est x-windowune 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 !

Je suppose que tu aimes

Origine blog.csdn.net/qq_48322523/article/details/127343346
conseillé
Classement