1 : // systemtap cache manager
2 : // Copyright (C) 2006-2007 Red Hat Inc.
3 : //
4 : // This file is part of systemtap, and is free software. You can
5 : // redistribute it and/or modify it under the terms of the GNU General
6 : // Public License (GPL); either version 2, or (at your option) any
7 : // later version.
8 :
9 :
10 : #include "session.h"
11 : #include "cache.h"
12 : #include "util.h"
13 : #include <cerrno>
14 : #include <string>
15 : #include <fstream>
16 : #include <cstring>
17 :
18 : extern "C" {
19 : #include <sys/types.h>
20 : #include <sys/stat.h>
21 : #include <fcntl.h>
22 : }
23 :
24 : using namespace std;
25 :
26 :
27 : void
28 261 : add_to_cache(systemtap_session& s)
29 : {
30 261 : string module_src_path = s.tmpdir + "/" + s.module_name + ".ko";
31 261 : if (s.verbose > 1)
32 0 : clog << "Copying " << module_src_path << " to " << s.hash_path << endl;
33 261 : if (copy_file(module_src_path.c_str(), s.hash_path.c_str()) != 0)
34 : {
35 : cerr << "Copy failed (\"" << module_src_path << "\" to \""
36 0 : << s.hash_path << "\"): " << strerror(errno) << endl;
37 0 : return;
38 : }
39 :
40 261 : string c_dest_path = s.hash_path;
41 261 : if (c_dest_path.rfind(".ko") == (c_dest_path.size() - 3))
42 261 : c_dest_path.resize(c_dest_path.size() - 3);
43 261 : c_dest_path += ".c";
44 :
45 261 : if (s.verbose > 1)
46 : clog << "Copying " << s.translated_source << " to " << c_dest_path
47 0 : << endl;
48 261 : if (copy_file(s.translated_source.c_str(), c_dest_path.c_str()) != 0)
49 : {
50 : cerr << "Copy failed (\"" << s.translated_source << "\" to \""
51 0 : << c_dest_path << "\"): " << strerror(errno) << endl;
52 261 : }
53 : }
54 :
55 :
56 : bool
57 347 : get_from_cache(systemtap_session& s)
58 : {
59 347 : string module_dest_path = s.tmpdir + "/" + s.module_name + ".ko";
60 347 : string c_src_path = s.hash_path;
61 : int fd_module, fd_c;
62 :
63 347 : if (c_src_path.rfind(".ko") == (c_src_path.size() - 3))
64 347 : c_src_path.resize(c_src_path.size() - 3);
65 347 : c_src_path += ".c";
66 :
67 : // See if module exists
68 347 : fd_module = open(s.hash_path.c_str(), O_RDONLY);
69 347 : if (fd_module == -1)
70 : {
71 : // It isn't in cache.
72 276 : return false;
73 : }
74 :
75 : // See if C file exists.
76 71 : fd_c = open(c_src_path.c_str(), O_RDONLY);
77 71 : if (fd_c == -1)
78 : {
79 : // The module is there, but the C file isn't. Cleanup and
80 : // return.
81 0 : close(fd_module);
82 0 : unlink(s.hash_path.c_str());
83 0 : return false;
84 : }
85 :
86 : // Copy the cached C file to the destination
87 71 : if (copy_file(c_src_path.c_str(), s.translated_source.c_str()) != 0)
88 : {
89 : cerr << "Copy failed (\"" << c_src_path << "\" to \""
90 0 : << s.translated_source << "\"): " << strerror(errno) << endl;
91 0 : close(fd_module);
92 0 : close(fd_c);
93 0 : return false;
94 : }
95 :
96 : // Copy the cached module to the destination (if needed)
97 71 : if (s.last_pass != 3)
98 : {
99 71 : if (copy_file(s.hash_path.c_str(), module_dest_path.c_str()) != 0)
100 : {
101 : cerr << "Copy failed (\"" << s.hash_path << "\" to \""
102 0 : << module_dest_path << "\"): " << strerror(errno) << endl;
103 0 : unlink(c_src_path.c_str());
104 0 : close(fd_module);
105 0 : close(fd_c);
106 0 : return false;
107 : }
108 : }
109 :
110 : // We're done with these file handles.
111 71 : close(fd_module);
112 71 : close(fd_c);
113 :
114 : // To preserve semantics (since this will happen if we're not
115 : // caching), display the C source if the last pass is 3.
116 71 : if (s.last_pass == 3)
117 : {
118 0 : ifstream i (s.translated_source.c_str());
119 0 : cout << i.rdbuf();
120 : }
121 : // And similarly, display probe module name for -p4.
122 71 : if (s.last_pass == 4)
123 6 : cout << s.hash_path << endl;
124 :
125 : // If everything worked, tell the user. We need to do this here,
126 : // since if copying the cached C file works, but copying the cached
127 : // module fails, we remove the cached C file and let the C file get
128 : // regenerated.
129 71 : if (s.verbose)
130 : {
131 6 : clog << "Pass 3: using cached " << c_src_path << endl;
132 6 : if (s.last_pass != 3)
133 6 : clog << "Pass 4: using cached " << s.hash_path << endl;
134 : }
135 :
136 71 : return true;
137 2188 : }
|