]> sourceware.org Git - systemtap.git/blame - rpm_finder.cxx
Allow utrace_syscall_args.stp to accepts arm64 use of syscall.openat
[systemtap.git] / rpm_finder.cxx
CommitLineData
2ed04863 1// systemtap debuginfo rpm finder
ef36f781 2// Copyright (C) 2009-2014 Red Hat Inc.
2ed04863
WC
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#include "config.h"
10#include "session.h"
11#include "rpm_finder.h"
12
13#include <iostream>
14#include <fstream>
15#include <sstream>
16#include <cerrno>
17#include <cstdlib>
18
19using namespace std;
20
21#ifdef HAVE_LIBRPM
22
23extern "C" {
24
25#define _RPM_4_4_COMPAT
26#include <string.h>
27#include <rpm/rpmlib.h>
28#include <rpm/rpmts.h>
29#include <rpm/rpmdb.h>
30#include <rpm/header.h>
31
32#ifndef xfree
33#define xfree free
34#endif
35
36}
37
d389518f
DB
38#if ! HAVE_LIBRPMIO && HAVE_NSS
39extern "C" {
40#include <nss.h>
41}
9a0b2b7c 42#include "nsscommon.h"
d389518f
DB
43#endif
44
2ed04863
WC
45/* Returns the count of newly added rpms. */
46/* based on the code in F11 gdb-6.8.50.20090302 source rpm */
76c87907 47/* Added in the rpm_type parameter to specify what rpm to look for */
2ed04863
WC
48
49static int
76c87907 50missing_rpm_enlist (systemtap_session& sess, const char *filename, const char *rpm_type)
2ed04863
WC
51{
52 static int rpm_init_done = 0;
53 rpmts ts;
54 rpmdbMatchIterator mi;
55 int count = 0;
56
57 if (filename == NULL)
58 return 0;
59
60 if (!rpm_init_done)
61 {
62 static int init_tried;
63
64 /* Already failed the initialization before? */
65 if (init_tried)
66 return 0;
67 init_tried = 1;
68
69 if (rpmReadConfigFiles(NULL, NULL) != 0)
70 {
efee9a98 71 cerr << _("Error reading the rpm configuration files") << endl;
2ed04863
WC
72 return 0;
73 }
74
75 rpm_init_done = 1;
76 }
77
5f429a70
JS
78 /* If we've seen this combo before, don't check again... */
79 if (!sess.rpms_checked.insert(string(filename) + rpm_type).second)
80 return 0;
81
76c87907 82 ts = rpmtsCreate();
2ed04863
WC
83
84 mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
85 if (mi != NULL)
86 {
87 for (;;)
88 {
89 Header h;
76c87907
LB
90 char *rpminfo, *s, *s2;
91 char header[31] = {};
92 const char* arch = ".%{arch}";
93 sprintf(header, "%%{sourcerpm}%s%s", rpm_type, arch);
2ed04863 94 errmsg_t err;
76c87907 95 size_t rpminfolen = strlen(rpm_type);
2ed04863 96 size_t srcrpmlen = sizeof (".src.rpm") - 1;
76c87907 97 rpmdbMatchIterator mi_rpminfo;
2ed04863
WC
98 h = rpmdbNextIterator(mi);
99 if (h == NULL)
100 break;
76c87907 101 /* Verify the kernel file is not already installed. */
2ed04863 102
76c87907
LB
103 rpminfo = headerSprintf(h, header,
104 rpmTagTable, rpmHeaderFormats, &err);
2ed04863 105
76c87907 106 if (!rpminfo)
2ed04863 107 {
efee9a98 108 cerr << _("Error querying the rpm file `") << filename << "': "
2ed04863
WC
109 << err << endl;
110 continue;
111 }
112 /* s = `.src.rpm-debuginfo.%{arch}' */
76c87907 113 s = strrchr (rpminfo, '-') - srcrpmlen;
2ed04863 114 s2 = NULL;
76c87907 115 if (s > rpminfo && memcmp (s, ".src.rpm", srcrpmlen) == 0)
2ed04863
WC
116 {
117 /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */
76c87907 118 s2 = (char *) memrchr (rpminfo, '-', s - rpminfo);
2ed04863
WC
119 }
120 if (s2)
121 {
122 /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
76c87907 123 s2 = (char *) memrchr (rpminfo, '-', s2 - rpminfo);
2ed04863
WC
124 }
125 if (!s2)
126 {
efee9a98 127 cerr << _("Error querying the rpm file `") << filename
76c87907
LB
128 << "': " << rpminfo << endl;
129 xfree (rpminfo);
2ed04863
WC
130 continue;
131 }
132 /* s = `.src.rpm-debuginfo.%{arch}' */
133 /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
76c87907
LB
134 memmove (s2 + rpminfolen, s2, s - s2);
135 memcpy (s2, rpm_type, rpminfolen);
2ed04863
WC
136 /* s = `XXXX.%{arch}' */
137 /* strlen ("XXXX") == srcrpmlen + debuginfolen */
138 /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */
139 /* strlen ("XX") == srcrpmlen */
76c87907
LB
140 memmove (s + rpminfolen, s + srcrpmlen + rpminfolen,
141 strlen (s + srcrpmlen + rpminfolen) + 1);
2ed04863
WC
142 /* s = `-debuginfo-%{version}-%{release}.%{arch}' */
143
144 /* RPMDBI_PACKAGES requires keylen == sizeof (int). */
145 /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */
76c87907
LB
146 mi_rpminfo = rpmtsInitIterator(ts, (rpmTag) RPMDBI_LABEL,
147 rpminfo, 0);
148 if (mi_rpminfo)
2ed04863 149 {
76c87907 150 rpmdbFreeIterator(mi_rpminfo);
2ed04863
WC
151 count = 0;
152 break;
153 }
2ed04863 154 /* The allocated memory gets utilized below for MISSING_RPM_HASH. */
76c87907
LB
155 if(strcmp(rpm_type,"-debuginfo")==0){
156 xfree(rpminfo);
157 rpminfo = headerSprintf(h,
158 "%{name}-%{version}-%{release}.%{arch}",
159 rpmTagTable, rpmHeaderFormats, &err);
160 }
161 if (!rpminfo)
2ed04863 162 {
efee9a98 163 cerr << _("Error querying the rpm file `") << filename
2ed04863
WC
164 << "': " << err << endl;
165 continue;
166 }
167
168 /* Base package name for `debuginfo-install'. We do not use the
76c87907
LB
169 `yum' command directly as the line
170 yum --enablerepo='*-debuginfo' install NAME-debuginfo.ARCH
171 would be more complicated than just:
172 debuginfo-install NAME-VERSION-RELEASE.ARCH
173 Do not supply the rpm base name (derived from .src.rpm name) as
174 debuginfo-install is unable to install the debuginfo package if
175 the base name PKG binary rpm is not installed while for example
176 PKG-libs would be installed (RH Bug 467901).
177 FUTURE: After multiple debuginfo versions simultaneously installed
178 get supported the support for the VERSION-RELEASE tags handling
179 may need an update. */
180 sess.rpms_to_install.insert(rpminfo);
181 }
182 count++;
2ed04863
WC
183 rpmdbFreeIterator(mi);
184 }
185
186 rpmtsFree(ts);
d389518f
DB
187
188#if HAVE_NSS
189 // librpm uses NSS cryptography but doesn't shut down NSS when it is done.
190 // If NSS is available, it will be used by the compile server client on
191 // specific certificate databases and thus, it must be shut down first.
192 // Get librpm to do it if we can. Otherwise do it ourselves.
193#if HAVE_LIBRPMIO
194 rpmFreeCrypto (); // Shuts down NSS within librpm
195#else
aeb9cc10 196 nssCleanup (NULL); // Shut down NSS ourselves
d389518f
DB
197#endif
198#endif
199
2ed04863
WC
200 return count;
201}
2ed04863
WC
202#endif /* HAVE_LIBRPM */
203
204void
76c87907 205missing_rpm_list_print (systemtap_session &sess, const char* rpm_type)
2ed04863
WC
206{
207#ifdef HAVE_LIBRPM
c05365e6 208 if (sess.rpms_to_install.size() > 0 && ! sess.suppress_warnings) {
76c87907
LB
209
210 if(strcmp(rpm_type,"-devel")==0)
efee9a98 211 cerr << _("Incorrect version or missing kernel-devel package, use: yum install ");
76c87907
LB
212
213 else if(strcmp(rpm_type,"-debuginfo")==0)
efee9a98 214 cerr << _("Missing separate debuginfos, use: debuginfo-install ");
76c87907
LB
215
216 else{
efee9a98 217 cerr << _("Incorrect parameter passed, please report this error.") << endl;
76c87907
LB
218 _exit(1);
219 }
220
2ed04863
WC
221 for (set<std::string>::iterator it=sess.rpms_to_install.begin();
222 it !=sess.rpms_to_install.end(); it++)
76c87907 223 {
2ed04863 224 cerr << *it << " ";
76c87907 225 }
2ed04863
WC
226 cerr << endl;
227 }
228#endif
229}
230
231int
232find_debug_rpms (systemtap_session &sess, const char * filename)
233{
234#ifdef HAVE_LIBRPM
76c87907
LB
235 const char *rpm_type = "-debuginfo";
236 return missing_rpm_enlist(sess, filename, rpm_type);
237#else
238 return 0;
239#endif
240}
241
242int find_devel_rpms(systemtap_session &sess, const char * filename)
243{
244#ifdef HAVE_LIBRPM
245 const char *rpm_type = "-devel";
246 return missing_rpm_enlist(sess, filename, rpm_type);
2ed04863
WC
247#else
248 return 0;
249#endif
250}
This page took 0.114134 seconds and 5 git commands to generate.