每次出错的都是和posix相关
先把结论说了:

fn_ofd_w和fn_ofd_r的SAFE_FCNTL参数F_OFD_SETLKW

fn_posix_w和fn_posix_r的SAFE_FCNTL参数F_SETLKW

四个函数都用的flock64结构体

case F_SETLK:
case F_SETLKW:
err = get_compat_flock(&flock, compat_ptr(arg));
case F_SETLK64:
case F_SETLKW64:
case F_OFD_SETLK:
case F_OFD_SETLKW:
err = get_compat_flock64(&flock, compat_ptr(arg));

显然posix调用get_compat_flock,传入的却是flock64

The original Linux fcntl() system call was not designed to handle large file offsets (in the flock structure).

Consequently, an fcntl64() system call was added in Linux 2.4. The newer system call employs a different structure for file locking, flock64, and corresponding commands, F_GETLK64, F_SETLK64, and F_SETLKW64. However, these details can be ignored by applications using glibc, whose fcntl() wrapper function transparently employs the more recent system call where it is available.

措施:fn_posix_w和fn_posix_r的

struct flock64 lck = {
        .l_whence = SEEK_SET,
        .l_start  = pa->offset,
        .l_len    = pa->length,
        .l_pid    = 0,
    };

改为

struct flock lck = {
        .l_whence = SEEK_SET,
        .l_start  = pa->offset,
        .l_len    = pa->length,
        .l_pid    = 0,
    };

static int thread_cnt;
static int fail_flag = 0;
static volatile int loop_flag = 1;
static const int max_thread_cnt = 32;
static const char fname[] = "tst_ofd_posix_locks"; //文件名
static const long write_size = 4096;
static pthread_barrier_t barrier;

struct param {
    long offset;
    long length;
    long cnt;
};

thread_cnt = tst_ncpus_conf() * 3; //四核 4*3=12

if (tst_fill_file(fname, 1, write_size, thread_cnt + 1))

写4096 (4+1)次 写入fname 写入1
if (pthread_barrier_init(&barrier, NULL, thread_cnt*3) != 0)
初始化屏障结构函数,设计屏障等待的最大线程数目(4*3)

for (i = 0; i < thread_cnt; i++) {

p0[i].offset = i * write_size;
        p0[i].length = write_size;
        p0[i].cnt = i + 2;

p1[i].offset = i * write_size + write_size / 4;
        p1[i].length = write_size;
        p1[i].cnt = i + 2;

p2[i].offset = i * write_size + write_size / 2;
        p2[i].length = write_size;
        p2[i].cnt = i + 2;
    }
P0[0]={0,4096,2}
P1[0]={1024,4096,2}
P2[0]={2048,4096,2}

P0[1]={4096,4096,3}
P1[1]={5120,4096,3}
P2[1]={6144,4096,3}

P0[2]={8192,4096,4}
P1[2]={9216,4096,4}
P2[2]={10240,4096,4}

P0[3]={12288,4096,5}
P1[3]={13312,4096,5}
P2[3]={14336,4096,5}

fail_flag = 0;
loop_flag = 1;

for (i = 0; i < thread_cnt; i++) {

SAFE_PTHREAD_CREATE(id0 + i, NULL, f0, (void *)&p0[i]);
    SAFE_PTHREAD_CREATE(id1 + i, NULL, f1, (void *)&p1[i]);
    SAFE_PTHREAD_CREATE(id2 + i, NULL, f2, (void *)&p2[i]);
}

static struct tcase {
    void *(*fn0)(void *);
    void *(*fn1)(void *);
    void *(*fn2)(void *);
    const char *desc;
} tcases[] = {
    {fn_ofd_r, fn_ofd_w, fn_dummy, "OFD read lock vs OFD write lock"},
    {fn_ofd_w, fn_posix_w, fn_dummy, "OFD write lock vs POSIX write lock"},
    {fn_ofd_r, fn_posix_w, fn_dummy, "OFD read lock vs POSIX write lock"},
    {fn_ofd_w, fn_posix_r, fn_dummy, "OFD write lock vs POSIX read lock"},
    {fn_ofd_w, fn_ofd_w, fn_dummy, "OFD write lock vs OFD write lock"},
    {fn_ofd_r, fn_ofd_w, fn_posix_w, "OFD r/w lock vs POSIX write lock"},
    {fn_ofd_r, fn_ofd_w, fn_posix_r, "OFD r/w lock vs POSIX read lock"},
};

