X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Flfs.c;h=089284dd288702a112ebd85ae0671cfb6cd26b75;hp=bf5d3cece2f57fd5f337f6a55101a994e6f2539d;hb=ed04ce44b1d434af9a36f50f1898e9a5417a7a6f;hpb=818340364d51ac9fb97151b0c244c4e2fd477715 diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index bf5d3ce..089284d 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -124,7 +124,8 @@ static int lfs_mirror_list_commands(int argc, char **argv); static int lfs_list_commands(int argc, char **argv); static inline int lfs_mirror_resync(int argc, char **argv); static inline int lfs_mirror_verify(int argc, char **argv); -static inline int lfs_mirror_dump(int argc, char **argv); +static inline int lfs_mirror_read(int argc, char **argv); +static inline int lfs_mirror_write(int argc, char **argv); enum setstripe_origin { SO_SETSTRIPE, @@ -233,15 +234,15 @@ static inline int lfs_mirror_split(int argc, char **argv) #define MIGRATE_USAGE \ SSM_CMD_COMMON("migrate ") \ - " [--block|-b]\n" \ - " [--non-block|-n]\n" \ - " [--non-direct|-D]\n" \ + " [--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" \ + "\tnon-direct: Do not use direct I/O to copy file contents\n" \ + "\tverbose: Print each filename as it is migrated\n" \ #define SETDIRSTRIPE_USAGE \ " [--mdt-count|-c stripe_count>\n" \ @@ -284,10 +285,14 @@ command_t mirror_cmdlist[] = { "\t mirror will be stored into. If not specified,\n" "\t a new file named .mirror~\n" "\t will be used.\n" }, - { .pc_name = "dump", .pc_func = lfs_mirror_dump, - .pc_help = "Dump the content of a specified mirror of a file.\n" - "usage: lfs mirror dump <--mirror-id|-N " - "[--outfile|-o ] \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 " + "[--outfile|-o ] \n" }, + { .pc_name = "write", .pc_func = lfs_mirror_write, + .pc_help = "Write to a specified mirror of a file.\n" + "usage: lfs mirror write <--mirror-id|-N " + "[--inputfile|-i ] \n" }, { .pc_name = "resync", .pc_func = lfs_mirror_resync, .pc_help = "Resynchronizes out-of-sync mirrored file(s).\n" "usage: lfs mirror resync [--only ] " @@ -297,7 +302,7 @@ command_t mirror_cmdlist[] = { "usage: lfs mirror verify " "[--only ] " "[--verbose|-v] [ ...]\n"}, - { .pc_name = "--list-commands", .pc_func = lfs_mirror_list_commands, + { .pc_name = "list-commands", .pc_func = lfs_mirror_list_commands, .pc_help = "list commands supported by lfs mirror"}, { .pc_name = "help", .pc_func = Parser_help, .pc_help = "help" }, { .pc_name = "exit", .pc_func = Parser_quit, .pc_help = "quit" }, @@ -403,9 +408,9 @@ command_t cmdlist[] = { "\t fnv_1a_64 FNV-1a hash algorithm\n" "\t all_char sum of characters % MDT_COUNT\n"}, {"check", lfs_check, 0, - "Display the status of MDS or OSTs (as specified in the command)\n" - "or all the servers (MDS and OSTs).\n" - "usage: check "}, + "Display the status of MGTs, MDTs or OSTs (as specified in the command)\n" + "or all the servers (MGTs, MDTs and OSTs).\n" + "usage: check "}, {"osts", lfs_osts, 0, "list OSTs connected to client " "[for specified path only]\n" "usage: osts [path]"}, {"mdts", lfs_mdts, 0, "list MDTs connected to client " @@ -586,7 +591,8 @@ command_t cmdlist[] = { "lfs mirror extend - add mirror(s) to an existing file\n" "lfs mirror split - split a mirror from an existing mirrored file\n" "lfs mirror resync - resynchronize out-of-sync mirrored file(s)\n" - "lfs mirror dump - dump a mirror content of a mirrored file\n" + "lfs mirror read - read a mirror content of a mirrored file\n" + "lfs mirror write - write to a mirror of a mirrored file\n" "lfs mirror verify - verify mirrored file(s)\n"}, {"getsom", lfs_getsom, 0, "To list the SOM info for a given file.\n" "usage: getsom [-s] [-b] [-f] \n" @@ -619,9 +625,10 @@ static int check_hashtype(const char *hashtype) static const char *error_loc = "syserror"; enum { - MIGRATION_NONBLOCK = 1 << 0, - MIGRATION_MIRROR = 1 << 1, - MIGRATION_NONDIRECT = 1 << 2, + MIGRATION_NONBLOCK = 0x0001, + MIGRATION_MIRROR = 0x0002, + MIGRATION_NONDIRECT = 0x0004, + MIGRATION_VERBOSE = 0x0008, }; static int lfs_component_create(char *fname, int open_flags, mode_t open_mode, @@ -1123,6 +1130,9 @@ out: if (rc < 0) fprintf(stderr, "error: %s: %s: %s: %s\n", progname, name, error_loc, strerror(-rc)); + else if (migration_flags & MIGRATION_VERBOSE) + printf("%s\n", name); + return rc; } @@ -3018,6 +3028,7 @@ static int lfs_setstripe_internal(int argc, char **argv, goto usage_error; } migrate_mdt_param.fp_verbose = VERBOSE_DETAIL; + migration_flags = MIGRATION_VERBOSE; break; case 'y': from_yaml = true; @@ -4600,16 +4611,22 @@ enum mntdf_flags { #define RSF "%4s" #define RDF "%3d%%" -static inline int obd_statfs_ratio(const struct obd_statfs *st) +static inline int obd_statfs_ratio(const struct obd_statfs *st, bool inodes) { double avail, used, ratio = 0; - avail = st->os_bavail; - used = st->os_blocks - st->os_bfree; + if (inodes) { + avail = st->os_ffree; + used = st->os_files - st->os_ffree; + } else { + avail = st->os_bavail; + used = st->os_blocks - st->os_bfree; + } if (avail + used > 0) - ratio = used / (used + avail) * 100 + 0.5; + ratio = used / (used + avail) * 100; - return (int)ratio; + /* Round up to match df(1) usage percentage */ + return (ratio - (int)ratio) > 0 ? (int)(ratio + 1) : (int)ratio; } static int showdf(char *mntdir, struct obd_statfs *stat, @@ -4643,7 +4660,7 @@ static int showdf(char *mntdir, struct obd_statfs *stat, total = (stat->os_blocks * stat->os_bsize) >> shift; } - ratio = obd_statfs_ratio(stat); + ratio = obd_statfs_ratio(stat, flags & MNTDF_INODES); if (flags & MNTDF_COOKED) { int i; @@ -4784,6 +4801,8 @@ static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags, } for (tp = types; tp->st_name != NULL; tp++) { + bool have_ost = false; + if (!(tp->st_op & ops)) continue; @@ -4805,6 +4824,20 @@ static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags, rc = rc2; } + /* If we have OSTs then don't report MDT block counts. + * For MDT-only filesystems the expectation is that all + * layouts have a DoM component. For filesystems with + * OSTs, files are not necessarily going to store data + * on MDTs, and MDT space is limited to a fraction of + * OST space, so don't include it in the summary. + */ + if (tp->st_op == LL_STATFS_LOV && !have_ost) { + have_ost = true; + sum.os_blocks = 0; + sum.os_bfree = 0; + sum.os_bavail = 0; + } + if (poolname && tp->st_op == LL_STATFS_LOV && llapi_search_ost(fsname, poolname, obd_uuid2str(&uuid_buf)) != 1) @@ -4828,20 +4861,21 @@ static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags, obd_uuid2str(&uuid_buf), flags, tp->st_name, index, rc2); - if (rc2 == 0) { - if (tp->st_op == LL_STATFS_LMV) { - sum.os_ffree += stat_buf.os_ffree; - sum.os_files += stat_buf.os_files; - } else /* if (tp->st_op == LL_STATFS_LOV) */ { - sum.os_blocks += stat_buf.os_blocks * - stat_buf.os_bsize; - sum.os_bfree += stat_buf.os_bfree * - stat_buf.os_bsize; - sum.os_bavail += stat_buf.os_bavail * - stat_buf.os_bsize; - ost_ffree += stat_buf.os_ffree; - } + if (rc2) + continue; + + if (tp->st_op == LL_STATFS_LMV) { + sum.os_ffree += stat_buf.os_ffree; + sum.os_files += stat_buf.os_files; + } else /* if (tp->st_op == LL_STATFS_LOV) */ { + ost_ffree += stat_buf.os_ffree; } + sum.os_blocks += stat_buf.os_blocks * + stat_buf.os_bsize; + sum.os_bfree += stat_buf.os_bfree * + stat_buf.os_bsize; + sum.os_bavail += stat_buf.os_bavail * + stat_buf.os_bsize; } } @@ -4870,8 +4904,8 @@ static int ll_statfs_data_comp(const void *sd1, const void *sd2) sd_st; const struct obd_statfs *st2 = &((const struct ll_statfs_data *)sd2)-> sd_st; - int r1 = obd_statfs_ratio(st1); - int r2 = obd_statfs_ratio(st2); + int r1 = obd_statfs_ratio(st1, false); + int r2 = obd_statfs_ratio(st2, false); int64_t result = r1 - r2; /* if both space usage are above 90, compare free inodes */ @@ -5151,8 +5185,8 @@ static int lfs_setdirstripe(int argc, char **argv) /* don't use server whose usage is above 90% */ while (nr != param->lsp_stripe_count && - obd_statfs_ratio(&lsb->sb_buf[nr].sd_st) - > 90) + obd_statfs_ratio(&lsb->sb_buf[nr].sd_st, + false) > 90) nr = MAX(param->lsp_stripe_count, nr / 2); @@ -5391,12 +5425,13 @@ static int lfs_getname(int argc, char **argv) static int lfs_check(int argc, char **argv) { - int rc; - char mntdir[PATH_MAX] = {'\0'}; - int num_types = 1; - char *obd_types[2]; - char obd_type1[4]; - char obd_type2[4]; + char mntdir[PATH_MAX] = {'\0'}; + int num_types = 1; + char *obd_types[3]; + char obd_type1[4]; + char obd_type2[4]; + char obd_type3[4]; + int rc; if (argc != 2) { fprintf(stderr, "%s check: server type must be specified\n", @@ -5404,17 +5439,23 @@ static int lfs_check(int argc, char **argv) return CMD_HELP; } - obd_types[0] = obd_type1; - obd_types[1] = obd_type2; - - if (strcmp(argv[1], "osts") == 0) { - strcpy(obd_types[0], "osc"); - } else if (strcmp(argv[1], "mds") == 0) { - strcpy(obd_types[0], "mdc"); - } else if (strcmp(argv[1], "servers") == 0) { - num_types = 2; - strcpy(obd_types[0], "osc"); - strcpy(obd_types[1], "mdc"); + obd_types[0] = obd_type1; + obd_types[1] = obd_type2; + obd_types[2] = obd_type3; + + if (strcmp(argv[1], "osts") == 0) { + strcpy(obd_types[0], "osc"); + } else if (strcmp(argv[1], "mdts") == 0 || + strcmp(argv[1], "mds") == 0) { + strcpy(obd_types[0], "mdc"); + } else if (strcmp(argv[1], "mgts") == 0) { + strcpy(obd_types[0], "mgc"); + } else if (strcmp(argv[1], "all") == 0 || + strcmp(argv[1], "servers") == 0) { + num_types = 3; + strcpy(obd_types[0], "osc"); + strcpy(obd_types[1], "mdc"); + strcpy(obd_types[2], "mgc"); } else { fprintf(stderr, "%s check: unrecognized option '%s'\n", progname, argv[1]); @@ -8271,7 +8312,7 @@ static inline int lfs_mirror_resync(int argc, char **argv) /* ignore previous file's error, continue with next file */ /* reset ioc */ - memset(ioc, 0, sizeof(__u32) * 4096); + memset(ioc, 0, sizeof(*ioc) + sizeof(__u32) * 4096); } free(ioc); @@ -8279,21 +8320,76 @@ error: return rc; } -static inline int lfs_mirror_dump(int argc, char **argv) +static inline int verify_mirror_id_by_fd(int fd, __u16 mirror_id) +{ + struct llapi_layout *layout; + int rc; + + layout = llapi_layout_get_by_fd(fd, 0); + if (layout == NULL) { + fprintf(stderr, "could not get layout.\n"); + return -EINVAL; + } + + rc = llapi_layout_comp_iterate(layout, find_mirror_id, &mirror_id); + if (rc < 0) { + fprintf(stderr, "failed to iterate layout\n"); + llapi_layout_free(layout); + + return rc; + } else if (rc == LLAPI_LAYOUT_ITER_CONT) { + fprintf(stderr, "does not find mirror with ID %u\n", mirror_id); + llapi_layout_free(layout); + + return -EINVAL; + } + llapi_layout_free(layout); + + return 0; +} + +/** + * Check whether two files are the same file + * \retval 0 same file + * \retval 1 not the same file + * \retval <0 error code + */ +static inline int check_same_file(const char *f1, const char *f2) +{ + struct stat stbuf1; + struct stat stbuf2; + + if (stat(f1, &stbuf1) < 0) { + fprintf(stderr, "%s: cannot stat file '%s': %s\n", + progname, f1, strerror(errno)); + return -errno; + } + + if (stat(f2, &stbuf2) < 0) { + fprintf(stderr, "%s: cannot stat file '%s': %s\n", + progname, f2, strerror(errno)); + return -errno; + } + + if (stbuf1.st_rdev == stbuf2.st_rdev && + stbuf1.st_ino == stbuf2.st_ino) + return 0; + + return 1; +} + +static inline int lfs_mirror_read(int argc, char **argv) { int rc = CMD_HELP; __u16 mirror_id = 0; const char *outfile = NULL; char *fname; - struct stat stbuf; int fd = 0; - struct llapi_layout *layout; int outfd; int c; - const size_t buflen = 4 << 20; void *buf; + const size_t buflen = 4 << 20; off_t pos; - struct option long_opts[] = { { .val = 'N', .name = "mirror-id", .has_arg = required_argument }, { .val = 'o', .name = "outfile", .has_arg = required_argument }, @@ -8315,6 +8411,10 @@ static inline int lfs_mirror_dump(int argc, char **argv) case 'o': outfile = optarg; break; + default: + fprintf(stderr, "%s: option '%s' unrecognized.\n", + progname, argv[optind - 1]); + return -EINVAL; } } @@ -8336,56 +8436,39 @@ static inline int lfs_mirror_dump(int argc, char **argv) /* open mirror file */ fname = argv[optind]; - if (stat(fname, &stbuf) < 0) { - fprintf(stderr, "%s %s: cannot stat file '%s': %s.\n", - progname, argv[0], fname, strerror(errno)); - return rc; - } - - if (!S_ISREG(stbuf.st_mode)) { - fprintf(stderr, "%s %s: '%s' is not a regular file.\n", - progname, argv[0], fname); - return rc; + if (outfile) { + rc = check_same_file(fname, outfile); + if (rc == 0) { + fprintf(stderr, + "%s %s: output file cannot be the mirrored file\n", + progname, argv[0]); + return -EINVAL; + } + if (rc < 0) + return rc; } fd = open(fname, O_DIRECT | O_RDONLY); if (fd < 0) { - fprintf(stderr, "%s %s: cannot open '%s': %s.\n", + fprintf(stderr, "%s %s: cannot open '%s': %s\n", progname, argv[0], fname, strerror(errno)); return rc; } /* verify mirror id */ - layout = llapi_layout_get_by_fd(fd, 0); - if (layout == NULL) { - fprintf(stderr, "%s %s: could not get layout of file '%s'.\n", - progname, argv[0], fname); - rc = -EINVAL; - goto close_fd; - } - - rc = llapi_layout_comp_iterate(layout, find_mirror_id, &mirror_id); - if (rc < 0) { - fprintf(stderr, "%s %s: failed to iterate layout of '%s'.\n", - progname, argv[0], fname); - llapi_layout_free(layout); - goto close_fd; - } else if (rc == LLAPI_LAYOUT_ITER_CONT) { + rc = verify_mirror_id_by_fd(fd, mirror_id); + if (rc) { fprintf(stderr, - "%s %s: file '%s' does not contain mirror with ID %u\n", - progname, argv[0], fname, mirror_id); - llapi_layout_free(layout); - - rc = -EINVAL; + "%s %s: cannot find mirror with ID %u in '%s'\n", + progname, argv[0], mirror_id, fname); goto close_fd; } - llapi_layout_free(layout); /* open output file */ if (outfile) { outfd = open(outfile, O_EXCL | O_WRONLY | O_CREAT, 0644); if (outfd < 0) { - fprintf(stderr, "%s %s: cannot create file '%s':%s.\n", + fprintf(stderr, "%s %s: cannot create file '%s': %s\n", progname, argv[0], outfile, strerror(errno)); rc = -errno; goto close_fd; @@ -8397,7 +8480,7 @@ static inline int lfs_mirror_dump(int argc, char **argv) /* allocate buffer */ rc = posix_memalign(&buf, sysconf(_SC_PAGESIZE), buflen); if (rc) { - fprintf(stderr, "%s %s: posix_memalign returns %d.\n", + fprintf(stderr, "%s %s: posix_memalign returns %d\n", progname, argv[0], rc); goto close_outfd; } @@ -8411,7 +8494,7 @@ static inline int lfs_mirror_dump(int argc, char **argv) if (bytes_read < 0) { rc = bytes_read; fprintf(stderr, - "%s %s: fail to read data from mirror %u:%s.\n", + "%s %s: fail to read data from mirror %u: %s\n", progname, argv[0], mirror_id, strerror(-rc)); goto free_buf; } @@ -8427,7 +8510,7 @@ static inline int lfs_mirror_dump(int argc, char **argv) bytes_read - written); if (written2 < 0) { fprintf(stderr, - "%s %s: fail to write %s:%s.\n", + "%s %s: fail to write %s: %s\n", progname, argv[0], outfile ? : "STDOUT", strerror(errno)); rc = -errno; @@ -8461,6 +8544,205 @@ close_fd: return rc; } +static inline int lfs_mirror_write(int argc, char **argv) +{ + int rc = CMD_HELP; + __u16 mirror_id = 0; + const char *inputfile = NULL; + char *fname; + int fd = 0; + int inputfd; + int c; + void *buf; + const size_t buflen = 4 << 20; + off_t pos; + size_t page_size = sysconf(_SC_PAGESIZE); + struct ll_ioc_lease_id ioc; + + struct option long_opts[] = { + { .val = 'N', .name = "mirror-id", .has_arg = required_argument }, + { .val = 'i', .name = "inputfile", .has_arg = required_argument }, + { .name = NULL } }; + + while ((c = getopt_long(argc, argv, "N:i:", long_opts, NULL)) >= 0) { + char *end; + + switch (c) { + case 'N': + mirror_id = strtoul(optarg, &end, 0); + if (*end != '\0' || mirror_id == 0) { + fprintf(stderr, + "%s %s: invalid mirror ID '%s'\n", + progname, argv[0], optarg); + return rc; + } + break; + case 'i': + inputfile = optarg; + break; + default: + fprintf(stderr, "%s: option '%s' unrecognized\n", + progname, argv[optind - 1]); + return -EINVAL; + } + } + + if (argc == optind) { + fprintf(stderr, "%s %s: no mirrored file provided\n", + progname, argv[0]); + return rc; + } else if (argc > optind + 1) { + fprintf(stderr, "%s %s: too many files\n", progname, argv[0]); + return rc; + } + + if (mirror_id == 0) { + fprintf(stderr, "%s %s: no valid mirror ID is provided\n", + progname, argv[0]); + return rc; + } + + /* open mirror file */ + fname = argv[optind]; + + if (inputfile) { + rc = check_same_file(fname, inputfile); + if (rc == 0) { + fprintf(stderr, + "%s %s: input file cannot be the mirrored file\n", + progname, argv[0]); + return -EINVAL; + } + if (rc < 0) + return rc; + } + + fd = open(fname, O_DIRECT | O_WRONLY); + if (fd < 0) { + fprintf(stderr, "%s %s: cannot open '%s': %s\n", + progname, argv[0], fname, strerror(errno)); + return rc; + } + + /* verify mirror id */ + rc = verify_mirror_id_by_fd(fd, mirror_id); + if (rc) { + fprintf(stderr, + "%s %s: cannot find mirror with ID %u in '%s'\n", + progname, argv[0], mirror_id, fname); + goto close_fd; + } + + /* open input file */ + if (inputfile) { + inputfd = open(inputfile, O_RDONLY, 0644); + if (inputfd < 0) { + fprintf(stderr, "%s %s: cannot open file '%s': %s\n", + progname, argv[0], inputfile, strerror(errno)); + rc = -errno; + goto close_fd; + } + } else { + inputfd = STDIN_FILENO; + } + + /* allocate buffer */ + rc = posix_memalign(&buf, page_size, buflen); + if (rc) { + fprintf(stderr, "%s %s: posix_memalign returns %d\n", + progname, argv[0], rc); + goto close_inputfd; + } + + /* prepare target mirror components instantiation */ + ioc.lil_mode = LL_LEASE_WRLCK; + ioc.lil_flags = LL_LEASE_RESYNC; + ioc.lil_mirror_id = mirror_id; + rc = llapi_lease_set(fd, (struct ll_ioc_lease *)&ioc); + if (rc < 0) { + fprintf(stderr, + "%s %s: '%s' llapi_lease_get_ext failed: %s\n", + progname, argv[0], fname, strerror(errno)); + goto free_buf; + } + + pos = 0; + while (1) { + ssize_t bytes_read; + ssize_t written; + size_t to_write; + + rc = llapi_lease_check(fd); + if (rc != LL_LEASE_WRLCK) { + fprintf(stderr, "%s %s: '%s' lost lease lock\n", + progname, argv[0], fname); + goto free_buf; + } + + bytes_read = read(inputfd, buf, buflen); + if (bytes_read < 0) { + rc = bytes_read; + fprintf(stderr, + "%s %s: fail to read data from '%s': %s\n", + progname, argv[0], inputfile ? : "STDIN", + strerror(errno)); + rc = -errno; + goto free_buf; + } + + /* EOF reached */ + if (bytes_read == 0) + break; + + /* round up to page align to make direct IO happy. */ + to_write = (bytes_read + page_size - 1) & ~(page_size - 1); + + written = llapi_mirror_write(fd, mirror_id, buf, to_write, + pos); + if (written < 0) { + rc = written; + fprintf(stderr, + "%s %s: fail to write to mirror %u: %s\n", + progname, argv[0], mirror_id, + strerror(-rc)); + goto free_buf; + } + + pos += bytes_read; + } + + if (pos & (page_size - 1)) { + rc = llapi_mirror_truncate(fd, mirror_id, pos); + if (rc < 0) + goto free_buf; + } + + ioc.lil_mode = LL_LEASE_UNLCK; + ioc.lil_flags = LL_LEASE_RESYNC_DONE; + ioc.lil_count = 0; + rc = llapi_lease_set(fd, (struct ll_ioc_lease *)&ioc); + if (rc <= 0) { + if (rc == 0) + rc = -EBUSY; + fprintf(stderr, + "%s %s: release lease lock of '%s' failed: %s\n", + progname, argv[0], fname, strerror(errno)); + goto free_buf; + } + + rc = 0; + +free_buf: + free(buf); +close_inputfd: + if (inputfile) + close(inputfd); +close_fd: + close(fd); + + return rc; +} + /** * struct verify_chunk - Mirror chunk to be verified. * @chunk: [start, end) of the chunk. @@ -9057,7 +9339,7 @@ static inline int lfs_mirror_verify(int argc, char **argv) verbose++; break; default: - fprintf(stderr, "%s: options '%s' unrecognized.\n", + fprintf(stderr, "%s: option '%s' unrecognized.\n", progname, argv[optind - 1]); rc = -EINVAL; goto error; @@ -9183,8 +9465,9 @@ static int lfs_getsom(int argc, char **argv) attrs = (void *)buf; rc = lgetxattr(path, "trusted.som", attrs, sizeof(buf)); if (rc < 0) { - fprintf(stderr, "%s failed to get som xattr: %s\n", argv[0], - strerror(-rc)); + rc = -errno; + fprintf(stderr, "%s failed to get som xattr: %s (%d)\n", + argv[0], strerror(errno), errno); return rc; } @@ -9210,7 +9493,7 @@ static int lfs_getsom(int argc, char **argv) return CMD_HELP; } - return rc; + return 0; } /**