}
run_test 806 "Verify Lazy Size on MDS"
-test_807() {
- [ -n "$FILESET" ] && skip "Not functional for FILESET set"
- [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
+verify_som_sync_utility() {
+ local utility=$1
+ local use_llsom_sync=false
+
+ [[ -z "$FILESET" ]] || skip "Not functional for FILESET set"
+ [[ $MDS1_VERSION -ge $(version_code 2.11.52) ]] ||
skip "Need MDS version at least 2.11.52"
- # Registration step
- changelog_register || error "changelog_register failed"
- local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
- changelog_users $SINGLEMDS | grep -q $cl_user ||
- error "User $cl_user not found in changelog_users"
+ case $utility in
+ llsom_sync ) use_llsom_sync=true ;;
+ somsync ) use_llsom_sync=false ;;
+ *) error "invalid utility $utility" ;;
+ esac
+
+ if $use_llsom_sync; then
+ # Registration step
+ changelog_register || error "changelog_register failed"
+ local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
+ changelog_users $SINGLEMDS | grep -q $cl_user ||
+ error "User $cl_user not found in changelog_users"
+ fi
rm -rf $DIR/$tdir || error "rm $tdir failed"
mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
# multi-client wirtes
local num=$(get_node_count ${CLIENTS//,/ })
local offset=0
- local i=0
+ local -a pids
echo "Test SOM for multi-client ($num) writes"
touch $DIR/$tfile || error "touch $tfile failed"
$TRUNCATE $DIR/$tfile 0
for client in ${CLIENTS//,/ }; do
do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
- local pids[$i]=$!
- i=$((i + 1))
- offset=$((offset + $bs))
- done
- for (( i=0; i < $num; i++ )); do
- wait ${pids[$i]}
+ pids+=( $! )
+ offset=$((offset + bs))
done
+ wait ${pids[@]}
do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
- $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
+
+ if $use_llsom_sync; then
+ $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT ||
+ error "$LSOM_SYNC failed"
+ else
+ $LFS somsync $DIR/$tfile ||
+ error "$LFS somsync $DIR/$tfile failed"
+ find $DIR/$tdir -type f | xargs $LFS path2fid |
+ awk '{print $2}' | xargs $LFS somsync --by-fid $DIR ||
+ error "$LFS somsync --by-fid $DIR failed"
+ fi
+
check_lsom_data $DIR/$tdir/trunc "(0)"
check_lsom_data $DIR/$tdir/single_dd "(1)"
check_lsom_data $DIR/$tfile "(2)"
rm -rf $DIR/$tdir
# Deregistration step
- changelog_deregister || error "changelog_deregister failed"
+ ! $use_llsom_sync || changelog_deregister ||
+ error "changelog_deregister failed"
+}
+
+test_807a() {
+ verify_som_sync_utility llsom_sync
+}
+run_test 807a "verify LSOM syncing tool"
+
+test_807b() {
+ verify_som_sync_utility somsync
}
-run_test 807 "verify LSOM syncing tool"
+run_test 807b "verify lfs somsync utility"
check_som_nologged()
{
static int lfs_mv(int argc, char **argv);
static int lfs_ladvise(int argc, char **argv);
static int lfs_getsom(int argc, char **argv);
+static int lfs_somsync(int argc, char **argv);
static int lfs_heat_get(int argc, char **argv);
static int lfs_heat_set(int argc, char **argv);
static int lfs_mirror(int argc, char **argv);
"\t-s: Only show the size value of the SOM data for a given file\n"
"\t-b: Only show the blocks value of the SOM data for a given file\n"
"\t-f: Only show the flags value of the SOM data for a given file\n"},
+ {"somsync", lfs_somsync, 0,
+ "Synchronize SOM xattr(s) for given file(s) or FID(s).\n"
+ "usage: somsync FILE ...\n"
+ " somsync --by-fid MOUNT FID ...\n"},
{"heat_get", lfs_heat_get, 0,
"To get heat of files.\n"
"usage: heat_get <file> ...\n"},
return 0;
}
+static inline int lfs_somsync_by_fd(int fd)
+{
+ struct stat st;
+ int rc = 0;
+
+ /* flush dirty pages from clients */
+ rc = llapi_fsync(fd);
+ if (rc < 0)
+ goto out;
+
+ rc = fstat(fd, &st);
+ if (rc < 0)
+ rc = -errno;
+
+ /*
+ * After call fstat(), it already gets OST attrs to the client,
+ * when close the file, MDS will update the LSOM data itself
+ * according the size and blocks information from the client.
+ */
+out:
+ close(fd);
+ return rc;
+}
+
+static inline int lfs_somsync_by_path(const char *fname)
+{
+ int fd;
+ int rc = 0;
+
+ fd = open(fname, O_RDONLY | O_NOATIME);
+ if (fd < 0) {
+ rc = -errno;
+ fprintf(stderr,
+ "%s somsync: cannot open '%s': %s\n",
+ progname, fname, strerror(errno));
+ return rc;
+ }
+
+ rc = lfs_somsync_by_fd(fd);
+ if (rc < 0) {
+ fprintf(stderr,
+ "%s somsync: cannot synchronize SOM data of '%s': %s\n",
+ progname, fname, strerror(-rc));
+ return rc;
+ }
+
+ return 0;
+}
+
+static inline int lfs_somsync_by_fid(const char *lustre_dir,
+ const struct lu_fid *fid)
+{
+ int fd = -1;
+ char fidstr[FID_LEN];
+ int rc = 0;
+
+ snprintf(fidstr, sizeof(fidstr), DFID, PFID(fid));
+ fd = llapi_open_by_fid(lustre_dir, fid, O_RDONLY | O_NOATIME);
+ if (fd < 0) {
+ rc = -errno;
+ fprintf(stderr,
+ "%s somsync: cannot open '%s': %s\n",
+ progname, fidstr, strerror(-rc));
+ return rc;
+ }
+
+ rc = lfs_somsync_by_fd(fd);
+ if (rc < 0) {
+ fprintf(stderr,
+ "%s somsync: cannot synchronize SOM data of '%s': %s\n",
+ progname, fidstr, strerror(-rc));
+ return rc;
+ }
+
+ return 0;
+}
+
+enum {
+ LFS_SOMSYNC_CLIENT_MOUNT = 1,
+};
+
+static int lfs_somsync(int argc, char **argv)
+{
+ struct option long_opts[] = {
+ { "by-fid", required_argument, NULL, LFS_SOMSYNC_CLIENT_MOUNT },
+ { NULL },
+ };
+ const char *client_mount = NULL;
+ int c;
+ int rc = 0, rc1;
+
+ while ((c = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
+ switch (c) {
+ case LFS_SOMSYNC_CLIENT_MOUNT:
+ client_mount = optarg;
+ break;
+ default:
+ fprintf(stderr,
+ "%s somsync: unrecognized option '%s'\n",
+ progname, argv[optind - 1]);
+ return CMD_HELP;
+ }
+ }
+
+ if (client_mount != NULL) {
+ /* lfs somsync --by-fid MOUNT FID ... */
+ char mntdir[PATH_MAX];
+ struct lu_fid fid;
+ char *fidstr;
+ int found;
+
+ if (argc == optind) {
+ fprintf(stderr, "%s somsync: missing FID\n", progname);
+ return CMD_HELP;
+ }
+
+ rc = llapi_search_mounts(client_mount, 0, mntdir, NULL);
+ if (rc < 0) {
+ fprintf(stderr,
+ "%s somsync: invalid MOUNT '%s': %s\n",
+ progname, client_mount, strerror(-rc));
+ return rc;
+ }
+
+ rc = 0;
+ while (optind < argc) {
+ found = 0;
+
+ fidstr = argv[optind++];
+ while (*fidstr == '[')
+ fidstr++;
+ found = sscanf(fidstr, SFID, RFID(&fid));
+ if (found != 3) {
+ fprintf(stderr,
+ "%s somsync: unrecognized FID: %s\n",
+ progname, argv[optind - 1]);
+ return -EINVAL;
+ }
+
+ rc1 = lfs_somsync_by_fid(mntdir, &fid);
+ if (rc1 && !rc)
+ rc = rc1;
+ }
+
+ return rc;
+ }
+
+ /* lfs somsync FILE ... */
+ if (argc == optind) {
+ fprintf(stderr, "%s somsync: missing FILE\n", progname);
+ return CMD_HELP;
+ }
+
+ rc = 0;
+ while (optind < argc) {
+ rc1 = lfs_somsync_by_path(argv[optind++]);
+ if (rc1 && !rc)
+ rc = rc1;
+ }
+
+ return rc;
+}
+
/**
* Check whether two files are the same file
* \retval 0 same file