FT2000+ qemu kvm 64C64G 通过频繁设置CPU online 状态导致虚拟机假死测试用例

news2025/2/22 3:08:40

宿主机配置

 

 

虚拟机配置文件

<domain type='kvm'>  //如果是Xen,则type=‘xen’
  
    
    <name>redflag1</name> //虚拟机名称,同一物理机唯一
  
    
    <uuid>44748c15-7c00-4817-8724-675a27c3f821</uuid>  //同一物理机唯一,可用uuidgen生成
  
    
    <memory>67108864</memory>
    <currentMemory>67108864</currentMemory>  //memory这两个值最好设成一样
  
    
    <vcpu>64</vcpu>
    <cpu mode="host-passthrough"/>
    <os>
        <type arch='aarch64' machine='virt'>hvm</type>
        <loader readonly='yes' type='pflash'>/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw</loader>
        <nvram template='/usr/share/edk2/aarch64/vars-template-pflash.raw'>/usr/share/edk2/aarch64/QEMU_VARS.fd</nvram>
    </os>
    <features>
        <acpi/>
        <apic/>
        <pae/>
    </features>
    <clock offset='localtime'/>  //虚拟机时钟设置,这里表示本地本机时间
  
    
    <on_poweroff>destroy</on_poweroff>  //突发事件动作
  
    
    <on_reboot>restart</on_reboot>
    <on_crash>restart</on_crash>
    <devices>   //设备配置
        
        <emulator>/usr/bin/qemu-kvm</emulator> //如果是Xen则是/usr/lib/xen/binqemu-dm            

        <controller type="scsi" index="0" model="virtio-scsi"/>
        <controller type='usb' index='0' model='qemu-xhci' ports='15'/>
        <input type='keyboard' bus='usb'/>
        <input type='mouse' bus='usb'/>
        <input type='tablet' bus='usb'/>
        <disk type='file' device='cdrom'>//光盘
      
            
            <driver name='qemu' type='raw'/>
            <source file='/home/yeqiang/RedFlag-Asianux-Server-7.5-aarch64-for-Phytium-dvddisc-20210701.iso'/>
            <target dev='hda' bus='scsi'/>
            <readonly/>
        </disk>

        <disk type='file' device='disk'> //硬盘      
            
            <driver name='qemu' type='qcow2'/>
            <source file='/home/yeqiang/qemu-virtual-machine/redflag.qcow2'/>
            <target dev='vda' bus='virtio'/>
        </disk>
                <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0' keymap='en-us'>  //配置vnc,windows下可以使用vncviewer登录,获取vnc端口号:virsh vncdisplay vm0
     
            
            <listen type='address' address='0.0.0.0'/>
        </graphics>
        <interface type='bridge'>
          <source bridge='virbr0'/>
        </interface>

    </devices>
</domain>

测试程序

#include <errno.h>
#include <iostream>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

using namespace std;
std::string sub_cgroup_dir("/sys/fs/cgroup/cpu/test");

// common lib
bool is_dir(const std::string &path) {
  struct stat statbuf;
  if (stat(path.c_str(), &statbuf) == 0) {
    if (0 != S_ISDIR(statbuf.st_mode)) {
      return true;
    }
  }
  return false;
}

bool write_file(const std::string &file_path, int num) {
  // std::cout << file_path << " op:" << num << std::endl;
  FILE *fp = fopen(file_path.c_str(), "w");
  if (fp == NULL) {
    return false;
  }

  // std::cout << file_path << " op:" << num << std::endl;
  std::string write_data = to_string(num);
  fputs(write_data.c_str(), fp);
  fclose(fp);
  return true;
}

// ms
long get_ms_timestamp() {
  timeval tv;
  gettimeofday(&tv, NULL);
  return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}

// cgroup
bool create_cgroup() {
  if (is_dir(sub_cgroup_dir) == false) {
    if (mkdir(sub_cgroup_dir.c_str(), S_IRWXU | S_IRGRP) != 0) {
      cout << "mkdir cgroup dir fail" << endl;
      return false;
    }
  }

  int pid = getpid();
  cout << "pid is " << pid << endl;
  std::string procs_path = sub_cgroup_dir + "/cgroup.procs";
  return write_file(procs_path, pid);
}