offset length cnt
建立以下线程
fn_ofd_r p00 P0[0]={0,4096,2}
fn_ofd_w p10 P1[0]={1024,4096,2}
fn_dummy p20 P2[0]={2048,4096,2}

fn_ofd_r p01 P0[1]={4096,4096,3}
fn_ofd_w p11 P1[1]={5120,4096,3}
fn_dummy p21 P2[1]={6144,4096,3}

fn_ofd_r p02 P0[2]={8192,4096,4}
fn_ofd_w p12 P1[2]={9216,4096,4}
fn_dummy p22 P2[2]={10240,4096,4}

fn_ofd_r p03 P0[3]={12288,4096,5}
fn_ofd_w p13 P1[3]={13312,4096,5}
fn_dummy p23 P2[3]={14336,4096,5}

/* OFD read lock reading data*/
static void *fn_ofd_r(void *arg)
{
    struct param *pa = arg;
    //pa P0[0]={0,4096,2} offset length cnt
    unsigned char buf[pa->length];//4096
    int i;
    int fd = SAFE_OPEN(fname, O_RDWR);

struct flock64 lck = {
        .l_whence = SEEK_SET,
        .l_start  = pa->offset,
        .l_len    = pa->length,
        .l_pid    = 0,
    };

while (loop_flag) {

memset(buf, 0, pa->length);

lck.l_type = F_RDLCK;
        SAFE_FCNTL(fd, F_OFD_SETLKW, &lck);

/* rlock acquired */
        SAFE_LSEEK(fd, pa->offset, SEEK_SET);
        SAFE_READ(1, fd, buf, pa->length);

/* Verifying data read */
        for (i = 0; i < pa->length; i++) {
  //buf的值介于1-254之间
            if (buf[i] < 1 || buf[i] > 254) {

tst_res(TFAIL, "Unexpected data "
                    "offset %ld value %d",
                    pa->offset + i, buf[i]);
                fail_flag = 1;
                break;
            }
  //buf 1024字节之内的数值应该一致,除法取整
            int j = (i / (pa->length/4)) * pa->length/4;

if (buf[i] != buf[j]) {

tst_res(TFAIL, "Unexpected data "
                    "offset %ld value %d",
                    pa->offset + i, buf[i]);
                fail_flag = 1;
                break;
            }
        }

lck.l_type = F_UNLCK;
        SAFE_FCNTL(fd, F_OFD_SETLK, &lck);

sched_yield();
    }

pthread_barrier_wait(&barrier);
    SAFE_CLOSE(fd);
    return NULL;
}

/* OFD write lock writing data*/
static void *fn_ofd_w(void *arg)
{
    struct param *pa = arg;

 //pa P1[0]={1024,4096,2} offset length cnt
    unsigned char buf[pa->length];
    int fd = SAFE_OPEN(fname, O_RDWR);
    long wt = pa->cnt;

struct flock64 lck = {
        .l_whence = SEEK_SET,
        .l_start  = pa->offset,
        .l_len    = pa->length,
        .l_pid    = 0,
    };

while (loop_flag) {

memset(buf, wt, pa->length);

lck.l_type = F_WRLCK;
        SAFE_FCNTL(fd, F_OFD_SETLKW, &lck);

SAFE_LSEEK(fd, pa->offset, SEEK_SET);
        SAFE_WRITE(1, fd, buf, pa->length);

lck.l_type = F_UNLCK;
        SAFE_FCNTL(fd, F_OFD_SETLKW, &lck);

wt++;
        if (wt >= 255)
            wt = pa->cnt;

sched_yield();
    }

pthread_barrier_wait(&barrier);
    SAFE_CLOSE(fd);
    return NULL;
}

//啥也不干

static void *fn_dummy(void *arg)
{
    arg = NULL;

pthread_barrier_wait(&barrier);
    return arg;
}

