X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fgpt-auto-generator%2Fgpt-auto-generator.c;h=f34cd030c2aad55e73c59858c68e7e27d55e008b;hp=017c35dcd6414014745169e708296ee32946527f;hb=e48fdd84432bbf9c2ecc339183258c7c33116032;hpb=96115cdfe0241ae9b4e7177cd3874c0a93d00b39 diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 017c35dcd..f34cd030c 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -40,6 +40,8 @@ #include "special.h" #include "unit-name.h" #include "virt.h" +#include "generator.h" +#include "gpt.h" /* TODO: * @@ -49,9 +51,6 @@ * */ -#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f) -#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15) - static const char *arg_dest = "/tmp"; DEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe); @@ -74,10 +73,8 @@ static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr errno = 0; r = blkid_do_safeprobe(b); - if (r == -2) - return -ENODEV; - else if (r == 1) - return -ENODEV; + if (r == -2 || r == 1) /* no result or uncertain */ + return -EBADSLT; else if (r != 0) return errno ? -errno : -EIO; @@ -154,10 +151,6 @@ static int add_swap(const char *path, const char *fstype) { fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" - "[Unit]\n" - "DefaultDependencies=no\n" - "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" - "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n" "[Swap]\n" "What=%s\n", path); @@ -181,42 +174,49 @@ static int add_swap(const char *path, const char *fstype) { return 0; } -static int add_home(const char *path, const char *fstype) { - _cleanup_free_ char *unit = NULL, *lnk = NULL, *fsck = NULL; +static int add_mount(const char *what, const char *where, const char *fstype, const char *description) { + _cleanup_free_ char *unit = NULL, *lnk = NULL, *p = NULL; _cleanup_fclose_ FILE *f = NULL; + int r; - if (dir_is_empty("/home") <= 0) + if (dir_is_empty(where) <= 0) { + log_debug("%s already populated, ignoring.", where); return 0; + } - log_debug("Adding home: %s %s", path, fstype); + log_debug("Adding %s: %s %s", where, what, fstype); - unit = strappend(arg_dest, "/home.mount"); + unit = unit_name_from_path(where, ".mount"); if (!unit) return log_oom(); - f = fopen(unit, "wxe"); + p = strjoin(arg_dest, "/", unit, NULL); + if (!p) + return log_oom(); + + f = fopen(p, "wxe"); if (!f) { log_error("Failed to create unit file %s: %m", unit); return -errno; } - fsck = unit_name_from_path_instance("systemd-fsck", path, ".service"); - if (!fsck) - return log_oom(); - fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" "[Unit]\n" - "DefaultDependencies=no\n" - "Requires=%s\n" - "After=" SPECIAL_LOCAL_FS_PRE_TARGET " %s\n" - "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" - "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n" + "Description=%s\n", + description); + + r = generator_write_fsck_deps(f, arg_dest, what, where, fstype); + if (r < 0) + return r; + + fprintf(f, + "\n" "[Mount]\n" "What=%s\n" - "Where=/home\n" + "Where=%s\n" "Type=%s\n", - fsck, fsck, path, fstype); + what, where, fstype); fflush(f); if (ferror(f)) { @@ -224,7 +224,7 @@ static int add_home(const char *path, const char *fstype) { return -errno; } - lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/home.mount", NULL); + lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/", unit, NULL); if (!lnk) return log_oom(); @@ -238,12 +238,12 @@ static int add_home(const char *path, const char *fstype) { } static int enumerate_partitions(struct udev *udev, dev_t dev) { - struct udev_device *parent = NULL; _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; _cleanup_udev_device_unref_ struct udev_device *d = NULL; + _cleanup_free_ char *home = NULL, *home_fstype = NULL, *srv = NULL, *srv_fstype = NULL; + unsigned home_nr = (unsigned) -1, srv_nr = (unsigned )-1; struct udev_list_entry *first, *item; - unsigned home_nr = (unsigned) -1; - _cleanup_free_ char *home = NULL, *home_fstype = NULL; + struct udev_device *parent = NULL; int r; e = udev_enumerate_new(udev); @@ -268,16 +268,15 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { r = udev_enumerate_scan_devices(e); if (r < 0) { - log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s", - major(dev), minor(dev), strerror(-r)); + log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s", major(dev), minor(dev), strerror(-r)); return r; } first = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(item, first) { + _cleanup_udev_device_unref_ struct udev_device *q; _cleanup_free_ char *fstype = NULL; const char *node = NULL; - _cleanup_udev_device_unref_ struct udev_device *q; sd_id128_t type_id; unsigned nr; @@ -297,8 +296,10 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { r = verify_gpt_partition(node, &type_id, &nr, &fstype); if (r < 0) { - log_error("Failed to verify GPT partition %s: %s", - node, strerror(-r)); + /* skip child devices which are not detected properly */ + if (r == -EBADSLT) + continue; + log_error("Failed to verify GPT partition %s: %s", node, strerror(-r)); return r; } if (r == 0) @@ -306,24 +307,48 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { if (sd_id128_equal(type_id, GPT_SWAP)) add_swap(node, fstype); + else if (sd_id128_equal(type_id, GPT_HOME)) { - if (!home || nr < home_nr) { - free(home); - home = strdup(node); - if (!home) - return log_oom(); - - home_nr = nr; - - free(home_fstype); - home_fstype = fstype; - fstype = NULL; - } + + /* We only care for the first /home partition */ + if (home && nr >= home_nr) + continue; + + home_nr = nr; + + free(home); + home = strdup(node); + if (!home) + return log_oom(); + + free(home_fstype); + home_fstype = fstype; + fstype = NULL; + + } else if (sd_id128_equal(type_id, GPT_SRV)) { + + /* We only care for the first /srv partition */ + if (srv && nr >= srv_nr) + continue; + + srv_nr = nr; + + free(srv); + srv = strdup(node); + if (!srv) + return log_oom(); + + free(srv_fstype); + srv_fstype = fstype; + fstype = NULL; } } if (home && home_fstype) - add_home(home, home_fstype); + add_mount(home, "/home", home_fstype, "Home Partition"); + + if (srv && srv_fstype) + add_mount(srv, "/srv", srv_fstype, "Server Data Partition"); return r; } @@ -383,7 +408,7 @@ static int get_block_device(const char *path, dev_t *dev) { assert(path); assert(dev); - if (lstat("/", &st)) + if (lstat(path, &st)) return -errno; if (major(st.st_dev) != 0) { @@ -391,7 +416,7 @@ static int get_block_device(const char *path, dev_t *dev) { return 1; } - if (statfs("/", &sfs) < 0) + if (statfs(path, &sfs) < 0) return -errno; if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) @@ -422,15 +447,14 @@ static int devno_to_devnode(struct udev *udev, dev_t devno, char **ret) { } int main(int argc, char *argv[]) { - _cleanup_free_ char *node = NULL; _cleanup_udev_unref_ struct udev *udev = NULL; + _cleanup_free_ char *node = NULL; dev_t devno; int r = 0; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); - r = -EINVAL; - goto finish; + return EXIT_FAILURE; } if (argc > 1) @@ -444,34 +468,33 @@ int main(int argc, char *argv[]) { if (in_initrd()) { log_debug("In initrd, exiting."); - goto finish; + return EXIT_SUCCESS; } if (detect_container(NULL) > 0) { log_debug("In a container, exiting."); - goto finish; + return EXIT_SUCCESS; } r = get_block_device("/", &devno); if (r < 0) { log_error("Failed to determine block device of root file system: %s", strerror(-r)); - goto finish; - } - if (r == 0) { + return EXIT_FAILURE; + } else if (r == 0) { log_debug("Root file system not on a (single) block device."); - goto finish; + return EXIT_SUCCESS; } udev = udev_new(); if (!udev) { - r = log_oom(); - goto finish; + log_oom(); + return EXIT_FAILURE; } r = devno_to_devnode(udev, devno, &node); if (r < 0) { log_error("Failed to determine block device node from major/minor: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } log_debug("Root device %s.", node); @@ -479,13 +502,16 @@ int main(int argc, char *argv[]) { r = verify_gpt_partition(node, NULL, NULL, NULL); if (r < 0) { log_error("Failed to verify GPT partition %s: %s", node, strerror(-r)); - goto finish; + return EXIT_FAILURE; + } + if (r == 0) { + log_debug("Not a GPT disk, exiting."); + return EXIT_SUCCESS; } - if (r == 0) - goto finish; r = enumerate_partitions(udev, devno); + if (r < 0) + return EXIT_FAILURE; -finish: - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return EXIT_SUCCESS; }