bool set_period(int period) {
  std::string period_path = sub_cgroup_dir + "/cpu.cfs_period_us";
  return write_file(period_path, period);
}

bool set_quota(int quota) {
  std::string quota_path = sub_cgroup_dir + "/cpu.cfs_quota_us";
  return write_file(quota_path, quota);
}

bool set_cpuOnline(int cpuId, int online) {
  std::string cpuPath = std::string("/sys/devices/system/cpu/cpu") +
                        std::to_string(cpuId) + std::string("/online");
  return write_file(cpuPath, online);
}

// thread
// param: ms interval
void *thread_func(void *param) {
  int i = 0;
  int interval = (long)param;
  long last = get_ms_timestamp();

  while (true) {
    i++;
    if (i % 100000 != 0) {
      continue;
    }

    long current = get_ms_timestamp();
    if ((current - last) >= interval) {
      last = current;
    }
  }

  pthread_exit(NULL);
}

void test_thread() {
  const int k_thread_num = 320;
  pthread_t pthreads[k_thread_num];

  for (int i = 0; i < k_thread_num; i++) {
    if (pthread_create(&pthreads[i], NULL, thread_func, (void *)(i + 1)) != 0) {
      cout << "create thread fail" << endl;
    } else {
      cout << "create thread success,tid is " << pthreads[i] << endl;
    }
  }
}

void *thread_cpu_online_ctl(void *param) {
  int online, cpu;
  bool b;
  while (true) {
    online = rand() % 2;
    cpu = rand() % 64;
    b = set_cpuOnline(cpu, online);
    // std::cout << cpu << " -> " << online << "result:" << b << std::endl;
  }

  pthread_exit(NULL);
}

void cpu_ctl_thread() {
  const int k_thread_num = 64;
  pthread_t pthreads[k_thread_num];

  for (int i = 0; i < k_thread_num; i++) {
    if (pthread_create(&pthreads[i], NULL, thread_cpu_online_ctl,
                       (void *)(i + 1)) != 0) {
      cout << "create thread fail" << endl;
    } else {
      cout << "create thread success,tid is " << pthreads[i] << endl;
    }
  }
}

int main(int argc, char *argv[]) {

  int period = 100000;
  int quota = 4000000;
  cout << "period is " << period << endl;
  cout << "quota is " << quota << endl;
  srand(time(nullptr));

  test_thread();
  cpu_ctl_thread();
  if (create_cgroup() == false) {
    cout << "create cgroup fail" << endl;
    return -1;
  }

  set_period(period);
  set_quota(quota);

  while (true) {
    sleep(10000);
  }

  return 0;
}

编译

g++ -std=c++11 -lpthread tcti.cpp -o tcti

执行

./tcti &

vmstat监控

vmstat 1

一段时间后

此时,bash上敲击回车能换行,但是无信息输出

ctrl+C 可退出程序(又一次测试未退出,卡主了)

tcti进程 cpu 0%

kill -9 无法杀死

reboot,卡死

此时键盘输入有信息打印

卡死后,放置约14小时后,再次vnc登录,光标已不再闪烁,键盘输入也没有给出反馈,彻底死机。

此时在宿主机查看kvm进程CPU状态,几乎没有消耗

 

virsh 导出内核转储文件分析(64G内存,时间较长)

virsh dump --memory-only --format=kdump-zlib  redflag1 redflag1-coredump-0428-stucked.zlib

重启虚拟机,分析coredump

crash调试

 

 

bt -a

 ps

 

原本期望通过不断设置CPU在线状态,迫使CFS触发_nohz_idle_balance。实际上的故障与期望不一致,产生了新问题。

重新测试

刚开始测试时,100.0 id 数值明显不对,应该是操作CPU在线状态导致

约6分钟后,测试进程没有CPU消耗了

 

 STAT:SI 

S      //处于休眠状态;

l      //多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads); 

参考:Linux进程状态(ps stat)详解_smartvxworks的博客-CSDN博客

说明此时线程sleep后没有再被调度器分配CPU了 。

当前CPU online状态

gdb attach上去看看

挂不上去,且无法退出

