Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add path() call #29

Closed
brendangregg opened this issue Sep 1, 2018 · 10 comments
Closed

add path() call #29

brendangregg opened this issue Sep 1, 2018 · 10 comments
Labels
enhancement New feature or request, changes on existing features kernel Issue may require kernel work

Comments

@brendangregg
Copy link
Contributor

prototype:

char *path(struct file *file)

So that this would work:

bpftrace -e 'kprobe:vfs_read { printf("reading path: %s\n", path(arg0)); }'

(or trace kprobe:__vfs_read) and it would print the full path.

For this to work, it may require a new BPF function added to the kernel to make this sane.

@brendangregg brendangregg added the kernel Issue may require kernel work label Sep 1, 2018
@fntlnz
Copy link

fntlnz commented Nov 26, 2018

This is ultimately useful @brendangregg , I was trying to access vfs_write using an inline struct but doesn't seem to be possible to print the full path right now

#include <linux/path.h>
#include <linux/dcache.h>

struct file {
	struct path *f_path;
}


kprobe:vfs_write
{
  $file = (file *)arg0;
  $file_name = str($file->f_path->dentry->d_name.name);
  printf("written file: %s", $file_name)
}

@tyroguru
Copy link
Contributor

@fntlnz - a path() call to print the absolute path of a file would be fantastic. You actually raise something here that I'm looking at now. The `vfs_{read()/write()' calls take a 'struct file' as their first parameter and it looks like its kernel definition isn't exported so what you would really like to do is:

kprobe_vfs_write
{
  @path = (path *)((char*)arg + 16);
  ...
}

However, bpftrace currently doesn't let you cast to an integral type. I'm looking at that now as it would make this and many other similar things much easier to do.

@tyroguru
Copy link
Contributor

@fntlnz - your script won't work as it is anyway as you need to pad out the first 16 bytes as explaiend above. Something like this will work:

#include <linux/path.h>
#include <linux/dcache.h>

struct file {
  char pad[16];
  struct path f_path;
}


kprobe:vfs_write
{
  @file = ((file *)arg0)->f_path;
  @file_name = str(((path*)@file)->dentry->d_name.name);
  @[@file_name] = count();
}

@fntlnz
Copy link

fntlnz commented Nov 26, 2018

@tyroguru after some reading of kernel source code I've been able to resolve that struct in this way

#include <linux/path.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/dcache.h>
#include <linux/mount.h>

kprobe:vfs_write
{
  $file = (file *)arg0;
  $file_name = str($file->f_path.dentry->d_name.name);
  @writes[$file_name] = sum(arg2);
}

Output:

