首先我们来看一下,pool的信息在内存中的存在形式
在内存中,pool的信息是保存在spa_t结构体中的,这个结构体比较大(145行左右),这里我们给出其中容易理解的一部分。
-
struct spa {
-
char spa_name[MAXNAMELEN]; /* pool的名称 */
-
char *spa_comment; /* 对这个pool的说明 */
-
avl_node_t spa_avl; /* 在整个spa名空间中的节点 - 系统中可能有多个pool,这些pool通过AVL树来管理 */
-
nvlist_t *spa_config; /* 上一次同步的配置信息 */
-
nvlist_t *spa_config_syncing; /* 当前同步的配置信息 */
-
...
-
uint64_t spa_config_txg; /* 上一次配置改变对应的txg */
-
pool_state_t spa_state; /* 这个pool的状态 */
-
...
-
boolean_t spa_is_initializing; /* 当前是否正在打开pool */
-
metaslab_class_t *spa_normal_class; /* 普通数据对应的metaslab_class */
-
metaslab_class_t *spa_log_class; /* ZIL数据对应的metaslab_class,ZIL后面将会详细说明,这里可以将它理解位日志文件系统的日志 */
-
uint64_t spa_first_txg; /* spa_open()执行完毕之后的第一个txg */
-
...
-
list_t spa_state_dirty_list; /* 被置脏的设备列表 */
-
spa_aux_vdev_t spa_spares; /* 热备份设备 */
-
spa_aux_vdev_t spa_l2cache; /* L2ARC缓存设备 */
-
nvlist_t *spa_label_features; /* 读取pool时需要的Label信息 */
-
uint64_t spa_config_object; /* 保存pool配置信息的元数据所在的对象号 */
-
...
-
};
这个庞大的结构体中,保存在pool在运行时素需要的一切信息,包括pool名称,设备构成,错误日志,历史操作记录,pool的运行状态等等
Pool Config相关的操作
这部分相关的函数主要在spa_config.c文件中体现。
1. 加载
void spa_config_load();
这个函数在ZFS模块第一次被加载的时候调用。它的作用是将spa的配置文件读入SPA的名空间。
默认读取的配置文件是:/etc/zfs/zpool.cache
这个配置文件是序列化(姑且这么说吧)之后的nvlist存储的,将文件读取之后,反序列化暂时存放在内存中,然后便利文件中的所有nvlist元素,为每一nvlist创建一个spa_t实例,同时通过读出来的信息初始化对应的spa_t结构体。
需要注意的是,这里仅仅是加载了配置文件,并没有真正地导入pool。
2. 生成配置信息
nvlist_t * spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats);
根据pool的当前运行状态生成配置信息,也就是根据当前的spa_t结构体中的信息,生成congfig信息。
3. 更新配置信息
void spa_config_update(spa_t *spa, int what);
根据给定的spa_t信息,修改既存config信息,并将修改后的配置信息同步到磁盘上。
4. 同步配置信息
void spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent);
遍历config list链表中的所有config信息(不管是新的还是旧的),这样,如果cache文件被修改了,新的文件就会被添加到链表中。
对每个cache文件中的每个pool的配置信息进行遍历,将合适的配置信息添加到nvlist中。
将存储池的配置信息同步到磁盘的cache文件中(/etc/zfs/zpool.cache),这需要在配置信息写入到MOS(Meta Object Set,ZFS中所有数据以对象来管理,多个对象就构成了Object Set)之后才能执行。这两个过程之间存在空隙,也就是说,有可能发生这样一种情况:存储池的配置信息被写入MOS之后,发生宕机,导致cache文件中的配置是错误的。这将在导入的过程中来处理。
阅读(4537) | 评论(0) | 转发(0) |