正确指令应该是 gdb attach 2034(虽然敲错了指令,但日志已显示Attatching to process 2034)

在kvm外,导出coredump

virsh dump --memory-only --format=kdump-zlib  redflag1 redflag1-coredump-0428-stucked2.zlib

 

 

 

 从目前看,应该是触发了bug,当前任务被调度出去,一直没能调度回来。该进程程序本身没有什么问题。

查看几个子线程,连号

 都在这个位置

复测,待续。。。 

10分51秒后,tcti CPU占用率掉到了0%

尝试手动调整cgroup限制,新开ssh窗口登录上去,方便观察top信息

cat /dev/null > /sys/fs/cgroup/cpu/test/cgroup.procs 
cat /dev/null > /sys/fs/cgroup/cpu/test/tasks 

查看发现无法清空

 设置所有CPU online=1

 ls /sys/devices/system/cpu/ | grep cpu | grep -v freq | grep -v idle | xargs -i echo "echo 1 > /sys/devices/system/cpu/"{}"/online" | bash

卡死了。。。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图形界面GUI相关概念GLX/Wayland/X11/DRM/DRI

1. GUI图形界面是什么 GUI是graphical user interface的缩写&#xff0c;图形用户接口&#xff0c;实现了基本的WIMP&#xff08;windows&#xff0c;icons&#xff0c;menus&#xff0c;pointer&#xff09;。一个GUI的基本组成&#xff1a;display server实现windowing syst…

传统制造企业如何数字化转型?中国减速机Top 1企业给出这份答案

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 数字中国建设正在如火如荼地展开&#xff0c;百业千行也都在寻求自身业务与数字化的深度融合。 2022年制造业增加值占GDP比重约为30%&#xff0c;在数字经济赋能新发展的当下&#xff0c;制造业成为数字技术重点实施落地的载…

2023/4/27总结

第一周任务 - Virtual Judge (vjudge.net) 1.这道题目穷举即可 最多90次 #include<stdio.h> int getLucky(int x) {int a[10],i,n,tx,max0,min10;for(i0;t;i){a[i]t%10;t/10;if(a[i]>max) maxa[i];if(a[i]<min) mina[i];}return max-min; } int slove(int l,int r…

Layui 2.8.1 正式发布,朴实归来

Layui 是一套开源免费的 Web UI 组件库&#xff0c;采用自身轻量级模块化规范&#xff0c;遵循原生态的 HTML/CSS/JavaScript 开发模式&#xff0c;极易上手&#xff0c;拿来即用。其风格简约轻盈&#xff0c;而内在雅致丰盈&#xff0c;甚至包括文档在内的每一处细节都经过精心…

docker部署harbor

Harbor介绍 以Docker为代表的容器技术的出现&#xff0c;改变了传统的交付方式。通过把业务及其依赖的环境打包进Docker镜像&#xff0c;解决了开发环境和生产环境的差异问题&#xff0c;提升了业务交付的效率。如何高效地管理和分发Docker镜像&#xff1f;是众多企业需要考虑…

Shenll编程之循环语句与函数

循环语句 一、for循环二、continue跳出循环continue二次跳出循环 三、break终止循环 循环是一种控制流程的结构&#xff0c;用于重复执行一段代码 遍历是一种数据操作的过程&#xff0c;用于访问并处理数据构成中的每个元素 在某些情况下&#xff0c;循环和遍历可以结合使用&am…

c++标准模板(STL)(std::array)(二)

定义于头文件 <array> template< class T, std::size_t N > struct array;(C11 起) std::array 是封装固定大小数组的容器。 此容器是一个聚合类型&#xff0c;其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数…

苹果id密码忘记了怎么重新设置?请收好这份攻略!

案例&#xff1a;怎么重新设置apple ID密码&#xff1f; 【9敏&#xff01;想下载美颜相机&#xff0c;结果忘记苹果id密码了&#xff0c;有什么方法重新设置吗&#xff1f;】 在日常使用中&#xff0c;我们有时候会遇到忘记苹果ID密码的问题&#xff0c;这时候需要重新设置苹…

车联网OTA安全实践

