@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