~smoser/ubuntu/quantal/module-init-tools/lp-1115710

« back to all changes in this revision

Viewing changes to modprobe.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft
  • Date: 2011-06-08 11:53:21 UTC
  • mfrom: (0.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110608115321-2zwtf5l3mbbz1sck
Tags: 3.13-1ubuntu1
* Manual Resync with Debian version 3.13-1.
  - Remaining changes:
    + Ubuntu specific control scripts carrying upgrade quirks
    + Ubuntu specific modprobe.d/depmod.d contents
    + debian/patches/ubuntu-maps_by_default -- Reenable map files
    + debian/patches/ubuntu-modinfo-wantparm-uninitialised -- fix
      performance issue due to unitialised variable in modinfo
    + switch source to 'unapply-patches' to simplify merging with
      debian upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
 
50
50
#include "testing.h"
51
51
 
52
 
int use_binary_indexes = 1; /* default to enabled. */
 
52
static int use_binary_indexes = 1; /* default to enabled. */
53
53
 
54
54
/* Limit do_softdep/do_modprobe recursion.
55
55
 * This is a simple way to handle dependency loops
56
56
 * caused by poorly written softdep commands.
57
57
 */
58
58
static int recursion_depth = 0;
59
 
const int MAX_RECURSION = 50; /* Arbitrary choice */
 
59
static const int MAX_RECURSION = 50; /* Arbitrary choice */
60
60
 
61
61
extern long init_module(void *, unsigned long, const char *);
62
62
extern long delete_module(const char *, unsigned int);
451
451
find_blacklist(const char *modname, const struct module_blacklist *blacklist)
452
452
{
453
453
        while (blacklist) {
454
 
                if (streq(blacklist->modulename, modname))
 
454
                if (streq(blacklist->modulename, modname)) {
 
455
                        warn("Not loading blacklisted module %s\n", modname);
455
456
                        return 1;
 
457
                }
456
458
                blacklist = blacklist->next;
457
459
        }
458
460
        return 0;
709
711
        return module_in_procfs(modname, usecount);
710
712
}
711
713
 
712
 
void dump_modversions(const char *filename, errfn_t error)
 
714
static void dump_modversions(const char *filename, errfn_t error)
713
715
{
714
716
        struct elf_file *module;
715
717
 
789
791
        return strsep(string, delim);
790
792
}
791
793
 
792
 
static int parse_config_scan(const char *filename,
793
 
                             struct modprobe_conf *conf,
 
794
static int parse_config_scan(struct modprobe_conf *conf,
794
795
                             int dump_only,
795
 
                             int removing);
 
796
                             int removing, ...);
796
797
 
797
798
static int parse_config_file(const char *filename,
798
799
                            struct modprobe_conf *conf,
847
848
                                warn("\"include /etc/modprobe.d\" is "
848
849
                                     "the default, ignored\n");
849
850
                        } else {
850
 
                                if (!parse_config_scan(newfilename,
851
 
                                                       &newconf, dump_only,
852
 
                                                       removing))
 
851
                                if (!parse_config_scan(&newconf, dump_only,
 
852
                                                       removing, newfilename,
 
853
                                                       NULL))
853
854
                                        warn("Failed to open included"
854
855
                                              " config file %s: %s\n",
855
856
                                              newfilename, strerror(errno));
1044
1045
        return 1;
1045
1046
}
1046
1047
 
1047
 
static int parse_config_scan(const char *filename,
1048
 
                             struct modprobe_conf *conf,
 
1048
static int parse_config_scan(struct modprobe_conf *conf,
1049
1049
                             int dump_only,
1050
 
                             int removing)
 
1050
                             int removing, ...)
1051
1051
{
 
1052
        va_list filelist;
 
1053
        char *filename;
1052
1054
        DIR *dir;
 
1055
        struct file_entry {
 
1056
                struct list_head node;
 
1057
                char *name;
 
1058
                char *path;
 
1059
        };
 
1060
        struct file_entry *fe, *fe_tmp;
 
1061
        LIST_HEAD(files_list);
1053
1062
        int ret = 0;
1054
1063
 
1055
 
        dir = opendir(filename);
1056
 
        if (dir) {
1057
 
                struct file_entry {
1058
 
                        struct list_head node;
1059
 
                        char name[];
1060
 
                };
1061
 
                LIST_HEAD(files_list);
1062
 
                struct file_entry *fe, *fe_tmp;
1063
 
                struct dirent *i;
1064
 
 
1065
 
                /* sort files from directory into list */
1066
 
                while ((i = readdir(dir)) != NULL) {
1067
 
                        size_t len;
1068
 
 
1069
 
                        if (i->d_name[0] == '.')
1070
 
                                continue;
1071
 
                        if (!config_filter(i->d_name))
1072
 
                                continue;
1073
 
 
1074
 
                        len = strlen(i->d_name);
1075
 
                        if (len < 6 ||
1076
 
                            (strcmp(&i->d_name[len-5], ".conf") != 0 &&
1077
 
                             strcmp(&i->d_name[len-6], ".alias") != 0))
1078
 
                                warn("All config files need .conf: %s/%s, "
1079
 
                                     "it will be ignored in a future release.\n",
1080
 
                                     filename, i->d_name);
1081
 
                        fe = malloc(sizeof(struct file_entry) + len + 1);
1082
 
                        if (fe == NULL)
1083
 
                                continue;
1084
 
                        strcpy(fe->name, i->d_name);
1085
 
                        list_for_each_entry(fe_tmp, &files_list, node)
1086
 
                                if (strcmp(fe_tmp->name, fe->name) >= 0)
1087
 
                                        break;
1088
 
                        list_add_tail(&fe->node, &fe_tmp->node);
1089
 
                }
1090
 
                closedir(dir);
1091
 
 
1092
 
                /* parse list of files */
1093
 
                list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
1094
 
                        char *cfgfile;
1095
 
 
1096
 
                        nofail_asprintf(&cfgfile, "%s/%s", filename, fe->name);
1097
 
                        if (!parse_config_file(cfgfile, conf,
1098
 
                                               dump_only, removing))
1099
 
                                warn("Failed to open config file "
1100
 
                                     "%s: %s\n", fe->name, strerror(errno));
1101
 
                        free(cfgfile);
1102
 
                        list_del(&fe->node);
1103
 
                        free(fe);
1104
 
                }
1105
 
 
1106
 
                ret = 1;
1107
 
        } else {
1108
 
                if (parse_config_file(filename, conf, dump_only, removing))
 
1064
        va_start(filelist, removing);
 
1065
 
 
1066
        while ((filename = va_arg(filelist, char*))) {
 
1067
                dir = opendir(filename);
 
1068
                if (dir) {
 
1069
                        struct dirent *i;
 
1070
 
 
1071
                        /* sort files from directories into list, ignoring duplicates */
 
1072
                        while ((i = readdir(dir)) != NULL) {
 
1073
                                size_t len;
 
1074
                                int cmp = -1;
 
1075
 
 
1076
                                if (i->d_name[0] == '.')
 
1077
                                        continue;
 
1078
                                if (!config_filter(i->d_name))
 
1079
                                        continue;
 
1080
 
 
1081
                                len = strlen(i->d_name);
 
1082
                                if (len < 6 ||
 
1083
                                    (strcmp(&i->d_name[len-5], ".conf") != 0 &&
 
1084
                                     strcmp(&i->d_name[len-6], ".alias") != 0))
 
1085
                                        warn("All config files need .conf: %s/%s, "
 
1086
                                             "it will be ignored in a future release.\n",
 
1087
                                             filename, i->d_name);
 
1088
                                fe = malloc(sizeof(struct file_entry));
 
1089
                                if (fe == NULL)
 
1090
                                        continue;
 
1091
 
 
1092
                                list_for_each_entry(fe_tmp, &files_list, node)
 
1093
                                        if ((cmp = strcmp(fe_tmp->name, i->d_name)) >= 0)
 
1094
                                                break;
 
1095
 
 
1096
                                if (cmp != 0) {
 
1097
                                        fe->name = malloc(len + 1);
 
1098
                                        fe->path = malloc(strlen(filename) + 1);
 
1099
                                        strcpy(fe->name, i->d_name);
 
1100
                                        strcpy(fe->path, filename);
 
1101
 
 
1102
                                        if (cmp < 0)
 
1103
                                                list_add_tail(&fe->node, &files_list);
 
1104
                                        else
 
1105
                                                list_add_tail(&fe->node, &fe_tmp->node);
 
1106
                                } else
 
1107
                                        info("Ignoring config file %s/%s\n", filename, i->d_name);
 
1108
 
 
1109
                        }
 
1110
                        closedir(dir);
 
1111
 
1109
1112
                        ret = 1;
1110
 
        }
 
1113
                } else {
 
1114
                        if (parse_config_file(filename, conf, dump_only, removing))
 
1115
                                ret = 1;
 
1116
                }
 
1117
        }
 
1118
 
 
1119
        /* parse list of files */
 
1120
        list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
 
1121
                char *cfgfile;
 
1122
 
 
1123
                nofail_asprintf(&cfgfile, "%s/%s", fe->path, fe->name);
 
1124
                if (!parse_config_file(cfgfile, conf,
 
1125
                                       dump_only, removing))
 
1126
                        warn("Failed to open config file %s: %s\n",
 
1127
                             cfgfile, strerror(errno));
 
1128
                free(cfgfile);
 
1129
                list_del(&fe->node);
 
1130
                free(fe->name);
 
1131
                free(fe->path);
 
1132
                free(fe);
 
1133
        }
 
