Welcome to Snooda's Blog
Windows远程桌面有个很实用的功能,就是全屏时不显示菜单栏,这样鼠标在顶部操作时(常用比如切换网页tab),不会频繁唤出烦人的菜单栏。
但是这样有个问题,就是全屏如果想要退出来,Ctrl+Tab是不行的,会被识别为远程切窗口。
需要按Ctrl+Alt+Break退出全屏。或者Ctrl+Alt+Del打开主机的锁屏页,然后打开任务管理器的方式间接切出来。但是后者明显要麻烦很多。

现在越来越多的键盘并没有设置Break键了。我尝试了一下网上推荐的Ctrl+Alt+Fn+B和Ctrl+Alt+Fn+P,均没有任何作用。杂牌键鼠和tp键盘均无效。

偶然发现按Ctrl+Alt+Home键是可以唤出菜单栏的,这时候点击菜单栏上的最小化/退出全屏按钮就ok了,很方便。
Tags: ,
关于磁盘分区表、系统分区、系统引导方面,有很多名词,目前各种资料也比较杂乱,特意整理了一下。

CHS:Cylinder-Head-Sector
最传统的 柱面-磁头-扇区 模式的磁盘寻址方式。传统只支持8GB以内的磁盘。目前磁盘早已不采用真*CHS来寻址,特别是SSD,压根没有磁头了。但依然保持兼容,支持虚拟CHS信息。

在DOS和Windows XP系统时代,分区必须要对齐柱面(原因是和bios命令INT 13h相关,这里不细展开),而引导分区在第一柱面上,所以根分区从第二个柱面开始。所以XP之前的根分区都是从63扇区开始。
http://www.pixelbeat.org/docs/disk/

DOS had the requirement that its image did not span across cylinders, and so this region was added by partition managers so that the first partition was aligned on a cylinder boundary. Therefore this region's size is determined by the number of sectors (512 bytes) per cylinder. The maximum (and usual given todays disk sizes and LBA) sectors per track is 63, which leaves 62 sectors free after the MBR (31,744 bytes).


按这里的说法,每组扇区是63个。


这里其实就有一个疑问,引导扇区到底是0号还是1号?按习惯来讲,应该是0号开始,那么0-62是第一柱面,63是第二柱面的第一个扇区,所以系统从63开始是合理的。

但CHS资料显示,扇区号范围是1-63。(111111)。这就很奇怪了。。那难道第二柱面的第一个扇区不应该是64才对么?

仔细研究了下
https://en.wikipedia.org/wiki/Cylinder-head-sector

The first LBA sector is sector # zero, the same sector in a CHS model is called sector # one.
    All the sectors of each head/track get counted before incrementing to the next head/track.
    All the heads/tracks of the same cylinder get counted before incrementing to the next cylinder.
    The outside half of a whole Hard Drive would be the first half of the drive.



这就引出了LBA:Logical Block Address。由于磁盘越来越大,CHS已经无法满足寻址需求。
所以现在采用了逻辑寻址,仍然兼容CHS,但LBA的起始扇区是0,对应CHS的起始扇区1.


CHS tuples can be mapped onto LBA addresses using the following formula:

    A = (c ⋅ Nheads + h) ⋅ Nsectors + (s − 1),

where A is the LBA address, Nheads is the number of heads on the disk, Nsectors is the maximum number of sectors per track, and (c, h, s) is the CHS address.



所以Fdisk使用LBA寻址方式的话,按0开始计算扇区号就ok。

这就引出了第二个经典问题:Windows XP分区使用SSD性能差问题。
核心原因之一就在于此。现代磁盘物理扇区都是4KB,需要4KB对齐,而起始的63显然不是4K对齐的。所以很多XP分区直接安装Windows7后,使用SSD时会报分区未对齐的问题。

