V851S Tina 5.0 SDK 无法使用文件锁的问题
-
起初是为了分析 opkg 工具用不了的问题:
root@TinaLinux:/# opkg list Collected errors: * opkg_conf_load: Could not lock /var/lock/opkg.lock: Permission denied.
通过分析其系统调用链,发现 opkg 试图设置文件锁失败了:
root@TinaLinux:/# strace opkg list execve("/bin/opkg", ["opkg", "list"], 0xbef8ad04 /* 21 vars */) = 0 set_tls(0xb6f555d8) = 0 set_tid_address(0xb6f5618c) = 1120 open("/usr/lib/eyesee-mpp/libubox.so.20210516", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/eyesee-mpp/libubox.so.20210516", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/etc/ld-musl-armhf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/libubox.so.20210516", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=38084, ...}) = 0 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\244!\0\0004\0\0\0"..., 936) = 936 mmap2(NULL, 106496, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xb6ec0000 mmap2(0xb6ed8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x8000) = 0xb6ed8000 close(3) = 0 mprotect(0xb6ed8000, 4096, PROT_READ) = 0 mprotect(0x3e000, 4096, PROT_READ) = 0 stat64("/etc/opkg.conf", {st_mode=S_IFREG|0644, st_size=85, ...}) = 0 open("/etc/opkg.conf", O_RDONLY|O_LARGEFILE) = 3 brk(NULL) = 0xd97000 brk(0xd98000) = 0xd98000 brk(0xd99000) = 0xd99000 brk(0xd9a000) = 0xd9a000 brk(0xd9b000) = 0xd9b000 brk(0xd9c000) = 0xd9c000 brk(0xd9d000) = 0xd9d000 brk(0xd9f000) = 0xd9f000 brk(0xda0000) = 0xda0000 read(3, "dest root /\ndest ram /tmp\nlists_"..., 1024) = 85 read(3, "", 1024) = 0 close(3) = 0 open("/etc/opkg/", O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 getdents64(3, 0xb6ed9378 /* 4 entries */, 2048) = 112 getdents64(3, 0xb6ed9378 /* 0 entries */, 2048) = 0 close(3) = 0 open("/etc/opkg/customfeeds.conf", O_RDONLY|O_LARGEFILE) = 3 read(3, "# add your custom package feeds "..., 1024) = 103 read(3, "", 1024) = 0 close(3) = 0 open("/var/lock/opkg.lock", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0640) = 3 fcntl64(3, F_SETLK64, {l_type=F_WRLCK, l_whence=SEEK_CUR, l_start=0, l_len=0}) = -1 EACCES (Permission denied) close(3) = 0 writev(2, [{iov_base="", iov_len=0}, {iov_base="Collected errors:\n", iov_len=18}], 2Collected errors: ) = 18 writev(2, [{iov_base=" * opkg_conf_load: Could not loc"..., iov_len=75}, {iov_base=NULL, iov_len=0}], 2 * opkg_conf_load: Could not lock /var/lock/opkg.lock: Permission denied. ) = 75 exit_group(-1) = ? +++ exited with 255 +++
然后自己写一个测试程序,确实会失败:
root@TinaLinux:/tmp# strace ./test execve("./test", ["./test"], 0xbeb32d00 /* 22 vars */) = 0 set_tls(0xb6f9c5d8) = 0 set_tid_address(0xb6f9d18c) = 1133 open("/usr/lib/eyesee-mpp/libstdc++.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/eyesee-mpp/libstdc++.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/etc/ld-musl-armhf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/libstdc++.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fstat64(3, {st_mode=S_IFREG|0775, st_size=976512, ...}) = 0 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\340\2\7\0004\0\0\0"..., 936) = 936 mmap2(NULL, 1048576, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xb6e21000 mmap2(0xb6f18000, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xe7000) = 0xb6f18000 mmap2(0xb6f20000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6f20000 close(3) = 0 open("/usr/lib/eyesee-mpp/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/eyesee-mpp/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fstat64(3, {st_mode=S_IFREG|0664, st_size=38356, ...}) = 0 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\230'\0\0004\0\0\0"..., 936) = 936 mmap2(NULL, 106496, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xb6e07000 mmap2(0xb6e1f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x8000) = 0xb6e1f000 close(3) = 0 mprotect(0xb6f18000, 20480, PROT_READ) = 0 mprotect(0xb6e1f000, 4096, PROT_READ) = 0 mprotect(0x20000, 4096, PROT_READ) = 0 brk(NULL) = 0xc2f000 brk(0xc34000) = 0xc34000 open("/tmp/opkg.lock", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0644) = 3 fcntl64(3, F_SETLK64, {l_type=F_WRLCK, l_whence=SEEK_CUR, l_start=0, l_len=0}) = -1 EACCES (Permission denied) ioctl(1, TIOCGWINSZ, {ws_row=0, ws_col=0, ws_xpixel=0, ws_ypixel=0}) = 0 writev(1, [{iov_base="fd:[3] rc:[-1", iov_len=13}, {iov_base="]\n", iov_len=2}], 2fd:[3] rc:[-1] ) = 15 close(3) = 0 exit_group(0) = ? +++ exited with 0 +++
在 ubuntu 上测试实例代码是可以上锁的,说明用法没问题:
ubuntu@ubuntu1804:~/work/v85x-tina-open/openwrt/package/dream/test/src$ g++ -o main main.cpp ubuntu@ubuntu1804:~/work/v85x-tina-open/openwrt/package/dream/test/src$ ubuntu@ubuntu1804:~/work/v85x-tina-open/openwrt/package/dream/test/src$ ./main fd:[3] rc:[0] ubuntu@ubuntu1804:~/work/v85x-tina-open/openwrt/package/dream/test/src$
请问各位大佬,有谁知道是咋回事吗?(附文件系统类型)
root@TinaLinux:/tmp# df -Th Filesystem Type Size Used Available Use% Mounted on /dev/root squashfs 12.0M 12.0M 0 100% /rom devtmpfs devtmpfs 23.8M 0 23.8M 0% /dev tmpfs tmpfs 25.0M 16.0K 25.0M 0% /tmp /dev/by-name/UDISK ubifs 10.4M 36.0K 9.8M 0% /mnt/UDISK overlayfs:/mnt/UDISK/overlay overlay 10.4M 36.0K 9.8M 0% / tmpfs tmpfs 25.0M 0 25.0M 0% /run
-
Tina的SDK,确实是有点问题,之前遇到过hexdump触摸evnet导致失败,在D1s下面又没有这个问题
-
@dream 同步最新的信息, 已经使用了 mutex 的方式,替换文件锁,可以解决 opkg remove 和 opkg list 等指令不能正常使用的问题,目前 opkg install 会出现段错误。
原以为解决了文件锁,就能解决 opkg 不能使用的问题,没想到只解决了一半
*** libopkg\opkg_conf.c 2022-02-25 04:27:58.000000000 +0800 --- libopkg\opkg_conf.c 2024-03-03 14:20:36.000000000 +0800 *************** *** 19,30 **** --- 19,31 ---- #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <glob.h> #include <unistd.h> + #include <sys/mman.h> #include "opkg_conf.h" #include "pkg_vec.h" #include "pkg.h" #include "xregex.h" #include "sprintf_alloc.h" *************** *** 423,436 **** --- 424,452 ---- int opkg_conf_init(void) { pkg_src_list_init(&conf->pkg_src_list); pkg_dest_list_init(&conf->pkg_dest_list); pkg_dest_list_init(&conf->tmp_dest_list); nv_pair_list_init(&conf->arch_list); + + conf->mlock = mmap(NULL, sizeof(struct mt_lock), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); + memset(conf->mlock, 0, sizeof(struct mt_lock)); + pthread_mutexattr_init(&conf->mlock->mutexattr); + pthread_mutexattr_setpshared(&conf->mlock->mutexattr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&conf->mlock->mutex, &conf->mlock->mutexattr); return 0; + } + + static int my_lockf(int fd, int cmd, off_t len) + { + switch(cmd){ + case F_TLOCK: return pthread_mutex_trylock(&conf->mlock->mutex); + case F_ULOCK: return pthread_mutex_unlock(&conf->mlock->mutex); + } + return -22; } int opkg_conf_load(void) { int i, glob_ret; char *tmp, *tmp_dir_base, **tmp_val; *************** *** 498,510 **** lock_fd = creat(lock_file, S_IRUSR | S_IWUSR | S_IRGRP); if (lock_fd == -1) { opkg_perror(ERROR, "Could not create lock file %s", lock_file); goto err2; } ! if (lockf(lock_fd, F_TLOCK, (off_t) 0) == -1) { opkg_perror(ERROR, "Could not lock %s", lock_file); if (close(lock_fd) == -1) opkg_perror(ERROR, "Couldn't close descriptor %d (%s)", lock_fd, lock_file); lock_fd = -1; goto err2; --- 514,526 ---- lock_fd = creat(lock_file, S_IRUSR | S_IWUSR | S_IRGRP); if (lock_fd == -1) { opkg_perror(ERROR, "Could not create lock file %s", lock_file); goto err2; } ! if (my_lockf(lock_fd, F_TLOCK, (off_t) 0) == -1) { opkg_perror(ERROR, "Could not lock %s", lock_file); if (close(lock_fd) == -1) opkg_perror(ERROR, "Couldn't close descriptor %d (%s)", lock_fd, lock_file); lock_fd = -1; goto err2; *************** *** 573,585 **** hash_table_deinit(&conf->file_hash); hash_table_deinit(&conf->obs_file_hash); if (rmdir(conf->tmp_dir) == -1) opkg_perror(ERROR, "Couldn't remove dir %s", conf->tmp_dir); err3: ! if (lockf(lock_fd, F_ULOCK, (off_t) 0) == -1) opkg_perror(ERROR, "Couldn't unlock %s", lock_file); if (close(lock_fd) == -1) opkg_perror(ERROR, "Couldn't close descriptor %d (%s)", lock_fd, lock_file); if (unlink(lock_file) == -1) --- 589,601 ---- hash_table_deinit(&conf->file_hash); hash_table_deinit(&conf->obs_file_hash); if (rmdir(conf->tmp_dir) == -1) opkg_perror(ERROR, "Couldn't remove dir %s", conf->tmp_dir); err3: ! if (my_lockf(lock_fd, F_ULOCK, (off_t) 0) == -1) opkg_perror(ERROR, "Couldn't unlock %s", lock_file); if (close(lock_fd) == -1) opkg_perror(ERROR, "Couldn't close descriptor %d (%s)", lock_fd, lock_file); if (unlink(lock_file) == -1) *************** *** 652,664 **** pkg_hash_deinit(); hash_table_deinit(&conf->file_hash); hash_table_deinit(&conf->obs_file_hash); if (lock_fd != -1) { ! if (lockf(lock_fd, F_ULOCK, (off_t) 0) == -1) opkg_perror(ERROR, "Couldn't unlock %s", lock_file); if (close(lock_fd) == -1) opkg_perror(ERROR, "Couldn't close descriptor %d (%s)", lock_fd, lock_file); --- 668,680 ---- pkg_hash_deinit(); hash_table_deinit(&conf->file_hash); hash_table_deinit(&conf->obs_file_hash); if (lock_fd != -1) { ! if (my_lockf(lock_fd, F_ULOCK, (off_t) 0) == -1) opkg_perror(ERROR, "Couldn't unlock %s", lock_file); if (close(lock_fd) == -1) opkg_perror(ERROR, "Couldn't close descriptor %d (%s)", lock_fd, lock_file); *** libopkg\opkg_conf.h 2022-02-25 04:27:58.000000000 +0800 --- libopkg\opkg_conf.h 2024-03-03 14:20:05.000000000 +0800 *************** *** 20,31 **** --- 20,32 ---- typedef struct opkg_conf opkg_conf_t; extern opkg_conf_t *conf; #include <stdarg.h> #include <fnmatch.h> /* FNM_CASEFOLD */ + #include <pthread.h> #include "hash_table.h" #include "pkg_src_list.h" #include "pkg_dest_list.h" #include "nv_pair_list.h" *************** *** 39,50 **** --- 40,56 ---- /* In case the config file defines no dest */ #define OPKG_CONF_DEFAULT_DEST_NAME "root" #define OPKG_CONF_DEFAULT_DEST_ROOT_DIR "/" #define OPKG_CONF_DEFAULT_HASH_LEN 1024 + + struct mt_lock { + pthread_mutex_t mutex; + pthread_mutexattr_t mutexattr; + }; struct opkg_conf { pkg_src_list_t pkg_src_list; pkg_dest_list_t pkg_dest_list; pkg_dest_list_t tmp_dest_list; nv_pair_list_t arch_list; *************** *** 105,116 **** --- 111,125 ---- char *signature_ca_file; char *signature_ca_path; hash_table_t pkg_hash; hash_table_t file_hash; hash_table_t obs_file_hash; + + // replace file lock + struct mt_lock *mlock; }; enum opkg_option_type { OPKG_OPT_TYPE_BOOL, OPKG_OPT_TYPE_INT, OPKG_OPT_TYPE_STRING
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号