全国招商加盟网免费,网站有源代码如何做seo,访问国外网站快的dns,网页设计作品下载一#xff0c;sysfs目录介绍
sysfs是一个基于内存的虚拟的文件系统#xff0c;有kernel提供#xff0c;挂载到/sys目录下#xff0c;负责以设备树的形式向user space提供直观的设备和驱动信息。
sysfs以不同的视角展示当前系统接入的设备#xff1a;
/sys/block 历史遗…一sysfs目录介绍
sysfs是一个基于内存的虚拟的文件系统有kernel提供挂载到/sys目录下负责以设备树的形式向user space提供直观的设备和驱动信息。
sysfs以不同的视角展示当前系统接入的设备
/sys/block 历史遗留问题存放块设备提供一设备名(如sda)到/sys/devices的符号链接
/sys/bus 按总线类型分类在某个总线目录之下可以找到链接该总线的设备的符号链接指向/sys/devices. 某个总线目录之下的drivers目录包含了该总线所需的所有驱动的符号链接。对应kernel中的struct bus_type
/sys/calss 按设备功能分类如输入设备在/sys/class/input之下图形设备在/sys/class/graphics之下是指向/sys/devices的符号链接。 对应kernel中的struct class
/sys/dev 按设备驱动程序分层(字符设备 块设备)提供以major:minor为名到/sys/devices的符号链接。 对应Kernel中的struct device_driver
/sys/devices 包含所有被发现的注册在各种总线上的各种物理设备。 所有物理设备都按其在总线上的拓扑结构来显示除了platform devices和system devices。 platform devices 一般是挂载在芯片内部高速或者低速总线上的各种控制器和外设能被CPU直接寻址。 system devices不是外设而是芯片内部的核心结构比如CPUtimer等。对应kernel中的strcut device
/sys/firmware 提供对固件的查询和操作接口(关于固件有专用于固件加载的一套api)
/sys/fs 描述当前加载的文件系统提供文件系统和文件系统已挂载的设备信息
/sys/kernel 提供kernel所有可调整参数但大多数可调整参数依然存放在sysctl(/proc/sys/kernel)
/sys/module 所有加载模块(包括内联、编译进kernel、外部的模块)信息按模块类型分类
/sys/power 电源选项可用于控制整个机器的电源状态如写入控制命令进行关机、重启等
sysfs支持多视角查看通过符号链接同样的信息可出现在多个目录下。
以硬盘sda为例既可以在块设备目录/sys/block下找到又可以在/sys/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/下找到。
二sysfs与kobject的关系
sysfs的信息来源是kobject层次结构读一个sysfs文件就是动态的从kobject结构提取信息生成文件。
每一个Kobject都会对应sysfs中的一个目录。因此在将Kobject添加到Kernel时create_dir接口会调用sysfs文件系统的创建目录接口创建和Kobject对应的目录相关的代码如下
static int create_dir(struct kobject *kobj)
{const struct kobj_type *ktype get_ktype(kobj);const struct kobj_ns_type_operations *ops;int error;error sysfs_create_dir_ns(kobj, kobject_namespace(kobj)); //创建dirif (error)return error;error populate_dir(kobj); //使用default attributes填充dirif (error) {sysfs_remove_dir(kobj);return error;}if (ktype) {error sysfs_create_groups(kobj, ktype-default_groups); //使用default_groups填充dirif (error) {sysfs_remove_dir(kobj);return error;}}... ...
}/**
* sysfs_create_dir_ns - create a directory for an object with a namespace tag
* kobj: object were creating directory for
* ns: the namespace tag to use
*/
int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{struct kernfs_node *parent, *kn;kuid_t uid;kgid_t gid;if (WARN_ON(!kobj))return -EINVAL;if (kobj-parent)parent kobj-parent-sd;elseparent sysfs_root_kn;if (!parent)return -ENOENT;kobject_get_ownership(kobj, uid, gid);kn kernfs_create_dir_ns(parent, kobject_name(kobj),S_IRWXU | S_IRUGO | S_IXUGO, uid, gid,kobj, ns); //调用文件系统操作接口创建dirif (IS_ERR(kn)) {if (PTR_ERR(kn) -EEXIST)sysfs_warn_dup(parent, kobject_name(kobj));return PTR_ERR(kn);}kobj-sd kn;return 0;
}
三attribute
1attribute功能概述
所谓的attibute就是内核空间和用户空间进行信息交互的一种方法。例如某个driver定义了一个变量却希望用户空间程序可以修改该变量以控制driver的运行行为那么就可以将该变量以sysfs attribute的形式开放出来。
Linux内核中attribute分为普通的attribute和二进制attribute如下
msm_kernel\include\linux\sysfs.h
struct attribute {const char *name;umode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOCbool ignore_lockdep:1;struct lock_class_key *key;struct lock_class_key skey;
#endif
};struct bin_attribute {struct attribute attr;size_t size;void *private;ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,char *, loff_t, size_t);ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,char *, loff_t, size_t);int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,struct vm_area_struct *vma);
};
struct attribute为普通的attribute使用该attribute生成的sysfs文件只能用字符串的形式读写。而struct bin_attribute在struct attribute的基础上增加了read、write等函数因此它所生成的sysfs文件可以用任何方式读写。
2attribute文件创建
/sys/bus/i2c # cat /sys/bus/i2c/drivers_autoprobe
1
有这样一个sysfs node当bus register的时候drivers_autoprobe node会被创建出来用来表示 device和device driver是否自动执行probe的操作看一下这个attribute的创建过程。
2.1 /sys/bus/i2c/drivers_autoprobe sysfs node创建流程
bus_register(struct bus_type *bus) //msm_kernel\drivers\base\bus.c
struct subsys_private *priv;
priv-subsys.kobj.ktype bus_ktype; //bus_ktype
----add_probe_files(bus);
--------bus_create_file(bus, bus_attr_drivers_autoprobe);
------------sysfs_create_file(dev-kobj, attr-attr);
----------------sysfs_create_file_ns(kobj, attr, NULL);
--------------------sysfs_add_file_mode_ns(kobj-sd, attr, false, attr-mode, uid, gid, ns);
------------------------kn __kernfs_create_file(parent, attr-name, mode 0777, uid, gid, size, ops, (void *)attr, ns, key);
----------------------------kn-priv priv; //(void *)attr
----------------------------kernfs_add_one(kn);
--------------------------------kernfs_link_sibling(kn);
关键代码解析
int sysfs_add_file_mode_ns(struct kernfs_node *parent,const struct attribute *attr, bool is_bin,umode_t mode, kuid_t uid, kgid_t gid, const void *ns)
{struct lock_class_key *key NULL;const struct kernfs_ops *ops;struct kernfs_node *kn;loff_t size;if (!is_bin) {struct kobject *kobj parent-priv;const struct sysfs_ops *sysfs_ops kobj-ktype-sysfs_ops;/* every kobject with an attribute needs a ktype assigned *///如果从属的kobject就是attribute文件所在的目录没有ktype或者没有ktype-sysfs_ops指针是不允许它注册任何attribute的if (WARN(!sysfs_ops, KERN_ERRmissing sysfs attribute operations for kobject: %s\n,kobject_name(kobj)))return -EINVAL;if (sysfs_ops-show sysfs_ops-store) {if (mode SYSFS_PREALLOC)ops sysfs_prealloc_kfops_rw; //判断ktype-sysfs_ops中的操作函数确定kernfs_ops ops支持哪些操作只读/只写/读写elseops sysfs_file_kfops_rw;} else if (sysfs_ops-show) {if (mode SYSFS_PREALLOC)ops sysfs_prealloc_kfops_ro;elseops sysfs_file_kfops_ro;} else if (sysfs_ops-store) {if (mode SYSFS_PREALLOC)ops sysfs_prealloc_kfops_wo;elseops sysfs_file_kfops_wo;} elseops sysfs_file_kfops_empty;size PAGE_SIZE;} else {struct bin_attribute *battr (void *)attr;if (battr-mmap)ops sysfs_bin_kfops_mmap;else if (battr-read battr-write)ops sysfs_bin_kfops_rw;else if (battr-read)ops sysfs_bin_kfops_ro;else if (battr-write)ops sysfs_bin_kfops_wo;elseops sysfs_file_kfops_empty;size battr-size;}#ifdef CONFIG_DEBUG_LOCK_ALLOCif (!attr-ignore_lockdep)key attr-key ?: (struct lock_class_key *)attr-skey;
#endifkn __kernfs_create_file(parent, attr-name, mode 0777, uid, gid,size, ops, (void *)attr, ns, key);if (IS_ERR(kn)) {if (PTR_ERR(kn) -EEXIST)sysfs_warn_dup(parent, attr-name);return PTR_ERR(kn);}return 0;
}/**
* __kernfs_create_file - kernfs internal function to create a file
* parent: directory to create the file in
* name: name of the file
* mode: mode of the file
* uid: uid of the file
* gid: gid of the file
* size: size of the file
* ops: kernfs operations for the file
* priv: private data for the file
* ns: optional namespace tag of the file
* key: lockdep key for the files active_ref, %NULL to disable lockdep
*
* Returns the created node on success, ERR_PTR() value on error.
*/
struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,const char *name,umode_t mode, kuid_t uid, kgid_t gid,loff_t size,const struct kernfs_ops *ops,void *priv, const void *ns,struct lock_class_key *key)
{struct kernfs_node *kn;unsigned flags;int rc;flags KERNFS_FILE;kn kernfs_new_node(parent, name, (mode S_IALLUGO) | S_IFREG,uid, gid, flags);if (!kn)return ERR_PTR(-ENOMEM);kn-attr.ops ops; // kernfs_node ops操作函数初始化 #1kn-attr.size size;kn-ns ns;kn-priv priv; //kernfs_node私有数据赋值这里是struct attribute *attr,后续读写attribute的时候会用到#ifdef CONFIG_DEBUG_LOCK_ALLOCif (key) {lockdep_init_map(kn-dep_map, kn-active, key, 0);kn-flags | KERNFS_LOCKDEP;}
#endif/** kn-attr.ops is accesible only while holding active ref. We* need to know whether some ops are implemented outside active* ref. Cache their existence in flags.*/if (ops-seq_show)kn-flags | KERNFS_HAS_SEQ_SHOW;if (ops-mmap)kn-flags | KERNFS_HAS_MMAP;if (ops-release)kn-flags | KERNFS_HAS_RELEASE;rc kernfs_add_one(kn);if (rc) {kernfs_put(kn);return ERR_PTR(rc);}return kn;
}
2.2 bus_ktype
如果从属的kobject就是attribute文件所在的目录没有ktype或者没有ktype-sysfs_ops指针是不允许它注册任何attribute的。
drivers/base/bus.c
static struct kobj_type bus_ktype {.sysfs_ops bus_sysfs_ops,.release bus_release,
};static const struct sysfs_ops bus_sysfs_ops {.show bus_attr_show, // #2.store bus_attr_store,
};#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,char *buf)
{struct bus_attribute *bus_attr to_bus_attr(attr);struct subsys_private *subsys_priv to_subsys_private(kobj);ssize_t ret 0;if (bus_attr-show)ret bus_attr-show(subsys_priv-bus, buf); // #3return ret;
}static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,const char *buf, size_t count)
{struct bus_attribute *bus_attr to_bus_attr(attr);struct subsys_private *subsys_priv to_subsys_private(kobj);ssize_t ret 0;if (bus_attr-store)ret bus_attr-store(subsys_priv-bus, buf, count);return ret;
}2.3 bus_attribute
struct bus_attribute {struct attribute attr;ssize_t (*show)(struct bus_type *bus, char *buf);ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf)
{return sysfs_emit(buf, %d\n, bus-p-drivers_autoprobe);
}static ssize_t drivers_autoprobe_store(struct bus_type *bus,const char *buf, size_t count)
{if (buf[0] 0)bus-p-drivers_autoprobe 0;elsebus-p-drivers_autoprobe 1;return count;
}static BUS_ATTR_RW(drivers_autoprobe);
ATTR 宏展开
#define BUS_ATTR_RW(_name) \struct bus_attribute bus_attr_##_name __ATTR_RW(_name)
#define BUS_ATTR_RO(_name) \struct bus_attribute bus_attr_##_name __ATTR_RO(_name)
#define BUS_ATTR_WO(_name) \struct bus_attribute bus_attr_##_name __ATTR_WO(_name)#define __ATTR(_name, _mode, _show, _store) { \.attr {.name __stringify(_name), \.mode VERIFY_OCTAL_PERMISSIONS(_mode) }, \.show _show, \.store _store, \
}#define __ATTR_PREALLOC(_name, _mode, _show, _store) { \.attr {.name __stringify(_name), \.mode SYSFS_PREALLOC | VERIFY_OCTAL_PERMISSIONS(_mode) },\.show _show, \.store _store, \
}#define __ATTR_RO(_name) { \.attr { .name __stringify(_name), .mode 0444 }, \.show _name##_show, \
}#define __ATTR_RO_MODE(_name, _mode) { \.attr { .name __stringify(_name), \.mode VERIFY_OCTAL_PERMISSIONS(_mode) }, \.show _name##_show, \
}#define __ATTR_RW_MODE(_name, _mode) { \.attr { .name __stringify(_name), \.mode VERIFY_OCTAL_PERMISSIONS(_mode) }, \.show _name##_show, \.store _name##_store, \
}#define __ATTR_WO(_name) { \.attr { .name __stringify(_name), .mode 0200 }, \.store _name##_store, \
}#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)3应用程序read sysfs属性文件是如何调用到属性文件的show函数的
3.1 cat sysfs节点流程
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) //fs/read_write.c
----ksys_read(fd, buf, count);
--------vfs_read(f.file, buf, count, ppos);
------------.read_iter kernfs_fop_read_iter //fs/kernfs/file.c
----------------seq_read_iter(iocb, iter);
--------------------struct seq_file *m iocb-ki_filp-private_data;
--------------------p m-op-start(m, m-index);
--------------------m-op-show(m, p);
------------------------.show kernfs_seq_show
----------------------------of-kn-attr.ops-seq_show(sf, v);
--------------------------------.seq_show sysfs_kf_seq_show,
------------------------------------const struct sysfs_ops *ops sysfs_file_ops(of-kn);
----------------------------------------ops-show(kobj, of-kn-priv, buf);
--------------------------------------------.show bus_attr_show, //msm_kernel\drivers\base\bus.c
------------------------------------------------struct bus_attribute *bus_attr to_bus_attr(attr);
------------------------------------------------bus_attr-show(subsys_priv-bus, buf);
----------------------------------------------------drivers_autoprobe_show(struct bus_type *bus, char *buf)msm_kernel\fs\kernfs\file.c
const struct file_operations kernfs_file_fops {.read_iter kernfs_fop_read_iter,.write_iter kernfs_fop_write_iter,.llseek generic_file_llseek,.mmap kernfs_fop_mmap,.open kernfs_fop_open,.release kernfs_fop_release,.poll kernfs_fop_poll,.fsync noop_fsync,.splice_read generic_file_splice_read,.splice_write iter_file_splice_write,
};msm_kernel\fs\kernfs\file.c
static const struct seq_operations kernfs_seq_ops {.start kernfs_seq_start,.next kernfs_seq_next,.stop kernfs_seq_stop,.show kernfs_seq_show,
};msm_kernel\fs\sysfs\file.c
static const struct kernfs_ops sysfs_file_kfops_ro {.seq_show sysfs_kf_seq_show,
};
3.2 dump log
eg:
cat /sys/bus/i2c/drivers_autoprobe10-18 05:40:09.284 8993 8993 I Call trace:
10-18 05:40:09.284 8993 8993 I : dump_backtrace.cfi_jt0x0/0x8
10-18 05:40:09.284 8993 8993 I : dump_stack_lvl0xe4/0x180
10-18 05:40:09.284 8993 8993 I : drivers_autoprobe_show0x28/0x5c
10-18 05:40:09.285 8993 8993 I : bus_attr_show0x40/0x8c
10-18 05:40:09.285 8993 8993 I : sysfs_kf_seq_show0xbc/0x158
10-18 05:40:09.285 8993 8993 I : kernfs_seq_show0x54/0x9c
10-18 05:40:09.285 8993 8993 I : seq_read_iter0x174/0x698
10-18 05:40:09.285 8993 8993 I : kernfs_fop_read_iter0x70/0x2dc
10-18 05:40:09.285 8993 8993 I : vfs_read0x2ec/0x368
10-18 05:40:09.285 8993 8993 I : ksys_read0x7c/0xf0
10-18 05:40:09.285 8993 8993 I : __arm64_sys_read0x20/0x30
10-18 05:40:09.285 8993 8993 I : el0_svc_common0xd8/0x27c
10-18 05:40:09.285 8993 8993 I : el0_svc0x38/0x9c
10-18 05:40:09.285 8993 8993 I : el0_sync_handler0x8c/0xf0
10-18 05:40:09.285 8993 8993 I : el0_sync0x1b4/0x1c0
3.3 关键代码解析
1当user space read drivers_autoprobe节点的时候会触发系统调用
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{return ksys_read(fd, buf, count);
}
然后会由VFS转到 file_operations 的read操作。
2在kernfs_fop_open函数中initialize sequential file
static int kernfs_fop_open(struct inode *inode, struct file *file)
{struct kernfs_node *kn inode-i_private;struct kernfs_root *root kernfs_root(kn);const struct kernfs_ops *ops;struct kernfs_open_file *of;bool has_read, has_write, has_mmap;int error -EACCES;if (!kernfs_get_active(kn))return -ENODEV;ops kernfs_ops(kn);has_read ops-seq_show || ops-read || ops-mmap;has_write ops-write || ops-mmap;has_mmap ops-mmap;/* see the flag definition for details */if (root-flags KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK) {if ((file-f_mode FMODE_WRITE) (!(inode-i_mode S_IWUGO) || !has_write))goto err_out;if ((file-f_mode FMODE_READ) (!(inode-i_mode S_IRUGO) || !has_read))goto err_out;}... .../** Always instantiate seq_file even if read access doesnt use* seq_file or is not requested. This unifies private data access* and readable regular files are the vast majority anyway.*/if (ops-seq_show)error seq_open(file, kernfs_seq_ops); //initialize sequential file, sets file, associating it with a sequence described by opelseerror seq_open(file, NULL);if (error)goto err_free;of-seq_file file-private_data;of-seq_file-private of;/* seq_file clears PWRITE unconditionally, restore it if WRITE */if (file-f_mode FMODE_WRITE)file-f_mode | FMODE_PWRITE;... ...
}
3
static int kernfs_seq_show(struct seq_file *sf, void *v)
{struct kernfs_open_file *of sf-private;of-event atomic_read(of-kn-attr.open-event);return of-kn-attr.ops-seq_show(sf, v); //在attribute节点创建的过程中赋值上文#1的位置
}
4可供选择的kernfs_ops
static const struct kernfs_ops sysfs_file_kfops_empty {
};static const struct kernfs_ops sysfs_file_kfops_ro {.seq_show sysfs_kf_seq_show,
};static const struct kernfs_ops sysfs_file_kfops_wo {.write sysfs_kf_write,
};static const struct kernfs_ops sysfs_file_kfops_rw {.seq_show sysfs_kf_seq_show,.write sysfs_kf_write,
};static const struct kernfs_ops sysfs_prealloc_kfops_ro {.read sysfs_kf_read,.prealloc true,
};static const struct kernfs_ops sysfs_prealloc_kfops_wo {.write sysfs_kf_write,.prealloc true,
};static const struct kernfs_ops sysfs_prealloc_kfops_rw {.read sysfs_kf_read,.write sysfs_kf_write,.prealloc true,
};
5找到 sysfs_ops
static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
{struct kernfs_open_file *of sf-private;struct kobject *kobj of-kn-parent-priv;const struct sysfs_ops *ops sysfs_file_ops(of-kn);ssize_t count;char *buf;/* acquire buffer and ensure that its PAGE_SIZE and clear */count seq_get_buf(sf, buf);if (count PAGE_SIZE) {seq_commit(sf, -1);return 0;}memset(buf, 0, PAGE_SIZE);/** Invoke show(). Control may reach here via seq file lseek even* if ops-show() isnt implemented.*/if (ops-show) {count ops-show(kobj, of-kn-priv, buf); //上文#2处定义了show函数if (count 0)return count;}
kobj-ktype-sysfs_ops
/*
* Determine ktype-sysfs_ops for the given kernfs_node. This function
* must be called while holding an active reference.
*/
static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn)
{struct kobject *kobj kn-parent-priv;if (kn-flags KERNFS_LOCKDEP)lockdep_assert_held(kn);return kobj-ktype ? kobj-ktype-sysfs_ops : NULL;
}
6
终于在上文#3处调用到了drivers_autoprobe的show函数。
4bus_attribute/device_attribute/driver_attribute
所有需要使用attribute的模块都不会直接定义struct attribute变量而是通过一个自定义的数据结构该数据结构的一个成员是struct attribute类型的变量并提供show和store回调函数。然后在该模块ktype所对应的struct sysfs_ops变量中实现该本模块整体的show和store函数并在被调用时转接到自定义数据结构struct class_attribute中的show和store函数中。这样每个atrribute文件实际上对应到一个自定义数据结构变量中了。
4.1 bus_attribute
struct bus_attribute {struct attribute attr;ssize_t (*show)(struct bus_type *bus, char *buf);ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
4.2 device_attribute
/* interface for exporting device attributes */
struct device_attribute {struct attribute attr;ssize_t (*show)(struct device *dev, struct device_attribute *attr,char *buf);ssize_t (*store)(struct device *dev, struct device_attribute *attr,const char *buf, size_t count);
};//device_attribute 节点创建举例
static ssize_t map_seg7_show(struct device *dev,struct device_attribute *attr,char *buf)
{memcpy(buf, txx9_seg7map, sizeof(txx9_seg7map));return sizeof(txx9_seg7map);
}static ssize_t map_seg7_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t size)
{if (size ! sizeof(txx9_seg7map))return -EINVAL;memcpy(txx9_seg7map, buf, size);return size;
}
static DEVICE_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store);error device_create_file(tx_7segled_subsys.dev_root, dev_attr_map_seg7);
4.3 driver_attribute
/* sysfs interface for exporting driver attributes */
struct driver_attribute {struct attribute attr;ssize_t (*show)(struct device_driver *driver, char *buf);ssize_t (*store)(struct device_driver *driver, const char *buf,size_t count);
};//driver_attribute 节点创建举例
static ssize_t new_id_show(struct device_driver *driver, char *buf)
{struct usb_driver *usb_drv to_usb_driver(driver);return usb_show_dynids(usb_drv-dynids, buf);
}static ssize_t new_id_store(struct device_driver *driver,const char *buf, size_t count)
{struct usb_driver *usb_drv to_usb_driver(driver);return usb_store_new_id(usb_drv-dynids, usb_drv-id_table, driver, buf, count);
}
static DRIVER_ATTR_RW(new_id);error driver_create_file(usb_drv-drvwrap.driver,driver_attr_new_id); 参考链接
Linux kernel sysfs device_attribute节点的创建和读写分析_如何在kernel中读取节点-CSDN博客
Linux设备模型(4)_sysfs 文章转载自: http://www.morning.wzjhl.cn.gov.cn.wzjhl.cn http://www.morning.spsqr.cn.gov.cn.spsqr.cn http://www.morning.slysg.cn.gov.cn.slysg.cn http://www.morning.nqmwk.cn.gov.cn.nqmwk.cn http://www.morning.nrxsl.cn.gov.cn.nrxsl.cn http://www.morning.cflxx.cn.gov.cn.cflxx.cn http://www.morning.pqyms.cn.gov.cn.pqyms.cn http://www.morning.mtktn.cn.gov.cn.mtktn.cn http://www.morning.ssfq.cn.gov.cn.ssfq.cn http://www.morning.cwznh.cn.gov.cn.cwznh.cn http://www.morning.pjxw.cn.gov.cn.pjxw.cn http://www.morning.gchqy.cn.gov.cn.gchqy.cn http://www.morning.tsxg.cn.gov.cn.tsxg.cn http://www.morning.mumgou.com.gov.cn.mumgou.com http://www.morning.080203.cn.gov.cn.080203.cn http://www.morning.zcyxq.cn.gov.cn.zcyxq.cn http://www.morning.mfsxd.cn.gov.cn.mfsxd.cn http://www.morning.ywxln.cn.gov.cn.ywxln.cn http://www.morning.cnhgc.cn.gov.cn.cnhgc.cn http://www.morning.nsncq.cn.gov.cn.nsncq.cn http://www.morning.ylqrc.cn.gov.cn.ylqrc.cn http://www.morning.nkyc.cn.gov.cn.nkyc.cn http://www.morning.pqndg.cn.gov.cn.pqndg.cn http://www.morning.nrlsg.cn.gov.cn.nrlsg.cn http://www.morning.fhrt.cn.gov.cn.fhrt.cn http://www.morning.rbrhj.cn.gov.cn.rbrhj.cn http://www.morning.rdkqt.cn.gov.cn.rdkqt.cn http://www.morning.rymd.cn.gov.cn.rymd.cn http://www.morning.frsbf.cn.gov.cn.frsbf.cn http://www.morning.jwpcj.cn.gov.cn.jwpcj.cn http://www.morning.qjlnh.cn.gov.cn.qjlnh.cn http://www.morning.gyxwh.cn.gov.cn.gyxwh.cn http://www.morning.wsxly.cn.gov.cn.wsxly.cn http://www.morning.dyght.cn.gov.cn.dyght.cn http://www.morning.mzwfw.cn.gov.cn.mzwfw.cn http://www.morning.tsmcc.cn.gov.cn.tsmcc.cn http://www.morning.lxlfr.cn.gov.cn.lxlfr.cn http://www.morning.rfpxq.cn.gov.cn.rfpxq.cn http://www.morning.csgwd.cn.gov.cn.csgwd.cn http://www.morning.lpbrp.cn.gov.cn.lpbrp.cn http://www.morning.wbxtx.cn.gov.cn.wbxtx.cn http://www.morning.cwnqd.cn.gov.cn.cwnqd.cn http://www.morning.dhqzc.cn.gov.cn.dhqzc.cn http://www.morning.dpzcc.cn.gov.cn.dpzcc.cn http://www.morning.xdxpq.cn.gov.cn.xdxpq.cn http://www.morning.wprxm.cn.gov.cn.wprxm.cn http://www.morning.zlcsz.cn.gov.cn.zlcsz.cn http://www.morning.lxjxl.cn.gov.cn.lxjxl.cn http://www.morning.bqyb.cn.gov.cn.bqyb.cn http://www.morning.brld.cn.gov.cn.brld.cn http://www.morning.tbbxn.cn.gov.cn.tbbxn.cn http://www.morning.drfcj.cn.gov.cn.drfcj.cn http://www.morning.qgwpx.cn.gov.cn.qgwpx.cn http://www.morning.mttqp.cn.gov.cn.mttqp.cn http://www.morning.lxngn.cn.gov.cn.lxngn.cn http://www.morning.fdsbs.cn.gov.cn.fdsbs.cn http://www.morning.ztrht.cn.gov.cn.ztrht.cn http://www.morning.ftcrt.cn.gov.cn.ftcrt.cn http://www.morning.bfcrp.cn.gov.cn.bfcrp.cn http://www.morning.c7498.cn.gov.cn.c7498.cn http://www.morning.ykmtz.cn.gov.cn.ykmtz.cn http://www.morning.zfqr.cn.gov.cn.zfqr.cn http://www.morning.bxbnf.cn.gov.cn.bxbnf.cn http://www.morning.nlnmy.cn.gov.cn.nlnmy.cn http://www.morning.rmtmk.cn.gov.cn.rmtmk.cn http://www.morning.ygkq.cn.gov.cn.ygkq.cn http://www.morning.drzkk.cn.gov.cn.drzkk.cn http://www.morning.ggtkk.cn.gov.cn.ggtkk.cn http://www.morning.qsmdd.cn.gov.cn.qsmdd.cn http://www.morning.sjbpg.cn.gov.cn.sjbpg.cn http://www.morning.lfdmf.cn.gov.cn.lfdmf.cn http://www.morning.skbbt.cn.gov.cn.skbbt.cn http://www.morning.qtzqk.cn.gov.cn.qtzqk.cn http://www.morning.zlqyj.cn.gov.cn.zlqyj.cn http://www.morning.bbyqz.cn.gov.cn.bbyqz.cn http://www.morning.qlbmc.cn.gov.cn.qlbmc.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn http://www.morning.ygrkg.cn.gov.cn.ygrkg.cn http://www.morning.wsyq.cn.gov.cn.wsyq.cn http://www.morning.ghxzd.cn.gov.cn.ghxzd.cn