文件访问被锁阻止 - 如何删除?

文件访问被锁阻止 - 如何删除?

我正在尝试在其创建的备份存储库之一上运行备份程序“restic”的“检查”功能。无论我做什么,它都会由于致命的“已锁定”问题而崩溃。以下是相关的命令行 I/O:

tomc@ANB:~/programs/restic-backup$ ./restic check -r
/media/tomc/usbhd4-p2/_restic-bkup/dropbox using temporary cache in /tmp/restic-check-cache-405001323 
enter password for repository:
repository fd5c0b03 opened successfully, password is correct 
created new cache in /tmp/restic-check-cache-405001323 
create exclusive lock for repository 
Fatal: unable to create lock in backend: repository is already locked by PID 30546 on ANB by tomc (UID 1000, GID 1000) 
lock was created at 2019-10-07 14:49:41 (509h0m19.239359465s ago) storage ID 0fe63838 

我可以做什么来解决这个问题?

答案1

repository is already locked by PID 30546 on ANB by tomc

您应该首先ps -fp 30546查看锁定存储库的进程是否仍然存在。由于根据错误消息,锁已经是 509h 了,因此该进程可能会挂起,或者如果该进程不存在或看起来完全不相关,则它可能是一个过时的锁文件。

如果 PID 30546 的进程看起来相关,您可以使用它lsof -p 30546来查看它打开了哪些文件。幸运的是,其中一个文件可能是日志文件,它可以提供有关进程状态的更多信息。如果中断看起来是安全的,您可以kill 30546尝试相对较好地停止它,使其有机会在退出时清理其锁定文件。

如果进程拒绝使用命令终止kill 30546,您可以使用kill -9 30546强制它停止,但在这种情况下,您肯定需要采取进一步的步骤来清除锁定。

根据GitHub 页面中的问题 #1450restic,在终止挂起的进程后,您可以使用此命令来清除陈旧的锁:

./restic unlock -r /media/tomc/usbhd4-p2/_restic-bkup/dropbox 

如果挂起的进程正在执行某些备份操作,您可能还需要执行以下命令:

./restic check -r /media/tomc/usbhd4-p2/_restic-bkup/dropbox 

# if the check returns "not referenced in any index" errors, then do this:
./restic rebuild-index -r /media/tomc/usbhd4-p2/_restic-bkup/dropbox 
./restic check -r /media/tomc/usbhd4-p2/_restic-bkup/dropbox 

# if there is still "not referenced in any index" errors, remove incomplete packs:
./restic prune -r /media/tomc/usbhd4-p2/_restic-bkup/dropbox 
./restic check -r /media/tomc/usbhd4-p2/_restic-bkup/dropbox 

此后,检查应该顺利通过。

答案2

这个答案有点特定于 Linux,但这个概念适用于任何 POSIX 系统:

首先弄清楚哪个进程实际上是保持锁,通常这是一个进程不是被锁挡住了。这将列出保持文件打开的进程:

lsof /path/to/lockfile

然后获取文件描述符并解锁:

# ls -l /proc/<pid>/fd
[... make a note of the file descriptor you care about and substitute <fd> below]
# gdb -p <pid>
gdb> call flock(<fd>, 8)

以上,8来自LOCK_UNfile.h

如果flock不起作用,那么您也可以尝试关闭文件描述符,但这可能会带来副作用,并且程序可能会中止,具体取决于其编写方式:

gdb> call close(<fd>)

完成后gdb让程序继续detach

gdb> detach

相关内容