+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
#include <libcryptsetup.h>
+#ifndef CRYPT_LUKS
+#define CRYPT_LUKS NULL
+#endif
#endif
#include <sys/mount.h>
#include "xattr-util.h"
_unused_ static int probe_filesystem(const char *node, char **ret_fstype) {
-#ifdef HAVE_BLKID
+#if HAVE_BLKID
_cleanup_blkid_free_probe_ blkid_probe b = NULL;
const char *fstype;
int r;
errno = 0;
r = blkid_do_safeprobe(b);
- if (r == -2 || r == 1) {
+ if (IN_SET(r, -2, 1)) {
log_debug("Failed to identify any partition type on partition %s", node);
goto not_found;
}
int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret) {
-#ifdef HAVE_BLKID
+#if HAVE_BLKID
sd_id128_t root_uuid = SD_ID128_NULL, verity_uuid = SD_ID128_NULL;
_cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
bool is_gpt, is_mbr, generic_rw, multiple_generic = false;
errno = 0;
r = blkid_do_safeprobe(b);
- if (r == -2 || r == 1) {
+ if (IN_SET(r, -2, 1)) {
log_debug("Failed to identify any partition table.");
return -ENOPKG;
}
return -EIO;
}
if (n < z + 1) {
- unsigned j;
+ unsigned j = 0;
/* The kernel has probed fewer partitions than blkid? Maybe the kernel prober is still running
* or it got EBUSY because udev already opened the device. Let's reprobe the device, which is a
* synchronous call that waits until probing is complete. */
- for (j = 0; j < 20; j++) {
+ for (;;) {
+ if (j++ > 20)
+ return -EBUSY;
- r = ioctl(fd, BLKRRPART, 0);
- if (r < 0)
+ if (ioctl(fd, BLKRRPART, 0) < 0) {
r = -errno;
- if (r >= 0 || r != -EBUSY)
+
+ if (r == -EINVAL) {
+ struct loop_info64 info;
+
+ /* If we are running on a loop device that has partition scanning off,
+ * return an explicit recognizable error about this, so that callers
+ * can generate a proper message explaining the situation. */
+
+ if (ioctl(fd, LOOP_GET_STATUS64, &info) >= 0 && (info.lo_flags & LO_FLAGS_PARTSCAN) == 0) {
+ log_debug("Device is loop device and partition scanning is off!");
+ return -EPROTONOSUPPORT;
+ }
+ }
+ if (r != -EBUSY)
+ return r;
+ } else
break;
/* If something else has the device open, such as an udev rule, the ioctl will return
*
* This is really something they should fix in the kernel! */
- usleep(50 * USEC_PER_MSEC);
+ (void) usleep(50 * USEC_PER_MSEC);
}
-
- if (r < 0)
- return r;
}
e = udev_enumerate_unref(e);
if (streq_ptr(p->fstype, "crypto_LUKS"))
m->encrypted = true;
+
+ if (p->fstype && fstype_is_ro(p->fstype))
+ p->rw = false;
}
*ret = m;
p = where;
/* If requested, turn on discard support. */
- if (STR_IN_SET(fstype, "btrfs", "ext4", "vfat", "xfs") &&
+ if (fstype_can_discard(fstype) &&
((flags & DISSECT_IMAGE_DISCARD) ||
((flags & DISSECT_IMAGE_DISCARD_ON_LOOP) && is_loop_device(m->node))))
options = "discard";
return 0;
}
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
typedef struct DecryptedPartition {
struct crypt_device *device;
char *name;
#endif
DecryptedImage* decrypted_image_unref(DecryptedImage* d) {
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
size_t i;
int r;
return NULL;
}
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
static int make_dm_name_and_node(const void *original_node, const char *suffix, char **ret_name, char **ret_node) {
_cleanup_free_ char *name = NULL, *node = NULL;
r = crypt_init(&cd, m->node);
if (r < 0)
- return r;
+ return log_debug_errno(r, "Failed to initialize dm-crypt: %m");
- r = crypt_load(cd, CRYPT_LUKS1, NULL);
- if (r < 0)
+ r = crypt_load(cd, CRYPT_LUKS, NULL);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to load LUKS metadata: %m");
goto fail;
+ }
r = crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, passphrase, strlen(passphrase),
((flags & DISSECT_IMAGE_READ_ONLY) ? CRYPT_ACTIVATE_READONLY : 0) |
((flags & DISSECT_IMAGE_DISCARD_ON_CRYPTO) ? CRYPT_ACTIVATE_ALLOW_DISCARDS : 0));
+ if (r < 0)
+ log_debug_errno(r, "Failed to activate LUKS device: %m");
if (r == -EPERM) {
r = -EKEYREJECTED;
goto fail;
DecryptedImage **ret) {
_cleanup_(decrypted_image_unrefp) DecryptedImage *d = NULL;
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
unsigned i;
int r;
#endif
return 0;
}
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
if (m->encrypted && !passphrase)
return -ENOKEY;
}
}
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
static int deferred_remove(DecryptedPartition *p) {
struct dm_ioctl dm = {
int decrypted_image_relinquish(DecryptedImage *d) {
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
size_t i;
int r;
#endif
/* Turns on automatic removal after the last use ended for all DM devices of this image, and sets a boolean so
* that we don't clean it up ourselves either anymore */
-#ifdef HAVE_LIBCRYPTSETUP
+#if HAVE_LIBCRYPTSETUP
for (i = 0; i < d->n_decrypted; i++) {
DecryptedPartition *p = d->decrypted + i;