1 From 83446ff328321ff05818fee1ed150f8efd4730b8 Mon Sep 17 00:00:00 2001
2 From: Colin Watson <cjwatson@ubuntu.com>
3 Date: Mon, 13 Jan 2014 12:13:10 +0000
4 Subject: Read /etc/default/grub.d/*.cfg after /etc/default/grub
6 Bug-Ubuntu: https://bugs.launchpad.net/bugs/901600
8 Last-Update: 2014-01-28
10 Patch-Name: default-grub-d.patch
12 grub-core/osdep/unix/config.c | 114 +++++++++++++++++++++++++++-------
13 util/grub-mkconfig.in | 5 ++
14 2 files changed, 98 insertions(+), 21 deletions(-)
16 diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c
17 index 65effa9f3..5478030fd 100644
18 --- a/grub-core/osdep/unix/config.c
19 +++ b/grub-core/osdep/unix/config.c
21 #include <grub/emu/config.h>
22 #include <grub/util/install.h>
23 #include <grub/util/misc.h>
24 +#include <grub/list.h>
27 #include <sys/types.h>
29 @@ -61,13 +63,27 @@ grub_util_get_localedir (void)
35 + struct cfglist *next;
36 + struct cfglist *prev;
41 grub_util_load_config (struct grub_util_config *cfg)
46 + char *script = NULL, *ptr;
47 const char *cfgfile, *iptr;
49 + grub_util_fd_dir_t d;
50 + struct cfglist *cfgpaths = NULL, *cfgpath, *next_cfgpath;
51 + int num_cfgpaths = 0;
52 + size_t len_cfgpaths = 0;
53 + char **sorted_cfgpaths = NULL;
58 @@ -83,29 +99,75 @@ grub_util_load_config (struct grub_util_config *cfg)
59 cfg->grub_distributor = xstrdup (v);
61 cfgfile = grub_util_get_config_filename ();
62 - if (!grub_util_is_regular (cfgfile))
64 + if (grub_util_is_regular (cfgfile))
67 + len_cfgpaths += strlen (cfgfile) * 4 + sizeof (". ''; ") - 1;
70 + cfgdir = xasprintf ("%s.d", cfgfile);
71 + d = grub_util_fd_opendir (cfgdir);
74 + grub_util_fd_dirent_t de;
76 + while ((de = grub_util_fd_readdir (d)))
78 + const char *ext = strrchr (de->d_name, '.');
80 + if (!ext || strcmp (ext, ".cfg") != 0)
83 + cfgpath = xmalloc (sizeof (*cfgpath));
84 + cfgpath->path = grub_util_path_concat (2, cfgdir, de->d_name);
85 + grub_list_push (GRUB_AS_LIST_P (&cfgpaths), GRUB_AS_LIST (cfgpath));
87 + len_cfgpaths += strlen (cfgpath->path) * 4 + sizeof (". ''; ") - 1;
89 + grub_util_fd_closedir (d);
92 + if (num_cfgpaths == 0)
95 + sorted_cfgpaths = xmalloc (num_cfgpaths * sizeof (*sorted_cfgpaths));
97 + if (grub_util_is_regular (cfgfile))
98 + sorted_cfgpaths[i++] = xstrdup (cfgfile);
99 + FOR_LIST_ELEMENTS_SAFE (cfgpath, next_cfgpath, cfgpaths)
101 + sorted_cfgpaths[i++] = cfgpath->path;
104 + assert (i == num_cfgpaths);
105 + qsort (sorted_cfgpaths + 1, num_cfgpaths - 1, sizeof (*sorted_cfgpaths),
106 + (int (*) (const void *, const void *)) strcmp);
111 - script = xmalloc (4 * strlen (cfgfile) + 300);
112 + script = xmalloc (len_cfgpaths + 300);
115 - memcpy (ptr, ". '", 3);
117 - for (iptr = cfgfile; *iptr; iptr++)
118 + for (i = 0; i < num_cfgpaths; i++)
121 + memcpy (ptr, ". '", 3);
123 + for (iptr = sorted_cfgpaths[i]; *iptr; iptr++)
125 - memcpy (ptr, "'\\''", 4);
130 + memcpy (ptr, "'\\''", 4);
137 + memcpy (ptr, "'; ", 3);
141 - strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" "
142 + strcpy (ptr, "printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" "
143 "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\"");
146 @@ -125,15 +187,25 @@ grub_util_load_config (struct grub_util_config *cfg)
147 waitpid (pid, NULL, 0);
153 - f = grub_util_fopen (cfgfile, "r");
155 + for (i = 0; i < num_cfgpaths; i++)
157 - grub_util_parse_config (f, cfg, 0);
159 + f = grub_util_fopen (sorted_cfgpaths[i], "r");
162 + grub_util_parse_config (f, cfg, 0);
166 + grub_util_warn (_("cannot open configuration file `%s': %s"),
167 + cfgfile, strerror (errno));
170 - grub_util_warn (_("cannot open configuration file `%s': %s"),
171 - cfgfile, strerror (errno));
175 + for (i = 0; i < num_cfgpaths; i++)
176 + free (sorted_cfgpaths[i]);
177 + free (sorted_cfgpaths);
180 diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
181 index 45cd4cc54..8a1bc0441 100644
182 --- a/util/grub-mkconfig.in
183 +++ b/util/grub-mkconfig.in
184 @@ -157,6 +157,11 @@ fi
185 if test -f ${sysconfdir}/default/grub ; then
186 . ${sysconfdir}/default/grub
188 +for x in ${sysconfdir}/default/grub.d/*.cfg ; do
189 + if [ -e "${x}" ]; then
194 # XXX: should this be deprecated at some point?
195 if [ "x${GRUB_TERMINAL}" != "x" ] ; then