summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2014-11-13 08:51:28 -0800
committerAaron Plattner <aplattner@nvidia.com>2014-11-13 08:51:28 -0800
commit6765fcac47d7270b8ac1eea1978de484d658bde1 (patch)
tree76f932f6773461276d7a278776befaf2c37b3b8c
parent2574fdfc9c20e9372ffda4f8601a0322bd408c4e (diff)
346.16346.16
-rw-r--r--Makefile7
-rw-r--r--backup.c107
-rw-r--r--command-list.c495
-rw-r--r--common-utils/common-utils.c98
-rw-r--r--common-utils/common-utils.h5
-rw-r--r--common-utils/nvgetopt.c16
-rw-r--r--crc.c36
-rw-r--r--dist-files.mk2
-rw-r--r--files.c897
-rw-r--r--files.h5
-rw-r--r--install-from-cwd.c388
-rw-r--r--kernel.c130
-rw-r--r--manifest.c124
-rw-r--r--misc.c377
-rw-r--r--misc.h6
-rw-r--r--ncurses-ui.c2
-rw-r--r--nvidia-installer.c37
-rw-r--r--nvidia-installer.h89
-rw-r--r--option_table.h42
-rw-r--r--precompiled.c49
-rw-r--r--sanity.c48
-rw-r--r--sanity.h1
-rw-r--r--snarf-ftp.c2
-rwxr-xr-xtls_test_Linux-ia64bin14162 -> 0 bytes
-rwxr-xr-xtls_test_dso_Linux-ia64.sobin10260 -> 0 bytes
-rw-r--r--update.c11
-rw-r--r--user-interface.c4
-rw-r--r--utils.mk90
-rw-r--r--version.mk2
29 files changed, 1751 insertions, 1319 deletions
diff --git a/Makefile b/Makefile
index e34851b..a6e4960 100644
--- a/Makefile
+++ b/Makefile
@@ -103,7 +103,6 @@ OPTIONS_1_INC = $(OUTPUTDIR)/options.1.inc
ifeq ($(TARGET_OS)-$(TARGET_ARCH), Linux-x86_64)
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) \
$(RTLD_TEST_32_C)
@@ -308,9 +307,9 @@ tls_test: tls_test.c
# 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)
+rebuild_rtld_test: rtld_test.c $(CONFIG_H)
+ $(call quiet_cmd,LINK) $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) -o $(RTLD_TEST) -lGL $<
+ $(call quiet_cmd,STRIP_CMD) $(RTLD_TEST)
# dummy rule to override implicit rule that builds dls_test from
# rtld_test.c
diff --git a/backup.c b/backup.c
index 0f8945d..3c32f92 100644
--- a/backup.c
+++ b/backup.c
@@ -141,7 +141,7 @@ int init_backup(Options *op, Package *p)
/* remove the directory, if it already exists */
- if (directory_exists(op, BACKUP_DIRECTORY)) {
+ if (directory_exists(BACKUP_DIRECTORY)) {
if (!remove_directory(op, BACKUP_DIRECTORY)) {
return FALSE;
}
@@ -208,7 +208,7 @@ int do_backup(Options *op, const char *filename)
{
int len, ret, ret_val;
struct stat stat_buf;
- char *tmp;
+ char *tmp = NULL;
FILE *log;
uint32 crc;
@@ -251,7 +251,6 @@ int do_backup(Options *op, const char *filename)
fprintf(log, "%u %04o %d %d\n", crc, stat_buf.st_mode,
stat_buf.st_uid, stat_buf.st_gid);
- free(tmp);
backup_file_number++;
} else if (S_ISLNK(stat_buf.st_mode)) {
tmp = get_symlink_target(op, filename);
@@ -267,7 +266,6 @@ int do_backup(Options *op, const char *filename)
fprintf(log, "%s\n", tmp);
fprintf(log, "%04o %d %d\n", stat_buf.st_mode,
stat_buf.st_uid, stat_buf.st_gid);
- free(tmp);
} else if (S_ISDIR(stat_buf.st_mode)) {
/* XXX IMPLEMENT ME: recursive moving of a directory */
@@ -284,6 +282,8 @@ int do_backup(Options *op, const char *filename)
done:
+ nvfree(tmp);
+
/* close the log file */
if (fclose(log) != 0) {
@@ -506,7 +506,7 @@ int log_mkdir(Options *op, const char *dirs)
* is within BACKUP_DIRECTORY, so the below fopen(3) call depends on
* the existence of BACKUP_DIRECTORY
*/
- if (!directory_exists(op, BACKUP_DIRECTORY) &&
+ if (!directory_exists(BACKUP_DIRECTORY) &&
!mkdir_recursive(op, BACKUP_DIRECTORY, BACKUP_DIRECTORY_PERMS, FALSE)) {
return FALSE;
}
@@ -832,27 +832,29 @@ static int do_uninstall(Options *op, const char *version)
/* XXX what to do if this fails?... nothing */
}
- /*
- * attempt to unload the kernel module(s), but don't abort if this fails:
- * the kernel may not have been configured with support for module
- * unloading or the user might have unloaded it themselves or the module
- * might not have existed at all.
- */
+ if (!op->skip_module_unload) {
+ /*
+ * attempt to unload the kernel module(s), but don't abort if this
+ * fails: the kernel may not have been configured with support for
+ * module unloading or the user might have unloaded it themselves or the
+ * module might not have existed at all.
+ */
- unload_nvidia_module(op, "-uvm");
+ unload_nvidia_module(op, "-uvm");
- unload_nvidia_module(op, "");
+ unload_nvidia_module(op, "");
- for (i = 0; i < NV_MAX_MODULE_INSTANCES; i++) {
- char num[5];
- memset(num, 0, sizeof(num));
- snprintf(num, sizeof(num), "%d", i);
- num[sizeof(num) - 1] = '\0';
+ for (i = 0; i < NV_MAX_MODULE_INSTANCES; i++) {
+ char num[5];
+ memset(num, 0, sizeof(num));
+ snprintf(num, sizeof(num), "%d", i);
+ num[sizeof(num) - 1] = '\0';
- unload_nvidia_module(op, num);
- }
+ unload_nvidia_module(op, num);
+ }
- unload_nvidia_module(op, "-frontend");
+ unload_nvidia_module(op, "-frontend");
+ }
run_distro_hook(op, "post-uninstall");
@@ -902,13 +904,13 @@ static BackupInfo *read_backup_log_file(Options *op)
if (fstat(fd, &stat_buf) == -1) {
ui_error(op, "Failure getting file properties for %s (%s).",
BACKUP_LOG, strerror(errno));
- return NULL;
+ goto pre_map_fail;
}
if ((stat_buf.st_mode & PERM_MASK) != BACKUP_LOG_PERMS) {
ui_error(op, "The file permissions of %s have been changed since "
"the file was written!", BACKUP_LOG);
- return NULL;
+ goto pre_map_fail;
}
/* map the file */
@@ -1033,11 +1035,14 @@ static BackupInfo *read_backup_log_file(Options *op)
ui_status_end(op, "error.");
munmap(buf, stat_buf.st_size);
- close(fd);
ui_error(op, "Error while parsing line %d of '%s'.", line_num, BACKUP_LOG);
- if (b) free(b);
+ nvfree(b);
+
+ pre_map_fail:
+
+ close(fd);
return NULL;
} /* read_backup_log_file() */
@@ -1376,18 +1381,15 @@ int uninstall_existing_driver(Options *op, const int interactive)
}
if (interactive && op->uninstall) {
- ret = ui_yes_no(op, FALSE,
- "If you plan to no longer use the NVIDIA driver, you "
- "should make sure that no X screens are configured to "
- "use the NVIDIA X driver in your X configuration file. "
- "If you used nvidia-xconfig to configure X, it may have "
- "created a backup of your original configuration. Would "
- "you like to run `nvidia-xconfig --restore-original-"
- "backup` to attempt restoration of the original X "
- "configuration file?");
- if (ret) {
- run_nvidia_xconfig(op, TRUE);
- }
+ const char *msg = "If you plan to no longer use the NVIDIA driver, you "
+ "should make sure that no X screens are configured to "
+ "use the NVIDIA X driver in your X configuration file. "
+ "If you used nvidia-xconfig to configure X, it may have "
+ "created a backup of your original configuration. Would "
+ "you like to run `nvidia-xconfig --restore-original-"
+ "backup` to attempt restoration of the original X "
+ "configuration file?";
+ run_nvidia_xconfig(op, TRUE, msg, FALSE);
}
ret = do_uninstall(op, version);
@@ -1426,13 +1428,40 @@ int run_existing_uninstaller(Options *op)
* uninstall log location: older installers may not do so implicitly. */
char *uninstall_cmd = nvstrcat(uninstaller, " -s --log-file-name="
DEFAULT_UNINSTALL_LOG_FILE_NAME, NULL);
- char *data;
+ char *data = NULL;
int ret;
ui_log(op, "Uninstalling the previous installation with %s.",
uninstaller);
- ret = run_command(op, uninstall_cmd, &data, FALSE, 0, TRUE);
+ if (!op->no_kernel_module && !op->kernel_name) {
+ /*
+ * Attempt to run the uninstaller with the --skip-module-unload
+ * option first. If that fails, fall back to running it without
+ * that option.
+ *
+ * We don't want the uninstaller to unload the module because this
+ * instance of the installer already unloaded the old module and
+ * loaded the new one.
+ */
+ char *uninstall_skip_unload_cmd =
+ nvstrcat(uninstall_cmd, " --skip-module-unload", NULL);
+ ret = run_command(op, uninstall_skip_unload_cmd, NULL, FALSE, 0, TRUE);
+ nvfree(uninstall_skip_unload_cmd);
+ } else {
+ /*
+ * If installing the kernel module was skipped or we're
+ * building/installing for a different kernel, then the new kernel
+ * module wasn't automatically loaded and we should unload whichever
+ * one is loaded now.
+ */
+ ret = 1;
+ }
+
+ if (ret) {
+ /* Try again without --skip-module-unload */
+ ret = run_command(op, uninstall_cmd, &data, FALSE, 0, TRUE);
+ }
nvfree(uninstall_cmd);
diff --git a/command-list.c b/command-list.c
index 1ff75e7..a35c7a6 100644
--- a/command-list.c
+++ b/command-list.c
@@ -47,18 +47,6 @@
static void free_file_list(FileList* l);
-static void find_conflicting_xfree86_libraries(Options *,
- const char *,
- FileList *);
-
-static void find_conflicting_xfree86_libraries_fullpath(Options *op,
- char *,
- FileList *l);
-
-static void find_conflicting_opengl_libraries(Options *,
- const char *,
- FileList *);
-
static void find_conflicting_kernel_modules(Options *op,
Package *p,
FileList *l);
@@ -84,6 +72,110 @@ typedef struct {
char *name; /* name to find: NULL to end the list */
} NoRecursionDirectory;
+static void find_conflicting_files(Options *op,
+ char *path,
+ ConflictingFileInfo *files,
+ FileList *l,
+ const NoRecursionDirectory *skipdirs);
+
+
+/*
+ * Check if a path already exists in the path list, or is a subdirectory of
+ * a path that exists in the path list, or is a symlink to or symlink target
+ * of a directory that exists in the path list.
+ */
+static int path_already_exists(char ***paths, int count, const char *path)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ int is_subdir = FALSE;
+
+ is_subdirectory((*paths)[i], path, &is_subdir);
+
+ if (is_subdir) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ * Add a new path to the list of paths to search, provided that it exists
+ * and is not redundant.
+ * XXX we only check to see if the new directory is a subdirectory of any
+ * existing directory, and not the other way around.
+ */
+static void add_search_path(char ***paths, int *count, const char *path)
+{
+ if (directory_exists(path) && !path_already_exists(paths, *count, path)) {
+ *paths = nvrealloc(*paths, sizeof(char *) * (*count + 1));
+ (*paths)[*count] = nvstrdup(path);
+ (*count)++;
+ }
+}
+
+/*
+ * Given a path, add the subdirectories "/lib", "/lib32", and "/lib64" to the
+ * list of paths to search.
+ */
+static void add_search_paths(char ***paths, int *count, const char *pathbase)
+{
+ int i;
+ const char *subdirs[] = {
+ "/lib",
+ "/lib32",
+ "/lib64",
+ };
+
+ for (i = 0; i < ARRAY_LEN(subdirs); i++) {
+ char *path = nvstrcat(pathbase, subdirs[i], NULL);
+ add_search_path(paths, count, path);
+ nvfree(path);
+ }
+}
+
+/*
+ * Build the list of paths under which to search for conflicting files.
+ * Returns the number of paths added to the search list.
+ */
+static int get_conflicting_search_paths(const Options *op, char ***paths)
+{
+ int ret = 0;
+
+ *paths = NULL;
+
+ add_search_paths(paths, &ret, DEFAULT_X_PREFIX);
+ add_search_paths(paths, &ret, XORG7_DEFAULT_X_PREFIX);
+ add_search_paths(paths, &ret, op->x_prefix);
+ add_search_paths(paths, &ret, DEFAULT_OPENGL_PREFIX);
+ add_search_paths(paths, &ret, op->opengl_prefix);
+ add_search_path(paths, &ret, op->x_module_path);
+ add_search_path(paths, &ret, op->x_library_path);
+
+#if defined(NV_X86_64)
+ if (op->compat32_chroot != NULL) {
+ int i;
+ char *subdirs[] = {
+ DEFAULT_X_PREFIX,
+ op->x_prefix,
+ DEFAULT_OPENGL_PREFIX,
+ op->opengl_prefix,
+ op->compat32_prefix,
+ };
+
+ for (i = 0; i < ARRAY_LEN(subdirs); i++) {
+ char *path = nvstrcat(op->compat32_chroot, "/", subdirs[i], NULL);
+ add_search_paths(paths, &ret, path);
+ nvfree(path);
+ }
+ }
+#endif
+
+ return ret;
+}
+
/*
* build_command_list() - construct a list of all the things to do
@@ -149,70 +241,30 @@ CommandList *build_command_list(Options *op, Package *p)
}
if (!op->kernel_module_only) {
+ char **paths;
+ int numpaths, i;
+
/*
- * Note that searching the various paths may produce duplicate
- * entries for conflicting files; this is OK because we will take
- * care of these duplicates in condense_file_list().
+ * stop recursing into any "nvidia-cg-toolkit"
+ * directory to prevent libGL.so.1 from being deleted
+ * (see bug 843595).
*/
+ static const NoRecursionDirectory skipdirs[] = {
+ { -1, "nvidia-cg-toolkit" },
+ { 0, NULL }
+ };
- ui_status_begin(op, "Searching for conflicting X files:", "Searching");
-
- ui_status_update(op, 0.16f, DEFAULT_X_PREFIX);
- find_conflicting_xfree86_libraries(op, DEFAULT_X_PREFIX, l);
- ui_status_update(op, 0.32f, XORG7_DEFAULT_X_PREFIX);
- find_conflicting_xfree86_libraries(op, XORG7_DEFAULT_X_PREFIX, l);
- ui_status_update(op, 0.48f, "%s", op->x_prefix);
- find_conflicting_xfree86_libraries(op, op->x_prefix, l);
+ numpaths = get_conflicting_search_paths(op, &paths);
- ui_status_update(op, 0.64f, "%s", op->x_module_path);
- find_conflicting_xfree86_libraries_fullpath(op, op->x_module_path, l);
- ui_status_update(op, 0.80f, "%s", op->x_library_path);
- find_conflicting_xfree86_libraries_fullpath(op, op->x_library_path, l);
-
- ui_status_end(op, "done.");
+ ui_status_begin(op, "Searching for conflicting files:", "Searching");
- ui_status_begin(op, "Searching for conflicting OpenGL files:", "Searching");
-
- ui_status_update(op, 0.20f, DEFAULT_X_PREFIX);
- find_conflicting_opengl_libraries(op, DEFAULT_X_PREFIX, l);
- ui_status_update(op, 0.40f, "%s", op->x_prefix);
- find_conflicting_opengl_libraries(op, op->x_prefix, l);
- ui_status_update(op, 0.60f, DEFAULT_OPENGL_PREFIX);
- find_conflicting_opengl_libraries(op, DEFAULT_OPENGL_PREFIX, l);
- ui_status_update(op, 0.80f, "%s", op->opengl_prefix);
- find_conflicting_opengl_libraries(op, op->opengl_prefix, l);
+ for (i = 0; i < numpaths; i++) {
+ ui_status_update(op, (i + 1.0f) / numpaths, "Searching: %s", paths[i]);
+ find_conflicting_files(op, paths[i], p->conflicting_files, l,
+ skipdirs);
+ }
ui_status_end(op, "done.");
-
-#if defined(NV_X86_64)
- if (op->compat32_chroot != NULL) {
- char *prefix;
-
- ui_status_begin(op, "Searching for conflicting compat32 files:", "Searching");
-
- prefix = nvstrcat(op->compat32_chroot, DEFAULT_X_PREFIX, NULL);
- ui_status_update(op, 0.20f, "%s", prefix);
- find_conflicting_opengl_libraries(op, prefix, l);
- nvfree(prefix);
-
- prefix = nvstrcat(op->compat32_chroot, op->x_prefix, NULL);
- ui_status_update(op, 0.40f, "%s", prefix);
- find_conflicting_opengl_libraries(op, prefix, l);
- nvfree(prefix);
-
- prefix = nvstrcat(op->compat32_chroot, DEFAULT_OPENGL_PREFIX, NULL);
- ui_status_update(op, 0.60f, "%s", prefix);
- find_conflicting_opengl_libraries(op, prefix, l);
- nvfree(prefix);
-
- prefix = nvstrcat(op->compat32_chroot, op->compat32_prefix, NULL);
- ui_status_update(op, 0.80f, "%s", prefix);
- find_conflicting_opengl_libraries(op, prefix, l);
- nvfree(prefix);
-
- ui_status_end(op, "done.");
- }
-#endif /* NV_X86_64 */
}
/*
@@ -369,16 +421,6 @@ CommandList *build_command_list(Options *op, Package *p)
nvfree(tmp);
}
- /*
- * if on SuSE or United Linux, also do `/usr/bin/chrc.config
- * SCRIPT_3D no`
- */
-
- if (((op->distro == SUSE) || (op->distro == UNITED_LINUX)) &&
- (access("/usr/bin/chrc.config", X_OK) == 0)) {
- add_command(c, RUN_CMD, "/usr/bin/chrc.config SCRIPT_3D no");
- }
-
/* free the FileList */
free_file_list(l);
@@ -569,197 +611,6 @@ int execute_command_list(Options *op, CommandList *c,
*/
-/*
- * CONFLICT_ARCH_ALL: file always conflicts, regardless of arch
- * CONFLICT_ARCH_32: file only conflicts if its arch is 32 bit
- * CONFLICT_ARCH_64: file only conflicts if its arch is 64 bit
- */
-
-typedef enum {
- CONFLICT_ARCH_ALL,
- CONFLICT_ARCH_32,
- CONFLICT_ARCH_64,
-} ConflictArch;
-
-
-typedef struct {
- const char *name;
- int len;
-
- /*
- * if requiredString is non-NULL, then a file must have this
- * string in order to be considered a conflicting file; we use
- * this to only consider "libglx.*" files conflicts if they have
- * the string "glxModuleData".
- */
-
- const char *requiredString;
-
- ConflictArch conflictArch;
-} ConflictingFileInfo;
-
-static void find_conflicting_files(Options *op,
- char *path,
- ConflictingFileInfo *files,
- FileList *l,
- const NoRecursionDirectory *skipdirs);
-
-static void find_conflicting_libraries(Options *op,
- const char *prefix,
- ConflictingFileInfo *libs,
- FileList *l);
-
-static ConflictingFileInfo __xfree86_opengl_libs[] = {
-
- /* Conflicting OpenGL libraries */
-
- { "libnvidia-glcore.", 17, /* strlen("libnvidia-glcore.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libGL.", 6, /* strlen("libGL.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libGLwrapper.", 13, /* strlen("libGLwrapper.") */
- NULL, CONFLICT_ARCH_ALL },
-
- /* Conflicting X extensions */
-
- { "libglx.", 7, /* strlen("libglx.") */
- "glxModuleData", CONFLICT_ARCH_ALL },
- { "libglamoregl.", 13, /* strlen("libglamoregl.") */
- NULL, CONFLICT_ARCH_ALL },
-
- /* Conflicting EGL libraries: */
-
- { "libEGL.", 7, /* strlen("libEGL.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libGLESv1_CM.", 13, /* strlen("libGLESv1_CM." */
- NULL, CONFLICT_ARCH_ALL },
- { "libGLESv2.", 10, /* strlen("libGLESv2." */
- NULL, CONFLICT_ARCH_ALL },
- { NULL, 0, NULL, CONFLICT_ARCH_ALL }
-};
-
-static ConflictingFileInfo __xfree86_non_opengl_libs[] = {
- { "nvidia_drv.", 11, /* strlen("nvidia_drv.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libvdpau_nvidia.", 16, /* strlen("libvdpau_nvidia.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-cfg.", 14, /* strlen("libnvidia-cfg.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libcuda.", 8, /* strlen("libcuda.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-compiler.", 19, /* strlen("libnvidia-compiler.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvcuvid.", 11, /* strlen("libnvcuvid.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-ml.", 13, /* strlen("libnvidia-ml.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-encode.", 17, /* strlen("libnvidia-encode.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-vgx.", 14, /* strlen("libnvidia-vgx.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-ifr.", 14, /* strlen("libnvidia-ifr.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-vgxcfg.", 17, /* strlen("libnvidia-vgxcfg.") */
- NULL, CONFLICT_ARCH_ALL },
- { NULL, 0, NULL, CONFLICT_ARCH_ALL }
-};
-
-static ConflictingFileInfo __xfree86_vdpau_wrapper_libs[] = {
- { "libvdpau.", 9, /* strlen("libvdpau.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libvdpau_trace.", 15, /* strlen("libvdpau_trace.") */
- NULL, CONFLICT_ARCH_ALL },
- { NULL, 0, NULL, CONFLICT_ARCH_ALL }
-};
-
-/*
- * find_conflicting_xfree86_libraries() - search for conflicting
- * libraries under the XFree86 installation prefix, for all possible
- * libdirs.
- */
-
-static void find_conflicting_xfree86_libraries(Options *op,
- const char *xprefix,
- FileList *l)
-{
- if (!op->no_opengl_files) {
- find_conflicting_libraries(op, xprefix, __xfree86_opengl_libs, l);
- }
- find_conflicting_libraries(op, xprefix, __xfree86_non_opengl_libs, l);
- if (op->install_vdpau_wrapper == NV_OPTIONAL_BOOL_TRUE) {
- find_conflicting_libraries(op, xprefix, __xfree86_vdpau_wrapper_libs, l);
- }
-
-} /* find_conflicting_xfree86_libraries() */
-
-
-
-/*
- * find_conflicting_xfree86_libraries_fullpath() - same as
- * find_conflicting_xfree86_libraries, but bypasses the
- * find_conflicting_libraries step, which appends "lib", "lib64", and
- * "lib32" to the path name. Use this when you have the fullpath that
- * you want searched.
- */
-
-static void find_conflicting_xfree86_libraries_fullpath(Options *op,
- char *path,
- FileList *l)
-{
- if (!op->no_opengl_files) {
- find_conflicting_files(op, path, __xfree86_opengl_libs, l, NULL);
- }
- find_conflicting_files(op, path, __xfree86_non_opengl_libs, l, NULL);
- if (op->install_vdpau_wrapper == NV_OPTIONAL_BOOL_TRUE) {
- find_conflicting_files(op, path, __xfree86_vdpau_wrapper_libs, l, NULL);
- }
-
-} /* find_conflicting_xfree86_libraries_fullpath() */
-
-
-
-static ConflictingFileInfo __opengl_libs[] = {
- { "libnvidia-glcore.", 17, /* strlen("libnvidia-glcore.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libGL.", 6, /* strlen("libGL.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-tls.", 14, /* strlen("libnvidia-tls.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libGLwrapper.", 13, /* strlen("libGLwrapper.") */
- NULL, CONFLICT_ARCH_ALL },
- { NULL, 0, NULL, CONFLICT_ARCH_ALL }
-};
-
-static ConflictingFileInfo __non_opengl_libs[] = {
- { "libnvidia-cfg.", 14, /* strlen("libnvidia-cfg.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libcuda.", 8, /* strlen("libcuda.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-compiler.", 19, /* strlen("libnvidia-compiler.") */
- NULL, CONFLICT_ARCH_ALL },
- { "libnvidia-ml.", 13, /* strlen("libnvidia-ml.") */
- NULL, CONFLICT_ARCH_ALL },
- { NULL, 0, NULL, CONFLICT_ARCH_ALL }
-};
-
-/*
- * find_conflicting_opengl_libraries() - search for conflicting
- * libraries under the OpenGL installation prefix, for all possible
- * libdirs.
- */
-
-static void find_conflicting_opengl_libraries(Options *op,
- const char *glprefix,
- FileList *l)
-{
- if (!op->no_opengl_files) {
- find_conflicting_libraries(op, glprefix, __opengl_libs, l);
- }
- find_conflicting_libraries(op, glprefix, __non_opengl_libs, l);
-
-} /* find_conflicting_opengl_libraries() */
-
-
/*
* find_conflicting_kernel_modules() - search for conflicting kernel
@@ -857,38 +708,7 @@ static int ignore_conflicting_file(Options *op,
struct stat stat_buf;
char *file = MAP_FAILED;
int ret = FALSE;
- int i, len;
-
- /* check if the file only conflicts on certain architectures */
-
- if (info.conflictArch != CONFLICT_ARCH_ALL) {
- ElfFileType elftype = get_elf_architecture(filename);
-
- switch (elftype) {
- case ELF_ARCHITECTURE_32:
- ret = info.conflictArch != CONFLICT_ARCH_32;
- break;
- case ELF_ARCHITECTURE_64:
- ret = info.conflictArch != CONFLICT_ARCH_64;
- break;
- default:
- /*
- * XXX ignore symlinks with indeterminate architectures: their
- * targets may have already been deleted, and they'll be reused
- * or replaced as part of the installation, anyway.
- */
- if (lstat(filename, &stat_buf) == -1) {
- ui_warn(op, "Unable to stat '%s'.", filename);
- } else if ((stat_buf.st_mode & S_IFLNK) == S_IFLNK) {
- ret = TRUE;
- } else {
- ui_warn(op, "Unable to determine the architecture of the "
- "file '%s', which has an architecture-specific "
- "conflict.", filename);
- }
- break;
- }
- }
+ int i, len, size = 0;
/* if no requiredString, do not check for the required string */
@@ -908,11 +728,13 @@ static int ignore_conflicting_file(Options *op,
goto cleanup;
}
- if (!stat_buf.st_size) {
+ size = stat_buf.st_size;
+
+ if (!size) {
goto cleanup;
}
- if ((file = mmap(0, stat_buf.st_size, PROT_READ,
+ if ((file = mmap(0, size, PROT_READ,
MAP_FILE | MAP_SHARED, fd, 0)) == MAP_FAILED) {
ui_error(op, "Unable to map file '%s' for reading (%s)",
filename, strerror(errno));
@@ -930,9 +752,9 @@ static int ignore_conflicting_file(Options *op,
len = strlen(info.requiredString);
- for (i = 0; (i + len) <= stat_buf.st_size; i++) {
+ for (i = 0; (i + len) <= size; i++) {
if ((strncmp(&file[i], info.requiredString, len) == 0) &&
- (((i + len) == stat_buf.st_size) || (file[i+len] == '\0'))) {
+ (((i + len) == size) || (file[i+len] == '\0'))) {
ret = FALSE;
break;
}
@@ -943,7 +765,7 @@ static int ignore_conflicting_file(Options *op,
cleanup:
if (file != MAP_FAILED) {
- munmap(file, stat_buf.st_size);
+ munmap(file, size);
}
if (fd != -1) {
@@ -1027,65 +849,6 @@ static void find_conflicting_files(Options *op,
-
-/*
- * 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,
- ConflictingFileInfo *files,
- FileList *l)
-{
- int i, j;
- char *paths[4];
-
- /*
- * stop recursing into any "nvidia-cg-toolkit"
- * directory to prevent libGL.so.1 from being deleted
- * (see bug 843595).
- */
- static const NoRecursionDirectory skipdirs[] = {
- { -1, "nvidia-cg-toolkit" },
- { 0, NULL }
- };
-
- paths[0] = nvstrcat(prefix, "/", "lib", NULL);
- paths[1] = nvstrcat(prefix, "/", "lib64", NULL);
- paths[2] = nvstrcat(prefix, "/", "lib32", NULL);
- paths[3] = NULL;
-
- for (i = 0; paths[i]; i++) {
- for (j = 0; (j < 3) && paths[i]; j++) {
- /*
- * XXX Check if any one of the 'paths' entries really
- * is a symbolic link pointing to one of the other
- * entries. The logic could be made smarter, since it's
- * unlikely that ../lib32 would be a symbolic link to
- * ../lib64 or vice versa.
- */
- if (!paths[j] || (i == j)) continue;
-
- if (is_symbolic_link_to(paths[i], paths[j])) {
- ui_expert(op, "The conflicting library search path "
- "'%s' is a symbolic link to the library "
- "search path '%s'; skipping '%s'.",
- paths[i], paths[j], paths[i]);
- free(paths[i]); paths[i] = NULL;
- }
- }
-
- if (paths[i]) find_conflicting_files(op, paths[i], files, l, skipdirs);
- }
-
- for (i = 0; i < 3; 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/common-utils/common-utils.c b/common-utils/common-utils.c
index f581f0d..81fd7ed 100644
--- a/common-utils/common-utils.c
+++ b/common-utils/common-utils.c
@@ -522,6 +522,68 @@ char *nv_basename(const char *path)
}
+/*
+ * nv_mkdir_recursive() - make a directory and all parent directories as needed.
+ * dir_list is an optional arguments that if not empty, will be set to a string
+ * containing a newline separated list of all directories created.
+ */
+int nv_mkdir_recursive(const char *path, const mode_t mode,
+ char **error_str, char **dir_list)
+{
+ char *c, *tmp, ch, *list;
+ int success = FALSE;
+
+ if (!path || !path[0]) {
+ return FALSE;
+ }
+
+ tmp = nvstrdup(path);
+ remove_trailing_slashes(tmp);
+
+ list = NULL;
+
+ c = tmp;
+ do {
+ c++;
+ if ((*c == '/') || (*c == '\0')) {
+ ch = *c;
+ *c = '\0';
+ if (!directory_exists(tmp)) {
+ char *tmplist;
+ if (mkdir(tmp, mode) != 0) {
+ *error_str =
+ nvasprintf("Failure creating directory '%s' : (%s)",
+ tmp, strerror(errno));
+ goto done;
+ }
+ /* Prepend the created directory path to a running list */
+ if (dir_list) {
+ tmplist = list;
+ list = nvstrcat(tmp, "\n", tmplist, NULL);
+ free(tmplist);
+ }
+ }
+ *c = ch;
+ }
+ } while (*c);
+
+ /* Log any created directories */
+ if (dir_list && list) {
+ *dir_list = list;
+ }
+
+ success = TRUE;
+
+ done:
+
+ if (!dir_list) {
+ free(list);
+ }
+ free(tmp);
+ return success;
+}
+
+
/****************************************************************************/
/* string helper functions */
/****************************************************************************/
@@ -611,3 +673,39 @@ char *nv_trim_char_strict(char *string, char trim) {
return NULL;
}
+/*
+ * directory_exists() - test whether the given directory exists
+ */
+
+int directory_exists(const char *dir)
+{
+ struct stat stat_buf;
+
+ if ((stat (dir, &stat_buf) == -1) || (!S_ISDIR(stat_buf.st_mode))) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/*
+ * remove_trailing_slashes() - begin at the end of the given string,
+ * and overwrite slashes with NULL as long as we find slashes.
+ */
+
+void remove_trailing_slashes(char *string)
+{
+ int len;
+
+ if (string == NULL) {
+ return;
+ }
+
+ len = strlen(string);
+
+ while (string[len-1] == '/') {
+ string[--len] = '\0';
+ }
+
+}
+
diff --git a/common-utils/common-utils.h b/common-utils/common-utils.h
index 3db71b6..709ff02 100644
--- a/common-utils/common-utils.h
+++ b/common-utils/common-utils.h
@@ -62,10 +62,15 @@ int nv_get_file_length(const char *filename);
void nv_set_file_length(const char *filename, int fd, int len);
void *nv_mmap(const char *filename, size_t len, int prot, int flags, int fd);
char *nv_basename(const char *path);
+int nv_mkdir_recursive(const char *path, const mode_t mode,
+ char **error_str, char **log_str);
char *nv_trim_space(char *string);
char *nv_trim_char(char *string, char trim);
char *nv_trim_char_strict(char *string, char trim);
+void remove_trailing_slashes(char *string);
+
+int directory_exists(const char *dir);
#if defined(__GNUC__)
# define NV_INLINE __inline__
diff --git a/common-utils/nvgetopt.c b/common-utils/nvgetopt.c
index 1c6c9b8..aaebd78 100644
--- a/common-utils/nvgetopt.c
+++ b/common-utils/nvgetopt.c
@@ -42,6 +42,7 @@ int nvgetopt(int argc,
int ret = 0;
int negate = NVGETOPT_FALSE;
int disable = NVGETOPT_FALSE;
+ int double_dash = NVGETOPT_FALSE;
const NVGetoptOption *o = NULL;
static int argv_index = 0;
@@ -65,6 +66,7 @@ int nvgetopt(int argc,
if ((arg[0] == '-') && (arg[1] == '-')) {
name = arg + 2;
+ double_dash = NVGETOPT_TRUE;
} else if (arg[0] == '-') {
name = arg + 1;
} else {
@@ -80,16 +82,26 @@ int nvgetopt(int argc,
c = name;
while (*c) {
- if (*c == '=') { argument = c + 1; *c = '\0'; break; }
+ if (*c == '=') {
+ argument = c + 1;
+ *c = '\0';
+ break;
+ }
c++;
}
/*
+ * if there is no character after '--' then stop processing options.
* if the string is terminated after one character, interpret it
* as a short option. Otherwise, interpret it as a long option.
*/
- if (name[1] == '\0') { /* short option */
+ if (name[0] == '\0') {
+ if (double_dash && argument == NULL) { /* option list terminator */
+ ret = -1;
+ goto done;
+ }
+ } else if (name[1] == '\0') { /* short option */
for (i = 0; options[i].name; i++) {
if (options[i].val == name[0]) {
o = &options[i];
diff --git a/crc.c b/crc.c
index e3e63bb..600e491 100644
--- a/crc.c
+++ b/crc.c
@@ -94,31 +94,41 @@ uint32 compute_crc_from_buffer(const uint8 *buf, int len)
uint32 compute_crc(Options *op, const char *filename)
{
uint32 cword = ~0;
- uint8 *buf;
+ uint8 *buf = MAP_FAILED;
+ int success = FALSE;
int fd;
struct stat stat_buf;
- size_t len;
+ size_t len = 0;
- if ((fd = open(filename, O_RDONLY)) == -1) goto fail;
- if (fstat(fd, &stat_buf) == -1) goto fail;
+ if ((fd = open(filename, O_RDONLY)) == -1) goto done;
+ if (fstat(fd, &stat_buf) == -1) goto done;
- if (stat_buf.st_size == 0) return 0;
+ if (stat_buf.st_size == 0) {
+ cword = 0;
+ success = TRUE;
+ goto done;
+ }
len = stat_buf.st_size;
buf = mmap(0, len, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
- if (buf == (void *) -1) goto fail;
+ if (buf == MAP_FAILED) goto done;
cword = compute_crc_from_buffer(buf, len);
- if (munmap(buf, len) == -1) goto fail;
- if (close(fd) == -1) goto fail;
+ success = TRUE;
- return cword;
+ done:
+ if (!success) {
+ ui_warn(op, "Unable to compute CRC for file '%s' (%s).",
+ filename, strerror(errno));
+ }
- fail:
-
- ui_warn(op, "Unable to compute CRC for file '%s' (%s).",
- filename, strerror(errno));
+ if (buf != MAP_FAILED) {
+ munmap(buf, len);
+ }
+ if (fd >= 0) {
+ close(fd);
+ }
return cword;
diff --git a/dist-files.mk b/dist-files.mk
index b08a951..c4b104f 100644
--- a/dist-files.mk
+++ b/dist-files.mk
@@ -73,11 +73,9 @@ DIST_FILES += rtld_test_Linux-x86_64
DIST_FILES += rtld_test_Linux-armv7l-gnueabi
DIST_FILES += rtld_test_Linux-armv7l-gnueabihf
-DIST_FILES += tls_test_Linux-ia64
DIST_FILES += tls_test_Linux-x86
DIST_FILES += tls_test_Linux-x86_64
-DIST_FILES += tls_test_dso_Linux-ia64.so
DIST_FILES += tls_test_dso_Linux-x86.so
DIST_FILES += tls_test_dso_Linux-x86_64.so
diff --git a/files.c b/files.c
index 5d8b8e6..c7c3628 100644
--- a/files.c
+++ b/files.c
@@ -57,8 +57,7 @@ int remove_directory(Options *op, const char *victim)
struct stat stat_buf;
DIR *dir;
struct dirent *ent;
- char *filename;
- int len;
+ int success = TRUE;
if (lstat(victim, &stat_buf) == -1) {
ui_error(op, "failure to open '%s'", victim);
@@ -75,7 +74,9 @@ int remove_directory(Options *op, const char *victim)
return FALSE;
}
- while ((ent = readdir(dir)) != NULL) {
+ while (success && (ent = readdir(dir)) != NULL) {
+ char *filename;
+ int len;
if (((strcmp(ent->d_name, ".")) == 0) ||
((strcmp(ent->d_name, "..")) == 0)) continue;
@@ -86,30 +87,32 @@ int remove_directory(Options *op, const char *victim)
if (lstat(filename, &stat_buf) == -1) {
ui_error(op, "failure to open '%s'", filename);
- free(filename);
- return FALSE;
- }
-
- if (S_ISDIR(stat_buf.st_mode)) {
- remove_directory(op, filename);
+ success = FALSE;
} else {
- if (unlink(filename) != 0) {
- ui_error(op, "Failure removing file %s (%s)",
- filename, strerror(errno));
+ if (S_ISDIR(stat_buf.st_mode)) {
+ success = remove_directory(op, filename);
+ } else {
+ if (unlink(filename) != 0) {
+ ui_error(op, "Failure removing file %s (%s)",
+ filename, strerror(errno));
+ success = FALSE;
+ }
}
}
+
free(filename);
}
+ closedir(dir);
+
if (rmdir(victim) != 0) {
ui_error(op, "Failure removing directory %s (%s)",
victim, strerror(errno));
return FALSE;
}
- return TRUE;
-
-} /* remove_directory() */
+ return success;
+}
@@ -125,7 +128,7 @@ int touch_directory(Options *op, const char *victim)
DIR *dir;
struct dirent *ent;
struct utimbuf time_buf;
- char *filename;
+ int success = FALSE;
if (lstat(victim, &stat_buf) == -1) {
ui_error(op, "failure to open '%s'", victim);
@@ -150,6 +153,8 @@ int touch_directory(Options *op, const char *victim)
/* loop over each entry in the directory */
while ((ent = readdir(dir)) != NULL) {
+ char *filename;
+ int entry_failed = FALSE;
if (((strcmp(ent->d_name, ".")) == 0) ||
((strcmp(ent->d_name, "..")) == 0)) continue;
@@ -160,16 +165,16 @@ int touch_directory(Options *op, const char *victim)
if (lstat(filename, &stat_buf) == -1) {
ui_error(op, "failure to open '%s'", filename);
- nvfree(filename);
- return FALSE;
+ entry_failed = TRUE;
+ goto entry_done;
}
/* if it is a directory, call this recursively */
if (S_ISDIR(stat_buf.st_mode)) {
if (!touch_directory(op, filename)) {
- nvfree(filename);
- return FALSE;
+ entry_failed = TRUE;
+ goto entry_done;
}
}
@@ -177,21 +182,28 @@ int touch_directory(Options *op, const char *victim)
if (utime(filename, &time_buf) != 0) {
ui_error(op, "Error setting modification time for %s", filename);
- nvfree(filename);
- return FALSE;
+ entry_failed = TRUE;
+ goto entry_done;
}
+ entry_done:
nvfree(filename);
+ if (entry_failed) {
+ goto done;
+ }
}
+ success = TRUE;
+
+ done:
+
if (closedir(dir) != 0) {
ui_error(op, "Error while closing directory %s.", victim);
- return FALSE;
+ success = FALSE;
}
-
- return TRUE;
-} /* touch_directory() */
+ return success;
+}
/*
@@ -205,48 +217,51 @@ int touch_directory(Options *op, const char *victim)
int copy_file(Options *op, const char *srcfile,
const char *dstfile, mode_t mode)
{
- int src_fd, dst_fd;
+ int src_fd = -1, dst_fd = -1;
+ int success = FALSE;
struct stat stat_buf;
char *src, *dst;
if ((src_fd = open(srcfile, O_RDONLY)) == -1) {
ui_error (op, "Unable to open '%s' for copying (%s)",
srcfile, strerror (errno));
- goto fail;
+ goto done;
}
if ((dst_fd = open(dstfile, O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) {
ui_error (op, "Unable to create '%s' for copying (%s)",
dstfile, strerror (errno));
- goto fail;
+ goto done;
}
if (fstat(src_fd, &stat_buf) == -1) {
ui_error (op, "Unable to determine size of '%s' (%s)",
srcfile, strerror (errno));
- goto fail;
+ goto done;
}
- if (stat_buf.st_size == 0)
+ if (stat_buf.st_size == 0) {
+ success = TRUE;
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));
- goto fail;
+ goto done;
}
if (write(dst_fd, "", 1) != 1) {
ui_error (op, "Unable to write file size for '%s' (%s)",
dstfile, strerror (errno));
- goto fail;
+ goto done;
}
if ((src = mmap(0, stat_buf.st_size, PROT_READ,
MAP_FILE | MAP_SHARED, src_fd, 0)) == (void *) -1) {
ui_error (op, "Unable to map source file '%s' for copying (%s)",
srcfile, strerror (errno));
- goto fail;
+ goto done;
}
if ((dst = mmap(0, stat_buf.st_size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, dst_fd, 0)) == (void *) -1) {
ui_error (op, "Unable to map destination file '%s' for copying (%s)",
dstfile, strerror (errno));
- goto fail;
+ goto done;
}
memcpy (dst, src, stat_buf.st_size);
@@ -254,31 +269,36 @@ int copy_file(Options *op, const char *srcfile,
if (munmap (src, stat_buf.st_size) == -1) {
ui_error (op, "Unable to unmap source file '%s' after copying (%s)",
srcfile, strerror (errno));
- goto fail;
+ goto done;
}
if (munmap (dst, stat_buf.st_size) == -1) {
ui_error (op, "Unable to unmap destination file '%s' after "
"copying (%s)", dstfile, strerror (errno));
- goto fail;
+ goto done;
}
+ success = TRUE;
+
done:
- /*
- * the mode used to create dst_fd may have been affected by the
- * user's umask; so explicitly set the mode again
- */
- fchmod(dst_fd, mode);
+ if (success) {
+ /*
+ * the mode used to create dst_fd may have been affected by the
+ * user's umask; so explicitly set the mode again
+ */
- close (src_fd);
- close (dst_fd);
-
- return TRUE;
+ fchmod(dst_fd, mode);
+ }
- fail:
- return FALSE;
+ if (src_fd != -1) {
+ close (src_fd);
+ }
+ if (dst_fd != -1) {
+ close (dst_fd);
+ }
-} /* copy_file() */
+ return success;
+}
@@ -368,7 +388,7 @@ char *write_temp_file(Options *op, const int len,
if (ret) {
return tmpfile;
} else {
- if (tmpfile) nvfree(tmpfile);
+ nvfree(tmpfile);
return NULL;
}
@@ -385,6 +405,7 @@ char *write_temp_file(Options *op, const int len,
void select_tls_class(Options *op, Package *p)
{
+#if defined(NV_TLS_TEST)
int i;
if (!tls_test(op, FALSE)) {
@@ -456,7 +477,7 @@ void select_tls_class(Options *op, Package *p)
}
#endif /* NV_X86_64 */
-
+#endif /* NV_TLS_TEST */
} /* select_tls_class() */
@@ -534,6 +555,10 @@ int set_destinations(Options *op, Package *p)
case FILE_TYPE_CUDA_LIB:
case FILE_TYPE_CUDA_SYMLINK:
+ case FILE_TYPE_OPENCL_LIB:
+ case FILE_TYPE_OPENCL_WRAPPER_LIB:
+ case FILE_TYPE_OPENCL_LIB_SYMLINK:
+ case FILE_TYPE_OPENCL_WRAPPER_SYMLINK:
if (p->entries[i].compat_arch == FILE_COMPAT_ARCH_COMPAT32) {
prefix = op->compat32_prefix;
dir = op->compat32_libdir;
@@ -550,13 +575,6 @@ int set_destinations(Options *op, Package *p)
path = "";
break;
- case FILE_TYPE_XLIB_SHARED_LIB:
- case FILE_TYPE_XLIB_STATIC_LIB:
- case FILE_TYPE_XLIB_SYMLINK:
- prefix = op->x_library_path;
- dir = path = "";
- break;
-
case FILE_TYPE_XMODULE_SHARED_LIB:
case FILE_TYPE_GLX_MODULE_SHARED_LIB:
case FILE_TYPE_XMODULE_SYMLINK:
@@ -714,6 +732,11 @@ int set_destinations(Options *op, Package *p)
path = "";
break;
+ case FILE_TYPE_XORG_OUTPUTCLASS_CONFIG:
+ prefix = op->x_sysconfig_path;
+ dir = path = "";
+ break;
+
default:
/*
@@ -768,8 +791,8 @@ int set_destinations(Options *op, Package *p)
int get_license_acceptance(Options *op)
{
struct stat buf;
- char *text, *tmp;
- int fd;
+ char *text = MAP_FAILED, *tmp = NULL;
+ int fd = -1, accepted = FALSE, size = 0;
/* trivial accept if the user accepted on the command line */
@@ -778,46 +801,50 @@ int get_license_acceptance(Options *op)
return TRUE;
}
- if ((fd = open(LICENSE_FILE, 0x0)) == -1) goto failed;
+ if ((fd = open(LICENSE_FILE, 0x0)) == -1) goto done;
- if (fstat(fd, &buf) != 0) goto failed;
+ if (fstat(fd, &buf) != 0) goto done;
+
+ size = buf.st_size;
- if ((text = (char *) mmap(NULL, buf.st_size, PROT_READ,
+ if ((text = (char *) mmap(NULL, size, PROT_READ,
MAP_FILE|MAP_SHARED,
- fd, 0x0)) == (char *) -1) goto failed;
+ fd, 0x0)) == MAP_FAILED) goto done;
/*
* the mmap'ed license file may not be NULL terminated, so copy it
* into a temporary buffer and explicity NULL terminate the string
*/
- tmp = nvalloc(buf.st_size + 1);
- memcpy(tmp, text, buf.st_size);
- tmp[buf.st_size] = '\0';
+ tmp = nvalloc(size + 1);
+ memcpy(tmp, text, size);
+ tmp[size] = '\0';
if (!ui_display_license(op, tmp)) {
ui_message(op, "License not accepted. Aborting installation.");
- nvfree(tmp);
- munmap(text, buf.st_size);
- close(fd);
- return FALSE;
+ } else {
+ ui_log(op, "License accepted.");
+ accepted = TRUE;
}
- ui_log(op, "License accepted.");
-
+ done:
+
nvfree(tmp);
- munmap(text, buf.st_size);
- close(fd);
-
- return TRUE;
- failed:
-
- ui_error(op, "Unable to open License file '%s' (%s)",
- LICENSE_FILE, strerror(errno));
- return FALSE;
+ if (text == MAP_FAILED || fd == -1) {
+ ui_error(op, "Unable to open License file '%s' (%s)",
+ LICENSE_FILE, strerror(errno));
+ }
+
+ if (text != MAP_FAILED) {
+ munmap(text, size);
+ }
+ if (fd != -1) {
+ close(fd);
+ }
-} /* get_license_acceptance() */
+ return accepted;
+}
@@ -850,8 +877,9 @@ int get_prefixes (Options *op)
* after the default prefixes/paths are assigned.
*/
- get_x_library_and_module_paths(op);
-
+ if (op->x_files_packaged) {
+ get_x_library_and_module_paths(op);
+ }
if (op->expert) {
ret = ui_get_input(op, op->x_library_path,
@@ -1106,23 +1134,6 @@ void remove_opengl_files_from_package(Options *op, Package *p)
}
-/*
- * remove_trailing_slashes() - begin at the end of the given string,
- * and overwrite slashes with NULL as long as we find slashes.
- */
-
-void remove_trailing_slashes(char *s)
-{
- int len;
-
- if (s == NULL) return;
- len = strlen(s);
-
- while (s[len-1] == '/') s[--len] = '\0';
-
-} /* remove_trailing_slashes() */
-
-
/*
* mode_string_to_mode() - convert the string s
@@ -1179,23 +1190,6 @@ char *mode_to_permission_string(mode_t mode)
/*
- * directory_exists() -
- */
-
-int directory_exists(Options *op, const char *dir)
-{
- struct stat stat_buf;
-
- if ((stat (dir, &stat_buf) == -1) || (!S_ISDIR(stat_buf.st_mode))) {
- return FALSE;
- } else {
- return TRUE;
- }
-} /* directory_exists() */
-
-
-
-/*
* confirm_path() - check that the path exists; if not, ask the user
* if it's OK to create it and then do mkdir().
*
@@ -1215,7 +1209,7 @@ int confirm_path(Options *op, const char *path)
/* return TRUE if the path already exists and is a directory */
- if (directory_exists(op, path)) return TRUE;
+ if (directory_exists(path)) return TRUE;
if (ui_multiple_choice(op, choices, 2, 0, "The directory '%s' does not "
"exist; would you like to create it, or would you "
@@ -1244,46 +1238,23 @@ int confirm_path(Options *op, const char *path)
int mkdir_recursive(Options *op, const char *path, const mode_t mode, int log)
{
- char *c, *tmp, ch, *list, *tmplist;
-
- if (!path || !path[0]) return FALSE;
-
- tmp = nvstrdup(path);
- remove_trailing_slashes(tmp);
-
- list = NULL;
+ char *error_str = NULL;
+ char *log_str = NULL;
+ int success = FALSE;
- c = tmp;
- do {
- c++;
- if ((*c == '/') || (*c == '\0')) {
- ch = *c;
- *c = '\0';
- if (!directory_exists(op, tmp)) {
- if (mkdir(tmp, mode) != 0) {
- ui_error(op, "Failure creating directory '%s': (%s)",
- tmp, strerror(errno));
- free(tmp);
- return FALSE;
- }
- /* Prepend the created directory path to a running list */
- tmplist = list;
- list = nvstrcat(tmp, "\n", tmplist, NULL);
- free(tmplist);
- }
- *c = ch;
- }
- } while (*c);
+ success = nv_mkdir_recursive(path, mode, &error_str, log ? &log_str : NULL);
- /* Log any created directories */
- if (log && list) {
- log_mkdir(op, list);
+ if (log_str) {
+ log_mkdir(op, log_str);
+ free(log_str);
}
- free(list);
- free(tmp);
- return TRUE;
+ if (error_str) {
+ ui_error(op, "%s", error_str);
+ free(error_str);
+ }
+ return success;
}
@@ -1481,7 +1452,7 @@ char *get_tmpdir(Options *op)
tmpdirs[3] = getenv("HOME");
for (i = 0; i < 4; i++) {
- if (tmpdirs[i] && directory_exists(op, tmpdirs[i])) {
+ if (tmpdirs[i] && directory_exists(tmpdirs[i])) {
return (tmpdirs[i]);
}
}
@@ -1505,7 +1476,7 @@ char *make_tmpdir(Options *op)
tmpdir = nvstrcat(op->tmpdir, "/nvidia-", tmp, NULL);
- if (directory_exists(op, tmpdir)) {
+ if (directory_exists(tmpdir)) {
remove_directory(op, tmpdir);
}
@@ -1629,8 +1600,7 @@ int copy_directory_contents(Options *op, const char *src, const char *dst)
{
DIR *dir;
struct dirent *ent;
- char *srcfile, *dstfile;
- struct stat stat_buf;
+ int status = FALSE;
if ((dir = opendir(src)) == NULL) {
ui_error(op, "Unable to open directory '%s' (%s).",
@@ -1639,6 +1609,9 @@ int copy_directory_contents(Options *op, const char *src, const char *dst)
}
while ((ent = readdir(dir)) != NULL) {
+ struct stat stat_buf;
+ char *srcfile, *dstfile;
+ int ret;
if (((strcmp(ent->d_name, ".")) == 0) ||
((strcmp(ent->d_name, "..")) == 0)) continue;
@@ -1654,12 +1627,20 @@ int copy_directory_contents(Options *op, const char *src, const char *dst)
dstfile = nvstrcat(dst, "/", ent->d_name, NULL);
- if (!copy_file(op, srcfile, dstfile, stat_buf.st_mode)) return FALSE;
+ ret = copy_file(op, srcfile, dstfile, stat_buf.st_mode);
nvfree(srcfile);
nvfree(dstfile);
+
+ if (!ret) {
+ goto done;
+ }
}
+ status = TRUE;
+
+ done:
+
if (closedir(dir) != 0) {
ui_error(op, "Failure while closing directory '%s' (%s).",
src, strerror(errno));
@@ -1667,7 +1648,7 @@ int copy_directory_contents(Options *op, const char *src, const char *dst)
return FALSE;
}
- return TRUE;
+ return status;
} /* copy_directory_contents() */
@@ -1692,24 +1673,32 @@ int pack_precompiled_files(Options *op, Package *p, int num_files,
/* make sure the precompiled_kernel_interface_directory exists */
- mkdir_recursive(op, p->precompiled_kernel_interface_directory, 0755, FALSE);
+ if (!mkdir_recursive(op, p->precompiled_kernel_interface_directory, 0755,
+ FALSE)) {
+ ui_error(op, "Failed to create the directory '%s'!",
+ p->precompiled_kernel_interface_directory);
+ return FALSE;
+ }
/* use the time in the output string... should be fairly unique */
t = time(NULL);
snprintf(time_str, 256, "%lu", t);
-
- /* read the proc version string */
-
- proc_version_string = read_proc_version(op, op->proc_mount_point);
/* use the uname string as the description */
- uname(&buf);
+ if (uname(&buf) != 0) {
+ ui_error(op, "Failed to retrieve uname identifiers from the kernel!");
+ return FALSE;
+ }
descr = nvstrcat(buf.sysname, " ",
buf.release, " ",
buf.version, " ",
buf.machine, NULL);
+
+ /* read the proc version string */
+
+ proc_version_string = read_proc_version(op, op->proc_mount_point);
/* build the PrecompiledInfo struct */
@@ -1729,7 +1718,7 @@ int pack_precompiled_files(Options *op, Package *p, int num_files,
nvfree(outfile);
free_precompiled(info);
-
+
if (ret) {
return TRUE;
}
@@ -1738,7 +1727,6 @@ int pack_precompiled_files(Options *op, Package *p, int num_files,
ui_error(op, "Unable to package precompiled kernel interface.");
return FALSE;
}
-
}
@@ -2129,12 +2117,139 @@ int set_security_context(Options *op, const char *filename)
ret = run_command(op, cmd, NULL, FALSE, 0, TRUE);
ret = ((ret == 0) ? TRUE : FALSE);
- if (cmd) nvfree(cmd);
+ nvfree(cmd);
return ret;
} /* set_security_context() */
+static char * const native_libdirs[] = {
+#if defined(NV_X86_64)
+ DEFAULT_AMD64_TRIPLET_LIBDIR,
+#elif defined(NV_X86)
+ DEFAULT_IA32_TRIPLET_LIBDIR,
+#elif defined(NV_ARMV7)
+#if defined(NV_GNUEABIHF)
+ DEFAULT_ARMV7HF_TRIPLET_LIBDIR,
+#else
+ DEFAULT_ARMV7_TRIPLET_LIBDIR,
+#endif /* GNUEABIHF */
+#elif defined(NV_AARCH64)
+ DEFAULT_AARCH64_TRIPLET_LIBDIR,
+#elif defined(NV_PPC64LE)
+ DEFAULT_PPC64LE_TRIPLET_LIBDIR,
+#endif
+#if NV_ARCH_BITS == 32
+ DEFAULT_32BIT_LIBDIR,
+#elif NV_ARCH_BITS == 64
+ DEFAULT_64BIT_LIBDIR,
+#else
+#error Unknown architecture! Please update utils.mk to add support for this \
+TARGET_ARCH, and make sure that an architecture-specific NV_$ARCH macro gets \
+defined, and that NV_ARCH_BITS gets defined to the correct word size in bits.
+#endif
+ DEFAULT_LIBDIR,
+ NULL
+};
+
+
+#if defined(NV_X86_64)
+static char * const compat_libdirs[] = {
+ DEFAULT_IA32_TRIPLET_LIBDIR,
+ DEFAULT_32BIT_LIBDIR,
+ DEFAULT_LIBDIR,
+ NULL
+};
+#endif
+
+
+
+/*
+ * get_ldconfig_cache() - retrieve the ldconfig(8) cache, or NULL on error
+ */
+
+static char *get_ldconfig_cache(Options *op)
+{
+ char *data, *cmd;
+ int ret;
+
+ cmd = nvstrcat(op->utils[LDCONFIG], " -p", NULL);
+ ret = run_command(op, cmd, &data, FALSE, 0, FALSE);
+ nvfree(cmd);
+
+ if (ret != 0) {
+ nvfree(data);
+ return NULL;
+ }
+
+ return data;
+}
+
+
+/*
+ * find_libdir() - search in 'prefix' (optionally under 'chroot'/'prefix')
+ * for directories in 'list', either in the ldconfig(8) cache or on the
+ * filesystem. return the first directory found, or NULL if none found.
+ */
+
+static char *find_libdir(char * const * list, const char *prefix,
+ const char *ldconfig_cache, const char *chroot)
+{
+ int i;
+ char *path = NULL;
+
+ for (i = 0; list[i]; i++) {
+ nvfree(path);
+
+ path = nvstrcat(chroot ? chroot : "",
+ "/", prefix, "/", list[i], "/", NULL);
+ collapse_multiple_slashes(path);
+
+ if (ldconfig_cache) {
+ if (strstr(ldconfig_cache, path)) {
+ break;
+ }
+ } else {
+ if (directory_exists(path)) {
+ break;
+ }
+ }
+ }
+
+ nvfree(path);
+ return list[i];
+}
+
+
+/*
+ * find_libdir_and_fall_back() - search for the first available directory from
+ * 'list' under 'prefix' that appears in the 'ldconfig_cache'. If no directory
+ * is found in 'ldconfig_cache', test for directory existence; if no directory
+ * from 'list' exists under 'prefix', default to DEFAULT_LIBDIR and print a
+ * warning message.
+ */
+static char * find_libdir_and_fall_back(Options *op, char * const * list,
+ const char *prefix,
+ const char *ldconfig_cache,
+ const char *name)
+{
+ char *libdir = find_libdir(list, prefix, ldconfig_cache, NULL);
+ if (!libdir) {
+ libdir = find_libdir(list, prefix, NULL, NULL);
+ }
+ if (!libdir) {
+ libdir = DEFAULT_LIBDIR;
+ ui_warn(op, "Unable to determine the default %s path. The path %s/%s "
+ "will be used, but this path was not detected in the "
+ "ldconfig(8) cache, and no directory exists at this path, "
+ "so it is likely that libraries installed there will not "
+ "be found by the loader.", name, prefix, libdir);
+ }
+
+ return libdir;
+}
+
+
/*
* get_default_prefixes_and_paths() - assign the default prefixes and
* paths depending on the architecture, distribution and the X.Org
@@ -2143,22 +2258,18 @@ int set_security_context(Options *op, const char *filename)
void get_default_prefixes_and_paths(Options *op)
{
- char *default_libdir;
-
-#if defined(NV_X86_64)
- if ((op->distro == DEBIAN) ||
- (op->distro == UBUNTU) ||
- (op->distro == ARCH)) {
- default_libdir = DEBIAN_DEFAULT_64BIT_LIBDIR;
- } else {
- default_libdir = DEFAULT_64BIT_LIBDIR;
- }
-#else
- default_libdir = DEFAULT_LIBDIR;
-#endif
+ char *default_libdir, *ldconfig_cache;
if (!op->opengl_prefix)
op->opengl_prefix = DEFAULT_OPENGL_PREFIX;
+
+ ldconfig_cache = get_ldconfig_cache(op);
+
+ default_libdir = find_libdir_and_fall_back(op, native_libdirs,
+ op->opengl_prefix,
+ ldconfig_cache, "library");
+
+
if (!op->opengl_libdir)
op->opengl_libdir = default_libdir;
if (!op->opengl_incdir)
@@ -2171,8 +2282,20 @@ void get_default_prefixes_and_paths(Options *op)
op->x_prefix = DEFAULT_X_PREFIX;
}
}
- if (!op->x_libdir)
- op->x_libdir = default_libdir;
+ if (!op->x_libdir) {
+ /* XXX if we just inherit default_libdir from above, we could end up
+ * with e.g. /usr/lib/x86_64-linux-gnu/xorg/modules as the module path.
+ * In practice, we haven't seen the tuplet-based paths used for X
+ * module paths, so skip the first (tuplet-based) entry from
+ * native_libdirs when getting a default value for x_libdir. This is
+ * only used when we have to guess the paths when the query fails. */
+ op->x_libdir = find_libdir_and_fall_back(op, &native_libdirs[1],
+ op->x_prefix, ldconfig_cache,
+ "X library");
+ }
+
+ nvfree(ldconfig_cache);
+
if (!op->x_moddir) {
if (op->modular_xorg) {
op->x_moddir = XORG7_DEFAULT_X_MODULEDIR ;
@@ -2184,58 +2307,6 @@ void get_default_prefixes_and_paths(Options *op)
#if defined(NV_X86_64)
if (!op->compat32_prefix)
op->compat32_prefix = DEFAULT_OPENGL_PREFIX;
-
- if (!op->compat32_libdir) {
- if ((op->distro == UBUNTU) ||
- (op->distro == GENTOO) ||
- (op->distro == ARCH)) {
- op->compat32_libdir = UBUNTU_DEFAULT_COMPAT32_LIBDIR;
- } else {
- op->compat32_libdir = DEFAULT_LIBDIR;
- }
- }
-
- if (op->distro == DEBIAN && !op->compat32_chroot) {
- /*
- * Newer versions of Debian install 32-bit compatibility libraries
- * to dedicated directories that are not part of a chroot structure.
- * Search for the known paths and use the first one that is found.
- */
-
- char *debian_compat32_paths[] = { DEBIAN_DEFAULT_COMPAT32_LIBDIR,
- UBUNTU_DEFAULT_COMPAT32_LIBDIR };
- int i, found = FALSE;
-
- for (i = 0; i < ARRAY_LEN(debian_compat32_paths); i++) {
- char *default_path = nvstrcat(op->compat32_prefix, "/",
- debian_compat32_paths[i], NULL);
-
- struct stat buf;
-
- if (lstat(default_path, &buf) == 0 && !S_ISLNK(buf.st_mode)) {
- /* path exists and is not a symbolic link, so use it */
- op->compat32_libdir = debian_compat32_paths[i];
- found = TRUE;
- }
-
- nvfree(default_path);
-
- if (found) {
- break;
- }
- }
-
- if (!found) {
- /*
- * Paths don't exist or are symbolic links. Use the compat32
- * chroot path instead.
- */
-
- op->compat32_chroot = DEBIAN_DEFAULT_COMPAT32_CHROOT;
- }
-
- }
-
#endif
if (!op->utility_prefix)
@@ -2268,6 +2339,119 @@ void get_default_prefixes_and_paths(Options *op)
} /* get_default_prefixes_and_paths() */
+#if defined NV_X86_64
+/*
+ * compat32_conflict() - given a value for the compatibility library directory,
+ * determines whether a conflict exists between the proposed compatibility
+ * library path and the existing OpenGL library path. e.g. if the native path
+ * is /usr/lib/x86_64-linux-gnu, then /usr/lib is probably not a good path for
+ * compat32 libs. On the other hand, /usr/lib/i386-linux-gnu might be a valid
+ * compat32 directory for a system where /usr/lib is the native library
+ * directory, so the comparison is one-directional.
+ *
+ * XXX this assumes that the native directory would never be a subdirectory of
+ * the compat directory, which might not actually be true.
+ */
+static int compat32_conflict(Options *op, const char *compat_libdir)
+{
+ char *native_path, *compat_path;
+ int ret, is_subdir;
+
+ native_path = nvstrcat(op->opengl_prefix, "/", op->opengl_libdir, NULL);
+ compat_path = nvstrcat(op->compat32_chroot ? op->compat32_chroot : "",
+ "/", op->compat32_prefix, "/", compat_libdir, NULL);
+
+ ret = is_subdirectory(compat_path, native_path, &is_subdir);
+
+ if (!ret) {
+ ui_error(op, "Failed to determine whether '%s' is a subdirectory of "
+ "'%s'; '%s' will not be considered as a candidate location "
+ "for installing 32-bit compatibility libraries.",
+ native_path, compat_path, compat_path);
+ is_subdir = TRUE;
+ }
+
+ nvfree(native_path);
+ nvfree(compat_path);
+
+ return is_subdir;
+}
+#endif
+
+
+/*
+ * get_compat32_path() - detect the appropriate path for installing the 32-bit
+ * compatibility files. This function must be called after parse_manifest(),
+ * and before set_destinations().
+ */
+void get_compat32_path(Options *op)
+{
+#if defined(NV_X86_64)
+ char *ldconfig_cache = get_ldconfig_cache(op);
+
+ if (!op->compat32_prefix)
+ op->compat32_prefix = DEFAULT_OPENGL_PREFIX;
+
+ if(!op->compat32_libdir) {
+ char *compat_libdir;
+
+
+ /* First, search the ldconfig(8) cache and filesystem normally */
+ compat_libdir = find_libdir(compat_libdirs, op->compat32_prefix,
+ ldconfig_cache, op->compat32_chroot);
+
+ if (!compat_libdir || compat32_conflict(op, compat_libdir)) {
+ compat_libdir = find_libdir(compat_libdirs, op->compat32_prefix,
+ NULL, op->compat32_chroot);
+ }
+
+ /*
+ * If we still didn't find a suitable directory, and the user did not
+ * specify an explicit chroot, try the old Debian 32-bit chroot.
+ */
+ if ((!compat_libdir || compat32_conflict(op, compat_libdir)) &&
+ !op->compat32_chroot) {
+ op->compat32_chroot = DEBIAN_DEFAULT_COMPAT32_CHROOT;
+
+ compat_libdir = find_libdir(compat_libdirs, op->compat32_prefix,
+ ldconfig_cache, op->compat32_chroot);
+
+ if (!compat_libdir || compat32_conflict(op, compat_libdir)) {
+ compat_libdir = find_libdir(compat_libdirs, op->compat32_prefix,
+ NULL, op->compat32_chroot);
+ }
+
+ /*
+ * If we still didn't find a suitable path in the old Debian chroot,
+ * reset the chroot path and the detected directory.
+ */
+ if (!compat_libdir || compat32_conflict(op, compat_libdir)) {
+ op->compat32_chroot = NULL;
+ compat_libdir = NULL;
+ }
+ }
+
+ /* If we still failed to find a directory, don't install 32-bit files */
+ if (op->install_compat32_libs != NV_OPTIONAL_BOOL_FALSE &&
+ (!compat_libdir || compat32_conflict(op, compat_libdir))) {
+ ui_warn(op, "Unable to find a suitable destination to install "
+ "32-bit compatibility libraries. Your system may not "
+ "be set up for 32-bit compatibility. 32-bit "
+ "compatibility files will not be installed; if you "
+ "wish to install them, re-run the installation and set "
+ "a valid directory with the --compat32-libdir option.");
+ op->install_compat32_libs = NV_OPTIONAL_BOOL_FALSE;
+ }
+
+ if (op->install_compat32_libs != NV_OPTIONAL_BOOL_FALSE) {
+ op->compat32_libdir = compat_libdir;
+ }
+ }
+
+ nvfree(ldconfig_cache);
+#endif
+}
+
/*
* get_xdg_data_dir() - determine if the XDG_DATA_DIRS environment
* variable is set; if set and not empty, return the first path
@@ -2347,19 +2531,25 @@ static char *extract_x_path(char *str, char **next)
} /* extract_x_path() */
+enum XPathType {
+ XPathLibrary,
+ XPathModule,
+ XPathSysConfig
+};
/*
* get_x_paths_helper() - helper function for determining the X
- * library and module paths; returns 'TRUE' if we had to guess at the
- * path
+ * library, module, and system xorg.conf.d paths; returns 'TRUE' if we had to
+ * guess at the path
*/
static int get_x_paths_helper(Options *op,
- int library,
+ enum XPathType pathType,
char *xserver_cmd,
char *pkg_config_cmd,
char *name,
- char **path)
+ char **path,
+ int require_existing_directory)
{
char *dirs, *cmd, *dir, *next;
int ret, guessed = 0;
@@ -2381,7 +2571,7 @@ static int get_x_paths_helper(Options *op,
* first, try the X server commandline option; this is the
* recommended query mechanism as of X.Org 7.2
*/
- if (op->utils[XSERVER]) {
+ if (op->utils[XSERVER] && xserver_cmd) {
dirs = NULL;
cmd = nvstrcat(op->utils[XSERVER], " ", xserver_cmd, NULL);
@@ -2396,8 +2586,8 @@ static int get_x_paths_helper(Options *op,
while (dir) {
- if (directory_exists(op, dir)) {
-
+ if (!require_existing_directory || directory_exists(dir)) {
+
ui_expert(op, "X %s path '%s' determined from `%s %s`",
name, dir, op->utils[XSERVER], xserver_cmd);
@@ -2443,7 +2633,7 @@ static int get_x_paths_helper(Options *op,
while (dir) {
- if (directory_exists(op, dir)) {
+ if (!require_existing_directory || directory_exists(dir)) {
ui_expert(op, "X %s path '%s' determined from `%s %s`",
name, dir, op->utils[PKG_CONFIG],
@@ -2483,11 +2673,19 @@ static int get_x_paths_helper(Options *op,
/* build the path */
-
- if (library) {
- *path = nvstrcat(op->x_prefix, "/", op->x_libdir, NULL);
- } else {
- *path = nvstrcat(op->x_library_path, "/", op->x_moddir, NULL);
+
+ switch (pathType) {
+ case XPathLibrary:
+ *path = nvstrcat(op->x_prefix, "/", op->x_libdir, NULL);
+ break;
+
+ case XPathModule:
+ *path = nvstrcat(op->x_library_path, "/", op->x_moddir, NULL);
+ break;
+
+ case XPathSysConfig:
+ *path = nvstrcat(DEFAULT_X_DATAROOT_PATH, "/", DEFAULT_CONFDIR, NULL);
+ break;
}
remove_trailing_slashes(*path);
@@ -2512,19 +2710,35 @@ static void get_x_library_and_module_paths(Options *op)
*/
guessed |= get_x_paths_helper(op,
- TRUE,
+ XPathLibrary,
"-showDefaultLibPath",
"--variable=libdir xorg-server",
"library",
- &op->x_library_path);
+ &op->x_library_path,
+ TRUE);
guessed |= get_x_paths_helper(op,
- FALSE,
+ XPathModule,
"-showDefaultModulePath",
"--variable=moduledir xorg-server",
"module",
- &op->x_module_path);
-
+ &op->x_module_path,
+ TRUE);
+
+ /*
+ * Get the sysconfig path (typically /usr/share/X11/xorg.conf.d). This is
+ * only needed if the nvidia.conf OutputClass config snippet is going to be
+ * installed. Don't complain if we had to guess the path; the server will
+ * still work without it if xorg.conf is set up.
+ */
+ get_x_paths_helper(op,
+ XPathSysConfig,
+ NULL,
+ "--variable=sysconfigdir xorg-server",
+ "sysconfig",
+ &op->x_sysconfig_path,
+ FALSE);
+
/*
* done assigning op->x_library_path and op->x_module_path; if we
* had to guess at either of the paths, print a warning
@@ -2551,31 +2765,33 @@ static void get_x_library_and_module_paths(Options *op)
*/
char *get_filename(Options *op, const char *def, const char *msg)
{
- struct stat stat_buf;
- char *file = NULL;
+ char *oldfile = nvstrdup(def);
/* XXX This function should never be called if op->no_questions is set,
* but just in case that happens by accident, do something besides looping
* infinitely if def is a filename that doesn't exist. */
if (op->no_questions) {
- return nvstrdup(def);
+ return oldfile;
}
- file = ui_get_input(op, file ? file : def, "%s", msg);
+ while (TRUE) {
+ struct stat stat_buf;
+ char *file = ui_get_input(op, oldfile, "%s", msg);
+
+ nvfree(oldfile);
- while (stat(file, &stat_buf) == -1 ||
- !(S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) {
- char *oldfile = file;
+ if (file && stat(file, &stat_buf) != -1 &&
+ (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) {
+ return file;
+ }
ui_message(op, "File \"%s\" does not exist, or is not a regular "
- "file. Please enter another filename.", file);
+ "file. Please enter another filename.", file ?
+ file : "(null)");
- file = ui_get_input(op, oldfile ? oldfile : def, "%s", msg);
- nvfree(oldfile);
+ oldfile = file;
}
-
- return file;
-} /* get_filename() */
+}
@@ -2624,3 +2840,148 @@ void invalidate_package_entry(PackageEntry *entry)
entry->dst = NULL;
memset(&(entry->caps), 0, sizeof(entry->caps));
}
+
+
+/*
+ * is_subdirectory() - test whether subdir is a subdir of dir
+ * returns TRUE on successful test, or FALSE on error
+ * sets *is_subdir based on the result of a successful test
+ *
+ * The testing is performed two ways: first, walk from subdir up to "/"
+ * and check at each step along the way if subdir's device and inode
+ * match dir's. If a match is not found this way, simply compare dir
+ * and subdir as normalized strings, up to the length of subdir, since
+ * the first method will fail if subdir is a symlink located inside dir
+ * whose target is outside of dir.
+ */
+
+int is_subdirectory(const char *dir, const char *subdir, int *is_subdir)
+{
+ struct stat root_st, dir_st;
+
+ if (stat("/", &root_st) != 0 || stat(dir, &dir_st) != 0) {
+ return FALSE;
+ } else {
+ struct stat testdir_st;
+ char *testdir = nvstrdup(subdir);
+
+ *is_subdir = FALSE;
+
+ do {
+ char *oldtestdir;
+
+ if (stat(testdir, &testdir_st) != 0) {
+ nvfree(testdir);
+ return FALSE;
+ }
+
+ if (testdir_st.st_dev == dir_st.st_dev &&
+ testdir_st.st_ino == dir_st.st_ino) {
+ *is_subdir = TRUE;
+ break;
+ }
+
+ oldtestdir = testdir;
+ testdir = nvstrcat(oldtestdir, "/..", NULL);
+ nvfree(oldtestdir);
+ } while (testdir_st.st_dev != root_st.st_dev ||
+ testdir_st.st_ino != root_st.st_ino);
+
+ nvfree(testdir);
+ }
+
+ if (!*is_subdir) {
+ char *dir_with_slash, *subdir_with_slash;
+
+ dir_with_slash = nvstrcat(dir, "/", NULL);
+ collapse_multiple_slashes(dir_with_slash);
+ subdir_with_slash = nvstrcat(subdir, "/", NULL);
+ collapse_multiple_slashes(subdir_with_slash);
+
+ *is_subdir = (strncmp(dir_with_slash, subdir_with_slash,
+ strlen(dir_with_slash)) == 0);
+
+ nvfree(dir_with_slash);
+ nvfree(subdir_with_slash);
+ }
+
+ return TRUE;
+}
+
+/*
+ * directory_equals() - if a is a subdirectory of b, and b is a subdirectory
+ * of a, then a and b are the same directory. Uses is_subdirectory() to do the
+ * subdirectory check, since the inode-based comparison will be resilient
+ * against symbolic links in either direction.
+ */
+static int directory_equals(const char *a, const char *b)
+{
+ int a_b, b_a;
+
+ if (is_subdirectory(a, b, &a_b) && is_subdirectory(b, a, &b_a)) {
+ return a_b && b_a;
+ }
+
+ return FALSE;
+}
+
+/*
+ * get_opengl_libdir() - get the path where OpenGL libraries will be installed.
+ */
+static char *get_opengl_libdir(const Options *op)
+{
+ return nvstrcat(op->opengl_prefix, "/", op->opengl_libdir, "/", NULL);
+}
+
+/*
+ * get_compat32_libdir() - get the path where 32-bit compatibility libraries
+ * will be installed, where applicable, or NULL when not applicable.
+ */
+static char *get_compat32_libdir(const Options *op)
+{
+#if defined NV_X86_64
+ return nvstrcat(op->compat32_chroot ? op->compat32_chroot : "", "/",
+ op->compat32_prefix, "/", op->compat32_libdir, "/", NULL);
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * add_libgl_abi_symlink() - check to see if either native or compatibility
+ * OpenGL libraries are destined to be installed to /usr/lib. If not, then
+ * create a symlink /usr/lib/libGL.so.1 that points to the native libGL.so.1,
+ * for compliance with the OpenGL ABI. Note: this function must be called
+ * after set_destinations() to avoid the hardcoded "/usr/lib" destination from
+ * being overwritten.
+ */
+void add_libgl_abi_symlink(Options *op, Package *p)
+{
+ static const char *usrlib = "/usr/lib/";
+ char *libgl = nvstrdup("libGL.so.1");
+ char *opengl_path = get_opengl_libdir(op);
+ char *opengl32_path = get_compat32_libdir(op);
+
+ if (!directory_equals(usrlib, opengl_path)
+#if defined (NV_X86_64)
+ && !directory_equals(usrlib, opengl32_path)
+#endif
+ ) {
+ char *target = nvstrcat(opengl_path, "libGL.so.1", NULL);
+ add_package_entry(p,
+ libgl,
+ NULL,
+ libgl,
+ target,
+ nvstrcat(usrlib, libgl, NULL),
+ FILE_TYPE_OPENGL_SYMLINK,
+ FILE_TLS_CLASS_NONE,
+ FILE_COMPAT_ARCH_NATIVE,
+ 0000);
+ } else {
+ nvfree(libgl);
+ }
+
+ nvfree(opengl_path);
+ nvfree(opengl32_path);
+}
diff --git a/files.h b/files.h
index 397c17c..1708926 100644
--- a/files.h
+++ b/files.h
@@ -38,10 +38,8 @@ int get_prefixes(Options *op); /* XXX move? */
int add_kernel_modules_to_package(Options *op, Package *p);
void remove_non_kernel_module_files_from_package(Options *op, Package *p);
void remove_opengl_files_from_package(Options *op, Package *p);
-void remove_trailing_slashes(char *s);
int mode_string_to_mode(Options *op, char *s, mode_t *mode);
char *mode_to_permission_string(mode_t mode);
-int directory_exists(Options *op, const char *dir);
int confirm_path(Options *op, const char *path);
int mkdir_recursive(Options *op, const char *path, const mode_t mode, int log);
int mkdir_with_log(Options *op, const char *path, const mode_t mode);
@@ -66,9 +64,12 @@ void process_libGL_la_files(Options *op, Package *p);
void process_dot_desktop_files(Options *op, Package *p);
int set_security_context(Options *op, const char *filename);
void get_default_prefixes_and_paths(Options *op);
+void get_compat32_path(Options *op);
char *nv_strreplace(char *src, char *orig, char *replace);
char *get_filename(Options *op, const char *def, const char *msg);
int secure_delete(Options *op, const char *file);
void invalidate_package_entry(PackageEntry *entry);
+int is_subdirectory(const char *dir, const char *subdir, int *is_subdir);
+void add_libgl_abi_symlink(Options *op, Package *p);
#endif /* __NVIDIA_INSTALLER_FILES_H__ */
diff --git a/install-from-cwd.c b/install-from-cwd.c
index 523cb57..64fc6d4 100644
--- a/install-from-cwd.c
+++ b/install-from-cwd.c
@@ -76,12 +76,11 @@ int install_from_cwd(Options *op)
{
Package *p;
CommandList *c;
- const char *msg;
int ret;
int ran_pre_install_hook = FALSE;
HookScriptStatus res;
- static const char edit_your_xf86config[] =
+ static const char* edit_your_xf86config =
"Please update your XF86Config or xorg.conf file as "
"appropriate; see the file /usr/share/doc/"
"NVIDIA_GLX-1.0/README.txt for details.";
@@ -93,6 +92,10 @@ int install_from_cwd(Options *op)
if ((p = parse_manifest(op)) == NULL) goto failed;
+ if (!op->x_files_packaged) {
+ edit_your_xf86config = "";
+ }
+
ui_set_title(op, "%s (%s)", p->description, p->version);
/*
@@ -248,6 +251,15 @@ int install_from_cwd(Options *op)
*/
if (!set_destinations(op, p)) goto failed;
+
+ /*
+ * if we are installing OpenGL libraries, ensure that a symlink gets
+ * installed to /usr/lib/libGL.so.1. add_libgl_abi_symlink() sets its own
+ * destination, so it must be called after set_destinations().
+ */
+ if (!op->kernel_module_only && !op->no_opengl_files) {
+ add_libgl_abi_symlink(op, p);
+ }
/*
* uninstall the existing driver; this needs to be done before
@@ -296,6 +308,23 @@ int install_from_cwd(Options *op)
if (op->dkms && !dkms_install_module(op, p->version, get_kernel_name(op)))
goto failed;
+ /* Make sure the RM is loaded */
+
+ if (!op->no_kernel_module || op->dkms) {
+ /*
+ * If a kernel module was installed the normal way, it should have been
+ * left loaded by test_kernel_module(). However, older versions of
+ * nvidia-uninstall don't honor the --skip-module-unload option, so
+ * uninstalling a previous driver may have unloaded the module that
+ * test_kernel_module() loaded. Just in case that happened, modprobe it
+ * again here.
+ *
+ * When installing the module via DKMS, the module is not loaded to
+ * begin with.
+ */
+ if (!load_kernel_module(op, p)) goto failed;
+ }
+
/* run the distro postinstall script */
run_distro_hook(op, "post-install");
@@ -307,7 +336,6 @@ 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 */
@@ -321,28 +349,22 @@ int install_from_cwd(Options *op)
/* ask the user if they would like to run nvidia-xconfig */
- ret = ui_yes_no(op, op->run_nvidia_xconfig,
- "Would you like to run the nvidia-xconfig utility "
- "to automatically update your X configuration file "
- "so that the NVIDIA X driver will be used when you "
- "restart X? Any pre-existing X configuration "
- "file will be backed up.");
+ const char *msg = "Would you like to run the nvidia-xconfig utility "
+ "to automatically update your X configuration file "
+ "so that the NVIDIA X driver will be used when you "
+ "restart X? Any pre-existing X configuration "
+ "file will be backed up.";
- if (ret) {
- ret = run_nvidia_xconfig(op, FALSE);
- }
+ ret = run_nvidia_xconfig(op, FALSE, msg, op->run_nvidia_xconfig);
if (ret) {
ui_message(op, "Your X configuration file has been successfully "
"updated. Installation of the %s (version: %s) is now "
"complete.", p->description, p->version);
} else {
-
- msg = edit_your_xf86config;
-
ui_message(op, "Installation of the %s (version: %s) is now "
"complete. %s", p->description,
- p->version, msg);
+ p->version, edit_your_xf86config);
}
}
@@ -453,7 +475,7 @@ dkmscatfailed:
* will be installed somewhere. Don't offer DKMS as an option if module
* signing was requested. */
- if (find_system_util("dkms") && !op->no_kernel_module_source &&
+ if (op->utils[DKMS] && !op->no_kernel_module_source &&
!(op->module_signing_secret_key && op->module_signing_public_key)) {
op->dkms = ui_yes_no(op, op->dkms,
"Would you like to register the kernel module "
@@ -492,14 +514,15 @@ dkmscatfailed:
if ((precompiled_info = find_precompiled_kernel_interface(op, p))) {
- int i;
+ int i, precompiled_success = TRUE;
/*
* make sure the required development tools are present on
* this system before trying to link the kernel interface.
*/
if (!check_precompiled_kernel_interface_tools(op)) {
- return FALSE;
+ precompiled_success = FALSE;
+ goto precompiled_done;
}
/*
@@ -515,10 +538,15 @@ dkmscatfailed:
for (i = 0; i < precompiled_info->num_files; i++) {
if (!link_kernel_module(op, p, p->kernel_module_build_directory,
&(precompiled_info->files[i]))) {
- return FALSE;
+ precompiled_success = FALSE;
+ goto precompiled_done;
}
}
-
+precompiled_done:
+ free_precompiled(precompiled_info);
+ if (!precompiled_success) {
+ return FALSE;
+ }
} else {
/*
* make sure the required development tools are present on
@@ -624,6 +652,49 @@ int add_this_kernel(Options *op)
+static void add_conflicting_file(Package *p, int *index, const char *file)
+{
+ char *c;
+
+ p->conflicting_files = nvrealloc(p->conflicting_files,
+ sizeof(ConflictingFileInfo) * (*index+1));
+
+ p->conflicting_files[*index].name = file;
+
+ if (file == NULL) {
+ /* Adding a terminator to the list. Pretend that the name is
+ * actually an empty string to avoid crashing later. */
+ file = "";
+ }
+
+ /*
+ * match the names of DSOs with "libfoo.so*" by stopping any comparisons
+ * after ".so".
+ */
+
+ c = strstr(file, ".so.");
+ if (c) {
+ p->conflicting_files[*index].len = (c - file) + 3;
+ } else {
+ p->conflicting_files[*index].len = strlen(file);
+ }
+
+ /*
+ * XXX avoid conflicting with libglx.so if it doesn't include the string
+ * "glxModuleData" to avoid removing the wrong libglx.so (bug 489316)
+ */
+
+ if (strncmp(file, "libglx.so", p->conflicting_files[*index].len) == 0) {
+ p->conflicting_files[*index].requiredString = "glxModuleData";
+ } else {
+ p->conflicting_files[*index].requiredString = NULL;
+ }
+
+ (*index)++;
+}
+
+
+
/*
* parse_manifest() - open and read the .manifest file in the current
* directory.
@@ -656,13 +727,14 @@ int add_this_kernel(Options *op)
static Package *parse_manifest (Options *op)
{
- char *buf, *c, *flag, *tmpstr, *module_suffix = "";
- int done, n, line;
+ char *buf, *c, *tmpstr, *module_suffix = "", *interface_suffix = "";
+ int n, line;
int fd, ret, len = 0;
struct stat stat_buf;
Package *p;
char *manifest = MAP_FAILED, *ptr;
int opengl_files_packaged = FALSE;
+ int num_conflicting_files = 0;
p = (Package *) nvalloc(sizeof (Package));
@@ -707,21 +779,22 @@ static Package *parse_manifest (Options *op)
if (op->multiple_kernel_modules) {
module_suffix = "0";
+ interface_suffix = "-0";
}
p->kernel_module_name = nvstrcat(tmpstr, module_suffix, NULL);
p->kernel_module_filename = nvstrcat(p->kernel_module_name, ".ko", NULL);
- p->kernel_interface_filename = nvstrcat("nv-linux", module_suffix, ".o", NULL);
+ p->kernel_interface_filename = nvstrcat("nv-linux", interface_suffix, ".o", NULL);
p->kernel_frontend_module_name = nvstrcat(tmpstr, "-frontend", NULL);
p->kernel_frontend_module_filename = nvstrcat(p->kernel_frontend_module_name,
".ko", NULL);
- p->kernel_frontend_interface_filename = "nv-linuxfrontend.o";
+ p->kernel_frontend_interface_filename = "nv-linux-frontend.o";
p->uvm_kernel_module_name = nvstrcat(tmpstr, "-uvm", NULL);
p->uvm_kernel_module_filename = nvstrcat(p->uvm_kernel_module_name, ".ko",
NULL);
- p->uvm_interface_filename = "nv-linuxuvm.o";
+ p->uvm_interface_filename = "nv-linux-uvm.o";
nvfree(tmpstr);
@@ -790,166 +863,195 @@ static Package *parse_manifest (Options *op)
/* the rest of the file is file entries */
- done = FALSE;
line++;
- do {
- buf = get_next_line(ptr, &ptr, manifest, len);
- if (!buf) {
- done = TRUE;
- } else if (buf[0] == '\0') {
+ for (; (buf = get_next_line(ptr, &ptr, manifest, len)); line++) {
+ char *flag = NULL;
+ PackageEntry entry;
+ int entry_success = FALSE;
+
+ if (buf[0] == '\0') {
free(buf);
- done = TRUE;
- } else {
- PackageEntry entry;
-
- /* initialize the new entry */
+ break;
+ }
- memset(&entry, 0, sizeof(PackageEntry));
+ /* initialize the new entry */
- /* read the file name and permissions */
+ memset(&entry, 0, sizeof(PackageEntry));
- c = buf;
+ /* read the file name and permissions */
- entry.file = read_next_word(buf, &c);
+ c = buf;
- if (!entry.file) goto invalid_manifest_file;
+ entry.file = read_next_word(buf, &c);
- tmpstr = read_next_word(c, &c);
-
- if (!tmpstr) goto invalid_manifest_file;
-
- /* translate the mode string into an octal mode */
-
- ret = mode_string_to_mode(op, tmpstr, &entry.mode);
+ if (!entry.file) goto entry_done;
- free(tmpstr);
+ tmpstr = read_next_word(c, &c);
- if (!ret) goto invalid_manifest_file;
-
- /* every file has a type field */
+ if (!tmpstr) goto entry_done;
- entry.type = FILE_TYPE_NONE;
+ /* translate the mode string into an octal mode */
- flag = read_next_word(c, &c);
- if (!flag) goto invalid_manifest_file;
+ ret = mode_string_to_mode(op, tmpstr, &entry.mode);
- entry.type = parse_manifest_file_type(flag, &entry.caps);
+ free(tmpstr);
- if (entry.type == FILE_TYPE_NONE) {
- nvfree(flag);
- goto invalid_manifest_file;
- }
+ if (!ret) goto entry_done;
+
+ /* every file has a type field */
- /* if any UVM files have been packaged, set uvm_files_packaged. */
+ entry.type = FILE_TYPE_NONE;
- if (entry.type == FILE_TYPE_UVM_MODULE_SRC) {
+ flag = read_next_word(c, &c);
+ if (!flag) goto entry_done;
+
+ entry.type = parse_manifest_file_type(flag, &entry.caps);
+
+ if (entry.type == FILE_TYPE_NONE) {
+ goto entry_done;
+ }
+
+ /* Track whether certain file types were packaged */
+
+ switch (entry.type) {
+ case FILE_TYPE_UVM_MODULE_SRC:
op->uvm_files_packaged = TRUE;
- }
+ break;
+ case FILE_TYPE_XMODULE_SHARED_LIB:
+ op->x_files_packaged = TRUE;
+ break;
+ default: break;
+ }
- /* set opengl_files_packaged if any OpenGL files were packaged */
+ /* set opengl_files_packaged if any OpenGL files were packaged */
- if (entry.caps.is_opengl) {
- opengl_files_packaged = TRUE;
- }
+ if (entry.caps.is_opengl) {
+ opengl_files_packaged = TRUE;
+ }
+
+ /* some libs/symlinks have an arch field */
+
+ entry.compat_arch = FILE_COMPAT_ARCH_NONE;
+ if (entry.caps.has_arch) {
nvfree(flag);
+ flag = read_next_word(c, &c);
+ if (!flag) goto entry_done;
+
+ if (strcmp(flag, "COMPAT32") == 0)
+ entry.compat_arch = FILE_COMPAT_ARCH_COMPAT32;
+ else if (strcmp(flag, "NATIVE") == 0)
+ entry.compat_arch = FILE_COMPAT_ARCH_NATIVE;
+ else {
+ goto entry_done;
+ }
+ }
- /* some libs/symlinks have an arch field */
+ /* if compat32 files are packaged, set compat32_files_packaged */
- entry.compat_arch = FILE_COMPAT_ARCH_NONE;
+ if (entry.compat_arch == FILE_COMPAT_ARCH_COMPAT32) {
+ op->compat32_files_packaged = TRUE;
+ }
- if (entry.caps.has_arch) {
- flag = read_next_word(c, &c);
- if (!flag) goto invalid_manifest_file;
+ /* some libs/symlinks have a class field */
- if (strcmp(flag, "COMPAT32") == 0)
- entry.compat_arch = FILE_COMPAT_ARCH_COMPAT32;
- else if (strcmp(flag, "NATIVE") == 0)
- entry.compat_arch = FILE_COMPAT_ARCH_NATIVE;
- else {
- nvfree(flag);
- goto invalid_manifest_file;
- }
+ entry.tls_class = FILE_TLS_CLASS_NONE;
- nvfree(flag);
+ if (entry.caps.has_tls_class) {
+ nvfree(flag);
+ flag = read_next_word(c, &c);
+ if (!flag) goto entry_done;
+
+ if (strcmp(flag, "CLASSIC") == 0)
+ entry.tls_class = FILE_TLS_CLASS_CLASSIC;
+ else if (strcmp(flag, "NEW") == 0)
+ entry.tls_class = FILE_TLS_CLASS_NEW;
+ else {
+ goto entry_done;
}
+ }
- /* some libs/symlinks have a class field */
+ /* libs and documentation have a path field */
- entry.tls_class = FILE_TLS_CLASS_NONE;
+ if (entry.caps.has_path) {
+ entry.path = read_next_word(c, &c);
+ if (!entry.path) goto invalid_manifest_file;
+ } else {
+ entry.path = NULL;
+ }
- if (entry.caps.has_tls_class) {
- flag = read_next_word(c, &c);
- if (!flag) goto invalid_manifest_file;
+ /* symlinks have a target */
- if (strcmp(flag, "CLASSIC") == 0)
- entry.tls_class = FILE_TLS_CLASS_CLASSIC;
- else if (strcmp(flag, "NEW") == 0)
- entry.tls_class = FILE_TLS_CLASS_NEW;
- else {
- nvfree(flag);
- goto invalid_manifest_file;
- }
+ if (entry.caps.is_symlink) {
+ entry.target = read_next_word(c, &c);
+ if (!entry.target) goto invalid_manifest_file;
+ } else {
+ entry.target = NULL;
+ }
- nvfree(flag);
- }
+ /*
+ * as a convenience for later, set the 'name' pointer to
+ * the basename contained in 'file' (ie the portion of
+ * 'file' without any leading directory components
+ */
- /* libs and documentation have a path field */
+ entry.name = strrchr(entry.file, '/');
+ if (entry.name) entry.name++;
- if (entry.caps.has_path) {
- entry.path = read_next_word(c, &c);
- if (!entry.path) goto invalid_manifest_file;
- } else {
- entry.path = NULL;
- }
-
- /* symlinks have a target */
+ if (!entry.name) entry.name = entry.file;
- if (entry.caps.is_symlink) {
- entry.target = read_next_word(c, &c);
- if (!entry.target) goto invalid_manifest_file;
- } else {
- entry.target = NULL;
- }
+ add_package_entry(p,
+ entry.file,
+ entry.path,
+ entry.name,
+ entry.target,
+ entry.dst,
+ entry.type,
+ entry.tls_class,
+ entry.compat_arch,
+ entry.mode);
+
+
+ /* Conflict with any non-wrapper shared libs. Don't conflict with
+ * OpenGL files if we won't be installing any. */
+ if (entry.caps.is_shared_lib && !entry.caps.is_wrapper &&
+ (!entry.caps.is_opengl || !op->no_opengl_files)) {
+ add_conflicting_file(p, &num_conflicting_files, entry.name);
+ }
- /*
- * as a convenience for later, set the 'name' pointer to
- * the basename contained in 'file' (ie the portion of
- * 'file' without any leading directory components
- */
+ entry_success = TRUE;
- entry.name = strrchr(entry.file, '/');
- if (entry.name) entry.name++;
-
- if (!entry.name) entry.name = entry.file;
+ entry_done:
+ /* clean up */
- add_package_entry(p,
- entry.file,
- entry.path,
- entry.name,
- entry.target,
- entry.dst,
- entry.type,
- entry.tls_class,
- entry.compat_arch,
- entry.mode);
-
- /* free the line */
-
- free(buf);
+ nvfree(buf);
+ nvfree(flag);
+ if (!entry_success) {
+ goto invalid_manifest_file;
}
-
- line++;
+ }
- } while (!done);
+ /* If no OpenGL files were packaged, we can't install them. Set the
+ * no_opengl_files flag so that everything we skip when explicitly
+ * excluding OpenGL is also skipped when OpenGL is not packaged. */
- /* If the package does not contain any OpenGL files, do not install
- * OpenGL files */
if (!opengl_files_packaged) {
op->no_opengl_files = TRUE;
}
+ /* XXX always conflict with these files if OpenGL files will be installed
+ * libglamoregl.so: prevent X from loading libGL and libglx simultaneously
+ * (bug 1299091)
+ * libGLwrapper.so: this library has an SONAME of libGL.so.1 (bug 74761) */
+ if (!op->no_opengl_files) {
+ add_conflicting_file(p, &num_conflicting_files, "libglamoregl.so");
+ add_conflicting_file(p, &num_conflicting_files, "libGLwrapper.so");
+ }
+
+ /* terminate the conflicting files list */
+ add_conflicting_file(p, &num_conflicting_files, NULL);
+
munmap(manifest, len);
if (fd != -1) close(fd);
@@ -1327,13 +1429,13 @@ generate_done:
if (op->multiple_kernel_modules) {
if (!sign_kernel_module(op, p->kernel_module_build_directory,
- "frontend", TRUE)) {
+ "-frontend", TRUE)) {
return FALSE;
}
}
if (op->install_uvm) {
- if (!sign_kernel_module(op, p->uvm_module_build_directory, "uvm",
+ if (!sign_kernel_module(op, p->uvm_module_build_directory, "-uvm",
TRUE)) {
return FALSE;
}
@@ -1391,7 +1493,7 @@ generate_done:
} else {
/* Remove any ':' characters from fingerprint and truncate */
char *tmp = nv_strreplace(fingerprint, ":", "");
- strncpy(short_fingerprint, tmp, sizeof(fingerprint));
+ strncpy(short_fingerprint, tmp, sizeof(short_fingerprint));
nvfree(tmp);
}
short_fingerprint[sizeof(short_fingerprint) - 1] = '\0';
diff --git a/kernel.c b/kernel.c
index 4819489..1f576ea 100644
--- a/kernel.c
+++ b/kernel.c
@@ -220,7 +220,7 @@ int determine_kernel_source_path(Options *op, Package *p)
result = ui_get_input(op, op->kernel_source_path,
"Kernel source path");
if (result && result[0]) {
- if (!directory_exists(op, result)) {
+ if (!directory_exists(result)) {
ui_warn(op, "Kernel source path '%s' does not exist.",
result);
free(result);
@@ -272,7 +272,7 @@ int determine_kernel_source_path(Options *op, Package *p)
/* check that the kernel source path exists */
- if (!directory_exists(op, op->kernel_source_path)) {
+ if (!directory_exists(op->kernel_source_path)) {
ui_error (op, "The kernel source path '%s' does not exist. %s",
op->kernel_source_path, install_your_kernel_source);
op->kernel_source_path = NULL;
@@ -364,7 +364,7 @@ int determine_kernel_output_path(Options *op)
"'--kernel-output-path' commandline option.",
op->kernel_output_path);
- if (!directory_exists(op, op->kernel_output_path)) {
+ if (!directory_exists(op->kernel_output_path)) {
ui_error(op, "The kernel output path '%s' does not exist.",
op->kernel_output_path);
op->kernel_output_path = NULL;
@@ -382,7 +382,7 @@ int determine_kernel_output_path(Options *op)
"SYSOUT environment variable.", str);
op->kernel_output_path = str;
- if (!directory_exists(op, op->kernel_output_path)) {
+ if (!directory_exists(op->kernel_output_path)) {
ui_error(op, "The kernel output path '%s' does not exist.",
op->kernel_output_path);
op->kernel_output_path = NULL;
@@ -404,7 +404,7 @@ int determine_kernel_output_path(Options *op)
nvfree(str);
str = nvstrcat("/lib/modules/", tmp, "/build", NULL);
- if (directory_exists(op, str)) {
+ if (directory_exists(str)) {
op->kernel_output_path = str;
return TRUE;
}
@@ -450,13 +450,9 @@ static int attach_signature(Options *op, Package *p,
if (module_file && fileInfo->signature_size) {
command_ret = fwrite(fileInfo->signature, 1,
fileInfo->signature_size, module_file);
- if (command_ret != fileInfo->signature_size) {
- goto attach_done;
+ if (command_ret == fileInfo->signature_size) {
+ op->kernel_module_signed = ret = !ferror(module_file);
}
-
- op->kernel_module_signed = ret = !ferror(module_file);
-attach_done:
- fclose(module_file);
} else {
ret = (ui_multiple_choice(op, choices, 2, 1,
"A detached signature was included with "
@@ -467,6 +463,10 @@ attach_done:
"still like to install the unsigned "
"kernel module?") == 0);
}
+
+ if (module_file) {
+ fclose(module_file);
+ }
} else {
ret = (ui_multiple_choice(op, choices, 2, 1,
"A detached signature was included with the "
@@ -578,22 +578,25 @@ static int build_kernel_module_helper(Options *op, const char *dir,
const char *module, int num_instances)
{
int ret;
- char *instances = NULL, *cmd, *tmp;
+ char *instances = NULL, *cmd, *tmp, *concurrency;
tmp = op->multiple_kernel_modules && num_instances ?
nvasprintf("%d", num_instances) : NULL;
instances = nvstrcat(" NV_BUILD_MODULE_INSTANCES=", tmp, NULL);
nvfree(tmp);
+ concurrency = nvasprintf(" -j%d ", op->concurrency_level);
+
tmp = nvasprintf("Building %s kernel module:", module);
ui_status_begin(op, tmp, "Building");
nvfree(tmp);
cmd = nvstrcat("cd ", dir, "; ", op->utils[MAKE], " module",
" SYSSRC=", op->kernel_source_path,
- " SYSOUT=", op->kernel_output_path,
+ " SYSOUT=", op->kernel_output_path, concurrency,
instances, NULL);
nvfree(instances);
+ nvfree(concurrency);
ret = run_command(op, cmd, NULL, TRUE, 25, TRUE);
@@ -736,7 +739,7 @@ int sign_kernel_module(Options *op, const char *build_directory,
const char *module_suffix, int status) {
char *cmd, *mod_sign_cmd, *mod_sign_hash;
int ret, success;
- char *build_module_instances_parameter;
+ char *build_module_instances_parameter, *concurrency;
/* if module_signing_script isn't set, then set mod_sign_cmd below to end
* the nvstrcat() that builds cmd early. */
@@ -762,15 +765,17 @@ int sign_kernel_module(Options *op, const char *build_directory,
build_module_instances_parameter = nvstrdup("");
}
+ concurrency = nvasprintf(" -j%d ", op->concurrency_level);
cmd = nvstrcat("cd ", build_directory, "; ", op->utils[MAKE], " module-sign"
" SYSSRC=", op->kernel_source_path,
" SYSOUT=", op->kernel_output_path,
" MODSECKEY=", op->module_signing_secret_key,
" MODPUBKEY=", op->module_signing_public_key,
- " NV_MODULE_SUFFIX=", module_suffix,
+ " BUILD_MODULES_LIST=\"nvidia", module_suffix, "\" ",
build_module_instances_parameter,
mod_sign_cmd ? mod_sign_cmd : "",
- mod_sign_hash ? mod_sign_hash : "", NULL);
+ mod_sign_hash ? mod_sign_hash : "", concurrency, NULL);
+ nvfree(concurrency);
ret = run_command(op, cmd, NULL, TRUE, 20 /* XXX */, TRUE);
success = ret == 0;
@@ -878,11 +883,11 @@ done:
static int build_kernel_interface_file(Options *op, const char *tmpdir,
PrecompiledFileInfo *fileInfo,
- const char *kernel_interface_filename,
- const char *module_suffix)
+ const char *kernel_interface_filename)
{
char *cmd;
char *kernel_interface, *build_module_instances_parameter = NULL;
+ char *concurrency;
int ret;
if (op->multiple_kernel_modules) {
@@ -890,14 +895,16 @@ static int build_kernel_interface_file(Options *op, const char *tmpdir,
nvasprintf(" NV_BUILD_MODULE_INSTANCES=%d", NV_MAX_MODULE_INSTANCES);
}
+ concurrency = nvasprintf(" -j%d ", op->concurrency_level);
+
cmd = nvstrcat("cd ", tmpdir, "; ", op->utils[MAKE], " ",
kernel_interface_filename,
" SYSSRC=", op->kernel_source_path,
- " SYSOUT=", op->kernel_output_path,
- " NV_MODULE_SUFFIX=", module_suffix,
+ " SYSOUT=", op->kernel_output_path, concurrency,
build_module_instances_parameter, NULL);
nvfree(build_module_instances_parameter);
+ nvfree(concurrency);
ret = run_command(op, cmd, NULL, TRUE, 25 /* XXX */, TRUE);
@@ -978,7 +985,7 @@ static int build_and_pack_interface(Options *op, Package *p, const char *tmpdir,
interface);
dir = nvstrcat(tmpdir, "/", subdir, NULL);
- ret = build_kernel_interface_file(op, dir, fileInfo, interface, suffix);
+ ret = build_kernel_interface_file(op, dir, fileInfo, interface);
if (!ret) {
goto done;
@@ -1020,7 +1027,6 @@ int build_kernel_interface(Options *op, Package *p,
PrecompiledFileInfo ** fileInfos)
{
char *tmpdir = NULL;
- char *dstfile = NULL;
int files_packaged = 0, i;
int num_files = 1, ret = FALSE;
char *uvmdir = NULL;
@@ -1119,7 +1125,7 @@ interface_done:
ret = build_and_pack_interface(op, p, tmpdir, "", *fileInfos + num_files,
p->kernel_frontend_interface_filename,
p->kernel_frontend_module_filename,
- "frontend", "");
+ "-frontend", "");
if (!ret) {
goto failed;
}
@@ -1131,7 +1137,7 @@ interface_done:
ret = build_and_pack_interface(op, p, tmpdir, UVM_SUBDIR,
*fileInfos + files_packaged,
p->uvm_interface_filename,
- p->uvm_kernel_module_filename, "uvm", "");
+ p->uvm_kernel_module_filename, "-uvm", "");
if (!ret) {
goto failed;
@@ -1153,8 +1159,6 @@ failed:
nvfree(tmpdir);
}
- if (dstfile) nvfree(dstfile);
-
return files_packaged;
} /* build_kernel_interface() */
@@ -1449,8 +1453,8 @@ static int ignore_load_error(Options *op, Package *p,
/*
- * test_kernel_module() - attempt to insmod the kernel module and then
- * rmmod it. Return TRUE if the insmod succeeded, or FALSE otherwise.
+ * test_kernel_module() - attempt to insmod the kernel modules and then rmmod
+ * nvidia-uvm. Return TRUE if the insmod succeeded, or FALSE otherwise.
*/
int test_kernel_module(Options *op, Package *p)
@@ -1559,9 +1563,14 @@ int test_kernel_module(Options *op, Package *p)
check_for_warning_messages(op);
/*
- * 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).
+ * attempt to unload the UVM kernel module, but don't abort if this fails:
+ * the kernel may not have been configured with support for module unloading
+ * (Linux 2.6).
+ *
+ * The nvidia module is left loaded in case an X server with
+ * OutputClass-based driver matching is being used. UVM is unloaded to make
+ * it easier to roll back to older versions of the driver whose installers
+ * didn't know how to unload the nvidia-uvm module.
*/
if (op->install_uvm) {
@@ -1570,17 +1579,6 @@ int test_kernel_module(Options *op, Package *p)
nvfree(cmd);
}
- cmd = nvstrcat(op->utils[RMMOD], " ", p->kernel_module_name, NULL);
- run_command(op, cmd, NULL, FALSE, 0, TRUE);
- nvfree(cmd);
-
- if (op->multiple_kernel_modules) {
- cmd = nvstrcat(op->utils[RMMOD], " ",
- p->kernel_frontend_module_name, NULL);
- run_command(op, cmd, NULL, FALSE, 0, TRUE);
- nvfree(cmd);
- }
-
ret = TRUE;
test_exit:
@@ -1811,12 +1809,12 @@ PrecompiledInfo *find_precompiled_kernel_interface(Options *op, Package *p)
proc_version_string = read_proc_version(op, op->proc_mount_point);
- if (!proc_version_string) goto failed;
+ if (!proc_version_string) goto done;
/* make sure the target directory exists */
if (!mkdir_recursive(op, p->kernel_module_build_directory, 0755, FALSE))
- goto failed;
+ goto done;
memset(search_filelist, 0, sizeof(search_filelist));
@@ -1883,7 +1881,7 @@ PrecompiledInfo *find_precompiled_kernel_interface(Options *op, Package *p)
"to compile a kernel interface for your kernel.",
op->precompiled_kernel_interfaces_url);
free_search_filelist(search_filelist);
- return NULL;
+ goto done;
}
}
@@ -1907,21 +1905,18 @@ PrecompiledInfo *find_precompiled_kernel_interface(Options *op, Package *p)
}
}
- if (info) {
- return info;
- }
+ done:
- failed:
+ nvfree(proc_version_string);
- if (op->expert) {
+ if (!info && op->expert) {
ui_message(op, "No precompiled kernel interface was found to match "
"your kernel; this means that the installer will need to "
"compile a new kernel interface.");
}
- return NULL;
-
-} /* find_precompiled_kernel_interface() */
+ return info;
+}
@@ -2022,7 +2017,7 @@ static char *default_kernel_module_installation_path(Options *op)
str = nvstrcat("/lib/modules/", tmp, "/kernel", NULL);
- if (directory_exists(op, str)) {
+ if (directory_exists(str)) {
free(str);
str = nvstrcat("/lib/modules/", tmp, "/kernel/drivers/video", NULL);
return str;
@@ -2114,7 +2109,7 @@ static char *default_kernel_source_path(Options *op)
if (tmp) {
str = nvstrcat("/lib/modules/", tmp, "/source", NULL);
- if (directory_exists(op, str)) {
+ if (directory_exists(str)) {
return str;
}
@@ -2122,7 +2117,7 @@ static char *default_kernel_source_path(Options *op)
str = nvstrcat("/lib/modules/", tmp, "/build", NULL);
- if (directory_exists(op, str)) {
+ if (directory_exists(str)) {
return str;
}
@@ -2134,7 +2129,7 @@ static char *default_kernel_source_path(Options *op)
*/
str = nvstrcat("/usr/src/linux-", tmp, NULL);
- if (directory_exists(op, str)) {
+ if (directory_exists(str)) {
return str;
}
@@ -2143,7 +2138,7 @@ static char *default_kernel_source_path(Options *op)
/* finally, try /usr/src/linux */
- if (directory_exists(op, "/usr/src/linux")) {
+ if (directory_exists("/usr/src/linux")) {
return "/usr/src/linux";
}
@@ -2294,12 +2289,12 @@ download_updated_kernel_interface(Options *op, Package *p,
{
int fd = -1;
int dst_fd = -1;
- int length, i;
+ int length = 0, i;
char *url = NULL;
char *tmpfile = NULL;
char *dstfile = NULL;
char *buf = NULL;
- char *str = (void *) -1;
+ char *str = MAP_FAILED;
char *ptr, *s;
struct stat stat_buf;
PrecompiledInfo *info = NULL;
@@ -2334,7 +2329,7 @@ download_updated_kernel_interface(Options *op, Package *p,
/* map the file into memory for easier reading */
str = mmap(0, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
- if (str == (void *) -1) goto done;
+ if (str == MAP_FAILED) goto done;
/*
* loop over each line of the updates file: each line should be of
@@ -2431,19 +2426,18 @@ download_updated_kernel_interface(Options *op, Package *p,
done:
- if (dstfile) nvfree(dstfile);
- if (buf) nvfree(buf);
- if (str != (void *) -1) munmap(str, stat_buf.st_size);
+ nvfree(dstfile);
+ nvfree(buf);
+ if (str != MAP_FAILED) munmap(str, length);
if (dst_fd > 0) close(dst_fd);
if (fd > 0) close(fd);
unlink(tmpfile);
- if (tmpfile) nvfree(tmpfile);
- if (url) nvfree(url);
+ nvfree(tmpfile);
+ nvfree(url);
return info;
-
-} /* get_updated_kernel_interfaces() */
+}
diff --git a/manifest.c b/manifest.c
index 45c8dec..d1f0e6e 100644
--- a/manifest.c
+++ b/manifest.c
@@ -32,7 +32,8 @@
_is_symlink, \
_is_shared_lib, \
_is_opengl, \
- _is_temporary) \
+ _is_temporary, \
+ _is_wrapper) \
#_name , FILE_TYPE_ ## _name , \
{ \
.has_arch = _has_arch, \
@@ -43,6 +44,7 @@
.is_shared_lib = _is_shared_lib, \
.is_opengl = _is_opengl, \
.is_temporary = _is_temporary, \
+ .is_wrapper = _is_wrapper, \
}
/*
@@ -56,62 +58,65 @@ static const struct {
} packageEntryFileTypeTable[] = {
/*
- * is_temporary ------------------------------------+
- * is_opengl ---------------------------------+ |
- * is_shared_lib ------------------------------+ | |
- * is_symlink ---------------------------+ | | |
- * has_path ------------------------+ | | | |
- * installable ---------------------+ | | | | |
- * has_tls_class ------------------+ | | | | | |
- * has_arch ---------------+ | | | | | | |
- * | | | | | | | |
+ * is_wrapper ---------------------------------------+
+ * is_temporary ------------------------------------+ |
+ * is_opengl ---------------------------------+ | |
+ * is_shared_lib ------------------------------+ | | |
+ * is_symlink ---------------------------+ | | | |
+ * has_path ------------------------+ | | | | |
+ * installable ---------------------+ | | | | | |
+ * has_tls_class ------------------+ | | | | | | |
+ * has_arch ---------------+ | | | | | | | |
+ * | | | | | | | | |
*/
- { ENTRY(KERNEL_MODULE_SRC, F, F, T, F, F, F, F, F ) },
- { ENTRY(KERNEL_MODULE_CMD, F, F, F, F, F, F, F, F ) },
- { ENTRY(KERNEL_MODULE, F, F, T, F, F, F, F, F ) },
- { ENTRY(OPENGL_HEADER, F, F, T, T, F, F, T, F ) },
- { ENTRY(CUDA_ICD, F, F, T, F, F, F, F, F ) },
- { ENTRY(OPENGL_LIB, T, F, T, F, F, T, T, F ) },
- { ENTRY(CUDA_LIB, T, F, T, T, F, T, F, F ) },
- { ENTRY(LIBGL_LA, T, F, T, F, F, F, T, T ) },
- { ENTRY(XLIB_STATIC_LIB, F, F, T, F, F, F, F, F ) },
- { ENTRY(XLIB_SHARED_LIB, F, F, T, F, F, T, F, F ) },
- { ENTRY(TLS_LIB, T, T, T, T, F, T, T, F ) },
- { ENTRY(UTILITY_LIB, T, F, T, F, F, T, F, F ) },
- { ENTRY(DOCUMENTATION, F, F, T, T, F, F, F, F ) },
- { ENTRY(APPLICATION_PROFILE, F, F, T, T, F, F, F, F ) },
- { ENTRY(MANPAGE, F, F, T, T, F, F, F, F ) },
- { ENTRY(EXPLICIT_PATH, F, F, T, T, F, F, F, F ) },
- { ENTRY(OPENGL_SYMLINK, T, F, F, F, T, F, T, F ) },
- { ENTRY(CUDA_SYMLINK, T, F, F, T, T, F, F, F ) },
- { ENTRY(XLIB_SYMLINK, F, F, F, F, T, F, F, F ) },
- { ENTRY(TLS_SYMLINK, T, T, F, T, T, F, T, F ) },
- { ENTRY(UTILITY_LIB_SYMLINK, T, F, F, F, T, F, F, F ) },
- { ENTRY(INSTALLER_BINARY, F, F, T, F, F, F, F, F ) },
- { ENTRY(UTILITY_BINARY, F, F, T, F, F, F, F, F ) },
- { ENTRY(UTILITY_BIN_SYMLINK, F, F, F, F, T, F, F, F ) },
- { ENTRY(DOT_DESKTOP, F, F, T, T, F, F, F, T ) },
- { ENTRY(XMODULE_SHARED_LIB, F, F, T, T, F, T, F, F ) },
- { ENTRY(XMODULE_SYMLINK, F, F, F, T, T, F, F, F ) },
- { ENTRY(GLX_MODULE_SHARED_LIB, F, F, T, T, F, T, T, F ) },
- { ENTRY(GLX_MODULE_SYMLINK, F, F, F, T, T, F, T, F ) },
- { ENTRY(XMODULE_NEWSYM, F, F, F, T, T, F, F, F ) },
- { ENTRY(VDPAU_LIB, T, F, T, T, F, T, F, F ) },
- { ENTRY(VDPAU_WRAPPER_LIB, T, F, T, T, F, T, F, F ) },
- { ENTRY(VDPAU_SYMLINK, T, F, F, T, T, F, F, F ) },
- { ENTRY(VDPAU_WRAPPER_SYMLINK, T, F, F, T, T, F, F, F ) },
- { ENTRY(NVCUVID_LIB, T, F, T, F, F, T, F, F ) },
- { ENTRY(NVCUVID_LIB_SYMLINK, T, F, F, F, T, F, F, F ) },
- { ENTRY(ENCODEAPI_LIB, T, F, T, F, F, T, F, F ) },
- { ENTRY(ENCODEAPI_LIB_SYMLINK, T, F, F, F, T, F, F, F ) },
- { ENTRY(VGX_LIB, F, F, T, F, F, T, F, F ) },
- { ENTRY(VGX_LIB_SYMLINK, F, F, F, F, T, F, F, F ) },
- { ENTRY(NVIDIA_MODPROBE, F, F, T, T, F, F, F, F ) },
- { ENTRY(NVIDIA_MODPROBE_MANPAGE,F, F, T, T, F, F, F, F ) },
- { ENTRY(MODULE_SIGNING_KEY, F, F, T, F, F, F, F, T ) },
- { ENTRY(NVIFR_LIB, T, F, T, F, F, T, F, F ) },
- { ENTRY(NVIFR_LIB_SYMLINK, T, F, F, F, T, F, F, F ) },
- { ENTRY(UVM_MODULE_SRC, F, F, T, F, F, F, F, F ) },
+ { ENTRY(KERNEL_MODULE_SRC, F, F, T, F, F, F, F, F, F) },
+ { ENTRY(KERNEL_MODULE_CMD, F, F, F, F, F, F, F, F, F) },
+ { ENTRY(KERNEL_MODULE, F, F, T, F, F, F, F, F, F) },
+ { ENTRY(OPENGL_HEADER, F, F, T, T, F, F, T, F, F) },
+ { ENTRY(CUDA_ICD, F, F, T, F, F, F, F, F, F) },
+ { ENTRY(OPENGL_LIB, T, F, T, F, F, T, T, F, F) },
+ { ENTRY(CUDA_LIB, T, F, T, T, F, T, F, F, F) },
+ { ENTRY(OPENCL_LIB, T, F, T, T, F, T, F, F, F) },
+ { ENTRY(OPENCL_WRAPPER_LIB, T, F, T, T, F, T, F, F, T) },
+ { ENTRY(OPENCL_LIB_SYMLINK, T, F, F, T, T, F, F, F, F) },
+ { ENTRY(OPENCL_WRAPPER_SYMLINK, T, F, F, T, T, F, F, F, T) },
+ { ENTRY(LIBGL_LA, T, F, T, F, F, F, T, T, F) },
+ { ENTRY(TLS_LIB, T, T, T, T, F, T, T, F, F) },
+ { ENTRY(UTILITY_LIB, T, F, T, F, F, T, F, F, F) },
+ { ENTRY(DOCUMENTATION, F, F, T, T, F, F, F, F, F) },
+ { ENTRY(APPLICATION_PROFILE, F, F, T, T, F, F, F, F, F) },
+ { ENTRY(MANPAGE, F, F, T, T, F, F, F, F, F) },
+ { ENTRY(EXPLICIT_PATH, F, F, T, T, F, F, F, F, F) },
+ { ENTRY(OPENGL_SYMLINK, T, F, F, F, T, F, T, F, F) },
+ { ENTRY(CUDA_SYMLINK, T, F, F, T, T, F, F, F, F) },
+ { ENTRY(TLS_SYMLINK, T, T, F, T, T, F, T, F, F) },
+ { ENTRY(UTILITY_LIB_SYMLINK, T, F, F, F, T, F, F, F, F) },
+ { ENTRY(INSTALLER_BINARY, F, F, T, F, F, F, F, F, F) },
+ { ENTRY(UTILITY_BINARY, F, F, T, F, F, F, F, F, F) },
+ { ENTRY(UTILITY_BIN_SYMLINK, F, F, F, F, T, F, F, F, F) },
+ { ENTRY(DOT_DESKTOP, F, F, T, T, F, F, F, T, F) },
+ { ENTRY(XMODULE_SHARED_LIB, F, F, T, T, F, T, F, F, F) },
+ { ENTRY(XMODULE_SYMLINK, F, F, F, T, T, F, F, F, F) },
+ { ENTRY(GLX_MODULE_SHARED_LIB, F, F, T, T, F, T, T, F, F) },
+ { ENTRY(GLX_MODULE_SYMLINK, F, F, F, T, T, F, T, F, F) },
+ { ENTRY(XMODULE_NEWSYM, F, F, F, T, T, F, F, F, F) },
+ { ENTRY(VDPAU_LIB, T, F, T, T, F, T, F, F, F) },
+ { ENTRY(VDPAU_WRAPPER_LIB, T, F, T, T, F, T, F, F, T) },
+ { ENTRY(VDPAU_SYMLINK, T, F, F, T, T, F, F, F, F) },
+ { ENTRY(VDPAU_WRAPPER_SYMLINK, T, F, F, T, T, F, F, F, T) },
+ { ENTRY(NVCUVID_LIB, T, F, T, F, F, T, F, F, F) },
+ { ENTRY(NVCUVID_LIB_SYMLINK, T, F, F, F, T, F, F, F, F) },
+ { ENTRY(ENCODEAPI_LIB, T, F, T, F, F, T, F, F, F) },
+ { ENTRY(ENCODEAPI_LIB_SYMLINK, T, F, F, F, T, F, F, F, F) },
+ { ENTRY(VGX_LIB, F, F, T, F, F, T, F, F, F) },
+ { ENTRY(VGX_LIB_SYMLINK, F, F, F, F, T, F, F, F, F) },
+ { ENTRY(NVIDIA_MODPROBE, F, F, T, T, F, F, F, F, F) },
+ { ENTRY(NVIDIA_MODPROBE_MANPAGE,F, F, T, T, F, F, F, F, F) },
+ { ENTRY(MODULE_SIGNING_KEY, F, F, T, F, F, F, F, T, F) },
+ { ENTRY(NVIFR_LIB, T, F, T, F, F, T, F, F, F) },
+ { ENTRY(NVIFR_LIB_SYMLINK, T, F, F, F, T, F, F, F, F) },
+ { ENTRY(UVM_MODULE_SRC, F, F, T, F, F, F, F, F, F) },
+ { ENTRY(XORG_OUTPUTCLASS_CONFIG,F, F, T, F, F, F, F, F, F) },
};
/*
@@ -123,7 +128,7 @@ PackageEntryFileCapabilities get_file_type_capabilities(
)
{
int i;
- PackageEntryFileCapabilities nullCaps = { F, F, F, F, F, F, F, F };
+ PackageEntryFileCapabilities nullCaps = { F, F, F, F, F, F, F, F, F };
for (i = 0; i < ARRAY_LEN(packageEntryFileTypeTable); i++) {
if (type == packageEntryFileTypeTable[i].type) {
@@ -192,6 +197,11 @@ void get_installable_file_type_list(
continue;
}
+ if ((type == FILE_TYPE_XORG_OUTPUTCLASS_CONFIG) &&
+ !op->xorg_supports_output_class) {
+ continue;
+ }
+
installable_file_types->types[type] = 1;
}
}
diff --git a/misc.c b/misc.c
index 849f1db..c54d975 100644
--- a/misc.c
+++ b/misc.c
@@ -127,16 +127,19 @@ int check_euid(Options *op)
int adjust_cwd(Options *op, const char *program_name)
{
- char *c, *path;
- int len;
-
+ char *c;
+ int success = TRUE;
+
/*
* extract any pathname portion out of the program_name and chdir
* to it
*/
-
+
c = strrchr(program_name, '/');
if (c) {
+ int len;
+ char *path;
+
len = c - program_name + 1;
path = (char *) nvalloc(len + 1);
strncpy(path, program_name, len);
@@ -145,14 +148,13 @@ int adjust_cwd(Options *op, const char *program_name)
if (chdir(path)) {
fprintf(stderr, "Unable to chdir to %s (%s)",
path, strerror(errno));
- return FALSE;
+ success = FALSE;
}
free(path);
}
-
- return TRUE;
-
-} /* adjust_cwd() */
+
+ return success;
+}
/*
@@ -292,13 +294,14 @@ int run_command(Options *op, const char *cmd, char **data, int output,
* command.
*/
- if ((stream = popen(cmd2, "r")) == NULL) {
+ stream = popen(cmd2, "r");
+ nvfree(cmd2);
+
+ if (stream == NULL) {
ui_error(op, "Failure executing command '%s' (%s).",
cmd, strerror(errno));
return errno;
}
-
- free(cmd2);
/*
* read from the stream, filling and growing buf, until we hit
@@ -459,6 +462,7 @@ static const Util __utils[] = {
[PKG_CONFIG] = { "pkg-config", "pkg-config" },
[XSERVER] = { "X", "xserver" },
[OPENSSL] = { "openssl", "openssl" },
+ [DKMS] = { "dkms", "dkms" },
/* ModuleUtils */
[INSMOD] = { "insmod", "module-init-tools' or 'kmod" },
@@ -592,6 +596,8 @@ int check_proc_modprobe_path(Options *op)
char *target = get_resolved_symlink_target(op, found_modprobe);
if (target && access(target, F_OK | X_OK) == 0) {
found_modprobe = target;
+ } else {
+ nvfree(target);
}
}
@@ -606,6 +612,8 @@ int check_proc_modprobe_path(Options *op)
if (target && access(target, F_OK | X_OK) == 0) {
nvfree(proc_modprobe);
proc_modprobe = target;
+ } else {
+ nvfree(target);
}
}
@@ -1115,54 +1123,35 @@ void should_install_opengl_headers(Options *op, Package *p)
void should_install_compat32_files(Options *op, Package *p)
{
#if defined(NV_X86_64)
- int i, have_compat32_files = FALSE, install_compat32_files;
- /*
- * 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].compat_arch == FILE_COMPAT_ARCH_COMPAT32) {
- have_compat32_files = TRUE;
- break;
- }
+ /* If there are no compat32 files, there is nothing to do */
+ if (!op->compat32_files_packaged) {
+ op->install_compat32_libs = NV_OPTIONAL_BOOL_FALSE;
+ return;
}
- if (!have_compat32_files)
- return;
+ /* Determine where the compatibility libraries should be installed */
+ get_compat32_path(op);
/*
- * Ask the user if the 32-bit compatibility libraries are
- * to be installed. If yes, check if the chosen prefix
- * exists. If not, notify the user and ask him/her if the
- * files are to be installed anyway.
+ * If the user hasn't explicitly specified whether to install compat32
+ * files, ask if the 32-bit compatibility libraries are to be installed.
+ * If yes, check if the chosen prefix exists. If not, notify the user and
+ * ask him/her if the files are to be installed anyway.
*/
- install_compat32_files = ui_yes_no(op, TRUE,
- "Install NVIDIA's 32-bit compatibility libraries?");
-
- if (install_compat32_files && (op->compat32_chroot != NULL) &&
- access(op->compat32_chroot, F_OK) < 0) {
+ if (op->install_compat32_libs == NV_OPTIONAL_BOOL_DEFAULT) {
+ int ret;
- const char *choices[2] = {
- "Install compatibility libraries",
- "Do not install compatibility libraries"
- };
+ ret = ui_yes_no(op, TRUE,
+ "Install NVIDIA's 32-bit compatibility libraries?");
- install_compat32_files = (ui_multiple_choice(op, choices, 2, 1,
- "The NVIDIA 32-bit compatibility libraries "
- "are to be installed relative to the "
- "top-level prefix (chroot) '%s'; however, "
- "this directory does not exist. Please "
- "consult your distribution's documentation "
- "to confirm the correct top-level "
- "installation prefix for 32-bit compatiblity "
- "libraries.\n\nWould you like to install "
- "NVIDIA 32-bit compatibility libraries "
- "anyway?", op->compat32_chroot) == 0);
+ op->install_compat32_libs = ret ? NV_OPTIONAL_BOOL_TRUE :
+ NV_OPTIONAL_BOOL_FALSE;
}
- if (!install_compat32_files) {
+ if (op->install_compat32_libs == NV_OPTIONAL_BOOL_FALSE) {
+ int i;
+
for (i = 0; i < p->num_entries; i++) {
if (p->entries[i].compat_arch == FILE_COMPAT_ARCH_COMPAT32) {
/* invalidate file */
@@ -1343,6 +1332,7 @@ void check_installed_files_from_package(Options *op, Package *p)
static int check_symlink(Options *op, const char *target, const char *link,
const char *descr)
{
+ int success = TRUE;
char *actual_target;
actual_target = get_symlink_target(op, link);
@@ -1375,12 +1365,12 @@ static int check_symlink(Options *op, const char *target, const char *link,
actual_target,
target,
link);
- free(actual_target);
- return FALSE;
+ success = FALSE;
}
- return TRUE;
-
-} /* check_symlink() */
+
+ nvfree(actual_target);
+ return success;
+}
@@ -1681,15 +1671,6 @@ static int tls_test_internal(Options *op, int which_tls,
return ret;
} /* test_tls_internal() */
-
-#else /* defined(NV_TLS_TEST) */
-
-int tls_test(Options *op, int compat_32_libs)
-{
- /* Assume the TLS test passed. */
- return TRUE;
-}
-
#endif /* defined(NV_TLS_TEST) */
@@ -1730,19 +1711,27 @@ static int rtld_test_internal(Options *op, Package *p,
int check_runtime_configuration(Options *op, Package *p)
{
- int ret = TRUE;
+ int ret = TRUE, which_tls, which_tls_compat32;
+
+#if defined(NV_TLS_TEST)
+ which_tls = op->which_tls;
+ which_tls_compat32 = op->which_tls_compat32;
+#else
+ /* Platforms that don't need the TLS test only support "new" ELF TLS. */
+ which_tls = which_tls_compat32 = TLS_LIB_NEW_TLS;
+#endif /* NV_TLS_TEST */
ui_status_begin(op, "Running runtime sanity check:", "Checking");
#if defined(NV_X86_64)
- ret = rtld_test_internal(op, p, op->which_tls_compat32,
+ ret = rtld_test_internal(op, p, 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,
+ ret = rtld_test_internal(op, p, which_tls,
rtld_test_array,
rtld_test_array_size,
FALSE);
@@ -2015,68 +2004,16 @@ static int rtld_test_internal(Options *op, Package *p,
} /* rtld_test_internal() */
-/*
- * get_distribution() - determine what distribution this is; only used
- * for several bits of distro-specific behavior requested by
- * distribution maintainers.
- *
- * XXX should we provide a commandline option to override this
- * detection?
- */
-
-Distribution get_distribution(Options *op)
-{
- FILE *fp;
- char *line = NULL, *ptr;
- int eof = FALSE;
-
- if (access("/etc/SuSE-release", F_OK) == 0) return SUSE;
- if (access("/etc/UnitedLinux-release", F_OK) == 0) return UNITED_LINUX;
- if (access("/etc/gentoo-release", F_OK) == 0) return GENTOO;
- if (access("/etc/arch-release", F_OK) == 0) return ARCH;
-
- /*
- * Attempt to determine if the host system is 'Ubuntu Linux'
- * based by checking for a line matching DISTRIB_ID=Ubuntu in
- * the file /etc/lsb-release.
- */
- fp = fopen("/etc/lsb-release", "r");
- if (fp != NULL) {
- while (((line = fget_next_line(fp, &eof))
- != NULL) && !eof) {
- ptr = strstr(line, "DISTRIB_ID");
- if (ptr != NULL) {
- fclose(fp);
- while (ptr != NULL && *ptr != '=') ptr++;
- if (ptr != NULL && *ptr == '=') ptr++;
- if (ptr != NULL && *ptr != '\0')
- if (!strcasecmp(ptr, "Ubuntu")) return UBUNTU;
- break;
- }
- }
- }
-
- if (access("/etc/debian_version", F_OK) == 0) return DEBIAN;
-
- return OTHER;
-
-} /* get_distribution() */
-
-
/*
* get_xserver_information() - parse the versionString (from `X
* -version`) and assign relevant information that we infer from the X
* server version.
- *
- * Note: this implementation should be shared with nvidia-xconfig
*/
static int get_xserver_information(const char *versionString,
- int *isXorg,
int *isModular,
- int *autoloadsGLX,
- int *supportsExtensionSection)
+ int *supportsOutputClassSection)
{
#define XSERVER_VERSION_FORMAT_1 "X Window System Version"
#define XSERVER_VERSION_FORMAT_2 "X.Org X Server"
@@ -2087,18 +2024,15 @@ static int get_xserver_information(const char *versionString,
/* check if this is an XFree86 X server */
if (strstr(versionString, "XFree86 Version")) {
- *isXorg = FALSE;
*isModular = FALSE;
- *autoloadsGLX = FALSE;
- *supportsExtensionSection = FALSE;
return TRUE;
}
- /* this must be an X.Org X server */
-
- *isXorg = TRUE;
- /* attempt to parse the major.minor version out of the string */
+ /*
+ * This must be an X.Org X server. Attempt to parse the major.minor version
+ * out of the string
+ */
found = FALSE;
@@ -2129,30 +2063,13 @@ static int get_xserver_information(const char *versionString,
}
/*
- * supportsExtensionSection: support for the "Extension" xorg.conf
- * section was added between X.Org 6.7 and 6.8. To account for
- * the X server version wrap, it is easier to check for X servers
- * that do not support the Extension section: 6.x (x < 8) X
- * servers.
+ * support for using OutputClass sections to automatically match drivers to
+ * platform devices was added in X.Org xserver 1.16.
*/
-
- if ((major == 6) && (minor < 8)) {
- *supportsExtensionSection = FALSE;
+ if ((major == 6) || (major == 7) || ((major == 1) && (minor < 16))) {
+ *supportsOutputClassSection = FALSE;
} else {
- *supportsExtensionSection = TRUE;
- }
-
- /*
- * support for autoloading GLX was added in X.Org 1.5. To account
- * for the X server version wrap, it is easier to check for X
- * servers that do not support GLX autoloading: 6.x, 7.x, or < 1.5
- * X servers.
- */
-
- if ((major == 6) || (major == 7) || ((major == 1) && (minor < 5))) {
- *autoloadsGLX = FALSE;
- } else {
- *autoloadsGLX = TRUE;
+ *supportsOutputClassSection = TRUE;
}
return TRUE;
@@ -2162,23 +2079,23 @@ static int get_xserver_information(const char *versionString,
/*
- * check_for_modular_xorg() - run the X binary with the '-version'
- * command line option and extract the version in an attempt to
- * determine if it's part of a modular Xorg release. If the version
- * can't be determined, we assume it's not.
+ * query_xorg_version() - run the X binary with the '-version'
+ * command line option and extract the version.
*
- * This should eventually get collapsed with xconfigGetXServerInUse()
- * in nvidia-xconfig.
+ * Using the version, try to infer if it's part of a modular Xorg release. If
+ * the version can't be determined, we assume it's not.
+ *
+ * This function assigns the following fields:
+ * op->modular_xorg
*/
#define OLD_VERSION_FORMAT "(protocol Version %d, revision %d, vendor release %d)"
#define NEW_VERSION_FORMAT "X Protocol Version %d, Revision %d, Release %d."
-int check_for_modular_xorg(Options *op)
+void query_xorg_version(Options *op)
{
char *cmd = NULL, *data = NULL;
- int modular_xorg = FALSE;
- int dummy, ret;
+ int ret = FALSE;
if (!op->utils[XSERVER])
goto done;
@@ -2195,30 +2112,27 @@ int check_for_modular_xorg(Options *op)
* modular
*/
- ret = get_xserver_information(data,
- &dummy, /* isXorg */
- &modular_xorg, /* isModular */
- &dummy, /* autoloadsGLX */
- &dummy); /* supportsExtensionSection */
+ ret = get_xserver_information(data, &op->modular_xorg,
+ &op->xorg_supports_output_class);
+
+ /* fall through */
+
+done:
/*
- * if get_xserver_information() failed, assume the X server is not
- * modular
+ * if no X server was found, or querying the version on the command line
+ * failed, or get_xserver_information() failed, assume the X server is
+ * modular, but does not support OutputClass sections
*/
if (!ret) {
- modular_xorg = FALSE;
+ op->modular_xorg = TRUE;
+ op->xorg_supports_output_class = FALSE;
}
- /* fall through */
-
-done:
nvfree(data);
nvfree(cmd);
-
- return modular_xorg;
-
-} /* check_for_modular_xorg() */
+}
/*
@@ -2252,8 +2166,12 @@ int check_for_running_x(Options *op)
for (i = 0; i < 8; i++) {
snprintf(path, 14, "/tmp/.X%1d-lock", i);
if (read_text_file(path, &buf) == TRUE) {
- sscanf(buf, "%d", &pid);
+ int num = sscanf(buf, "%d", &pid);
nvfree(buf);
+ if (num != 1) {
+ ui_warn(op, "Failed to read a pid from X lock file '%s'", path);
+ return TRUE;
+ }
snprintf(procpath, 17, "/proc/%d", pid);
if (access(procpath, F_OK) == 0) {
ui_log(op, "The file '%s' exists and appears to contain the "
@@ -2491,40 +2409,58 @@ int check_selinux(Options *op)
/*
* run_nvidia_xconfig() - run the `nvidia-xconfig` utility. Without
* any options, this will just make sure the X config file uses the
- * NVIDIA driver by default. The restore parameter controls whether
- * the --restore-original-backup option is added, which attempts to
- * restore the original backed up X config file.
+ * NVIDIA driver by default.
+ *
+ * Parameters:
+ *
+ * restore: controls whether the --restore-original-backup option is added,
+ * which attempts to restore the original backed up X config file.
+ * question: if this is non-NULL, the user will be asked 'question' as a
+ * yes or no question, to determine whether to run nvidia-xconfig.
+ * answer: the default answer to 'question'.
+ *
+ * Returns TRUE if nvidia-xconfig ran successfully; returns FALSE if
+ * nvidia-xconfig ran unsuccessfully, or did not run at all.
*/
-int run_nvidia_xconfig(Options *op, int restore)
+int run_nvidia_xconfig(Options *op, int restore, const char *question,
+ int default_answer)
{
- int ret, bRet = TRUE;
- char *data = NULL, *cmd = NULL, *args, *nvidia_xconfig;
+ int ret = FALSE;
+ char *nvidia_xconfig;
nvidia_xconfig = find_system_util("nvidia-xconfig");
if (nvidia_xconfig == NULL) {
+ /* nvidia-xconfig not found: don't run it or ask any questions */
goto done;
}
- args = restore ? " --restore-original-backup" : "";
-
- cmd = nvstrcat(nvidia_xconfig, args, NULL);
-
- ret = run_command(op, cmd, &data, FALSE, 0, TRUE);
-
- if (ret != 0) {
- ui_error(op, "Failed to run `%s`:\n%s", cmd, data);
- bRet = FALSE;
+ ret = question ? ui_yes_no(op, default_answer, "%s", question) : TRUE;
+
+ if (ret) {
+ int cmd_ret;
+ char *data, *cmd, *args;
+
+ args = restore ? " --restore-original-backup" : "";
+
+ cmd = nvstrcat(nvidia_xconfig, args, NULL);
+
+ cmd_ret = run_command(op, cmd, &data, FALSE, 0, TRUE);
+
+ if (cmd_ret != 0) {
+ ui_error(op, "Failed to run `%s`:\n%s", cmd, data);
+ ret = FALSE;
+ }
+
+ nvfree(cmd);
+ nvfree(data);
}
done:
-
- nvfree(cmd);
- nvfree(data);
nvfree(nvidia_xconfig);
- return bRet;
+ return ret;
} /* run_nvidia_xconfig() */
@@ -2987,14 +2923,13 @@ int check_for_nouveau(Options *op)
static int run_dkms(Options *op, const char* verb, const char *version,
const char *kernel, char** out)
{
- char *cmd, *cmdline, *veropt, *kernopt = NULL, *kernopt_all = "";
+ char *cmdline, *veropt, *kernopt = NULL, *kernopt_all = "";
const char *modopt = " -m nvidia"; /* XXX real name is in the Package */
char *output;
int ret;
/* Fail if DKMS not found */
- cmd = find_system_util("dkms");
- if (!cmd) {
+ if (!op->utils[DKMS]) {
if (strcmp(verb, DKMS_STATUS) != 0) {
ui_error(op, "Failed to find dkms on the system!");
}
@@ -3012,9 +2947,8 @@ static int run_dkms(Options *op, const char* verb, const char *version,
kernopt = kernel ? nvstrcat(" -k ", kernel, NULL) : NULL;
}
- cmdline = nvstrcat(cmd, verb, modopt, veropt, kernopt_all, kernopt, NULL);
-
- nvfree(cmd);
+ cmdline = nvstrcat(op->utils[DKMS], verb, modopt, veropt,
+ kernopt_all, kernopt, NULL);
/* Run DKMS */
ret = run_command(op, cmdline, &output, FALSE, 0, TRUE);
@@ -3190,3 +3124,48 @@ ElfFileType get_elf_architecture(const char *filename)
default: return ELF_INVALID_FILE;
}
}
+
+
+
+/*
+ * set_concurrency_level() - automatically determine the concurrency level,
+ * if the user has not specified it.
+ */
+
+void set_concurrency_level(Options *op)
+{
+ int detected_cpus;
+
+ if (op->concurrency_level) {
+ ui_log(op, "Concurrency level set to %d on the command line.",
+ op->concurrency_level);
+ } else {
+#if defined _SC_NPROCESSORS_ONLN
+ detected_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+ if (detected_cpus >= 1) {
+ ui_log(op, "Detected %d CPUs online; setting concurrency level "
+ "to %d.", detected_cpus, detected_cpus);
+ } else
+#else
+#warning _SC_NPROCESSORS_ONLN not defined; nvidia-installer will not be able \
+to detect the number of processors.
+#endif
+ {
+ ui_log(op, "Unable to detect the number of processors: setting "
+ "concurrency level to 1.");
+ detected_cpus = 1;
+ }
+ op->concurrency_level = detected_cpus;
+ }
+
+ if (op->expert) {
+ int val = op->concurrency_level;
+ do {
+ char *strval = nvasprintf("%d", val);
+ val = atoi(ui_get_input(op, strval, "Concurrency level"));
+ nvfree(strval);
+ } while (val < 1);
+ op->concurrency_level = val;
+ }
+}
diff --git a/misc.h b/misc.h
index f89bf7b..5eecb6d 100644
--- a/misc.h
+++ b/misc.h
@@ -79,11 +79,10 @@ int tls_test(Options *op, int compat_32_libs);
int check_runtime_configuration(Options *op, Package *p);
void collapse_multiple_slashes(char *s);
int is_symbolic_link_to(const char *path, const char *dest);
-Distribution get_distribution(Options *op);
int check_for_running_x(Options *op);
-int check_for_modular_xorg(Options *op);
+void query_xorg_version(Options *op);
int check_for_nvidia_graphics_devices(Options *op, Package *p);
-int run_nvidia_xconfig(Options *op, int restore);
+int run_nvidia_xconfig(Options *op, int restore, const char *question, int answer);
HookScriptStatus run_distro_hook(Options *op, const char *hook);
int check_for_alternate_install(Options *op);
int check_for_nouveau(Options *op);
@@ -94,5 +93,6 @@ int verify_crc(Options *op, const char *filename, unsigned int crc,
unsigned int *actual_crc);
int secure_boot_enabled(void);
ElfFileType get_elf_architecture(const char *filename);
+void set_concurrency_level(Options *op);
#endif /* __NVIDIA_INSTALLER_MISC_H__ */
diff --git a/ncurses-ui.c b/ncurses-ui.c
index 621846e..e28f229 100644
--- a/ncurses-ui.c
+++ b/ncurses-ui.c
@@ -898,7 +898,7 @@ static void nv_ncurses_status_update(Options *op, const float percent,
*/
if (ch == NV_NCURSES_CTRL('L')) {
nv_ncurses_check_resize(d, TRUE);
- if (d->message) nv_ncurses_destroy_region(d->message);
+ nv_ncurses_destroy_region(d->message);
nv_ncurses_do_progress_bar_region(d);
}
}
diff --git a/nvidia-installer.c b/nvidia-installer.c
index 2a45222..f243654 100644
--- a/nvidia-installer.c
+++ b/nvidia-installer.c
@@ -134,7 +134,6 @@ static Options *load_default_options(void)
op->ftp_site = DEFAULT_FTP_SITE;
op->tmpdir = get_tmpdir(op);
- op->distro = get_distribution(op);
op->logging = TRUE; /* log by default */
op->opengl_headers = FALSE; /* do not install our GL headers by default */
@@ -150,6 +149,7 @@ static Options *load_default_options(void)
op->check_for_alternate_installs = TRUE;
op->num_kernel_modules = 1;
op->install_uvm = TRUE;
+ op->install_compat32_libs = NV_OPTIONAL_BOOL_DEFAULT;
return op;
@@ -206,7 +206,6 @@ static void parse_commandline(int argc, char *argv[], Options *op)
op->driver_info = TRUE;
op->ui_str = "none";
break;
-
case 'n': op->no_precompiled_interface = TRUE; break;
case 'c': op->no_ncurses_color = TRUE; break;
case 'l': op->latest = TRUE; break;
@@ -230,12 +229,20 @@ static void parse_commandline(int argc, char *argv[], Options *op)
break;
case 'z': op->no_nouveau_check = TRUE; break;
case 'Z': op->disable_nouveau = TRUE; break;
-
case 'k':
op->kernel_name = strval;
op->no_precompiled_interface = TRUE;
op->ignore_cc_version_check = TRUE;
break;
+ case 'j':
+ if (intval < 1) {
+ nv_error_msg("Invalid concurrency level %d: nvidia-installer "
+ "will attempt to autodetect the number of CPUs.",
+ intval);
+ intval = 0;
+ }
+ op->concurrency_level = intval;
+ break;
case XFREE86_PREFIX_OPTION:
case X_PREFIX_OPTION:
@@ -244,6 +251,8 @@ static void parse_commandline(int argc, char *argv[], Options *op)
op->x_library_path = strval; break;
case X_MODULE_PATH_OPTION:
op->x_module_path = strval; break;
+ case X_SYSCONFIG_PATH_OPTION:
+ op->x_sysconfig_path = strval; break;
case OPENGL_PREFIX_OPTION:
op->opengl_prefix = strval; break;
case OPENGL_LIBDIR_OPTION:
@@ -255,6 +264,10 @@ static void parse_commandline(int argc, char *argv[], Options *op)
op->compat32_prefix = strval; break;
case COMPAT32_LIBDIR_OPTION:
op->compat32_libdir = strval; break;
+ case INSTALL_COMPAT32_LIBS_OPTION:
+ op->install_compat32_libs = boolval ? NV_OPTIONAL_BOOL_TRUE :
+ NV_OPTIONAL_BOOL_FALSE;
+ break;
#endif
case DOCUMENTATION_PREFIX_OPTION:
op->documentation_prefix = strval; break;
@@ -276,6 +289,8 @@ static void parse_commandline(int argc, char *argv[], Options *op)
op->kernel_module_installation_path = strval; break;
case UNINSTALL_OPTION:
op->uninstall = TRUE; break;
+ case SKIP_MODULE_UNLOAD_OPTION:
+ op->skip_module_unload = TRUE; break;
case PROC_MOUNT_POINT_OPTION:
op->proc_mount_point = strval; break;
case USER_INTERFACE_OPTION:
@@ -291,6 +306,7 @@ static void parse_commandline(int argc, char *argv[], Options *op)
op->opengl_headers = TRUE; break;
case NO_NVIDIA_MODPROBE_OPTION:
op->nvidia_modprobe = FALSE; break;
+#if defined(NV_TLS_TEST)
case FORCE_TLS_OPTION:
if (strcasecmp(strval, "new") == 0)
op->which_tls = FORCE_NEW_TLS;
@@ -312,7 +328,8 @@ static void parse_commandline(int argc, char *argv[], Options *op)
goto fail;
}
break;
-#endif
+#endif /* NV_X86_64 */
+#endif /* NV_TLS_TEST */
case SANITY_OPTION:
op->sanity = TRUE;
break;
@@ -555,6 +572,11 @@ int main(int argc, char *argv[])
/* initialize the user interface */
if (!ui_init(op)) return 1;
+
+ /* determine the concurrency level: do this early on, to allow for
+ * parallelization of as much of the install as possible. */
+
+ set_concurrency_level(op);
/* check that we're running as root */
@@ -571,11 +593,10 @@ int main(int argc, char *argv[])
if (!find_module_utils(op)) goto done;
if (!check_selinux(op)) goto done;
- /* check if we need to worry about modular Xorg */
+ /* check for X server properties based on the version of the server */
+
+ query_xorg_version(op);
- op->modular_xorg =
- check_for_modular_xorg(op);
-
/* get the default installation prefixes/paths */
get_default_prefixes_and_paths(op);
diff --git a/nvidia-installer.h b/nvidia-installer.h
index fdb1ddf..eed02a7 100644
--- a/nvidia-installer.h
+++ b/nvidia-installer.h
@@ -57,6 +57,7 @@ typedef enum {
PKG_CONFIG,
XSERVER,
OPENSSL,
+ DKMS,
MAX_SYSTEM_OPTIONAL_UTILS
} SystemOptionalUtils;
@@ -92,22 +93,6 @@ typedef enum {
#define MAX_UTILS MAX_DEVELOP_UTILS
-/*
- * Enumerated type of distributions; this isn't an exhaustive list of
- * supported distributions... just distributions that have asked for
- * special behavior.
- */
-
-typedef enum {
- SUSE,
- UNITED_LINUX,
- DEBIAN,
- UBUNTU,
- GENTOO,
- ARCH,
- OTHER
-} Distribution;
-
typedef uint32_t uint32;
typedef uint16_t uint16;
@@ -128,6 +113,7 @@ typedef struct __options {
int update;
int expert;
int uninstall;
+ int skip_module_unload;
int driver_info;
int debug;
int logging;
@@ -139,8 +125,10 @@ typedef struct __options {
int nvidia_modprobe;
int no_questions;
int silent;
+#if defined(NV_TLS_TEST)
int which_tls;
int which_tls_compat32;
+#endif /* NV_TLS_TEST */
int sanity;
int add_this_kernel;
int no_backup;
@@ -167,8 +155,12 @@ typedef struct __options {
int num_kernel_modules;
int install_uvm;
int uvm_files_packaged;
+ int compat32_files_packaged;
+ int x_files_packaged;
+ int concurrency_level;
NVOptionalBool install_vdpau_wrapper;
+ NVOptionalBool install_compat32_libs;
char *opengl_prefix;
char *opengl_libdir;
@@ -179,6 +171,7 @@ typedef struct __options {
char *x_moddir;
char *x_module_path;
char *x_library_path;
+ char *x_sysconfig_path;
char *compat32_chroot;
char *compat32_prefix;
@@ -198,6 +191,7 @@ typedef struct __options {
char *application_profile_path;
int modular_xorg;
+ int xorg_supports_output_class;
char *kernel_source_path;
char *kernel_output_path;
@@ -231,8 +225,6 @@ typedef struct __options {
int kernel_module_signed;
- Distribution distro;
-
void *ui_priv; /* for use by the ui's */
int ignore_cc_version_check;
@@ -249,11 +241,8 @@ typedef enum {
FILE_TYPE_KERNEL_MODULE_CMD,
FILE_TYPE_OPENGL_HEADER,
FILE_TYPE_OPENGL_LIB,
- FILE_TYPE_XLIB_STATIC_LIB,
- FILE_TYPE_XLIB_SHARED_LIB,
FILE_TYPE_DOCUMENTATION,
FILE_TYPE_OPENGL_SYMLINK,
- FILE_TYPE_XLIB_SYMLINK,
FILE_TYPE_KERNEL_MODULE,
FILE_TYPE_INSTALLER_BINARY,
FILE_TYPE_UTILITY_BINARY,
@@ -269,7 +258,11 @@ typedef enum {
FILE_TYPE_MANPAGE,
FILE_TYPE_EXPLICIT_PATH,
FILE_TYPE_CUDA_LIB,
+ FILE_TYPE_OPENCL_LIB,
+ FILE_TYPE_OPENCL_WRAPPER_LIB,
FILE_TYPE_CUDA_SYMLINK,
+ FILE_TYPE_OPENCL_LIB_SYMLINK,
+ FILE_TYPE_OPENCL_WRAPPER_SYMLINK,
FILE_TYPE_VDPAU_LIB,
FILE_TYPE_VDPAU_WRAPPER_LIB,
FILE_TYPE_VDPAU_SYMLINK,
@@ -291,6 +284,7 @@ typedef enum {
FILE_TYPE_NVIFR_LIB,
FILE_TYPE_NVIFR_LIB_SYMLINK,
FILE_TYPE_UVM_MODULE_SRC,
+ FILE_TYPE_XORG_OUTPUTCLASS_CONFIG,
FILE_TYPE_MAX
} PackageEntryFileType;
@@ -315,6 +309,7 @@ typedef struct {
unsigned int is_shared_lib : 1;
unsigned int is_opengl : 1;
unsigned int is_temporary : 1;
+ unsigned int is_wrapper : 1;
} PackageEntryFileCapabilities;
/*
@@ -374,6 +369,25 @@ typedef struct __package_entry {
*/
} PackageEntry;
+/*
+ * Information about a conflicting file; nvidia-installer searches for existing
+ * files that conflict with files that are to be installed.
+ */
+
+typedef struct {
+ const char *name;
+ int len;
+
+ /*
+ * if requiredString is non-NULL, then a file must have this
+ * string in order to be considered a conflicting file; we use
+ * this to only consider "libglx.*" files conflicts if they have
+ * the string "glxModuleData".
+ */
+
+ const char *requiredString;
+} ConflictingFileInfo;
+
typedef struct __package {
@@ -397,6 +411,7 @@ typedef struct __package {
PackageEntry *entries; /* array of filename/checksum/bytesize entries */
int num_entries;
+ ConflictingFileInfo *conflicting_files;
} Package;
@@ -439,16 +454,25 @@ typedef struct __package {
#define DEFAULT_APPLICATION_PROFILE_PATH "/usr/share/nvidia"
#define DEFAULT_LIBDIR "lib"
+#define DEFAULT_32BIT_LIBDIR "lib32"
#define DEFAULT_64BIT_LIBDIR "lib64"
+#define DEFAULT_IA32_TRIPLET_LIBDIR "lib/i386-linux-gnu"
+#define DEFAULT_AMD64_TRIPLET_LIBDIR "lib/x86_64-linux-gnu"
+#define DEFAULT_ARMV7_TRIPLET_LIBDIR "lib/arm-linux-gnueabi"
+#define DEFAULT_ARMV7HF_TRIPLET_LIBDIR "lib/arm-linux-gnueabihf"
+#define DEFAULT_AARCH64_TRIPLET_LIBDIR "lib/aarch64-linux-gnu"
+#define DEFAULT_PPC64LE_TRIPLET_LIBDIR "lib/powerpc64le-linux-gnu"
#define DEFAULT_BINDIR "bin"
#define DEFAULT_INCDIR "include"
#define DEFAULT_X_MODULEDIR "modules"
#define DEFAULT_DOT_DESKTOPDIR "share/applications"
#define DEFAULT_DOCDIR "share/doc"
#define DEFAULT_MANDIR "share/man"
+#define DEFAULT_CONFDIR "X11/xorg.conf.d"
#define DEFAULT_MODULE_SIGNING_KEY_PATH "/usr/share/nvidia"
#define DEFAULT_KERNEL_MODULE_SRC_PREFIX "/usr/src"
+#define DEFAULT_X_DATAROOT_PATH "/usr/share"
/*
* As of Xorg 7.x, X components need not be installed relative
@@ -467,29 +491,6 @@ typedef struct __package {
*/
#define DEBIAN_DEFAULT_COMPAT32_CHROOT "/emul/ia32-linux"
-/*
- * Debian GNU/Linux and Ubuntu do not follow the lib64 library
- * path naming convention used by other distributors. 64-bit
- * libraries are placed under ../lib.
- */
-#define DEBIAN_DEFAULT_64BIT_LIBDIR "lib"
-
-/*
- * Ubuntu GNU/Linux and Gentoo Linux do not follow the "lib"
- * library path naming convention used for 32-bit compatibility
- * libraries by other distributors. These libraries are
- * placed under ../lib32.
- */
-#define UBUNTU_DEFAULT_COMPAT32_LIBDIR "lib32"
-
-/*
- * Newer versions of Debian GNU/Linux may install 32-bit
- * compatibility libraries to ../lib/i386-linux-gnu instead
- * of ../lib32.
- */
-
-#define DEBIAN_DEFAULT_COMPAT32_LIBDIR "lib/i386-linux-gnu"
-
#define DEFAULT_PROC_MOUNT_POINT "/proc"
#define DEFAULT_FTP_SITE "ftp://download.nvidia.com"
diff --git a/option_table.h b/option_table.h
index 1d49dda..c9c5c60 100644
--- a/option_table.h
+++ b/option_table.h
@@ -41,6 +41,7 @@ enum {
KERNEL_INCLUDE_PATH_OPTION,
KERNEL_INSTALL_PATH_OPTION,
UNINSTALL_OPTION,
+ SKIP_MODULE_UNLOAD_OPTION,
PROC_MOUNT_POINT_OPTION,
USER_INTERFACE_OPTION,
LOG_FILE_NAME_OPTION,
@@ -96,6 +97,8 @@ enum {
NO_CHECK_FOR_ALTERNATE_INSTALLS_OPTION,
MULTIPLE_KERNEL_MODULES_OPTION,
NO_UVM_OPTION,
+ INSTALL_COMPAT32_LIBS_OPTION,
+ X_SYSCONFIG_PATH_OPTION,
};
static const NVGetoptOption __options[] = {
@@ -138,6 +141,11 @@ static const NVGetoptOption __options[] = {
{ "uninstall", UNINSTALL_OPTION, 0, NULL,
"Uninstall the currently installed NVIDIA driver." },
+ { "skip-module-unload", SKIP_MODULE_UNLOAD_OPTION,
+ NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL, NULL,
+ "When uninstalling the driver, skip unloading of the NVIDIA kernel "
+ "module. This option is ignored when the driver is being installed." },
+
{ "sanity", SANITY_OPTION, 0, NULL,
"Perform basic sanity tests on an existing NVIDIA "
"driver installation." },
@@ -192,6 +200,13 @@ static const NVGetoptOption __options[] = {
DEFAULT_64BIT_LIBDIR "' or '" DEFAULT_LIBDIR "' on 64bit systems, "
"depending on the installed Linux distribution." },
+ { "x-sysconfig-path", X_SYSCONFIG_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, NULL,
+ "The path under which X system configuration files will be installed. "
+ "If this option is not specified, nvidia-installer uses the following "
+ "search order and selects the first valid directory it finds: 1) "
+ "`pkg-config --variable=sysconfigdir xorg-server`, or 2) "
+ DEFAULT_X_DATAROOT_PATH "/" DEFAULT_CONFDIR "." },
+
{ "opengl-prefix", OPENGL_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, NULL,
"The prefix under which the OpenGL components of the "
"NVIDIA driver will be installed; the default is: '" DEFAULT_OPENGL_PREFIX
@@ -229,9 +244,16 @@ static const NVGetoptOption __options[] = {
"The path relative to the 32bit compatibility prefix under which the "
"32bit compatibility components of the NVIDIA driver will "
"be installed. The default is '" DEFAULT_LIBDIR "' or '"
- UBUNTU_DEFAULT_COMPAT32_LIBDIR "', depending on the installed Linux "
+ DEFAULT_32BIT_LIBDIR "', depending on the installed Linux "
"distribution. Only under very rare circumstances should this "
"option be used." },
+
+ { "install-compat32-libs", INSTALL_COMPAT32_LIBS_OPTION,
+ NVGETOPT_IS_BOOLEAN, NULL,
+ "32-bit compatibility libraries may be optionally installed. Setting "
+ "--install-compat32-libs will install these libraries. Setting "
+ "--no-install-compat32-libs will skip installation of these libraries. "
+ "Note: this option will have no effect on -no-compat32.run packages." },
#endif /* NV_X86_64 */
{ "installer-prefix", INSTALLER_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT,
@@ -366,6 +388,7 @@ static const NVGetoptOption __options[] = {
"needed if other means of loading the NVIDIA kernel module and creating "
"the NVIDIA device files are unavailable." },
+#if defined(NV_TLS_TEST)
{ "force-tls", FORCE_TLS_OPTION, NVGETOPT_STRING_ARGUMENT, NULL,
"NVIDIA's OpenGL libraries are compiled with one of two "
"different thread local storage (TLS) mechanisms: 'classic tls' "
@@ -383,6 +406,7 @@ static const NVGetoptOption __options[] = {
"32bit compatibility OpenGL TLS library; further details "
"can be found in the description of the '--force-tls' option." },
#endif /* NV_X86_64 */
+#endif
{ "kernel-name", 'k', NVGETOPT_STRING_ARGUMENT, NULL,
"Build and install the NVIDIA kernel module for the "
@@ -620,16 +644,22 @@ static const NVGetoptOption __options[] = {
NVGETOPT_INTEGER_ARGUMENT, NULL,
"Build and install multiple NVIDIA kernel modules. The maximum number "
"of NVIDIA kernel modules that may be built is 8. '--multiple-kernel-"
- "modules' implies '--no-unified-memory'."},
+ "modules' implies '--no-unified-memory'." },
{ "no-unified-memory", NO_UVM_OPTION, 0, NULL,
"Do not install the NVIDIA Unified Memory kernel module. This kernel "
- "module is required for CUDA, and if it is not installed, the CUDA "
- "driver and CUDA applications will not be able to run. The "
- "'--no-unified-memory' option should only be used to work around "
- "failures to build or install the Unified Memory kernel module on "
+ "module is required for CUDA on 64-bit systems, and if it is not "
+ "installed, the CUDA driver and CUDA applications will not be able to "
+ "run. The '--no-unified-memory' option should only be used to work "
+ "around failures to build or install the Unified Memory kernel module on "
"systems that do not need to run CUDA." },
+ { "concurrency-level", 'j', NVGETOPT_INTEGER_ARGUMENT, NULL,
+ "Set the concurrency level for operations such as building the kernel "
+ "module which may be parallelized on SMP systems. By default, this will "
+ "be set to the number of detected CPUs, or to '1', if nvidia-installer "
+ "fails to detect the number of CPUs." },
+
/* Orphaned options: These options were in the long_options table in
* nvidia-installer.c but not in the help. */
{ "debug", 'd', 0, NULL,NULL },
diff --git a/precompiled.c b/precompiled.c
index 5a4c1c1..50d6183 100644
--- a/precompiled.c
+++ b/precompiled.c
@@ -81,7 +81,7 @@ static uint32 read_uint32(const char *buf, int *offset)
char *read_proc_version(Options *op, const char *proc_mount_point)
{
- int fd, ret, len, version_len;
+ int fd, len, version_len;
char *version, *c = NULL;
char *proc_verson_filename;
@@ -105,6 +105,8 @@ char *read_proc_version(Options *op, const char *proc_mount_point)
version = NULL;
while (1) {
+ int ret;
+
if (version_len == len) {
version_len += NV_LINE_LEN;
version = nvrealloc(version, version_len);
@@ -114,8 +116,9 @@ char *read_proc_version(Options *op, const char *proc_mount_point)
if (ret == -1) {
ui_warn(op, "Error reading %s (%s).",
proc_verson_filename, strerror(errno));
- free(version);
- return NULL;
+ nvfree(version);
+ version = NULL;
+ goto done;
}
if (ret == 0) {
*c = '\0';
@@ -131,11 +134,12 @@ char *read_proc_version(Options *op, const char *proc_mount_point)
while ((*c != '\0') && (*c != '\n')) c++;
*c = '\0';
- free(proc_verson_filename);
+ done:
+ nvfree(proc_verson_filename);
+ close(fd);
return version;
-
-} /* read_proc_version() */
+}
@@ -160,7 +164,7 @@ PrecompiledInfo *get_precompiled_info(Options *op,
PrecompiledFileInfo *fileInfos = NULL;
fd = size = 0;
- buf = description = proc_version_string = NULL;
+ buf = description = proc_version_string = version = NULL;
/* open the file to be unpacked */
@@ -233,7 +237,7 @@ PrecompiledInfo *get_precompiled_info(Options *op,
/* check if this precompiled kernel interface is the right driver
version */
- if (package_version && (strcmp(version, package_version) != 0)) {
+ if (!version || !package_version || strcmp(version, package_version) != 0) {
goto done;
}
@@ -332,11 +336,11 @@ PrecompiledInfo *get_precompiled_info(Options *op,
info->files = fileInfos;
/*
- * XXX so that the proc version and description strings, and the
+ * XXX so that the proc version, description, and version strings, and the
* PrecompiledFileInfo array aren't freed below
*/
- proc_version_string = description = NULL;
+ proc_version_string = description = version = NULL;
fileInfos = NULL;
done:
@@ -344,10 +348,11 @@ done:
/* cleanup whatever needs cleaning up */
if (buf) munmap(buf, size);
- if (fd > 0) close(fd);
- if (description) free(description);
- if (proc_version_string) free(proc_version_string);
- if (fileInfos) free(fileInfos);
+ if (fd >= 0) close(fd);
+ nvfree(description);
+ nvfree(proc_version_string);
+ nvfree(fileInfos);
+ nvfree(version);
return info;
@@ -942,11 +947,17 @@ const char **precompiled_file_attribute_names(uint32 attribute_mask)
"linked module crc",
"embedded signature",
};
+ static const char *unknown_attribute = "unknown attribute";
- ret = nvalloc((ARRAY_LEN(file_attribute_names) + 1) * sizeof(char *));
+ const int max_file_attribute_names = sizeof(attribute_mask) * 8;
- for (i = 0; i < 32; i++) {
- if (attribute_mask & (1 << i)) {
+ /* leave room for a NULL terminator */
+ ret = nvalloc((max_file_attribute_names + 1) * sizeof(char *));
+
+ for (i = 0; i < max_file_attribute_names; i++) {
+ if (i >= ARRAY_LEN(file_attribute_names)) {
+ ret[attr++] = unknown_attribute;
+ } else if (attribute_mask & (1 << i)) {
ret[attr++] = file_attribute_names[i];
}
}
@@ -997,6 +1008,8 @@ int byte_tail(const char *infile, int start, char **buf)
}
done:
- fclose(in);
+ if (in) {
+ fclose(in);
+ }
return size;
}
diff --git a/sanity.c b/sanity.c
index 3a5729d..f9074a7 100644
--- a/sanity.c
+++ b/sanity.c
@@ -21,18 +21,10 @@
*/
#include "nvidia-installer.h"
-#include "command-list.h"
#include "user-interface.h"
#include "backup.h"
-#include "misc.h"
#include "sanity.h"
-#include <sys/types.h>
-#include <sys/shm.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
/*
* sanity() - perform sanity tests on an existing installation
@@ -68,10 +60,6 @@ int sanity(Options *op)
return FALSE;
}
- /* check that shared memory works */
-
- if (!check_sysvipc(op)) return FALSE;
-
/*
* XXX There are lots of additional tests that could be added:
*
@@ -95,39 +83,3 @@ int sanity(Options *op)
return TRUE;
} /* sanity() */
-
-
-/*
- * check_sysvipc() - test that shmat() and friends work
- */
-
-int check_sysvipc(Options *op)
-{
- int shmid = -1;
- int ret = FALSE;
- int size = sysconf(_SC_PAGESIZE);
- void *address = (void *) -1;
-
- shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
- if (shmid == -1) goto done;
-
- address = shmat(shmid, 0, 0);
- if (address == (void *) -1) goto done;
-
- ret = TRUE;
-
- done:
-
- if (shmid != -1) shmctl(shmid, IPC_RMID, 0);
- if (address != (void *) -1) shmdt(address);
-
- if (ret) {
- ui_log(op, "Shared memory test passed.");
- } else {
- ui_message(op, "Shared memory test failed (%s): please check that "
- "your kernel has CONFIG_SYSVIPC enabled.", strerror(errno));
- }
-
- return ret;
-
-} /* check_sysvipc() */
diff --git a/sanity.h b/sanity.h
index acb29d3..706ad8d 100644
--- a/sanity.h
+++ b/sanity.h
@@ -24,6 +24,5 @@
#define __NVIDIA_INSTALLER_SANITY_H__
int sanity(Options *);
-int check_sysvipc(Options *op);
#endif /* __NVIDIA_INSTALLER_SANITY_H__ */
diff --git a/snarf-ftp.c b/snarf-ftp.c
index d2cde60..4a2d171 100644
--- a/snarf-ftp.c
+++ b/snarf-ftp.c
@@ -317,8 +317,8 @@ int ftp_transfer(UrlResource *rsrc)
/* do the password dance */
if (!check_numeric("230", line)) {
if (!check_numeric("331", line)) {
- nvfree(line);
ui_error(rsrc->op, "bad/unexpected response: %s", line);
+ nvfree(line);
return FALSE;
} else {
nvfree(line);
diff --git a/tls_test_Linux-ia64 b/tls_test_Linux-ia64
deleted file mode 100755
index 23a50b7..0000000
--- a/tls_test_Linux-ia64
+++ /dev/null
Binary files differ
diff --git a/tls_test_dso_Linux-ia64.so b/tls_test_dso_Linux-ia64.so
deleted file mode 100755
index b1ac50f..0000000
--- a/tls_test_dso_Linux-ia64.so
+++ /dev/null
Binary files differ
diff --git a/update.c b/update.c
index a8e8700..4b9e434 100644
--- a/update.c
+++ b/update.c
@@ -265,11 +265,11 @@ static int get_latest_driver_version_and_filename(Options *op,
char **pFileName)
{
int fd = -1;
- int length;
+ int length = 0;
int ret = FALSE;
char *tmpfile = NULL;
char *url = NULL;
- char *str = (void *) -1;
+ char *str = MAP_FAILED;
char *s = NULL;
char *buf = NULL;
char *buf2 = NULL;
@@ -311,7 +311,7 @@ static int get_latest_driver_version_and_filename(Options *op,
length = stat_buf.st_size;
str = mmap(0, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
- if (str == (void *) -1) {
+ if (str == MAP_FAILED) {
ui_error(op, "Unable to determine most recent NVIDIA %s-%s driver "
"version (%s).", INSTALLER_OS, INSTALLER_ARCH,
strerror(errno));
@@ -354,7 +354,7 @@ static int get_latest_driver_version_and_filename(Options *op,
nvfree(buf);
nvfree(buf2);
- if (str != (void *) -1) munmap(str, stat_buf.st_size);
+ if (str != MAP_FAILED) munmap(str, length);
if (fd != -1) close(fd);
unlink(tmpfile);
@@ -364,5 +364,4 @@ static int get_latest_driver_version_and_filename(Options *op,
nvfree(version);
return ret;
-
-} /* get_latest_driver_version() */
+}
diff --git a/user-interface.c b/user-interface.c
index 8009672..adf9ca1 100644
--- a/user-interface.c
+++ b/user-interface.c
@@ -126,7 +126,7 @@ int ui_init(Options *op)
i = 1;
}
- for (; ui_list[i].descr && !__ui; i++) {
+ for (; i < ARRAY_LEN(ui_list) && ui_list[i].descr && !__ui; i++) {
if (!extract_user_interface(op, &ui_list[i])) continue;
@@ -605,7 +605,7 @@ static int extract_user_interface(Options *op, user_interface_attribute_t *ui)
if (dst != (void *) -1) munmap(dst, ui->data_array_size);
if (fd != -1) { close(fd); unlink(ui->filename); }
- if (ui->filename) free(ui->filename);
+ free(ui->filename);
return FALSE;
diff --git a/utils.mk b/utils.mk
index cc989d0..88598d2 100644
--- a/utils.mk
+++ b/utils.mk
@@ -55,6 +55,7 @@ endif
INSTALL ?= install
INSTALL_BIN_ARGS ?= -m 755
+INSTALL_LIB_ARGS ?= -m 644
INSTALL_DOC_ARGS ?= -m 644
M4 ?= m4
@@ -98,6 +99,26 @@ ifndef TARGET_ARCH
TARGET_ARCH := $(subst i686,x86,$(TARGET_ARCH))
endif
+ifeq ($(TARGET_ARCH),x86)
+ CFLAGS += -DNV_X86 -DNV_ARCH_BITS=32
+endif
+
+ifeq ($(TARGET_ARCH),x86_64)
+ CFLAGS += -DNV_X86_64 -DNV_ARCH_BITS=64
+endif
+
+ifeq ($(TARGET_ARCH),armv7l)
+ CFLAGS += -DNV_ARMV7 -DNV_ARCH_BITS=32
+endif
+
+ifeq ($(TARGET_ARCH),aarch64)
+ CFLAGS += -DNV_AARCH64 -DNV_ARCH_BITS=64
+endif
+
+ifeq ($(TARGET_ARCH),ppc64le)
+ CFLAGS += -DNV_PPC64LE -DNV_ARCH_BITS=64
+endif
+
ifeq ($(TARGET_OS),Linux)
LIBDL_LIBS = -ldl
else
@@ -113,6 +134,14 @@ ifeq ($(TARGET_ARCH),armv7l)
endif
TARGET_ARCH_ABI ?=
+ifeq ($(TARGET_ARCH_ABI),gnueabi)
+ CFLAGS += -DNV_GNUEABI
+endif
+
+ifeq ($(TARGET_ARCH_ABI),gnueabihf)
+ CFLAGS += -DNV_GNUEABIHF
+endif
+
OUTPUTDIR ?= _out/$(TARGET_OS)_$(TARGET_ARCH)
OUTPUTDIR_ABSOLUTE ?= $(CURDIR)/$(OUTPUTDIR)
@@ -143,6 +172,7 @@ endif
PREFIX ?= /usr/local
BINDIR = $(DESTDIR)$(PREFIX)/bin
+LIBDIR = $(DESTDIR)$(PREFIX)/lib
MANDIR = $(DESTDIR)$(PREFIX)/share/man/man1
@@ -230,7 +260,7 @@ NV_MODULE_LOGGING_NAME ?=
ifeq ($(NV_VERBOSE),0)
quiet_cmd = @$(PRINTF) \
- " $(if $(NV_MODULE_LOGGING_NAME),[ %-17.17s ],%s) $(quiet_$(1))\n" \
+ " $(if $(NV_MODULE_LOGGING_NAME),[ %-17.17s ],%s) $(quiet_$(1))\n" \
"$(NV_MODULE_LOGGING_NAME)" && $($(1))
else
quiet_cmd = $($(1))
@@ -262,32 +292,49 @@ quiet_STRIP_CMD = $(call define_quiet_cmd,STRIP ,$@)
##############################################################################
# function to generate a list of object files from their corresponding
-# source files; example usage:
+# source files using the specified path. The _WITH_DIR variant takes an
+# output path as the second argument while the BUILD_OBJECT_LIST defaults
+# to using the value of OUTPUTDIR as the output path. example usage:
#
-# OBJS = $(call BUILD_OBJECT_LIST,$(SRC))
+# OBJS = $(call BUILD_OBJECT_LIST_WITH_DIR,$(SRC),$(DIR))
##############################################################################
+BUILD_OBJECT_LIST_WITH_DIR = \
+ $(addprefix $(2)/,$(notdir $(addsuffix .o,$(basename $(1)))))
+
BUILD_OBJECT_LIST = \
- $(addprefix $(OUTPUTDIR)/,$(notdir $(addsuffix .o,$(basename $(1)))))
+ $(call BUILD_OBJECT_LIST_WITH_DIR,$(1),$(OUTPUTDIR))
##############################################################################
# function to generate a list of dependency files from their
-# corresponding source files; example usage:
+# corresponding source files using the specified path. The _WITH_DIR
+# variant takes an output path as the second argument while the
+# BUILD_DEPENDENCY_LIST default to using the value of OUTPUTDIR as the
+# output path. example usage:
#
-# DEPS = $(call BUILD_DEPENDENCY_LIST,$(SRC))
+# DEPS = $(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(SRC),$(DIR))
##############################################################################
+BUILD_DEPENDENCY_LIST_WITH_DIR = \
+ $(addprefix $(2)/,$(notdir $(addsuffix .d,$(basename $(1)))))
+
BUILD_DEPENDENCY_LIST = \
- $(addprefix $(OUTPUTDIR)/,$(notdir $(addsuffix .d,$(basename $(1)))))
+ $(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(1),$(OUTPUTDIR))
##############################################################################
# functions to define a rule to build an object file; the first
-# argument whether the rule is for the target or host platform ("HOST"
-# or "TARGET"), the second argument is the source file to compile, and
-# the third argument (_WITH_OBJECT_NAME-only) is the object filename
-# to produce. Example usage:
+# argument for all functions is whether the rule is for the target or
+# host platform ("HOST" or "TARGET"), the second argument for all
+# functions is the source file to compile.
+#
+# The _WITH_OBJECT_NAME and _WITH_DIR function name suffixes describe
+# the third and possibly fourth arguments based on order. The
+# _WITH_OBJECT_NAME argument is the object filename to produce while
+# the _WITH_DIR argument is the destination path for the object file.
+#
+# Example usage:
#
# $(eval $(call DEFINE_OBJECT_RULE,TARGET,foo.c))
#
@@ -299,26 +346,35 @@ BUILD_DEPENDENCY_LIST = \
# from the source file name (this is normally what you want).
##############################################################################
-define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME
+define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME_WITH_DIR
$(3): $(2)
- @$(MKDIR) $(OUTPUTDIR)
+ @$(MKDIR) $(4)
$$(call quiet_cmd,$(call host_target_cc,$(1))) \
$$($(call host_target_cflags,$(1))) -c $$< -o $$@ \
$(call AUTO_DEP_CMD,$(1),$(2),$(3))
- -include $$(call BUILD_DEPENDENCY_LIST,$(3))
+ -include $$(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(3),$(4))
# declare empty rule for generating dependency file; we generate the
# dependency files implicitly when compiling the source file (see
# AUTO_DEP_CMD above), so we don't want gmake to spend time searching
# for an explicit rule to generate the dependency file
- $$(call BUILD_DEPENDENCY_LIST,$(3)): ;
+ $$(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(3),$(4)): ;
+
+endef
+
+define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME
+ $$(eval $$(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME_WITH_DIR,$(1),$(2),\
+ $(3),$(OUTPUTDIR)))
+endef
+define DEFINE_OBJECT_RULE_WITH_DIR
+ $$(eval $$(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME_WITH_DIR,$(1),$(2),\
+ $$(call BUILD_OBJECT_LIST_WITH_DIR,$(2),$(3)),$(3)))
endef
define DEFINE_OBJECT_RULE
- $$(eval $$(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME,$(1),$(2),\
- $$(call BUILD_OBJECT_LIST,$(2))))
+ $$(eval $$(call DEFINE_OBJECT_RULE_WITH_DIR,$(1),$(2),$(OUTPUTDIR)))
endef
diff --git a/version.mk b/version.mk
index 66ba96f..14c4194 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 343.22
+NVIDIA_VERSION = 346.16