コード例 #1
0
static void set_log_level()
{
	unsigned int level;
	glob_t path;
	FILE *file;

	if (cfs_get_param_paths(&path,
				"sptlrpc/gss/lgss_keyring/debug_level") != 0)
		return;
	file = fopen(path.gl_pathv[0], "r");
	if (file == NULL) {
		cfs_free_param_data(&path);
		return;
	}

	if (fscanf(file, "%u", &level) != 1)
		goto out;

	if (level >= LL_MAX)
		goto out;

	lgss_set_loglevel(level);
out:
	cfs_free_param_data(&path);
	fclose(file);
}
コード例 #2
0
int llapi_nodemap_exists(const char *nodemap)
{
	glob_t param;
	int rc;

	rc = cfs_get_param_paths(&param, "nodemap/%s", nodemap);
	cfs_free_param_data(&param);
	return rc != 0 ? 1 : 0;
}
コード例 #3
0
int compare(struct obd_uuid *puuid, struct lov_user_md *lum_dir,
	    struct lov_user_md *lum_file1, struct lov_user_md *lum_file2)
{
	int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
	int stripe_size = 0;
	int stripe_offset = -1;
	int ost_count;
	char buf[128];
	glob_t path;
	int i;

	if (cfs_get_param_paths(&path, "lov/%s/stripecount", puuid->uuid) != 0)
		return 2;
	if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
		cfs_free_param_data(&path);
                return 5;
	}
	cfs_free_param_data(&path);
	def_stripe_count = (short)atoi(buf);

	if (cfs_get_param_paths(&path, "lov/%s/numobd", puuid->uuid) != 0)
		return 2;
	if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
		cfs_free_param_data(&path);
                return 6;
	}
	cfs_free_param_data(&path);
        ost_count = atoi(buf);

        if (lum_dir == NULL) {
                stripe_count = def_stripe_count;
                min_stripe_count = -1;
        } else {
                stripe_count = (signed short)lum_dir->lmm_stripe_count;
                printf("dir stripe %d, ", stripe_count);
                min_stripe_count = 1;
        }

        printf("default stripe %d, ost count %d\n",
               def_stripe_count, ost_count);

        if (stripe_count == 0) {
                min_stripe_count = -1;
                stripe_count = 1;
        }

        stripe_count = (stripe_count > 0 && stripe_count <= ost_count) ?
                                                stripe_count : ost_count;
        min_stripe_count = min_stripe_count > 0 ? stripe_count :
                                                ((stripe_count + 1) / 2);

        if (lum_file1->lmm_stripe_count != stripe_count ||
            lum_file1->lmm_stripe_count < min_stripe_count) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "file1 stripe count %d != dir %d\n",
                                  lum_file1->lmm_stripe_count, stripe_count);
                return 7;
        }

        if (lum_file1->lmm_stripe_count < stripe_count)
                llapi_err_noerrno(LLAPI_MSG_WARN,
                                  "warning: file1 used fewer stripes"
                                  " %d < dir %d (likely due to bug 4900)\n",
                                  lum_file1->lmm_stripe_count, stripe_count);

        if (lum_dir != NULL)
                stripe_size = (int)lum_dir->lmm_stripe_size;
        if (stripe_size == 0) {
		if (cfs_get_param_paths(&path, "lov/%s/stripesize",
					puuid->uuid) != 0)
			return 2;
		if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
			cfs_free_param_data(&path);
			return 5;
		}
		cfs_free_param_data(&path);

                stripe_size = atoi(buf);
        }

        if (lum_file1->lmm_stripe_size != stripe_size) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "file1 stripe size %d != dir %d\n",
                                  lum_file1->lmm_stripe_size, stripe_size);
                return 8;
        }

        if (lum_dir != NULL)
                stripe_offset = (short int)lum_dir->lmm_stripe_offset;
        if (stripe_offset != -1) {
                for (i = 0; i < stripe_count; i++)
                        if (lum_file1->lmm_objects[i].l_ost_idx !=
                            (stripe_offset + i) % ost_count) {
                                llapi_err_noerrno(LLAPI_MSG_WARN,
                                          "warning: file1 non-sequential "
                                          "stripe[%d] %d != %d\n", i,
                                          lum_file1->lmm_objects[i].l_ost_idx,
                                          (stripe_offset + i) % ost_count);
                        }
        } else if (lum_file2 != NULL) {
                int next, idx, stripe = stripe_count - 1;
                next = (lum_file1->lmm_objects[stripe].l_ost_idx + 1) %
                       ost_count;
                idx = lum_file2->lmm_objects[0].l_ost_idx;
                if (idx != next) {
                        llapi_err_noerrno(LLAPI_MSG_WARN,
                                  "warning: non-sequential "
                                  "file1 stripe[%d] %d != file2 stripe[0] %d\n",
                                  stripe, lum_file1->lmm_objects[stripe].l_ost_idx,
                                  idx);
                }
        }

        return 0;
}
コード例 #4
0
ファイル: lustre_cfg.c プロジェクト: KnightKu/lustre-stable
/**
 * Perform a read, write or just a listing of a parameter
 *
 * \param[in] popt		list,set,get parameter options
 * \param[in] pattern		search filter for the path of the parameter
 * \param[in] value		value to set the parameter if write operation
 * \param[in] mode		what operation to perform with the parameter
 *
 * \retval number of bytes written on success.
 * \retval -errno on error and prints error message.
 */
