summaryrefslogtreecommitdiffstats
path: root/lib/loopdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/loopdev.c')
-rw-r--r--lib/loopdev.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/lib/loopdev.c b/lib/loopdev.c
index 99a093926..ac46f5312 100644
--- a/lib/loopdev.c
+++ b/lib/loopdev.c
@@ -665,6 +665,9 @@ struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc)
if (fd < 0)
return NULL;
+ /* indicate that file format support is implemented in sys-utils */
+ lc->info.lo_flags |= LO_FLAGS_FILE_FMT;
+
if (ioctl(fd, LOOP_GET_STATUS64, &lc->info) == 0) {
lc->has_info = 1;
lc->info_failed = 0;
@@ -824,6 +827,75 @@ int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type)
}
/*
+ * @file_fmt_type_str: file format type string.
+ * @file_fmt_type: returns file format type from the given file format string.
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int parse_file_fmt_type(const char *file_fmt_type_str, uint32_t *file_fmt_type)
+{
+ int rc = 0;
+
+ if (!strcmp(file_fmt_type_str, "RAW"))
+ *file_fmt_type = LO_FILE_FMT_RAW;
+ else if (!strcmp(file_fmt_type_str, "QCOW"))
+ *file_fmt_type = LO_FILE_FMT_QCOW;
+ else if (!strcmp(file_fmt_type_str, "VDI"))
+ *file_fmt_type = LO_FILE_FMT_VDI;
+ else if (!strcmp(file_fmt_type_str, "VMDK"))
+ *file_fmt_type = LO_FILE_FMT_VMDK;
+ else
+ rc = -EINVAL;
+
+ return rc;
+}
+
+/*
+ * @lc: context
+ * @file_fmt_type: returns file format type of the given device
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_get_file_fmt_type(struct loopdev_cxt *lc, uint32_t* file_fmt_type)
+{
+ struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
+ int rc = 0;
+
+ if (sysfs) {
+ /* check if file_fmt_type is accessible and supported by the kernel module */
+ char* file_fmt_str = NULL;
+ if (ul_path_read_string(sysfs, &file_fmt_str, "loop/file_fmt_type") == 0)
+ rc = parse_file_fmt_type(file_fmt_str, file_fmt_type);
+ } else
+ rc = -errno;
+
+ if (rc != 0 && loopcxt_ioctl_enabled(lc)) {
+ struct loop_info64 *lo = loopcxt_get_info(lc);
+ if (lo)
+ *file_fmt_type = lo->lo_file_fmt_type;
+ }
+
+ return 0;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns (allocated) string with file format type of the current loop device.
+ */
+char *loopcxt_get_file_fmt_type_string(struct loopdev_cxt *lc)
+{
+ struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
+ char *res = NULL;
+
+ if (sysfs)
+ ul_path_read_string(sysfs, &res, "loop/file_fmt_type");
+
+ DBG(CXT, ul_debugobj(lc, "loopcxt_get_file_fmt_type_string [%s]", res));
+ return res;
+}
+
+/*
* @lc: context
* @devno: returns crypt name
*
@@ -1124,6 +1196,23 @@ int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
/*
* @lc: context
+ * @file_fmt_type: kernel LO_FILE_FMT_{RAW,QCOW,VDI,VMDK} flags
+ *
+ * The setting is removed by loopcxt_set_device() loopcxt_next()!
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int loopcxt_set_file_fmt_type(struct loopdev_cxt *lc, uint32_t file_fmt_type) {
+ if (!lc)
+ return -EINVAL;
+ lc->info.lo_file_fmt_type = file_fmt_type;
+
+ DBG(CXT, ul_debugobj(lc, "set file_fmt_type=%u", (unsigned) file_fmt_type));
+ return 0;
+}
+
+/*
+ * @lc: context
* @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags
*
* The setting is removed by loopcxt_set_device() loopcxt_next()!
@@ -1353,6 +1442,10 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
}
do {
+ /* indicate that file format support is implemented in
+ * sys-utils */
+ lc->info.lo_flags |= LO_FLAGS_FILE_FMT;
+
err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info);
again = err && errno == EAGAIN;
if (again)
@@ -1415,6 +1508,10 @@ int loopcxt_ioctl_status(struct loopdev_cxt *lc)
DBG(SETUP, ul_debugobj(lc, "device open: OK"));
do {
+ /* indicate that file format support is implemented in
+ * sys-utils */
+ lc->info.lo_flags |= LO_FLAGS_FILE_FMT;
+
err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info);
again = err && errno == EAGAIN;
if (again)