摘要&#xff1a; 近年来&#xff0c;智能汽车已成为全球汽车产业发展的战略方向&#xff0c;汽车技术与工程核心逐渐从传统硬件层面转移到软件层面&#xff0c;汽车行业已经踏上了软件定义汽车&#xff08;SDV&#xff09;的变革之路。 在SDV的大趋势下&#xff0c;汽车零部件…

界面控件DevExpress WinForm的垂直网格,让数据展示更灵活(二)

DevExpress WinForm Vertical Grid&#xff08;垂直网格&#xff09;组件设计用于提供UI灵活性&#xff0c;它允许显示数据集中的单个行&#xff0c;或在其90度反向网格容器中显示多个数据集行。此外&#xff0c;开发者还可以将其用作属性网格&#xff0c;就像在Visual Studio …

VueBaiDuMap百度地图组件常用案例

VueBaiDuMap获取可视区边界点坐标_毛三仙的博客-CSDN博客【代码】VueBaiDuMap获取可视区边界点坐标。百度地图&#xff0c;左上角左下角右上角右下角坐标https://blog.csdn.net/m0_74149462/article/details/130420983?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%…

《springboot实战》 第十二章 SpringBoot整合swagger-bootstrap-ui

前言 SpringBoot整合swagger&#xff0c;使用swagger-bootstrap-ui美化页面。 1、环境配置 1.1、导入依赖包 <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version…

不得不说的结构型模式-代理模式

目录 代理模式&#xff1a; 下面是一个简单的C代码案例 下面是面试中可能遇到的问题&#xff1a; 代理模式&#xff1a; 代理模式是一种结构型设计模式&#xff0c;它通过引入一个代理对象来控制对另一个对象的访问。代理对象充当原始对象的中介&#xff0c;通过拦截对原始…

倾斜摄影超大场景的三维模型的顶层合并的点云抽稀处理技术分析

倾斜摄影超大场景的三维模型的顶层合并的点云抽稀处理技术分析 倾斜摄影超大场景的三维模型的顶层合并需要进行点云抽稀处理&#xff0c;以减小数据量和提高数据处理和展示性能。以下是几种常用的点云抽稀处理技术&#xff1a; 1、体素栅格化&#xff1a;将点云数据转换为3D体…

【TCP 协议】报文格式,数据可靠传输的机制(一)

哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a;保护小周ღ 本期为大家带来的是网络编程的 TCP 传输控制协议的概念 &#xff0c;首先会讲解 TCP 协议的报文格式&#xff0c;在学习报文格式之后&#xff0c;会学习两种 TCP 保证数据可靠传输的机制&#xff0c;确认应答…

getType() 和 getGenericType()的区别

处理泛型时会经常用到这两个方法&#xff0c;但是二者的区别是什么&#xff1f; 先看看官方的解释&#xff1a; getType 》&#xff1a;Returns a Class object that identifies the declared type for the field represented by this Field object. 返回字段对象声明类型的…

nodejs+python+php+springboot+vue 婚庆公司服务网站管理系统

管理员模块 &#xff08;1&#xff09;信息管理模块&#xff1a;对商家和个人的查看&#xff0c;修改。 &#xff08;2&#xff09;留言管理模块&#xff1a;对留言进行管理&#xff0c;确定是否能进行发布&#xff0c;对留言进行回复。 &#xff08;3&#xff09;权限管理&…

Git常用命令2

git commit --amend 有时候我们提交完了才发现漏掉了几个文件没有添加&#xff0c;或者提交信息写错了。 此时&#xff0c;可以运行带有 --amend 选项的提交命令来重新提交,这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改&#xff08;例如&#xff0c;…

【C++入门】一篇搞懂auto关键字

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】 目录 作用不那么大的场景auto真正的价值注意点auto不能推导的场景范围for范围for的使用条件 作用不那么大的场景 在C中推出了…

工业元宇宙对于制造业的影响有哪些?

伴随元宇宙的快速发展&#xff0c;它在诸多现实场景中都实现了广泛应用&#xff0c;特别是在全球科技与产业竞争核心的智能制造领域。元宇宙与智能制造融合的本质是重构企业研发、制造、销售、终端四大场景&#xff0c;相当于把企业打包进虚拟世界&#xff0c;在虚拟世界中建设…