Re: dtrace and full path (was Re: question about CFURLCreateFileURL)
Re: dtrace and full path (was Re: question about CFURLCreateFileURL)
- Subject: Re: dtrace and full path (was Re: question about CFURLCreateFileURL)
- From: Jim Luther <email@hidden>
- Date: Fri, 20 Jan 2012 09:34:48 -0800
My guess... There's a bug and something in the kernel isn't set up the way the pathopens.d script expects. You could modify the first syscall::open*:return function in the filebyproc.d dtrace script to print out the 3 variables used to create the full pathname and maybe figure out which is causing the problem. Like this:
syscall::open*:return
/self->ok && arg0 != -1/
{
self->file = copyinstr(self->pathp);
self->char0 = copyin(self->pathp, 1);
/* fetch current working directory */
this->path = (curproc->p_fd->fd_cdir->v_name);
/* print out the variables used to construct the full path */
printf("self->file %s\n", self->file);
printf("v_name %s\n", curproc->p_fd->fd_cdir->v_name);
printf("cwd %s\n", this->path);
/*
* Make the full pathname
*
* This routine takes the cwd and the filename, and generates a
* full pathname. Sometimes the filename is absolute, so we must
* ignore the cwd. This also checks if the cwd ends in an
* unnecessary '/'.
*/
this->len = strlen(this->path);
self->join = *(char *)(this->path + this->len - 1) == '/' ? "" : "/";
self->dir = strjoin(cwd, self->join);
self->dir = *(char *)self->char0 == '/' ? "" : self->dir;
self->full = strjoin(self->dir, self->file);
/* save to aggregation */
@num[self->full] = count();
/* cleanup */
self->join = 0;
self->full = 0;
self->dir = 0;
self->file = 0;
self->char0 = 0;
}
If you don't know dtrace scripting, you need to grab the "DTrace User Guide" and the "Solaris Dynamic Tracing Guide" from Sun/Oracle.
- Jim
On Jan 20, 2012, at 1:53 AM, Patrick Proniewski wrote:
> Jim,
>
> Thank you very much for your explanations, and for your code. It's working as expected, and it solves one of my problem.
>
> While not exactly related to filesystem-dev, I've some questions about file path. If it's too much off-topic feel free to route me to the proper list.
> When I use Dtrace, via /usr/bin/pathopens.d and /usr/bin/filebyproc.d I get a list of paths accessed:
>
> ----------
> (sample filebyproc.d output)
> 1 19445 open_nocancel:entry Terminal /Users/patpro/Library/Preferences/com.apple.Terminal.plist.5SjtLlT
> 0 18659 open:entry mdworker /Users/patpro/Library/Preferences/com.apple.Terminal.plist
> 0 18659 open:entry mds .
>
> filebyproc.d almost always return a full path. The big exception is for the process mds:
>
> 0 18659 open:entry mds .
> 0 19445 open_nocancel:entry mds .
> 0 18659 open:entry mds live.11.shadowIndexTermIds
> 0 18659 open:entry mds .
>
> Is there any way to know what is the absolute path of mds "open*:entry" calls?
>
> ----------
> (sample pathopens.d output)
> 25 /Users/patpro/Library/Mail
> 28 /dev/urandom
> 58 Hard-drive/.
>
> the code of pathopens.d reads:
>
> * This program prints a count of the number of times files have been
> * successfully opened. This is somewhat special in that the full pathname
> * is calculated, even if the file open referred to a relative pathname.
>
> So I would expect "Hard-drive/." to be a full path, but it doesn't look like it is. Is it a special file system trick (like /.vol/ for example)?
>
> regards,
> Patrick
>
>
> On 19 janv. 2012, at 19:39, Jim Luther wrote:
>
>> Patrick,
>>
>> The "VolFS" style paths in the form "/.vol/<volumeID>/<dirID>/<name>" or "/.vol/<volumeID>/<CNID>" are built by the Carbon File Manager and are described in this technical Q&A <https://developer.apple.com/legacy/mac/library/#qa/qa2001/qa1113.html#//apple_ref/doc/uid/DTS10001661>.
>>
>> Those "VolFS" paths are NOT the same as the paths in file reference CFURLs, so you CANNOT create a CFURL with a VolFS path, and then use CFURLCreateFilePathURL() to convert it to a regular POSIX-style path.
>>
>> The only good way I can think of to convert a "VolFS" style path to a regular POSIX path is to use getattrlist(2) and ask for the ATTR_CMN_FULLPATH attribute. I know you don't work in C, so you'll have to get someone to build a command line tool from this code for you. You can call the tool something like "fullpath". The tool takes the input path, gets the full POSIX path from getattrlist, and then prints that full path to stdout and returns EXIT_SUCCESS (0). If the input path cannot be converted, it prints an error message to stderr and exits with EXIT_FAILURE (1). That way, you can use it from a script.
>>
>> Hope this works for you.
>>
>> - Jim
>>
>> #include <sys/attr.h>
>> #include <unistd.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>>
>> #pragma pack(push, 4)
>> struct FullPathAttributeBuffer
>> {
>> u_int32_t length;
>> attrreference_t fullPathAttr;
>> char fullPathBuf[PATH_MAX];
>> };
>> #pragma pack(pop)
>>
>> int main(int argc, const char * argv[])
>> {
>> int result = EXIT_SUCCESS;
>> // make sure there's an input path
>> if ( argc == 2 ) {
>> const char *inPath = argv[1];
>> struct attrlist attrList = {
>> ATTR_BIT_MAP_COUNT,
>> 0,
>> ATTR_CMN_FULLPATH,
>> 0,
>> 0,
>> 0,
>> 0,
>> };
>> struct FullPathAttributeBuffer attrBuf;
>> // use getattrlist to get the full path from the input path
>> if ( getattrlist(inPath, &attrList, &attrBuf, sizeof(attrBuf), FSOPT_NOFOLLOW) == 0 ) {
>> if ( attrBuf.fullPathAttr.attr_length > 0 ) {
>> // print the full path to stdout
>> fprintf(stdout, "%s\n", (const char *)&attrBuf.fullPathAttr + attrBuf.fullPathAttr.attr_dataoffset);
>> }
>> else {
>> // send error message to stderr
>> result = EXIT_FAILURE;
>> fprintf(stderr, "getattrlist could not obtain a path for %s\n", inPath);
>> }
>> }
>> else {
>> // send error message to stderr
>> result = EXIT_FAILURE;
>> fprintf(stderr, "getattrlist failed to find %s\n", inPath);
>> }
>> }
>> else {
>> // send error message to stderr
>> result = EXIT_FAILURE;
>> fprintf(stderr, "missing input argument\n");
>> }
>> return ( result );
>> }
>>
>> On Jan 19, 2012, at 8:38 AM, Patrick Proniewski wrote:
>>
>>> Hello,
>>>
>>> First, I must admit I'm not a developer. I know almost nothing about compiled languages and I can't write a single line of C code (but I'm proficient with bash).
>>> I want to track down file access using Dtrace tools like /usr/bin/filebyproc.d or /usr/bin/pathopens.d for example. It appears that some processes access files using their ID instead of their human readable Path. ie. they open /.vol/VOLUME_ID/INODE instead of /path/to/the/file.
>>> I need to convert this ID URL into a Path URL.
>>> Mac OS X 10.6 documentation refers to the function CFURLCreateFileURL that is supposed to convert a file-ID URL to a path-based URL. But I can't find any sample code that uses this function, nor any already-made command line utility that provides this conversion.
>>>
>>> <http://developer.apple.com/library/mac/#releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_6.html#//apple_ref/doc/uid/TP40008898-SW1>
>>>
>>> First question: am-I right about the possibility to convert /.vol/VOLUME_ID/INODE into /path/to/the/file?
>>> Second question: if so, is there any sample code I could use, or even better a command line application, or DTrace function that would do the translation?
>>>
>>> My purpose is to design a script/utility that would run in the background to collect a log of file accesses over few days/week. The final log would be parsed later for analysis. Later translation of /.vol/VOLUME_ID/INODE into /path/to/the/file (using find for example) is not an option.
>>> The final analysis would show what files/directories/volumes are accessed, sorted by frequency (or other metric available thru DTrace like seektime, byte…)
>>>
>>> Any help appreciated.
>>>
>>> Patrick _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Filesystem-dev mailing list (email@hidden)
>>> Help/Unsubscribe/Update your Subscription:
>>>
>>> This email sent to email@hidden
>>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden