mirror of
https://github.com/systemd/systemd.git
synced 2026-08-04 15:10:33 +00:00
gpt-auto: use LoopDevice object to manage whole block disk
This commit is contained in:
@@ -42,71 +42,6 @@ static bool arg_enabled = true;
|
||||
static bool arg_root_enabled = true;
|
||||
static int arg_root_rw = -1;
|
||||
|
||||
static int open_parent_block_device(dev_t devnum, int *ret_fd) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
|
||||
const char *name, *devtype, *node;
|
||||
sd_device *parent;
|
||||
dev_t pn;
|
||||
int fd, r;
|
||||
|
||||
assert(ret_fd);
|
||||
|
||||
r = sd_device_new_from_devnum(&d, 'b', devnum);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create device object for block device "DEVNUM_FORMAT_STR": %m",
|
||||
DEVNUM_FORMAT_VAL(devnum));
|
||||
|
||||
if (sd_device_get_devname(d, &name) < 0) {
|
||||
r = sd_device_get_syspath(d, &name);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Device " DEVNUM_FORMAT_STR " does not have a name, ignoring: %m",
|
||||
DEVNUM_FORMAT_VAL(devnum));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_device_get_parent(d, &parent);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Not a partitioned device, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Does it have a devtype? */
|
||||
r = sd_device_get_devtype(parent, &devtype);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(parent, r, "Parent doesn't have a device type, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is this a disk or a partition? We only care for disks... */
|
||||
if (!streq(devtype, "disk")) {
|
||||
log_device_debug(parent, "Parent isn't a raw disk, ignoring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Does it have a device node? */
|
||||
r = sd_device_get_devname(parent, &node);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(parent, r, "Parent device does not have device node, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_device_debug(d, "Root device %s.", node);
|
||||
|
||||
r = sd_device_get_devnum(parent, &pn);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(parent, r, "Parent device is not a proper block device, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = open(node, O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to open %s: %m", node);
|
||||
|
||||
*ret_fd = fd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
_cleanup_free_ char *e = NULL, *n = NULL, *d = NULL;
|
||||
@@ -694,27 +629,31 @@ static int add_root_mount(void) {
|
||||
}
|
||||
|
||||
static int enumerate_partitions(dev_t devnum) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
|
||||
_cleanup_free_ char *devname = NULL;
|
||||
int r, k;
|
||||
|
||||
r = open_parent_block_device(devnum, &fd);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
r = block_get_whole_disk(devnum, &devnum);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get whole block device for " DEVNUM_FORMAT_STR ": %m",
|
||||
DEVNUM_FORMAT_VAL(devnum));
|
||||
|
||||
r = devname_from_devnum(S_IFBLK, devnum, &devname);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get device node of " DEVNUM_FORMAT_STR ": %m",
|
||||
DEVNUM_FORMAT_VAL(devnum));
|
||||
|
||||
/* Let's take a LOCK_SH lock on the block device, in case udevd is already running. If we don't take
|
||||
* the lock, udevd might end up issuing BLKRRPART in the middle, and we don't want that, since that
|
||||
* might remove all partitions while we are operating on them. */
|
||||
if (flock(fd, LOCK_SH) < 0)
|
||||
return log_error_errno(errno, "Failed to lock root block device: %m");
|
||||
r = loop_device_open(devname, O_RDONLY, LOCK_SH, &loop);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to opne %s: %m", devname);
|
||||
|
||||
r = dissect_image(
|
||||
fd,
|
||||
NULL,
|
||||
r = dissect_loop_device(
|
||||
loop,
|
||||
NULL, NULL,
|
||||
/* diskseq= */ 0,
|
||||
UINT64_MAX,
|
||||
USEC_INFINITY,
|
||||
DISSECT_IMAGE_GPT_ONLY|
|
||||
DISSECT_IMAGE_USR_NO_ROOT,
|
||||
&m);
|
||||
|
||||
Reference in New Issue
Block a user