[libvirt] [PATCH v3 0/5] Alter the clearing of device for new partition table

Well kind of a v2/v3 type mashup - essentially reworked the portion of the series: https://www.redhat.com/archives/libvir-list/2017-April/msg00402.html that dealt with the zeroing of the header of the device path. The changes now will allow both the head and tail of the device path to be cleared rather than just the header of the file which was ACK'd for at least the logical backend. Additionally, bump the size of the clear/zero from 2048KB to 1MB and use it for both the logical and disk backends. John Ferlan (5): storage: Modify storageBackendWipeLocal to allow zero from end of device storage: Introduce virStorageBackendZeroPartitionTable logical: Use virStorageBackendZeroPartitionTable logical: Increase the size of the data to wipe disk: Use virStorageBackendZeroPartitionTable src/storage/storage_backend_disk.c | 6 ++- src/storage/storage_backend_logical.c | 44 +--------------------- src/storage/storage_util.c | 70 ++++++++++++++++++++++++++++------- src/storage/storage_util.h | 4 ++ 4 files changed, 67 insertions(+), 57 deletions(-) -- 2.9.3

Add bool 'zero_end' and logic that would allow a caller to wipe specific portions of a target device either from the beginning (the default) or from the end when zero_end is true. This will allow for this code to wipe out partition table information from a device. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_util.c | 48 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a2d89af..c1734e7 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -2516,24 +2516,44 @@ static int storageBackendWipeLocal(const char *path, int fd, unsigned long long wipe_len, - size_t writebuf_length) + size_t writebuf_length, + bool zero_end) { int ret = -1, written = 0; unsigned long long remaining = 0; + off_t size; size_t write_size = 0; char *writebuf = NULL; - VIR_DEBUG("wiping start: 0 len: %llu", wipe_len); - if (VIR_ALLOC_N(writebuf, writebuf_length) < 0) goto cleanup; - if (lseek(fd, 0, SEEK_SET) < 0) { - virReportSystemError(errno, - _("Failed to seek to the start in volume " - "with path '%s'"), - path); - goto cleanup; + if (!zero_end) { + if (lseek(fd, 0, SEEK_SET) < 0) { + virReportSystemError(errno, + _("Failed to seek to the start in volume " + "with path '%s'"), + path); + goto cleanup; + } + VIR_DEBUG("wiping start: 0 len: %llu", wipe_len); + } else { + if ((size = lseek(fd, 0, SEEK_END)) == (off_t)-1) { + virReportSystemError(errno, + _("Failed to seek to the end in volume " + "with path '%s'"), + path); + goto cleanup; + } + size -= wipe_len; + if (lseek(fd, size, SEEK_SET) < 0) { + virReportSystemError(errno, + _("Failed to seek to %zd bytes in volume " + "with path '%s'"), + size, path); + goto cleanup; + } + VIR_DEBUG("wiping start: %zd len: %llu", size, wipe_len); } remaining = wipe_len; @@ -2573,7 +2593,8 @@ storageBackendWipeLocal(const char *path, static int storageBackendVolWipeLocalFile(const char *path, unsigned int algorithm, - unsigned long long allocation) + unsigned long long allocation, + bool zero_end) { int ret = -1, fd = -1; const char *alg_char = NULL; @@ -2648,7 +2669,8 @@ storageBackendVolWipeLocalFile(const char *path, if (S_ISREG(st.st_mode) && st.st_blocks < (st.st_size / DEV_BSIZE)) { ret = storageBackendVolZeroSparseFileLocal(path, st.st_size, fd); } else { - ret = storageBackendWipeLocal(path, fd, allocation, st.st_blksize); + ret = storageBackendWipeLocal(path, fd, allocation, st.st_blksize, + zero_end); } if (ret < 0) goto cleanup; @@ -2686,7 +2708,7 @@ storageBackendVolWipePloop(virStorageVolDefPtr vol, goto cleanup; if (storageBackendVolWipeLocalFile(target_path, algorithm, - vol->target.allocation) < 0) + vol->target.allocation, false) < 0) goto cleanup; if (virFileRemove(disk_desc, 0, 0) < 0) { @@ -2735,7 +2757,7 @@ virStorageBackendVolWipeLocal(virConnectPtr conn ATTRIBUTE_UNUSED, ret = storageBackendVolWipePloop(vol, algorithm); } else { ret = storageBackendVolWipeLocalFile(vol->target.path, algorithm, - vol->target.allocation); + vol->target.allocation, false); } return ret; -- 2.9.3

On 04/07/2017 06:30 PM, John Ferlan wrote:
Add bool 'zero_end' and logic that would allow a caller to wipe specific portions of a target device either from the beginning (the default) or from the end when zero_end is true.
This will allow for this code to wipe out partition table information from a device.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_util.c | 48 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a2d89af..c1734e7 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -2516,24 +2516,44 @@ static int storageBackendWipeLocal(const char *path, int fd, unsigned long long wipe_len, - size_t writebuf_length) + size_t writebuf_length, + bool zero_end) { int ret = -1, written = 0; unsigned long long remaining = 0; + off_t size; size_t write_size = 0; char *writebuf = NULL;
- VIR_DEBUG("wiping start: 0 len: %llu", wipe_len); - if (VIR_ALLOC_N(writebuf, writebuf_length) < 0) goto cleanup;
- if (lseek(fd, 0, SEEK_SET) < 0) { - virReportSystemError(errno, - _("Failed to seek to the start in volume " - "with path '%s'"), - path); - goto cleanup; + if (!zero_end) { + if (lseek(fd, 0, SEEK_SET) < 0) { + virReportSystemError(errno, + _("Failed to seek to the start in volume " + "with path '%s'"), + path); + goto cleanup; + } + VIR_DEBUG("wiping start: 0 len: %llu", wipe_len); + } else { + if ((size = lseek(fd, 0, SEEK_END)) == (off_t)-1) { + virReportSystemError(errno, + _("Failed to seek to the end in volume " + "with path '%s'"), + path); + goto cleanup; + } + size -= wipe_len; + if (lseek(fd, size, SEEK_SET) < 0) { + virReportSystemError(errno, + _("Failed to seek to %zd bytes in volume " + "with path '%s'"), + size, path);
Is off_t really ssize_t? I think we should typecast it.
+ goto cleanup; + }
Or, instead of these two seeks: if ((size = lseek(fd, -wipe_len, SEEK_END)) < 0) { virReportSystemError(); goto cleanup; }
+ VIR_DEBUG("wiping start: %zd len: %llu", size, wipe_len);
This DEBUG is the same as in the other body for the if statement. While it's just VIR_DEBUG I wouldn't care, but just consider the following for a moment: Move this VIR_DEBUG right after this if statement and initialize @size to zero (and obviously drop the other VIR_DEBUG with hardcoded 0). That way we know what the current position is and how long section is to be wiped. Or even better: + if (!zero_end) { + if ((size = lseek(fd, 0, SEEK_SET)) < 0) { + virReportSystemError(errno, + _("Failed to seek to the start in volume " + "with path '%s'"), + path); + goto cleanup; + } + } else { + if ((size = lseek(fd, -wipe_len, SEEK_END)) < 0) { + virReportSystemError(errno, + _("Failed to seek to %llu bytes to the end in volume " + "with path '%s'"), + wipe_len, path); + goto cleanup; + } } + VIR_DEBUG("wiping start: %zd len: %llu", (ssize_t) size, wipe_len);
}
remaining = wipe_len; @@ -2573,7 +2593,8 @@ storageBackendWipeLocal(const char *path, static int storageBackendVolWipeLocalFile(const char *path, unsigned int algorithm, - unsigned long long allocation) + unsigned long long allocation, + bool zero_end) { int ret = -1, fd = -1; const char *alg_char = NULL; @@ -2648,7 +2669,8 @@ storageBackendVolWipeLocalFile(const char *path, if (S_ISREG(st.st_mode) && st.st_blocks < (st.st_size / DEV_BSIZE)) { ret = storageBackendVolZeroSparseFileLocal(path, st.st_size, fd); } else { - ret = storageBackendWipeLocal(path, fd, allocation, st.st_blksize); + ret = storageBackendWipeLocal(path, fd, allocation, st.st_blksize, + zero_end); } if (ret < 0) goto cleanup; @@ -2686,7 +2708,7 @@ storageBackendVolWipePloop(virStorageVolDefPtr vol, goto cleanup;
if (storageBackendVolWipeLocalFile(target_path, algorithm, - vol->target.allocation) < 0) + vol->target.allocation, false) < 0) goto cleanup;
if (virFileRemove(disk_desc, 0, 0) < 0) { @@ -2735,7 +2757,7 @@ virStorageBackendVolWipeLocal(virConnectPtr conn ATTRIBUTE_UNUSED, ret = storageBackendVolWipePloop(vol, algorithm); } else { ret = storageBackendVolWipeLocalFile(vol->target.path, algorithm, - vol->target.allocation); + vol->target.allocation, false); }
return ret;
Michal

On 04/25/2017 03:06 AM, Michal Privoznik wrote:
On 04/07/2017 06:30 PM, John Ferlan wrote:
Add bool 'zero_end' and logic that would allow a caller to wipe specific portions of a target device either from the beginning (the default) or from the end when zero_end is true.
This will allow for this code to wipe out partition table information from a device.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_util.c | 48 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a2d89af..c1734e7 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -2516,24 +2516,44 @@ static int storageBackendWipeLocal(const char *path, int fd, unsigned long long wipe_len, - size_t writebuf_length) + size_t writebuf_length, + bool zero_end) { int ret = -1, written = 0; unsigned long long remaining = 0; + off_t size; size_t write_size = 0; char *writebuf = NULL;
- VIR_DEBUG("wiping start: 0 len: %llu", wipe_len); - if (VIR_ALLOC_N(writebuf, writebuf_length) < 0) goto cleanup;
- if (lseek(fd, 0, SEEK_SET) < 0) { - virReportSystemError(errno, - _("Failed to seek to the start in volume " - "with path '%s'"), - path); - goto cleanup; + if (!zero_end) { + if (lseek(fd, 0, SEEK_SET) < 0) { + virReportSystemError(errno, + _("Failed to seek to the start in volume " + "with path '%s'"), + path); + goto cleanup; + } + VIR_DEBUG("wiping start: 0 len: %llu", wipe_len); + } else { + if ((size = lseek(fd, 0, SEEK_END)) == (off_t)-1) { + virReportSystemError(errno, + _("Failed to seek to the end in volume " + "with path '%s'"), + path); + goto cleanup; + } + size -= wipe_len; + if (lseek(fd, size, SEEK_SET) < 0) { + virReportSystemError(errno, + _("Failed to seek to %zd bytes in volume " + "with path '%s'"), + size, path);
Is off_t really ssize_t? I think we should typecast it.
OK - I do (now) have a recollection of printing an off_t cause some sort of issue for some arch, but I forget which one...
+ goto cleanup; + }
Or, instead of these two seeks:
if ((size = lseek(fd, -wipe_len, SEEK_END)) < 0) { virReportSystemError(); goto cleanup; }
+ VIR_DEBUG("wiping start: %zd len: %llu", size, wipe_len);
This DEBUG is the same as in the other body for the if statement. While it's just VIR_DEBUG I wouldn't care, but just consider the following for a moment:
Move this VIR_DEBUG right after this if statement and initialize @size to zero (and obviously drop the other VIR_DEBUG with hardcoded 0). That way we know what the current position is and how long section is to be wiped.
Or even better:
+ if (!zero_end) { + if ((size = lseek(fd, 0, SEEK_SET)) < 0) { + virReportSystemError(errno, + _("Failed to seek to the start in volume " + "with path '%s'"), + path); + goto cleanup; + } + } else { + if ((size = lseek(fd, -wipe_len, SEEK_END)) < 0) { + virReportSystemError(errno, + _("Failed to seek to %llu bytes to the end in volume " + "with path '%s'"), + wipe_len, path); + goto cleanup; + } }
+ VIR_DEBUG("wiping start: %zd len: %llu", (ssize_t) size, wipe_len);
I'll go with this... Thanks John
}
remaining = wipe_len; @@ -2573,7 +2593,8 @@ storageBackendWipeLocal(const char *path, static int storageBackendVolWipeLocalFile(const char *path, unsigned int algorithm, - unsigned long long allocation) + unsigned long long allocation, + bool zero_end) { int ret = -1, fd = -1; const char *alg_char = NULL; @@ -2648,7 +2669,8 @@ storageBackendVolWipeLocalFile(const char *path, if (S_ISREG(st.st_mode) && st.st_blocks < (st.st_size / DEV_BSIZE)) { ret = storageBackendVolZeroSparseFileLocal(path, st.st_size, fd); } else { - ret = storageBackendWipeLocal(path, fd, allocation, st.st_blksize); + ret = storageBackendWipeLocal(path, fd, allocation, st.st_blksize, + zero_end); } if (ret < 0) goto cleanup; @@ -2686,7 +2708,7 @@ storageBackendVolWipePloop(virStorageVolDefPtr vol, goto cleanup;
if (storageBackendVolWipeLocalFile(target_path, algorithm, - vol->target.allocation) < 0) + vol->target.allocation, false) < 0) goto cleanup;
if (virFileRemove(disk_desc, 0, 0) < 0) { @@ -2735,7 +2757,7 @@ virStorageBackendVolWipeLocal(virConnectPtr conn ATTRIBUTE_UNUSED, ret = storageBackendVolWipePloop(vol, algorithm); } else { ret = storageBackendVolWipeLocalFile(vol->target.path, algorithm, - vol->target.allocation); + vol->target.allocation, false); }
return ret;
Michal

Create a wrapper/helper that can be used to call the storage backend wipe helper - storageBackendVolWipeLocalFile for future use by logical and disk backends to clear out the partition table rather than having each open code the same algorithm. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_util.c | 22 ++++++++++++++++++++++ src/storage/storage_util.h | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index c1734e7..d7394d6 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -4111,3 +4111,25 @@ virStorageBackendSCSIFindLUs(virStoragePoolObjPtr pool, return found; } + + +/* + * @path: Path to the device to initialize + * @size: Size to be cleared + * + * Zero out possible partition table information for the specified + * bytes from the start of the @path and from the end of @path + * + * Returns 0 on success, -1 on failure with error message set + */ +int +virStorageBackendZeroPartitionTable(const char *path, + unsigned long long size) +{ + if (storageBackendVolWipeLocalFile(path, VIR_STORAGE_VOL_WIPE_ALG_ZERO, + size, false) < 0) + return -1; + + return storageBackendVolWipeLocalFile(path, VIR_STORAGE_VOL_WIPE_ALG_ZERO, + size, true); +} diff --git a/src/storage/storage_util.h b/src/storage/storage_util.h index 602d3a0..a05c35d 100644 --- a/src/storage/storage_util.h +++ b/src/storage/storage_util.h @@ -167,4 +167,8 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, int virStorageBackendSCSIFindLUs(virStoragePoolObjPtr pool, uint32_t scanhost); +int +virStorageBackendZeroPartitionTable(const char *path, + unsigned long long size); + #endif /* __VIR_STORAGE_UTIL_H__ */ -- 2.9.3

Rather than open code it, use the new function which uses the wipe algorithm in order to zero the front and tail of the partition. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_logical.c | 44 +---------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index d87aaf0..a865036 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -92,9 +92,6 @@ virStorageBackendLogicalRemoveDevice(const char *path) static int virStorageBackendLogicalInitializeDevice(const char *path) { - int fd = -1; - char zeros[4 * PV_BLANK_SECTOR_SIZE] = {0}; - off_t size; int ret = -1; virCommandPtr pvcmd = NULL; @@ -103,46 +100,8 @@ virStorageBackendLogicalInitializeDevice(const char *path) * a whole disk as a PV. So we just blank them out regardless * rather than trying to figure out if we're a disk or partition */ - if ((fd = open(path, O_WRONLY)) < 0) { - virReportSystemError(errno, _("cannot open device '%s'"), path); + if (virStorageBackendZeroPartitionTable(path, 4 * PV_BLANK_SECTOR_SIZE) < 0) return -1; - } - - if ((size = lseek(fd, 0, SEEK_END)) == (off_t)-1) { - virReportSystemError(errno, - _("failed to seek to end of %s"), path); - goto cleanup; - } - - if (size < 4 * PV_BLANK_SECTOR_SIZE) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("cannot initialize '%s' detected size='%zd' less " - "than minimum required='%d"), - path, (ssize_t) size, 4 * PV_BLANK_SECTOR_SIZE); - goto cleanup; - } - if ((size = lseek(fd, 0, SEEK_SET)) == (off_t)-1) { - virReportSystemError(errno, - _("failed to seek to start of %s"), path); - goto cleanup; - } - - if (safewrite(fd, zeros, sizeof(zeros)) < 0) { - virReportSystemError(errno, _("cannot clear device header of '%s'"), - path); - goto cleanup; - } - - if (fsync(fd) < 0) { - virReportSystemError(errno, _("cannot flush header of device'%s'"), - path); - goto cleanup; - } - - if (VIR_CLOSE(fd) < 0) { - virReportSystemError(errno, _("cannot close device '%s'"), path); - goto cleanup; - } /* * Initialize the physical volume because vgcreate is not @@ -155,7 +114,6 @@ virStorageBackendLogicalInitializeDevice(const char *path) ret = 0; cleanup: - VIR_FORCE_CLOSE(fd); virCommandFree(pvcmd); return ret; -- 2.9.3

Since a sector size may be larger than 512 bytes, let's just increase the size to wipe to 1MB rather than 2048KB Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_logical.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index a865036..ed26c24 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -100,7 +100,7 @@ virStorageBackendLogicalInitializeDevice(const char *path) * a whole disk as a PV. So we just blank them out regardless * rather than trying to figure out if we're a disk or partition */ - if (virStorageBackendZeroPartitionTable(path, 4 * PV_BLANK_SECTOR_SIZE) < 0) + if (virStorageBackendZeroPartitionTable(path, 1024 * 1024) < 0) return -1; /* -- 2.9.3

On 04/07/2017 06:30 PM, John Ferlan wrote:
Since a sector size may be larger than 512 bytes, let's just increase the size to wipe to 1MB rather than 2048KB
2048KB = 2MB ;-) So probably you meant 2KB?
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_logical.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index a865036..ed26c24 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -100,7 +100,7 @@ virStorageBackendLogicalInitializeDevice(const char *path) * a whole disk as a PV. So we just blank them out regardless * rather than trying to figure out if we're a disk or partition */ - if (virStorageBackendZeroPartitionTable(path, 4 * PV_BLANK_SECTOR_SIZE) < 0) + if (virStorageBackendZeroPartitionTable(path, 1024 * 1024) < 0) return -1;
/*
Michal

https://bugzilla.redhat.com/show_bug.cgi?id=1439132 During 'matrix' testing of all possible combinations I found that if device is formated with "gpt" first, then an attempt is made to format using "mac", a startup will fail. Deeper analysis by Peter Krempa indicates that the "mac" table fits into the first block on the disk. Since the GPT disklabel is stored at LBA address 1 it is not overwritten at all. Thus it's apparent that the (blkid) detection tool then prefers GPT over a older disklabel. The GPT disklabel has also a secondary copy at the last LBA of the disk. So, follow the same logic as the logical pool in clearing a 1MB swath at the beginning and end of the device to avoid potential issues with larger sector sizes for the device. Also fixed a minor formatting nit in virStorageBackendDeviceIsEmpty call. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_disk.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index 39371f2..e8f67bb 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -491,11 +491,15 @@ virStorageBackendDiskBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED, ok_to_mklabel = true; } else { if (virStorageBackendDeviceIsEmpty(pool->def->source.devices[0].path, - fmt, true)) + fmt, true)) ok_to_mklabel = true; } if (ok_to_mklabel) { + if (virStorageBackendZeroPartitionTable(pool->def->source.devices[0].path, + 1024 * 1024) < 0) + goto error; + /* eg parted /dev/sda mklabel --script msdos */ if (format == VIR_STORAGE_POOL_DISK_UNKNOWN) format = pool->def->source.format = VIR_STORAGE_POOL_DISK_DOS; -- 2.9.3

ping? Tks - John On 04/07/2017 12:30 PM, John Ferlan wrote:
Well kind of a v2/v3 type mashup - essentially reworked the portion of the series:
https://www.redhat.com/archives/libvir-list/2017-April/msg00402.html
that dealt with the zeroing of the header of the device path. The changes now will allow both the head and tail of the device path to be cleared rather than just the header of the file which was ACK'd for at least the logical backend.
Additionally, bump the size of the clear/zero from 2048KB to 1MB and use it for both the logical and disk backends.
John Ferlan (5): storage: Modify storageBackendWipeLocal to allow zero from end of device storage: Introduce virStorageBackendZeroPartitionTable logical: Use virStorageBackendZeroPartitionTable logical: Increase the size of the data to wipe disk: Use virStorageBackendZeroPartitionTable
src/storage/storage_backend_disk.c | 6 ++- src/storage/storage_backend_logical.c | 44 +--------------------- src/storage/storage_util.c | 70 ++++++++++++++++++++++++++++------- src/storage/storage_util.h | 4 ++ 4 files changed, 67 insertions(+), 57 deletions(-)

On 04/07/2017 06:30 PM, John Ferlan wrote:
Well kind of a v2/v3 type mashup - essentially reworked the portion of the series:
https://www.redhat.com/archives/libvir-list/2017-April/msg00402.html
that dealt with the zeroing of the header of the device path. The changes now will allow both the head and tail of the device path to be cleared rather than just the header of the file which was ACK'd for at least the logical backend.
Additionally, bump the size of the clear/zero from 2048KB to 1MB and use it for both the logical and disk backends.
John Ferlan (5): storage: Modify storageBackendWipeLocal to allow zero from end of device storage: Introduce virStorageBackendZeroPartitionTable logical: Use virStorageBackendZeroPartitionTable logical: Increase the size of the data to wipe disk: Use virStorageBackendZeroPartitionTable
src/storage/storage_backend_disk.c | 6 ++- src/storage/storage_backend_logical.c | 44 +--------------------- src/storage/storage_util.c | 70 ++++++++++++++++++++++++++++------- src/storage/storage_util.h | 4 ++ 4 files changed, 67 insertions(+), 57 deletions(-)
ACK series. But please see my comments before pushing - you'll need to fix couple of things before. Michal
participants (2)
-
John Ferlan
-
Michal Privoznik