@writes[.touch]: 0
@writes[sh-thd.hhQinh]: 1
@writes[sh-thd.SuACZD]: 1
@writes[oom_score_adj]: 4
@writes[0]: 11
@writes[init-stderr]: 11
@writes[UDP]: 27
@writes[tty]: 29
@writes[sh-thd.LOe9QJ]: 39
@writes[ptmx]: 39
@writes[update-notifier-npm.json.510683803]: 55
@writes[sh-thd.LQsZt6]: 67
@writes[sh-thd.KAmXB0]: 78
@writes[.zsh_history]: 94
@writes[request-header-ca-config.json]: 98
@writes[client-ca-config.json]: 98
@writes[server-ca-config.json]: 98
@writes[sh-thd.K6HW6s]: 110
@writes[fntlnz]: 112
@writes[sh-thd.YDZten]: 143
@writes[sh-thd.Eq70JP]: 210
@writes[sh-thd.1ydON4]: 402
@writes[sh-thd.zgZ6j2]: 417
@writes[sh-thd.PT6r71]: 428
@writes[sh-thd.RY4a0Z]: 436
@writes[sh-thd.nUL4G1]: 443
@writes[sh-thd.gPMIm1]: 450
@writes[sh-thd.XZvck3]: 454
@writes[data_0]: 468
@writes[webapp-T0JK1PCN6-console.log]: 471
@writes[sh-thd.GZKkR2]: 478
@writes[sh-thd.P1oiO3]: 487
@writes[webapp-T3C9DQYE5-console.log]: 494
@writes[sh-thd.pEW0DZ]: 519
@writes[sh-thd.gtvONY]: 544
@writes[sh-thd.FdxT7Y]: 544
@writes[sh-thd.HhbML4]: 574
@writes[sh-thd.9H5FsZ]: 584
@writes[webapp-T02GAR81Y-console.log]: 685
@writes[webapp-T09NY5SBT-console.log]: 685
@writes[data_1]: 768
@writes[client-auth-proxy.csr]: 944
@writes[client-scheduler.csr]: 948
@writes[client-controller.csr]: 960
@writes[serving-kube-aggregator.csr]: 964
@writes[client-admin.csr]: 968
@writes[client-kube-proxy.csr]: 972
@writes[client-kubelet.csr]: 980
@writes[client-kube-aggregator.csr]: 985
@writes[serving-kube-apiserver.csr]: 1021
@writes[client-auth-proxy.pem]: 1289
@writes[client-scheduler.pem]: 1294
@writes[client-controller.pem]: 1306
@writes[server-ca.crt]: 1310
@writes[serving-kube-aggregator.pem]: 1310
@writes[client-ca.crt]: 1310
@writes[request-header-ca.crt]: 1310
@writes[client-admin.pem]: 1314
@writes[client-kube-proxy.pem]: 1318
@writes[client-kubelet.pem]: 1326
@writes[client-kube-aggregator.pem]: 1330
@writes[serving-kube-apiserver.pem]: 1367
@writes[client-scheduler-key.pem]: 1675
@writes[client-kubelet-key.pem]: 1675
@writes[kube-serviceaccount.key]: 1675
@writes[client-kube-proxy-key.pem]: 1675
@writes[serving-kube-aggregator-key.pem]: 1675
@writes[serving-kube-apiserver-key.pem]: 1675
@writes[client-admin-key.pem]: 1679
@writes[client-controller-key.pem]: 1679
@writes[client-auth-proxy-key.pem]: 1679
@writes[client-kube-aggregator-key.pem]: 1679
@writes[client-ca.key]: 1704
@writes[request-header-ca.key]: 1704
@writes[server-ca.key]: 1704
@writes[.rnd]: 3072
@writes[null]: 4526
@writes[5]: 7463
@writes[Cookies]: 12288
@writes[Cookies-journal]: 12836
@writes[kube-aggregator.kubeconfig]: 12878
@writes[etcd.log]: 14077
@writes[[eventfd]]: 34024
@writes[UNIX]: 38159
@writes[SiteSecurityServiceState.txt]: 56404
@writes[0000000000000000-0000000000000000.wal]: 94832
@writes[kube-apiserver.log]: 170271
@writes[recovery.jsonlz4.tmp]: 193322
@writes[cookies.sqlite]: 294912
@writes[]: 311459
@writes[TCP]: 388794
@writes[TCPv6]: 397112
@writes[cookies.sqlite-wal]: 557496
@writes[db]: 573440

@tyroguru
Copy link
Contributor

@fntlnz - sigh... My bad - I was missing the declaration of 'struct file' in fs.h and only picking up the forward declaration provided in file.h. Thanks for the pointer.

@gmarler
Copy link
Contributor

gmarler commented Jan 2, 2020

@brendangregg, did this, or something like it, ever come to pass?

Converting either a struct file or struct dentry being passed into vfs_* functions into absolute paths is certainly useful.

Or are we still waiting for the underlying function(s) that would unwind an absolute path to be added to BCC first, then implemented in bpftrace?

@fbs
Copy link
Contributor

fbs commented Jan 2, 2020

Looks like work is being done on a helper for this iovisor/bcc#2544

But it has not been merged yet (https://patchwork.ozlabs.org/patch/1211861/) so it will be a while before this will be available.

@gmarler
Copy link
Contributor

gmarler commented Jan 2, 2020

Thanks, fd2path() in iovisor/bcc#2544 does look like it produces the necessary absolute path.

It's just not clear (to me) whether that could be leveraged directly to convert a struct dentry into an absolute path.

Like, for instance, if you're going to vfs_unlink() a file, the struct dentry is all that is passed, so you don't have the necessary fd necessary for fd2path() to work.

This would imply that another helper would be needed for such cases where the file being manipulated doesn't have an associated file descriptor open at the time.

Or I'm just missing something.

@wanghh2000
Copy link

The absolute path is very useful in some performance trace cases, expect this feature. :)

@ajor
Copy link
Member

ajor commented Oct 3, 2023

This was done in #1492, although it only works for a very limited set of kernel functions.

@ajor ajor closed this as completed Oct 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request, changes on existing features kernel Issue may require kernel work
Projects
None yet
Development

No branches or pull requests

8 participants