Android vendor.img中文件执行权问题
问题
Android 9、11往vendor.img增加文件,烧写到设备后发现增加的可执行文件没有执行权限。经过漫长查找,终于找到了问题的根源,谨以此篇献给哪些脚踏实地的人们。
根本原因
system/core/libcutils/fs_config.cpp文件,fs_config函数根据android_dirs、android_files中的配置修改文件的uid、gui、mode(权限)。除了/vendor/bin/、/vendor/xbin/目录下的文件的有执行权限,/vendor目录下的其他文件都没有执行权限。
vendor.img是如何生成的
build/core/Makefile
INSTALLED_VENDORIMAGE_TARGET
3314 # We just build this directly to the install location.
3315 INSTALLED_VENDORIMAGE_TARGET := $(BUILT_VENDORIMAGE_TARGET)
3316 $(INSTALLED_VENDORIMAGE_TARGET): \
3317 $(INTERNAL_USERIMAGES_DEPS) \
3318 $(INTERNAL_VENDORIMAGE_FILES) \
3319 $(INSTALLED_FILES_FILE_VENDOR) \
3320 $(RECOVERY_FROM_BOOT_PATCH)
3321 $(build-vendorimage-target)
build-vendorimage-target
BUILT_VENDORIMAGE_TARGET
3294 vendorimage_intermediates := \
3295 $(call intermediates-dir-for,PACKAGING,vendor)
3296 BUILT_VENDORIMAGE_TARGET := $(PRODUCT_OUT)/vendor.img
3297 define build-vendorimage-target
3298 # $(hide) /usr/bin/python build/tools/rcmerge.py $(subst full_,,$(TARGET_PRODUCT)) vnd
3299 $(call pretty,"Target vendor fs image: $(INSTALLED_VENDORIMAGE_TARGET)")
3300 @mkdir -p $(TARGET_OUT_VENDOR)
3301 @rm -rf $(TARGET_OUT_VENDOR)/avm
3302 @mkdir -p $(TARGET_OUT_VENDOR)/avm
3303 $(call create-vendor-odm-symlink)
3304 @mkdir -p $(vendorimage_intermediates) && rm -rf $(vendorimage_intermediates)/vendor_image_info.txt
3305 $(hide) cp -rf $(TOP)/vendor/autochips/proprietary/frameworks/base/avm/file/* $(TARGET_OUT_VENDOR)/avm
3306 $(call generate-image-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt,vendor,skip_fsck=true)
3307 PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
3308 $(BUILD_IMAGE) \
3309 $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt \
3310 $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
3311 $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET) $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
3312 endef
build_image
build/core/config.mk
635 BUILD_IMAGE := $(HOST_OUT_EXECUTABLES)/build_image$(HOST_EXECUTABLE_SUFFIX)
out/host/linux-x86/bin/build_image
Builds output_image from the given input_directory, properties_file,
and writes the image to target_output_directory.Usage: build_image input_directory properties_file output_image \target_output_directory
build_image.py
build/tools/releasetools/build_image.py
BuildImageMkfs
231 def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config):
232 """Builds a pure image for the files under in_dir and writes it to out_file.
233
234 Args:
235 in_dir: Path to input directory.
236 prop_dict: A property dict that contains info like partition size. Values
237 will be updated with computed values.
238 out_file: The output image file.
239 target_out: Path to the TARGET_OUT directory as in Makefile. It actually
240 points to the /system directory under PRODUCT_OUT. fs_config (the one
241 under system/core/libcutils) reads device specific FS config files from
242 there.
243 fs_config: The fs_config file that drives the prototype
244
245 Raises:
246 BuildImageError: On build image failures.
247 """
build_command
mkuserimg_mke2fs -s out/target/product/ac8257_64bit/vendor out/target/product/ac8257_64bit/vendor.img ext4 vendor 825540608 -j 0 -D out/target/product/ac8257_64bit/system -L vendor -M 0 --inode_size 256 out/target/product/ac8257_64bit/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin
mkuserimg_mke2fs.py
system/extras/ext4_utils/mkuserimg_mke2fs.py
mke2fs
Usage: mke2fs [-c|-l filename] [-b block-size] [-C cluster-size][-i bytes-per-inode] [-I inode-size] [-J journal-options][-G flex-group-size] [-N number-of-inodes] [-d root-directory][-m reserved-blocks-percentage] [-o creator-os][-g blocks-per-group] [-L volume-label] [-M last-mounted-directory][-O feature[,...]] [-r fs-revision] [-E extended-option[,...]][-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior][-z undo_file][-jnqvDFSV] device [blocks-count]
MKE2FS_CONFIG=out/soong/.temp/tmpGyRCz5mke2fs -O ^has_journal -L vendor -I 256 -M /vendor -m 0 -E android_sparse -t ext4 -b 4096 out/target/product/ac8257_64bit/vendor.img 201548
e2fsdroid
e2fsdroid -p out/target/product/ac8257_64bit/system -S out/target/product/ac8257_64bit/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin -f out/target/product/ac8257_64bit/vendor -a /vendor out/target/product/ac8257_64bit/vendor.img
file_contexts
obj/ETC/file_contexts.bin_intermediates
system/sepolicy/private/file_contexts
device/autochips/sepolicy/basic/plat_private/file_contexts
device/autochips/sepolicy/bsp/plat_private/file_contexts
SetUpInDirAndFsConfig
e2fsdroid源在何处
external/e2fsprogs/contrib/android/e2fsdroid.c
Usage
e2fsdroid [-B block_list] [-D basefs_out] [-T timestamp][-C fs_config] [-S file_contexts] [-p product_out][-a mountpoint] [-d basefs_in] [-f src_dir] [-e] [-s] image
android_configure_fs
326 errcode_t android_configure_fs(ext2_filsys fs, char *src_dir, char *target_out,
327 char *mountpoint,
328 struct selinux_opt *seopts EXT2FS_ATTR((unused)),
329 unsigned int nopt EXT2FS_ATTR((unused)),
330 char *fs_config_file, time_t fixed_time,
331 const struct ugid_map* uid_map,
332 const struct ugid_map* gid_map)
333 {359 /* Load the FS config */
360 if (fs_config_file) {
361 retval = load_canned_fs_config(fs_config_file);
362 if (retval < 0) {
363 com_err(__func__, retval,
364 _("while loading fs_config \"%s\""),
365 fs_config_file);
366 return retval;
367 }
368 fs_config_func = canned_fs_config;
369 } else if (mountpoint)
370 fs_config_func = fs_config;
371
372 return __android_configure_fs(fs, src_dir, target_out, mountpoint,
373 fs_config_func, sehnd, fixed_time,
374 uid_map, gid_map);
375 }
fs_config
system/core/libcutils/fs_config.cpp文件,fs_config函数根据android_dirs、android_files中的配置修改文件的uid、gui、mode(权限)。除了/vendor/bin/、/vendor/xbin/目录下的文件的有执行权限,/vendor目录下的其他文件都没有执行权限。
366 for (pc = dir ? android_dirs : android_files; pc->prefix; pc++) {
367 if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) {
368 break;
369 }
370 }
371 *uid = pc->uid;
372 *gid = pc->gid;
373 *mode = (*mode & (~07777)) | pc->mode;
374 *capabilities = pc->capabilities;
375 }
android_dirs
59 static const struct fs_path_config android_dirs[] = {60 // clang-format off61 { 00770, AID_SYSTEM, AID_CACHE, 0, "cache" },62 { 00555, AID_ROOT, AID_ROOT, 0, "config" },63 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" },64 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" },65 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral" },66 { 00771, AID_ROOT, AID_ROOT, 0, "data/dalvik-cache" },67 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/data" },68 { 00771, AID_SHELL, AID_SHELL, 0, "data/local/tmp" },69 { 00771, AID_SHELL, AID_SHELL, 0, "data/local" },70 { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" },71 { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" },72 { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" },73 { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },74 { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" },75 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest" },76 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64" },77 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest" },78 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest64" },79 { 00775, AID_ROOT, AID_ROOT, 0, "data/preloads" },80 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },81 { 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" },82 { 00751, AID_ROOT, AID_SHELL, 0, "product/bin" },83 { 00777, AID_ROOT, AID_ROOT, 0, "sdcard" },84 { 00751, AID_ROOT, AID_SDCARD_R, 0, "storage" },85 { 00751, AID_ROOT, AID_SHELL, 0, "system/bin" },86 { 00755, AID_ROOT, AID_ROOT, 0, "system/etc/ppp" },87 { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" },88 { 00751, AID_ROOT, AID_SHELL, 0, "system/xbin" },89 { 00751, AID_ROOT, AID_SHELL, 0, "system/apex/*/bin" },90 { 00751, AID_ROOT, AID_SHELL, 0, "system_ext/bin" },91 { 00751, AID_ROOT, AID_SHELL, 0, "system_ext/apex/*/bin" },92 { 00751, AID_ROOT, AID_SHELL, 0, "vendor/bin" },93 { 00755, AID_ROOT, AID_SHELL, 0, "vendor" },94 { 00755, AID_ROOT, AID_ROOT, 0, 0 },95 // clang-format on96 };
android_files
139 static const struct fs_path_config android_files[] = {
140 // clang-format off
141 { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
142 { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral/*" },
143 { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" },
144 { 00644, AID_APP, AID_APP, 0, "data/data/*" },
145 { 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" },
146 { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest/tests.txt" },
147 { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest64/tests.txt" },
148 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest/*" },
149 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64/*" },
150 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest/*" },
151 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest64/*" },
152 { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, // legacy
153 { 00600, AID_ROOT, AID_ROOT, 0, "system/etc/prop.default" },
154 { 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" }, // legacy; only for P release
155 { 00600, AID_ROOT, AID_ROOT, 0, "odm/default.prop" }, // legacy; only for P release
156 { 00600, AID_ROOT, AID_ROOT, 0, "odm/etc/build.prop" },
157 { 00444, AID_ROOT, AID_ROOT, 0, odm_conf_dir + 1 },
158 { 00444, AID_ROOT, AID_ROOT, 0, odm_conf_file + 1 },
159 { 00444, AID_ROOT, AID_ROOT, 0, oem_conf_dir + 1 },
160 { 00444, AID_ROOT, AID_ROOT, 0, oem_conf_file + 1 },
161 { 00600, AID_ROOT, AID_ROOT, 0, "product/build.prop" },
162 { 00444, AID_ROOT, AID_ROOT, 0, product_conf_dir + 1 },
163 { 00444, AID_ROOT, AID_ROOT, 0, product_conf_file + 1 },
164 { 00600, AID_ROOT, AID_ROOT, 0, "system_ext/build.prop" },
165 { 00444, AID_ROOT, AID_ROOT, 0, system_ext_conf_dir + 1 },
166 { 00444, AID_ROOT, AID_ROOT, 0, system_ext_conf_file + 1 },
167 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump32" },
168 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump64" },
169 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/debuggerd" },
170 { 00550, AID_LOGD, AID_LOGD, 0, "system/bin/logd" },
171 { 00700, AID_ROOT, AID_ROOT, 0, "system/bin/secilc" },
172 { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" },
173 { 00600, AID_ROOT, AID_ROOT, 0, "system/build.prop" },
174 { 00444, AID_ROOT, AID_ROOT, 0, sys_conf_dir + 1 },
175 { 00444, AID_ROOT, AID_ROOT, 0, sys_conf_file + 1 },
176 { 00440, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.rc" },
177 { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.sh" },
178 { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.ril" },
179 { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" },
180 { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" },
181 { 00750, AID_ROOT, AID_ROOT, 0, "vendor/bin/install-recovery.sh" },
182 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/build.prop" },
183 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/default.prop" },
184 { 00440, AID_ROOT, AID_ROOT, 0, "vendor/etc/recovery.img" },
185 { 00444, AID_ROOT, AID_ROOT, 0, ven_conf_dir + 1 },
186 { 00444, AID_ROOT, AID_ROOT, 0, ven_conf_file + 1 },
187
188 // the following two files are INTENTIONALLY set-uid, but they
189 // are NOT included on user builds.
190 { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
191 { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
192
193 // the following files have enhanced capabilities and ARE included
194 // in user builds.
195 { 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND),
196 "system/bin/inputflinger" },
197 { 00750, AID_ROOT, AID_SHELL, CAP_MASK_LONG(CAP_SETUID) |
198 CAP_MASK_LONG(CAP_SETGID),
199 "system/bin/run-as" },
200 { 00750, AID_ROOT, AID_SHELL, CAP_MASK_LONG(CAP_SETUID) |
201 CAP_MASK_LONG(CAP_SETGID),
202 "system/bin/simpleperf_app_runner" },
203 { 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/e2fsck" },
204 { 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/tune2fs" },
205 { 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/resize2fs" },
206 // generic defaults
207 { 00755, AID_ROOT, AID_ROOT, 0, "bin/*" },
208 { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" },
209 { 00750, AID_ROOT, AID_SHELL, 0, "init*" },
210 { 00755, AID_ROOT, AID_SHELL, 0, "odm/bin/*" },
211 { 00755, AID_ROOT, AID_SHELL, 0, "product/bin/*" },
212 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },
213 { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" },
214 { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/*/bin/*" },
215 { 00755, AID_ROOT, AID_SHELL, 0, "system_ext/bin/*" },
216 { 00755, AID_ROOT, AID_SHELL, 0, "system_ext/apex/*/bin/*" },
217 { 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" },
218 { 00755, AID_ROOT, AID_SHELL, 0, "vendor/xbin/*" },
219 { 00771, AID_ROOT, AID_SYSTEM, 0, "avm/*" },
220 { 00644, AID_ROOT, AID_ROOT, 0, 0 },
221 // clang-format on
222 };
如何调试
build_image.py
build/core
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -341,8 +341,12 @@ def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config):raise BuildImageError("Error: unknown filesystem type: {}".format(fs_type))+ if "vendor" == prop_dict["mount_point"]:
+ print("build_command: %s" % (build_command))try:mkfs_output = common.RunAndCheckOutput(build_command)
+ if "vendor" == prop_dict["mount_point"]:
+ print("mkfs_output: %s" % mkfs_output)except:try:du = GetDiskUsage(in_dir)
mkuserimg_mke2fs.py
system/extras
--- a/ext4_utils/mkuserimg_mke2fs.py
+++ b/ext4_utils/mkuserimg_mke2fs.py
@@ -223,6 +223,7 @@ def main(argv):if args.timestamp:mke2fs_env["E2FSPROGS_FAKE_TIME"] = args.timestamp+ print("mke2fs_cmd: %s, mke2fs_env: %s\n" % (mke2fs_cmd, mke2fs_env))output, ret = RunCommand(mke2fs_cmd, mke2fs_env)print(output)if ret != 0:
@@ -234,6 +235,7 @@ def main(argv):if args.timestamp:e2fsdroid_env["E2FSPROGS_FAKE_TIME"] = args.timestamp+ print("e2fsdroid_cmd: %s, e2fsdroid_env: %s\n" % (e2fsdroid_cmd, e2fsdroid_env))output, ret = RunCommand(e2fsdroid_cmd, e2fsdroid_env)# The build script is parsing the raw output of e2fsdroid; keep the pattern# unchanged for now.
fs_config.cpp
system/core
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -367,6 +367,7 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned*break;}}
+ printf("%s %s, prefix: %s %o\n", path, target_out_path, pc->prefix, pc->mode);*uid = pc->uid;*gid = pc->gid;*mode = (*mode & (~07777)) | pc->mode;
相关文章:
Android vendor.img中文件执行权问题
问题 Android 9、11往vendor.img增加文件,烧写到设备后发现增加的可执行文件没有执行权限。经过漫长查找,终于找到了问题的根源,谨以此篇献给哪些脚踏实地的人们。 根本原因 system/core/libcutils/fs_config.cpp文件,fs_confi…...
环境搭建--vscode
vscode官网下载合适版本 安装vscode插件 安装 MinGW 配置环境变量 把安装目录D:\mingw64 配置在用户的环境变量path里即可 选择用户环境变量path 点确定保存后开启cmd输入g,如提示no input files 则说明Mingw64 安装成功,如果提示g 不是内…...
30289_SC65XX功能机MMI开发笔记(ums9117)
建立窗口步骤: 引入图片资源 放入图片 然后跑make pprj new job8 可能会有bug,宏定义 还会有开关灯报错,看命令行注释掉 接着把ture改成false 然后命令行new一遍,编译一遍没报错后 把编译器的win文件删掉, 再跑一遍虚拟机命令行…...
IDEA工具下载、配置和Tomcat配置
1. IDEA工具下载、配置 1.1. IDEA工具下载 1.1.1. 下载方式一 官方地址下载 1.1.2. 下载方式二 官方地址下载:https://www.jetbrains.com/idea/ 1.1.3. 注册账户 官网地址:https://account.jetbrains.com/login 1.1.4. JetBrains官方账号注册…...
【10.2】队列-设计循环队列
一、题目 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普…...
多人-多agent协同可能会挑战维纳的反馈
在多人-多Agent协同系统中,维纳的经典反馈机制将面临新的挑战,而协同过程中的“算计”(策略性决策与协调)成为实现高效协作的核心。 1、非线性与动态性 维纳的反馈理论(尤其是在控制理论中)通常假设系统的动…...
JS 时间格式大全(含大量示例)
在 JS 中,处理时间和日期是常见的需求。无论是展示当前时间、格式化日期字符串,还是进行时间计算,JavaScript 都提供了丰富的 API 来满足这些需求。本文将详细介绍如何使用 JavaScript 生成各种时间格式,从基础到高级,…...
HarmonyOS简介:应用开发的机遇、挑战和趋势
问题 更多的智能设备并没有带来更好的全场景体验 连接步骤复杂数据难以互通生态无法共享能力难以协同 主要挑战 针对不同设备上的不同操作系统,重复开发,维护多套版本 多种语言栈,对人员技能要求高 多种开发框架,不同的编程…...
区间选点(贪心)
给定 NN 个闭区间 [ai,bi][ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第一行包含整数 NN,表示区间数。 接下来 NN 行,…...
深度学习|表示学习|卷积神经网络|输出维度公式|15
如是我闻: 在卷积和池化操作中,计算输出维度的公式是关键,它们分别可以帮助我们计算卷积操作和池化操作后的输出大小。下面分别总结公式,并结合解释它们的意义: 1. 卷积操作的输出维度公式 当我们对输入图像进行卷积时…...
Edge-TTS在广电系统中的语音合成技术的创新应用
Edge-TTS在广电系统中的语音合成技术的创新应用 作者:本人是一名县级融媒体中心的工程师,多年来一直坚持学习、提升自己。喜欢Python编程、人工智能、网络安全等多领域的技术。 摘要 随着人工智能技术的快速发展,文字转语音(Te…...
2025课题推荐——USBL与DVL数据融合的实时定位系统
准确的定位技术是现代海洋探测、海洋工程和水下机器人操作的基础。超短基线(USBL)和多普勒速度计(DVL)是常用的水下定位技术,但单一技术难以应对复杂环境。因此,USBL与DVL的数据融合以构建实时定位系统&…...
RK3588平台开发系列讲解(ARM篇)ARM64底层中断处理
文章目录 一、异常级别二、异常分类2.1、同步异常2.2、异步异常三、中断向量表沉淀、分享、成长,让自己和他人都能有所收获!😄 一、异常级别 ARM64处理器确实定义了4个异常级别(Exception Levels, EL),分别是EL0到EL3。这些级别用于管理处理器的特权级别和权限,级别越高…...
MyBatis最佳实践:提升数据库交互效率的秘密武器
第一章:框架的概述: MyBatis 框架的概述: MyBatis 是一个优秀的基于 Java 的持久框架,内部对 JDBC 做了封装,使开发者只需要关注 SQL 语句,而不关注 JDBC 的代码,使开发变得更加的简单MyBatis 通…...
Three.js实战项目02:vue3+three.js实现汽车展厅项目
文章目录 实战项目02项目预览项目创建初始化项目模型加载与展厅灯光加载汽车模型设置灯光材质设置完整项目下载实战项目02 项目预览 完整项目效果: 项目创建 创建项目: pnpm create vue安装包: pnpm add three@0.153.0 pnpm add gsap初始化项目 修改App.js代码&#x…...
CPP-存储区域
CPP支持手动开辟和释放内存,所以对于内存的理解非常重要! 在C中,内存存储通常可以大致分为几个区域,这些区域根据存储的数据类型、生命周期和作用域来划分。这些区域主要包括: 代码区(Code Segment/Text S…...
1月27(信息差)
🌍喜大普奔,适用于 VS Code 的 GitHub Copilot 全新免费版本正式推出,GitHub 全球开发者突破1.5亿 🎄Kimi深夜炸场:满血版多模态o1级推理模型!OpenAI外全球首次!Jim Fan:同天两款国…...
开发环境搭建-3:配置 nodejs 开发环境 (fnm+ node + pnpm)
在 WSL 环境中配置:WSL2 (2.3.26.0) Oracle Linux 8.7 官方镜像 node 官网:https://nodejs.org/zh-cn/download 点击【下载】,选择想要的 node 版本、操作系统、node 版本管理器、npm包管理器 根据下面代码提示依次执行对应代码即可 基本概…...
深入理解Pytest中的Setup和Teardown
关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 对于简单程序而言,使用 Pytest 运行测试直截了当。然而,当你…...
一个局域网通过NAT访问另一个地址重叠的局域网(IP方式访问)
正文共:1335 字 7 图,预估阅读时间:4 分钟 现在,我们已经可以通过调整两台设备的组合配置(地址重叠时,用户如何通过NAT访问对端IP网络?)或仅调整一台设备的配置(仅操作一…...
MongoDB中常用的几种高可用技术方案及优缺点
MongoDB 的高可用性方案主要依赖于其内置的 副本集 (Replica Set) 和 Sharding 机制。下面是一些常见的高可用性技术方案: 1. 副本集 (Replica Set) 副本集是 MongoDB 提供的主要高可用性解决方案,确保数据在多个节点之间的冗余存储和自动故障恢复。副…...
DeepSeek学术题目选择效果怎么样?
论文选题 一篇出色的论文背后,必定有一个“智慧的选题”在撑腰。选题足够好文章就能顺利登上高水平期刊;选题不行再精彩的写作也只能“当花瓶”。然而许多宝子们常常忽视这个环节,把大量时间花在写作上,选题时却像抓阄一样随便挑一…...
Lesson 119 A true story
Lesson 119 A true story 词汇 story n. 故事,传记,小说,楼层storey 搭配:tell a story 讲故事,说谎 true story 真实的故事 the second floor 二楼 例句:我猜他正在说谎。 I guess he…...
正反转电路梯形图
1、正转联锁控制。按下正转按钮SB1→梯形图程序中的正转触点X000闭合→线圈Y000得电→Y000自锁触点闭合,Y000联锁触点断开,Y0端子与COM端子间的内部硬触点闭合→Y000自锁触点闭合,使线圈Y000在X000触点断开后仍可得电。 Y000联锁触点断开&…...
Java并发学习:进程与线程的区别
进程的基本原理 一个进程是一个程序的一次启动和执行,是操作系统程序装入内存,给程序分配必要的系统资源,并且开始运行程序的指令。 同一个程序可以多次启动,对应多个进程,例如同一个浏览器打开多次。 一个进程由程…...
解锁罗技键盘新技能:轻松锁定功能键(罗技K580)
在使用罗技键盘的过程中,你是否曾因 F11、F12 功能键的默认设置与实际需求不符而感到困扰? 别担心,今天就为大家分享一个简单实用的小技巧 —— 锁定罗技键盘的 F11、F12 功能键,让你的操作更加得心应手! 通常情况下…...
分布式微服务系统架构第88集:kafka集群
使用集 群最大的好处是可以跨服务器进行负载均衡,再则就是可以使用复制功能来避免因单点故 障造成的数据丢失。在维护 Kafka 或底层系统时,使用集群可以确保为客户端提供高可用 性。 需要多少个broker 一个 Kafka 集群需要多少个 broker 取决于以下几个因…...
ESP32-S3模组上跑通esp32-camera(33)
接前一篇文章:ESP32-S3模组上跑通esp32-camera(32) 一、OV5640初始化 2. 相机初始化及图像传感器配置 上一回开始解析camera_probe函数的第8段即最后一段代码,本回继续解析该段代码。为了便于理解和回顾,再次贴出camera_probe函数源码,在components/esp32-camera/drive…...
一次端口监听正常,tcpdump无法监听到指定端口报文问题分析
tcpdump命令: sudo tcpdump -i ens2f0 port 6471 -XXnnvvv 下面是各个部分的详细解释: 1.tcpdump: 这是用于捕获和分析网络数据包的命令行工具。 2.-i ens2f0: 指定监听的网络接口。ens2f0 表示本地网卡),即计算机该指定网络接口捕…...
高可用集群故障之join
本文记录了在部署高可用的k8s集群时,遇到的一个故障及其解决方法。 集群环境 描述:三主三从,eth0为外网网卡,eth1为内网网卡,内网互通。 需求:eth0只负责访问外网,eth1作为集群间的通信。 主…...
