Saturday, December 26, 2009

strace package management tool

I think I found out why there is big talk about using strace to track files created by an install, but no howtos to back it up. This is not a howto, it is just some notes. To make a long story short, it is a simple concept that is extremely difficult to put into practice. Two very large obstacles are that strace output is difficult to convert to a file list, and strace accepts only a single command with its options. That doesn't sound very hard until you try it. It is not uncommon to use a series of commands to perform the "install". It is important to avoid stracing "configure" and "make" and "make check". Only the "install" steps should be traced because you only want to know which files get installed.

Strace may have a few advantages over installwatch although they share the advantage of tracing files created only by a process and its children. Installwatch cannot trace setuid and setguid programs and strace potentially can. Installwatch cannot trace statically linked programs -- I don't know whether strace can. Installwatch works by preloading a library, and the lfs book ponders the possibility that preloading the library may cause some unwanted side-effects during installation. More mud to sling at installwatch is that it has been focused at its use in checkinstall which is predominantly for rpm and deb installations. The main reason that I am not comfortable with relying on installwatch is that I might happen to install something that doesn't track some of the files created and then I might never know what did not get tracked. I can think of no way to predict when that might happen. I don't suspect that it happens a lot, but I don't like the idea of not knowing. Sudo is a setuid, however you would put sudo at the far left on the command line instead of in the middle, but I don't know what else.

Iv'e been working on a script called do_strace. It is not finished except for testing. The guts of do_strace is a perl script that aims to detect files being created in the strace jabber. Another thing do_strace does is to act as a wrapper around strace to feed it the stuff you want to get traced. The steps are to strace file related system calls for your stuff to a logfile, then concoct a file list from the logfile.

Since you can only throw one command at strace, I've also been working on a script called do_eval which throws a bunch of stuff at strace while seeming to be just one command. Needless to say this can be very messy business. Do_eval lives dangerously by performing a bash eval on the stuff it got. Note that strace will not accept eval as a command because it is not a command. Eval is a bash builtin. On the other hand, do_eval is a script that has a "shebang" line and can this be executed as a command by strace. Any executable script that has a proper shebang line can be straced. Do_eval is an attempted means to an end of having the convenience of cutting and pasting stuff and getting it straced.

A further level of messiness can be added. If do_eval gets stuff as arguments, then it uses the arguments as the stuff. You might want to do it that way if you were scripting an install. If do_eval doesn't get arguments, it reads through stdin to get the stuff. It could get stdin from a redirection from a file as in "do_eval < myfile" or from the keyboard or from mouse pasting. The least error prone way is to let do_eval get stuff from stdin. This is because if stuff comes from stdin, do_eval can check line by line and insert double ampersands to separate commands if necessary. When do_eval gets stuff as arguments, it is up to you to make sure that commands are separated by double ampersands. It is important here to separate the commands with double ampersands because we are trying to pass a block, but good old bash eats the newlines. In any case, it is a good idea to separate commands with && so that if one command fails, it will not stupidly proceed to the rest of the commands.

To illustrate, these have entirely different results:
echo you echo foo
echo you && echo foo

The first one prints:
you echo foo

The second one prints:
you
foo

So, if going with arguments to do_eval, it is important to make sure the commands are separated with double ampersands.

Even so, the only way I have found to feed multiple commands to do_eval is with a cat/heredoc trick:
do_eval $(cat << "CAT_EOF"
echo you &&
echo foo
CAT_EOF
)

But you cannot use the cat/heredoc trick to feed stuff to strace:
strace $(cat << "CAT_EOF"
echo you &&
echo foo
CAT_EOF
)

Well, maybe you can, but it certainly won't do what you expect.

As an alternative to the do_eval mess, you could just prepend do_strace to each command concerned with the "install". But then, the file lists would get all separated. And what you really wanted was to know what files got created by the whole "install".

What I am trying so far, is to "set" the command line, press ENTER, and then type or paste the "stuff".

So the command line I "set" is:
do_strace do eval <ENTER>

And the type or pasted stuff is:
echo you > youfoo
echo foo >> youfoo
<ENTER>

And the output is:
FILE LISTING [+add -del !update] Name Bytes Type Inode# #links Ctime sMode oMode User Group
! youfoo 8 f 1225051 1 1261859113 -rw-r--r-- 644 root root

And the contents of youfoo is:
you
foo

The do_eval arguments version produced the same results:
do_strace do_eval $(cat << "CAT_EOF"
echo you > youfoo &&
echo foo >> youfoo
CAT_EOF
)


So in the end, it doesn't surprise me that I could hardly find any howtos about using strace to track files created by an install. I might work on this some more in the future.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

Click blog title for the latest post