Get minimum size of NTFS filesystem in bytes. This is used primarily for
shrinking images.
In case of a full images ntfsresize returns error code and does not print
minimum size.
So we calculate it manually by rounding 'volume size' up to 'cluster
size'.
---
daemon/ntfs.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 17 +++++++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/daemon/ntfs.c b/daemon/ntfs.c
index 1ead159..f0a8c3b 100644
--- a/daemon/ntfs.c
+++ b/daemon/ntfs.c
@@ -153,6 +153,74 @@ do_ntfsresize_size (const char *device, int64_t size)
return do_ntfsresize (device, size, 0);
}
+int64_t
+do_ntfsresize_info (const char *device)
+{
+ CLEANUP_FREE char *err = NULL, *out = NULL;
+ CLEANUP_FREE_STRING_LIST char **lines = NULL;
+ int r;
+ size_t i;
+ char *p;
+ int64_t ret, volume_size = 0;
+ const char *size_pattern = "You might resize at ",
+ *full_pattern = "Volume is full",
+ *cluster_size_pattern = "Cluster size",
+ *volume_size_pattern = "Current volume size:";
+ int is_full = 0;
+ int32_t cluster_size = 0;
+
+ /* FS may be marked for check, so force ntfsresize */
+ r = command (&out, &err, str_ntfsresize, "--info",
"-ff", device, NULL);
+
+ lines = split_lines (out);
+ if (lines == NULL)
+ return -1;
+
+ if (verbose) {
+ for (i = 0; lines[i] != NULL; ++i)
+ fprintf (stderr, "ntfsresize_info: lines[%zu] =
\"%s\"\n", i, lines[i]);
+ }
+
+ if (r == -1) {
+ /* If volume is full, ntfsresize returns error. */
+ for (i = 0; lines[i] != NULL; ++i) {
+ if (strstr (lines[i], full_pattern))
+ is_full = 1;
+ else if ((p = strstr (lines[i], cluster_size_pattern))) {
+ if (sscanf (p + strlen(cluster_size_pattern),
+ "%*[ ]:%" SCNd32, &cluster_size) != 1)
+ return -1;
+ }
+ else if ((p = strstr (lines[i], volume_size_pattern))) {
+ if (sscanf (p + strlen(volume_size_pattern),
+ "%" SCNd64, &volume_size) != 1)
+ return -1;
+ }
+ }
+ if (is_full) {
+ /* Ceil to cluster size */
+ if (cluster_size == 0) {
+ reply_with_error("%s", "Bad cluster size");
+ return -1;
+ }
+ return (volume_size + cluster_size - 1) / cluster_size * cluster_size;
+ }
+
+ reply_with_error ("%s", err);
+ return -1;
+ }
+
+ for (i = 0; lines[i] != NULL; ++i) {
+ if ((p = strstr (lines[i], size_pattern))) {
+ if (sscanf (p + strlen(size_pattern), "%" SCNd64, &ret) !=
1)
+ return -1;
+ return ret;
+ }
+ }
+
+ return -1;
+}
+
/* Takes optional arguments, consult optargs_bitmask. */
int
do_ntfsfix (const char *device, int clearbadsectors)
diff --git a/generator/actions.ml b/generator/actions.ml
index 274ef3f..ede6278 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12765,6 +12765,23 @@ Get the estimated minimum filesystem size of an
ext2/3/4 filesystem in blocks.
See also L<resize2fs(8)>." };
+ { defaults with
+ name = "ntfsresize_info"; added = (1, 31, 17);
+ style = RInt64 "sizeinbytes", [Device "device"], [];
+ proc_nr = Some 458;
+ tests = [
+ InitPartition, Always, TestRun(
+ [["mkfs"; "ntfs"; "/dev/sda1";
""; "NOARG"; ""; ""; "NOARG"];
+ ["ntfsresize_info"; "/dev/sda1"]]), [];
+ ];
+ shortdesc = "get minimum NTFS filesystem size";
+ longdesc = "\
+Get the minimum size of NTFS filesystem in bytes.
+
+This number is expected to be safely passed as C<guestfs_ntfsresize>
command parameter.
+
+See also L<ntfsresize(8)>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index de2a00c..c92ddb6 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-457
+458
--
1.8.3.1
On Friday 16 October 2015 15:55:44 Maxim Perevedentsev wrote:> Get minimum size of NTFS filesystem in bytes. This is used primarily for shrinking images. > > In case of a full images ntfsresize returns error code and does not print minimum size. > So we calculate it manually by rounding 'volume size' up to 'cluster size'.NACK to a separate API per-filesystem. As I said in a previous email, please turn the newly added resize2fs_P into a generic API for getting the minimum size of a filesystem, either bytes or blocks. See for example set_label and set_uuid. Thanks, -- Pino Toscano
Richard W.M. Jones
2015-Oct-16 13:06 UTC
Re: [Libguestfs] [PATCH] New API: ntfsresize_info
On Fri, Oct 16, 2015 at 03:00:15PM +0200, Pino Toscano wrote:> On Friday 16 October 2015 15:55:44 Maxim Perevedentsev wrote: > > Get minimum size of NTFS filesystem in bytes. This is used primarily for shrinking images. > > > > In case of a full images ntfsresize returns error code and does not print minimum size. > > So we calculate it manually by rounding 'volume size' up to 'cluster size'. > > NACK to a separate API per-filesystem. > > As I said in a previous email, please turn the newly added resize2fs_P > into a generic API for getting the minimum size of a filesystem, either > bytes or blocks. See for example set_label and set_uuid.For example: https://github.com/libguestfs/libguestfs/blob/master/daemon/labels.c#L61-L93 Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW