summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2008-02-13 10:20:36 -0800
committerAaron Plattner <aplattner@nvidia.com>2008-02-13 10:20:36 -0800
commitb581a5923ce164af5c8cd5634f4cba4fd098f711 (patch)
tree3a0295cdd4fa9bcdd7e1ce6308834d552fe66402
parentf048a99526c5bad39bef29d414635ad3a5b53371 (diff)
1.0-66291.0-6629
-rw-r--r--Makefile36
-rw-r--r--backup.c10
-rw-r--r--command-list.c208
-rw-r--r--command-list.h4
-rw-r--r--crc.c1
-rw-r--r--files.c86
-rw-r--r--install-from-cwd.c132
-rw-r--r--kernel.c114
-rw-r--r--kernel.h1
-rw-r--r--log.c45
-rw-r--r--misc.c381
-rw-r--r--misc.h4
-rw-r--r--nvidia-installer.c66
-rw-r--r--nvidia-installer.h70
-rw-r--r--rtld_test.c4
-rwxr-xr-xrtld_test_Linux-x86bin0 -> 3056 bytes
-rwxr-xr-xrtld_test_Linux-x86_64bin0 -> 4688 bytes
-rw-r--r--sanity.c24
-rw-r--r--user-interface.c6
19 files changed, 964 insertions, 228 deletions
diff --git a/Makefile b/Makefile
index 655d171..7e8224a 100644
--- a/Makefile
+++ b/Makefile
@@ -102,8 +102,14 @@ TLS_TEST_DSO_SO = tls_test_dso_$(INSTALLER_OS)-$(INSTALLER_ARCH).so
TLS_TEST_32_C = g_tls_test_32.c
TLS_TEST_DSO_32_C = g_tls_test_dso_32.c
-TLS_TEST_32 = tls_test_Linux-x86
-TLS_TEST_DSO_SO_32 = tls_test_dso_Linux-x86.so
+TLS_TEST_32 = tls_test_$(INSTALLER_OS)-x86
+TLS_TEST_DSO_SO_32 = tls_test_dso_$(INSTALLER_OS)-x86.so
+
+RTLD_TEST_C = g_rtld_test.c
+RTLD_TEST = rtld_test_$(INSTALLER_OS)-$(INSTALLER_ARCH)
+
+RTLD_TEST_32_C = g_rtld_test_32.c
+RTLD_TEST_32 = rtld_test_$(INSTALLER_OS)-x86
GEN_UI_ARRAY = ./gen-ui-array
CONFIG_H = config.h
@@ -115,7 +121,8 @@ TLS_MODEL=initial-exec
PIC=-fPIC
CFLAGS += -DNV_X86_64
# Only Linux-x86_64 needs the tls_test_32 files
-COMPAT_32_SRC = $(TLS_TEST_32_C) $(TLS_TEST_DSO_32_C)
+COMPAT_32_SRC = $(TLS_TEST_32_C) $(TLS_TEST_DSO_32_C) \
+ $(RTLD_TEST_32_C)
else
# So far all other platforms use local-exec
TLS_MODEL=local-exec
@@ -144,7 +151,7 @@ SRC = backup.c \
sanity.c
ALL_SRC = $(SRC) $(NCURSES_UI_C) $(TLS_TEST_C) $(TLS_TEST_DSO_C) \
- $(COMPAT_32_SRC) $(STAMP_C)
+ $(RTLD_TEST_C) $(COMPAT_32_SRC) $(STAMP_C)
OBJS = $(ALL_SRC:.c=.o)
@@ -196,6 +203,12 @@ $(TLS_TEST_32_C): $(GEN_UI_ARRAY) $(TLS_TEST_32)
$(TLS_TEST_DSO_32_C): $(GEN_UI_ARRAY) $(TLS_TEST_DSO_SO_32)
$(GEN_UI_ARRAY) $(TLS_TEST_DSO_SO_32) tls_test_dso_array_32 > $@
+$(RTLD_TEST_C): $(GEN_UI_ARRAY) $(RTLD_TEST)
+ $(GEN_UI_ARRAY) $(RTLD_TEST) rtld_test_array > $@
+
+$(RTLD_TEST_32_C): $(GEN_UI_ARRAY) $(RTLD_TEST_32)
+ $(GEN_UI_ARRAY) $(RTLD_TEST_32) rtld_test_array_32 > $@
+
ncurses-ui.o: ncurses-ui.c $(CONFIG_H)
$(CC) -c $(ALL_CFLAGS) $< -fPIC -o $@
@@ -228,7 +241,7 @@ $(STAMP_C): $(filter-out $(STAMP_C:.c=.o), $(OBJS))
clean clobber:
rm -rf $(NVIDIA_INSTALLER) $(MKPRECOMPILED) \
$(NCURSES_UI) $(NCURSES_UI_C) \
- $(TLS_TEST_C) $(TLS_TEST_DSO_C) $(COMPAT_32_SRC) \
+ $(TLS_TEST_C) $(TLS_TEST_DSO_C) $(RTLD_TEST_C) $(COMPAT_32_SRC) \
$(GEN_UI_ARRAY) $(CONFIG_H) $(STAMP_C) *.o *~ *.d
# rule to rebuild tls_test and tls_test_dso; a precompiled tls_test
@@ -250,6 +263,19 @@ rebuild_tls_test_dso: tls_test_dso.c
tls_test: tls_test.c
touch $@
+# rule to rebuild rtld_test; a precompiled rtld_test is distributed with
+# nvidia-installer to simplify x86-64 builds.
+
+rebuild_rtld_test: rtld_test.c
+ gcc -Wall -O2 -fomit-frame-pointer -o $(RTLD_TEST) -lGL $<
+ strip $(RTLD_TEST)
+
+# dummy rule to override implicit rule that builds dls_test from
+# rtld_test.c
+
+rtld_test: rtld_test.c
+ touch $@
+
print_version:
@ echo $(NVIDIA_INSTALLER_VERSION)
diff --git a/backup.c b/backup.c
index 9841541..899cd74 100644
--- a/backup.c
+++ b/backup.c
@@ -219,8 +219,14 @@ int do_backup(Options *op, const char *filename)
}
if (lstat(filename, &stat_buf) == -1) {
- ui_error(op, "Unable to determine properties for file '%s' (%s).",
- filename, strerror(errno));
+ switch (errno) {
+ case ENOENT:
+ ret_val = TRUE;
+ break;
+ default:
+ ui_error(op, "Unable to determine properties for file '%s' (%s).",
+ filename, strerror(errno));
+ }
goto done;
}
diff --git a/command-list.c b/command-list.c
index ae63036..fc721d6 100644
--- a/command-list.c
+++ b/command-list.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <fts.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
@@ -91,17 +92,33 @@ CommandList *build_command_list(Options *op, Package *p)
if (!op->kernel_module_only) {
find_conflicting_xfree86_libraries
- (DEFAULT_XFREE86_INSTALLATION_PREFIX,l);
+ (op, DEFAULT_XFREE86_INSTALLATION_PREFIX, l);
if (strcmp(DEFAULT_XFREE86_INSTALLATION_PREFIX,
op->xfree86_prefix) != 0)
- find_conflicting_xfree86_libraries(op->xfree86_prefix, l);
+ find_conflicting_xfree86_libraries(op, op->xfree86_prefix, l);
find_conflicting_opengl_libraries
- (DEFAULT_OPENGL_INSTALLATION_PREFIX,l);
+ (op, DEFAULT_OPENGL_INSTALLATION_PREFIX, l);
if (strcmp(DEFAULT_OPENGL_INSTALLATION_PREFIX, op->opengl_prefix) != 0)
- find_conflicting_opengl_libraries(op->opengl_prefix, l);
+ find_conflicting_opengl_libraries(op, op->opengl_prefix, l);
+
+#if defined(NV_X86_64)
+ if (op->compat32_prefix != NULL) {
+ char *prefix = nvstrcat(op->compat32_prefix,
+ DEFAULT_OPENGL_INSTALLATION_PREFIX, NULL);
+ find_conflicting_opengl_libraries(op, prefix, l);
+ nvfree(prefix);
+
+ if (strcmp(DEFAULT_OPENGL_INSTALLATION_PREFIX,
+ op->opengl_prefix) != 0) {
+ prefix = nvstrcat(op->compat32_prefix, op->opengl_prefix, NULL);
+ find_conflicting_opengl_libraries(op, prefix, l);
+ nvfree(prefix);
+ }
+ }
+#endif /* NV_X86_64 */
}
find_conflicting_kernel_modules(op, p, l);
@@ -148,6 +165,16 @@ CommandList *build_command_list(Options *op, Package *p)
p->entries[i].dst,
p->entries[i].mode);
}
+
+ /*
+ * delete the temporary libGL.la file generated based on
+ * the template earlier.
+ */
+
+ if (p->entries[i].flags & FILE_TYPE_LIBGL_LA) {
+ add_command(c, DELETE_CMD,
+ p->entries[i].file);
+ }
}
@@ -365,7 +392,24 @@ int execute_command_list(Options *op, CommandList *c,
***************************************************************************
*/
-static const char *__libdirs[] = { "lib", "lib64", NULL };
+typedef struct {
+ const char *name;
+ int len;
+} ConflictingLibInfo;
+
+static void find_conflicting_libraries(Options *op,
+ const char *prefix,
+ ConflictingLibInfo *libs,
+ FileList *l);
+
+static ConflictingLibInfo __xfree86_libs[] = {
+ { "libGLcore.", 10 /* strlen("libGLcore.") */ },
+ { "libGL.", 6 /* strlen("libGL.") */ },
+ { "libGLwrapper.", 13 /* strlen("libGLwrapper.") */ },
+ { "libglx.", 7 /* strlen("libglx.") */ },
+ { "libXvMCNVIDIA", 14 /* strlen("libXvMCNVIDIA") */ },
+ { NULL, 0 }
+};
/*
* find_conflicting_xfree86_libraries() - search for conflicting
@@ -373,60 +417,21 @@ static const char *__libdirs[] = { "lib", "lib64", NULL };
* libdirs.
*/
-void find_conflicting_xfree86_libraries(const char *xprefix, FileList *l)
+void find_conflicting_xfree86_libraries(Options *op,
+ const char *xprefix, FileList *l)
{
- char *s;
- const char *libdir;
- int i;
+ find_conflicting_libraries(op, xprefix, __xfree86_libs, l);
- for (i = 0; __libdirs[i]; i++) {
-
- libdir = __libdirs[i];
-
- /*
- * [xprefix]/[libdir]/libGL.*
- * [xprefix]/[libdir]/libGLcore.*
- * [xprefix]/[libdir]/libXvMCNVIDIA*
- * [xprefix]/[libdir]/libGLwrapper.*
- */
-
- s = nvstrcat(xprefix, "/", libdir, NULL);
- find_matches(s, "libGL.", l, FALSE);
- find_matches(s, "libGLcore.", l, FALSE);
- find_matches(s, "libXvMCNVIDIA", l, FALSE);
- find_matches(s, "libGLwrapper.", l, FALSE);
- free(s);
-
- /*
- * [xprefix]/[libdir]/tls/libGL.*
- * [xprefix]/[libdir]/tls/libGLcore.*
- * [xprefix]/[libdir]/tls/libXvMCNVIDIA*
- * [xprefix]/[libdir]/tls/libGLwrapper.*
- */
-
- s = nvstrcat(xprefix, "/", libdir, "/tls", NULL);
- find_matches(s, "libGL.", l, FALSE);
- find_matches(s, "libGLcore.", l, FALSE);
- find_matches(s, "libXvMCNVIDIA", l, FALSE);
- find_matches(s, "libGLwrapper.", l, FALSE);
- free(s);
-
- /*
- * [xprefix]/[libdir]/modules/extensions/libGLcore.*
- * [xprefix]/[libdir]/modules/extensions/libglx.*
- * [xprefix]/[libdir]/modules/extensions/libGLwrapper.*
- */
-
- s = nvstrcat(xprefix, "/", libdir, "/modules/extensions", NULL);
- find_matches(s, "libglx.", l, FALSE);
- find_matches(s, "libGLcore.", l, FALSE);
- find_matches(s, "libGLwrapper.", l, FALSE);
- free(s);
- }
-
} /* find_conflicting_xfree86_libraries() */
+static ConflictingLibInfo __opengl_libs[] = {
+ { "libGLcore.", 10 /* strlen("libGLcore.") */ },
+ { "libGL.", 6 /* strlen("libGL.") */ },
+ { "libnvidia-tls.", 14 /* strlen("libnvidia-tls.") */ },
+ { "libGLwrapper.", 13 /* strlen("libGLwrapper.") */ },
+ { NULL, 0 }
+};
/*
* find_conflicting_opengl_libraries() - search for conflicting
@@ -434,40 +439,11 @@ void find_conflicting_xfree86_libraries(const char *xprefix, FileList *l)
* libdirs.
*/
-void find_conflicting_opengl_libraries(const char *glprefix, FileList *l)
+void find_conflicting_opengl_libraries(Options *op,
+ const char *glprefix, FileList *l)
{
- char *s;
- const char *libdir;
- int i;
+ find_conflicting_libraries(op, glprefix, __opengl_libs, l);
- for (i = 0; __libdirs[i]; i++) {
-
- libdir = __libdirs[i];
-
- /*
- * [glprefix]/[libdir]/libGL.*
- * [glprefix]/[libdir]/libGLcore.*
- * [glprefix]/[libdir]/libGLwrapper.*
- * [glprefix]/[libdir]/tls/libGL.*
- * [glprefix]/[libdir]/tls/libGLcore.*
- * [glprefix]/[libdir]/tls/libGLwrapper.*
- */
-
- s = nvstrcat(glprefix, "/", libdir, NULL);
- find_matches(s, "libGL.", l, FALSE);
- find_matches(s, "libGLcore.", l, FALSE);
- find_matches(s, "libGLwrapper.", l, FALSE);
- find_matches(s, "libnvidia-tls.", l, FALSE);
- free(s);
-
- s = nvstrcat(glprefix, "/", libdir, "/tls", NULL);
- find_matches(s, "libGL.", l, FALSE);
- find_matches(s, "libGLcore.", l, FALSE);
- find_matches(s, "libGLwrapper.", l, FALSE);
- find_matches(s, "libnvidia-tls.", l, FALSE);
- free(s);
- }
-
} /* find_conflicting_opengl_libraries() */
@@ -538,6 +514,66 @@ static void find_existing_files(Package *p, FileList *l, unsigned int flag)
+
+/*
+ * find_conflicting_libraries() - search for any conflicting
+ * libraries in all relevant libdirs within the hierarchy under
+ * the given prefix.
+ */
+
+static void find_conflicting_libraries(Options *op,
+ const char *prefix,
+ ConflictingLibInfo *libs,
+ FileList *l)
+{
+ int i;
+ char *paths[3];
+ FTS *fts;
+ FTSENT *ent;
+
+ paths[0] = nvstrcat(prefix, "/", "lib", NULL);
+ paths[1] = nvstrcat(prefix, "/", "lib64", NULL);
+ paths[2] = NULL;
+
+ fts = fts_open(paths, FTS_LOGICAL | FTS_NOSTAT, NULL);
+ if (!fts) return;
+
+ while ((ent = fts_read(fts)) != NULL) {
+ switch (ent->fts_info) {
+ case FTS_F:
+ case FTS_SLNONE:
+ for (i = 0; libs[i].name; i++) {
+ if (!strncmp(ent->fts_name, libs[i].name, libs[i].len))
+ add_file_to_list(NULL, ent->fts_path, l);
+ }
+ break;
+
+ case FTS_DP:
+ case FTS_D:
+ if (op->no_recursion)
+ fts_set(fts, ent, FTS_SKIP);
+ break;
+
+ default:
+ /*
+ * we only care about regular files, symbolic links
+ * and directories; traversing the hierarchy logically
+ * to simplify handling of paths with symbolic links
+ * to directories, we only need to handle broken links
+ * and, if recursion was disabled, directories.
+ */
+ break;
+ }
+ }
+
+ fts_close(fts);
+
+ for (i = 0; paths[i]; i++)
+ nvfree(paths[i]);
+
+} /* find_conflicting_libraries() */
+
+
/*
* condense_file_list() - Take a FileList stucture and delete any
* duplicate entries in the list. This is a pretty brain dead
diff --git a/command-list.h b/command-list.h
index d25415e..ca85a23 100644
--- a/command-list.h
+++ b/command-list.h
@@ -83,8 +83,8 @@ CommandList *build_command_list(Options*, Package *);
void free_command_list(Options*, CommandList*);
int execute_command_list(Options*, CommandList*, const char*, const char*);
-void find_conflicting_xfree86_libraries(const char*, FileList*);
-void find_conflicting_opengl_libraries(const char*, FileList*);
+void find_conflicting_xfree86_libraries(Options*,const char*, FileList*);
+void find_conflicting_opengl_libraries(Options*, const char*, FileList*);
void condense_file_list(FileList *l);
#endif /* __NVIDIA_INSTALLER_COMMAND_LIST_H__ */
diff --git a/crc.c b/crc.c
index d085e1a..a5b4a4f 100644
--- a/crc.c
+++ b/crc.c
@@ -92,6 +92,7 @@ uint32 compute_crc(Options *op, const char *filename)
if ((fd = open(filename, O_RDONLY)) == -1) goto fail;
if (fstat(fd, &stat_buf) == -1) goto fail;
+ if (stat_buf.st_size == 0) return 0;
len = stat_buf.st_size;
buf = mmap(0, len, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
diff --git a/files.c b/files.c
index 02934e0..a407520 100644
--- a/files.c
+++ b/files.c
@@ -223,6 +223,8 @@ int copy_file(Options *op, const char *srcfile,
srcfile, strerror (errno));
goto fail;
}
+ if (stat_buf.st_size == 0)
+ goto done;
if (lseek(dst_fd, stat_buf.st_size - 1, SEEK_SET) == -1) {
ui_error (op, "Unable to set file size for '%s' (%s)",
dstfile, strerror (errno));
@@ -259,6 +261,7 @@ int copy_file(Options *op, const char *srcfile,
goto fail;
}
+ done:
/*
* the mode used to create dst_fd may have been affected by the
* user's umask; so explicitly set the mode again
@@ -377,7 +380,9 @@ void select_tls_class(Options *op, Package *p)
int i;
if (!tls_test(op, FALSE)) {
-
+ op->which_tls = (op->which_tls & TLS_LIB_TYPE_FORCED);
+ op->which_tls |= TLS_LIB_CLASSIC_TLS;
+
/*
* tls libraries will not run on this system; just install the
* classic OpenGL libraries: clear the FILE_TYPE of any
@@ -387,12 +392,16 @@ void select_tls_class(Options *op, Package *p)
ui_log(op, "Installing classic TLS OpenGL libraries.");
for (i = 0; i < p->num_entries; i++) {
- if (p->entries[i].flags & FILE_CLASS_NEW_TLS) {
+ if ((p->entries[i].flags & FILE_CLASS_NEW_TLS) &&
+ (p->entries[i].flags & FILE_CLASS_NATIVE)) {
+ nvfree(p->entries[i].dst);
p->entries[i].flags &= ~FILE_TYPE_MASK;
p->entries[i].dst = NULL;
}
}
} else {
+ op->which_tls = (op->which_tls & TLS_LIB_TYPE_FORCED);
+ op->which_tls |= TLS_LIB_NEW_TLS;
/*
* tls libraries will run on this system: install both the
@@ -410,7 +419,9 @@ void select_tls_class(Options *op, Package *p)
*/
if (!tls_test(op, TRUE)) {
-
+ op->which_tls_compat32 = (op->which_tls_compat32 & TLS_LIB_TYPE_FORCED);
+ op->which_tls_compat32 |= TLS_LIB_CLASSIC_TLS;
+
/*
* 32bit tls libraries will not run on this system; just
* install the classic OpenGL libraries: clear the FILE_TYPE
@@ -420,13 +431,17 @@ void select_tls_class(Options *op, Package *p)
ui_log(op, "Installing classic TLS 32bit OpenGL libraries.");
for (i = 0; i < p->num_entries; i++) {
- if (p->entries[i].flags & FILE_CLASS_NEW_TLS_32) {
+ if ((p->entries[i].flags & FILE_CLASS_NEW_TLS) &&
+ (p->entries[i].flags & FILE_CLASS_COMPAT32)) {
+ nvfree(p->entries[i].dst);
p->entries[i].flags &= ~FILE_TYPE_MASK;
p->entries[i].dst = NULL;
}
}
} else {
-
+ op->which_tls_compat32 = (op->which_tls_compat32 & TLS_LIB_TYPE_FORCED);
+ op->which_tls_compat32 |= TLS_LIB_NEW_TLS;
+
/*
* 32bit tls libraries will run on this system: install both
* the classic and new TLS libraries.
@@ -478,6 +493,17 @@ int set_destinations(Options *op, Package *p)
path = p->entries[i].path;
break;
+ case FILE_TYPE_TLS_LIB:
+ case FILE_TYPE_TLS_SYMLINK:
+ prefix = op->opengl_prefix;
+ path = p->entries[i].path;
+ break;
+
+ case FILE_TYPE_LIBGL_LA:
+ prefix = op->opengl_prefix;
+ path = p->entries[i].path;
+ break;
+
/*
* XXX should the OpenGL headers and documentation also go
* under the OpenGL installation prefix? The Linux OpenGL
@@ -528,6 +554,23 @@ int set_destinations(Options *op, Package *p)
name = p->entries[i].name;
p->entries[i].dst = nvstrcat(prefix, "/", path, "/", name, NULL);
+
+#if defined(NV_X86_64)
+ if ((p->entries[i].flags & FILE_CLASS_COMPAT32) &&
+ (op->compat32_prefix != NULL)) {
+
+ /*
+ * prepend an additional prefix; this is currently only
+ * used for Debian GNU/Linux on Linux/x86-64, but may see
+ * more use in the future.
+ */
+
+ char *dst = p->entries[i].dst;
+ p->entries[i].dst = nvstrcat(op->compat32_prefix, dst, NULL);
+
+ nvfree(dst);
+ }
+#endif /* NV_X86_64 */
}
return TRUE;
@@ -625,6 +668,21 @@ int get_prefixes (Options *op)
remove_trailing_slashes(op->opengl_prefix);
ui_expert(op, "OpenGL installation prefix is: '%s'", op->opengl_prefix);
+#if defined(NV_X86_64)
+ if (op->expert) {
+ ret = ui_get_input(op, op->compat32_prefix,
+ "Compat32 installation prefix");
+ if (ret && ret[0]) {
+ op->compat32_prefix = ret;
+ if (!confirm_path(op, op->compat32_prefix)) return FALSE;
+ }
+ }
+
+ remove_trailing_slashes(op->compat32_prefix);
+ ui_expert(op, "Compat32 installation prefix is: '%s'",
+ op->compat32_prefix);
+#endif /* NV_X86_64 */
+
if (op->expert) {
ret = ui_get_input(op, op->installer_prefix,
"Installer installation prefix");
@@ -717,7 +775,10 @@ void remove_non_kernel_module_files_from_package(Options *op, Package *p)
void remove_trailing_slashes(char *s)
{
- int len = strlen(s);
+ int len;
+
+ if (s == NULL) return;
+ len = strlen(s);
while (s[len-1] == '/') s[--len] = '\0';
@@ -1348,8 +1409,10 @@ void process_libGL_la_files(Options *op, Package *p)
struct stat stat_buf;
char *src, *dst, *tmp, *tmp0, *tmp1, *tmpfile;
- for (i = 0; i < p->num_entries; i++) {
- if (p->entries[i].flags & FILE_TYPE_LIBGL_LA) {
+ int package_num_entries = p->num_entries;
+
+ for (i = 0; i < package_num_entries; i++) {
+ if ((p->entries[i].flags & FILE_TYPE_LIBGL_LA)) {
src_fd = dst_fd = -1;
tmp0 = tmp1 = src = dst = tmpfile = NULL;
@@ -1436,6 +1499,11 @@ void process_libGL_la_files(Options *op, Package *p)
memcpy(dst, tmp1, len);
+ /* invalidate the template file */
+
+ p->entries[i].flags &= ~FILE_TYPE_MASK;
+ p->entries[i].dst = NULL;
+
/* add this new file to the package */
n = p->num_entries;
@@ -1447,7 +1515,7 @@ void process_libGL_la_files(Options *op, Package *p)
p->entries[n].path = p->entries[i].path;
p->entries[n].target = NULL;
p->entries[n].flags = ((p->entries[i].flags & FILE_CLASS_MASK) |
- FILE_TYPE_OPENGL_LIB);
+ FILE_TYPE_LIBGL_LA);
p->entries[n].mode = p->entries[i].mode;
p->entries[n].name = nvstrdup(p->entries[i].name);
diff --git a/install-from-cwd.c b/install-from-cwd.c
index eb72e77..514b79f 100644
--- a/install-from-cwd.c
+++ b/install-from-cwd.c
@@ -150,8 +150,12 @@ int install_from_cwd(Options *op)
if (!link_kernel_module(op, p)) goto failed;
} else {
-
- /* XXX we need to do a cc version check */
+ /*
+ * make sure the required development tools are present on
+ * this system before attempting to verify the compiler and
+ * trying to build a custom kernel interface.
+ */
+ if (!check_development_tools(op)) goto failed;
/*
* we do not have a prebuilt kernel interface; thus we'll need
@@ -162,6 +166,13 @@ int install_from_cwd(Options *op)
if (!determine_kernel_source_path(op)) goto failed;
determine_kernel_output_path(op);
+ /*
+ * make sure that the selected or default system compiler
+ * is compatible with the target kernel; the user may choose
+ * to override the check.
+ */
+ if (!check_cc_version(op, p)) goto failed;
+
/* and now, build the kernel interface */
if (!build_kernel_module(op, p)) goto failed;
@@ -211,6 +222,15 @@ int install_from_cwd(Options *op)
*/
process_libGL_la_files(op, p);
+
+#if defined(NV_X86_64)
+ /*
+ * ask if we should install the 32bit compatibility files on
+ * this machine.
+ */
+
+ should_install_compat32_files(op, p);
+#endif /* NV_X86_64 */
}
/*
@@ -264,6 +284,7 @@ int install_from_cwd(Options *op)
check_installed_files_from_package(op, p);
if (!check_sysvipc(op)) goto failed;
+ if (!check_runtime_configuration(op, p)) goto failed;
/* done */
@@ -367,6 +388,8 @@ int add_this_kernel(Options *op)
* - a filename (relative to the cwd)
* - an octal value describing the permissions
* - a flag describing the file type
+ * - certain file types have an architecture
+ * - certain file types have a second flag
* - certain file types will have a path
* - symbolic links will name the target of the link
*/
@@ -378,7 +401,7 @@ static Package *parse_manifest (Options *op)
int fd, len = 0;
struct stat stat_buf;
Package *p;
- char *manifest = NULL, *ptr;
+ char *manifest = MAP_FAILED, *ptr;
p = (Package *) nvalloc(sizeof (Package));
@@ -396,7 +419,7 @@ static Package *parse_manifest (Options *op)
len = stat_buf.st_size;
manifest = mmap(0, len, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
- if (manifest == (void *) -1) goto cannot_open;
+ if (manifest == MAP_FAILED) goto cannot_open;
/* the first line is the description */
@@ -412,35 +435,20 @@ static Package *parse_manifest (Options *op)
if (!nvid_version(p->version_string, &p->major, &p->minor, &p->patch))
goto invalid_manifest_file;
- /* the third line is the kernel module filename */
-
- line++;
- p->kernel_module_filename = get_next_line(ptr, &ptr);
- if (!p->kernel_module_filename) goto invalid_manifest_file;
-
- /*
- * XXX The kernel module filename in the .manifest file can no
- * longer be used: the filename is different for 2.4 or 2.6
- * kernels.
- */
-
- free(p->kernel_module_filename);
- p->kernel_module_filename = NULL;
-
- /* new fourth line is the kernel interface filename */
+ /* new third line is the kernel interface filename */
line++;
p->kernel_interface_filename = get_next_line(ptr, &ptr);
if (!p->kernel_interface_filename) goto invalid_manifest_file;
- /* the fifth line is the kernel module name */
+ /* the fourth line is the kernel module name */
line++;
p->kernel_module_name = get_next_line(ptr, &ptr);
if (!p->kernel_module_name) goto invalid_manifest_file;
/*
- * the sixth line is a whitespace-separated list of kernel modules
+ * the fifth line is a whitespace-separated list of kernel modules
* to be unloaded before installing the new kernel module
*/
@@ -460,7 +468,7 @@ static Package *parse_manifest (Options *op)
} while (p->bad_modules[n-1]);
/*
- * the seventh line is a whitespace-separated list of kernel module
+ * the sixth line is a whitespace-separated list of kernel module
* filenames to be uninstalled before installing the new kernel
* module
*/
@@ -480,7 +488,7 @@ static Package *parse_manifest (Options *op)
p->bad_module_filenames[n-1] = read_next_word(c, &c);
} while (p->bad_module_filenames[n-1]);
- /* the eighth line is the kernel module build directory */
+ /* the seventh line is the kernel module build directory */
line++;
p->kernel_module_build_directory = get_next_line(ptr, &ptr);
@@ -488,7 +496,7 @@ static Package *parse_manifest (Options *op)
remove_trailing_slashes(p->kernel_module_build_directory);
/*
- * the nineth line is the directory containing precompiled kernel
+ * the eigth line is the directory containing precompiled kernel
* interfaces
*/
@@ -539,7 +547,7 @@ static Package *parse_manifest (Options *op)
}
free(tmpstr);
- /* now, parse the flags */
+ /* every file has a type field */
p->entries[n].flags = 0x0;
@@ -558,39 +566,63 @@ static Package *parse_manifest (Options *op)
p->entries[n].flags |= FILE_TYPE_LIBGL_LA;
else if (strcmp(flag, "XFREE86_LIB") == 0)
p->entries[n].flags |= FILE_TYPE_XFREE86_LIB;
+ else if (strcmp(flag, "TLS_LIB") == 0)
+ p->entries[n].flags |= FILE_TYPE_TLS_LIB;
else if (strcmp(flag, "DOCUMENTATION") == 0)
p->entries[n].flags |= FILE_TYPE_DOCUMENTATION;
else if (strcmp(flag, "OPENGL_SYMLINK") == 0)
p->entries[n].flags |= FILE_TYPE_OPENGL_SYMLINK;
else if (strcmp(flag, "XFREE86_SYMLINK") == 0)
p->entries[n].flags |= FILE_TYPE_XFREE86_SYMLINK;
+ else if (strcmp(flag, "TLS_SYMLINK") == 0)
+ p->entries[n].flags |= FILE_TYPE_TLS_SYMLINK;
else if (strcmp(flag, "INSTALLER_BINARY") == 0)
p->entries[n].flags |= FILE_TYPE_INSTALLER_BINARY;
else if (strcmp(flag, "UTILITY_BINARY") == 0)
p->entries[n].flags |= FILE_TYPE_UTILITY_BINARY;
- else if (strcmp(flag, "OPENGL_LIB_CLASSIC_TLS") == 0)
- p->entries[n].flags |= (FILE_TYPE_OPENGL_LIB |
- FILE_CLASS_CLASSIC_TLS);
- else if (strcmp(flag, "OPENGL_LIB_NEW_TLS") == 0)
- p->entries[n].flags |= (FILE_TYPE_OPENGL_LIB |
- FILE_CLASS_NEW_TLS);
- else if (strcmp(flag, "OPENGL_SYMLINK_CLASSIC_TLS") == 0)
- p->entries[n].flags |= (FILE_TYPE_OPENGL_SYMLINK |
- FILE_CLASS_CLASSIC_TLS);
- else if (strcmp(flag, "OPENGL_SYMLINK_NEW_TLS") == 0)
- p->entries[n].flags |= (FILE_TYPE_OPENGL_SYMLINK |
- FILE_CLASS_NEW_TLS);
- else if (strcmp(flag, "OPENGL_LIB_NEW_TLS_32") == 0)
- p->entries[n].flags |= (FILE_TYPE_OPENGL_LIB |
- FILE_CLASS_NEW_TLS_32);
- else if (strcmp(flag, "OPENGL_SYMLINK_NEW_TLS_32") == 0)
- p->entries[n].flags |= (FILE_TYPE_OPENGL_SYMLINK |
- FILE_CLASS_NEW_TLS_32);
- else
+ else {
+ nvfree(flag);
goto invalid_manifest_file;
-
- free(flag);
-
+ }
+
+ nvfree(flag);
+
+ /* some libs/symlinks have an arch field */
+
+ if (p->entries[n].flags & FILE_TYPE_HAVE_ARCH) {
+ flag = read_next_word(c, &c);
+ if (!flag) goto invalid_manifest_file;
+
+ if (strcmp(flag, "COMPAT32") == 0)
+ p->entries[n].flags |= FILE_CLASS_COMPAT32;
+ else if (strcmp(flag, "NATIVE") == 0)
+ p->entries[n].flags |= FILE_CLASS_NATIVE;
+ else {
+ nvfree(flag);
+ goto invalid_manifest_file;
+ }
+
+ nvfree(flag);
+ }
+
+ /* some libs/symlinks have a class field */
+
+ if (p->entries[n].flags & FILE_TYPE_HAVE_CLASS) {
+ flag = read_next_word(c, &c);
+ if (!flag) goto invalid_manifest_file;
+
+ if (strcmp(flag, "CLASSIC") == 0)
+ p->entries[n].flags |= FILE_CLASS_CLASSIC_TLS;
+ else if (strcmp(flag, "NEW") == 0)
+ p->entries[n].flags |= FILE_CLASS_NEW_TLS;
+ else {
+ nvfree(flag);
+ goto invalid_manifest_file;
+ }
+
+ nvfree(flag);
+ }
+
/* libs and documentation have a path field */
if (p->entries[n].flags & FILE_TYPE_HAVE_PATH) {
@@ -629,7 +661,7 @@ static Package *parse_manifest (Options *op)
} while (!done);
- if (manifest) munmap(manifest, len);
+ munmap(manifest, len);
if (fd != -1) close(fd);
return p;
@@ -647,7 +679,7 @@ static Package *parse_manifest (Options *op)
fail:
if (p && p->entries) free(p->entries);
if (p) free(p);
- if (manifest) munmap(manifest, len);
+ if (manifest != MAP_FAILED) munmap(manifest, len);
if (fd != -1) close(fd);
return NULL;
diff --git a/kernel.c b/kernel.c
index 9e332ff..227f665 100644
--- a/kernel.c
+++ b/kernel.c
@@ -51,7 +51,6 @@ static int check_for_loaded_kernel_module(Options *op, const char *);
static int rmmod_kernel_module(Options *op, const char *);
static PrecompiledInfo *download_updated_kernel_interface(Options*, Package*,
const char*);
-static int cc_version_check(Options *op, Package *p);
static int rivafb_check(Options *op, Package *p);
static void rivafb_module_check(Options *op, Package *p);
@@ -201,13 +200,23 @@ int determine_kernel_source_path(Options *op)
/*
* I suppose we could ask them here for the kernel source
- * path, but we've already given them multiple methods of
+ * path, but we've already given users multiple methods of
* specifying their kernel source tree.
*/
return FALSE;
}
-
+
+ /* reject /usr as an invalid kernel source path */
+
+ if (!strcmp(op->kernel_source_path, "/usr") ||
+ !strcmp(op->kernel_source_path, "/usr/")) {
+ ui_error (op, "The kernel source path '%s' is invalid. %s",
+ op->kernel_source_path, install_your_kernel_source);
+ op->kernel_source_path = NULL;
+ return FALSE;
+ }
+
/* check that the kernel source path exists */
if (!directory_exists(op, op->kernel_source_path)) {
@@ -299,7 +308,8 @@ int determine_kernel_source_path(Options *op)
int determine_kernel_output_path(Options *op)
{
- char *str;
+ char *str, *tmp;
+ int len;
/* check --kernel-output-path */
@@ -307,6 +317,14 @@ int determine_kernel_output_path(Options *op)
ui_log(op, "Using the kernel output path '%s' as specified by the "
"'--kernel-output-path' commandline option.",
op->kernel_output_path);
+
+ if (!directory_exists(op, op->kernel_output_path)) {
+ ui_error(op, "The kernel output path '%s' does not exist.",
+ op->kernel_output_path);
+ op->kernel_output_path = NULL;
+ return FALSE;
+ }
+
return TRUE;
}
@@ -317,9 +335,38 @@ int determine_kernel_output_path(Options *op)
ui_log(op, "Using the kernel output path '%s', as specified by the "
"SYSOUT environment variable.", str);
op->kernel_output_path = str;
+
+ if (!directory_exists(op, op->kernel_output_path)) {
+ ui_error(op, "The kernel output path '%s' does not exist.",
+ op->kernel_output_path);
+ op->kernel_output_path = NULL;
+ return FALSE;
+ }
+
return TRUE;
}
+ /* check /lib/modules/`uname -r`/{source,build} */
+
+ tmp = get_kernel_name(op);
+
+ if (tmp) {
+ str = nvstrcat("/lib/modules/", tmp, "/source", NULL);
+ len = strlen(str);
+
+ if (!strncmp(op->kernel_source_path, str, len)) {
+ nvfree(str);
+ str = nvstrcat("/lib/modules/", tmp, "/build", NULL);
+
+ if (directory_exists(op, str)) {
+ op->kernel_output_path = str;
+ return TRUE;
+ }
+ }
+
+ nvfree(str);
+ }
+
op->kernel_output_path = op->kernel_source_path;
return TRUE;
}
@@ -368,9 +415,6 @@ int link_kernel_module(Options *op, Package *p)
* build_kernel_module() - determine the kernel include directory,
* copy the kernel module source files into a temporary directory, and
* compile nvidia.o.
- *
- * XXX depends on things like make, gcc, ld, existing. Should we
- * check that the user has these before doing this?
*/
int build_kernel_module(Options *op, Package *p)
@@ -378,8 +422,6 @@ int build_kernel_module(Options *op, Package *p)
char *result, *cmd, *tmp;
int len, ret;
- if (!cc_version_check(op, p)) return FALSE;
-
/*
* touch all the files in the build directory to avoid make time
* skew messages
@@ -625,11 +667,30 @@ int test_kernel_module(Options *op, Package *p)
if (!op->expert) ui_log(op, "Kernel module load error: %s", data);
ret = FALSE;
+
+ nvfree(cmd);
+ nvfree(data);
+
+ /*
+ * display/log the last five lines of the kernel ring buffer
+ * to provide further details on the load failure.
+ */
+
+ cmd = nvstrcat(op->utils[DMESG], " | ",
+ op->utils[TAIL], " -n 5", NULL);
+
+ if (!run_command(op, cmd, &data, FALSE, 0, TRUE))
+ ui_log(op, "Kernel messages:\n%s", data);
} else {
free(cmd);
+
+ /*
+ * attempt to unload the kernel module, but don't abort if
+ * this fails: the kernel may not have been configured with
+ * support for module unloading (Linux 2.6).
+ */
cmd = nvstrcat(op->utils[RMMOD], " ", p->kernel_module_name, NULL);
run_command(op, cmd, NULL, FALSE, 0, TRUE);
- /* what if we fail to rmmod? */
ret = TRUE;
}
@@ -770,12 +831,15 @@ int check_for_unloaded_kernel_module(Options *op, Package *p)
if (check_for_loaded_kernel_module(op, p->bad_modules[n])) {
ui_error(op, "An NVIDIA kernel module '%s' appears to already "
"be loaded in your kernel. This may be because it is "
- "in use (for example, by the X server). Please be "
- "sure you have exited X before attempting to upgrade "
- "your driver. If you have exited X but still receive "
- "this message, then an error has occured that has "
- "confused the usage count of the kernel module; the "
- "simplest remedy is to reboot your computer.",
+ "in use (for example, by the X server), but may also "
+ "happen if your kernel was configured without support "
+ "for module unloading. Please be sure you have exited "
+ "X before attempting to upgrade your driver. If you "
+ "have exited X, know that your kernel supports module "
+ "unloading, and still receive this message, then an "
+ "error may have occured that has corrupted the NVIDIA "
+ "kernel module's usage count; the simplest remedy is "
+ "to reboot your computer.",
p->bad_modules[n]);
return FALSE;
@@ -1063,6 +1127,14 @@ static char *default_kernel_source_path(Options *op)
tmp = get_kernel_name(op);
if (tmp) {
+ str = nvstrcat("/lib/modules/", tmp, "/source", NULL);
+
+ if (directory_exists(op, str)) {
+ return str;
+ }
+
+ nvfree(str);
+
str = nvstrcat("/lib/modules/", tmp, "/build", NULL);
if (directory_exists(op, str)) {
@@ -1315,10 +1387,12 @@ download_updated_kernel_interface(Options *op, Package *p,
/*
- * cc_version_check() -
+ * check_cc_version() - check if the selected or default system
+ * compiler is compatible with the one that was used to build the
+ * currently running kernel.
*/
-static int cc_version_check(Options *op, Package *p)
+int check_cc_version(Options *op, Package *p)
{
char *cmd, *CC, *result;
int ret;
@@ -1338,7 +1412,7 @@ static int cc_version_check(Options *op, Package *p)
CC = getenv("CC");
if (!CC) CC = "cc";
- ui_log(op, "Performing cc_version_check with CC=\"%s\".", CC);
+ ui_log(op, "Performing CC test with CC=\"%s\".", CC);
cmd = nvstrcat("sh ", p->kernel_module_build_directory,
"/conftest.sh ", CC, " ",
@@ -1366,7 +1440,7 @@ static int cc_version_check(Options *op, Package *p)
return !ret;
-} /* cc_version_check() */
+} /* check_cc_version() */
diff --git a/kernel.h b/kernel.h
index e56bd22..686e60c 100644
--- a/kernel.h
+++ b/kernel.h
@@ -31,6 +31,7 @@ int determine_kernel_module_installation_path (Options*);
int determine_kernel_source_path (Options*);
int determine_kernel_output_path (Options*);
int link_kernel_module (Options*, Package*);
+int check_cc_version (Options*, Package*);
int build_kernel_module (Options*, Package*);
int build_kernel_interface (Options*, Package*);
int test_kernel_module (Options*, Package*);
diff --git a/log.c b/log.c
index 84d8ef6..96a29e9 100644
--- a/log.c
+++ b/log.c
@@ -48,6 +48,15 @@ static FILE *log_file_stream;
#define STRSTR(x) ((x) ? (x) : "(not specified)")
+#define TLSSTR(x) ({ \
+ const char *__tls_str = NULL; \
+ switch (x) { \
+ case FORCE_CLASSIC_TLS: __tls_str = "classic"; break; \
+ case FORCE_NEW_TLS: __tls_str = "elf-tls"; break; \
+ default: __tls_str = "(not specified)"; \
+ } \
+ __tls_str; \
+})
/*
* log_init() - if logging is enabled, initialize the log file; if
@@ -105,14 +114,44 @@ void log_init(Options *op)
BOOLSTR(op->no_questions));
log_printf(op, TRUE, NULL, " silent : %s",
BOOLSTR(op->silent));
+ log_printf(op, TRUE, NULL, " no backup : %s",
+ BOOLSTR(op->no_backup));
+ log_printf(op, TRUE, NULL, " kernel module only : %s",
+ BOOLSTR(op->kernel_module_only));
+ log_printf(op, TRUE, NULL, " sanity : %s",
+ BOOLSTR(op->sanity));
+ log_printf(op, TRUE, NULL, " add this kernel : %s",
+ BOOLSTR(op->add_this_kernel));
+ log_printf(op, TRUE, NULL, " no runlevel check : %s",
+ BOOLSTR(op->no_runlevel_check));
+ log_printf(op, TRUE, NULL, " no network : %s",
+ BOOLSTR(op->no_network));
+ log_printf(op, TRUE, NULL, " no ABI note : %s",
+ BOOLSTR(op->no_abi_note));
+ log_printf(op, TRUE, NULL, " no RPMs : %s",
+ BOOLSTR(op->no_rpms));
+ log_printf(op, TRUE, NULL, " force tls : %s",
+ TLSSTR(op->which_tls));
+ log_printf(op, TRUE, NULL, " force compat32 tls : %s",
+ TLSSTR(op->which_tls_compat32));
log_printf(op, TRUE, NULL, " X install prefix : %s",
STRSTR(op->xfree86_prefix));
log_printf(op, TRUE, NULL, " OpenGL install prefix : %s",
STRSTR(op->opengl_prefix));
- log_printf(op, TRUE, NULL, " Installer install prefix: %s",
+ log_printf(op, TRUE, NULL, " compat32 install prefix : %s",
+ STRSTR(op->compat32_prefix));
+ log_printf(op, TRUE, NULL, " installer install prefix: %s",
STRSTR(op->installer_prefix));
+ log_printf(op, TRUE, NULL, " utility install prefix : %s",
+ STRSTR(op->utility_prefix));
+ log_printf(op, TRUE, NULL, " kernel name : %s",
+ STRSTR(op->kernel_name));
+ log_printf(op, TRUE, NULL, " kernel include path : %s",
+ STRSTR(op->kernel_include_path));
log_printf(op, TRUE, NULL, " kernel source path : %s",
STRSTR(op->kernel_source_path));
+ log_printf(op, TRUE, NULL, " kernel output path : %s",
+ STRSTR(op->kernel_output_path));
log_printf(op, TRUE, NULL, " kernel install path : %s",
STRSTR(op->kernel_module_installation_path));
log_printf(op, TRUE, NULL, " proc mount point : %s",
@@ -121,8 +160,10 @@ void log_init(Options *op)
STRSTR(op->ui_str));
log_printf(op, TRUE, NULL, " tmpdir : %s",
STRSTR(op->tmpdir));
- log_printf(op, TRUE, NULL, " ftp site : %s",
+ log_printf(op, TRUE, NULL, " ftp mirror : %s",
STRSTR(op->ftp_site));
+ log_printf(op, TRUE, NULL, " RPM file list : %s",
+ STRSTR(op->rpm_file_list));
log_printf(op, TRUE, NULL, "");
diff --git a/misc.c b/misc.c
index dc8bfd6..5fddf54 100644
--- a/misc.c
+++ b/misc.c
@@ -49,7 +49,7 @@
static int check_symlink(Options*, const char*, const char*, const char*);
static int check_file(Options*, const char*, const mode_t, const uint32);
-static char *find_system_util(char *util);
+static char *find_system_util(const char *util);
/*
@@ -635,16 +635,16 @@ int run_command(Options *op, const char *cmd, char **data, int output,
int find_system_utils(Options *op)
{
- /* keep in sync with the Utils enum type */
- const struct { char *util, *package; } needed_utils[] = {
- { "insmod", "modutils" },
- { "modprobe", "modutils" },
- { "rmmod", "modutils" },
- { "lsmod", "modutils" },
- { "depmod", "modutils" },
- { "ldconfig", "glibc" },
+ /* keep in sync with the SystemUtils enum type */
+ const struct { const char *util, *package; } needed_utils[] = {
+ { "ldconfig", "glibc" },
+ { "ldd", "glibc" },
{ "ld", "binutils" },
{ "objcopy", "binutils" },
+ { "grep", "grep" },
+ { "dmesg", "util-linux" },
+ { "tail", "coreutils" },
+ { "cut", "coreutils" }
};
int i;
@@ -653,7 +653,7 @@ int find_system_utils(Options *op)
/* search the PATH for each utility */
- for (i = 0; i < MAX_UTILS; i++) {
+ for (i = 0; i < MAX_SYSTEM_UTILS; i++) {
op->utils[i] = find_system_util(needed_utils[i].util);
if (!op->utils[i]) {
ui_error(op, "Unable to find the system utility `%s`; please "
@@ -675,13 +675,115 @@ int find_system_utils(Options *op)
+typedef struct {
+ const char *util;
+ const char *package;
+} Util;
+
+/* keep in sync with the ModuleUtils enum type */
+static Util __module_utils[] = {
+ { "insmod", "module-init-tools" },
+ { "modprobe", "module-init-tools" },
+ { "rmmod", "module-init-tools" },
+ { "lsmod", "module-init-tools" },
+ { "depmod", "module-init-tools" },
+};
+
+/* keep in sync with the ModuleUtils enum type */
+static Util __module_utils_linux24[] = {
+ { "insmod", "modutils" },
+ { "modprobe", "modutils" },
+ { "rmmod", "modutils" },
+ { "lsmod", "modutils" },
+ { "depmod", "modutils" },
+};
+
+/*
+ * find_module_utils() - search the $PATH (as well as some common
+ * additional directories) for the utilities that the installer will
+ * need to use. Returns TRUE on success and assigns the util fields
+ * in the option struct; it returns FALSE on failures.
+ */
+
+int find_module_utils(Options *op)
+{
+ int i, j = 0;
+ Util *needed_utils = __module_utils;
+
+ if (strncmp(get_kernel_name(op), "2.4", 3) == 0)
+ needed_utils = __module_utils_linux24;
+
+ ui_expert(op, "Searching for module utilities:");
+
+ /* search the PATH for each utility */
+
+ for (i = MAX_SYSTEM_UTILS; i < MAX_UTILS; i++, j++) {
+ op->utils[i] = find_system_util(needed_utils[j].util);
+ if (!op->utils[i]) {
+ ui_error(op, "Unable to find the module utility `%s`; please "
+ "make sure you have the package '%s' installed. If "
+ "you do have %s installed, then please check that "
+ "`%s` is in your PATH.",
+ needed_utils[j].util, needed_utils[j].package,
+ needed_utils[j].package, needed_utils[j].util);
+ return FALSE;
+ }
+
+ ui_expert(op, "found `%s` : `%s`",
+ needed_utils[j].util, op->utils[i]);
+ };
+
+ return TRUE;
+
+} /* find_module_utils() */
+
+
+/*
+ * check_development_tools() - check if the development tools needed
+ * to build custom kernel interfaces are available.
+ */
+
+int check_development_tools(Options *op)
+{
+#define MAX_TOOLS 2
+ const struct { char *tool, *package; } needed_tools[] = {
+ { "cc", "gcc" },
+ { "make", "make" }
+ };
+
+ int i;
+ char *tool;
+
+ ui_expert(op, "Checking development tools:");
+
+ for (i = 0; i < MAX_TOOLS; i++) {
+ tool = find_system_util(needed_tools[i].tool);
+ if (!tool) {
+ ui_error(op, "Unable to find the development tool `%s` in "
+ "your path; please make sure that you have the "
+ "package '%s' installed. If %s is installed on your "
+ "system, then please check that `%s` is in your "
+ "PATH.",
+ needed_tools[i].tool, needed_tools[i].package,
+ needed_tools[i].package, needed_tools[i].tool);
+ return FALSE;
+ }
+
+ ui_expert(op, "found `%s` : `%s`", needed_tools[i].tool, tool);
+ }
+
+ return TRUE;
+
+} /* check_development_tools() */
+
+
/*
* find_system_util() - build a search path and search for the named
* utility. If the utility is found, the fully qualified path to the
* utility is returned. On failure NULL is returned.
*/
-static char *find_system_util(char *util)
+static char *find_system_util(const char *util)
{
char *buf, *path, *file, *x, *y;
@@ -835,7 +937,10 @@ void should_install_opengl_headers(Options *op, Package *p)
*/
for (i = 0; i < p->num_entries; i++) {
- if (p->entries[i].flags & FILE_TYPE_OPENGL_HEADER) have_headers = TRUE;
+ if (p->entries[i].flags & FILE_TYPE_OPENGL_HEADER) {
+ have_headers = TRUE;
+ break;
+ }
}
if (!have_headers) return;
@@ -863,6 +968,44 @@ void should_install_opengl_headers(Options *op, Package *p)
} /* should_install_opengl_headers() */
+/*
+ * should_install_compat32_files() - ask the user if he/she wishes to
+ * install 32bit compatibily libraries.
+ */
+
+void should_install_compat32_files(Options *op, Package *p)
+{
+#if defined(NV_X86_64)
+ int i, have_compat32_files = FALSE;
+
+ /*
+ * first, scan through the package to see if we have any
+ * 32bit compatibility files to install.
+ */
+
+ for (i = 0; i < p->num_entries; i++) {
+ if (p->entries[i].flags & FILE_CLASS_COMPAT32) {
+ have_compat32_files = TRUE;
+ break;
+ }
+ }
+
+ if (!have_compat32_files)
+ return;
+
+ if (!ui_yes_no(op, TRUE, "Install NVIDIA's 32bit compatibility "
+ "OpenGL libraries?")) {
+ for (i = 0; i < p->num_entries; i++) {
+ if (p->entries[i].flags & FILE_CLASS_COMPAT32) {
+ /* invalidate file */
+ p->entries[i].flags &= ~FILE_TYPE_MASK;
+ p->entries[i].dst = NULL;
+ }
+ }
+ }
+#endif /* NV_X86_64 */
+}
+
/*
* check_installed_files_from_package() - scan through the entries in
@@ -899,12 +1042,8 @@ void check_installed_files_from_package(Options *op, Package *p)
}
ui_status_end(op, "done.");
+ ui_log(op, "Post-install sanity check %s.", ret ? "passed" : "failed");
- if (ret) {
- ui_log(op, "Sanity check passed.");
- } else {
- ui_log(op, "The sanity check found some discrepancies.");
- }
} /* check_installed_files_from_package() */
@@ -1078,7 +1217,7 @@ extern const int tls_test_dso_array_32_size;
/* forward prototype */
-static int tls_test_internal(Options *op,
+static int tls_test_internal(Options *op, int which_tls,
const unsigned char *test_array,
const int test_array_size,
const unsigned char *dso_test_array,
@@ -1091,7 +1230,7 @@ int tls_test(Options *op, int compat_32_libs)
if (compat_32_libs) {
#if defined(NV_X86_64)
- return tls_test_internal(op,
+ return tls_test_internal(op, op->which_tls_compat32,
tls_test_array_32,
tls_test_array_32_size,
tls_test_dso_array_32,
@@ -1101,7 +1240,7 @@ int tls_test(Options *op, int compat_32_libs)
#endif /* NV_X86_64 */
} else {
- return tls_test_internal(op,
+ return tls_test_internal(op, op->which_tls,
tls_test_array,
tls_test_array_size,
tls_test_dso_array,
@@ -1117,7 +1256,7 @@ int tls_test(Options *op, int compat_32_libs)
* just selects which array data is used as the test.
*/
-static int tls_test_internal(Options *op,
+static int tls_test_internal(Options *op, int which_tls,
const unsigned char *test_array,
const int test_array_size,
const unsigned char *test_dso_array,
@@ -1128,8 +1267,8 @@ static int tls_test_internal(Options *op,
/* allow commandline options to bypass this test */
- if (op->which_tls == FORCE_NEW_TLS) return TRUE;
- if (op->which_tls == FORCE_CLASSIC_TLS) return FALSE;
+ if (which_tls == FORCE_NEW_TLS) return TRUE;
+ if (which_tls == FORCE_CLASSIC_TLS) return FALSE;
/* check that we have the test program */
@@ -1193,6 +1332,201 @@ static int tls_test_internal(Options *op,
/*
+ * check_runtime_configuration() - In the past, nvidia-installer has
+ * frequently failed to backup/move all conflicting files prior to
+ * installing the NVIDIA OpenGL libraries. Consequently, some of the
+ * installations considered successful by the installer didn't work
+ * correctly.
+ *
+ * This sanity check attemps to verify that the correct libraries are
+ * picked up by the runtime linker. It returns TRUE on success and
+ * FALSE on failure.
+ */
+
+/* pull in the array and size from g_rtld_test.c */
+
+extern const unsigned char rtld_test_array[];
+extern const int rtld_test_array_size;
+
+#if defined(NV_X86_64)
+
+/* pull in the array and size from g_rtld_test_32.c */
+
+extern const unsigned char rtld_test_array_32[];
+extern const int rtld_test_array_32_size;
+
+#endif /* NV_X86_64 */
+
+
+/* forward prototype */
+
+static int rtld_test_internal(Options *op, Package *p,
+ int which_tls,
+ const unsigned char *test_array,
+ const int test_array_size,
+ int compat_32_libs);
+
+int check_runtime_configuration(Options *op, Package *p)
+{
+ int ret = TRUE;
+
+ ui_status_begin(op, "Running runtime sanity check:", "Checking");
+
+#if defined(NV_X86_64)
+ ret = rtld_test_internal(op, p, op->which_tls_compat32,
+ rtld_test_array_32,
+ rtld_test_array_32_size,
+ TRUE);
+#endif /* NV_X86_64 */
+
+ if (ret == TRUE) {
+ ret = rtld_test_internal(op, p, op->which_tls,
+ rtld_test_array,
+ rtld_test_array_size,
+ FALSE);
+ }
+
+ ui_status_end(op, "done.");
+ ui_log(op, "Runtime sanity check %s.", ret ? "passed" : "failed");
+
+ return ret;
+
+} /* check_runtime_configuration() */
+
+
+/*
+ * rtld_test_internal() - this routine writes the test binaries to a file
+ * and performs the test; the caller (rtld_test()) selects which array data
+ * is used (native, compat_32).
+ */
+
+static int rtld_test_internal(Options *op, Package *p,
+ int which_tls,
+ const unsigned char *test_array,
+ const int test_array_size,
+ int compat_32_libs)
+{
+ int i, ret = TRUE;
+ char *name = NULL, *cmd = NULL, *data = NULL;
+ char *tmpfile, *s;
+ struct stat stat_buf0, stat_buf1;
+
+ if ((test_array == NULL) || (test_array_size == 0)) {
+ ui_warn(op, "The runtime configuration test program is not "
+ "present; assuming successful installation.");
+ return TRUE;
+ }
+
+ /* write the rtld_test data to a temporary file */
+
+ tmpfile = write_temp_file(op, test_array_size, test_array,
+ S_IRUSR|S_IWUSR|S_IXUSR);
+
+ if (!tmpfile) {
+ ui_warn(op, "Unable to create a temporary file for the runtime "
+ "configuration test program (%s); assuming successful "
+ "installation.", strerror(errno));
+ goto done;
+ }
+
+ /* perform the test(s) */
+
+ for (i = 0; i < p->num_entries; i++) {
+ if (!(p->entries[i].flags & FILE_TYPE_RTLD_CHECKED))
+ continue;
+ else if ((which_tls & TLS_LIB_TYPE_FORCED) &&
+ (p->entries[i].flags & FILE_TYPE_TLS_LIB))
+ continue;
+#if defined(NV_X86_64)
+ else if ((p->entries[i].flags & FILE_CLASS_NATIVE)
+ && compat_32_libs)
+ continue;
+ else if ((p->entries[i].flags & FILE_CLASS_COMPAT32)
+ && !compat_32_libs)
+ continue;
+#endif /* NV_X86_64 */
+ else if ((which_tls == TLS_LIB_NEW_TLS) &&
+ (p->entries[i].flags & FILE_CLASS_CLASSIC_TLS))
+ continue;
+ else if ((which_tls == TLS_LIB_CLASSIC_TLS) &&
+ (p->entries[i].flags & FILE_CLASS_NEW_TLS))
+ continue;
+
+ name = nvstrdup(p->entries[i].name);
+ if (!name) continue;
+
+ s = strstr(name, ".so.1");
+ if (!s) goto next;
+ *(s + strlen(".so.1")) = '\0';
+
+ cmd = nvstrcat(op->utils[LDD], " ", tmpfile, " | ",
+ op->utils[GREP], " ", name, " | ",
+ op->utils[CUT], " -d \" \" -f 3", NULL);
+
+ if (run_command(op, cmd, &data, FALSE, 0, TRUE)) {
+ ui_warn(op, "Unable to perform the runtime configuration "
+ "check (%s); assuming successful installation.",
+ strerror(errno));
+ goto done;
+ }
+
+ nvfree(name); name = NULL;
+ name = nvstrdup(p->entries[i].dst);
+ if (!name) goto next;
+
+ s = strstr(name, ".so.1");
+ if (!s) goto next;
+ *(s + strlen(".so.1")) = '\0';
+
+ if ((strcmp(data, name) != 0)) {
+ /*
+ * XXX Handle the case where the same library is
+ * referred to, once directly and once via a symbolic
+ * link. This check is far from perfect, but should
+ * get the job done.
+ */
+
+ if ((stat(data, &stat_buf0) == 0) &&
+ (stat(name, &stat_buf1) == 0) &&
+ (memcmp(&stat_buf0, &stat_buf1, sizeof(struct stat)) == 0))
+ goto next;
+
+ ui_error(op, "The runtime configuration check failed for "
+ "library '%s' (expected: '%s', found: '%s'). "
+ "The most likely reason for this is that conflicting "
+ "OpenGL libraries are installed in a location "
+ "not inspected by nvidia-installer. Please be sure "
+ "you have uninstalled any third-party OpenGL and "
+ "third-party graphics driver packages.",
+ p->entries[i].name, name,
+ (data && strlen(data)) ? data : "(not found)");
+
+ ret = FALSE;
+ goto done;
+ }
+
+ next:
+ nvfree(name); name = NULL;
+ nvfree(cmd); cmd = NULL;
+ nvfree(data); data = NULL;
+ }
+
+ done:
+ if (tmpfile) {
+ unlink(tmpfile);
+ nvfree(tmpfile);
+ }
+
+ nvfree(name);
+ nvfree(cmd);
+ nvfree(data);
+
+ return ret;
+
+} /* rtld_test_internal() */
+
+
+/*
* get_distribution() - determine what distribution this is; only used
* for several bits of distro-specific behavior requested by
* distribution maintainers.
@@ -1205,6 +1539,7 @@ Distribution get_distribution(Options *op)
{
if (access("/etc/SuSE-release", F_OK) == 0) return SUSE;
if (access("/etc/UnitedLinux-release", F_OK) == 0) return UNITED_LINUX;
+ if (access("/etc/debian_version", F_OK) == 0) return DEBIAN;
return OTHER;
diff --git a/misc.h b/misc.h
index d182d13..74b3e4b 100644
--- a/misc.h
+++ b/misc.h
@@ -51,13 +51,17 @@ char *get_next_line(char *buf, char **e);
int run_command(Options *op, const char *cmd, char **data,
int output, int status, int redirect);
int find_system_utils(Options *op);
+int find_module_utils(Options *op);
+int check_development_tools(Options *op);
int nvid_version (const char *str, int *major, int *minor, int *patch);
int continue_after_error(Options *op, const char *fmt, ...);
int do_install(Options *op, Package *p, CommandList *c);
void should_install_opengl_headers(Options *op, Package *p);
+void should_install_compat32_files(Options *op, Package *p);
void check_installed_files_from_package(Options *op, Package *p);
unsigned int get_installable_file_mask(Options *op);
int tls_test(Options *op, int compat_32_libs);
+int check_runtime_configuration(Options *op, Package *p);
Distribution get_distribution(Options *op);
int check_for_running_x(Options *op);
diff --git a/nvidia-installer.c b/nvidia-installer.c
index e40cd35..75c4a8d 100644
--- a/nvidia-installer.c
+++ b/nvidia-installer.c
@@ -231,6 +231,16 @@ static void print_advanced_options_args_only(int args_only)
"mandates this default value.",
DEFAULT_OPENGL_INSTALLATION_PREFIX);
fmtout("");
+
+#if defined(NV_X86_64)
+ fmtout("--compat32-prefix=[COMPAT32 PREFIX]");
+ fmtoutp(TAB, "The path relative to which the 32bit compatibility "
+ "libraries will be installed on x86-64 systems; this option "
+ "is unset by default, the OpenGL prefix alone determines "
+ "the target location. Only under very rare circumstances "
+ "should this option need to be used.");
+ fmtout("");
+#endif /* NV_X86_64 */
fmtout("--installer-prefix=[INSTALLER PREFIX]");
fmtoutp(TAB, "The prefix under which the installer binary will be "
@@ -348,6 +358,14 @@ static void print_advanced_options_args_only(int args_only)
"'classic'.");
fmtout("");
+#if defined(NV_X86_64)
+ fmtout("--force-tls-compat32=[TLS TYPE]");
+ fmtoutp(TAB, "This option forces the installer to install a specific "
+ "32bit compatibility OpenGL TLS library; further details "
+ "can be found in the description of the '--force-tls' option.");
+ fmtout("");
+#endif /* NV_X86_64 */
+
fmtout("-k, --kernel-name=[KERNELNAME]");
fmtoutp(TAB, "Build and install the NVIDIA kernel module for the "
"non-running kernel specified by [KERNELNAME] ([KERNELNAME] "
@@ -399,6 +417,13 @@ static void print_advanced_options_args_only(int args_only)
"connect to the NVIDIA ftp site (for updated precompiled kernel "
"interfaces, for example).");
fmtout("");
+
+ fmtout("--no-recursion");
+ fmtoutp(TAB, "Normally, nvidia-installer will recursively search for "
+ "potentially conflicting libraries under the default OpenGL "
+ "and X server installation locations. With this option set, "
+ "the installer will only search in the top-level directories.");
+ fmtout("");
fmtout("-K, --kernel-module-only");
fmtoutp(TAB, "Install a kernel module only, and don't uninstall the "
@@ -463,6 +488,9 @@ Options *parse_commandline(int argc, char *argv[])
#define NO_RPMS_OPTION 24
#define X_PREFIX_OPTION 25
#define KERNEL_OUTPUT_PATH_OPTION 26
+#define NO_RECURSION_OPTION 27
+#define FORCE_TLS_COMPAT32_OPTION 28
+#define COMPAT32_PREFIX_OPTION 29
static struct option long_options[] = {
@@ -486,6 +514,7 @@ Options *parse_commandline(int argc, char *argv[])
{ "kernel-module-only", 0, NULL, 'K' },
{ "xfree86-prefix", 1, NULL, XFREE86_PREFIX_OPTION },
{ "x-prefix", 1, NULL, X_PREFIX_OPTION },
+ { "compat32-prefix", 1, NULL, COMPAT32_PREFIX_OPTION },
{ "opengl-prefix", 1, NULL, OPENGL_PREFIX_OPTION },
{ "installer-prefix", 1, NULL, INSTALLER_PREFIX_OPTION },
{ "utility-prefix", 1, NULL, UTILITY_PREFIX_OPTION },
@@ -501,6 +530,7 @@ Options *parse_commandline(int argc, char *argv[])
{ "tmpdir", 1, NULL, TMPDIR_OPTION },
{ "opengl-headers", 0, NULL, OPENGL_HEADERS_OPTION },
{ "force-tls", 1, NULL, FORCE_TLS_OPTION },
+ { "force-tls-compat32", 1, NULL, FORCE_TLS_COMPAT32_OPTION },
{ "sanity", 0, NULL, SANITY_OPTION },
{ "add-this-kernel", 0, NULL, ADD_THIS_KERNEL_OPTION },
{ "rpm-file-list", 1, NULL, RPM_FILE_LIST_OPTION },
@@ -508,6 +538,7 @@ Options *parse_commandline(int argc, char *argv[])
{ "no-network", 0, NULL, NO_NETWORK_OPTION },
{ "no-abi-note", 0, NULL, NO_ABI_NOTE_OPTION },
{ "no-rpms", 0, NULL, NO_RPMS_OPTION },
+ { "no-recursion", 0, NULL, NO_RECURSION_OPTION },
{ "precompiled-kernel-interfaces-path", 1, NULL,
PRECOMPILED_KERNEL_INTERFACES_PATH },
{ "advanced-options-args-only", 0, NULL,
@@ -521,17 +552,18 @@ Options *parse_commandline(int argc, char *argv[])
op->xfree86_prefix = DEFAULT_XFREE86_INSTALLATION_PREFIX;
op->opengl_prefix = DEFAULT_OPENGL_INSTALLATION_PREFIX;
- op->installer_prefix = NULL;
op->utility_prefix = DEFAULT_UTILITY_INSTALLATION_PREFIX;
op->proc_mount_point = DEFAULT_PROC_MOUNT_POINT;
op->log_file_name = DEFAULT_LOG_FILE_NAME;
op->ftp_site = DEFAULT_FTP_SITE;
+
op->tmpdir = get_tmpdir(op);
- op->no_runlevel_check = FALSE;
- op->no_backup = FALSE;
- op->no_network = FALSE;
- op->kernel_module_only = FALSE;
- op->no_abi_note = FALSE;
+ op->distro = get_distribution(op);
+
+#if defined(NV_X86_64)
+ if (op->distro == DEBIAN)
+ op->compat32_prefix = DEBIAN_COMPAT32_INSTALLATION_PREFIX;
+#endif
op->logging = TRUE; /* log by default */
@@ -579,6 +611,8 @@ Options *parse_commandline(int argc, char *argv[])
op->xfree86_prefix = optarg; break;
case OPENGL_PREFIX_OPTION:
op->opengl_prefix = optarg; break;
+ case COMPAT32_PREFIX_OPTION:
+ op->compat32_prefix = optarg; break;
case INSTALLER_PREFIX_OPTION:
op->installer_prefix = optarg; break;
case UTILITY_PREFIX_OPTION:
@@ -618,6 +652,20 @@ Options *parse_commandline(int argc, char *argv[])
exit(1);
}
break;
+ case FORCE_TLS_COMPAT32_OPTION:
+ if (strcasecmp(optarg, "new") == 0)
+ op->which_tls_compat32 = FORCE_NEW_TLS;
+ else if (strcasecmp(optarg, "classic") == 0)
+ op->which_tls_compat32 = FORCE_CLASSIC_TLS;
+ else {
+ fmterr("");
+ fmterr("Invalid parameter for '--force-tls-compat32'; "
+ "please run `%s --help` for usage information.",
+ argv[0]);
+ fmterr("");
+ exit(1);
+ }
+ break;
case SANITY_OPTION:
op->sanity = TRUE;
break;
@@ -645,6 +693,9 @@ Options *parse_commandline(int argc, char *argv[])
case NO_RPMS_OPTION:
op->no_rpms = TRUE;
break;
+ case NO_RECURSION_OPTION:
+ op->no_recursion = TRUE;
+ break;
default:
fmterr("");
@@ -670,8 +721,6 @@ Options *parse_commandline(int argc, char *argv[])
exit(1);
}
- op->distro = get_distribution(op);
-
/*
* if the installer prefix was not specified, default it to the
* utility prefix; this is done so that the installer prefix is
@@ -730,6 +779,7 @@ int main(int argc, char *argv[])
*/
if (!find_system_utils(op)) goto done;
+ if (!find_module_utils(op)) goto done;
/* get the latest available driver version */
diff --git a/nvidia-installer.h b/nvidia-installer.h
index c7cdd87..7914377 100644
--- a/nvidia-installer.h
+++ b/nvidia-installer.h
@@ -34,21 +34,35 @@
/*
* Enumerated type, listing each of the system utilities we'll need.
* Keep this enum in sync with the needed_utils string array in
- * misc.c:find_system_utils()
+ * misc.c:find_system_utils().
*/
typedef enum {
- INSMOD = 0,
+ LDCONFIG = 0,
+ LDD,
+ LD,
+ OBJCOPY,
+ GREP,
+ DMESG,
+ TAIL,
+ CUT,
+ MAX_SYSTEM_UTILS
+} SystemUtils;
+
+/*
+ * Enumerated type, listing each of the module utilities we'll need.
+ * Keep this enum in sync with the needed_utils string array in
+ * misc.c:find_module_utils().
+ */
+
+typedef enum {
+ INSMOD = MAX_SYSTEM_UTILS,
MODPROBE,
RMMOD,
LSMOD,
DEPMOD,
- LDCONFIG,
- LD,
- OBJCOPY,
MAX_UTILS
-} Utils;
-
+} ModuleUtils;
/*
* Enumerated type of distributions; this isn't an exhaustive list of
@@ -59,6 +73,7 @@ typedef enum {
typedef enum {
SUSE,
UNITED_LINUX,
+ DEBIAN,
OTHER
} Distribution;
@@ -92,6 +107,7 @@ typedef struct __options {
int no_questions;
int silent;
int which_tls;
+ int which_tls_compat32;
int sanity;
int add_this_kernel;
int no_runlevel_check;
@@ -100,9 +116,11 @@ typedef struct __options {
int kernel_module_only;
int no_abi_note;
int no_rpms;
+ int no_recursion;
char *xfree86_prefix;
char *opengl_prefix;
+ char *compat32_prefix;
char *installer_prefix;
char *utility_prefix;
@@ -236,6 +254,8 @@ typedef struct {
#define FILE_TYPE_INSTALLER_BINARY 0x00000200
#define FILE_TYPE_UTILITY_BINARY 0x00000400
#define FILE_TYPE_LIBGL_LA 0x00000800
+#define FILE_TYPE_TLS_LIB 0x00001000
+#define FILE_TYPE_TLS_SYMLINK 0x00002000
/* file class: this is used to distinguish OpenGL libraries */
@@ -243,31 +263,52 @@ typedef struct {
#define FILE_CLASS_NEW_TLS 0x00010000
#define FILE_CLASS_CLASSIC_TLS 0x00020000
-#define FILE_CLASS_NEW_TLS_32 0x00040000
+#define FILE_CLASS_NATIVE 0x00040000
+#define FILE_CLASS_COMPAT32 0x00080000
#define FILE_TYPE_INSTALLABLE_FILE (FILE_TYPE_OPENGL_LIB | \
FILE_TYPE_XFREE86_LIB | \
+ FILE_TYPE_TLS_LIB | \
FILE_TYPE_DOCUMENTATION | \
FILE_TYPE_OPENGL_HEADER | \
FILE_TYPE_KERNEL_MODULE | \
FILE_TYPE_INSTALLER_BINARY | \
- FILE_TYPE_UTILITY_BINARY)
+ FILE_TYPE_UTILITY_BINARY | \
+ FILE_TYPE_LIBGL_LA)
#define FILE_TYPE_HAVE_PATH (FILE_TYPE_OPENGL_LIB | \
FILE_TYPE_OPENGL_SYMLINK | \
FILE_TYPE_LIBGL_LA | \
FILE_TYPE_XFREE86_LIB | \
FILE_TYPE_XFREE86_SYMLINK | \
+ FILE_TYPE_TLS_LIB | \
+ FILE_TYPE_TLS_SYMLINK | \
FILE_TYPE_DOCUMENTATION)
-#define FILE_TYPE_SYMLINK (FILE_TYPE_OPENGL_SYMLINK | \
- FILE_TYPE_XFREE86_SYMLINK)
+#define FILE_TYPE_HAVE_ARCH (FILE_TYPE_OPENGL_LIB | \
+ FILE_TYPE_OPENGL_SYMLINK | \
+ FILE_TYPE_LIBGL_LA | \
+ FILE_TYPE_TLS_LIB | \
+ FILE_TYPE_TLS_SYMLINK)
+
+#define FILE_TYPE_HAVE_CLASS (FILE_TYPE_TLS_LIB | \
+ FILE_TYPE_TLS_SYMLINK)
+
+#define FILE_TYPE_SYMLINK (FILE_TYPE_OPENGL_SYMLINK | \
+ FILE_TYPE_XFREE86_SYMLINK | \
+ FILE_TYPE_TLS_SYMLINK)
+
+#define FILE_TYPE_RTLD_CHECKED (FILE_TYPE_OPENGL_LIB | \
+ FILE_TYPE_TLS_LIB)
+
+#define TLS_LIB_TYPE_FORCED 0x0001
+#define TLS_LIB_NEW_TLS 0x0002
+#define TLS_LIB_CLASSIC_TLS 0x0004
-#define SELECT_TLS 0
-#define FORCE_CLASSIC_TLS 1
-#define FORCE_NEW_TLS 2
+#define FORCE_CLASSIC_TLS (TLS_LIB_CLASSIC_TLS | TLS_LIB_TYPE_FORCED)
+#define FORCE_NEW_TLS (TLS_LIB_NEW_TLS | TLS_LIB_TYPE_FORCED)
#define PERM_MASK (S_IRWXU|S_IRWXG|S_IRWXO)
@@ -277,6 +318,7 @@ typedef struct {
#define DEFAULT_OPENGL_INSTALLATION_PREFIX "/usr"
#define DEFAULT_INSTALLER_INSTALLATION_PREFIX "/usr"
#define DEFAULT_UTILITY_INSTALLATION_PREFIX "/usr"
+#define DEBIAN_COMPAT32_INSTALLATION_PREFIX "/emul/ia32-linux"
#define DEFAULT_PROC_MOUNT_POINT "/proc"
diff --git a/rtld_test.c b/rtld_test.c
new file mode 100644
index 0000000..4a7c3ee
--- /dev/null
+++ b/rtld_test.c
@@ -0,0 +1,4 @@
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/rtld_test_Linux-x86 b/rtld_test_Linux-x86
new file mode 100755
index 0000000..b60ea47
--- /dev/null
+++ b/rtld_test_Linux-x86
Binary files differ
diff --git a/rtld_test_Linux-x86_64 b/rtld_test_Linux-x86_64
new file mode 100755
index 0000000..be5e874
--- /dev/null
+++ b/rtld_test_Linux-x86_64
Binary files differ
diff --git a/sanity.c b/sanity.c
index c5527d3..abd1025 100644
--- a/sanity.c
+++ b/sanity.c
@@ -162,15 +162,31 @@ static int find_conflicting_libraries(Options *op)
/* search for possibly conflicting libraries */
- find_conflicting_xfree86_libraries(DEFAULT_XFREE86_INSTALLATION_PREFIX, l);
+ find_conflicting_xfree86_libraries(op, DEFAULT_XFREE86_INSTALLATION_PREFIX, l);
if (strcmp(DEFAULT_XFREE86_INSTALLATION_PREFIX, op->xfree86_prefix) != 0)
- find_conflicting_xfree86_libraries(op->xfree86_prefix, l);
+ find_conflicting_xfree86_libraries(op, op->xfree86_prefix, l);
- find_conflicting_opengl_libraries(DEFAULT_OPENGL_INSTALLATION_PREFIX, l);
+ find_conflicting_opengl_libraries(op, DEFAULT_OPENGL_INSTALLATION_PREFIX, l);
if (strcmp(DEFAULT_OPENGL_INSTALLATION_PREFIX, op->opengl_prefix) != 0)
- find_conflicting_opengl_libraries(op->opengl_prefix, l);
+ find_conflicting_opengl_libraries(op, op->opengl_prefix, l);
+
+#if defined(NV_X86_64)
+ if (op->compat32_prefix != NULL) {
+ char *prefix = nvstrcat(op->compat32_prefix,
+ DEFAULT_OPENGL_INSTALLATION_PREFIX, NULL);
+ find_conflicting_opengl_libraries(op, prefix, l);
+ nvfree(prefix);
+
+ if (strcmp(DEFAULT_OPENGL_INSTALLATION_PREFIX,
+ op->opengl_prefix) != 0) {
+ prefix = nvstrcat(op->compat32_prefix, op->opengl_prefix, NULL);
+ find_conflicting_opengl_libraries(op, prefix, l);
+ nvfree(prefix);
+ }
+ }
+#endif /* NV_X86_64 */
/* condense the file list */
diff --git a/user-interface.c b/user-interface.c
index 1ef5a1c..4bfed83 100644
--- a/user-interface.c
+++ b/user-interface.c
@@ -204,14 +204,14 @@ char *ui_get_input(Options *op, const char *def, const char *fmt, ...)
va_end(ap);
if (op->no_questions) {
- ret = nvstrdup(def);
- tmp = nvstrcat(msg, " (Answer: '", ret," ')", NULL);
+ ret = nvstrdup(def ? def : "");
+ tmp = nvstrcat(msg, " (Answer: '", ret, "')", NULL);
if (!op->silent) {
__ui->message(op, NV_MSG_LEVEL_LOG, tmp);
}
} else {
ret = __ui->get_input(op, def, msg);
- tmp = nvstrcat(msg, " (Answer: '", ret," ')", NULL);
+ tmp = nvstrcat(msg, " (Answer: '", ret, "')", NULL);
}
log_printf(op, TRUE, NV_BULLET_STR, tmp);
nvfree(msg);