@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