static int
param_display(struct param_opts *popt, char *pattern, char *value,
	      enum parameter_operation mode)
{
	int dir_count = 0;
	char **dir_cache;
	glob_t paths;
	char *opname = parameter_opname[mode];
	int rc, i;

	rc = cfs_get_param_paths(&paths, "%s", pattern);
	if (rc != 0) {
		rc = -errno;
		if (!popt->po_recursive) {
			fprintf(stderr, "error: %s: param_path '%s': %s\n",
				opname, pattern, strerror(errno));
		}
		return rc;
	}

	dir_cache = calloc(paths.gl_pathc, sizeof(char *));
	if (dir_cache == NULL) {
		rc = -ENOMEM;
		fprintf(stderr,
			"error: %s: allocating '%s' dir_cache[%zd]: %s\n",
			opname, pattern, paths.gl_pathc, strerror(-rc));
		goto out_param;
	}

	for (i = 0; i < paths.gl_pathc; i++) {
		char *param_name = NULL, *tmp;
		char pathname[PATH_MAX];
		struct stat st;
		int rc2;

		if (stat(paths.gl_pathv[i], &st) == -1) {
			fprintf(stderr, "error: %s: stat '%s': %s\n",
				opname, paths.gl_pathv[i], strerror(errno));
			if (rc == 0)
				rc = -errno;
			continue;
		}

		if (popt->po_only_dir && !S_ISDIR(st.st_mode))
			continue;

		param_name = display_name(paths.gl_pathv[i], &st, popt);
		if (param_name == NULL) {
			fprintf(stderr,
				"error: %s: generating name for '%s': %s\n",
				opname, paths.gl_pathv[i], strerror(ENOMEM));
			if (rc == 0)
				rc = -ENOMEM;
			continue;
		}

		/**
		 * For the upstream client the parameter files locations
		 * are split between under both /sys/kernel/debug/lustre
		 * and /sys/fs/lustre. The parameter files containing
		 * small amounts of data, less than a page in size, are
		 * located under /sys/fs/lustre and in the case of large
		 * parameter data files, think stats for example, are
		 * located in the debugfs tree. Since the files are split
		 * across two trees the directories are often duplicated
		 * which means these directories are listed twice which
		 * leads to duplicate output to the user. To avoid scanning
		 * a directory twice we have to cache any directory and
		 * check if a search has been requested twice.
		 */
		if (S_ISDIR(st.st_mode)) {
			int j;

			for (j = 0; j < dir_count; j++) {
				if (!strcmp(dir_cache[j], param_name))
					break;
			}
			if (j != dir_count) {
				free(param_name);
				param_name = NULL;
				continue;
			}
			dir_cache[dir_count++] = strdup(param_name);
		}

		switch (mode) {
		case GET_PARAM:
			/* Read the contents of file to stdout */
			if (S_ISREG(st.st_mode))
				read_param(paths.gl_pathv[i], param_name, popt);
			break;
		case SET_PARAM:
			if (S_ISREG(st.st_mode)) {
				rc2 = write_param(paths.gl_pathv[i],
						  param_name, popt, value);
				if (rc2 < 0 && rc == 0)
					rc = rc2;
			}
			break;
		case LIST_PARAM:
			if (popt->po_show_path)
				printf("%s\n", param_name);
			break;
		}

		/* Only directories are searched recursively if
		 * requested by the user */
		if (!S_ISDIR(st.st_mode) || !popt->po_recursive) {
			free(param_name);
			param_name = NULL;
			continue;
		}

		/* Turn param_name into file path format */
		rc2 = clean_path(popt, param_name);
		if (rc2 < 0) {
			fprintf(stderr, "error: %s: cleaning '%s': %s\n",
				opname, param_name, strerror(-rc2));
			free(param_name);
			param_name = NULL;
			if (rc == 0)
				rc = rc2;
			continue;
		}

		/* Use param_name to grab subdirectory tree from full path */
		tmp = strstr(paths.gl_pathv[i], param_name);

		/* cleanup paramname now that we are done with it */
		free(param_name);
		param_name = NULL;

		/* Shouldn't happen but just in case */
		if (tmp == NULL) {
			if (rc == 0)
				rc = -EINVAL;
			continue;
		}

		rc2 = snprintf(pathname, sizeof(pathname), "%s/*", tmp);
		if (rc2 < 0) {
			/* snprintf() should never an error, and if it does
			 * there isn't much point trying to use fprintf() */
			continue;
		}
		if (rc2 >= sizeof(pathname)) {
			fprintf(stderr, "error: %s: overflow processing '%s'\n",
				opname, pathname);
			if (rc == 0)
				rc = -EINVAL;
			continue;
		}

		rc2 = param_display(popt, pathname, value, mode);
		if (rc2 != 0 && rc2 != -ENOENT) {
			/* errors will be printed by param_display() */
			if (rc == 0)
				rc = rc2;
			continue;
		}
	}

