diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-03-05 22:26:10 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-03-06 04:00:41 +0100 |
commit | e48fdd84432bbf9c2ecc339183258c7c33116032 (patch) | |
tree | f4726a824d9a497accf80489a3df50b09ece0af0 /src/gpt-auto-generator/gpt-auto-generator.c | |
parent | 848e3e24b00a61130f20226ef5f051433d478c69 (diff) |
generators: rework mount generators
- Add support for finding and mounting /srv based on GPT data, similar
to how we already handly /home.
- Share the fsck logic between GPT, EFI and fstab generators
- Make sure we never run the EFI generator inside containers
- Drop DefaultDependencies=no from EFI mount units
- Other fixes
Diffstat (limited to 'src/gpt-auto-generator/gpt-auto-generator.c')
-rw-r--r-- | src/gpt-auto-generator/gpt-auto-generator.c | 155 |
1 files changed, 90 insertions, 65 deletions
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 05934da82f..f34cd030c2 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); @@ -152,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); @@ -179,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)) { @@ -222,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(); @@ -236,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); @@ -266,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; @@ -298,8 +299,7 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { /* skip child devices which are not detected properly */ if (r == -EBADSLT) continue; - log_error("Failed to verify GPT partition %s: %s", - node, strerror(-r)); + log_error("Failed to verify GPT partition %s: %s", node, strerror(-r)); return r; } if (r == 0) @@ -307,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; } @@ -384,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) { @@ -392,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)) @@ -423,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) @@ -445,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); @@ -480,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; } |