1134
 
 
1135
        va_end(filelist);
1111
1136
        return ret;
1112
1137
}
1113
1138
 
1117
1142
                                  int removing)
1118
1143
{
1119
1144
        if (filename) {
1120
 
                if (!parse_config_scan(filename, conf, dump_only, removing))
 
1145
                if (!parse_config_scan(conf, dump_only, removing, filename,
 
1146
                                       NULL))
1121
1147
                        fatal("Failed to open config file %s: %s\n",
1122
1148
                              filename, strerror(errno));
1123
1149
                return;
1130
1156
                      "all config files belong into /etc/modprobe.d/.\n");
1131
1157
 
1132
1158
        /* default config */
1133
 
        parse_config_scan("/etc/modprobe.d", conf, dump_only, removing);
 
1159
        parse_config_scan(conf, dump_only, removing, "/run/modprobe.d",
 
1160
                          "/etc/modprobe.d", "/usr/local/lib/modprobe.d",
 
1161
                          "/lib/modprobe.d", NULL);
1134
1162
}
1135
1163
 
1136
1164
/* Read possible module arguments from the kernel command line. */
1137
 
static int parse_kcmdline(int dump_only, struct module_options **options)
 
1165
static int parse_kcmdline(int dump_only, struct modprobe_conf *conf)
1138
1166
{
1139
1167
        char *line;
1140
1168
        unsigned int linenum = 0;
1141
1169
        FILE *kcmdline;
 
1170
        struct module_options **options = &conf->options;
 
1171
        struct module_blacklist **blacklist = &conf->blacklist;
1142
1172
 
1143
1173
        kcmdline = fopen("/proc/cmdline", "r");
1144
1174
        if (!kcmdline)
1151
1181
                while ((arg = strsep_skipspace(&ptr, "\t ")) != NULL) {
1152
1182
                        char *sep, *modname, *opt;
1153
1183
 
 
1184
                        if (strstr(arg, "modprobe.blacklist=") != NULL) {
 
1185
                                ptr = strchr(arg,'=') + 1;
 
1186
 
 
1187
                                while ((modname = strsep(&ptr, ",")) != NULL) {
 
1188
                                        if (dump_only)
 
1189
                                                printf("blacklist %s\n", modname);
 
1190
 
 
1191
                                        *blacklist = add_blacklist(underscores(modname), *blacklist);
 
1192
                                }
 
1193
                        }
 
1194
 
1154
1195
                        sep = strchr(arg, '.');
1155
1196
                        if (sep) {
1156
1197
                                if (!strchr(sep, '='))
1272
1313
}
1273
1314
 
1274
1315
/* Forward declaration */
1275
 
int do_modprobe(const char *modname,
 
1316
static int do_modprobe(const char *modname,
1276
1317
                const char *cmdline_opts,
1277
1318
                const struct modprobe_conf *conf,
1278
1319
                const char *dirname,
1563
1604
        return 0;
1564
1605
}
1565
1606
 
1566
 
int handle_builtin_module(const char *modname,
 
1607
static int handle_builtin_module(const char *modname,
1567
1608
                          errfn_t error,
1568
1609
                          modprobe_flags_t flags)
1569
1610
{
1580
1621
        return 0;
1581
1622
}
1582
1623
 
1583
 
int do_modprobe(const char *modname,
 
1624
static int do_modprobe(const char *modname,
1584
1625
                const char *cmdline_opts,
1585
1626
                const struct modprobe_conf *conf,
1586
1627
                const char *dirname,
1670
1711
        return failed;
1671
1712
}
1672
1713
 
1673
 
static struct option options[] = { { "version", 0, NULL, 'V' },
 
1714
static const struct option options[] = { { "version", 0, NULL, 'V' },
1674
1715
                                   { "verbose", 0, NULL, 'v' },
1675
1716
                                   { "quiet", 0, NULL, 'q' },
1676
1717
                                   { "syslog", 0, NULL, 's' },
1836
1877
        parse_toplevel_config(configname, &conf, dump_config, flags & mit_remove);
1837
1878
 
1838
1879
        /* Read module options from kernel command line */
1839
 
        parse_kcmdline(dump_config, &conf.options);
 
1880
        parse_kcmdline(dump_config, &conf);
1840
1881
        
1841
1882
        if (dump_config) {
1842
1883
                char *aliasfilename, *symfilename;