diff options
author | Daniel Mack <github@zonque.org> | 2015-09-07 12:28:34 +0200 |
---|---|---|
committer | Daniel Mack <github@zonque.org> | 2015-09-07 12:28:34 +0200 |
commit | fcf554fd7a914ebced1a14d749b0ab4359b042ee (patch) | |
tree | cfbea9429eb0f72e8ab20bb409a84b3976be6cf0 /src | |
parent | f9a25b6ad551ed65786da514510cb4154eb00f59 (diff) | |
parent | 4c3e8e39ea1316863e55afa41b6431d7cef38a9c (diff) |
Merge pull request #1178 from poettering/gpt-auto-fixes
handle LUKS root partitions better in gpt-auto, plus other fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/gpt-auto-generator/gpt-auto-generator.c | 92 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 27 |
2 files changed, 97 insertions, 22 deletions
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 0a34f86be7..cf25d9847f 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -666,6 +666,7 @@ static int enumerate_partitions(dev_t devnum) { first = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(item, first) { _cleanup_udev_device_unref_ struct udev_device *q; + unsigned long long flags; const char *stype, *subnode; sd_id128_t type_id; blkid_partition pp; @@ -705,10 +706,10 @@ static int enumerate_partitions(dev_t devnum) { if (sd_id128_from_string(stype, &type_id) < 0) continue; + flags = blkid_partition_get_flags(pp); + if (sd_id128_equal(type_id, GPT_SWAP)) { - unsigned long long flags; - flags = blkid_partition_get_flags(pp); if (flags & GPT_FLAG_NO_AUTO) continue; @@ -727,6 +728,10 @@ static int enumerate_partitions(dev_t devnum) { if (boot && nr >= boot_nr) continue; + /* Note that we do not honour the "no-auto" + * flag for the ESP, as it is often unset, to + * hide it from Windows. */ + boot_nr = nr; r = free_and_strdup(&boot, subnode); @@ -734,9 +739,7 @@ static int enumerate_partitions(dev_t devnum) { return log_oom(); } else if (sd_id128_equal(type_id, GPT_HOME)) { - unsigned long long flags; - flags = blkid_partition_get_flags(pp); if (flags & GPT_FLAG_NO_AUTO) continue; @@ -752,9 +755,7 @@ static int enumerate_partitions(dev_t devnum) { return log_oom(); } else if (sd_id128_equal(type_id, GPT_SRV)) { - unsigned long long flags; - flags = blkid_partition_get_flags(pp); if (flags & GPT_FLAG_NO_AUTO) continue; @@ -799,6 +800,10 @@ static int get_block_device(const char *path, dev_t *dev) { assert(path); assert(dev); + /* Get's the block device directly backing a file system. If + * the block device is encrypted, returns the device mapper + * block device. */ + if (lstat(path, &st)) return -errno; @@ -816,6 +821,77 @@ static int get_block_device(const char *path, dev_t *dev) { return 0; } +static int get_block_device_harder(const char *path, dev_t *dev) { + _cleanup_closedir_ DIR *d = NULL; + _cleanup_free_ char *p = NULL, *t = NULL; + struct dirent *de, *found = NULL; + const char *q; + unsigned maj, min; + dev_t dt; + int r; + + assert(path); + assert(dev); + + /* Gets the backing block device for a file system, and + * handles LUKS encrypted file systems, looking for its + * immediate parent, if there is one. */ + + r = get_block_device(path, &dt); + if (r <= 0) + return r; + + if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0) + return -ENOMEM; + + d = opendir(p); + if (!d) { + if (errno == ENOENT) + goto fallback; + + return -errno; + } + + FOREACH_DIRENT_ALL(de, d, return -errno) { + + if (STR_IN_SET(de->d_name, ".", "..")) + continue; + + if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN)) + continue; + + if (found) /* Don't try to support multiple backing block devices */ + goto fallback; + + found = de; + break; + } + + if (!found) + goto fallback; + + q = strjoina(p, "/", found->d_name, "/dev"); + + r = read_one_line_file(q, &t); + if (r == -ENOENT) + goto fallback; + if (r < 0) + return r; + + if (sscanf(t, "%u:%u", &maj, &min) != 2) + return -EINVAL; + + if (maj == 0) + goto fallback; + + *dev = makedev(maj, min); + return 1; + +fallback: + *dev = dt; + return 1; +} + static int parse_proc_cmdline_item(const char *key, const char *value) { int r; @@ -883,11 +959,11 @@ static int add_mounts(void) { dev_t devno; int r; - r = get_block_device("/", &devno); + r = get_block_device_harder("/", &devno); if (r < 0) return log_error_errno(r, "Failed to determine block device of root file system: %m"); else if (r == 0) { - r = get_block_device("/usr", &devno); + r = get_block_device_harder("/usr", &devno); if (r < 0) return log_error_errno(r, "Failed to determine block device of /usr file system: %m"); else if (r == 0) { diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8d80aae182..d9523d37f2 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -535,10 +535,8 @@ static int get_unit_list( return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, &reply); - if (r < 0) { - log_error("Failed to list units: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)"); if (r < 0) @@ -605,7 +603,7 @@ static int get_unit_list_recursive( r = set_put(replies, reply); if (r < 0) { sd_bus_message_unref(reply); - return r; + return log_oom(); } if (arg_recursive) { @@ -614,7 +612,7 @@ static int get_unit_list_recursive( r = sd_get_machine_names(&machines); if (r < 0) - return r; + return log_error_errno(r, "Failed to get machine names: %m"); STRV_FOREACH(i, machines) { _cleanup_bus_flush_close_unref_ sd_bus *container = NULL; @@ -622,7 +620,7 @@ static int get_unit_list_recursive( r = sd_bus_open_system_machine(&container, *i); if (r < 0) { - log_error_errno(r, "Failed to connect to container %s: %m", *i); + log_warning_errno(r, "Failed to connect to container %s, ignoring: %m", *i); continue; } @@ -635,7 +633,7 @@ static int get_unit_list_recursive( r = set_put(replies, reply); if (r < 0) { sd_bus_message_unref(reply); - return r; + return log_oom(); } } @@ -1743,7 +1741,7 @@ static int get_machine_list( _cleanup_free_ char *hn = NULL; size_t sz = 0; char **i; - int c = 0; + int c = 0, r; hn = gethostname_malloc(); if (!hn) @@ -1761,7 +1759,10 @@ static int get_machine_list( c++; } - sd_get_machine_names(&m); + r = sd_get_machine_names(&m); + if (r < 0) + return log_error_errno(r, "Failed to get machine list: %m"); + STRV_FOREACH(i, m) { _cleanup_free_ char *class = NULL; @@ -4267,10 +4268,8 @@ static int show_one( &error, &reply, "s", ""); - if (r < 0) { - log_error("Failed to get properties: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}"); if (r < 0) |