oparchive.cpp

Go to the documentation of this file.
00001 
00013 #include <cstdlib>
00014 
00015 #include <iostream>
00016 #include <fstream>
00017 #include <cstdlib>
00018 
00019 #include <errno.h>
00020 #include <string.h>
00021 #include <dirent.h>
00022 
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <unistd.h>
00026 #include "op_file.h"
00027 #include "op_bfd.h"
00028 #include "op_config.h"
00029 #include "oparchive_options.h"
00030 #include "file_manip.h"
00031 #include "cverb.h"
00032 #include "image_errors.h"
00033 #include "string_manip.h"
00034 #include "locate_images.h"
00035 
00036 using namespace std;
00037 
00038 namespace {
00039 
00040 
00041 void copy_one_file(image_error err, string const & source, string const & dest)
00042 {
00043     if (!op_file_readable(source))
00044         return;
00045 
00046     if (options::list_files) {
00047         cout << source << endl;
00048         return;
00049     }
00050 
00051     if (!copy_file(source, dest) && err == image_ok) {
00052         cerr << "can't copy from " << source << " to " << dest
00053              << " cause: " << strerror(errno) << endl;
00054     }
00055 }
00056 
00057 void copy_stats(string const & session_samples_dir,
00058         string const & archive_path)
00059 {
00060     DIR * dir;
00061     struct dirent * dirent;
00062     string stats_path;
00063     
00064     stats_path = session_samples_dir + "stats/";
00065 
00066     if (!(dir = opendir(stats_path.c_str()))) {
00067         return;
00068     }
00069 
00070     string sample_base_dir = session_samples_dir.substr(archive_path.size());
00071     string archive_stats = options::outdirectory + sample_base_dir + "stats/";
00072     string archive_stats_path = archive_stats + "event_lost_overflow";
00073     if (!options::list_files &&
00074         create_path(archive_stats_path.c_str())) {
00075         cerr << "Unable to create directory for "
00076              << archive_stats << "." << endl;
00077         exit (EXIT_FAILURE);
00078     }
00079 
00080     copy_one_file(image_ok, stats_path + "/event_lost_overflow", archive_stats_path);
00081 
00082     while ((dirent = readdir(dir))) {
00083         int cpu_nr;
00084         string path;
00085         if (sscanf(dirent->d_name, "cpu%d", &cpu_nr) != 1)
00086             continue;
00087         path = string(dirent->d_name) + "/" + "sample_lost_overflow";
00088         archive_stats_path = archive_stats + path;
00089         if (!options::list_files &&
00090             create_path(archive_stats_path.c_str())) {
00091             cerr << "Unable to create directory for "
00092                  << archive_stats_path << "." << endl;
00093             exit (EXIT_FAILURE);
00094         }
00095         copy_one_file(image_ok, stats_path + path, archive_stats_path);
00096 
00097     }
00098     closedir(dir);
00099 
00100 }
00101 
00102 int oparchive(options::spec const & spec)
00103 {
00104     handle_options(spec);
00105 
00106     string archive_path = classes.extra_found_images.get_archive_path();
00107 
00108     /* Check to see if directory can be created */
00109     if (!options::list_files && create_path(options::outdirectory.c_str())) {
00110         cerr << "Unable to create directory for " 
00111              << options::outdirectory << "." << endl;
00112         exit (EXIT_FAILURE);
00113     }
00114 
00115     /* copy over each of the executables and the debuginfo files */
00116     list<inverted_profile> iprofiles = invert_profiles(classes);
00117 
00118     report_image_errors(iprofiles, classes.extra_found_images);
00119 
00120     list<inverted_profile>::iterator it = iprofiles.begin();
00121     list<inverted_profile>::iterator const end = iprofiles.end();
00122 
00123     cverb << vdebug << "(exe_names)" << endl << endl;
00124     for (; it != end; ++it) {
00125 
00126         string exe_name = it->image;
00127         image_error error;
00128         string real_exe_name =
00129             classes.extra_found_images.find_image_path(it->image,
00130                           error, true);
00131 
00132         if (error == image_ok)
00133             exe_name = classes.extra_found_images.strip_path_prefix(real_exe_name);
00134 
00135         // output name must be identical to the original name, when
00136         // using this archive the used fixup will be identical e.g.:
00137         // oparchive -p /lib/modules/2.6.42/kernel -o tmp;
00138         // opreport  -p /lib/modules/2.6.42/kernel { archive:tmp }
00139         string exe_archive_file = options::outdirectory + exe_name;
00140 
00141         // FIXME: hacky
00142         if (it->error == image_not_found && is_prefix(exe_name, "anon "))
00143             continue;
00144 
00145         cverb << vdebug << real_exe_name << endl;
00146         /* Create directory for executable file. */
00147         if (!options::list_files &&
00148             create_path(exe_archive_file.c_str())) {
00149             cerr << "Unable to create directory for "
00150                  << exe_archive_file << "." << endl;
00151             exit (EXIT_FAILURE);
00152         }
00153 
00154         /* Copy actual executable files */
00155         copy_one_file(it->error, real_exe_name, exe_archive_file);
00156 
00157         /* If there are any debuginfo files, copy them over.
00158          * Need to copy the debug info file to somewhere we'll
00159          * find it - executable location + "/.debug"
00160          * to avoid overwriting files with the same name. The
00161          * /usr/lib/debug search path is not going to work.
00162          */
00163         bfd * ibfd = open_bfd(real_exe_name);
00164         if (ibfd) {
00165             string dirname = op_dirname(real_exe_name);
00166             string debug_filename;
00167             if (find_separate_debug_file(ibfd, real_exe_name,
00168                 debug_filename, classes.extra_found_images)) {
00169                 /* found something copy it over */
00170                 string dest_debug_dir = options::outdirectory +
00171                     dirname + "/.debug/";
00172                 if (!options::list_files &&
00173                     create_dir(dest_debug_dir.c_str())) {
00174                     cerr << "Unable to create directory: "
00175                     << dest_debug_dir << "." << endl;
00176                     exit (EXIT_FAILURE);
00177                 }
00178 
00179                 string dest_debug = dest_debug_dir +
00180                     op_basename(debug_filename);
00181                 copy_one_file(image_ok, debug_filename, dest_debug);
00182             }
00183             bfd_close(ibfd);
00184         }
00185     }
00186 
00187     /* copy over each of the sample files */
00188     list<string>::iterator sit = sample_files.begin();
00189     list<string>::iterator const send = sample_files.end();
00190 
00191     string a_sample_file = *sit;
00192     int offset = a_sample_file.find('{');
00193     string base_samples_dir = a_sample_file.substr(0, offset);
00194     copy_stats(base_samples_dir, archive_path);
00195 
00196     cverb << vdebug << "(sample_names)" << endl << endl;
00197 
00198     for (; sit != send; ++sit) {
00199         string sample_name = *sit;
00200         /* Get rid of the the archive_path from the name */
00201         string sample_base = sample_name.substr(archive_path.size());
00202         string sample_archive_file = options::outdirectory + sample_base;
00203         
00204         cverb << vdebug << sample_name << endl;
00205         cverb << vdebug << " destp " << sample_archive_file << endl;
00206         if (!options::list_files &&
00207             create_path(sample_archive_file.c_str())) {
00208             cerr << "Unable to create directory for "
00209                  << sample_archive_file << "." << endl;
00210             exit (EXIT_FAILURE);
00211         }
00212 
00213         /* Copy over actual sample file. */
00214         copy_one_file(image_ok, sample_name, sample_archive_file);
00215     }
00216 
00217     /* copy over the <session-dir>/abi file if it exists */
00218     char * real_session_dir = realpath(op_session_dir, NULL);
00219     if (!real_session_dir) {
00220         cerr << "Unable to to obtain realpath for " << op_session_dir << endl;
00221         exit (EXIT_FAILURE);
00222     }
00223     string abi_name = string(real_session_dir) + "/abi";
00224     copy_one_file(image_ok, archive_path + abi_name,
00225                   options::outdirectory + abi_name);
00226 
00227     /* copy over the <session-dir>/samples/oprofiled.log file */
00228     string log_name = string(real_session_dir) + string("/samples") + "/oprofiled.log";
00229     copy_one_file(image_ok, archive_path + log_name,
00230                   options::outdirectory + log_name);
00231 
00232     /* copy over the <session-dir>/samples/operf.log file */
00233     log_name = string(real_session_dir) + string("/samples") + "/operf.log";
00234     copy_one_file(image_ok, archive_path + log_name,
00235                   options::outdirectory + log_name);
00236 
00237     free(real_session_dir);
00238 
00239     return 0;
00240 }
00241 
00242 }  // anonymous namespace
00243 
00244 
00245 int main(int argc, char const * argv[])
00246 {
00247     return run_pp_tool(argc, argv, oparchive);
00248 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1