.br
.B lreplicate --source|-s <src> --target|-t <tgt>
.br
-.B\t\t\t --mdt|-m <mdt> --user|-u <user id> --xattr|-x <yes|no>
+.B\t\t\t --mdt|-m <mdt> [--user|-u <user id>]
.br
-.B\t\t\t --verbose|-v --statuslog|-l <log> --dry-run
+.B\t\t\t [--xattr|-x <yes|no>] [--verbose|-v]
+.br
+.B\t\t\t [--statuslog|-l <log>] [--dry-run] [--abort-on-err]
.br
.br
.br
Shows what the program would do without actually replicating data.
+.B --abort-on-err
+.br
+Stop processing upon first error. Default is to continue processing.
+
.SH EXAMPLES
.TP
if UTILS
pkginclude_HEADERS = lustre_idl.h lustre_user.h liblustreapi.h libiam.h \
- ll_fiemap.h lreplicate.h
+ ll_fiemap.h
endif
-EXTRA_DIST = lustre_idl.h lustre_user.h liblustreapi.h libiam.h ll_fiemap.h \
- lreplicate.h
+EXTRA_DIST = lustre_idl.h lustre_user.h liblustreapi.h libiam.h ll_fiemap.h
long long endrec);
extern int llapi_changelog_register(const char *mdtname);
extern int llapi_changelog_unregister(const char *mdtname, int id);
-struct lu_fid;
extern int llapi_fid2path(char *device, char *fid, char *path, int pathlen,
long long *recno, int *linkno);
#endif
__u32 cs_id;
} __attribute__((packed));
-/** fid2path request/reply structure */
-struct getinfo_fid2path {
- struct lu_fid gf_fid;
- __u64 gf_recno;
- __u32 gf_linkno;
- __u32 gf_pathlen;
- char gf_path[0];
-};
-
-void lustre_swab_fid2path (struct getinfo_fid2path *gf);
-
/** changelog record */
struct llog_changelog_rec {
struct llog_rec_hdr cr_hdr;
char lee_name[0];
};
+/** fid2path request/reply structure */
+struct getinfo_fid2path {
+ struct lu_fid gf_fid;
+ __u64 gf_recno;
+ __u32 gf_linkno;
+ __u32 gf_pathlen;
+ char gf_path[0];
+} __attribute__((packed));
+
+void lustre_swab_fid2path (struct getinfo_fid2path *gf);
+
+
#endif
/** @} lustreidl */
# define offsetof(typ,memb) ((unsigned long)((char *)&(((typ *)0)->memb)))
#endif
-#define mdd_dot_lustre_name ".lustre"
+#define dot_lustre_name ".lustre"
#endif /* _LUSTRE_USER_H */
OBD_FREE_PTR(icc);
RETURN(rc);
}
+ case OBD_IOC_FID2PATH:
+ RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
default:
RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp,0,NULL,(void *)arg));
RETURN(rc);
}
+int ll_fid2path(struct obd_export *exp, void *arg)
+{
+ struct getinfo_fid2path *gfout, *gfin;
+ int outsize, rc;
+ ENTRY;
+
+ /* Need to get the buflen */
+ OBD_ALLOC_PTR(gfin);
+ if (gfin == NULL)
+ RETURN(-ENOMEM);
+ if (copy_from_user(gfin, arg, sizeof(*gfin))) {
+ OBD_FREE_PTR(gfin);
+ RETURN(-EFAULT);
+ }
+
+ outsize = sizeof(*gfout) + gfin->gf_pathlen;
+ OBD_ALLOC(gfout, outsize);
+ if (gfout == NULL) {
+ OBD_FREE_PTR(gfin);
+ RETURN(-ENOMEM);
+ }
+ memcpy(gfout, gfin, sizeof(*gfout));
+ OBD_FREE_PTR(gfin);
+
+ /* Call mdc_iocontrol */
+ rc = obd_iocontrol(OBD_IOC_FID2PATH, exp, outsize, gfout, NULL);
+ if (rc)
+ GOTO(gf_free, rc);
+ if (copy_to_user(arg, gfout, outsize))
+ rc = -EFAULT;
+
+gf_free:
+ OBD_FREE(gfout, outsize);
+ RETURN(rc);
+}
+
int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
RETURN(0);
}
+ case OBD_IOC_FID2PATH:
+ RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
+
default: {
int err;
int ll_merge_lvb(struct inode *inode);
int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg);
int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
+int ll_fid2path(struct obd_export *exp, void *arg);
/* llite/dcache.c */
/* llite/namei.c */
RETURN(0);
}
-/* This routine is quite similar to mdt_ioc_fid2path() */
-int mdc_ioc_fid2path(struct obd_export *exp, struct obd_ioctl_data *data)
+static int mdc_ioc_fid2path(struct obd_export *exp, struct getinfo_fid2path *gf)
{
- struct getinfo_fid2path *fp = NULL;
- int keylen = size_round(sizeof(KEY_FID2PATH)) + sizeof(*fp);
- int pathlen = data->ioc_plen1;
- __u32 vallen = pathlen + sizeof(*fp);
- int alloclen = keylen + vallen;
- void *buf;
+ __u32 keylen, vallen;
+ void *key;
int rc;
- if (pathlen > PATH_MAX)
- RETURN(-EINVAL);
- if (pathlen < 2)
- RETURN(-EINVAL);
+ if (gf->gf_pathlen > PATH_MAX)
+ RETURN(-ENAMETOOLONG);
+ if (gf->gf_pathlen < 2)
+ RETURN(-EOVERFLOW);
- OBD_ALLOC(buf, alloclen);
- if (buf == NULL)
+ /* Key is KEY_FID2PATH + getinfo_fid2path description */
+ keylen = size_round(sizeof(KEY_FID2PATH)) + sizeof(*gf);
+ OBD_ALLOC(key, keylen);
+ if (key == NULL)
RETURN(-ENOMEM);
- fp = buf + size_round(sizeof(KEY_FID2PATH));
- memcpy(buf, KEY_FID2PATH, sizeof(KEY_FID2PATH));
- memcpy(&fp->gf_fid, data->ioc_inlbuf1, sizeof(struct lu_fid));
- memcpy(&fp->gf_recno, data->ioc_inlbuf2, sizeof(fp->gf_recno));
- memcpy(&fp->gf_linkno, data->ioc_inlbuf3,
- sizeof(fp->gf_linkno));
- fp->gf_pathlen = pathlen;
+ memcpy(key, KEY_FID2PATH, sizeof(KEY_FID2PATH));
+ memcpy(key + size_round(sizeof(KEY_FID2PATH)), gf, sizeof(*gf));
CDEBUG(D_IOCTL, "path get "DFID" from "LPU64" #%d\n",
- PFID(&fp->gf_fid), fp->gf_recno, fp->gf_linkno);
+ PFID(&gf->gf_fid), gf->gf_recno, gf->gf_linkno);
- if (!fid_is_sane(&fp->gf_fid))
+ if (!fid_is_sane(&gf->gf_fid))
GOTO(out, rc = -EINVAL);
- rc = obd_get_info(exp, keylen, buf, &vallen, fp, NULL);
+ /* Val is struct getinfo_fid2path result plus path */
+ vallen = sizeof(*gf) + gf->gf_pathlen;
+
+ rc = obd_get_info(exp, keylen, key, &vallen, gf, NULL);
if (rc)
GOTO(out, rc);
- if (vallen < sizeof(*fp) + 1)
+ if (vallen <= sizeof(*gf))
GOTO(out, rc = -EPROTO);
- else if (vallen - sizeof(*fp) > pathlen)
+ else if (vallen > sizeof(*gf) + gf->gf_pathlen)
GOTO(out, rc = -EOVERFLOW);
- if (copy_to_user(data->ioc_pbuf1, fp->gf_path,
- pathlen))
- GOTO(out, rc = -EFAULT);
- memcpy(data->ioc_inlbuf2, &fp->gf_recno, sizeof(fp->gf_recno));
- memcpy(data->ioc_inlbuf3, &fp->gf_linkno,
- sizeof(fp->gf_linkno));
-out:
- OBD_FREE(buf, alloclen);
+ CDEBUG(D_IOCTL, "path get "DFID" from "LPU64" #%d\n%s\n",
+ PFID(&gf->gf_fid), gf->gf_recno, gf->gf_linkno, gf->gf_path);
+out:
+ OBD_FREE(key, keylen);
return rc;
}
GOTO(out, rc);
}
case OBD_IOC_FID2PATH: {
- rc = mdc_ioc_fid2path(exp, data);
+ rc = mdc_ioc_fid2path(exp, karg);
GOTO(out, rc);
}
case OBD_IOC_CLIENT_RECOVER:
ptlrpc_request_set_replen(req);
rc = ptlrpc_queue_wait(req);
- if (!rc) {
+ if (rc == 0) {
tmp = req_capsule_server_get(&req->rq_pill, &RMF_GETINFO_VAL);
memcpy(val, tmp, vallen);
if (lustre_msg_swabbed(req->rq_repmsg)) {
memcpy(fid, &LU_DOT_LUSTRE_FID, sizeof(struct lu_fid));
mdo = llo_store_create_index(env, &m->mdd_md_dev, m->mdd_child,
- mdd_root_dir_name, mdd_dot_lustre_name,
+ mdd_root_dir_name, dot_lustre_name,
fid, &dt_directory_features);
/* .lustre dir may be already present */
if (IS_ERR(mdo) && PTR_ERR(mdo) != -EEXIST) {
rc = PTR_ERR(mdo);
CERROR("creating obj [%s] fid = "DFID" rc = %d\n",
- mdd_dot_lustre_name, PFID(fid), rc);
+ dot_lustre_name, PFID(fid), rc);
RETURN(rc);
}
return rc;
dt_dot_lustre = dt_store_open(env, m->mdd_child, mdd_root_dir_name,
- mdd_dot_lustre_name, fid);
+ dot_lustre_name, fid);
if (IS_ERR(dt_dot_lustre)) {
rc = PTR_ERR(dt_dot_lustre);
GOTO(out, rc);
RETURN(0);
}
-/* This routine is quite similar to mdc_ioc_fid2path() */
-static int mdt_ioc_fid2path(struct lu_env *env, struct mdt_device *mdt,
- struct obd_ioctl_data *data)
-{
- struct getinfo_fid2path *fp = NULL;
- int pathlen;
- int alloclen;
- int rc;
-
- ENTRY;
-
- pathlen = data->ioc_plen1;
- if (pathlen > PATH_MAX)
- GOTO(out, rc = -EINVAL);
- if (pathlen < 2)
- GOTO(out, rc = -EINVAL);
-
- alloclen = sizeof(*fp) + pathlen;
- OBD_ALLOC(fp, alloclen);
- if (fp == NULL)
- GOTO(out, rc = -ENOMEM);
-
- memcpy(&fp->gf_fid, data->ioc_inlbuf1, sizeof(struct lu_fid));
- memcpy(&fp->gf_recno, data->ioc_inlbuf2, sizeof(fp->gf_recno));
- memcpy(&fp->gf_linkno, data->ioc_inlbuf3,
- sizeof(fp->gf_linkno));
- fp->gf_pathlen = pathlen;
-
- if (!fid_is_sane(&fp->gf_fid))
- GOTO(out, rc = -EINVAL);
-
- rc = mdt_fid2path(env, mdt, fp);
-
- if (!rc && copy_to_user(data->ioc_pbuf1, fp->gf_path, pathlen))
- GOTO(out, rc = -EFAULT);
- memcpy(data->ioc_inlbuf2, &fp->gf_recno, sizeof(fp->gf_recno));
- memcpy(data->ioc_inlbuf3, &fp->gf_linkno, sizeof(fp->gf_linkno));
-out:
- if (fp)
- OBD_FREE(fp, alloclen);
- RETURN(rc);
-}
-
static int mdt_rpc_fid2path(struct mdt_thread_info *info, void *key,
- int keylen, void *val, int vallen)
+ void *val, int vallen)
{
struct lu_env env;
struct mdt_device *mdt = mdt_dev(info->mti_exp->exp_obd->obd_lu_dev);
- struct ptlrpc_request *req = mdt_info_req(info);
struct getinfo_fid2path *fpout, *fpin;
int rc = 0;
fpin = key + size_round(sizeof(KEY_FID2PATH));
fpout = val;
- if (lustre_msg_swabbed(req->rq_reqmsg))
+ if (lustre_msg_swabbed(mdt_info_req(info)->rq_reqmsg))
lustre_swab_fid2path(fpin);
memcpy(fpout, fpin, sizeof(*fpin));
static int mdt_get_info(struct mdt_thread_info *info)
{
+ struct ptlrpc_request *req = mdt_info_req(info);
char *key;
- int keysize;
int keylen;
- __u32 *valin;
- __u32 vallen;
- int valsize;
+ __u32 *vallen;
void *valout;
int rc;
- struct ptlrpc_request *req = mdt_info_req(info);
-
ENTRY;
key = req_capsule_client_get(info->mti_pill, &RMF_GETINFO_KEY);
CDEBUG(D_IOCTL, "No GETINFO key");
RETURN(-EFAULT);
}
- keysize = req_capsule_get_size(info->mti_pill, &RMF_GETINFO_KEY,
+ keylen = req_capsule_get_size(info->mti_pill, &RMF_GETINFO_KEY,
RCL_CLIENT);
- keylen = strnlen(key, keysize);
- valin = req_capsule_client_get(info->mti_pill, &RMF_GETINFO_VALLEN);
- if (valin == NULL) {
+ vallen = req_capsule_client_get(info->mti_pill, &RMF_GETINFO_VALLEN);
+ if (vallen == NULL) {
CDEBUG(D_IOCTL, "Unable to get RMF_GETINFO_VALLEN buffer");
RETURN(-EFAULT);
}
- valsize = req_capsule_get_size(info->mti_pill, &RMF_GETINFO_VALLEN,
- RCL_CLIENT);
- if (valsize != sizeof(vallen)) {
- CDEBUG(D_IOCTL, "RMF_GETINFO_VALLEN has invalid size");
- RETURN(-EINVAL);
- }
- vallen = *valin;
req_capsule_set_size(info->mti_pill, &RMF_GETINFO_VAL, RCL_SERVER,
- vallen);
+ *vallen);
rc = req_capsule_server_pack(info->mti_pill);
valout = req_capsule_server_get(info->mti_pill, &RMF_GETINFO_VAL);
if (valout == NULL) {
}
if (KEY_IS(KEY_FID2PATH))
- rc = mdt_rpc_fid2path(info, key, keysize, valout, vallen);
+ rc = mdt_rpc_fid2path(info, key, valout, *vallen);
else
rc = -EINVAL;
target_stop_recovery_thread(obd);
rc = 0;
break;
- case OBD_IOC_FID2PATH:
- rc = mdt_ioc_fid2path(&env, mdt, karg);
- break;
case OBD_IOC_CHANGELOG_REG:
case OBD_IOC_CHANGELOG_DEREG:
case OBD_IOC_CHANGELOG_CLEAR:
export LREPLICATE=${LREPLICATE:-"$LUSTRE/utils/lreplicate"}
[ ! -f "$LREPLICATE" ] && export LREPLICATE=$(which lreplicate)
+export LREPLICATE="$LREPLICATE -v" # -a
# control the time of tests
DBENCH_TIME=${DBENCH_TIME:-60} # No of seconds to run dbench
ln -s $DIR/$tdir/d1/link1 $DIR/$tdir/d1/link3
# Device files
- mknod $DIR/$tdir/dev1 b 8 1
+ #mknod $DIR/$tdir/dev1 b 8 1
# Replicate
echo "Replication #1"
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
# Set attributes
chmod 000 $DIR/$tdir/d2/file3
fi
echo "Replication #2"
- $LREPLICATE -l $LREPL_LOG -v
+ $LREPLICATE -l $LREPL_LOG
if [ "$xattr" == "yes" ]; then
local xval1=$(getfattr -n user.foo --absolute-names --only-values \
fi
RC=0
- if [[ ! -b $TGT/$tdir/dev1 ]] || [[ ! -b $TGT2/$tdir/dev1 ]]; then
- ls -l $DIR/$tdir/dev1 $TGT/$tdir/dev1 $TGT2/$tdir/dev1
- error "Error replicating block devices"
- RC=1
- elif [[ "$xattr" == "yes" ]] &&
+
+ # fid2path and path2fid aren't implemented for block devices
+ #if [[ ! -b $TGT/$tdir/dev1 ]] || [[ ! -b $TGT2/$tdir/dev1 ]]; then
+ # ls -l $DIR/$tdir/dev1 $TGT/$tdir/dev1 $TGT2/$tdir/dev1
+ # error "Error replicating block devices"
+ # RC=1
+
+ if [[ "$xattr" == "yes" ]] &&
[[ "$xval1" != "bar" || "$xval2" != "bar" ]]; then
error "Error in replicating xattrs. $xval1, $xval2"
RC=1
sh rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME || error "dbench failed!"
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
# Use diff to compare the source and the destination
check_diff $DIR/$tdir $TGT/$tdir
$KILL -SIGSTOP $child_pid
echo Starting replication
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
echo Resuming dbench
$KILL -SIGSTOP $child_pid
echo Starting replication
- $LREPLICATE -l $LREPL_LOG -v
+ $LREPLICATE -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
echo "Wait for dbench to finish"
# Replicate the changes to $TGT
echo Starting replication
- $LREPLICATE -l $LREPL_LOG -v
+ $LREPLICATE -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
while [ $quit -le 1 ];
do
echo "Running lreplicate"
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m ${mds1_svc} -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m ${mds1_svc} -u $CL_USER -l $LREPL_LOG
sleep 5
pgrep dbench
if [ $? -ne 0 ]; then
createmany -o $DIR/$tdir/$tfile $numfiles || error "createmany failed!"
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
writemany -q -a $DIR/$tdir/$tfile $time $threads || error "writemany failed!"
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
unlinkmany $DIR/$tdir/$tfile $numfiles || error "unlinkmany failed!"
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
$KILL -SIGSTOP $child_pid
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
sleep 60
$KILL -SIGKILL $child_pid
- $LREPLICATE -l $LREPL_LOG -v
+ $LREPLICATE -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v &
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG &
local child_pid=$!
sleep 30
$KILL -SIGHUP $child_pid
wait
- $LREPLICATE -l $LREPL_LOG -v
+ $LREPLICATE -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v &
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG &
local child_pid=$!
sleep 30
$KILL -SIGKILL $child_pid
wait
- $LREPLICATE -l $LREPL_LOG -v
+ $LREPLICATE -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
done
# Replicate the changes to $TGT
- $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff $DIR/$tdir $TGT/$tdir
check_diff $DIR/$tdir $TGT2/$tdir
do_facet $SINGLEMDS lctl set_param -n mdd.$MDT0.changelog off
mkdir $DIR/tgt
- $LREPLICATE -s $DIR -t $DIR/tgt -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $DIR/tgt -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff ${DIR}/$tdir $DIR/tgt/$tdir
local i=0
mv $DIR/$tdir/d$i $DIR/$tdir/d0$i
done
- $LREPLICATE -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
+ $LREPLICATE -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG
check_diff ${DIR}/$tdir $TGT/$tdir
ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[')
- if [ "$($LFS fid2path ${mds1_svc} $FID | wc -l)" != "5" ]; then
- $LFS fid2path ${mds1_svc} $FID
+ if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
+ $LFS fid2path $DIR $FID
err17935 "bad link ea"
fi
# middle
rm $DIR/$tdir/$tfile
# rename
mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
- if [ "$($LFS fid2path ${mds1_svc} --link 1 $FID)" != "/$tdir/foo2/maggie" ]
+ if [ "$($LFS fid2path $DIR --link 1 $FID)" != "/$tdir/foo2/maggie" ]
then
- $LFS fid2path ${mds1_svc} $FID
+ $LFS fid2path $DIR $FID
err17935 "bad link rename"
fi
rm $DIR/$tdir/foo2/maggie
local longname=filename_avg_len_is_thirty_two_
createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 || \
error "failed to hardlink many files"
- links=$($LFS fid2path ${mds1_svc} $FID | wc -l)
+ links=$($LFS fid2path $DIR $FID | wc -l)
echo -n "${links}/1000 links in link EA"
[ ${links} -gt 60 ] || err17935 "expected at least 60 links in link EA"
unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
mkdir -p $DIR/$tdir/d2/a/b/c
mkdir -p $DIR/$tdir/d2/p/q/r
FID=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[')
- check_path "/$tdir/d2/$tfile" ${mds1_svc} $FID --link 0
+ check_path "/$tdir/d2/$tfile" $DIR $FID --link 0
ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
FID=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[')
- check_path "/$tdir/d2/a/b/c/new_file" ${mds1_svc} $FID --link 1
- check_path "/$tdir/d2/p/q/r/hlink" ${mds1_svc} $FID --link 0
+ # fid2path dir/fsname should both work
+ check_path "/$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 1
+ check_path "/$tdir/d2/p/q/r/hlink" $DIR $FID --link 0
# check that there are 2 links
- ${LFS} fid2path ${mds1_svc} $FID | wc -l | grep -q 2 || \
+ ${LFS} fid2path $DIR $FID | wc -l | grep -q 2 || \
err17935 "expected 2 links"
rm $DIR/$tdir/d2/p/q/r/hlink
- check_path "/$tdir/d2/a/b/c/new_file" ${mds1_svc} $FID --link 0
+ check_path "/$tdir/d2/a/b/c/new_file" $DIR $FID --link 0
# Doesnt work with CMD yet: 17935
return 0
}
run_test 162 "path lookup sanity"
-test_154() {
+test_169() {
# do directio so as not to populate the page cache
log "creating a 10 Mb file"
multiop $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
log "removing the temporary file"
rm -rf $DIR/$tfile || error "tmp file removal failed"
}
-run_test 154 "parallel read and truncate should not deadlock ==="
+run_test 169 "parallel read and truncate should not deadlock ==="
test_170() {
$LCTL clear # bug 18514
"Resolve the full path to a given FID. For a specific hardlink "
"specify link number <linkno>.\n"
/* "For a historical name, specify changelog record <recno>.\n" */
- "usage: fid2path <mdtname> <fid> [--link <linkno>]"/*[--rec <recno>]*/},
+ "usage: fid2path <fsname|rootpath> <fid> [--link <linkno>]"
+ /*[--rec <recno>]*/},
{"path2fid", lfs_path2fid, 0, "Display the fid for a given path.\n"
"usage: path2fid <path>"},
{"help", Parser_help, 0, "help"},
endrec = strtoll(argv[optind++], NULL, 10);
fd = llapi_changelog_open(mdd, startrec);
- if (fd < 0)
+ if (fd < 0) {
+ fprintf(stderr, "%s Can't open changelog: %s\n", argv[0],
+ strerror(errno = -fd));
return fd;
+ }
while ((len = get_next_full_line(fd, &ptr)) >= 0) {
if (len == 0) {
static int lfs_changelog_clear(int argc, char **argv)
{
long long endrec;
+ int rc;
if (argc != 4)
return CMD_HELP;
endrec = strtoll(argv[3], NULL, 10);
- return(llapi_changelog_clear(argv[1], argv[2], endrec));
+ rc = llapi_changelog_clear(argv[1], argv[2], endrec);
+ if (rc)
+ fprintf(stderr, "%s error: %s\n", argv[0],
+ strerror(errno = -rc));
+ return rc;
}
static int lfs_fid2path(int argc, char **argv)
}
if (printcur)
- fprintf(stdout, "%lld %s\n", recno, path);
+ fprintf(stdout, "%lld %s\n", rectmp, path);
else
fprintf(stdout, "%s\n", path);
#include <unistd.h>
#endif
-#include <libcfs/libcfsutil.h> /* l_ioctl */
#include <liblustre.h>
#include <lnet/lnetctl.h>
#include <obd.h>
return 0;
}
-
static int print_pool_members(char *fs, char *pool_dir, char *pool_file)
{
char path[PATH_MAX + 1];
}
/*
- * Resolve lustre fsname from pathname
+ * Find the fsname, the full path, and/or an open fd.
+ * Either the fsname or path must not be NULL
*/
-static int search_fsname(const char *pathname, char *fsname)
+#define WANT_PATH 0x1
+#define WANT_FSNAME 0x2
+#define WANT_FD 0x4
+static int get_root_path(int want, char *fsname, int *outfd, char *path)
{
+ struct mntent mnt;
+ char buf[PATH_MAX];
char *ptr;
FILE *fp;
- struct mntent *mnt = NULL;
+ int fd;
+ int rc = -ENODEV;
/* get the mount point */
fp = setmntent(MOUNTED, "r");
strerror (errno));
return -EIO;
}
- mnt = getmntent(fp);
- while ((feof(fp) == 0) && ferror(fp) == 0) {
- if (llapi_is_lustre_mnt(mnt)) {
- /* search by pathname */
- if (strncmp(mnt->mnt_dir, pathname,
- max(strlen(pathname),
- strlen(mnt->mnt_dir))) == 0) {
- ptr = strchr(mnt->mnt_fsname, '/');
- if (ptr == NULL)
- return -EINVAL;
- ptr++;
- strcpy(fsname, ptr);
- return 0;
- }
+ while (1) {
+ if (getmntent_r(fp, &mnt, buf, sizeof(buf)) == NULL)
+ break;
+
+ if (!llapi_is_lustre_mnt(&mnt))
+ continue;
+
+ ptr = strrchr(mnt.mnt_fsname, '/');
+ if (!ptr) {
+ rc = -EINVAL;
+ break;
}
- mnt = getmntent(fp);
- }
- endmntent(fp);
- return -ENOENT;
-}
+ ptr++;
-/*
- * Return an open fd to the named Lustre fs root
- */
-static int get_root_fd(char *fsname)
-{
- char *ptr;
- FILE *fp;
- struct mntent *mnt = NULL;
- int fd;
+ /* If path was specified and matches, store the fsname */
+ if ((want & WANT_FSNAME) && (strcmp(mnt.mnt_dir, path) == 0))
+ strcpy(fsname, ptr);
+ /* Else check the fsname for a match */
+ else if (strcmp(ptr, fsname) != 0)
+ continue;
- /* get the mount point */
- fp = setmntent(MOUNTED, "r");
- if (fp == NULL) {
- llapi_err(LLAPI_MSG_ERROR,
- "setmntent(%s) failed: %s:", MOUNTED,
- strerror (errno));
- return -EIO;
- }
- mnt = getmntent(fp);
- while ((feof(fp) == 0) && ferror(fp) == 0) {
- if (llapi_is_lustre_mnt(mnt)) {
- ptr = strrchr(mnt->mnt_fsname, '/');
- if (!ptr)
- return -EINVAL;
- ptr++;
-
- if (strcmp(ptr, fsname) == 0) {
- fd = open(mnt->mnt_dir, O_RDONLY | O_DIRECTORY);
- if (fd < 0) {
- perror("open");
- return -errno;
- }
- endmntent(fp);
- return fd;
+ /* Found it */
+ rc = 0;
+ if (want & WANT_PATH)
+ strcpy(path, mnt.mnt_dir);
+ if (want & WANT_FD) {
+ fd = open(mnt.mnt_dir,
+ O_RDONLY | O_DIRECTORY | O_NONBLOCK);
+ if (fd < 0) {
+ perror("open");
+ rc = -errno;
+ } else {
+ *outfd = fd;
}
}
- mnt = getmntent(fp);
+ break;
}
endmntent(fp);
- return -ENOENT;
+ if (rc)
+ llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
+ "can't find fs root for '%s': %d",
+ (want & WANT_PATH) ? fsname : path, rc);
+ return rc;
+}
+
+int llapi_search_fsname(const char *pathname, char *fsname)
+{
+ return get_root_path(WANT_FSNAME, fsname, NULL, (char *)pathname);
}
/* return the first file matching this pattern */
char buffer[PATH_MAX];
if (fsname == NULL) {
- rc = search_fsname(pathname, buffer);
+ rc = get_root_path(WANT_FSNAME, buffer, NULL, pathname);
if (rc != 0)
return rc;
fsname = buffer;
strcpy(pathname, fsname);
}
- snprintf(pattern, PATH_MAX,
- "/proc/fs/lustre/lov/%s-*/pools",
- fsname);
+ snprintf(pattern, PATH_MAX, "/proc/fs/lustre/lov/%s-*/pools", fsname);
rc = first_match(pattern, buffer);
if (rc)
return rc;
return -EINVAL;
if (!realpath(name, rname)) {
rc = -errno;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: invalid path '%s'",
- name);
+ llapi_err(LLAPI_MSG_ERROR, "invalid path '%s'", name);
return rc;
}
rc = poolpath(NULL, rname, pathname);
if (rc != 0) {
errno = -rc;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: '%s' is not"
- " a Lustre filesystem",
- name);
+ llapi_err(LLAPI_MSG_ERROR, "'%s' is not"
+ " a Lustre filesystem", name);
return rc;
}
fsname = rname;
poolname++;
}
rc = poolpath(fsname, NULL, pathname);
- if (rc != 0) {
- errno = -rc;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: Lustre filesystem '%s'"
- " not found", name);
- return rc;
- }
}
if (rc != 0) {
errno = -rc;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: Lustre filesystem '%s' not found",
+ llapi_err(LLAPI_MSG_ERROR, "Lustre filesystem '%s' not found",
name);
return rc;
}
continue;
/* Don't traverse .lustre directory */
- if (!(strcmp(dent->d_name, mdd_dot_lustre_name)))
+ if (!(strcmp(dent->d_name, dot_lustre_name)))
continue;
path[len] = 0;
char suffix[]="-MDT0000";
int len = strlen(name);
- if (len > 16) {
- llapi_err(LLAPI_MSG_ERROR, "bad MDT name |%s|\n", name);
- return -EINVAL;
+ if (len > 8) {
+ if ((len <= 16) && strncmp(name + len - 8, "-MDT", 4) == 0) {
+ suffix[0] = '\0';
+ } else {
+ /* Not enough room to add suffix */
+ llapi_err(LLAPI_MSG_ERROR, "MDT name too long |%s|\n",
+ name);
+ return -EINVAL;
+ }
}
- if ((len > 8) && (strncmp(name + len - 8, "-MDT", 4) == 0))
- suffix[0] = '\0';
-
return sprintf(buf, format, name, suffix);
}
/* Return a file descriptor to a readable changelog */
-int llapi_changelog_open(const char *mdtname, long long startrec)
+int llapi_changelog_open(const char *device, long long startrec)
{
char path[256];
+ char mdtname[17];
int rc, fd;
+ if (device[0] == '/')
+ rc = get_root_path(WANT_FSNAME, mdtname, NULL, (char *)device);
+ else
+ strncpy(mdtname, device, sizeof(mdtname));
+
/* Use either the mdd changelog (preferred) or a client mdc changelog */
if (get_mdtname(mdtname,
"/proc/fs/lustre/md[cd]/%s%s{,-mdc-*}/changelog",
long long endrec)
{
struct ioc_changelog_clear data;
+ char fsname[17];
char *ptr;
int id, fd, index, rc;
return -EINVAL;
}
- ptr = strstr(mdtname, "-MDT");
- if (!ptr)
- return -EINVAL;
- index = strtol(ptr + 1, NULL, 10);
- *ptr = '\0';
-
- fd = get_root_fd((char *)mdtname);
- if (fd < 0) {
+ /* Take path, fsname, or MDTNAME. Assume MDT0000 in the former cases */
+ if (mdtname[0] == '/') {
+ index = 0;
+ fd = open(mdtname, O_RDONLY | O_DIRECTORY | O_NONBLOCK);
+ rc = fd < 0 ? -errno : 0;
+ } else {
+ if (get_mdtname(mdtname, "%s%s", fsname) < 0)
+ return -EINVAL;
+ ptr = fsname + strlen(fsname) - 8;
+ *ptr = '\0';
+ index = strtol(ptr + 4, NULL, 10);
+ rc = get_root_path(WANT_FD, fsname, &fd, NULL);
+ }
+ if (rc < 0) {
llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
- "can't open fs root for '%s': %d", mdtname, fd);
- return fd;
+ "Can't open %s: %d\n", mdtname, rc);
+ return rc;
}
data.icc_mdtindex = index;
return rc;
}
-static int dev_ioctl(struct obd_ioctl_data *data, int dev, int cmd)
-{
- static char rawbuf[8192];
- static char *buf = rawbuf;
- int rc;
-
- data->ioc_dev = dev;
- memset(buf, 0, sizeof(rawbuf));
-
- if ((rc = obd_ioctl_pack(data, &buf, sizeof(rawbuf)))) {
- llapi_err(LLAPI_MSG_ERROR,
- "error: ioctl pack (%d) failed: rc %d", cmd, rc);
- return rc;
- }
-
- rc = l_ioctl(OBD_DEV_ID, cmd, buf);
- if (rc < 0) {
- /* ioctl returns -1 with errno set */
- rc = -errno;
- return rc;
- }
-
- if (obd_ioctl_unpack(data, buf, sizeof(rawbuf))) {
- llapi_err(LLAPI_MSG_ERROR,
- "error: invalid reply\n");
- return -EPROTO;
- }
- return rc;
-}
-
-static int dev_name2dev(char *name)
-{
- struct obd_ioctl_data data;
- int rc;
-
- memset(&data, 0, sizeof(data));
- data.ioc_inllen1 = strlen(name) + 1;
- data.ioc_inlbuf1 = name;
-
- rc = dev_ioctl(&data, -1, OBD_IOC_NAME2DEV);
- if (rc < 0)
- return rc;
-
- return data.ioc_dev;
-}
-
-int llapi_search_fsname(const char *pathname, char *fsname)
-{
- return search_fsname(pathname, fsname);
-}
-
-static void do_get_mdcname(char *obd_type_name, char *obd_name,
- char *obd_uuid, void *name)
-{
- if (strncmp(obd_name, (char *)name, strlen((char *)name)) == 0)
- strcpy((char *)name, obd_name);
-}
-
-static int get_mdcdev(const char *mdtname)
-{
- char name[MAX_OBD_NAME];
- char *type[] = { "mdc" };
- int rc;
-
- strcpy(name, mdtname);
- rc = llapi_target_iterate(1, type, (void *)name, do_get_mdcname);
- rc = rc < 0 ? : -rc;
- if (rc < 0) {
- llapi_err(LLAPI_MSG_ERROR, "Device %s not found %d\n", name,rc);
- return rc;
- }
- rc = dev_name2dev(name);
- if (rc < 0)
- llapi_err(LLAPI_MSG_ERROR, "Device %s not found %d\n", name,rc);
- return rc;
-}
-
int llapi_fid2path(char *device, char *fidstr, char *buf, int buflen,
long long *recno, int *linkno)
{
+ char path[PATH_MAX];
struct lu_fid fid;
- struct obd_ioctl_data data;
- char mdtname[256];
- int dev, rc;
+ struct getinfo_fid2path *gf;
+ int fd, rc;
while (*fidstr == '[')
fidstr++;
return -EINVAL;
}
- /* If the node is an MDS, issue the ioctl to the MDT . If not,
- issue it to the MDC. */
- rc = get_mdtname(device, "%s%s", mdtname);
- if (rc < 0)
- return rc;
- dev = dev_name2dev(mdtname);
- if (dev < 0) {
- dev = get_mdcdev(mdtname);
- if (dev < 0) {
- llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
- "can't find mdc for '%s'\n", mdtname);
- return dev;
- }
+ /* Take path or fsname */
+ if (device[0] == '/') {
+ strcpy(path, device);
+ } else {
+ rc = get_root_path(WANT_PATH, device, NULL, path);
+ if (rc < 0)
+ return rc;
}
+ sprintf(path, "%s/%s/fid/%s", path, dot_lustre_name, fidstr);
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
- memset(&data, 0, sizeof(data));
- data.ioc_inlbuf1 = (char *)&fid;
- data.ioc_inllen1 = sizeof(fid);
- data.ioc_inlbuf2 = (char *)recno;
- data.ioc_inllen2 = sizeof(__u64);
- data.ioc_inlbuf3 = (char *)linkno;
- data.ioc_inllen3 = sizeof(int);
- data.ioc_plen1 = buflen;
- data.ioc_pbuf1 = buf;
- rc = dev_ioctl(&data, dev, OBD_IOC_FID2PATH);
+ gf = malloc(sizeof(*gf) + buflen);
+ gf->gf_fid = fid;
+ gf->gf_recno = *recno;
+ gf->gf_linkno = *linkno;
+ gf->gf_pathlen = buflen;
+ rc = ioctl(fd, OBD_IOC_FID2PATH, gf);
+ if (rc) {
+ llapi_err(LLAPI_MSG_ERROR, "ioctl err %d", rc);
+ } else {
+ memcpy(buf, gf->gf_path, gf->gf_pathlen);
+ *recno = gf->gf_recno;
+ *linkno = gf->gf_linkno;
+ }
+ free(gf);
+ close(fd);
return rc;
}
#include <libcfs/libcfsutil.h>
#include <lustre/liblustreapi.h>
#include <lustre/lustre_idl.h>
-#include <lustre/lreplicate.h>
+#include "lreplicate.h"
#define REPLICATE_STATUS_VER 1
#define CLEAR_INTERVAL 100
long long rsync_threshold = DEFAULT_RSYNC_THRESHOLD;
int quit; /* Flag to stop processing the changelog; set on the
receipt of a signal */
+int abort_on_err = 0;
+
char rsync[PATH_MAX];
char rsync_ver[PATH_MAX];
struct lr_parent_child_list *parents;
{"mdt", required_argument, 0, 'm'},
{"user", required_argument, 0, 'u'},
{"statuslog", required_argument, 0, 'l'},
- {"verbose", no_argument, 0, 'v'},
+ {"verbose", no_argument, 0, 'v'},
{"xattr", required_argument, 0, 'x'},
- {"dry-run", no_argument, 0, 'z'},
+ {"dry-run", no_argument, 0, 'z'},
/* Undocumented options follow */
{"cl-clear", required_argument, 0, 'c'},
- {"use-rsync", no_argument, 0, 'r'},
+ {"use-rsync", no_argument, 0, 'r'},
{"rsync-threshold", required_argument, 0, 'y'},
{"start-recno", required_argument, 0, 'n'},
+ {"abort-on-err",no_argument, 0, 'a'},
{"debug", required_argument, 0, 'd'},
- {0, 0, 0, 0}
+ {0, 0, 0, 0}
};
/* Command line usage */
"-m <mdt> -r <user id> -l <status log>\n"
"lreplicate can also pick up parameters from a "
"status log created earlier.\n"
- "\tlreplicate -l <log_file>\n");
+ "\tlreplicate -l <log_file>\n"
+ "options:\n"
+ "\t--xattr <yes|no> replicate EAs\n"
+ "\t--abort-on-err abort at first err\n"
+ "\t--verbose\n"
+ "\t--dry-run don't write anything\n");
}
/* Print debug information. This is controlled by the value of the
long long recno = -1;
int rc;
- rc = llapi_fid2path(status->ls_mdt_device, fidstr, info->path,
+ rc = llapi_fid2path(status->ls_source, fidstr, info->path,
PATH_MAX, &recno, &linkno);
if (rc < 0 && rc != -ENOENT) {
fprintf(stderr, "fid2path error: (%s, %s) %d %s\n",
- status->ls_mdt_device, fidstr,
- -rc, strerror(errno = -rc));
+ status->ls_source, fidstr, -rc, strerror(errno = -rc));
}
return rc;
void lr_get_FID_PATH(char *mntpt, char *fidstr, char *buf, int bufsize)
{
/* Open-by-FID path is <mntpt>/.lustre/fid/[SEQ:OID:VER] */
- snprintf(buf, bufsize, "%s/%s/fid/%s", mntpt, mdd_dot_lustre_name,
+ snprintf(buf, bufsize, "%s/%s/fid/%s", mntpt, dot_lustre_name,
fidstr + 2);
return;
}
for (i = 0; i < st.st_nlink && (info->src[0] == 0 ||
info->dest[0] == 0); i++) {
rc1 = lr_get_path_ln(info, info->tfid + 3, i);
+ lr_debug(rc1 ? 0:DTRACE, "\tfid2path %s, %s, %d rc=%d\n",
+ info->path, info->name, i, rc1);
if (rc1)
break;
- else
- lr_debug(DTRACE, "\tfid2path %s, %s, %d\n",
- info->path, info->name, i);
len = strlen(info->path) - strlen(info->name);
if (len > 0 && strcmp(info->path + len,
SPECIAL_DIR, info->tfid + 2);
rc1 = link(info->src, info->dest);
- lr_debug(DINFO, "link: %s [to] %s; rc1=%d,errno=%d\n",
- info->src, info->dest, rc1, errno);
+ lr_debug(rc1?0:DINFO, "link: %s [to] %s; rc1=%d %s\n",
+ info->src, info->dest, rc1, strerror(errno));
if (rc1)
rc = rc1;
info = calloc(1, sizeof(struct lr_info));
if (info == NULL)
return -ENOMEM;
-
+
rc = llapi_search_fsname(status->ls_source, status->ls_source_fs);
if (rc) {
fprintf(stderr, "Source path is not a valid Lustre client "
"index %lld failed: %d\n",
info->type, info->recno, rc);
errors++;
+ if (abort_on_err)
+ break;
}
lr_clear_cl(info, 0);
if (debug) {
if ((rc = lr_init_status()) != 0)
return rc;
- while ((c = getopt_long(argc, argv, "s:t:m:u:l:vx:zc:ry:n:d:",
+ while ((c = getopt_long(argc, argv, "as:t:m:u:l:vx:zc:ry:n:d:",
long_opts, NULL)) >= 0) {
switch (c) {
+ case 'a':
+ /* Assume absolute paths */
+ abort_on_err++;
+ break;
case 's':
/* Assume absolute paths */
strncpy(status->ls_source, optarg, PATH_MAX);
(void) lr_read_log();
break;
case 'v':
- verbose = 1;
+ verbose++;
break;
case 'x':
if (strcmp("no", optarg) == 0) {