	for (i = 0; i < dir_count; i++)
		free(dir_cache[i]);
	free(dir_cache);
out_param:
	cfs_free_param_data(&paths);
	return rc;
}
コード例 #5
0
int do_nego_rpc(struct lgss_nego_data *lnd,
                gss_buffer_desc *gss_token,
                struct lgss_init_res *gr)
{
	struct lgssd_ioctl_param param;
	struct passwd *pw;
	int fd, ret, res;
	char outbuf[8192];
	unsigned int *p;
	glob_t path;
	int rc;

        logmsg(LL_TRACE, "start negotiation rpc\n");

        pw = getpwuid(lnd->lnd_uid);
        if (!pw) {
                logmsg(LL_ERR, "no uid %u in local user database\n",
                       lnd->lnd_uid);
                return -EACCES;
        }

        param.version = GSSD_INTERFACE_VERSION;
        param.secid = lnd->lnd_secid;
        param.uuid = lnd->lnd_uuid;
        param.lustre_svc = lnd->lnd_lsvc;
        param.uid = lnd->lnd_uid;
        param.gid = pw->pw_gid;
        param.send_token_size = gss_token->length;
        param.send_token = (char *) gss_token->value;
        param.reply_buf_size = sizeof(outbuf);
        param.reply_buf = outbuf;

	rc = cfs_get_param_paths(&path, "sptlrpc/gss/init_channel");
	if (rc != 0)
		return rc;

	logmsg(LL_TRACE, "to open %s\n", path.gl_pathv[0]);

	fd = open(path.gl_pathv[0], O_WRONLY);
        if (fd < 0) {
		logmsg(LL_ERR, "can't open %s\n", path.gl_pathv[0]);
		rc = -EACCES;
		goto out_params;
        }

	logmsg(LL_TRACE, "to down-write\n");

