mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
crtools: restore flock&posix file locks
According to the file lock information from the image, we recall flock or fcntl with proper parameters, so we can rehold the file locks as we were dumped. We only support flock and posix file locks so far. Changelog since the initial version: a. Use prepare_file_locks instead of restore function directly. b. Fix some bugs. Originally-signed-off-by: Zheng Gu <cengku.gu@huawei.com> Signed-off-by: Qiang Huang <h.huangqiang@huawei.com> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
95801808aa
commit
4bf96b6680
@ -55,6 +55,7 @@
|
||||
#include "tty.h"
|
||||
#include "cpu.h"
|
||||
#include "fpu.h"
|
||||
#include "file-lock.h"
|
||||
|
||||
#include "protobuf.h"
|
||||
#include "protobuf/sa.pb-c.h"
|
||||
@ -599,6 +600,9 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
|
||||
if (prepare_fs(pid))
|
||||
return -1;
|
||||
|
||||
if (prepare_file_locks(pid))
|
||||
return -1;
|
||||
|
||||
if (prepare_sigactions(pid))
|
||||
return -1;
|
||||
|
||||
|
102
file-lock.c
102
file-lock.c
@ -1,5 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "file-lock.h"
|
||||
|
||||
@ -37,3 +40,102 @@ int dump_one_file_lock(FileLockEntry *fle, const struct cr_fdset *fdset)
|
||||
return pb_write_one(fdset_fd(fdset, CR_FD_FILE_LOCKS),
|
||||
fle, PB_FILE_LOCK);
|
||||
}
|
||||
|
||||
static int restore_file_lock(FileLockEntry *fle)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned int cmd;
|
||||
|
||||
if (fle->flag & FL_FLOCK) {
|
||||
if (fle->type & LOCK_MAND) {
|
||||
cmd = fle->type;
|
||||
} else if (fle->type == F_RDLCK) {
|
||||
cmd = LOCK_SH;
|
||||
} else if (fle->type == F_WRLCK) {
|
||||
cmd = LOCK_EX;
|
||||
} else if (fle->type == F_UNLCK) {
|
||||
cmd = LOCK_UN;
|
||||
} else {
|
||||
pr_err("Unknow flock type!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
pr_info("(flock)flag: %d, type: %d, cmd: %d, pid: %d, fd: %d\n",
|
||||
fle->flag, fle->type, cmd, fle->pid, fle->fd);
|
||||
|
||||
ret = flock(fle->fd, cmd);
|
||||
if (ret < 0) {
|
||||
pr_err("Can not set flock!\n");
|
||||
goto err;
|
||||
}
|
||||
} else if (fle->flag & FL_POSIX) {
|
||||
struct flock flk;
|
||||
memset(&flk, 0, sizeof(flk));
|
||||
|
||||
flk.l_whence = SEEK_SET;
|
||||
flk.l_start = fle->start;
|
||||
flk.l_len = fle->len;
|
||||
flk.l_pid = fle->pid;
|
||||
flk.l_type = fle->type;
|
||||
|
||||
pr_info("(posix)flag: %d, type: %d, pid: %d, fd: %d, "
|
||||
"start: %8lx, len: %8lx\n",
|
||||
fle->flag, fle->type, fle->pid, fle->fd,
|
||||
fle->start, fle->len);
|
||||
|
||||
ret = fcntl(fle->fd, F_SETLKW, &flk);
|
||||
if (ret < 0) {
|
||||
pr_err("Can not set posix lock!\n");
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
pr_err("Unknow file lock style!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int restore_file_locks(int pid)
|
||||
{
|
||||
int fd, ret = -1;
|
||||
FileLockEntry *fle;
|
||||
|
||||
fd = open_image_ro(CR_FD_FILE_LOCKS, pid);
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ret = pb_read_one_eof(fd, &fle, PB_FILE_LOCK);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
ret = restore_file_lock(fle);
|
||||
file_lock_entry__free_unpacked(fle, NULL);
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
close_safe(&fd);
|
||||
return 0;
|
||||
err:
|
||||
close_safe(&fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int prepare_file_locks(int pid)
|
||||
{
|
||||
if (!opts.handle_file_locks)
|
||||
return 0;
|
||||
|
||||
pr_info("Restore file locks.\n");
|
||||
|
||||
return restore_file_locks(pid);
|
||||
}
|
||||
|
@ -16,6 +16,12 @@
|
||||
#endif
|
||||
|
||||
/* operations for bsd flock(), also used by the kernel implementation */
|
||||
#define LOCK_SH 1 /* shared lock */
|
||||
#define LOCK_EX 2 /* exclusive lock */
|
||||
#define LOCK_NB 4 /* or'd with one of the above to prevent
|
||||
blocking */
|
||||
#define LOCK_UN 8 /* remove lock */
|
||||
|
||||
#define LOCK_MAND 32 /* This is a mandatory flock ... */
|
||||
#define LOCK_READ 64 /* which allows concurrent read operations */
|
||||
#define LOCK_WRITE 128 /* which allows concurrent write operations */
|
||||
@ -42,4 +48,6 @@ extern struct file_lock *alloc_file_lock(void);
|
||||
extern void free_file_locks(void);
|
||||
extern int dump_one_file_lock(FileLockEntry *fle, const struct cr_fdset *fdset);
|
||||
|
||||
extern int prepare_file_locks(int pid);
|
||||
|
||||
#endif /* __FILE_LOCK_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user