fdisk: introduce common fdisk_new_context_fd() helper

We do the same thing over and over again and it's a bit ugly, hence
let's unify the code for it at one common place.
This commit is contained in:
Lennart Poettering 2022-11-23 16:23:35 +01:00 committed by Yu Watanabe
parent f329a41be4
commit f8cf3d19d2
6 changed files with 68 additions and 44 deletions

View file

@ -2752,7 +2752,8 @@ if conf.get('ENABLE_HOMED') == 1
'systemd-homework',
systemd_homework_sources,
include_directories : includes,
link_with : [libshared],
link_with : [libshared,
libshared_fdisk],
dependencies : [threads,
libblkid,
libcrypt,
@ -3331,7 +3332,8 @@ if conf.get('ENABLE_SYSUPDATE') == 1
'systemd-sysupdate',
systemd_sysupdate_sources,
include_directories : includes,
link_with : [libshared],
link_with : [libshared,
libshared_fdisk],
dependencies : [threads,
libblkid,
libfdisk,
@ -3807,7 +3809,8 @@ if conf.get('ENABLE_REPART') == 1
'systemd-repart',
systemd_repart_sources,
include_directories : includes,
link_with : [libshared],
link_with : [libshared,
libshared_fdisk],
dependencies : [threads,
libblkid,
libfdisk,
@ -3827,7 +3830,8 @@ if conf.get('ENABLE_REPART') == 1
link_with : [libshared_static,
libbasic,
libbasic_gcrypt,
libsystemd_static],
libsystemd_static,
libshared_fdisk],
dependencies : [threads,
libblkid,
libfdisk,

View file

@ -1837,7 +1837,7 @@ static int make_partition_table(
_cleanup_(fdisk_unref_partitionp) struct fdisk_partition *p = NULL, *q = NULL;
_cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL;
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
_cleanup_free_ char *path = NULL, *disk_uuid_as_string = NULL;
_cleanup_free_ char *disk_uuid_as_string = NULL;
uint64_t offset, size, first_lba, start, last_lba, end;
sd_id128_t disk_uuid;
int r;
@ -1855,14 +1855,7 @@ static int make_partition_table(
if (r < 0)
return log_error_errno(r, "Failed to initialize partition type: %m");
c = fdisk_new_context();
if (!c)
return log_oom();
if (asprintf(&path, "/proc/self/fd/%i", fd) < 0)
return log_oom();
r = fdisk_assign_device(c, path, 0);
r = fdisk_new_context_fd(fd, /* read_only= */ false, &c);
if (r < 0)
return log_error_errno(r, "Failed to open device: %m");
@ -2645,7 +2638,7 @@ static int prepare_resize_partition(
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
_cleanup_(fdisk_unref_tablep) struct fdisk_table *t = NULL;
_cleanup_free_ char *path = NULL, *disk_uuid_as_string = NULL;
_cleanup_free_ char *disk_uuid_as_string = NULL;
struct fdisk_partition *found = NULL;
sd_id128_t disk_uuid;
size_t n_partitions;
@ -2668,14 +2661,7 @@ static int prepare_resize_partition(
return 0;
}
c = fdisk_new_context();
if (!c)
return log_oom();
if (asprintf(&path, "/proc/self/fd/%i", fd) < 0)
return log_oom();
r = fdisk_assign_device(c, path, 0);
r = fdisk_new_context_fd(fd, /* read_only= */ false, &c);
if (r < 0)
return log_error_errno(r, "Failed to open device: %m");
@ -2759,7 +2745,6 @@ static int apply_resize_partition(
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
_cleanup_free_ void *two_zero_lbas = NULL;
_cleanup_free_ char *path = NULL;
ssize_t n;
int r;
@ -2791,14 +2776,7 @@ static int apply_resize_partition(
if (n != 1024)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while wiping partition table.");
c = fdisk_new_context();
if (!c)
return log_oom();
if (asprintf(&path, "/proc/self/fd/%i", fd) < 0)
return log_oom();
r = fdisk_assign_device(c, path, 0);
r = fdisk_new_context_fd(fd, /* read_only= */ false, &c);
if (r < 0)
return log_error_errno(r, "Failed to open device: %m");

View file

@ -1945,16 +1945,17 @@ static int context_load_partition_table(
assert(context->end == UINT64_MAX);
assert(context->total == UINT64_MAX);
c = fdisk_new_context();
if (!c)
return log_oom();
/* libfdisk doesn't have an API to operate on arbitrary fds, hence reopen the fd going via the
* /proc/self/fd/ magic path if we have an existing fd. Open the original file otherwise. */
if (*backing_fd < 0)
if (*backing_fd < 0) {
c = fdisk_new_context();
if (!c)
return log_oom();
r = fdisk_assign_device(c, node, arg_dry_run);
else
r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(*backing_fd), arg_dry_run);
} else
r = fdisk_new_context_fd(*backing_fd, arg_dry_run, &c);
if (r == -EINVAL && arg_size_auto) {
struct stat st;
@ -6065,11 +6066,7 @@ static int resize_pt(int fd) {
* possession of the enlarged backing file. For this it suffices to open the device with libfdisk and
* immediately write it again, with no changes. */
c = fdisk_new_context();
if (!c)
return log_oom();
r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(fd), 0);
r = fdisk_new_context_fd(fd, /* read_only= */ false, &c);
if (r < 0)
return log_error_errno(r, "Failed to open device '%s': %m", FORMAT_PROC_FD_PATH(fd));

29
src/shared/fdisk-util.c Normal file
View file

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "fd-util.h"
#include "fdisk-util.h"
#if HAVE_LIBFDISK
int fdisk_new_context_fd(int fd, bool read_only, struct fdisk_context **ret) {
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
int r;
assert(ret);
if (fd < 0)
return -EBADF;
c = fdisk_new_context();
if (!c)
return -ENOMEM;
r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(fd), read_only);
if (r < 0)
return r;
*ret = TAKE_PTR(c);
return 0;
}
#endif

View file

@ -12,4 +12,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct fdisk_partition*, fdisk_unref_partition,
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct fdisk_parttype*, fdisk_unref_parttype, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct fdisk_table*, fdisk_unref_table, NULL);
int fdisk_new_context_fd(int fd, bool read_only, struct fdisk_context **ret);
#endif

View file

@ -125,7 +125,6 @@ shared_sources = files(
'exit-status.h',
'extension-release.c',
'extension-release.h',
'fdisk-util.h',
'fdset.c',
'fdset.h',
'fileio-label.c',
@ -493,3 +492,18 @@ libshared = shared_library(
dependencies : libshared_deps,
install : true,
install_dir : rootpkglibdir)
shared_fdisk_sources = files(
'fdisk-util.h',
'fdisk-util.c',
)
if get_option('fdisk') != 'false'
libshared_fdisk = static_library(
'shared-fdisk',
shared_fdisk_sources,
include_directories : includes,
dependencies : [libfdisk],
c_args : ['-fvisibility=default'],
build_by_default : false)
endif