	ret = write(fd, &param, sizeof(param));
	close(fd);
	if (ret != sizeof(param)) {
		logmsg(LL_ERR, "lustre ioctl err: %s\n", strerror(errno));
		rc = -EACCES;
		goto out_params;
	}

        logmsg(LL_TRACE, "do_nego_rpc: to parse reply\n");
        if (param.status) {
		logmsg(LL_ERR, "status: %ld (%s)\n",
		       param.status, strerror((int)param.status));

                /* kernel return -ETIMEDOUT means the rpc timedout, we should
                 * notify the caller to reinitiate the gss negotiation, by
                 * returning -ERESTART
                 */
                if (param.status == -ETIMEDOUT)
			rc = -ERESTART;
		else
			rc = param.status;
		goto out_params;
	}

        p = (unsigned int *)outbuf;
        res = *p++;
        gr->gr_major = *p++;
        gr->gr_minor = *p++;
        gr->gr_win = *p++;

        gr->gr_ctx.length = *p++;
        gr->gr_ctx.value = malloc(gr->gr_ctx.length);
        memcpy(gr->gr_ctx.value, p, gr->gr_ctx.length);
        p += (((gr->gr_ctx.length + 3) & ~3) / 4);

        gr->gr_token.length = *p++;
        gr->gr_token.value = malloc(gr->gr_token.length);
        memcpy(gr->gr_token.value, p, gr->gr_token.length);
        p += (((gr->gr_token.length + 3) & ~3) / 4);

	logmsg(LL_DEBUG, "do_nego_rpc: receive handle len %zu, token len %zu, "
	       "res %d\n", gr->gr_ctx.length, gr->gr_token.length, res);
out_params:
	cfs_free_param_data(&path);
	return rc;
}
コード例 #6
0
ファイル: l_getidentity.c プロジェクト: Xyratex/lustre-stable
int main(int argc, char **argv)
{
	char *end;
	struct identity_downcall_data *data = NULL;
	glob_t path;
	unsigned long uid;
	int fd, rc = -EINVAL, size, maxgroups;

	progname = basename(argv[0]);
	if (argc != 3) {
		usage();
		goto out;
	}

	uid = strtoul(argv[2], &end, 0);
	if (*end) {
		errlog("%s: invalid uid '%s'\n", progname, argv[2]);
		goto out;
	}

	maxgroups = sysconf(_SC_NGROUPS_MAX);
	if (maxgroups > NGROUPS_MAX)
		maxgroups = NGROUPS_MAX;
	if (maxgroups == -1) {
		rc = -EINVAL;
		goto out;
	}

	size = offsetof(struct identity_downcall_data, idd_groups[maxgroups]);
	data = malloc(size);
	if (!data) {
		errlog("malloc identity downcall data(%d) failed!\n", size);
		rc = -ENOMEM;
		goto out;
	}

	memset(data, 0, size);
	data->idd_magic = IDENTITY_DOWNCALL_MAGIC;
	data->idd_uid = uid;
	/* get groups for uid */
	rc = get_groups_local(data, maxgroups);
	if (rc)
		goto downcall;

	size = offsetof(struct identity_downcall_data,
			idd_groups[data->idd_ngroups]);
	/* read permission database */
	rc = get_perms(data);

downcall:
	if (strcmp(argv[1], "-d") == 0 || getenv("L_GETIDENTITY_TEST")) {
		show_result(data);
		rc = 0;
		goto out;
	}

	rc = cfs_get_param_paths(&path, "mdt/%s/identity_info", argv[1]);
	if (rc != 0) {
		rc = -errno;
		goto out;
	}

	fd = open(path.gl_pathv[0], O_WRONLY);
	if (fd < 0) {
		errlog("can't open file '%s':%s\n", path.gl_pathv[0],
		       strerror(errno));
		rc = -errno;
		goto out_params;
	}

	rc = write(fd, data, size);
	close(fd);
	if (rc != size) {
		errlog("partial write ret %d: %s\n", rc, strerror(errno));
		rc = -1;
	} else {
		rc = 0;
	}

out_params:
	cfs_free_param_data(&path);
out:
	if (data)
		free(data);
	return rc;
}