ltp-fcntl36 偶尔出现fail unexpected data offset 20928 value 94的更多相关文章

  1. linux内核启动时报错ubi0 error: validate_ec_hdr: bad data offset 256, expected 128

    1.错误解析 ubi的EC header中有一个字段data_offset来记录数据偏移,数据偏移必须正确才能正确读取每一个物理擦除块中的数据 2.解决方法 擦除整块flash,然后再重新烧写包含ub ...

  2. [转贴]LTP--linux稳定性测试 linux性能测试 ltp压力测试 ---IBM 的 linux test project

    https://blog.csdn.net/melody157398/article/details/24354415   LTP--linux稳定性测试 linux性能测试 ltp压力测试 ---I ...

  3. LTP(LinuxTest Project)测试工具

    LTP(LinuxTest Project)是SGI.IBM.OSDL和Bull合作的项目,目的是为开源社区提供一个测试套件,用来验证Linux系统可靠性.健壮性和稳定性.LTP测试套件是测试Linu ...

  4. LTP--linux稳定性测试 linux性能测试 ltp压力测试 ---IBM 的 linux test project

    LTP--linux稳定性测试 linux性能测试 ltp压力测试 ---IBM 的 linux test project Peter盼 2014-04-23 11:25:49  20302  收藏  ...

  5. LTP--linux稳定性测试 linux性能测试 ltp压力测试 内核更新 稳定性测试

    LTP--linux稳定性测试 linux性能测试 ltp压力测试 zhangzj1030关注14人评论33721人阅读2011-12-09 12:07:45   说明:在写这篇文章之前,本人也不曾了 ...

  6. LTP--linux稳定性测试 linux性能测试 ltp压力测试 ltp-pan

    LTP--linux稳定性测试 linux性能测试 ltp压力测试 zhangzj1030关注14人评论33710人阅读2011-12-09 12:07:45   说明:在写这篇文章之前,本人也不曾了 ...

  7. LTP介绍

    1.LTP介绍    LTP--linut test project ,ltp套件是由Linux Test Project所开发的一套系统測试套件.它基于系统资源的利用率统计开发了一个測试的组合,为系 ...

  8. Offset Management For Apache Kafka With Apache Spark Streaming

    An ingest pattern that we commonly see being adopted at Cloudera customers is Apache Spark Streaming ...

  9. kafka使用getOffsetsBefore()获取获取offset异常分析

    根据时间戳获取kafka的topic的偏移量,结果获取的偏移量量数据组的长度为0,就会出现如下的数组下标越界的异常,实现的原理是使用了kafka的getOffsetsBefore()方法: Excep ...

随机推荐

  1. vue 刷新当前页面

    情景: 比如在删除或者增加一条记录的时候希望当前页面可以重新刷新 请求接口中直接将数组结果取第0个数组或者第n个数组给变量,会报错 0 的错误,此时多次刷新即可 方法一.这种方法简单快捷,但是页面会有 ...

  2. 高并发负载均衡——nginx与lvs

    一.企业级web项目架构 一.企业级web项目架构图 二.架构分析 客户端通过企业防火墙发送请求 在App服务器如tomcat接收客户端请求前,面对高并发大数据量访问的企业架构,会通过加入负载均衡主备 ...

  3. sync修饰符的简易说明

    其实这个就说的很好了. sync会自动更新父组件的数据 原本valuechild 的值是222,父页面显示的222,把值传递给子组件 子组件也显示的222, 我点击子组件的按钮 把333传递给父组件, ...

  4. MyBatis SpringMVC映射配置注意

    applicationContext.xml中要配置 <!-- MyBatis 的 sqlSessionFactory --> <bean id="sqlSessionFa ...

  5. InstallShield12的安装破解方法

    InstallShield是一个非常专业的windows程序打包工具,利用它我们可以轻松方便地将我们开发的windows程序进行封装打包.下面呢我就以我自己的实际操作经历来给大家介绍一下如何安装和破解 ...

  6. 用Partimage创建或恢复分区备份

    1 Preliminary Note Partimage is part of the system rescue CD found on http://www.sysresccd.org which ...

  7. 使用Github进行代码管理

    准备: Github地址:https://github.com 注册Github帐号 一.新建仓库 进入如下界面: 到这里仓库就创建完成了. 二.安装Github-window-desktop 安装g ...

  8. 16.和input相关的知识点

    1.改变input里面placeholder颜色 <input class="pre_name" type="text" placeholder=&quo ...

  9. Windows server 2008 R2实现多用户远程连接 (转)

    经常使用远程桌面的朋友可能会注意到,Windows server 2008 R2中,远程桌面最多只允许两个人远程连接,第三个人就无法连接过去,但是生产环境中有一些服务器可能有许多人需要连接上去,而微软 ...

  10. sql2008升级到r2提示:检查当前是否正确配置了报表服务器、数据库服务器是否正在运行以及您是否有权访问

    sql2008升级到r2提示:检查当前是否正确配置了报表服务器.数据库服务器是否正在运行以及您是否有权访问 解决方法:把服务开启ok