On Wed, 2010-09-01 at 21:50 +0300, Panu Matilainen wrote:
> On Wed, 1 Sep 2010, Ralf Corsepius wrote:
> >
> > b) To equippe the rpm/yum/mock etc. infrastructure with a mechanism to
> > pull-in "foreign binaries" into a sys-root (E.g. to install Fedora
> > *.ppc.rpm rpms into /usr/ppc-redhat/sys-root). So far, such mechanism
> > doesn't exist.
>
> You should be able to force rpm to lay down the files, given enough
> override-switches. Something like
> # rpm -Uvh --root /usr/ppc-redhat/sys-root --ignorearch --noscripts *.rpm
>
> (or alternatively --relocate with --badrelocate instead of --root, if you
> want the packages showing in system rpmdb instead of alternate root, and
> then you'd /really/ need arch-specific buildrequires which in turn is
> another can of worms etc)
>
> ...but the resulting pile of files is likely to be fairly useless since
> no scripts are executed. Having some way of executing scriptlets in an
> emulator (eg qemu) might be an interesting experiment actually ;)
>
> - Panu -
Speaking of crazy experiments, I came up with the attached rpm patch
last year when I was bootstrapping another arch. In short, to run
scripts without having to write a simulator, it bind mounts native
binary (/bin, /lib, etc) directories into the target sysroot before
running a script and unmounts them afterward. As crazy as that is, it
worked surprisingly well for a core set of F-10 rpms. Of course, it
doesn't work for scripts that try writing to the binary directories,
but it did help me compose a cross rootfs based on a kickstart file.
Something simulator based would definitely have been better.
--Mark
diff -rup a/lib/poptALL.c b/lib/poptALL.c
--- a/lib/poptALL.c 2009-03-03 01:51:52.000000000 -0500
+++ b/lib/poptALL.c 2009-08-03 16:01:23.295685376 -0400
@@ -68,6 +68,8 @@ const char * rpmcliRcfile = NULL;
const char * rpmcliRootDir = "/";
+const char * rpmcliNativeRootDir = NULL;
+
rpmQueryFlags rpmcliQueryFlags;
extern int _rpmio_debug;
@@ -238,6 +240,10 @@ struct poptOption rpmcliAllPoptTable[] =
N_("use ROOT as top level directory"),
N_("ROOT") },
+ { "nativeroot", '\0', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmcliNativeRootDir, 0,
+ N_("use ROOT as top level directory of native binaries"),
+ N_("ROOT") },
+
{ "querytags", '\0', 0, 0, POPT_QUERYTAGS,
N_("display known query tags"), NULL },
{ "showrc", '\0', 0, NULL, POPT_SHOWRC,
diff -rup a/lib/psm.c b/lib/psm.c
--- a/lib/psm.c 2009-04-03 07:04:46.000000000 -0400
+++ b/lib/psm.c 2009-08-04 16:39:57.944559570 -0400
@@ -4,6 +4,7 @@
*/
#include "system.h"
+#include <sys/mount.h>
#include <rpm/rpmlib.h> /* rpmvercmp and others */
#include <rpm/rpmmacro.h>
@@ -63,6 +64,69 @@ struct rpmpsm_s {
int nrefs; /*!< Reference count. */
};
+static const char *nativeDirs[] = {
+ "bin",
+ "sbin",
+ "usr/bin",
+ "usr/sbin",
+ "lib",
+ "usr/lib",
+ "usr/libexec",
+ NULL
+};
+
+static int rpmMountNatives(rpmts ts)
+{
+ const char * rootDir = rpmtsRootDir(ts);
+ const char *nativeDir = rpmtsNativeDir(ts);
+
+ if (rootDir != NULL && nativeDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
+ char **dirs;
+ if (rpmtsChrootDone(ts))
+ rootDir = "/";
+
+ for (dirs = nativeDirs; *dirs != NULL; ++dirs) {
+ struct stat st;
+ char *srcDir = rpmGetPath(rootDir, "native/", *dirs, NULL);
+ char *targetDir = rpmGetPath(rootDir, *dirs, NULL);
+
+ if (stat(srcDir, &st) == 0) {
+ rpmioMkpath(targetDir, 0755, -1, -1);
+ mount(srcDir, targetDir, NULL, MS_BIND, NULL);
+ }
+
+ _free(srcDir);
+ _free(targetDir);
+ }
+ }
+ return 0;
+}
+
+static int rpmUmountNatives(rpmts ts)
+{
+ const char * rootDir = rpmtsRootDir(ts);
+ char *nativeDir = rpmtsNativeDir(ts);
+
+ if (rootDir != NULL && nativeDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
+ char **dirs;
+ if (rpmtsChrootDone(ts))
+ rootDir = "/";
+
+ for (dirs = nativeDirs; *dirs != NULL; ++dirs) {
+ struct stat st;
+ char *targetDir = rpmGetPath(rootDir, *dirs, NULL);
+
+ if (stat(targetDir, &st) == 0) {
+ umount(targetDir);
+ unlink(targetDir);
+ }
+
+ _free(targetDir);
+ }
+ }
+ return 0;
+}
+
int rpmVersionCompare(Header first, Header second)
{
struct rpmtd_s one, two;
@@ -482,11 +546,13 @@ static rpmRC runLuaScript(rpmpsm psm, He
var = rpmluavFree(var);
rpmluaPop(lua);
+ rpmMountNatives(ts);
if (rpmluaRunScript(lua, script, sname) == 0) {
rc = RPMRC_OK;
} else if ((stag != RPMTAG_PREIN && stag != RPMTAG_PREUN)) {
warn_only = 1;
}
+ rpmUmountNatives(ts);
rpmluaDelVar(lua, "arg");
@@ -744,6 +810,7 @@ static rpmRC runScript(rpmpsm psm, Heade
goto exit;
}
+ rpmMountNatives(ts);
xx = rpmsqFork(&psm->sq);
if (psm->sq.child == 0) {
rpmlog(RPMLOG_DEBUG, "%s: %s\texecv(%s) pid %d\n",
@@ -778,6 +845,7 @@ static rpmRC runScript(rpmpsm psm, Heade
/* if we get this far we're clear */
rc = RPMRC_OK;
}
+ rpmUmountNatives(ts);
exit:
rpmtdFreeData(&prefixes);
@@ -1556,17 +1624,41 @@ rpmRC rpmpsmStage(rpmpsm psm, pkgStage s
case PSM_CHROOT_IN:
{ const char * rootDir = rpmtsRootDir(ts);
/* Change root directory if requested and not already done. */
+ rpmlog(RPMLOG_DEBUG, "PSM_CHROOT_IN: rootDir: %s\n", rootDir ? rootDir : "NULL");
if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')
&& !rpmtsChrootDone(ts) && !psm->chrootDone)
{
+ const char * nativeDir = rpmtsNativeDir(ts);
+ char *chrootNative = NULL;
+ rpmlog(RPMLOG_DEBUG, "PSM_CHROOT_IN: nativeDir: %s\n", nativeDir ? nativeDir : "NULL");
+ if (nativeDir != NULL) {
+ chrootNative = rpmGetPath(rootDir, "native", NULL);
+ /* mount nativeDir somewhere we can get to from chroot */
+ if (mkdir(chrootNative, 0755)) {
+ rpmlog(RPMLOG_ERR, _("Unable to make chroot native directory: %m\n"));
+ return -1;
+ }
+ if (mount(nativeDir, chrootNative, NULL, MS_BIND, NULL)) {
+ rpmlog(RPMLOG_ERR, _("Unable to mount chroot native directory: %m\n"));
+ rmdir(chrootNative);
+ _free(chrootNative);
+ return -1;
+ }
+ }
xx = chdir("/");
if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
if (chroot(rootDir) == -1) {
rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
+ if (chrootNative) {
+ umount(chrootNative);
+ rmdir(chrootNative);
+ _free(chrootNative);
+ }
return -1;
}
psm->chrootDone = 1;
(void) rpmtsSetChrootDone(ts, 1);
+ _free(chrootNative);
}
} break;
case PSM_CHROOT_OUT:
@@ -1574,8 +1666,16 @@ rpmRC rpmpsmStage(rpmpsm psm, pkgStage s
if (psm->chrootDone) {
const char * rootDir = rpmtsRootDir(ts);
const char * currDir = rpmtsCurrDir(ts);
- if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
+ if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
+ const char * nativeDir = rpmtsNativeDir(ts);
rc = chroot(".");
+ if (nativeDir != NULL) {
+ char *tmpDir = rpmGetPath(rootDir, "native", NULL);
+ umount(tmpDir);
+ rmdir(tmpDir);
+ _free(tmpDir);
+ }
+ }
psm->chrootDone = 0;
(void) rpmtsSetChrootDone(ts, 0);
if (currDir != NULL) /* XXX can't happen */
diff -rup a/lib/rpmcli.h b/lib/rpmcli.h
--- a/lib/rpmcli.h 2009-04-03 06:59:20.000000000 -0400
+++ b/lib/rpmcli.h 2009-08-04 15:43:51.432639428 -0400
@@ -40,6 +40,8 @@ extern const char * rpmcliRcfile;
extern const char * rpmcliRootDir;
+extern const char * rpmcliNativeRootDir;
+
/** \ingroup rpmcli
* Initialize most everything needed by an rpm CLI executable context.
* @param argc no. of args
diff -rup a/lib/rpmts.c b/lib/rpmts.c
--- a/lib/rpmts.c 2009-04-03 07:36:48.000000000 -0400
+++ b/lib/rpmts.c 2009-08-04 11:40:51.269560123 -0400
@@ -594,6 +594,7 @@ rpmts rpmtsFree(rpmts ts)
ts->scriptFd = NULL;
}
ts->rootDir = _free(ts->rootDir);
+ ts->nativeDir = _free(ts->nativeDir);
ts->currDir = _free(ts->currDir);
ts->order = _free(ts->order);
@@ -681,6 +682,50 @@ int rpmtsSetRootDir(rpmts ts, const char
return 0;
}
+const char * rpmtsNativeDir(rpmts ts)
+{
+ const char * nativeDir = NULL;
+
+ if (ts == NULL)
+ return NULL;
+
+ if (ts->nativeDir == NULL) {
+ char *x = getenv("RPM_NATIVEDIR");
+ if (x)
+ ts->nativeDir = rpmGetPath(x, NULL);
+ }
+
+ if (ts->nativeDir != NULL) {
+ urltype ut = urlPath(ts->nativeDir, &nativeDir);
+ switch (ut) {
+ case URL_IS_UNKNOWN:
+ case URL_IS_PATH:
+ break;
+ /* XXX these shouldn't be allowed as nativedir! */
+ case URL_IS_HTTPS:
+ case URL_IS_HTTP:
+ case URL_IS_HKP:
+ case URL_IS_FTP:
+ case URL_IS_DASH:
+ default:
+ nativeDir = NULL;
+ break;
+ }
+ }
+ return nativeDir;
+}
+
+int rpmtsSetNativeDir(rpmts ts, const char * nativeDir)
+{
+ if (ts == NULL || (nativeDir && nativeDir[0] != '/')) {
+ return -1;
+ }
+
+ ts->nativeDir = _free(ts->nativeDir);
+ ts->nativeDir = nativeDir ? rpmGetPath(nativeDir, NULL) : NULL ;
+ return 0;
+}
+
const char * rpmtsCurrDir(rpmts ts)
{
const char * currDir = NULL;
@@ -1129,6 +1174,7 @@ rpmts rpmtsCreate(void)
sizeof(*ts->removedPackages));
ts->rootDir = NULL;
+ ts->nativeDir = NULL;
ts->currDir = NULL;
ts->chrootDone = 0;
diff -rup a/lib/rpmts.h b/lib/rpmts.h
--- a/lib/rpmts.h 2009-04-03 06:59:20.000000000 -0400
+++ b/lib/rpmts.h 2009-08-04 13:11:36.436559980 -0400
@@ -394,6 +394,21 @@ const char * rpmtsRootDir(rpmts ts);
int rpmtsSetRootDir(rpmts ts, const char * rootDir);
/** \ingroup rpmts
+ * Get transaction nativeDir, i.e. path to native binaries.
+ * @param ts transaction set
+ * @return transaction nativeDir
+ */
+const char * rpmtsNativeDir(rpmts ts);
+
+/** \ingroup rpmts
+ * Set transaction nativeDir, i.e. path to native binaries.
+ * @param ts transaction set
+ * @param nativeDir new transaction nativeDir (or NULL)
+ * @return 0 on success, -1 on error (invalid rootDir)
+ */
+int rpmtsSetNativeDir(rpmts ts, const char * nativeDir);
+
+/** \ingroup rpmts
* Get transaction currDir, i.e. current directory before chroot(2).
* @param ts transaction set
* @return transaction currDir
diff -rup a/lib/rpmts_internal.h b/lib/rpmts_internal.h
--- a/lib/rpmts_internal.h 2009-04-03 07:36:48.000000000 -0400
+++ b/lib/rpmts_internal.h 2009-08-03 21:20:18.112685343 -0400
@@ -73,6 +73,7 @@ struct rpmts_s {
int selinuxEnabled; /*!< Is SE linux enabled? */
int chrootDone; /*!< Has chroot(2) been been done? */
char * rootDir; /*!< Path to top of install tree. */
+ char * nativeDir; /*!< Path to top of native install tree. */
char * currDir; /*!< Current working directory. */
FD_t scriptFd; /*!< Scriptlet stdout/stderr. */
int delta; /*!< Delta for reallocation. */
diff -rup a/python/rpmts-py.c b/python/rpmts-py.c
--- a/python/rpmts-py.c 2009-08-03 15:52:47.104684373 -0400
+++ b/python/rpmts-py.c 2009-09-14 15:28:49.281737146 -0400
@@ -790,6 +790,22 @@ fprintf(stderr, "*** rpmts_GetKeys(%p) t
return tuple;
}
+static PyObject *
+rpmts_SetNativeRoot(rpmtsObject * s, PyObject * args, PyObject * kwds)
+{
+ const char *nativeRoot;
+ char * kwlist[] = {"nativeRoot", NULL};
+
+if (_rpmts_debug)
+fprintf(stderr, "*** rpmts_SetNativeRoot(%p) ts %p\n", s, s->ts);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetNativeRoot", kwlist,
+ &nativeRoot))
+ return NULL;
+
+ return Py_BuildValue("i", rpmtsSetNativeDir(s->ts, nativeRoot));
+}
+
/** \ingroup py_c
*/
static void *
@@ -1217,6 +1233,8 @@ static struct PyMethodDef rpmts_methods[
{"next", (PyCFunction)rpmts_Next, METH_NOARGS,
"ts.next() -> te\n\
- Retrieve next transaction set element.\n" },
+ {"setNativeRoot",(PyCFunction) rpmts_SetNativeRoot, METH_VARARGS|METH_KEYWORDS,
+ NULL },
{NULL, NULL} /* sentinel */
};
@@ -1310,19 +1328,21 @@ static PyObject * rpmts_new(PyTypeObject
rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
char * rootDir = "/";
+ char * nativeDir = NULL;
rpmVSFlags vsflags = rpmExpandNumeric("%{?__vsflags}");
- char * kwlist[] = {"rootdir", "vsflags", 0};
+ char * kwlist[] = {"rootdir", "vsflags", "nativeRoot", 0};
if (_rpmts_debug < 0)
fprintf(stderr, "*** rpmts_new(%p,%p,%p)\n", s, args, kwds);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sis:rpmts_init", kwlist,
&rootDir, &vsflags))
return NULL;
s->ts = rpmtsCreate();
/* XXX: Why is there no rpmts_SetRootDir() ? */
(void) rpmtsSetRootDir(s->ts, rootDir);
+ (void) rpmtsSetNativeDir(s->ts, nativeDir);
/* XXX: make this use common code with rpmts_SetVSFlags() to check the
* python objects */
(void) rpmtsSetVSFlags(s->ts, vsflags);
diff -rup a/rpmqv.c b/rpmqv.c
--- a/rpmqv.c 2009-04-03 07:05:52.000000000 -0400
+++ b/rpmqv.c 2009-08-04 15:44:01.539559986 -0400
@@ -597,6 +597,7 @@ int main(int argc, char *argv[])
ts = rpmtsCreate();
(void) rpmtsSetRootDir(ts, rpmcliRootDir);
+ (void) rpmtsSetNativeDir(ts, rpmcliNativeRootDir);
switch (bigMode) {
#ifdef IAM_RPMDB
case MODE_INITDB:
diff --git a/tools/debugedit.c b/tools/debugedit.c
index f42b34a..5d150e8 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -1247,6 +1247,56 @@ edit_dwarf2 (DSO *dso)
return 0;
}
+/* The .GCC-command-line section will likely have the RPM_BUILD_ROOT string
+ in it. This causes check-buildroot to abort the build. Since this section
+ is informational, just change the string slightly to avoid problems with
+ check-buildroot. */
+static int
+edit_commandline (DSO *dso)
+{
+ Elf_Data *data;
+ Elf_Scn *scn;
+ char *p, *end;
+ int i, changed;
+
+ for (i = 1; i < dso->ehdr.e_shnum; ++i)
+ if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR))
+ && dso->shdr[i].sh_size)
+ {
+ const char *name = strptr (dso, dso->ehdr.e_shstrndx,
+ dso->shdr[i].sh_name);
+ if (strcmp (name, ".GCC-command-line") == 0)
+ {
+ scn = dso->scn[i];
+ data = elf_rawdata (scn, NULL);
+ assert (data != NULL && data->d_buf != NULL);
+ assert (elf_rawdata (scn, data) == NULL);
+ assert (data->d_off == 0);
+ assert (data->d_size == dso->shdr[i].sh_size);
+
+ changed = 0;
+ p = data->d_buf;
+ end = p + data->d_size - strlen("BUILDR00T");
+ while (p < end)
+ {
+ /* just change "BUILDROOT" to "BUILDR00T" */
+ if (*p == 'B' && strncmp(p, "BUILDROOT", 9) == 0)
+ {
+ p[6] = p[7] = '0';
+ changed = 1;
+ p += 9;
+ }
+ else
+ ++p;
+ }
+ if (changed)
+ elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+ }
+ }
+ return 0;
+}
+
+
static struct poptOption optionsTable[] = {
{ "base-dir", 'b', POPT_ARG_STRING, &base_dir, 0,
"base build directory of objects", NULL },
@@ -1530,7 +1580,7 @@ main (int argc, char *argv[])
if (stat(file, &stat_buf) < 0)
{
- fprintf (stderr, "Failed to open input file '%s': %s\n", file, strerror(errno));
+ fprintf (stderr, "Failed to stat input file '%s': %s\n", file, strerror(errno));
exit (1);
}
@@ -1564,6 +1614,10 @@ main (int argc, char *argv[])
if (strcmp (name, ".debug_info") == 0)
edit_dwarf2 (dso);
+ /* Handle gcc command-line section */
+ if (strcmp (name, ".GCC-command-line") == 0)
+ edit_commandline (dso);
+
break;
case SHT_NOTE:
if (do_build_id
--
devel mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/devel