Tomo, Please find attached a patch that adds a new argument to tgtimg to allow to create thin-provisioned files. The default for tgtimg is to fully allocate all device files it creates. Using this flag allows to create a "sparse" file for use by the LUN. regards ronnie sahlberg
Attachment:
0001-TGTIMG-Add-support-for-thin-provisioning.patch.gz
Description: GNU Zip compressed data
From fc6859e6ab9dea7bbf71a8f411519dbf5f02f0ef Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> Date: Fri, 30 Mar 2012 16:46:38 +1100 Subject: [PATCH 1/2] TGTIMG: Add support for thin-provisioning A new flag --ting-provisioning is added to the tgtimg command. When used this flag will create a sparse file without any allocation guarantee. It will also verify that FALLOC_FL_PUNCH_HOLE works. If such files are created, a future patch to tgtd will add support for the UNMAP command that is used by initiators to release blocks that are no longer in use. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> --- doc/tgtimg.8.xml | 22 ++++++++++++++++++++++ usr/tgtimg.c | 45 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/doc/tgtimg.8.xml b/doc/tgtimg.8.xml index 5a787af..e067db0 100644 --- a/doc/tgtimg.8.xml +++ b/doc/tgtimg.8.xml @@ -21,6 +21,7 @@ <arg choice="opt">-s --size <size></arg> <arg choice="opt">-t --type <media-type></arg> <arg choice="opt">-f --file <path></arg> + <arg choice="opt">-T --thin-provisioning</arg> </cmdsynopsis> <cmdsynopsis> <command>tgtimg --help</command> @@ -126,6 +127,27 @@ Supported media types for tape devices are : </listitem> </varlistentry> + <varlistentry><term><option>-T, --thin-provisioning</option></term> + <listitem> + <para> + This argument makes the allocation of the image format use + thin-provisioning. This means that the file created will be a + sparse file that will allocate blocks from the filesystem on demand. + </para> + <para> + Be careful when using thin-provisioning. If the filesystem + fills up a iSCSI write to a thin-provisioned LUN + can fail. Initiators generally do not handle "out of space" errors + gracefully. + </para> + <para> + Thin-provisioning uses FALLOC_FL_PUNCH_HOLE which is only available + on some linux filesystems. Thin-provisioning can only be used for + DISK images. + </para> + </listitem> + </varlistentry> + </variablelist> </refsect1> diff --git a/usr/tgtimg.c b/usr/tgtimg.c index f4388d9..bb417fe 100644 --- a/usr/tgtimg.c +++ b/usr/tgtimg.c @@ -1,5 +1,5 @@ /* - * Create blank media files for bs_tape backing store + * Create media files for TGTD devices * * Copyright (C) 2008 Mark Harvey markh794@xxxxxxxxx * @@ -22,6 +22,7 @@ #define _XOPEN_SOURCE 600 #include <errno.h> #include <fcntl.h> +#include <linux/falloc.h> #include <getopt.h> #include <inttypes.h> #include <stdio.h> @@ -59,6 +60,7 @@ struct option const long_options[] = { {"size", required_argument, NULL, 's'}, {"type", required_argument, NULL, 't'}, {"file", required_argument, NULL, 'f'}, + {"thin-provisioning", no_argument, NULL, 'T'}, {NULL, 0, NULL, 0}, }; @@ -71,7 +73,7 @@ static void usage(int status) printf("\ Linux SCSI Target Framework Image File Utility, version %s\n\ \n\ - --op new --device-type tape --barcode=[code] --size=[size] --type=[type] --file=[path]\n\ + --op new --device-type tape --barcode=[code] --size=[size] --type=[type] --file=[path] [--thin-provisioning]\n\ create a new tape image file.\n\ [code] is a string of chars.\n\ [size] is media size(in megabytes).\n\ @@ -83,6 +85,7 @@ Linux SCSI Target Framework Image File Utility, version %s\n\ --op show --device-type tape --file=[path]\n\ dump the tape image file contents.\n\ [path] is the tape image file\n\ + --thin-provisioning create a sparse file for the media\n\ --help display this help and exit\n\ \n\ Report bugs to <stgt@xxxxxxxxxxxxxxx>.\n", TGT_VERSION); @@ -414,7 +417,7 @@ static int mmc_ops(int op, char *path, char *media_type) return 0; } -static int sbc_new(int op, char *path, char *capacity, char *media_type) +static int sbc_new(int op, char *path, char *capacity, char *media_type, int thin) { int fd; @@ -438,9 +441,29 @@ static int sbc_new(int op, char *path, char *capacity, char *media_type) perror("Failed creating file"); exit(2); } - if (posix_fallocate(fd, 0, size*1024*1024LL) == -1) { - perror("posix_fallocate failed."); - exit(3); + if (thin) { +#ifdef FALLOC_FL_PUNCH_HOLE + if (ftruncate(fd, size*1024*1024LL) != 0) { + perror("Failed to set file size"); + exit(6); + } + if (fallocate(fd, + FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, + 0, size*1024*1024LL) != 0) { + perror("Thin provisioning not available on" + " this file"); + exit(5); + } +#else + perror("This version of tgtimg is not compiled " + "with thin-provisioning support."); + exit(6); +#endif + } else { + if (posix_fallocate(fd, 0, size*1024*1024LL) == -1) { + perror("posix_fallocate failed."); + exit(3); + } } free(buf); @@ -456,7 +479,7 @@ static int sbc_new(int op, char *path, char *capacity, char *media_type) return 0; } -static int sbc_ops(int op, char *path, char *capacity, char *media_type) +static int sbc_ops(int op, char *path, char *capacity, char *media_type, int thin) { if (op == OP_NEW) { if (!media_type) { @@ -471,7 +494,7 @@ static int sbc_ops(int op, char *path, char *capacity, char *media_type) eprintf("Missing the capacity param\n"); usage(1); } - return sbc_new(op, path, capacity, media_type); + return sbc_new(op, path, capacity, media_type, thin); } else { eprintf("unknown the operation type\n"); usage(1); @@ -489,6 +512,7 @@ int main(int argc, char **argv) int dev_type = TYPE_TAPE; int op = -1; char *path = NULL; + int thin = 0; while ((ch = getopt_long(argc, argv, short_options, long_options, &longindex)) >= 0) { @@ -514,6 +538,9 @@ int main(int argc, char **argv) case 'h': usage(0); break; + case 'T': + thin = 1; + break; default: eprintf("unrecognized option '%s'\n", optarg); usage(1); @@ -543,7 +570,7 @@ int main(int argc, char **argv) mmc_ops(op, path, media_type); break; case TYPE_DISK: - sbc_ops(op, path, media_capacity, media_type); + sbc_ops(op, path, media_capacity, media_type, thin); break; default: eprintf("unsupported the device type operation\n"); -- 1.7.3.1