]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect-image: introduce probe_filesystem_full() which can take file descriptor of... 24625/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 1 Oct 2022 02:02:40 +0000 (11:02 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 Oct 2022 20:09:27 +0000 (05:09 +0900)
In dissect_loop_device(), we have opened the device node. Let's reuse
the file descriptor.

src/shared/dissect-image.c
src/shared/dissect-image.h

index dc85ce9ea518bdeca34d71d94e6f976a873c532b..2989d31d3c295ec32b7136914cb9434f492e9363 100644 (file)
 /* how many times to wait for the device nodes to appear */
 #define N_DEVICE_NODE_LIST_ATTEMPTS 10
 
-int probe_filesystem(const char *node, char **ret_fstype) {
+int probe_filesystem_full(int fd, const char *path, char **ret_fstype) {
         /* Try to find device content type and return it in *ret_fstype. If nothing is found,
          * 0/NULL will be returned. -EUCLEAN will be returned for ambiguous results, and an
          * different error otherwise. */
 
 #if HAVE_BLKID
         _cleanup_(blkid_free_probep) blkid_probe b = NULL;
+        _cleanup_free_ char *path_by_fd = NULL;
+        _cleanup_close_ int fd_close = -1;
         const char *fstype;
         int r;
 
-        errno = 0;
-        b = blkid_new_probe_from_filename(node);
+        assert(fd >= 0 || path);
+        assert(ret_fstype);
+
+        if (fd < 0) {
+                fd_close = open(path, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
+                if (fd_close < 0)
+                        return -errno;
+
+                fd = fd_close;
+        }
+
+        if (!path) {
+                r = fd_get_path(fd, &path_by_fd);
+                if (r < 0)
+                        return r;
+
+                path = path_by_fd;
+        }
+
+        b = blkid_new_probe();
         if (!b)
+                return -ENOMEM;
+
+        errno = 0;
+        r = blkid_probe_set_device(b, fd, 0, 0);
+        if (r != 0)
                 return errno_or_else(ENOMEM);
 
         blkid_probe_enable_superblocks(b, 1);
@@ -98,16 +123,16 @@ int probe_filesystem(const char *node, char **ret_fstype) {
                 goto not_found;
         if (r == -2)
                 return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
-                                       "Results ambiguous for partition %s", node);
+                                       "Results ambiguous for partition %s", path);
         if (r != 0)
-                return log_debug_errno(errno_or_else(EIO), "Failed to probe partition %s: %m", node);
+                return log_debug_errno(errno_or_else(EIO), "Failed to probe partition %s: %m", path);
 
         (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
 
         if (fstype) {
                 char *t;
 
-                log_debug("Probed fstype '%s' on partition %s.", fstype, node);
+                log_debug("Probed fstype '%s' on partition %s.", fstype, path);
 
                 t = strdup(fstype);
                 if (!t)
@@ -118,7 +143,7 @@ int probe_filesystem(const char *node, char **ret_fstype) {
         }
 
 not_found:
-        log_debug("No type detected on partition %s", node);
+        log_debug("No type detected on partition %s", path);
         *ret_fstype = NULL;
         return 0;
 #else
@@ -140,8 +165,8 @@ static int dissected_image_probe_filesystem(DissectedImage *m) {
                 if (!p->found)
                         continue;
 
-                if (!p->fstype && p->node) {
-                        r = probe_filesystem(p->node, &p->fstype);
+                if (!p->fstype && p->mount_node_fd >= 0 && !p->decrypted_node) {
+                        r = probe_filesystem_full(p->mount_node_fd, p->node, &p->fstype);
                         if (r < 0 && r != -EUCLEAN)
                                 return r;
                 }
@@ -2326,8 +2351,8 @@ int dissected_image_decrypt(
                                 return r;
                 }
 
-                if (!p->decrypted_fstype && p->decrypted_node) {
-                        r = probe_filesystem(p->decrypted_node, &p->decrypted_fstype);
+                if (!p->decrypted_fstype && p->mount_node_fd >= 0 && p->decrypted_node) {
+                        r = probe_filesystem_full(p->mount_node_fd, p->decrypted_node, &p->decrypted_fstype);
                         if (r < 0 && r != -EUCLEAN)
                                 return r;
                 }
index cd0f5b6e64d1b8e15969f29049a84afaff4fb496..8007b544e7a4133b17b7284c5ab8346d7634fea6 100644 (file)
@@ -267,7 +267,10 @@ MountOptions* mount_options_free_all(MountOptions *options);
 DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
 const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator);
 
-int probe_filesystem(const char *node, char **ret_fstype);
+int probe_filesystem_full(int fd, const char *path, char **ret_fstype);
+static inline int probe_filesystem(const char *path, char **ret_fstype) {
+        return probe_filesystem_full(-1, path, ret_fstype);
+}
 int dissect_image_file(
                 const char *path,
                 const VeritySettings *verity,