diff --git a/file-lock.c b/file-lock.c index 377c7eb7a..8e4e48192 100644 --- a/file-lock.c +++ b/file-lock.c @@ -10,6 +10,7 @@ #include "imgset.h" #include "files.h" #include "fs-magic.h" +#include "kerndat.h" #include "image.h" #include "mount.h" #include "proc_parse.h" @@ -209,6 +210,9 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p) struct file_lock *fl; int ret; + if (kdat.has_fdinfo_lock) + return 0; + list_for_each_entry(fl, &file_lock_list, list) { ret = lock_file_match(pid->real, fd, fl, p); if (ret < 0) diff --git a/files.c b/files.c index dfb9a64b9..0f7f10756 100644 --- a/files.c +++ b/files.c @@ -213,7 +213,7 @@ static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd, { int ret; struct statfs fsbuf; - struct fdinfo_common fdinfo = { .mnt_id = -1 }; + struct fdinfo_common fdinfo = { .mnt_id = -1, .owner = ctl->pid.virt }; if (fstat(lfd, &p->stat) < 0) { pr_perror("Can't stat fd %d", lfd); @@ -225,7 +225,7 @@ static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd, return -1; } - if (parse_fdinfo(lfd, FD_TYPES__UND, NULL, &fdinfo)) + if (parse_fdinfo_pid(ctl->pid.real, fd, FD_TYPES__UND, NULL, &fdinfo)) return -1; p->fs_type = fsbuf.f_type; diff --git a/include/proc_parse.h b/include/proc_parse.h index e5d59d2bd..ebb53511d 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -199,6 +199,7 @@ struct fdinfo_common { off64_t pos; int flags; int mnt_id; + int owner; }; extern int parse_fdinfo(int fd, int type, diff --git a/proc_parse.c b/proc_parse.c index 14ef589af..fad405533 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -1233,6 +1233,8 @@ nodata: #define fdinfo_field(str, field) !strncmp(str, field":", sizeof(field)) +static int parse_file_lock_buf(char *buf, struct file_lock *fl, + bool is_blocked); static int parse_fdinfo_pid_s(int pid, int fd, int type, int (*cb)(union fdinfo_entries *e, void *arg), void *arg) { @@ -1282,6 +1284,41 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, continue; } + if (fdinfo_field(str, "lock")) { + struct file_lock *fl; + struct fdinfo_common *fdinfo = arg; + + if (type != FD_TYPES__UND) + continue; + + fl = alloc_file_lock(); + if (!fl) { + pr_perror("Alloc file lock failed!"); + goto out; + } + + if (parse_file_lock_buf(str + 6, fl, 0)) { + xfree(fl); + goto parse_err; + } + + pr_info("lockinfo: %lld:%d %x %d %02x:%02x:%ld %lld %s\n", + fl->fl_id, fl->fl_kind, fl->fl_ltype, + fl->fl_owner, fl->maj, fl->min, fl->i_no, + fl->start, fl->end); + + + if (fl->fl_kind == FL_UNKNOWN) { + pr_err("Unknown file lock!\n"); + xfree(fl); + goto out; + } + + fl->real_owner = fdinfo->owner; + fl->owners_fd = fd; + list_add_tail(&fl->list, &file_lock_list); + } + if (type == FD_TYPES__UND) continue; @@ -1601,6 +1638,9 @@ int parse_file_locks(void) int exit_code = -1; bool is_blocked; + if (kdat.has_fdinfo_lock) + return 0; + fl_locks = fopen_proc(PROC_GEN, "locks"); if (!fl_locks) { pr_perror("Can't open file locks file!");