1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
7 Copyright 2013 Kay Sievers
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include <sys/statfs.h>
43 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
44 #define streq(a,b) (strcmp((a),(b)) == 0)
46 static inline bool streq_ptr(const char *a, const char *b) {
54 static inline bool isempty(const char *p) {
58 static inline const char *strna(const char *s) {
59 return isempty(s) ? "n/a" : s;
62 static int uuid_parse(const char *s, uint8_t uuid[16]) {
66 if (sscanf(s, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
67 &u[0], &u[1], &u[2], &u[3], &u[4], &u[5], &u[6], &u[7],
68 &u[8], &u[9], &u[10], &u[11], &u[12], &u[13], &u[14], &u[15]) != 16)
71 for (i = 0; i < 16; i++)
77 static int verify_esp(const char *p, uint32_t *part, uint64_t *pstart, uint64_t *psize, uint8_t uuid[16]) {
85 if (statfs(p, &sfs) < 0) {
86 fprintf(stderr, "Failed to check file system type of %s: %m\n", p);
90 if (sfs.f_type != 0x4d44) {
91 fprintf(stderr, "File system %s is not a FAT EFI System Partition (ESP) file system.\n", p);
95 if (stat(p, &st) < 0) {
96 fprintf(stderr, "Failed to determine block device node of %s: %m\n", p);
100 if (major(st.st_dev) == 0) {
101 fprintf(stderr, "Block device node of %p is invalid.\n", p);
105 r = asprintf(&t, "%s/..", p);
107 fprintf(stderr, "Out of memory.\n");
114 fprintf(stderr, "Failed to determine block device node of parent of %s: %m\n", p);
118 if (st.st_dev == st2.st_dev) {
119 fprintf(stderr, "Directory %s is not the root of the EFI System Partition (ESP) file system.\n", p);
123 r = asprintf(&t, "/dev/block/%u:%u", major(st.st_dev), minor(st.st_dev));
125 fprintf(stderr, "Out of memory.\n");
130 b = blkid_new_probe_from_filename(t);
134 fprintf(stderr, "Failed to open file system %s: %m\n", p);
138 fprintf(stderr, "Out of memory.\n");
142 blkid_probe_enable_superblocks(b, 1);
143 blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
144 blkid_probe_enable_partitions(b, 1);
145 blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
148 r = blkid_do_safeprobe(b);
150 fprintf(stderr, "File system %s is ambigious.\n", p);
154 fprintf(stderr, "File system %s does not contain a label.\n", p);
158 r = errno ? -errno : -EIO;
159 fprintf(stderr, "Failed to probe file system %s: %s\n", p, strerror(-r));
164 r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
166 r = errno ? -errno : -EIO;
167 fprintf(stderr, "Failed to probe file system type %s: %s\n", p, strerror(-r));
171 if (strcmp(v, "vfat") != 0) {
172 fprintf(stderr, "File system %s is not a FAT EFI System Partition (ESP) file system after all.\n", p);
178 r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
180 r = errno ? -errno : -EIO;
181 fprintf(stderr, "Failed to probe partition scheme %s: %s\n", p, strerror(-r));
185 if (strcmp(v, "gpt") != 0) {
186 fprintf(stderr, "File system %s is not on a GPT partition table.\n", p);
192 r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
194 r = errno ? -errno : -EIO;
195 fprintf(stderr, "Failed to probe partition type UUID %s: %s\n", p, strerror(-r));
199 if (strcmp(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b") != 0) {
201 fprintf(stderr, "File system %s is not an EFI System Partition (ESP).\n", p);
206 r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
208 r = errno ? -errno : -EIO;
209 fprintf(stderr, "Failed to probe partition entry UUID %s: %s\n", p, strerror(-r));
215 r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
217 r = errno ? -errno : -EIO;
218 fprintf(stderr, "Failed to probe partition number %s: %s\n", p, strerror(-r));
221 *part = strtoul(v, NULL, 10);
224 r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
226 r = errno ? -errno : -EIO;
227 fprintf(stderr, "Failed to probe partition offset %s: %s\n", p, strerror(-r));
230 *pstart = strtoul(v, NULL, 10);
233 r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
235 r = errno ? -errno : -EIO;
236 fprintf(stderr, "Failed to probe partition size %s: %s\n", p, strerror(-r));
239 *psize = strtoul(v, NULL, 10);
249 /* search for "#### LoaderInfo: gummiboot 31 ####" string inside the binary */
250 static int get_file_version(FILE *f, char **v) {
260 if (fstat(fileno(f), &st) < 0)
266 buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fileno(f), 0);
267 if (buf == MAP_FAILED)
270 s = memmem(buf, st.st_size - 8, "#### LoaderInfo: ", 17);
275 e = memmem(s, st.st_size - (s - buf), " ####", 5);
276 if (!e || e - s < 3) {
277 fprintf(stderr, "Malformed version string.\n");
282 x = strndup(s, e - s);
284 fprintf(stderr, "Out of memory.\n");
291 munmap(buf, st.st_size);
296 static int enumerate_binaries(const char *esp_path, const char *path, const char *prefix) {
298 char *p = NULL, *q = NULL;
302 if (asprintf(&p, "%s/%s", esp_path, path) < 0) {
303 fprintf(stderr, "Out of memory.\n");
310 if (errno == ENOENT) {
315 fprintf(stderr, "Failed to read %s: %m\n", p);
320 while ((de = readdir(d))) {
325 if (de->d_name[0] == '.')
328 n = strlen(de->d_name);
329 if (n < 4 || strcasecmp(de->d_name + n - 4, ".efi") != 0)
332 if (prefix && strncasecmp(de->d_name, prefix, strlen(prefix)) != 0)
337 if (asprintf(&q, "%s/%s/%s", esp_path, path, de->d_name) < 0) {
338 fprintf(stderr, "Out of memory.\n");
345 fprintf(stderr, "Failed to open %s for reading: %m\n", q);
350 r = get_file_version(f, &v);
357 printf(" %s (Unknown product and version)\n", q);
359 printf(" %s (%s)\n", q, v);
378 static int status_binaries(const char *esp_path) {
381 printf("Boot loader binaries found in ESP:\n");
383 r = enumerate_binaries(esp_path, "EFI/gummiboot", NULL);
385 fprintf(stderr, "Gummiboot not installed in ESP.\n");
389 r = enumerate_binaries(esp_path, "EFI/BOOT", "BOOT");
391 fprintf(stderr, "No default/fallback boot loader installed in ESP.\n");
399 static int print_efi_option(uint16_t id) {
402 uint8_t partition[16];
405 r = efi_get_boot_option(id, &title, partition, &path);
407 fprintf(stderr, "Failed to read EFI boot entry Boot%04X: %s.\n", id, strerror(-r));
411 printf(" Title: %s\n", strna(title));
412 printf(" Number: %04X\n", id);
414 printf(" Binary: %s\n", path);
415 printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
416 partition[0], partition[1], partition[2], partition[3], partition[4], partition[5], partition[6], partition[7],
417 partition[8], partition[9], partition[10], partition[11], partition[12], partition[13], partition[14], partition[15]);
427 static int status_variables(void) {
429 int n_options, n_order;
430 uint16_t *options = NULL, *order = NULL;
433 if (!is_efi_boot()) {
434 fprintf(stderr, "Not booted with EFI, not showing EFI variables.\n");
438 r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareType", &s);
443 printf("Firmware Information:\n");
445 efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &s2);
446 printf(" Firmware: %s (%s)\n", s, s2);
450 r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &s);
453 printf(" Loader: %s\n", s);
457 flag = is_efi_secure_boot();
459 printf(" Secure Boot: %s\n", flag ? "enabled" : "disabled");
461 flag = is_efi_secure_boot_setup_mode();
463 printf(" Setup Mode: %s\n", flag ? "setup" : "user");
468 printf("Boot entries found in EFI variables:\n");
469 n_options = efi_get_boot_options(&options);
471 if (n_options == -ENOENT)
472 fprintf(stderr, "Failed to access EFI variables, "
473 "efivarfs needs to be available at /sys/firmware/efi/efivars/.\n");
475 fprintf(stderr, "Failed to read EFI boot entries: %s\n", strerror(-n_options));
480 n_order = efi_get_boot_order(&order);
481 if (n_order == -ENOENT) {
482 fprintf(stderr, "No boot entries registered in EFI variables.\n");
485 } else if (n_order < 0) {
486 fprintf(stderr, "Failed to read EFI boot order.\n");
491 for (i = 0; i < n_order; i++)
492 print_efi_option(order[i]);
494 printf("Inactive boot entries found in EFI variables:\n");
495 for (i = 0; i < n_options; i++) {
499 for (j = 0; j < n_order; j++)
500 if (options[i] == order[j]) {
508 print_efi_option(options[i]);
519 static int compare_product(const char *a, const char *b) {
528 return x < y ? -1 : x > y ? 1 : 0;
530 return strncmp(a, b, x);
533 static int compare_version(const char *a, const char *b) {
537 a += strcspn(a, " ");
539 b += strcspn(b, " ");
542 return strverscmp(a, b);
545 static int version_check(FILE *f, const char *from, const char *to) {
547 char *a = NULL, *b = NULL;
554 r = get_file_version(f, &a);
559 fprintf(stderr, "Source file %s does not carry version information!\n", from);
565 if (errno == ENOENT) {
571 fprintf(stderr, "Failed to open %s for reading: %m\n", to);
575 r = get_file_version(g, &b);
578 if (r == 0 || compare_product(a, b) != 0) {
580 fprintf(stderr, "Skipping %s, since it's owned by another boot loader.\n", to);
584 if (compare_version(a, b) < 0) {
586 fprintf(stderr, "Skipping %s, since it's a newer boot loader version already.\n", to);
600 static int copy_file(const char *from, const char *to, bool force) {
601 FILE *f = NULL, *g = NULL;
604 struct timespec t[2];
610 f = fopen(from, "re");
612 fprintf(stderr, "Failed to open %s for reading: %m\n", from);
617 /* If this is an update, then let's compare versions first */
618 r = version_check(f, from, to);
623 if (asprintf(&p, "%s~", to) < 0) {
624 fprintf(stderr, "Out of memory.\n");
631 /* Directory doesn't exist yet? Then let's skip this... */
632 if (!force && errno == ENOENT) {
637 fprintf(stderr, "Failed to open %s for writing: %m\n", to);
645 uint8_t buf[32*1024];
647 k = fread(buf, 1, sizeof(buf), f);
649 fprintf(stderr, "Failed to read %s: %m\n", from);
656 fwrite(buf, 1, k, g);
658 fprintf(stderr, "Failed to write %s: %m\n", to);
666 fprintf(stderr, "Failed to write %s: %m\n", to);
671 r = fstat(fileno(f), &st);
673 fprintf(stderr, "Failed to get file timestamps of %s: %m", from);
681 r = futimens(fileno(g), t);
683 fprintf(stderr, "Failed to change file timestamps for %s: %m", p);
688 if (rename(p, to) < 0) {
689 fprintf(stderr, "Failed to rename %s to %s: %m\n", p, to);
694 fprintf(stderr, "Copied %s to %s.\n", from, to);
712 static char* strupper(char *s) {
721 static int mkdir_one(const char *prefix, const char *suffix) {
724 if (asprintf(&p, "%s/%s", prefix, suffix) < 0) {
725 fprintf(stderr, "Out of memory.\n");
729 if (mkdir(p, 0700) < 0) {
730 if (errno != EEXIST) {
731 fprintf(stderr, "Failed to create %s: %m\n", p);
736 fprintf(stderr, "Created %s.\n", p);
742 static int create_dirs(const char *esp_path) {
745 r = mkdir_one(esp_path, "EFI");
749 r = mkdir_one(esp_path, "EFI/gummiboot");
753 r = mkdir_one(esp_path, "EFI/BOOT");
757 r = mkdir_one(esp_path, "loader");
761 r = mkdir_one(esp_path, "loader/entries");
768 static int copy_one_file(const char *esp_path, const char *name, bool force) {
769 char *p = NULL, *q = NULL, *v = NULL;
772 if (asprintf(&p, GUMMIBOOTLIBDIR "/%s", name) < 0) {
773 fprintf(stderr, "Out of memory.\n");
778 if (asprintf(&q, "%s/EFI/gummiboot/%s", esp_path, name) < 0) {
779 fprintf(stderr, "Out of memory.\n");
784 r = copy_file(p, q, force);
786 if (strncmp(name, "gummiboot", 9) == 0) {
789 /* Create the EFI default boot loader name (specified for removable devices) */
790 if (asprintf(&v, "%s/EFI/BOOT/%s", esp_path, name + 5) < 0) {
791 fprintf(stderr, "Out of memory.\n");
795 strupper(strrchr(v, '/') + 1);
797 k = copy_file(p, v, force);
798 if (k < 0 && r == 0) {
811 static int install_binaries(const char *esp_path, bool force) {
817 /* Don't create any of these directories when we are
818 * just updating. When we update we'll drop-in our
819 * files (unless there are newer ones already), but we
820 * won't create the directories for them in the first
822 r = create_dirs(esp_path);
827 d = opendir(GUMMIBOOTLIBDIR);
829 fprintf(stderr, "Failed to open "GUMMIBOOTLIBDIR": %m\n");
833 while ((de = readdir(d))) {
837 if (de->d_name[0] == '.')
840 n = strlen(de->d_name);
841 if (n < 4 || strcmp(de->d_name + n - 4, ".efi") != 0)
844 k = copy_one_file(esp_path, de->d_name, force);
853 static bool same_entry(uint16_t id, const uint8_t uuid[16], const char *path) {
859 err = efi_get_boot_option(id, NULL, ouuid, &opath);
862 if (memcmp(uuid, ouuid, 16) != 0)
865 if (!streq_ptr(path, opath))
875 static int find_slot(const uint8_t uuid[16], const char *path, uint16_t *id) {
876 uint16_t *options = NULL;
880 bool existing = false;
882 n_options = efi_get_boot_options(&options);
886 /* find already existing gummiboot entry */
887 for (i = 0; i < n_options; i++)
888 if (same_entry(options[i], uuid, path)) {
894 /* find free slot in the sorted BootXXXX variable list */
895 for (i = 0; i < n_options; i++)
896 if (i != options[i]) {
907 static int insert_into_order(uint16_t slot, bool first) {
908 uint16_t *order = NULL;
914 n_order = efi_get_boot_order(&order);
916 /* no entry, add us */
917 err = efi_set_boot_order(&slot, 1);
921 /* are we the first and only one? */
922 if (n_order == 1 && order[0] == slot)
925 /* are we already in the boot order? */
926 for (i = 0; i < n_order; i++) {
927 if (order[i] != slot)
930 /* we do not require to be the first one, all is fine */
934 /* move us to the first slot */
935 memmove(&order[1], order, i * sizeof(uint16_t));
937 efi_set_boot_order(order, n_order);
942 new_order = realloc(order, (n_order+1) * sizeof(uint16_t));
949 /* add us to the top or end of the list */
951 memmove(&order[1], order, n_order * sizeof(uint16_t));
954 order[n_order] = slot;
956 efi_set_boot_order(order, n_order+1);
963 static int remove_from_order(uint16_t slot) {
964 uint16_t *order = NULL;
969 n_order = efi_get_boot_order(&order);
975 for (i = 0; i < n_order; i++) {
976 if (order[i] != slot)
980 memmove(&order[i], &order[i+1], (n_order - i) * sizeof(uint16_t));
981 efi_set_boot_order(order, n_order-1);
989 static int install_variables(const char *esp_path,
990 uint32_t part, uint64_t pstart, uint64_t psize,
991 const uint8_t uuid[16], const char *path,
994 uint16_t *options = NULL;
998 if (!is_efi_boot()) {
999 fprintf(stderr, "Not booted with EFI, skipping EFI variable setup.\n");
1003 if (asprintf(&p, "%s%s", esp_path, path) < 0) {
1004 fprintf(stderr, "Out of memory.\n");
1008 if (access(p, F_OK) < 0) {
1009 if (errno == ENOENT)
1016 r = find_slot(uuid, path, &slot);
1019 fprintf(stderr, "Failed to access EFI variables. Is the \"efivarfs\" filesystem mounted?\n");
1021 fprintf(stderr, "Failed to determine current boot order: %s\n", strerror(-r));
1025 if (first || r == false) {
1026 r = efi_add_boot_option(slot, "Linux Boot Manager",
1027 part, pstart, psize,
1030 fprintf(stderr, "Failed to create EFI Boot variable entry: %s\n", strerror(-r));
1033 fprintf(stderr, "Created EFI boot entry \"Linux Boot Manager\".\n");
1036 insert_into_order(slot, first);
1044 static int delete_nftw(const char *path, const struct stat *sb, int typeflag, struct FTW *ftw) {
1047 if (typeflag == FTW_D || typeflag == FTW_DNR || typeflag == FTW_DP)
1053 fprintf(stderr, "Failed to remove %s: %m\n", path);
1055 fprintf(stderr, "Removed %s.\n", path);
1060 static int rm_rf(const char *p) {
1061 nftw(p, delete_nftw, 20, FTW_DEPTH|FTW_MOUNT|FTW_PHYS);
1065 static int remove_boot_efi(const char *esp_path) {
1067 char *p = NULL, *q = NULL;
1071 if (asprintf(&p, "%s/EFI/BOOT", esp_path) < 0) {
1072 fprintf(stderr, "Out of memory.\n");
1078 if (errno == ENOENT) {
1083 fprintf(stderr, "Failed to read %s: %m\n", p);
1088 while ((de = readdir(d))) {
1093 if (de->d_name[0] == '.')
1096 n = strlen(de->d_name);
1097 if (n < 4 || strcasecmp(de->d_name + n - 4, ".EFI") != 0)
1100 if (strncasecmp(de->d_name, "BOOT", 4) != 0)
1105 if (asprintf(&q, "%s/%s", p, de->d_name) < 0) {
1106 fprintf(stderr, "Out of memory.\n");
1113 fprintf(stderr, "Failed to open %s for reading: %m\n", q);
1118 r = get_file_version(f, &v);
1124 if (r > 0 && strncmp(v, "gummiboot ", 10) == 0) {
1128 fprintf(stderr, "Failed to remove %s: %m\n", q);
1133 fprintf(stderr, "Removed %s.\n", q);
1151 static int rmdir_one(const char *prefix, const char *suffix) {
1154 if (asprintf(&p, "%s/%s", prefix, suffix) < 0) {
1155 fprintf(stderr, "Out of memory.\n");
1160 if (errno != ENOENT && errno != ENOTEMPTY) {
1161 fprintf(stderr, "Failed to remove %s: %m\n", p);
1166 fprintf(stderr, "Removed %s.\n", p);
1173 static int remove_binaries(const char *esp_path) {
1177 if (asprintf(&p, "%s/EFI/gummiboot", esp_path) < 0) {
1178 fprintf(stderr, "Out of memory.\n");
1185 q = remove_boot_efi(esp_path);
1186 if (q < 0 && r == 0)
1189 q = rmdir_one(esp_path, "loader/entries");
1190 if (q < 0 && r == 0)
1193 q = rmdir_one(esp_path, "loader");
1194 if (q < 0 && r == 0)
1197 q = rmdir_one(esp_path, "EFI/BOOT");
1198 if (q < 0 && r == 0)
1201 q = rmdir_one(esp_path, "EFI/gummiboot");
1202 if (q < 0 && r == 0)
1205 q = rmdir_one(esp_path, "EFI");
1206 if (q < 0 && r == 0)
1212 static int remove_variables(const uint8_t uuid[16], const char *path, bool in_order) {
1219 r = find_slot(uuid, path, &slot);
1223 r = efi_remove_boot_option(slot);
1228 remove_from_order(slot);
1233 static int install_loader_config(const char *esp_path) {
1236 char *vendor = NULL;
1239 f = fopen("/etc/machine-id", "re");
1243 if (fgets(line, sizeof(line), f) != NULL) {
1246 s = strchr(line, '\n');
1249 if (strlen(line) == 32)
1258 if (asprintf(&p, "%s/%s", esp_path, "loader/loader.conf") < 0) {
1259 fprintf(stderr, "Out of memory.\n");
1263 f = fopen(p, "wxe");
1265 fprintf(f, "#timeout 3\n");
1266 fprintf(f, "default %s-*\n", vendor);
1274 static int help(void) {
1275 printf("%s [COMMAND] [OPTIONS...]\n"
1277 "Install, update or remove the Gummiboot EFI boot loader.\n\n"
1278 " -h --help Show this help\n"
1279 " --version Print version\n"
1280 " --path=PATH Path to the EFI System Partition (ESP)\n"
1281 " --no-variables Don't touch EFI variables\n"
1284 " status Show status of installed Gummiboot and EFI variables\n"
1285 " install Install Gummiboot to the ESP and EFI variables\n"
1286 " update Update Gummiboot in the ESP and EFI variables\n"
1287 " remove Remove Gummiboot from the ESP and EFI variables\n",
1288 program_invocation_short_name);
1293 static const char *arg_path = NULL;
1294 static bool arg_touch_variables = true;
1296 static int parse_argv(int argc, char *argv[]) {
1303 static const struct option options[] = {
1304 { "help", no_argument, NULL, 'h' },
1305 { "version", no_argument, NULL, ARG_VERSION },
1306 { "path", required_argument, NULL, ARG_PATH },
1307 { "no-variables", no_argument, NULL, ARG_NO_VARIABLES },
1308 { NULL, 0, NULL, 0 }
1316 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
1324 printf(VERSION "\n");
1331 case ARG_NO_VARIABLES:
1332 arg_touch_variables = false;
1339 fprintf(stderr, "Unknown option code '%c'.\n", c);
1347 int main(int argc, char*argv[]) {
1353 } arg_action = ACTION_STATUS;
1355 static const struct {
1359 { "status", ACTION_STATUS },
1360 { "install", ACTION_INSTALL },
1361 { "update", ACTION_UPDATE },
1362 { "remove", ACTION_REMOVE },
1365 uint8_t uuid[16] = "";
1367 uint64_t pstart = 0;
1373 r = parse_argv(argc, argv);
1378 for (i = 0; i < ELEMENTSOF(verbs); i++) {
1379 if (!streq(argv[optind], verbs[i].verb))
1381 arg_action = verbs[i].action;
1384 if (i >= ELEMENTSOF(verbs)) {
1385 fprintf(stderr, "Unknown operation %s\n", argv[optind]);
1394 if (geteuid() != 0) {
1395 fprintf(stderr, "Need to be root.\n");
1400 r = verify_esp(arg_path, &part, &pstart, &psize, uuid);
1401 if (r == -ENODEV && !arg_path)
1402 fprintf(stderr, "You might want to use --path= to indicate the path to your ESP, in case it is not mounted to /boot.\n");
1406 switch (arg_action) {
1408 r = status_binaries(arg_path);
1412 if (arg_touch_variables)
1413 r = status_variables();
1416 case ACTION_INSTALL:
1420 r = install_binaries(arg_path, arg_action == ACTION_INSTALL);
1424 if (arg_action == ACTION_INSTALL)
1425 install_loader_config(arg_path);
1427 if (arg_touch_variables)
1428 r = install_variables(arg_path,
1429 part, pstart, psize, uuid,
1430 "/EFI/gummiboot/gummiboot" MACHINE_TYPE_NAME ".efi",
1431 arg_action == ACTION_INSTALL);
1435 r = remove_binaries(arg_path);
1437 if (arg_touch_variables) {
1438 q = remove_variables(uuid, "/EFI/gummiboot/gummiboot" MACHINE_TYPE_NAME ".efi", true);
1439 if (q < 0 && r == 0)
1446 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;