#endif
#include <poll.h>
-#include <libcfs/libcfs.h>
+#include <libcfs/util/string.h>
#include <lnet/lnetctl.h>
#include <lustre/lustreapi.h>
#include <lustre_ioctl.h>
* the value of the index will be ignored. The pathname will return data if
* the pathname is located on a lustre mount. Index is used to pick which
* mount point you want in the case of multiple mounted lustre file systems.
- * See function lfs_osts in lfs.c for a example of the index use.
+ * See function lfs_osts in lfs.c for an example of the index use.
*/
int llapi_search_mounts(const char *pathname, int index, char *mntdir,
char *fsname)
unsigned int used = 0;
unsigned int i;
- /* initilize output array */
+ /* initialize output array */
for (i = 0; i < list_size; i++)
poollist[i] = NULL;
lum_size = PATH_MAX + 1;
param->fp_lum_size = lum_size;
- param->fp_lmd = malloc(sizeof(lstat_t) + param->fp_lum_size);
+ param->fp_lmd = calloc(1, sizeof(lstat_t) + param->fp_lum_size);
if (param->fp_lmd == NULL) {
llapi_error(LLAPI_MSG_ERROR, -ENOMEM,
"error: allocation of %zu bytes for ioctl",
}
param->fp_lmv_stripe_count = 256;
- param->fp_lmv_md = malloc(lmv_user_md_size(param->fp_lmv_stripe_count,
+ param->fp_lmv_md = calloc(1,
+ lmv_user_md_size(param->fp_lmv_stripe_count,
LMV_MAGIC_V1));
if (param->fp_lmv_md == NULL) {
llapi_error(LLAPI_MSG_ERROR, -ENOMEM,
static int cb_get_dirstripe(char *path, DIR *d, struct find_param *param)
{
+ int ret;
+
+again:
param->fp_lmv_md->lum_stripe_count = param->fp_lmv_stripe_count;
if (param->fp_get_default_lmv)
param->fp_lmv_md->lum_magic = LMV_USER_MAGIC;
else
param->fp_lmv_md->lum_magic = LMV_MAGIC_V1;
- return ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, param->fp_lmv_md);
+ ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, param->fp_lmv_md);
+ if (errno == E2BIG && ret != 0) {
+ int stripe_count;
+ int lmv_size;
+
+ stripe_count = (__u32)param->fp_lmv_md->lum_stripe_count;
+ if (stripe_count <= param->fp_lmv_stripe_count)
+ return ret;
+
+ free(param->fp_lmv_md);
+ param->fp_lmv_stripe_count = stripe_count;
+ lmv_size = lmv_user_md_size(stripe_count, LMV_MAGIC_V1);
+ param->fp_lmv_md = malloc(lmv_size);
+ if (param->fp_lmv_md == NULL) {
+ llapi_error(LLAPI_MSG_ERROR, -ENOMEM,
+ "error: allocation of %d bytes for ioctl",
+ lmv_user_md_size(param->fp_lmv_stripe_count,
+ LMV_MAGIC_V1));
+ return -ENOMEM;
+ }
+ goto again;
+ }
+ return ret;
}
static int get_lmd_info(char *path, DIR *parent, DIR *dir,
/*
* If uuidp is NULL, return the number of available obd uuids.
* If uuidp is non-NULL, then it will return the uuids of the obds. If
- * there are more OSTs then allocated to uuidp, then an error is returned with
+ * there are more OSTs than allocated to uuidp, then an error is returned with
* the ost_count set to number of available obd uuids.
*/
static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp,
int raw, char *pool_name)
{
char *prefix = is_dir ? "" : "lmm_";
- char *seperator = "";
+ char *separator = "";
int rc;
if (is_dir && lmm_oi_seq(&lum->lmm_oi) == FID_SEQ_LOV_DEFAULT) {
llapi_printf(LLAPI_MSG_NORMAL, "%hd",
(__s16)lum->lmm_stripe_count);
}
- seperator = is_dir ? " " : "\n";
+ separator = is_dir ? " " : "\n";
}
if (verbose & VERBOSE_SIZE) {
- llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_SIZE)
llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_size: ",
prefix);
llapi_printf(LLAPI_MSG_NORMAL, "%u",
lum->lmm_stripe_size);
}
- seperator = is_dir ? " " : "\n";
+ separator = is_dir ? " " : "\n";
}
if ((verbose & VERBOSE_LAYOUT) && !is_dir) {
- llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_LAYOUT)
llapi_printf(LLAPI_MSG_NORMAL, "%spattern: ",
prefix);
llapi_printf(LLAPI_MSG_NORMAL, "%.x", lum->lmm_pattern);
- seperator = "\n";
+ separator = "\n";
}
if ((verbose & VERBOSE_GENERATION) && !is_dir) {
- llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_GENERATION)
llapi_printf(LLAPI_MSG_NORMAL, "%slayout_gen: ",
prefix);
llapi_printf(LLAPI_MSG_NORMAL, "%u",
(int)lum->lmm_layout_gen);
- seperator = "\n";
+ separator = "\n";
}
if (verbose & VERBOSE_OFFSET) {
- llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_OFFSET)
llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_offset: ",
prefix);
else
llapi_printf(LLAPI_MSG_NORMAL, "%u",
objects[0].l_ost_idx);
- seperator = is_dir ? " " : "\n";
+ separator = is_dir ? " " : "\n";
}
if ((verbose & VERBOSE_POOL) && (pool_name != NULL)) {
- llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_POOL)
llapi_printf(LLAPI_MSG_NORMAL, "%spool: ",
prefix);
}
- if ((verbose & VERBOSE_POOL) && (pool_name[0] != '\0')) {
+ if ((verbose & VERBOSE_POOL) && pool_name != NULL &&
+ pool_name[0] != '\0') {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
if (verbose & ~VERBOSE_POOL)
llapi_printf(LLAPI_MSG_NORMAL, "%slmv_pool: ",
strlcpy(pool_name, lmmv3->lmm_pool_name, sizeof(pool_name));
objects = lmmv3->lmm_objects;
- lov_dump_user_lmm_v1v3(¶m->fp_lmd->lmd_lmm, pool_name,
+ lov_dump_user_lmm_v1v3(¶m->fp_lmd->lmd_lmm,
+ pool_name[0] == '\0' ? NULL : pool_name,
objects, path, is_dir,
param->fp_obd_index, param->fp_max_depth,
param->fp_verbose, param->fp_raw);
lum = (struct lmv_user_md *)param->fp_lmv_md;
strlcpy(pool_name, lum->lum_pool_name, sizeof(pool_name));
- lmv_dump_user_lmm(lum, pool_name, path,
- param->fp_obd_index, param->fp_max_depth,
- param->fp_verbose);
+ lmv_dump_user_lmm(lum,
+ pool_name[0] == '\0' ? NULL : pool_name,
+ path, param->fp_obd_index,
+ param->fp_max_depth, param->fp_verbose);
break;
}
default:
if (decision == 0) {
ret = get_lmd_info(path, parent, dir, param->fp_lmd,
param->fp_lum_size);
+ if (ret == 0 && param->fp_lmd->lmd_lmm.lmm_magic == 0 &&
+ (param->fp_check_pool || param->fp_check_stripe_count ||
+ param->fp_check_stripe_size || param->fp_check_layout)) {
+ struct lov_user_md *lmm = ¶m->fp_lmd->lmd_lmm;
+
+ /* We need to "fake" the "use the default" values
+ * since the lmm struct is zeroed out at this point. */
+ lmm->lmm_magic = LOV_USER_MAGIC_V1;
+ lmm->lmm_pattern = 0xFFFFFFFF;
+ if (!param->fp_raw)
+ ostid_set_seq(&lmm->lmm_oi,
+ FID_SEQ_LOV_DEFAULT);
+ lmm->lmm_stripe_size = 0;
+ lmm->lmm_stripe_count = 0;
+ lmm->lmm_stripe_offset = -1;
+ }
if (ret == 0 && param->fp_mdt_uuid != NULL) {
if (dir != NULL) {
ret = llapi_file_fget_mdtidx(dirfd(dir),
(param->fp_mdt_uuid && param->fp_mdt_index == OBD_NOT_FOUND))
goto decided;
- /* If a OST or MDT UUID is given, and some OST matches,
+ /* If an OST or MDT UUID is given, and some OST matches,
* check it here. */
if (param->fp_obd_index != OBD_NOT_FOUND ||
param->fp_mdt_index != OBD_NOT_FOUND) {
if (param->fp_mdt_index != OBD_NOT_FOUND)
print_failed_tgt(param, path, LL_STATFS_LMV);
- if (S_ISDIR(st->st_mode))
+ if (dir != NULL)
ret = fstat_f(dirfd(dir), st);
- else if (dir != NULL)
- ret = ioctl(dirfd(dir), IOC_LOV_GETINFO,
- (void *)param->fp_lmd);
+ else if (de != NULL)
+ ret = fstatat_f(dirfd(parent), de->d_name, st,
+ AT_SYMLINK_NOFOLLOW);
else
- ret = ioctl(dirfd(parent), IOC_LOV_GETINFO,
- (void *)param->fp_lmd);
+ ret = lstat_f(path, st);
if (ret) {
if (errno == ENOENT) {
return 0;
}
-static int cb_mv_init(char *path, DIR *parent, DIR **dirp,
+static int cb_migrate_mdt_init(char *path, DIR *parent, DIR **dirp,
void *param_data, struct dirent64 *de)
{
struct find_param *param = (struct find_param *)param_data;
ret = ioctl(fd, LL_IOC_MIGRATE, rawbuf);
if (ret != 0) {
ret = -errno;
- fprintf(stderr, "%s migrate failed %d\n", path, ret);
+ fprintf(stderr, "%s migrate failed: %s (%d)\n",
+ path, strerror(-ret), ret);
goto out;
} else if (param->fp_verbose & VERBOSE_DETAIL) {
fprintf(stdout, "migrate %s to MDT%d\n",
return ret;
}
+int llapi_migrate_mdt(char *path, struct find_param *param)
+{
+ return param_callback(path, cb_migrate_mdt_init, cb_common_fini, param);
+}
+
int llapi_mv(char *path, struct find_param *param)
{
- return param_callback(path, cb_mv_init, cb_common_fini, param);
+#if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 9, 53, 0)
+ static bool printed;
+
+ if (!printed) {
+ llapi_error(LLAPI_MSG_ERROR, -ESTALE,
+ "llapi_mv() is deprecated, use llapi_migrate_mdt()\n");
+ printed = true;
+ }
+#endif
+ return llapi_migrate_mdt(path, param);
}
int llapi_find(char *path, struct find_param *param)
strstr(mnt->mnt_fsname, ":/") != NULL);
}
-int llapi_quotacheck(char *mnt, int check_type)
-{
- DIR *root;
- int rc;
-
- root = opendir(mnt);
- if (!root) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
- return rc;
- }
-
- rc = ioctl(dirfd(root), OBD_IOC_QUOTACHECK, check_type);
- if (rc < 0)
- rc = -errno;
-
- closedir(root);
- return rc;
-}
-
-int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk)
-{
- DIR *root;
- int poll_intvl = 2;
- int rc;
-
- root = opendir(mnt);
- if (!root) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
- return rc;
- }
-
- while (1) {
- rc = ioctl(dirfd(root), OBD_IOC_POLL_QUOTACHECK, qchk);
- if (!rc)
- break;
- sleep(poll_intvl);
- if (poll_intvl < 30)
- poll_intvl *= 2;
- }
-
- closedir(root);
- return 0;
-}
-
int llapi_quotactl(char *mnt, struct if_quotactl *qctl)
{
DIR *root;
return rc;
}
-static int cb_quotachown(char *path, DIR *parent, DIR **dirp, void *data,
- struct dirent64 *de)
-{
- struct find_param *param = (struct find_param *)data;
- DIR *d = dirp == NULL ? NULL : *dirp;
- lstat_t *st;
- int rc;
-
- LASSERT(parent != NULL || d != NULL);
-
- rc = get_lmd_info(path, parent, d, param->fp_lmd, param->fp_lum_size);
- if (rc) {
- if (rc == -ENODATA) {
- if (!param->fp_obd_uuid && !param->fp_quiet)
- llapi_error(LLAPI_MSG_ERROR, -ENODATA,
- "%s has no stripe info", path);
- rc = 0;
- } else if (rc == -ENOENT) {
- rc = 0;
- }
- return rc;
- }
-
- st = ¶m->fp_lmd->lmd_st;
-
- /* libc chown() will do extra check, and if the real owner is
- * the same as the ones to set, it won't fall into kernel, so
- * invoke syscall directly. */
- rc = syscall(SYS_chown, path, -1, -1);
- if (rc)
- llapi_error(LLAPI_MSG_ERROR, errno,
- "error: chown %s", path);
-
- rc = chmod(path, st->st_mode);
- if (rc) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "error: chmod %s (%hu)",
- path, st->st_mode);
- }
-
- return rc;
-}
-
-int llapi_quotachown(char *path, int flag)
-{
- struct find_param param;
-
- memset(¶m, 0, sizeof(param));
- param.fp_recursive = 1;
- param.fp_verbose = 0;
- param.fp_quiet = 1;
-
- return param_callback(path, cb_quotachown, NULL, ¶m);
-}
-
#include <pwd.h>
#include <grp.h>
#include <mntent.h>
struct changelog_private {
int magic;
enum changelog_send_flag flags;
- lustre_kernelcomm kuc;
+ struct lustre_kernelcomm kuc;
};
/** Start reading from a changelog
/**
* Swap the layouts between 2 file descriptors
- * the 2 files must be open in write
+ * the 2 files must be open for writing
* first fd received the ioctl, second fd is passed as arg
* this is assymetric but avoid use of root path for ioctl
*/
-int llapi_fswap_layouts(int fd1, int fd2, __u64 dv1, __u64 dv2, __u64 flags)
+int llapi_fswap_layouts_grouplock(int fd1, int fd2, __u64 dv1, __u64 dv2,
+ int gid, __u64 flags)
{
struct lustre_swap_layouts lsl;
+ struct stat st1;
+ struct stat st2;
int rc;
+ if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) {
+ rc = fstat(fd1, &st1);
+ if (rc < 0)
+ return -errno;
+
+ rc = fstat(fd2, &st2);
+ if (rc < 0)
+ return -errno;
+ }
lsl.sl_fd = fd2;
lsl.sl_flags = flags;
-
- do
- lsl.sl_gid = random();
- while (lsl.sl_gid == 0);
-
+ lsl.sl_gid = gid;
lsl.sl_dv1 = dv1;
lsl.sl_dv2 = dv2;
rc = ioctl(fd1, LL_IOC_LOV_SWAP_LAYOUTS, &lsl);
- if (rc)
- rc = -errno;
- return rc;
+ if (rc < 0)
+ return -errno;
+
+ if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) {
+ struct timeval tv1[2];
+ struct timeval tv2[2];
+
+ memset(tv1, 0, sizeof(tv1));
+ memset(tv2, 0, sizeof(tv2));
+
+ if (flags & SWAP_LAYOUTS_KEEP_ATIME) {
+ tv1[0].tv_sec = st1.st_atime;
+ tv2[0].tv_sec = st2.st_atime;
+ } else {
+ tv1[0].tv_sec = st2.st_atime;
+ tv2[0].tv_sec = st1.st_atime;
+ }
+
+ if (flags & SWAP_LAYOUTS_KEEP_MTIME) {
+ tv1[1].tv_sec = st1.st_mtime;
+ tv2[1].tv_sec = st2.st_mtime;
+ } else {
+ tv1[1].tv_sec = st2.st_mtime;
+ tv2[1].tv_sec = st1.st_mtime;
+ }
+
+ rc = futimes(fd1, tv1);
+ if (rc < 0)
+ return -errno;
+
+ rc = futimes(fd2, tv2);
+ if (rc < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+
+int llapi_fswap_layouts(int fd1, int fd2, __u64 dv1, __u64 dv2, __u64 flags)
+{
+ int rc;
+ int grp_id;
+
+ do
+ grp_id = random();
+ while (grp_id == 0);
+
+ rc = llapi_fswap_layouts_grouplock(fd1, fd2, dv1, dv2, grp_id, flags);
+ if (rc < 0)
+ return rc;
+
+ return 0;
}
/**