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); }
int llapi_nodemap_exists(const char *nodemap) { glob_t param; int rc; rc = cfs_get_param_paths(¶m, "nodemap/%s", nodemap); cfs_free_param_data(¶m); return rc != 0 ? 1 : 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; }
/** * 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; }
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, ¶m, 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; }
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; }