fclose后断电引起的数据丢失问题
问题背景:
客户反馈,设备断电以后,重新启动,原有配置丢失变砖
问题分析:
变砖的直接原因是配置丢失,配置丢失的原因是启动后flash上的数据已经被破坏,读取失败;
进一步分析,主要是flash数据未完全写入导致;
为何先前发布的yaffs2文件系统没有问题?目前的ubi文件系统会存在问题?
分析app层对于flash数据的操作流程,主要是以下步骤:
fopen -> fwrite -> fsync -> fclose
然而,实际的应该是如下步骤:
fopen -> fwrite -> fflush -> fsync -> fclose
fopen是带有缓冲的io操作,fflush的调用,可以使c库缓冲中的数据刷新到os层,而fsync只是将os层数据同步到介质中;
因此再缺失fflush的情况下,只是fsync再fclose,立即断电,会导致刷新数据不全。
至于yaffs2文件系统为什么没有问题,内核方面给出解释是:yaffs2文件系统是不带缓冲的,fclose可以触发将缓冲中残留数据刷新到介质;
结合man手册的走读,有如下结论:
1. 如果需要再描述符关闭前,将数据同步刷新到介质,需要调用fync接口,尤其针对一些关键的数据(丢失会引起严重问题的数据);
2. fopen方式打开的,如果需要调用fsync,正确的调用顺序为:fopen -> fwrite -> fflush -> fsync -> fclose
3. open方式打开的,如果需要调用到fsync,正确的调用顺序为:open -> write -> fsync -> close
问题修复:
1. 写配置文件的接口中,fsync前用fflush,出临时版本
2. 检索工程中,所有fopen打开文件,调用fsync前,增加fflush的调用
3. 鉴于业务的特殊情况,检索工程中,所有fclose或者close前,没有调用fsync的接口,需要补充fsync的调用
以下是man手册上摘录相关接口的一些注意点:
close()调用的理解(来自https://linux.die.net/man/2/close):
Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota.
A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a file system to flush the buffers when the stream is closed. If you need to be sure that the data is physically stored use fsync(2). (It will depend on the disk hardware at this point.)
It is probably unwise to close file descriptors while they may be in use by system calls in other threads in the same process. Since a file descriptor may be reused, there are some obscure race conditions that may cause unintended side effects
有可能有些write的错误,是报在close调用的时候,close的返回值不判断可能会不知情的情况下,已经丢失了数据。尤其是在带有磁盘配额的NFS文件系统上;
close函数不保证数据写到介质上的,要保证刷新到介质,需要调用fsync进行刷新,再去看fsync的接口手册,对于自身带有缓冲的介质,fsync也是无法保证真正写入的。
fclose()调用的理解(来自man手册):
Note that fclose() only flushes the user space buffers provided by the C library. To ensure that the data is physically stored on disk the kernel buffers must be flushed too,
for example, with sync(2) or fsync(2).
fclose只刷新C库提供的用户空间buf,数据到物理介质的写入还需要sync或者fsync来保证;
fclose后断电引起的数据丢失问题的更多相关文章
- vue单页面应用刷新网页后vuex的state数据丢失问题以及beforeunload的兼容性
最近在用vue写h5项目,当使用window.location重定向页面或者刷新当前页面时, 发现当刷新网页后,保存在vuex实例store里的数据会丢失. 后来在网上查找大神的解决方案如下: exp ...
- 前端 vue单页面应用刷新网页后vuex的state数据丢失的解决方案(转载)
最近接手了一个项目,前端后端都要做,之前一直在做服务端的语言.框架和环境,前端啥都不会啊. 突然需要前端编程,两天速成了JS和VUE框架,可惜还是个半吊子.然后遇到了一个困扰了一整天的问题.一直调试都 ...
- vue单页面应用刷新网页后vuex的state数据丢失的解决方案
1. 产生原因其实很简单,因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值. 2. 解决思路一种是state里的数据全部是通过请求 ...
- vue单页面应用刷新网页后vuex的state数据丢失的解决办法
第一种方案 首先将数据保存在vuex的store中,同时将这些信息也保存在sessionStorage中.这里需要注意的是vuex中的变量是响应式的,而sessionStorage不是,当你改变vue ...
- php history.back返回后表单数据丢失的解决办法
js使用history.back返回表单数据丢失的主要原因就是使用了session_start();的原因,该函数会强制当前页面不被缓存.本文章向码农介绍php history.back返回后表单数据 ...
- MySQL Cluster 集群简介
简介 MySQL集群是一种在无共享架构(SNA,Share Nothing Architecture)系统里应用内存数据库集群的技术.这种无共享的架构可以使得系统使用低廉的硬件获取高的可扩展性. My ...
- C的文件操作2
[转] C语言文件操作 概述 所谓文件(file)一般指存储在外部介质上数据的集合,比如我们经常使用的mp3.mp4.txt.bmp.jpg.exe.rmvb等等.这些文件各有各的用途,我们通常将它 ...
- Solr -- 实时搜索
在solr中,实时搜索有3种方案 ①soft commit,这其实是近实时搜索,不能完全实时. ②RealTimeGet,这是实时,但只支持根据文档ID的查询. ③和第一种类似,只是触发softcom ...
- 【Linux】系统 之 RAID
本人从事DBA相关的工作,最近遇到了IO抖动伴随shread running抖动的情况,主机宕机重启后备库及下游解析binlog出现损坏的案例,向一些有经验的同事咨询学习,其中最大的嫌疑是:raid卡 ...
随机推荐
- Codeforces Round #347 (Div.2)_A. Complicated GCD
题目链接:http://codeforces.com/contest/664/problem/A A. Complicated GCD time limit per test 1 second mem ...
- IBM带库加磁带操作
1.查询要弹出磁带的信息 可查询media日志,冻结,可用等,详情可查 查看带库空闲槽位 vmcheckxxx -rt tld -rn 0(0为带库名) 磁带详细信息: bpmedialist -m ...
- npm包发布过程
在上一章节中,我封装了一个基于react的树状组件,后来想把它发布到npm上,下面主要介绍一下发布过程中遇到的问题: 1.去注册npm账号,注册地址(https://www.npmjs.com), 再 ...
- linux系统中 redis 保存数据的5种形式 linux后端模式启动 jedis无法通过IP地址和端口号访问如何修改linux防火墙
vim修改redis.conf配置文件(我的已经复制到虚拟机的/usr/local/redis/bin目录下)为daemonize yes, 以后端模式启动 ./redis-server redis. ...
- Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库
Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库 文档 https://phonycode.github.io/wuss-weapp 扫码体验 使用微信扫一扫体验小程序组 ...
- BZOJ1061: [Noi2008]志愿者招募(线性规划)
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 5725 Solved: 3437[Submit][Status][Discuss] Descript ...
- BAT及各大互联网公司2014前端笔试面试题
很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习前端基础更是大有裨益. 而更多的题目是我一路以来收集的,也有往年的,答案不确保一定正 ...
- Android和IOS网页不一致汇总
1.input type=text 内容输入框的不一致,ios会默认给输入框添加自己的样式,导致在横向的输入框长度精准控制的时候,ios的输入框一般都比android上要长一点,还有内部阴影 解决此问 ...
- linux 特殊命令(一)
1.ifconfig 网卡配置:ifconfig [网络设备] [参数] 1) up 启动指定网络设备/网卡. 2) down 关闭指定网络设备/网卡.该参数可以有效地阻止通过指定接口的IP信息流, ...
- C++指针之间的赋值与转换规则总结
C++指针之间的赋值与转换规则总结 Note:以下结论不适用于类的成员函数指针,关于类的成员函数指针会单独讨论. 一.任何类型的指针变量均可直接赋值给const void * 任何类型的非const指 ...