X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi.c;h=f7f8e69d52ab9b3090145c7bf883d072d4d73772;hp=761069370f513b0eccecbdab43922b98e11b06d6;hb=35b3a429d1915ec147f01a42c4ec0526b887d1c7;hpb=2115c58384bd03bf4a76ba492bdf47a257cd5a3f diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 7610693..f7f8e69 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -426,63 +426,70 @@ static int get_param_obdvar(const char *fsname, const char *file_path, const char *obd_type, const char *param_name, char *value, unsigned int val_len) { - char devices[PATH_MAX + 1], dev[PATH_MAX + 1] = "*", fs[PATH_MAX + 1]; - FILE *fp = fopen(DEVICES_LIST, "r"); - int rc = 0; - - if (!fsname && file_path) { - rc = llapi_search_fsname(file_path, fs); - if (rc) { - llapi_error(LLAPI_MSG_ERROR, rc, - "'%s' is not on a Lustre filesystem", - file_path); - if (fp != NULL) - fclose(fp); - return rc; - } - } else if (fsname) { - if (strlen(fsname) > sizeof(fs)-1) { - if (fp != NULL) - fclose(fp); - return -E2BIG; - } - strncpy(fs, fsname, sizeof(fs)); - } - - if (fp == NULL) { - rc = -errno; - llapi_error(LLAPI_MSG_ERROR, rc, "error: opening "DEVICES_LIST); - return rc; - } + char devices[PATH_MAX]; + char dev[PATH_MAX] = "*"; + char fs[PATH_MAX]; + FILE *fp = NULL; + int rc = 0; - while (fgets(devices, sizeof(devices), fp) != NULL) { - char *bufp = devices, *tmp; + fp = fopen(DEVICES_LIST, "r"); + if (fp == NULL) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "error: opening "DEVICES_LIST); + GOTO(out, rc); + } - while (bufp[0] == ' ') - ++bufp; + if (fsname == NULL && file_path != NULL) { + rc = llapi_search_fsname(file_path, fs); + if (rc) { + llapi_error(LLAPI_MSG_ERROR, rc, + "'%s' is not on a Lustre filesystem", + file_path); + GOTO(out, rc); + } + } else if (fsname != NULL) { + rc = strlcpy(fs, fsname, sizeof(fs)); + if (rc >= sizeof(fs)) + GOTO(out, rc = -E2BIG); + } - tmp = strstr(bufp, obd_type); - if (tmp) { - tmp += strlen(obd_type) + 1; - if (strcmp(tmp, fs)) - continue; - if (strlen(tmp) > sizeof(dev)-1) { - fclose(fp); - return -E2BIG; - } - strncpy(dev, tmp, sizeof(dev)); - tmp = strchr(dev, ' '); + while (fgets(devices, sizeof(devices) - 1, fp) != NULL) { + char *bufp = devices, *tmp; + + devices[sizeof(devices) - 1] = '\0'; + while (bufp[0] == ' ') + ++bufp; + + tmp = strstr(bufp, obd_type); + if (tmp != NULL) { + tmp += strlen(obd_type) + 1; + if (strcmp(tmp, fs)) + continue; + rc = strlcpy(dev, tmp, sizeof(dev)); + if (rc >= sizeof(dev)) + GOTO(out, rc = -E2BIG); + tmp = strchr(dev, ' '); if (tmp != NULL) *tmp = '\0'; - break; - } - } + break; + } + } - if (dev[0] == '*' && strlen(fs)) - snprintf(dev, PATH_MAX, "%s-*", fs); - snprintf(devices, PATH_MAX, "%s/%s/%s", obd_type, dev, param_name); - fclose(fp); - return get_param(devices, value, val_len); + if (dev[0] == '*' && strlen(fs)) { + rc = snprintf(dev, sizeof(dev), "%s-*", fs); + if (rc >= sizeof(dev)) + GOTO(out, rc = -E2BIG); + } + rc = snprintf(devices, sizeof(devices), "%s/%s/%s", obd_type, dev, + param_name); + if (rc >= sizeof(devices)) + GOTO(out, rc = -E2BIG); + fclose(fp); + return get_param(devices, value, val_len); +out: + if (fp != NULL) + fclose(fp); + return rc; } /* @@ -708,7 +715,8 @@ retry_open: lum.lmm_stripe_count = stripe_count; lum.lmm_stripe_offset = stripe_offset; if (pool_name != NULL) { - strncpy(lum.lmm_pool_name, pool_name, LOV_MAXPOOLNAME); + strlcpy(lum.lmm_pool_name, pool_name, + sizeof(lum.lmm_pool_name)); } else { /* If no pool is specified at all, use V1 request */ lum.lmm_magic = LOV_USER_MAGIC_V1; @@ -792,7 +800,8 @@ int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset, ": too large pool name: %s", name, pool_name); return -E2BIG; } - strncpy(lum.lum_pool_name, pool_name, strlen(pool_name)); + strncpy(lum.lum_pool_name, pool_name, + sizeof(lum.lum_pool_name)); } fd = open(name, O_DIRECTORY | O_RDONLY); @@ -817,7 +826,7 @@ int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset, return rc; } -int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, +int llapi_dir_create_pool(const char *name, int mode, int stripe_offset, int stripe_count, int stripe_pattern, const char *pool_name) { @@ -859,6 +868,7 @@ int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, data.ioc_inllen1 = strlen(filename) + 1; data.ioc_inlbuf2 = (char *)&lmu; data.ioc_inllen2 = sizeof(struct lmv_user_md); + data.ioc_type = mode; rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { llapi_error(LLAPI_MSG_ERROR, rc, @@ -1054,19 +1064,23 @@ int llapi_search_fsname(const char *pathname, char *fsname) path = realpath(pathname, NULL); if (path == NULL) { - char buf[PATH_MAX + 1], *ptr; - - buf[0] = 0; - if (pathname[0] != '/') { - /* Need an absolute path, but realpath() only works for - * pathnames that actually exist. We go through the - * extra hurdle of dirname(getcwd() + pathname) in - * case the relative pathname contains ".." in it. */ - if (getcwd(buf, sizeof(buf) - 1) == NULL) - return -errno; - strcat(buf, "/"); - } - strncat(buf, pathname, sizeof(buf) - strlen(buf)); + char buf[PATH_MAX], *ptr; + + buf[0] = '\0'; + if (pathname[0] != '/') { + /* Need an absolute path, but realpath() only works for + * pathnames that actually exist. We go through the + * extra hurdle of dirname(getcwd() + pathname) in + * case the relative pathname contains ".." in it. */ + if (getcwd(buf, sizeof(buf) - 2) == NULL) + return -errno; + rc = strlcat(buf, "/", sizeof(buf)); + if (rc >= sizeof(buf)) + return -E2BIG; + } + rc = strlcat(buf, pathname, sizeof(buf)); + if (rc >= sizeof(buf)) + return -E2BIG; path = realpath(buf, NULL); if (path == NULL) { ptr = strrchr(buf, '/'); @@ -1162,20 +1176,20 @@ static int poolpath(char *fsname, char *pathname, char *pool_pathname) int llapi_get_poolmembers(const char *poolname, char **members, int list_size, char *buffer, int buffer_size) { - char fsname[PATH_MAX + 1]; - char *pool, *tmp; - char pathname[PATH_MAX + 1]; - char path[PATH_MAX + 1]; - char buf[1024]; + char fsname[PATH_MAX]; + char *pool, *tmp; + char pathname[PATH_MAX]; + char path[PATH_MAX]; + char buf[1024]; FILE *fd; int rc = 0; int nb_entries = 0; int used = 0; /* name is FSNAME.POOLNAME */ - if (strlen(poolname) > PATH_MAX) - return -EOVERFLOW; - strcpy(fsname, poolname); + if (strlen(poolname) >= sizeof(fsname)) + return -EOVERFLOW; + strlcpy(fsname, poolname, sizeof(fsname)); pool = strchr(fsname, '.'); if (pool == NULL) return -EINVAL; @@ -1192,7 +1206,9 @@ int llapi_get_poolmembers(const char *poolname, char **members, } llapi_printf(LLAPI_MSG_NORMAL, "Pool: %s.%s\n", fsname, pool); - sprintf(path, "%s/%s", pathname, pool); + rc = snprintf(path, sizeof(path), "%s/%s", pathname, pool); + if (rc >= sizeof(path)) + return -EOVERFLOW; fd = fopen(path, "r"); if (fd == NULL) { rc = -errno; @@ -1206,6 +1222,7 @@ int llapi_get_poolmembers(const char *poolname, char **members, rc = -EOVERFLOW; break; } + buf[sizeof(buf) - 1] = '\0'; /* remove '\n' */ tmp = strchr(buf, '\n'); if (tmp != NULL) @@ -1350,8 +1367,14 @@ int llapi_poollist(const char *name) int obdcount, bufsize, rc, nb, i; char *poolname = NULL, *tmp = NULL, data[16]; - if (name[0] != '/') { - fsname = strdup(name); + if (name == NULL) + return -EINVAL; + + if (name[0] != '/') { + fsname = strdup(name); + if (fsname == NULL) + return -ENOMEM; + poolname = strchr(fsname, '.'); if (poolname) *poolname = '\0'; @@ -1512,7 +1535,7 @@ static int get_lmd_info(char *path, DIR *parent, DIR *dir, fname = (fname == NULL ? path : fname + 1); /* retrieve needed file info */ - strncpy((char *)lmd, fname, lumlen); + strlcpy((char *)lmd, fname, lumlen); ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd); } @@ -1558,8 +1581,8 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, int len, ret; DIR *d, *p = NULL; - ret = 0; - len = strlen(path); + ret = 0; + len = strlen(path); d = opendir(path); if (!d && errno != ENOTDIR) { @@ -1579,12 +1602,12 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, if (sem_init && (ret = sem_init(path, parent ?: p, &d, data, de))) goto err; - if (!d || (param->get_lmv && !param->recursive)) { - ret = 0; + if (d == NULL) goto out; - } while ((dent = readdir64(d)) != NULL) { + int rc; + param->have_fileinfo = 0; if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) @@ -1607,13 +1630,15 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, if (dent->d_type == DT_UNKNOWN) { lstat_t *st = ¶m->lmd->lmd_st; - ret = get_lmd_info(path, d, NULL, param->lmd, + rc = get_lmd_info(path, d, NULL, param->lmd, param->lumlen); - if (ret == 0) + if (rc == 0) dent->d_type = IFTODT(st->st_mode); + else if (ret == 0) + ret = rc; - if (ret == -ENOENT) - continue; + if (rc == -ENOENT) + continue; } switch (dent->d_type) { case DT_UNKNOWN: @@ -1621,21 +1646,21 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, "error: %s: '%s' is UNKNOWN type %d", __func__, dent->d_name, dent->d_type); break; - case DT_DIR: - ret = llapi_semantic_traverse(path, size, d, sem_init, - sem_fini, data, dent); - if (ret < 0) - goto out; - break; - default: - ret = 0; - if (sem_init) { - ret = sem_init(path, d, NULL, data, dent); - if (ret < 0) - goto out; - } - if (sem_fini && ret == 0) - sem_fini(path, d, NULL, data, dent); + case DT_DIR: + rc = llapi_semantic_traverse(path, size, d, sem_init, + sem_fini, data, dent); + if (rc != 0 && ret == 0) + ret = rc; + break; + default: + rc = 0; + if (sem_init) { + rc = sem_init(path, d, NULL, data, dent); + if (rc < 0 && ret == 0) + ret = rc; + } + if (sem_fini && rc == 0) + sem_fini(path, d, NULL, data, dent); } } @@ -1649,7 +1674,7 @@ err: closedir(d); if (p) closedir(p); - return ret; + return ret; } static int param_callback(char *path, semantic_func_t sem_init, @@ -1669,7 +1694,7 @@ static int param_callback(char *path, semantic_func_t sem_init, if (!buf) return -ENOMEM; - strncpy(buf, path, PATH_MAX + 1); + strlcpy(buf, path, PATH_MAX + 1); ret = common_param_init(param, buf); if (ret) goto out; @@ -1751,10 +1776,11 @@ enum tgt_type { static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp, int *ost_count, enum tgt_type type) { - struct obd_uuid name; - char buf[1024]; - FILE *fp; - int rc = 0, index = 0; + struct obd_uuid name; + char buf[1024]; + char format[32]; + FILE *fp; + int rc = 0, index = 0; /* Get the lov name */ if (type == LOV_TYPE) { @@ -1777,9 +1803,11 @@ static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp, return rc; } - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (uuidp && (index < *ost_count)) { - if (sscanf(buf, "%d: %s", &index, uuidp[index].uuid) <2) + snprintf(format, sizeof(format), + "%%d: %%%zus", sizeof(uuidp[0].uuid) - 1); + while (fgets(buf, sizeof(buf), fp) != NULL) { + if (uuidp && (index < *ost_count)) { + if (sscanf(buf, format, &index, uuidp[index].uuid) < 2) break; } index++; @@ -1847,11 +1875,11 @@ int llapi_uuid_match(char *real_uuid, char *search_uuid) * returned in param->obdindex */ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) { - struct obd_uuid obd_uuid; - char uuid[sizeof(struct obd_uuid)]; - char buf[1024]; - FILE *fp; - int rc = 0, index; + struct obd_uuid obd_uuid; + char buf[1024]; + char format[32]; + FILE *fp; + int rc = 0; if (param->got_uuids) return rc; @@ -1887,12 +1915,17 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) llapi_printf(LLAPI_MSG_NORMAL, "%s:\n", param->get_lmv ? "MDTS" : "OBDS:"); - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (sscanf(buf, "%d: %s", &index, uuid) < 2) - break; + snprintf(format, sizeof(format), + "%%d: %%%zus", sizeof(obd_uuid.uuid) - 1); + while (fgets(buf, sizeof(buf), fp) != NULL) { + int index; - if (param->obduuid) { - if (llapi_uuid_match(uuid, param->obduuid->uuid)) { + if (sscanf(buf, format, &index, obd_uuid.uuid) < 2) + break; + + if (param->obduuid) { + if (llapi_uuid_match(obd_uuid.uuid, + param->obduuid->uuid)) { param->obdindex = index; break; } @@ -2070,7 +2103,7 @@ static int clilovpath(const char *fsname, const char *const pathname, if (rc != 0) return rc; - strncpy(clilovpath, buffer, sizeof(buffer)); + strlcpy(clilovpath, buffer, sizeof(buffer)); return 0; } @@ -2178,10 +2211,10 @@ static int sattr_cache_get_defaults(const char *const fsname, if (rc) return rc; } else { - strncpy(fsname_buf, fsname, PATH_MAX); + strlcpy(fsname_buf, fsname, sizeof(fsname_buf)); } - if (strncmp(fsname_buf, cache.fsname, PATH_MAX) != 0) { + if (strncmp(fsname_buf, cache.fsname, sizeof(fsname_buf) - 1) != 0) { /* * Ensure all 3 sattrs (count, size, and offset) are * successfully retrieved and stored in tmp before writing to @@ -2195,7 +2228,7 @@ static int sattr_cache_get_defaults(const char *const fsname, cache.stripecount = tmp[0]; cache.stripesize = tmp[1]; cache.stripeoffset = tmp[2]; - strncpy(cache.fsname, fsname_buf, PATH_MAX); + strlcpy(cache.fsname, fsname_buf, sizeof(cache.fsname)); } if (scount) @@ -2390,18 +2423,27 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, char *separator = ""; if (obdindex != OBD_NOT_FOUND) { - for (i = 0; i < lum->lum_stripe_count; i++) { - if (obdindex == objects[i].lum_mds) { - llapi_printf(LLAPI_MSG_NORMAL, "%s%s\n", prefix, - path); + if (lum->lum_stripe_count == 0) { + if (obdindex == lum->lum_stripe_offset) obdstripe = 1; - break; + } else { + for (i = 0; i < lum->lum_stripe_count; i++) { + if (obdindex == objects[i].lum_mds) { + llapi_printf(LLAPI_MSG_NORMAL, + "%s%s\n", prefix, + path); + obdstripe = 1; + break; + } } } } else { obdstripe = 1; } + if (!obdstripe) + return; + /* show all information default */ if (!verbose) { if (lum->lum_magic == LMV_USER_MAGIC) @@ -2419,7 +2461,10 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, llapi_printf(LLAPI_MSG_NORMAL, "lmv_stripe_count: "); llapi_printf(LLAPI_MSG_NORMAL, "%u", (int)lum->lum_stripe_count); - separator = "\n"; + if (verbose & VERBOSE_OFFSET) + separator = " "; + else + separator = "\n"; } if (verbose & VERBOSE_OFFSET) { @@ -2483,8 +2528,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) struct lov_user_ost_data_v1 *objects; struct lov_user_md_v3 *lmmv3 = (void *)¶m->lmd->lmd_lmm; - strncpy(pool_name, lmmv3->lmm_pool_name, LOV_MAXPOOLNAME); - pool_name[LOV_MAXPOOLNAME] = '\0'; + strlcpy(pool_name, lmmv3->lmm_pool_name, sizeof(pool_name)); objects = lmmv3->lmm_objects; lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, pool_name, objects, path, is_dir, @@ -2498,7 +2542,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) struct lmv_user_md *lum; lum = (struct lmv_user_md *)param->fp_lmv_md; - strncpy(pool_name, lum->lum_pool_name, LOV_MAXPOOLNAME); + strlcpy(pool_name, lum->lum_pool_name, sizeof(pool_name)); lmv_dump_user_lmm(lum, pool_name, path, param->obdindex, param->fp_max_depth, param->verbose); @@ -3283,18 +3327,11 @@ static int cb_getstripe(char *path, DIR *parent, DIR **dirp, void *data, (void *)¶m->lmd->lmd_lmm); } - } else if (parent) { + } else if (parent && !param->get_lmv && !param->get_default_lmv) { char *fname = strrchr(path, '/'); fname = (fname == NULL ? path : fname + 1); - if (param->get_lmv) { - llapi_printf(LLAPI_MSG_NORMAL, - "%s get dirstripe information for file\n", - path); - goto out; - } - - strncpy((char *)¶m->lmd->lmd_lmm, fname, param->lumlen); + strlcpy((char *)¶m->lmd->lmd_lmm, fname, param->lumlen); ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE, (void *)¶m->lmd->lmd_lmm); @@ -4093,7 +4130,7 @@ int llapi_changelog_start(void **priv, int flags, const char *device, cp->flags = flags; /* Set up the receiver */ - rc = libcfs_ukuc_start(&cp->kuc, 0 /* no group registration */); + rc = libcfs_ukuc_start(&cp->kuc, 0 /* no group registration */, 0); if (rc < 0) goto out_free; @@ -4430,14 +4467,21 @@ int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags) } /* - * Create a volatile file and open it for write: - * - file is created as a standard file in the directory - * - file does not appears in directory and directory mtime does not change - * - file is removed at close - * - file modes are rw-------, if user wants another one it must use fchmod() - * \param directory Directory where the file is created - * \param idx MDT index on which the file is created - * \param open_flags Standard open flags + * Create a file without any name open it for read/write + * + * - file is created as if it were a standard file in the given \a directory + * - file does not appear in \a directory and mtime does not change because + * the filename is handled specially by the Lustre MDS. + * - file is removed at final close + * - file modes are rw------- since it doesn't make sense to have a read-only + * or write-only file that cannot be opened again. + * - if user wants another mode it must use fchmod() on the open file, no + * security problems arise because it cannot be opened by another process. + * + * \param[in] directory directory from which to inherit layout/MDT idx + * \param[in] idx MDT index on which the file is created, + * \a idx == -1 means no specific MDT is requested + * \param[in] open_flags standard open(2) flags * * \retval 0 on success. * \retval -errno on error. @@ -4479,11 +4523,16 @@ int llapi_create_volatile_idx(char *directory, int idx, int open_flags) fd = open(file_path, O_RDWR | O_CREAT | open_flags, S_IRUSR | S_IWUSR); if (fd < 0) { llapi_error(LLAPI_MSG_ERROR, errno, - "Cannot create volatile file %s in %s\n", + "Cannot create volatile file '%s' in '%s'\n", filename + LUSTRE_VOLATILE_HDR_LEN, directory); return -errno; } + /* unlink file in case this wasn't a Lustre filesystem, and the + * magic volatile filename wasn't handled as intended. The effect + * is the same. */ + unlink(file_path); + return fd; }