目前Windows的默认起始扇区都是2048了,即首个分区前面空出来1MB的空间。这样就没有了4KB对齐的问题。
(1MB原因:Using a 1-MB alignment boundary allows safer editing of the partition table with Vista Disk Management. 详情可见https://en.wikipedia.org/wiki/Logical_Disk_Manager   主要还是空出来足够多的空间为了兼容一下历史的各种分区工具)



综上,CHS和LBA主要讲的是磁盘寻址方式。目前主要是LBA寻址了。历史上的4K对齐问题,就是因为寻址方式切换带来的问题。由于目前均已经采用了LBA模式,所以这块已经比较清爽了。



然后比较杂乱的就是MBR/EFI/GPT这一大堆了。

主要原因在于MBR在不同语境下具有了多种通俗含义。下面分场景来梳理一下。

在磁盘分区表场景,传统的分区表经常被叫做MBR分区表,与之对应的叫GPT分区表。在这里,MBR是分区表类型名。

MBR分区表信息是存在MBR分区里的,限于512容量限制,只支持4个分区槽位,所以就有MBR最大只支持4个主分区的限制。另外由于扇区号为32bit,所以在512扇区场景下,只能寻址2TB,所以也有2TB容量限制。


GPT分区表是UEFI标准的一部分,主要是支持更大磁盘和更新的引导模式,主要是使用扇区1存储主元信息,存储磁盘空间,uuid等信息,扇区2-33存储分区信息(这里有个有趣的点,就是GPT最大到底支持多少个分区,理论推算应该是32扇区 * 512扇区大小 / 128每个分区表项大小= 128,很多文章说gpt支持无限个分区,推测应该是有一些扩展实现。不过OS层面,windows只支持128个分区,linux只支持256个,所以开多了也并没有用)
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/genhd.h?h=v5.0.12#n63


这里就需要注意了:在使用GPT分区表的磁盘上,依然可以有MBR引导扇区。因为GPT是从扇区1开始的。

目前实践上,UEFI模式启动必须要用GPT分区。BIOS/MBR/legacy模式(后面统称传统模式)可以启动MBR分区/GPT分区磁盘。
注意:支持UEFI模式的硬件一般也向下兼容legacy模式

Case1:传统模式启动MBR分区:

传统模式,grub/老的Windows都是如此,差不多从Windows8开始,默认已经都改成UEFI启动了。但依然支持传统引导模式(Windows 11是否依然支持暂时没调研)。

对于grub来讲,大概分为stage1,stage1.5,stage2。
stage1放在MBR中,用来加载第二个扇区的stage1.5(MBR容量有限)
stage1.5加载后面连续n个扇区,用来加载文件系统,进入stage2
stage2进入主分区,启动系统内核

由于使用的都是63扇区之前的内容,所以并不会干扰正常分区中的内容


Case2:传统模式启动GPT分区:

grub2是支持该模式的。由于分区1-33都被gpt分区表占了。所以一般需要一个BIOS Boot Partition
https://en.wikipedia.org/wiki/BIOS_boot_partition
这个分区需要30KB以上,可以在任意位置,part entry type是固定的21686148-6449-6E6F-744E-656564454649 (ASCII string "Hah!IdontNeedEFI",blkid -p可查看)
但由于上面提到,主流分区工具都会预留一个1MB的空间在头部,所以这个分区就可以缩在这里,即扇区34-2047这个区间。目前看debian系是放在这里的。redhat系似乎是放在了2048-4095处(只看了一个样本)。虽然没有对齐之类的,但这个区域本身也基本不读写。所以还ok。


Case3:UEFI启动MBR分区:

Compatibility Support Module (CSM) 兼容模式,用传统模式启动。

Case4:UEFI启动GPT分区:

一般使用EFI system partition (also called ESP),推荐512MB,存放系统内核等文件。类型是EFI System。
文件系统推荐采用FAT32,UEFI默认是支持FAT12/16/32,但是可以扩展。比如apple就支持HFS+。



由上可知。legacy和efi模式启动其实是可以共存的,只要同时有BIOS Boot Partition和ESP,就可以同时支持两种模式启动。当然,更新内核时需要注意同时更新/boot和ESP中的内核。这样才不会产生不一致的问题。


Tags: , , , , ,

gitlab使用samba/cifs作为存储

[| 不指定 2021/09/17 02:14]
    gitlab默认是无法直接使用cifs挂载作为数据存储目录的,不过经过一些小小的移植,可以实现正常运行。

    1,关注.ssh/authorzed_keys,由于cifs挂载默认使用同样的权限,而.ssh/authorized_keys分别要求目录是700,文件是600权限,所以默认会导致推送代码时公钥认证失败,一般对.ssh目录额外进行一个挂载即可,挂载参数添加file_mode=0600,dir_mode=0700。另外该目录所有人需要是gitlab-shell指定的用户,默认为git,需要查询git在/etc/passwd内的uid,/etc/group中的gid,指定uid=xxx,gid=yyy。(同样适用于docker内)。
    2,关注repositories,默认迁移后会发现一个诡异的问题,就是提交代码可以成功,代码库也可以看到新代码,但是push events没有更新。其实是因为gitlab的hooks默认是软链,迁移至samba后,被屏蔽掉了,这里推荐gitlab自带的check工具(scripts目录下),可以检查每个仓库的hooks是否正常安装了。如果提示hooks有问题,那么直接ln -s是不行的,需要在挂载参数里添加mfsymlinks,启用软链支持,然后需要在samba server上将原有软链删除掉(如果不删除,则client端既看不到软链,但创建时又提示存在),再使用ln -s重新修复hook即可,此时可以看到,samba server是使用一个特殊文件来存储软链信息的。理论上对于所有的软链,迁移至samba后都要进行这个修复。


     修复后,就可以使用了。
Tags: , ,

Gpu Passthrough实践-Windows7/10

[| 不指定 2021/09/09 21:56]
    Passthrough技术在虚拟化场景运用的比较成熟了,最早落地的像网卡SR-IOV技术,可以将网卡直通到虚机内,提升网络吞吐性能。像Gpu Passthrough技术,最近几年随着深度学习的快速发展,也得到了大规模的运用,不过线上用的一般都是计算卡直接跑计算任务,对于家用场景,则是另外一种玩法。现在多合一越来越流行起来,NAS,软路由,下载机,steam多合一可以更好的节省空间,避免了塞爆弱电箱。
    本着学习的态度,调研了一下kvm下Gpu Passthrough的落地,发现有如下几个要点
    1,SeaBIOS兼容性更好,OVMF使用比较复杂,Windows10用SeaBIOS也可以直通的。
    2,i440fx在Windows10下运行通过,Q35在Windows7下运行通过,互换没有测试,大概率是ok的。
    3,如果启用了hyper-v支持,里面的vendor_id属性一定要去掉,否则会黑屏。网上有教程说vendor_id是用来绕过n卡43错误的,但随着今年n卡放开虚拟化场景下使用,直接安装21年4月后的n卡驱动就没有43问题了,不需要vendor_id(用21年8月的30版本驱动跑通)
    4,存量系统也可以直通的,第一显卡设vnc,第二显卡设要直通的显卡,进系统后打好驱动,这时候物理显卡应该会报12错误,没问题,第一显卡设置成透传显卡,然后启动,rdp远程登陆,进去后查看显卡状态是否正常,有可能会报43等其他的错误,卸掉驱动后重新安装/禁用重新启用,一般会解决。之所以要先vnc那一步,主要是排查一下是否有其他影响启动的因素(如强制关机导致的默认进修复模式/开机蓝屏等,此时rdp无法登陆,vnc就很重要),实测物理机上的windows7迁移到kvm内直通成功。


    综上,win7,存量系统,老硬件(Ivy Bridge)均可以直通,放心实践。显卡直通技术可以解决一机多人使用(同时使用需多套键鼠+多显卡)问题。
Tags: , ,
    最近遇到一个bug,定位了非常久,感觉有必要分享出来。。。避免后人掉坑。

    前段时间发现了一个raft主从间内存不一致的场景,导致切主后数据异常。。当时费了很大的力气排除掉其他模块逻辑问题。后来问题缩小到raft state machine里。由于raft高度依赖state machine幂等性(重启、切主都会导致状态机重做,如果逻辑不是严格幂等,就会出现状态不一致问题),一般要求日志中必须记录绝对操作,尽量不记相对操作。但有一个round-robin分配资源的场景,还是依赖了一下资源节点的排序问题。

    最早是使用std::map来存,使用迭代器遍历。由于map本身是有序的,所以三副本之间是一致的。
    后来有不熟悉的同学为了优化map的lg(n)性能,改用了基于哈希的unorderedmap,那么问题就来了。逻辑上map和unorderedmap都支持迭代器遍历。所以只修改数据类型,不修改逻辑是可以兼容的。简单执行也没有问题。

    已知unorderedmap肯定不能保证遍历结果的有序,但是目前场景也并不要求结果有序,只要每次遍历结果顺序不变就行,那么unorderedmap能否保证遍历顺序幂等性?目前看答案是“不能”。

    简单来想,hash表就是对元素做哈希,然后选定桶,对于桶内的元素就串到list上。那么只要按同样的顺序插入,似乎也是可以保序的。因为unorderedmap内部存在自动rehash过程。。一旦rehash,节点的遍历顺序就会变化。。。

    所以一定要重视“unordered”关键字。。。任何情况下unorderedmap都不保证任何顺序。。。。
Tags: ,
        生产环境线上一般是不允许开启conntrack的,因为默认的连接跟踪表也就万级别,不小心打满后,容易导致很难排查的网络问题。(iptables -t nat只查看也会不知不觉启用conntrack)所以很多团队是规定禁止线上运行iptables的。        但是某些设备上,conntrack是必备的一项功能,比如网关,用来做防火墙、包转发等。        今天就遇到了一个很特殊的场景。。表现特征是iptables配的MASQUERADE看起来并不生效。有时不知怎么回事生效以后,删掉规则居然仍然能转发。。明明删除了规则,居然还能ping通,新增了规则,居然还转发到老的地方。。

后来研究了一下,发现原来对于iptables的nat表来讲,只有连接新建时,才会查表进行一次匹配。当连接被conntrack后,就不再走nat表匹配了。
对于icmp来讲,默认conntrack会保留30s,所以如果添加规则前30s如果ping了一下。那么添加完并不会生效已有的。。。。反之亦然。
可以使用conntrack -E作为验证手段。该命令会打印conntrack模块对连接的跟踪情况。

如果想手动移除映射关系,可以使用conntrack -D
最近看到很多科技网站上提出,在ios10.3中引入了Apple File System,由此可以节省2GB的系统存储空间,个人对这个说法是持一定怀疑态度的,毕竟这个缩减比例还是有点高的。

昨天ios10.3 Beta3发布,决定实际测试一下升级效果。

找了一部16GB ipod touch6,升级前为10.1.1版本。剩余空间<500M。系统总可用空间是12GB+

安装ios10.3 Beta3描述文件后重启设备,可以看到新版本了,大小提示1.6GB,点击下载并安装,居然开始下载了,因为按现在的剩余空间是不够存放rom的,进入容量页面查看,发现可用容量持续上涨,按home进入主页面检查,发现app开始轮流显示“清理中”。等app都清理完后,扣除已下载的rom占用空间,系统多出来1-2GB的可用容量。此时系统并未升级。

然后进行升级,升级后进入系统,总可用空间依然是12GB+,大概比之前增加了500MB,可用空间比升级前(清理后)同步增加了500MB。

综上,升级后确实可用空间多出来2GB左右,但ios10.3升级本身只贡献了500MB,其余大部分都是ios在准备升级阶段调用清理操作节省出来的。

所以对于不想升级系统、又想获得空闲空间的同学,只需要点击升级,就会触发系统清理,清理完后停掉升级流程即可。







Tags:
    今天写了一个自动拉起脚本,调试的时候出了点状况,导致启动了很多个openvpn实例,并且还在不断启动中。对于使用同证书的实例,默认会后面的踢掉前面的,所以网络就陷入了还没连上就被踢掉的循环,无法登陆,也就失去了控制。

    首先尝试打开server端的duplicate-cn支持。这样每个连接都会分配到一个单独ip,不会互相踢掉。但由于进程太多,每个进程连接上后都试图刷新路由表,导致路由表不停变更,网络依然不能连通。

    这时就需要从server端限制:只能有一个客户端连接上。首先调研了下是否支持只接受第一个连接上的实例而忽略掉后面的连接请求,发现是没有这个特性的。因为如果正常使用中客户网络闪断,这种情况下就不得不等待很久session超时后才能连上,用户体验太差。

    对于网络层面的控制,iptables是个很有效的利器。于是采用了如下的方式:
    1,首先设置DROP掉指定机器所有入包     iptables -I INPUT 1 -p udp -s xxx.xxx.xxx.xxx -j DROP
         这时候所有连入请求都会timeout。
    2,然后使用tcpdump host xxx.xxx.xxx.xxx
         查看所有连入请求的来源端口,选取其中一个。
    3,执行          iptables -I INPUT 1 -p udp -s xxx.xxx.xxx.xxx --source-port yyyyy -j ACCEPT
         为这个实例单独开一个入口。

等待几秒,等待其重试连接,这时候只有这一个实例可以连入。成功恢复连接。

这里需要注意,第一步应使用DROP而不是REJECT,因为前者会让请求方重试的时间间隔更长一些,为后续操作赢得更多时间。









Tags:
    早在大学的时候就买过一套电烙铁。大概二三十块吧。有一个电烙铁、烙铁架、松香、海绵、一小卷焊锡丝。当时也没怎么用过,后来小焊锡丝找不到了。于是又买过3块钱的一小管焊锡。前几年试图在洞洞板上焊接一个51最小系统,焊接的很痛苦。感觉焊锡丝很难溶化,并且化了也不往电路板上沾,都堆在烙铁头上。当时以为是因为操作技术问题。后来由于树莓派、arduino的兴起,很多传感器都有焊接好的最小系统板卖了。只需要杜邦线插一下就能完成连接,焊接这事就放下了。

    前段时间买了一块tm7705,排针没有焊,于是又把尘封很久的设备翻了出来。依然难用,搞了很久也不行,上了助焊剂也毫无作用。思考了一下,既然焊锡丝不好化,是不是烙铁温度不够?于是上京东搞了一个宝工的206焊台,心想这下换了高级设备是不是就可以搞定了。。。买回来后发现依然如故。温度调到350以下焊锡丝不化,400度以上能化但是不沾板,并且烙铁头很容易就烧死了。上网仔细搜了下教程。发现问题主要有两个:一个是手法问题,即应该是烙铁头加热引脚几秒后,焊锡丝接触烙铁头和引脚溶化焊接。而不是先把焊锡丝化到烙铁头上往引脚涂,因为这么操作焊盘温度不够,就会不沾锡,并且焊锡沾到引脚就凝固,会虚焊,焊点形状也不好控制;第二个就是焊锡丝质量很可能有问题,有人提到焊锡丝不容易化或者焊点呈豆腐渣样有一个原因是铅和杂质比例太高。由于大部分情况下我的焊锡丝直接按到烙铁头上都不能融化,那么手法问题就是其次的了,焊锡丝质量的问题更大一些。于是决定重新买一些焊锡丝。


    调研了一下,出于健康考虑,现在工业生产用的焊锡已经不允许含铅了。但是卖的焊锡丝很多还是传统的铅锡合金。这种焊锡丝熔点低,焊点亮,所以在diy市场里还是很受欢迎。我倾向于健康一些的无铅焊锡。于是调研了一下。

    目前无铅焊锡主要是锡铜合金,99.3%的锡和0.7%的铜,熔点227度。比传统的63%锡铅合金的183度要高了四十多度。还有比较小众的锡银合金,主要是音乐发烧友使用(个人对于那零点几个点的银能否发挥什么作用持保留态度,不过b格是够了,可以号称焊出来的板子比小米的还nb了,不但含黄金,还含白银),熔点221度。还有黄花的锡银铜铈合金,含稀土不知道有什么特性。

    这次不敢随便买了,准备还是选择大品牌产品。首先还是考虑和焊台同品牌的宝工,宝工的无铅焊锡只有锡铜合金,含银的那款是含铅的。于是转向考虑其他品牌,发现广州黄花在烙铁和焊锡市场上也比较受欢迎,于是选择了黄花的锡银焊锡。为了不把鸡蛋放到同一个篮子里,还选了友邦的锡铜焊锡。前两天收到了。做工比较精致,今天打开试了一把。刚开始心情还是比较忐忑的,毕竟无铅焊锡焊接难度要高一点。先尝试黄花锡银,打开焊台调到325度,十几秒后温度稳定。烙铁加热焊点->加焊锡,很快焊锡就融化了,向上抬起烙铁头,一个焊点就焊好了。。果然不是一个世界的体验,换用友邦,也很顺利。。。原来问题的根源在于几块钱的焊锡丝。。



    终于掌握了焊接技术,以后diy的自由度又高了一些,不用再忍受乱糟糟的线了。没想到的是问题居然一直出在最不起眼的几块钱的焊锡丝上。。。搞diy还是不能马虎啊,新手更应该用好东西。否则出了问题都不知道是啥原因。



dns缓存nscd原理及相关知识

[| 不指定 2016/06/12 15:05]
    由于sshd是支持包转发的。所以最近配置了一些规则,将指定uid的包转发到指定目标。通过统计包数量,发现tcp的数据是正常的,但dns请求包不生效,还是走原路径。tcpdump抓包发现确实是发到系统配置的resolver那里去了。看了眼sshd的代码,是使用了libc里面的res_query方法来做域名解析的。像gethostbyaddr也是使用的这个方法。考虑到可能是这里发生的问题,于是用strace抓包看了一眼。发现该方法是先去连接/var/run/nscd/socket。如果成功,则发送域名解析请求,然后由nscd服务进行dns解析。所以按uid来抓包会失效。

    nscd是一个缓存服务。会缓存passwd、hosts、resolv三类信息。和dnsmasq类似。先试图停掉nscd服务再进行尝试,果然进程在试图连接/var/run/nscd/socket失败后,转为连接resolv.conf里指定的server,可以成功被iptables转发。


    定位了具体问题原因后,开始寻找更多解决方案。停掉nscd固然最简单,但会导致整个系统都失去dns缓存,对性能还是有一定影响的。于是寻找优化一些的方案。思路是对于指定进程绕过nscd机制。


    研究了一下。发现nscd为了避免自己的请求发送给自己导致死循环,调用了一个__nss_disable_nscd方法。调用该方法后即可关闭nscd机制。于是改动了一下sshd源码,重新编译了一个。再次重试。果然ok了。












Tags: ,
分页: 1/31 第一页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]