最近在做移植Samba服务到嵌入式设备中,在移植的过程中出现如下问题:
tdb(unnamed): tdb_brlock failed (fd=4) at offset 0 rw_type=1 lck_type=14 len=1
tdb(unnamed): tdb_open_ex: failed to get global lock on /usr/local/samba/var/locks/messages.tdb: Permission denied
ERROR: Failed to initialise messages database: Permission denied
messaging_tdb_init failed: NT_STATUS_ACCESS_DENIED
Could not init smbd messaging context.
经过各种权限设置都不能解决,之后通过排查发现是使用fcntl()设置F_SETLKW写入锁造成的,在网上搜索到以下程序进行测试,问题得以重现:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int lock_reg(int fd, int cmd, short lock_type, short lock_whence, off_t lock_start, off_t lock_len)
{
struct flock lock;
lock.l_type = lock_type;
lock.l_whence = lock_whence;
lock.l_start = lock_start;
lock.l_len = lock_len;
lock.l_pid = getpid();
if (fcntl(fd, cmd, &lock) < 0) {
if (errno == EACCES || errno == EAGAIN ) {
printf("file lock by other processes: %s\n", strerror(errno));
while(1);
return -1;
}
printf("lock file fail.\n");
return -1;
}
if (lock_type == F_WRLCK) {
printf("lock by %d.\n", getpid());
} else if (lock_type == F_UNLCK) {
printf("unlock by %d.\n", getpid());
}
return 0;
}
int reg_lock(int fd)
{
return lock_reg(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0);
}
int reg_unlock(int fd)
{
return lock_reg(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0);
}
int reg_lockw(int fd)
{
return lock_reg(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0);
}
int reg_unlockw(int fd)
{
return lock_reg(fd, F_SETLKW, F_UNLCK, 0, SEEK_SET, 0);
}
int main(int argv, char *argc[])
{
char *buf;
int i;
int ret;
int fd;
if (argv < 2) {
printf("argc error!\n");
return -1;
}
fd = open("processes.txt", O_CREAT|O_RDWR|O_APPEND, 777);
ret = reg_lockw(fd);
if (ret !=0 ) {
return -1;
}
sleep(5);
buf = argc[1];
i = 0;
while (i < strlen(buf)) {
if (write(fd, buf+i, sizeof(char)) < sizeof(char)) {
printf("printf out error!\n");
return -1;
}
printf(" %c:out by pid %d.\n", buf[i], getpid());
i++;
sleep(1);
}
ret = reg_unlockw(fd);
if (ret !=0 ) {
return -1;
}
close(fd);
return 0;
}
问题虽然找到了,但怎么解决却没有思路,猜想可能是文件系统或者内核设置造成的,如有人也遇到过同样的问题并解决成功,还望赐教。
Linux内核版本:4.19.91
文件系统:
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 126908 0 126908 0% /dev
tmpfs 126908 3012 123896 2% /tmp
tmpfs 126908 12 126896 0% /var/run
/dev/ubi0_0 27980 19792 8188 71% /lib/modules
/dev/ubi0_0 27980 19792 8188 71% /usr/bin
/dev/ubi0_0 27980 19792 8188 71% /usr/lib
/dev/ubi1_0 40828 19472 21356 48% /mnt/app
/dev/mmcblk0p1 31166464 29193472 1972992 94% /mnt/sd
mount信息:
rootfs on / type rootfs (rw)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
tmpfs on /var/run type tmpfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
/dev/ubi0_0 on /lib/modules type ubifs (rw,relatime,assert=read-only,ubi=0,vol=0)
/dev/ubi0_0 on /usr/bin type ubifs (rw,relatime,assert=read-only,ubi=0,vol=0)
/dev/ubi0_0 on /usr/lib type ubifs (rw,relatime,assert=read-only,ubi=0,vol=0)
/dev/ubi1_0 on /mnt/app type ubifs (rw,relatime,assert=read-only,ubi=1,vol=0)
/dev/mmcblk0p1 on /mnt/sd type vfat (rw,dirsync,relatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,tz=UTC,errors=remount-ro)