diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-02-03 13:21:12 -0500 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2013-02-08 12:28:04 -0500 |
commit | bdf8647c44766590ed02f9a84a450a796558b753 (patch) | |
tree | fb3510335d4c1ce67e109df2f80eb26c67d8b589 /include | |
parent | f22c1bb6b4706be3502b378cb14564449b15f983 (diff) |
uprobes: Introduce uprobe_apply()
Currently it is not possible to change the filtering constraints after
uprobe_register(), so a consumer can not, say, start to trace a task/mm
which was previously filtered out, or remove the no longer needed bp's.
Introduce uprobe_apply() which simply does register_for_each_vma() again
to consult uprobe_consumer->filter() and install/remove the breakpoints.
The only complication is that register_for_each_vma() can no longer
assume that uprobe->consumers should be consulter if is_register == T,
so we change it to accept "struct uprobe_consumer *new" instead.
Unlike uprobe_register(), uprobe_apply(true) doesn't do "unregister" if
register_for_each_vma() fails, it is up to caller to handle the error.
Note: we probably need to cleanup the current interface, it is strange
that uprobe_apply/unregister need inode/offset. We should either change
uprobe_register() to return "struct uprobe *", or add a private ->uprobe
member in uprobe_consumer. And in the long term uprobe_apply() should
take a single argument, uprobe or consumer, even "bool add" should go
away.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/uprobes.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 95d0002efda5..02b83db8e2c5 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h | |||
@@ -101,6 +101,7 @@ extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsign | |||
101 | extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); | 101 | extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); |
102 | extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); | 102 | extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); |
103 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 103 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
104 | extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); | ||
104 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 105 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
105 | extern int uprobe_mmap(struct vm_area_struct *vma); | 106 | extern int uprobe_mmap(struct vm_area_struct *vma); |
106 | extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); | 107 | extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); |
@@ -124,6 +125,11 @@ uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) | |||
124 | { | 125 | { |
125 | return -ENOSYS; | 126 | return -ENOSYS; |
126 | } | 127 | } |
128 | static inline int | ||
129 | uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) | ||
130 | { | ||
131 | return -ENOSYS; | ||
132 | } | ||
127 | static inline void | 133 | static inline void |
128 | uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) | 134 | uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) |
129 | { | 135 | { |