diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2013-05-08 12:54:29 -0700 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2013-05-08 12:54:29 -0700 |
commit | 9363e4b2b799ae4f501cfef8300d7abbe371805d (patch) | |
tree | 5fabb72905899f539f4c312912d5eca442c0db1d | |
parent | 2b2f40c3ec6d7c57b36654c38e8a110672b168ce (diff) |
-rw-r--r-- | common-utils/common-utils.c | 13 | ||||
-rw-r--r-- | common-utils/common-utils.h | 1 | ||||
-rw-r--r-- | misc.c | 137 | ||||
-rw-r--r-- | version.mk | 2 |
4 files changed, 106 insertions, 47 deletions
diff --git a/common-utils/common-utils.c b/common-utils/common-utils.c index a8ee75a..1149a8e 100644 --- a/common-utils/common-utils.c +++ b/common-utils/common-utils.c @@ -281,6 +281,19 @@ char *tilde_expansion(const char *str) } /* tilde_expansion() */ +/* + * nv_prepend_to_string_list() - add a new string to a string list, delimited + * by the given string delimiter. The original list is freed. + */ + +char *nv_prepend_to_string_list(char *list, const char *item, const char *delim) +{ + char *new_list = nvstrcat(item, list ? delim : NULL, list, NULL); + nvfree(list); + return new_list; +} + + /****************************************************************************/ /* TextRows helper functions */ /****************************************************************************/ diff --git a/common-utils/common-utils.h b/common-utils/common-utils.h index 626fd1b..f95bfd3 100644 --- a/common-utils/common-utils.h +++ b/common-utils/common-utils.h @@ -55,6 +55,7 @@ char *nvstrtolower(char *s); void nvfree(void *s); char *tilde_expansion(const char *str); +char *nv_prepend_to_string_list(char *list, const char *item, const char *delim); TextRows *nv_format_text_rows(const char *prefix, const char *str, @@ -2441,47 +2441,46 @@ static int nouveau_is_present(void) -/* - * Write a modprobe configuration fragment to disable loading of - * nouveau: - * - * if [ -d /etc/modprobe.d ]; then - * name=/etc/modprobe.d/nvidia-installer-nouveau-blacklist - * echo "# generated by nvidia-installer" > $name - * echo "blacklist nouveau" >> $name - * echo "options nouveau modeset=0" >> $name - * fi - * - * Returns TRUE if successful; returns FALSE if there was a failure. - */ - -#define ETC_MODPROBE_D "/etc/modprobe.d" -#define ETC_MODPROBE_D_FILE \ - ETC_MODPROBE_D "/nvidia-installer-disable-nouveau.conf" +static const char* modprobe_directories[] = { "/etc/modprobe.d", + "/usr/lib/modprobe.d" }; +#define DISABLE_NOUVEAU_FILE "/nvidia-installer-disable-nouveau.conf" /* * this checksum is the result of compute_crc() for the file contents * written in blacklist_nouveau() */ -#define ETC_MODPROBE_D_FILE_CKSUM 3728279991U +#define DISABLE_NOUVEAU_FILE_CKSUM 3728279991U + +/* + * blacklist_filename() - generate the filename of a blacklist file. The + * caller should ensure that the directory exists, or be able to handle + * failures correctly if the directory does not exist. + */ +static char *blacklist_filename(const char *directory) +{ + return nvstrcat(directory, DISABLE_NOUVEAU_FILE, NULL); +} -static int blacklist_nouveau(void) +static char *write_blacklist_file(const char *directory) { int ret; struct stat stat_buf; FILE *file; + char *filename; - ret = stat(ETC_MODPROBE_D, &stat_buf); + ret = stat(directory, &stat_buf); - if (ret != 0) { - return FALSE; + if (ret != 0 || !S_ISDIR(stat_buf.st_mode)) { + return NULL; } - file = fopen(ETC_MODPROBE_D_FILE, "w+"); + filename = blacklist_filename(directory); + file = fopen(filename, "w+"); if (!file) { - return FALSE; + nvfree(filename); + return NULL; } fprintf(file, "# generated by nvidia-installer\n"); @@ -2491,30 +2490,71 @@ static int blacklist_nouveau(void) ret = fclose(file); if (ret != 0) { - return FALSE; + nvfree(filename); + return NULL; } - return TRUE; + return filename; } - /* - * Check if the nouveau blacklist file is already present with the - * contents that we expect + * Write modprobe configuration fragments to disable loading of + * nouveau: + * + * for directory in /etc/modprobe.d /usr/lib/modprobe.d; do + * if [ -d $directory ]; then + * name=$directory/nvidia-installer-nouveau-blacklist.conf + * echo "# generated by nvidia-installer" > $name + * echo "blacklist nouveau" >> $name + * echo "options nouveau modeset=0" >> $name + * fi + * done + * + * Returns a list of written configuration files if successful; + * returns NULL if there was a failure. */ -static int nouveau_blacklist_file_is_present(Options *op) +static char *blacklist_nouveau(void) { - if (access(ETC_MODPROBE_D_FILE, R_OK) != 0) { - return FALSE; + int i; + char *filelist = NULL; + + for (i = 0; i < ARRAY_LEN(modprobe_directories); i++) { + char *filename = write_blacklist_file(modprobe_directories[i]); + if (filename) { + filelist = nv_prepend_to_string_list(filelist, filename, ", "); + nvfree(filename); + } } - if (compute_crc(op, ETC_MODPROBE_D_FILE) != ETC_MODPROBE_D_FILE_CKSUM) { - return FALSE; + return filelist; +} + + + +/* + * Check if any nouveau blacklist file is already present with the + * contents that we expect, and return the paths to any found files, + * or NULL if no matching files were found + */ + +static char *nouveau_blacklist_file_is_present(Options *op) +{ + int i; + char *filelist = NULL; + + for (i = 0; i < ARRAY_LEN(modprobe_directories); i++) { + char *filename = blacklist_filename(modprobe_directories[i]); + + if ((access(filename, R_OK) == 0) && + (compute_crc(op, filename) == DISABLE_NOUVEAU_FILE_CKSUM)) { + filelist = nv_prepend_to_string_list(filelist, filename, ", "); + } + nvfree(filename); } - return TRUE; + return filelist; } @@ -2531,6 +2571,7 @@ static int nouveau_blacklist_file_is_present(Options *op) int check_for_nouveau(Options *op) { int ret; + char *blacklist_files; #define NOUVEAU_POINTER_MESSAGE \ "Please consult the NVIDIA driver README and your Linux " \ @@ -2546,14 +2587,17 @@ int check_for_nouveau(Options *op) "driver, and must be disabled before proceeding. " NOUVEAU_POINTER_MESSAGE); - if (nouveau_blacklist_file_is_present(op)) { - ui_warn(op, "The modprobe configuration file to disable Nouveau, " - ETC_MODPROBE_D_FILE ", is already present. Please be " - "sure you have rebooted your system since that file was " + blacklist_files = nouveau_blacklist_file_is_present(op); + + if (blacklist_files) { + ui_warn(op, "One or more modprobe configuration files to disable " + "Nouveau are already present at: %s. Please be " + "sure you have rebooted your system since these files were " "written. If you have rebooted, then Nouveau may be enabled " "for other reasons, such as being included in the system " "initial ramdisk or in your X configuration file. " - NOUVEAU_POINTER_MESSAGE); + NOUVEAU_POINTER_MESSAGE, blacklist_files); + nvfree(blacklist_files); return FALSE; } @@ -2563,18 +2607,19 @@ int check_for_nouveau(Options *op) "to attempt to create this modprobe file for you?"); if (ret) { - ret = blacklist_nouveau(); + blacklist_files = blacklist_nouveau(); - if (ret) { - ui_message(op, "The modprobe configuration file to disable " - "Nouveau, " ETC_MODPROBE_D_FILE ", has been written. " + if (blacklist_files) { + ui_message(op, "One or more modprobe configuration files to " + "disable Nouveau, have been written. " "For some distributions, this may be sufficient to " "disable Nouveau; other distributions may require " "modification of the initial ramdisk. Please reboot " "your system and attempt NVIDIA driver installation " "again. Note if you later wish to reenable Nouveau, " - "you will need to delete the file " - ETC_MODPROBE_D_FILE "."); + "you will need to delete these files: %s", + blacklist_files); + nvfree(blacklist_files); } else { ui_warn(op, "Unable to alter the nouveau modprobe configuration. " NOUVEAU_POINTER_MESSAGE); @@ -1 +1 @@ -NVIDIA_VERSION = 310.44 +NVIDIA_VERSION = 310.51 |