从最近某一天开始,我的nas上镜像就没法更新了,不是网络问题。
最后尝试把’ ~/.docker/config.json’里面的”https://index.docker.io/v1/”属性删掉之后却就正常了。
从最近某一天开始,我的nas上镜像就没法更新了,不是网络问题。
最后尝试把’ ~/.docker/config.json’里面的”https://index.docker.io/v1/”属性删掉之后却就正常了。
今天出现了从不同运营商网络访问部分网站出现被持有”redirect-cnzz”证书的服务器劫持的情况,很奇怪,不知道有没有别人也碰到这情况。
kvmem-llama.cpp的0.17.0版本发了,但是只有源码没有预编译包,我让agent编译了一个
测试了几天,记录一下部署qwen3.8 27B可以比较正常运行的参数。
环境lmstudio,显卡rtx 3090,显存24G,内存16G。
以下参数名称为中文界面下显示的名称
GPU卸载 : 65
评估批处理大小 : 2048
Physical Batch Size : 64 (显存不够时尝试降低此值,显存够时增加此值)
Context Checkpoints : 32
保持模型在内存中 : false
尝试mmap : false
其他参数不变。
MTP(多token预测,或投机解码)预测token设置过2或3或6,感觉差别不大。
速度大概在47~50 token/s 。
注意,尽量不要开启KV缓存量化!要开也开KV都Q8量化,我花了一天时间得出了此结论,低于此量化开启后模型会严重降智,严重时会出现无限循环文本。
有时候服务器意外关机,会导致UrBackup的sqlite数据库出现无法自动恢复的错误,我这边就出现了这样的提示:
在访问或检查UrBackup内部数据库时发生错误。这表示内部数据库错误或者没有足够的可用空间。如果这个错误发生,请从备份中恢复数据库文件(backup_server.db, backup_server_files.db, backup_server_links.db, backup_server_link_journal.db and backup_server_settings.db)。详细数据请参阅日志文件。
出现这种情况,当然最好的处理方式是从备份恢复这个数据库,但是如果没有数据库备份的话,只能尝试修复现有的数据库。
进行任何修复之前首先关闭urbackup的进程,如果是docker运行的就关闭docker容器。
然后需要确保操作的电脑上有sqlite3命令,没有的话就进行对应的安装。
准备好之后,开始检查所有数据库文件,看看到底哪些坏了,终端命令进入到urbackup数据库文件所在的目录(一条一条执行,以免分不清哪个结果属于哪个检查):
sqlite3 backup_server.db "PRAGMA integrity_check;" sqlite3 backup_server_files.db "PRAGMA integrity_check;" sqlite3 backup_server_link_journal.db "PRAGMA integrity_check;" sqlite3 backup_server_links.db "PRAGMA integrity_check;" sqlite3 backup_server_settings.db "PRAGMA integrity_check;"
如果返回的是”ok”,那么这个数据库文件就没问题,否则就说明这个文件需要处理。
先备份需要处理的文件,可以创建一个bak目录然后把损坏的数据库文件复制进去,当然想要保险一点也可以把所有数据库文件都备份一遍。
然后把有损坏的数据库文件名后面都加上”.corrupt”,防止一会儿分不清,接着尝试以下方法:
sqlite3 损坏db.corrupt ".recover" > recovered.sql 2>/dev/null sqlite3 损坏db < recovered.sql #把"损坏db"替换成原始的数据库文件名
然后检查生成的数据库文件内部结构和原来的是否一样,可以用一些可视化工具比对起来会方便一点,比如DB Browser for SQLite 。
有一些表即使无法恢复也不影响urbackup正常运行,比如”backup_server.db”中的”log_data”和”user_tokens”这种表,无法恢复就不用管了。
如果recover命令无法恢复主要内容的话,就尝试方法二。
下载这个脚本放在数据库目录: https://gist.github.com/JiaJiaJiang/8baa74abbc320da41259d49c44f293d8。
给它执行权限:chmod +x sqlite_rebuild_db.sh
然后执行 ./sqlite_rebuild_db.sh 损坏db.corrupt 损坏db ,看到有报错也没事,直接检查生成的数据库内容是否包含了必要的核心表。我自己用这个方法恢复出来的数据比方法一要多,生成的数据库文件也可以直接正常启动urbackup,报错没有了。
我刚刚发现我在TrueNAS里面安装的虚拟机和宿主机无法互相ping通,怪不得把网关设置成里面的openwrt虚拟机一直连不上外网。
查了一下是因为我把TrueNAS宿主和虚拟机的网卡都直接绑定到宿主机的物理网卡上了,导致网卡不知道这些数据包之间互相怎么路由。
需要做的事情是要在宿主机里创建一个网桥充当虚拟交换机,然后把TrueNAS的地址设置到网桥上,把虚拟机的网卡也绑定到网桥上就可以了。
做个笔记,方便下次再用。
qm importdisk 虚拟机ID /var/lib/vz/template/iso/openwrt-25.12.5-x86-64-generic-ext4-combined-efi.img(改成你的镜像文件名) local-zfs(存放虚拟硬盘的位置,改成你的存储库名称)
vi /etc/config/network修改网络配置的以下部分:
config interface 'lan'
option ifname 'br-lan'
option proto 'static'
option ipaddr '192.168.1.1' # 按需设置
option netmask '255.255.255.0'# 按需设置
option gateway '你的网关IP' # 如有需要
list dns '8.8.8.8' # 如有需要
改完以后保存退出(按”:wq回车”)。
/etc/init.d/network restart重启网络服务,此时应该可以ping通这个openwrt了。passwd设置一个root密码,然后用ssh客户端登录进行后续步骤,可以方便粘贴东西(此时的pve vnc界面是没法复制粘贴文字的)。sed -i 's_https\?://downloads.openwrt.org_https://mirrors.tuna.tsinghua.edu.cn/openwrt_' /etc/apk/repositories.d/distfeeds.list apk update
apk add luci-i18n-base-zh-cn。apk add openssh-sftp-server。dnsmasq软件包,它的部分功能和开启tun模式的clash是冲突的,但如果你需要在这个openwrt上开启DHCP功能,则不能删除它,需要对dnsmasq进行具体的设置来消除冲突。apk add curlcurl -x socks5h://socks5代理地址:端口 -sSL https://github.com/nikkinikki-org/OpenWrt-nikki/raw/refs/heads/main/feed.sh | ash
然后在luci的包管理界面安装执行nikki luci-app-nikki luci-i18n-nikki-zh-cn这三个包,注意不要使用apk直接安装,因为luci模块有后处理步骤,直接使用apk安装的话不会在web界面显示出来。
至此在pve上安装openwrt并安装clash的步骤就完成了。
直接使用磁盘镜像写入的openwrt系统存储区默认很小,需要自己额外运行一个官方脚本来把可用空间扩展到剩余可用大小。
opkg install parted losetup resize2fs blkid #新版本的openwrt使用apk包管理 apk add parted losetup resize2fs blkid
wget -U "" -O expand-root.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/expand_root?codeblock=0" chmod +x expand-root.sh . ./expand-root.sh
注意你可能不会看到任何输出,但是不要多次执行此脚本,执行完之后如果没有自动重启就手动reboot,系统可能会自动重启几次,直到它不再重启就代表空间已经成功扩展好了。
有时候有的设备需要爬墙但又不能指定代理,而且家里又没有单独的可以爬墙的路由器时,可以用这个方法把windows系统的电脑临时变成网关来使用。
要用这个方法需要你的梯子软件开启TUN模式,才能把过来的网络流量转发到梯子去。注意,你可能需要用两张网卡来实现这个功能,否则会出现代理流量在clash虚拟网卡和出口网卡之间回环路由,一张只接受网络中的流量(在这上面配置路由转发),另一张作为网络出口。
此方法适用于windows 10以上的系统,在PowerShell(管理员)中使用以下命令即可在指定网卡上开启路由转发,开启后此网卡上接收到的网络流量会走系统路由表转发出去。
Set-NetIPInterface -InterfaceAlias "网卡接口名称" -AddressFamily IPv4 -Forwarding Enabled #不指定网卡时将会开启所有网卡的路由转发 Set-NetIPInterface -AddressFamily IPv4 -Forwarding Enabled
使用以下命令查看网卡是否已经打开了路由转发:
Get-NetIPInterface -AddressFamily IPv4 | Format-Table InterfaceAlias, InterfaceIndex, Forwarding -AutoSize
注意此方法在重启系统后会失效,如果需要保持转发效果,可以写一个powershell脚本配合任务计划在开机后自动执行。
我在PVE中跑了个TrueNAS系统,不过之前一直是通过软SCSI控制器把硬盘一块块映射到虚拟机里面去的,虽然这样能用,但这样一个问题是有性能开销,truenas也不能直接对硬盘进行最直接的控制,另一个问题是换盘的时候都要重新执行映射指令,很麻烦。
于是我想着还是得实现真正的直通才行,要实现对虚拟机来说能让硬盘即插即用最干脆的方法还是直接把整个SATA控制器映射进去,我刚好有个插在主板m.2插槽上的PCIE转SATA扩展卡,扩出来5个SATA口。
注意主板上的SATA控制器是不可以映射到虚拟机里的,一个原因是其iommu分组一定会绑定主板芯片组里其它兼职的部分无法分开,另一个原因是如果你的PVE系统盘在主板上的SATA接口上或者在通过芯片组的m.2接口上(通常是远离CPU的那个m.2接口),会导致pve启动不了。
这篇文章的主要部分就是以上我踩的坑,分享出来给同样遇到问题的人参考一下,下面是跟着AI的指导操作的步骤。
编辑PVE的配置文件,设置在PVE主机中屏蔽需要直通硬件的驱动:
/etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 中添加 intel_iommu=on(Intel)或 amd_iommu=on(AMD)以及 iommu=pt。pcie_acs_override=downstream,multifunction。GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt pcie_acs_override=downstream,multifunction
/etc/modules,确保里面包含:
vfio vfio_iommu_type1 vfio_pci vfio_virqfd
proxmox-boot-tool refresh,然后重启PVE。for d in /sys/kernel/iommu_groups/*/devices/*; do n=${d#*/iommu_groups/*}; n=${n%%/*}; printf '%s\t%s\n' "$n" "$(lspci -nns ${d##*/})"; done | sort -n
如果此时你要直通的设备还是和其他设备共用一个组号,那么要考虑更换直通CPU的插槽,换插槽也没用就是没有办法了。
lspci -n -s 26:00.0查看你的设备ID(这里面的PCI地址替换成你自己设备的那个),我的设备id返回的是这个样式的:197b:0585。/etc/modprobe.d/vfio.conf中添加以下内容:options vfio-pci ids=你的设备ID/etc/modprobe.d/pve-blacklist.conf中添加:softdep ahci pre: vfio-pciupdate-initramfs -u -k all。lspci -k -s 你的设备PCI地址,检查是否有Kernel driver in use: vfio-pci,有的话就是驱动成功被接管了。完成以上步骤直通SATA控制器就设置好了,然后可以打开虚拟机。
被这个破问题困扰了好几天,明明我没有在搜索语法中使用前缀搜索,但搜索结果就硬是会出现只有前缀匹配的结果,自己的测试结果和groonga文档里的结果都不一样,搞得自己怀疑是不是我的pgsql服务坏了。
挣扎了三天才发现pgroonga扩展打开了强制前缀搜索,要修改这个参数:
SET pgroonga.match_escalation_threshold = -1;
这个参数默认值为0,表示“如果主关键字的命中数为 0,则升级为松散前缀搜索”,设置为-1之后即可关闭这个功能。
PostgreSQL Docker从17升级到18版本,有一些大的变动,因此升级过程需要进行一些额外的操作。
首先,17版本默认是不开启数据检验和的,因此需要先把17版本的数据库启用校验和,才能正确迁移升级到18版本。
docker run --rm -it \ --mount "type=bind,src=17版本数据库目录路径,dst=/var/lib/postgresql/data" \ postgres:17 \ pg_checksums --enable --verbose --progress -D /var/lib/postgresql/data
如果出现类似这样的错误:`pg_checksums: error: invalid segment number 0 in file name “/var/lib/postgresql/data/base/24699/pgrn.conf”`,可能是插件生成的文件此工具无法识别,暂时把它们移走,等执行完以上命令之后再移动回来。
Checksum operation completed Files scanned: 1991 Blocks scanned: 7209262 Files written: 1674 Blocks written: 7209185 pg_checksums: syncing data directory pg_checksums: updating control file Data checksum version: 1 Checksums enabled in cluster
现在数据库的校验和就开启完成了,然后就是改变数据库的目录结构,17版本以及之前的数据目录在`/var/lib/postgresql/data`中,但18版本开始,数据目录需要在以大版本号命名的子目录中,使用以下流程进行迁移:
docker run --name temp-pg-18 \ --mount "type=bind,src=pgsql数据目录/tmp,dst=/var/lib/postgresql/" \ -e POSTGRES_USER=超级用户名 \ -e POSTGRES_PASSWORD=超级用户密码 \ -e POSTGRES_DB=postgres \ -d postgres:18
容器成功运行后等十几秒钟,检查”pgsql数据目录/tmp”目录中是否已经生成了数据库文件,有了的话执行命令清除临时容器:
docker stop temp-pg-18 && docker rm temp-pg-18
mv tmp/18 ./18 rm -r tmp
docker run --rm \
--mount "type=bind,src=pgsql数据目录,dst=/var/lib/postgresql" \
--env "PGDATAOLD=/var/lib/postgresql/17/docker" \
--env "PGDATANEW=/var/lib/postgresql/18/docker" \
--env "PGUSER=超级用户名" \
tianon/postgres-upgrade:17-to-18 \
/bin/bash -c "apt update && \ #在这里执行你的依赖安装命令,如果不需要安装依赖的话可以把这个apt命令也去掉,仅占位示例用
/usr/local/bin/docker-upgrade --link"
不算安装依赖的时间,迁移过程应该很快会完成,并且给出如下提示:
Upgrade Complete
----------------
Some statistics are not transferred by pg_upgrade.
Once you start the new server, consider running these two commands:
/usr/lib/postgresql/18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
/usr/lib/postgresql/18/bin/vacuumdb --all --analyze-only
Running this script will delete the old cluster's data files:
./delete_old_cluster.sh
docker run --rm -it \ --mount "type=bind,src=pgsql数据目录,dst=/var/lib/postgresql/data" \ postgres:18 \ pg_checksums --check -D /var/lib/postgresql/data/18/docker
vacuumdb -U 超级用户名 --all --analyze-in-stages
这样基本上就完成了迁移工作。
为了在订婚宴上更好地控制背景音乐,用AI连夜写了个背景音乐控制器,然后这两天又好好鞭笞AI修掉了大部分bug,现在分享出来;
项目地址:https://github.com/JiaJiaJiang/bgm-controller
在现示例:https://pages.luojia.me/bgm-controller/dist/ (示例中的音乐可不是我订婚宴用的音乐哦,是正好在我静态文件存储里有的音乐)
今天订婚啦!
写一篇小笔记,记录一下第一次脱壳并逆向修改安卓应用的过程,为了避免麻烦,这里不会有被我逆向应用的信息。
为了把一个应用使用的一个库换成opencv,我这个连java都不会写的人硬着头皮消耗了一个月,甚至整个春节假期在做这个事情。
首先需要的一个工具是apktool [https://github.com/iBotPeaches/Apktool],它的作用是把应用安装包apk文件中的各个部分提取出来,变成一个apktool项目目录,且修改完之后我们也需要用它打包回apk。
以下是用ai生成的一个apktool反编译后目录的结构,另外此次逆向修改过程中也大量使用了ai,不然以我这第一次认识这些东西的知识储备,还得更久才能弄好。
your_app/ ├── AndroidManifest.xml # 应用主配置文件,声明组件、权限、包名等 ├── apktool.yml # APKTool 元数据,记录 SDK 版本、资源 ID 偏移、压缩规则等,用于重打包 ├── smali/ # 主 DEX 反编译出的 Dalvik 字节码(.smali),对应 Java/Kotlin 逻辑,如果没有选择反编译资源的话,则不会有这个目录,取而代之的是classes.dex文件 │ └── com/example/... # 按原始包名组织的类文件 ├── smali_classes2/ # (若存在)第二个 DEX 文件的 smali 代码,用于 multidex 应用 ├── smali_classes3/ # (若存在)第三个 DEX,依此类推 ├── res/ # 编译后的资源目录,已还原为可读 XML │ ├── layout/ # 界面布局文件(.xml) │ ├── values/ # 字符串(strings.xml)、颜色(colors.xml)、样式(styles.xml)等 │ └── drawable-*/ # 图片资源,按屏幕密度分类(如 drawable-xhdpi) ├── assets/ # (可选)原始资产目录,内容不被编译,通过 AssetManager 访问(如 .json、.db) ├── lib/ # (可选)原生库目录,包含 .so 文件 │ ├── arm64-v8a/ # 64 位 ARM 架构原生库 │ └── armeabi-v7a/ # 32 位 ARM 架构原生库(其他架构如 x86 等也可能存在) ├── original/ # (可选)原始 APK 中的 META-INF 目录,含签名文件(重打包时通常会被替换) └── [resources.arsc] # (注:此文件在反编译后不直接出现,其内容已解析并融入 res/ 目录中)
要修改应用的逻辑,则需要修改各个smali目录下的smali文件,这些是反编译出来的字节码文件。 继续阅读安卓应用脱壳逆向笔记
我让ai给我写了段调试安卓应用的frida脚本,里面有一段类似这样的代码:
var SystemClass = Java.use("java.lang.System");
SystemClass.loadLibrary.overload("java.lang.String").implementation = function (libname) {
console.log("[库加载] System.loadLibrary被调用: " + libname);
// 所有库都调用原始方法,不做任何拦截
this.loadLibrary(libname);
};
然后调试应用的时候就发现应用总是只从”/system/lib/”和” /vendor/lib/”中寻找库文件了,结果当时是加载失败,踩了个坑,记录一下。
似乎一旦重载了这种方法,就会影响应用加载库的搜索路径,目前没找到什么好办法解决。