*
*/
-
/* for O_DIRECTORY */
#define _GNU_SOURCE
#include <unistd.h>
#endif
-#include <lnet/lnetctl.h>
-
#include <liblustre.h>
+#include <lnet/lnetctl.h>
#include <obd.h>
#include <lustre_lib.h>
-#include <lustre/liblustreapi.h>
#include <obd_lov.h>
#include <lustre/liblustreapi.h>
fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
}
-int llapi_file_create(const char *name, unsigned long stripe_size,
- int stripe_offset, int stripe_count, int stripe_pattern)
+int llapi_file_open(const char *name, int flags, int mode,
+ unsigned long stripe_size, int stripe_offset,
+ int stripe_count, int stripe_pattern)
{
struct lov_user_md lum = { 0 };
int fd, rc = 0;
int isdir = 0;
int page_size;
- fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
- if (errno == EISDIR) {
+ fd = open(name, flags | O_LOV_DELAY_CREATE, mode);
+ if (fd < 0 && errno == EISDIR) {
fd = open(name, O_DIRECTORY | O_RDONLY);
isdir++;
}
if (fd < 0) {
rc = -errno;
- err_msg("unable to open '%s'",name);
+ err_msg("unable to open '%s'", name);
return rc;
}
if (errno != EEXIST && errno != EALREADY)
errmsg = strerror(errno);
- rc = -errno;
fprintf(stderr, "error on ioctl "LPX64" for '%s' (%d): %s\n",
(__u64)LL_IOC_LOV_SETSTRIPE, name, fd, errmsg);
}
out:
- if (close(fd) < 0) {
- if (rc == 0)
- rc = -errno;
- err_msg("error on close for '%s' (%d)", name, fd);
+ if (rc) {
+ close(fd);
+ fd = rc;
}
- return rc;
+
+ return fd;
+}
+
+int llapi_file_create(const char *name, unsigned long stripe_size,
+ int stripe_offset, int stripe_count, int stripe_pattern)
+{
+ int fd;
+
+ fd = llapi_file_open(name, O_CREAT | O_WRONLY, 0644, stripe_size,
+ stripe_offset, stripe_count, stripe_pattern);
+ if (fd < 0)
+ return fd;
+
+ close(fd);
+ return 0;
}
typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, void *data);
int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
{
- struct obd_ioctl_data data = { 0, };
- struct lov_desc desc = { 0, };
- char *buf = NULL;
- int max_ost_count, rc;
- __u32 *obdgens;
-
- max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) -
- size_round(sizeof(desc))) /
- (sizeof(*uuidp) + sizeof(*obdgens));
- if (max_ost_count > *ost_count)
- max_ost_count = *ost_count;
-
- obdgens = malloc(size_round(max_ost_count * sizeof(*obdgens)));
- if (!obdgens) {
- err_msg("error: %d generation #'s", max_ost_count);
- return(-ENOMEM);
- }
-
- data.ioc_inllen1 = sizeof(desc);
- data.ioc_inlbuf1 = (char *)&desc;
- data.ioc_inllen2 = size_round(max_ost_count * sizeof(*uuidp));
- data.ioc_inlbuf2 = (char *)uuidp;
- data.ioc_inllen3 = size_round(max_ost_count * sizeof(*obdgens));
- data.ioc_inlbuf3 = (char *)obdgens;
-
- desc.ld_tgt_count = max_ost_count;
-
- if (obd_ioctl_pack(&data, &buf, OBD_MAX_IOCTL_BUFFER)) {
- fprintf(stderr, "error: %s: internal packing error\n",
- __FUNCTION__);
- rc = EINVAL;
- goto out;
- }
+ char lov_name[sizeof(struct obd_uuid)];
+ char buf[1024];
+ FILE *fp;
+ int rc = 0, index = 0;
- rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
+ /* Get the lov name */
+ rc = ioctl(fd, OBD_IOC_GETNAME, (void *) lov_name);
if (rc) {
rc = errno;
- err_msg("error: %s: getting LOV config", __FUNCTION__);
- goto out;
+ err_msg("error: can't get lov name.");
+ return rc;
}
- if (obd_ioctl_unpack(&data, buf, OBD_MAX_IOCTL_BUFFER)) {
- rc = errno = EINVAL;
- err_msg("error: %s: internal ioctl unpack", __FUNCTION__);
- goto out;
+ /* Now get the ost uuids from /proc */
+ snprintf(buf, sizeof(buf), "/proc/fs/lustre/lov/%s/target_obd",
+ lov_name);
+ fp = fopen(buf, "r");
+ if (fp == NULL) {
+ rc = errno;
+ err_msg("error: opening '%s'", buf);
+ return rc;
}
- *ost_count = desc.ld_tgt_count;
-out:
- free(buf);
- free(obdgens);
+ while ((fgets(buf, sizeof(buf), fp) != NULL) && index < *ost_count) {
+ if (sscanf(buf, "%d: %s", &index, uuidp[index].uuid) < 2)
+ break;
+ index++;
+ }
+
+ fclose(fp);
+ *ost_count = index;
return rc;
}
return parent;
}
-static int llapi_semantic_traverse(char *path, DIR *parent,
+static int llapi_semantic_traverse(char *path, int size, DIR *parent,
semantic_func_t sem_init,
semantic_func_t sem_fini, void *data)
{
continue;
path[len] = 0;
+ if ((len + dent->d_reclen + 2) > size) {
+ fprintf(stderr,
+ "error: %s: string buffer is too small\n",
+ __FUNCTION__);
+ break;
+ }
strcat(path, "/");
strcat(path, dent->d_name);
* tool only makes sense for lustre filesystems. */
break;
case DT_DIR:
- ret = llapi_semantic_traverse(path, d, sem_init,
+ ret = llapi_semantic_traverse(path, size, d, sem_init,
sem_fini, data);
if (ret < 0)
goto out;
/* If a OST UUID is given, and some OST matches, check it here. */
if (decision != -1 && param->obdindex != OBD_NOT_FOUND) {
- /* Only those files should be accepted, which have a strip on
- * the specified OST. */
+ if (!S_ISREG(st->st_mode))
+ goto decided;
+
+ /* Only those files should be accepted, which have a
+ * stripe on the specified OST. */
if (!param->lmd->lmd_lmm.lmm_stripe_count) {
decision = -1;
} else {
if (!decision) {
int for_mds;
- for_mds = lustre_fs ? param->lmd->lmd_lmm.lmm_stripe_count : 0;
+ for_mds = lustre_fs ? (S_ISREG(st->st_mode) &&
+ param->lmd->lmd_lmm.lmm_stripe_count)
+ : 0;
decision = find_time_check(st, param, for_mds);
}
/* If file still fits the request, ask osd for updated info.
The regulat stat is almost of the same speed as some new
'glimpse-size-ioctl'. */
- if (!decision && param->lmd->lmd_lmm.lmm_stripe_count) {
+ if (!decision && param->lmd->lmd_lmm.lmm_stripe_count &&
+ S_ISREG(st->st_mode)) {
+ if (param->obdindex != OBD_NOT_FOUND) {
+ /* Check whether the obd is active or not, if it is
+ * not active, just print the object affected by this
+ * failed ost
+ * */
+ struct obd_statfs stat_buf;
+ struct obd_uuid uuid_buf;
+
+ memset(&stat_buf, 0, sizeof(struct obd_statfs));
+ memset(&uuid_buf, 0, sizeof(struct obd_uuid));
+ ret = llapi_obd_statfs(path, LL_STATFS_LOV,
+ param->obdindex, &stat_buf,
+ &uuid_buf);
+ if (ret) {
+ if (ret == -ENODATA || ret == -ENODEV
+ || ret == -EIO)
+ errno = EIO;
+ printf("obd_uuid: %s failed %s ",
+ param->obduuid->uuid, strerror(errno));
+ goto print_path;
+ }
+ }
if (dir) {
ret = ioctl(dirfd(dir), IOC_LOV_GETINFO,
(void *)param->lmd);
decision = find_time_check(st, param, 0);
}
+print_path:
if (decision != -1) {
printf("%s", path);
if (param->zeroend)
printf("\n");
}
+decided:
/* Do not get down anymore? */
if (param->depth == param->maxdepth)
return 1;
int llapi_find(char *path, struct find_param *param)
{
- char buf[PATH_MAX + 1];
- int ret;
+ char *buf;
+ int ret, len = strlen(path);
+
+ if (len > PATH_MAX) {
+ fprintf(stderr, "%s: Path name '%s' is too long.\n",
+ __FUNCTION__, path);
+ return -EINVAL;
+ }
+
+ buf = (char *)malloc(PATH_MAX + 1);
+ if (!buf)
+ return -ENOMEM;
ret = common_param_init(param);
- if (ret)
+ if (ret) {
+ free(buf);
return ret;
+ }
param->depth = 0;
- strncpy(buf, path, strlen(path));
- buf[strlen(path)] = '\0';
- ret = llapi_semantic_traverse(buf, NULL, cb_find_init,
+ strncpy(buf, path, PATH_MAX + 1);
+ ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_find_init,
cb_common_fini, param);
find_param_fini(param);
+ free(buf);
return ret < 0 ? ret : 0;
}
int llapi_getstripe(char *path, struct find_param *param)
{
- int ret = 0;
+ char *buf;
+ int ret = 0, len = strlen(path);
+
+ if (len > PATH_MAX) {
+ fprintf(stderr, "%s: Path name '%s' is too long.\n",
+ __FUNCTION__, path);
+ return -EINVAL;
+ }
+
+ buf = (char *)malloc(PATH_MAX + 1);
+ if (!buf)
+ return -ENOMEM;
ret = common_param_init(param);
- if (ret)
+ if (ret) {
+ free(buf);
return ret;
+ }
param->depth = 0;
- ret = llapi_semantic_traverse(path, NULL, cb_getstripe,
+
+ strncpy(buf, path, PATH_MAX + 1);
+ ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_getstripe,
cb_common_fini, param);
find_param_fini(param);
+ free(buf);
return ret < 0 ? ret : 0;
}
/* 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, st->st_uid, st->st_gid);
+ rc = syscall(SYS_chown, path, -1, -1);
+ if (rc)
+ err_msg("error: chown %s (%u,%u)", path);
+
+ rc = chmod(path, st->st_mode);
if (rc)
- err_msg("error: chown %s (%u,%u)",
- path, st->st_uid, st->st_gid);
+ err_msg("error: chmod %s (%hu)", path, st->st_mode);
+
return rc;
}
int llapi_quotachown(char *path, int flag)
{
struct find_param param;
- int ret = 0;
+ char *buf;
+ int ret = 0, len = strlen(path);
+
+ if (len > PATH_MAX) {
+ fprintf(stderr, "%s: Path name '%s' is too long.\n",
+ __FUNCTION__, path);
+ return -EINVAL;
+ }
+
+ buf = (char *)malloc(PATH_MAX + 1);
+ if (!buf)
+ return -ENOMEM;
memset(¶m, 0, sizeof(param));
param.recursive = 1;
if (ret)
goto out;
- ret = llapi_semantic_traverse(path, NULL, cb_quotachown,
+ strncpy(buf, path, PATH_MAX + 1);
+ ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_quotachown,
NULL, ¶m);
out:
find_param_fini(¶m);
+ free(buf);
return ret;
}
+
+int llapi_getfacl(char *fname, char *cmd)
+{
+ struct rmtacl_ioctl_data data;
+ char out[RMTACL_SIZE_MAX] = "";
+ int fd, rc;
+
+ data.cmd = cmd;
+ data.cmd_len = strlen(cmd) + 1;
+ data.res = out;
+ data.res_len = sizeof(out);
+
+ fd = open(fname, 0);
+ if (fd == -1) {
+ err_msg("open %s failed", fname);
+ return -1;
+ }
+
+ rc = ioctl(fd, LL_IOC_GETFACL, &data);
+ close(fd);
+ if (errno == EBADE) {
+ fprintf(stderr, "Please use getfacl directly!\n");
+ rc = 1;
+ } else if (rc) {
+ err_msg("getfacl %s failed", fname);
+ } else {
+ printf("%s", out);
+ }
+
+ return rc;
+}
+
+int llapi_setfacl(char *fname, char *cmd)
+{
+ struct rmtacl_ioctl_data data;
+ char out[RMTACL_SIZE_MAX] = "";
+ int fd, rc;
+
+ data.cmd = cmd;
+ data.cmd_len = strlen(cmd) + 1;
+ data.res = out;
+ data.res_len = sizeof(out);
+
+ fd = open(fname, 0);
+ if (fd == -1) {
+ err_msg("open %s failed", fname);
+ return -1;
+ }
+
+ rc = ioctl(fd, LL_IOC_SETFACL, &data);
+ close(fd);
+ if (errno == EBADE) {
+ fprintf(stderr, "Please use setfacl directly!\n");
+ rc = 1;
+ } else if (errno == EOPNOTSUPP) {
+ fprintf(stderr, "setfacl: %s: %s\n", fname, strerror(errno));
+ rc = 1;
+ } else if (rc) {
+ err_msg("setfacl %s failed", fname);
+ } else {
+ printf("%s", out);
+ }
+
+ return rc;
+}