From 568018cf265cbe862420d2366c23ab848d1cad77 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Mon, 19 Apr 2021 15:32:31 -0600 Subject: [PATCH 1/1] LU-930 doc: update lfs migrate usage and man page Update the usage and man page for "lfs migrate -m", noting that this command will recursively migrate an entire directory tree. It is not currently possible to migrate files with DoM components between MDTs, so provide an example of how to work around this. Only print the command-line options for commands in the usage message instead of the full usage, since it is otherwise much too verbose to see the actual error message being printed. The user should read the lfs-migrate.1 man page for full usage. Test-Parameters: trivial Signed-off-by: Andreas Dilger Change-Id: I9e34a33fcc3f0e2b90bc499fb7b946c53e6111d1 Reviewed-on: https://review.whamcloud.com/43378 Tested-by: jenkins Reviewed-by: James Nunez Reviewed-by: Lai Siyao Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/doc/lfs-migrate.1 | 116 ++++++++++++++++++++++++-------- lustre/utils/lfs.c | 170 +++++++++-------------------------------------- 2 files changed, 122 insertions(+), 164 deletions(-) diff --git a/lustre/doc/lfs-migrate.1 b/lustre/doc/lfs-migrate.1 index fb72541..795b5d3 100644 --- a/lustre/doc/lfs-migrate.1 +++ b/lustre/doc/lfs-migrate.1 @@ -1,18 +1,23 @@ -.TH LFS-MIGRATE 1 2015-12-07 "Lustre" "Lustre Utilities" +.TH LFS-MIGRATE 1 2021-11-08 "Lustre" "Lustre Utilities" .SH NAME lfs migrate \- migrate files or directories between MDTs or OSTs. .SH SYNOPSIS .B lfs migrate .RB [ -h "] [" -v ] .RI [ SETSTRIPE_OPTIONS " ... ]" -.RI < file "> ..." +.IR FILE " ..." .br -.B lfs migrate -m \fIstart_mdt_index +.B lfs migrate -m \fISTART_MDT_INDEX .RB [ -cHv ] -.RI < directory > +.I DIRECTORY .br .SH DESCRIPTION -Migrate OST objects or MDT inodes between MDTs and OSTs respectively. +Migrate OST objects between OSTs for the specified +.IR FILE , +or recursively migrate +.I DIRECTORY +and all inodes/directories therein between MDTs. +.SH OST MIGRATE OPTIONS .P The .B lfs migrate @@ -27,8 +32,7 @@ In OST object migration mode, the command supports the same .I SETSTRIPE_OPTIONS listed in .BR lfs-setstripe (1) -to specify the layout of the target file. The migrate command differs -from +to specify the layout of the target file. The migrate command differs from .B lfs setstripe in that .B lfs migrate @@ -36,7 +40,6 @@ will copy the data from the existing file(s) using the new layout parameters to the new OST(s). In contrast, .B lfs setstripe is used for creating new (empty) files with the specified layout. -.SH OST MIGRATE OPTIONS For OST object migration, there additional options available: .TP .BR -b , --block @@ -83,25 +86,48 @@ data between OSTs and has a separate man page. See for details. .SH MDT MIGRATE OPTIONS .TP -.BR -m , --mdt-index=\fIstart_mdt_index\fR -Directory will be migrated to MDTs starting with -.I start_mdt_index -, or specific MDTs if multiple MDTs are specified in a comma-seperated list. +.BR -m , --mdt-index=\fIMDT_INDEX [, \fIMDT_INDEX ,...] +The specified +.I DIRECTORY +.B and all subdirectories and inodes +will be migrated to the MDT with the specified +.IR MDT_INDEX . This is useful if new MDTs have been added to a filesystem and existing user or project directories should be migrated off old MDTs to balance the space usage and future metadata workload. If -.I start_mdt_index -is set to -1, the MDT will be chosen by space and inode usage. +.I MDT_INDEX +is -1, the MDT index will be balanced by free space and inodes among +available MDTs. If multiple +.I MDT_INDEX +values are specified in a comma-seperated list, then all +subdirectories will be +.B striped +across all of the specified MDT indices as if an equivalent +.BI -c N +option were given. .TP .BR -c , --mdt-count=\fICOUNT\fR -Directory will be migrated to +All directories and subdirectories in the tree will be striped across +.I COUNT +MDTs, always using +.I MDT_INDEX +as the primary MDT for the directory. If +.I MDT_INDEX is +.B -1 +then .I COUNT -MDTs. +directory stripes will be chosen from MDTs proportional to the amount +of free inodes and space on each MDT. If multiple +.I MDT_INDEX +values are specified in a comma-separated list, then the number of specified +.I MDT_INDEX +values must match +.IR COUNT . .TP .BR -H , --mdt-hash=\fIHASH_TYPE\fR Use .I HASH_TYPE -for the new layout. +for the new directory layout. .RS 1.2i .TP .B all_char (type 1) @@ -121,14 +147,25 @@ algorithm, so minimum sub files need to relocate during directory restripe. .RE .P +.TP +.B NOTE Only the root user can migrate directories. Files that have been archived by HSM or are currently opened will fail to migrate, user can run the same migrate command again to finish migration when files are ready. Both inode and directory entry will be migrated. During migration directory and sub files can -be accessed like normal ones. +be accessed like normal ones, but the migration itself cannot be interrupted. +.TP +.B NOTE +It is not currently possible to migrate files with an +.B mdt +component (Data-on-MDT, DoM). If it is necessary to migrate such files off +a particular MDT, they must first be migrated to have a non-DoM file layout +and then the inodes migrated separately. See +.B EXAMPLES +for details on how to migrate DoM files between MDTs. .TP -\fIWARNING\fR -A migrated file or directory will have a new FID, and hence a new inode +.B WARNING +Each migrated file or directory will have a new FID, and hence a new inode number. As a consequence, files archived by Lustre HSM that depend on the FID as the identifier in the HSM archive cannot currently be migrated. Having a new inode number may also cause backup tools to consider the @@ -137,14 +174,41 @@ migrated file(s) to be a new, and cause them to be backed up again. .SH EXAMPLES .TP .B $ lfs migrate -c 2 /mnt/lustre/file1 -This migrates the file into a new layout with 2 stripes. +This migrates the data in +.B file1 +into a new layout with 2 stripes. .TP -.B $ lfs migrate -E 64M -c 1 -E 256M -c 4 -E -1 -c -1 /mnt/lustre/file1 -This migrates the file into a three component composite layout. +.B $ lfs migrate -E 256M -c 1 -E 16G -c 4 -E eof -c 40 /mnt/lustre/file2 +.br +This migrates the data in +.B file2 +into a three component composite layout (number of stripes depends on +file size). .TP -.B $ lfs migrate -m 0,2 ./testremote -Move the inodes contained in directory ./testremote from their current -MDT to the MDT with index 0 and 2. +.B # lfs migrate -m 0,2 testremote +.br +Recursively move the subdirectories and inodes contained in directory +.B remotedir +from its current MDT to MDT0000 and MDT0002. The +.B testremote +directory and all of its subdirectories will be striped across both MDTs. +.TP +.B # lfs setstripe -E 256M -c 1 -E 16G -c 4 -E eof -c 40 topdir +Set a default PFL layout (without any DoM component) on the directory +.BR topdir , +.TP +.B # lfs find dir -type f -L mdt -0 | xargs -0 lfs migrate --copy topdir +then find and migrate all regular files that have an +.B mdt +component to copy the default layout from the specified +.BR topdir , +.TP +.B # lfs migrate -m 2 topdir +.br +and finally migrate the directory +.B topdir +and all files and subdirectories in that tree to MDT0002. This allows +migrating files with DoM components off an MDT. .SH AUTHOR The lfs command is part of the Lustre filesystem. .SH SEE ALSO diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index d160fa2..58fed51 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -191,97 +191,34 @@ static inline int lfs_mirror_delete(int argc, char **argv) /* Setstripe and migrate share mostly the same parameters */ #define SSM_CMD_COMMON(cmd) \ "usage: "cmd" [--component-end|-E COMP_END]\n" \ - " [--stripe-count|-c STRIPE_COUNT]\n" \ - " [--overstripe-count|-C STRIPE_COUNT]\n" \ - " [--stripe-index|-i START_OST_IDX]\n" \ - " [--stripe-size|-S STRIPE_SIZE]\n" \ - " [--extension-size|--ext-size|-z]\n" \ + " [--copy=LUSTRE_SRC]\n" \ + " [--extension-size|--ext-size|-z SIZE]\n" \ " [--help|-h] [--layout|-L PATTERN]\n" \ - " [--mirror_count|-N[MIRROR_COUNT]]\n" \ + " [--layout|-L PATTERN]\n" \ + " [--mirror-count|-N[MIRROR_COUNT]]\n" \ " [--ost|-o OST_INDICES]\n" \ + " [--overstripe-count|-C STRIPE_COUNT]\n" \ " [--pool|-p POOL_NAME]\n" \ - " [--yaml|-y YAML_TEMPLATE_FILE]\n" \ - " [--copy=LUSTRE_SRC]\n" - -#define SSM_HELP_COMMON \ - "\tSTRIPE_COUNT: Number of OSTs to stripe on (0=fs default, -1 all)\n" \ - "\t Using -C instead of -c allows overstriping, which\n" \ - "\t will place more than one stripe per OST if\n" \ - "\t stripe_count is greater than the number of OSTs.\n" \ - "\tSTART_OST_IDX: OST index of first stripe (-1=default round robin)\n"\ - "\tSTRIPE_SIZE: Number of bytes on each OST (0=fs default)\n" \ - "\t Optional K, M, or G suffix (for KB, MB, GB\n" \ - "\t respectively). Must be a multiple of 64KiB.\n" \ - "\tEXTENSION_SIZE:\n" \ - "\t Number of bytes the previous component is extended\n" \ - "\t each time. Optional K, M, or G suffix (for KB,\n" \ - "\t MB, GB respectively)\n" \ - "\tPOOL_NAME: Name of OST pool to use (default none)\n" \ - "\tLAYOUT: stripe pattern type: raid0, mdt (default raid0)\n" \ - "\tOST_INDICES: List of OST indices, can be repeated multiple times\n"\ - "\t Indices be specified in a format of:\n" \ - "\t -o OST_1,OST_I-OST_J,OST_N\n" \ - "\t Or:\n" \ - "\t -o OST_1 -o OST_I-OST_J -o OST_N\n" \ - "\t If --pool is set with --ost then the OSTs\n" \ - "\t must be the members of the pool.\n" \ - "\tCOMP_END: Extent end of component, start after previous end.\n" \ - "\t Optional K, M, or G suffix (for KiB, MiB, GiB), or\n" \ - "\t -1 or 'eof' for max file size). Must be a multiple\n" \ - "\t of stripe_size and a multiple of 64KiB.\n" \ - "\tYAML_TEMPLATE_FILE:\n" \ - "\t YAML layout template file, can't be used with -c,\n" \ - "\t -i, -S, -p, -o, or -E arguments.\n" \ - "\tLUSTRE_SRC: Lustre file/dir whose layout info is used to set\n" \ - "\t another lustre file or directory, can't used with\n" \ - "\t -c, -i, -S, -p, -o, or -E arguments.\n" - -#define MIRROR_CREATE_HELP \ - "\tMIRROR_COUNT: Number of mirrors to be created with the upcoming\n" \ - "\t setstripe layout options\n" \ - "\t It defaults to 1 if not specified; if specified,\n" \ - "\t it must follow the option without a space.\n" \ - "\t The option can also be repeated multiple times to\n" \ - "\t separate mirrors that have different layouts.\n" \ - "\tSETSTRIPE_OPTIONS: Mirror layout as with 'setstripe'\n" \ - "\t It can be a plain layout or a composite layout.\n" \ - "\t If not specified, the stripe options inherited\n" \ - "\t from the previous component will be used.\n" \ - "\tFLAGS: set flags to the component of the current mirror.\n" \ - "\t Only \"prefer\" flag is supported so far.\n" - -#define MIRROR_EXTEND_HELP \ - MIRROR_CREATE_HELP \ - "\tVICTIM_FILE: The layout of victim_file will be split and used\n" \ - "\t as a mirror added to the mirrored file.\n" \ - "\tno-verify: This option indicates not to verify the mirror(s)\n" \ - "\t from victim file(s) in case the victim file(s)\n" \ - "\t contains the same data as the original mirrored\n" \ - "\t file.\n" - -#define MIRROR_EXTEND_USAGE \ - " {--mirror-count|-N[mirror_count]}\n" \ - " [SETSTRIPE_OPTIONS|-f|--file VICTIM_FILE]\n" \ + " [--stripe-count|-c STRIPE_COUNT]\n" \ + " [--stripe-index|-i START_OST_IDX]\n" \ + " [--stripe-size|-S STRIPE_SIZE]\n" \ + " [--yaml|-y YAML_TEMPLATE_FILE]\n" + +#define MIRROR_EXTEND_USAGE \ + " {--mirror-count|-N[MIRROR_COUNT]}\n" \ + " [SETSTRIPE_OPTIONS|-f|--file VICTIM_FILE]\n" \ " [--no-verify]\n" #define SETSTRIPE_USAGE \ SSM_CMD_COMMON("setstripe") \ MIRROR_EXTEND_USAGE \ - " \n" \ - SSM_HELP_COMMON \ - MIRROR_EXTEND_HELP + " DIRECTORY|FILENAME\n" #define MIGRATE_USAGE \ SSM_CMD_COMMON("migrate ") \ " [--block|-b] [--non-block|-n]\n" \ " [--non-direct|-D] [--verbose|-v]\n" \ - " \n" \ - SSM_HELP_COMMON \ - "\n" \ - "\tblock: Block file access during data migration (default)\n" \ - "\tnon-block: Abort migrations if concurrent access is detected\n" \ - "\tnon-direct: Do not use direct I/O to copy file contents\n" \ - "\tverbose: Print each filename as it is migrated\n" \ + " FILENAME\n" #define SETDIRSTRIPE_USAGE \ " [--mdt-count|-c stripe_count>\n" \ @@ -290,19 +227,9 @@ static inline int lfs_mirror_delete(int argc, char **argv) " [--default|-D] [--mode|-o mode]\n" \ " [--max-inherit|-X max_inherit]\n" \ " [--max-inherit-rr max_inherit_rr] \n" \ - "\tstripe_count: stripe count of the striped directory\n" \ - "\tmdt_index: MDT index of first stripe\n" \ - "\tmdt_hash: hash type of the striped directory. mdt types:\n" \ - " crush CRUSH hash algorithm (default)\n" \ - " fnv_1a_64 FNV-1a hash algorithm\n" \ - " all_char sum of characters % MDT_COUNT (not recommended)\n" \ - "\tdefault_stripe: set default dirstripe of the directory\n" \ - "\tmode: the file access permission of the directory (octal)\n" \ "To create dir with a foreign (free format) layout :\n" \ "setdirstripe|mkdir --foreign[=FOREIGN_TYPE] -x|-xattr STRING " \ - "[--mode|-o MODE] [--flags HEX] \n" \ - "\tmode: the file access permissions of the directory\n" \ - "\tforeign_type: none, daos, symlink, or numeric value\n" + " [--mode|-o MODE] [--flags HEX] DIRECTORY\n" /** * command_t mirror_cmdlist - lfs mirror commands. @@ -310,32 +237,24 @@ static inline int lfs_mirror_delete(int argc, char **argv) command_t mirror_cmdlist[] = { { .pc_name = "create", .pc_func = lfs_mirror_create, .pc_help = "Create a mirrored file.\n" - "usage: lfs mirror create {--mirror-count|-N[MIRROR_COUNT]}\n" - "\t\t[SETSTRIPE_OPTIONS] ...\n" - MIRROR_CREATE_HELP }, + "usage: lfs mirror create --mirror-count|-N[MIRROR_COUNT]\n" + " [SETSTRIPE_OPTIONS] ... FILENAME|DIRECTORY ...\n" }, { .pc_name = "delete", .pc_func = lfs_mirror_delete, .pc_help = "Delete a mirror from a file.\n" - "usage: lfs mirror delete {--mirror-id MIRROR_ID|-p POOL|\n" - "\t --component-id|--comp-id|-I COMP_ID} \n" + "usage: lfs mirror delete {--mirror-id |\n" + "\t --component-id|--comp-id|-I COMP_ID |\n" + "\t -p } MIRRORED_FILE ...\n" }, { .pc_name = "extend", .pc_func = lfs_mirror_extend, .pc_help = "Extend a mirrored file.\n" - "usage: lfs mirror extend {--mirror-count|-N[MIRROR_COUNT]}\n" - "\t\t[--no-verify] [SETSTRIPE_OPTIONS|-f VICTIM_FILE] ... ...\n" - MIRROR_EXTEND_HELP }, + "usage: lfs mirror extend " + "{--mirror-count|-N[MIRROR_COUNT]} [--no-verify] " + "[SETSTRIPE_OPTIONS|-f VICTIM_FILE] ... FILENAME ...\n" }, { .pc_name = "split", .pc_func = lfs_mirror_split, .pc_help = "Split a mirrored file.\n" - "usage: lfs mirror split [--destroy|-d] [-f NEW_FILE] [--help|-h]\n" - "\t\t{--mirror-id MIRROR_ID|--component-id|-I COMP_ID|-p POOL}\n" - "\t\t ...\n" - "\tMIRROR_ID: The numerical unique identifier for a mirror.\n" - "\t It can be fetched by the 'lfs getstripe' command.\n" - "\tCOMP_ID: Unique component ID within a mirror.\n" - "\tPOOL: Components using specified pool.\n" - "\tNEW_FILE: This option indicates the layout of the split\n" - "\t mirror will be stored into. If not specified,\n" - "\t a new file named .mirror~MIRROR_ID\n" - "\t will be used.\n" }, + "usage: lfs mirror split {--mirror-id MIRROR_ID |\n" + "\t --component-id|-I COMP_ID|-p POOL} [--destroy|-d]\n" + "\t [-f NEW_FILE] MIRRORED_FILE ...\n" }, { .pc_name = "read", .pc_func = lfs_mirror_read, .pc_help = "Read the content of a specified mirror of a file.\n" "usage: lfs mirror read {--mirror-id|-N MIRROR_ID}\n" @@ -405,7 +324,6 @@ command_t cmdlist[] = { " or\n" "To add component(s) to an existing composite file:\n" SSM_CMD_COMMON("setstripe --component-add") - SSM_HELP_COMMON "To totally delete the default striping from an existing directory:\n" "usage: setstripe [--delete|-d] \n" " or\n" @@ -645,39 +563,15 @@ command_t cmdlist[] = { {"swap_layouts", lfs_swap_layouts, 0, "Swap layouts between 2 files.\n" "usage: swap_layouts "}, {"migrate", lfs_setstripe_migrate, 0, - "migrate a directory between MDTs.\n" + "migrate directories and their inodes between MDTs.\n" "usage: migrate [--mdt-count|-c STRIPE_COUNT]\n" " [--mdt-hash|-H HASH_TYPE]\n" " [--mdt-index|-m START_MDT_INDEX] [--verbose|-v]\n" - " \n" - "\tmdt: MDTs to stripe over, if only one MDT is specified\n" - " it's the MDT index of first stripe\n" - "\tmdt_count: number of MDTs to stripe a directory over\n" - "\tmdt_hash: hash type of the striped directory. mdt types:\n" - " all_char (type 1)sum of characters % MDT_COUNT\n" - " fnv_1a_64 (type 2)FNV-1a hash algorithm (default)\n" - " crush (type 3)CRUSH hash algorithm\n" + " DIRECTORY\n" "\n" - "migrate file objects from one OST " - "layout\nto another (may be not safe with concurent writes).\n" - "usage: migrate [--stripe-count|-c STRIPE_COUNT]\n" - " [--overstripe-count|-C STRIPE_COUNT]\n" - " [--stripe-index|-i START_OST_INDEX]\n" - " [--stripe-size|-S STRIPE_SIZE]\n" - " [--pool|-p ] [--ost|-o OST_INDICES]\n" - " [--block|-b] [--non-block|-n] [--non-direct|-D]\n" - " \n" - "\tstripe_count: number of OSTs to stripe a file over\n" - "\t Using -C instead of -c allows overstriping, which\n" - "\t will place more than one stripe per OST if\n" - "\t stripe_count is greater than the number of OSTs\n" - "\tstripe_ost_index: index of the first OST to stripe a file over\n" - "\tstripe_size: number of bytes to store before moving to the next OST\n" - "\tpool_name: name of the predefined pool of OSTs\n" - "\tost_indices: OSTs to stripe over, in order\n" - "\tblock: Block file access during data migration (default)\n" - "\tnon-block: Abort migrations if concurrent access is detected\n" - "\tnon-direct: do not use direct I/O to copy file contents.\n"}, + "migrate file objects from one OST layout to another\n" + "(may be not safe with concurent writes).\n" + MIGRATE_USAGE }, {"mv", lfs_mv, 0, "To move directories between MDTs. This command is deprecated, " "use \"migrate\" instead.\n" -- 1.8.3.1