@@ -54,7 +54,7 @@
/* OBD Operations Declarations */
struct obd_device *class_exp2obd(struct obd_export *exp);
int class_handle_ioctl(unsigned int cmd, unsigned long arg);
-int lustre_get_jobid(char *jobid);
+int lustre_get_jobid(char *jobid, size_t len);
struct lu_device_type;
@@ -1672,7 +1672,7 @@ static inline void class_uuid_unparse(class_uuid_t uu, struct obd_uuid *out)
int class_check_uuid(struct obd_uuid *uuid, u64 nid);
/* class_obd.c */
-extern char obd_jobid_node[];
+extern char obd_jobid_name[];
int class_procfs_init(void);
int class_procfs_clean(void);
@@ -195,11 +195,11 @@ struct ll_inode_info {
int lli_async_rc;
/*
- * whenever a process try to read/write the file, the
+ * Whenever a process try to read/write the file, the
* jobid of the process will be saved here, and it'll
* be packed into the write PRC when flush later.
*
- * so the read/write statistics for jobid will not be
+ * So the read/write statistics for jobid will not be
* accurate if the file is shared by different jobs.
*/
char lli_jobid[LUSTRE_JOBID_SIZE];
@@ -937,7 +937,7 @@ void ll_lli_init(struct ll_inode_info *lli)
lli->lli_async_rc = 0;
}
mutex_init(&lli->lli_layout_mutex);
- memset(lli->lli_jobid, 0, LUSTRE_JOBID_SIZE);
+ memset(lli->lli_jobid, 0, sizeof(lli->lli_jobid));
}
int ll_fill_super(struct super_block *sb)
@@ -1419,7 +1419,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
* it's not accurate if the file is shared by different
* jobs.
*/
- lustre_get_jobid(lli->lli_jobid);
+ lustre_get_jobid(lli->lli_jobid, sizeof(lli->lli_jobid));
} else if (io->ci_type == CIT_SETATTR) {
if (!cl_io_is_trunc(io))
io->ci_lockreq = CILR_MANDATORY;
@@ -212,7 +212,8 @@ static void vvp_req_attr_set(const struct lu_env *env, struct cl_object *obj,
obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid);
if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_INVALID_PFID))
oa->o_parent_oid++;
- memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid, LUSTRE_JOBID_SIZE);
+ memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid,
+ sizeof(attr->cra_jobid));
}
static const struct cl_object_operations vvp_ops = {
@@ -32,17 +32,19 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
+#include <linux/ctype.h>
#include <linux/user_namespace.h>
#ifdef HAVE_UIDGID_HEADER
#include <linux/uidgid.h>
#endif
+#include <linux/utsname.h>
#include <obd_support.h>
#include <obd_class.h>
#include <lustre_net.h>
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
-char obd_jobid_node[LUSTRE_JOBID_SIZE + 1];
+char obd_jobid_name[LUSTRE_JOBID_SIZE] = "%e.%u";
/* Get jobid of current process from stored variable or calculate
* it from pid and user_id.
@@ -52,9 +54,89 @@
* This is now deprecated.
*/
-int lustre_get_jobid(char *jobid)
+/*
+ * jobid_interpret_string()
+ *
+ * Interpret the jobfmt string to expand specified fields, like coredumps do:
+ * %e = executable
+ * %g = gid
+ * %h = hostname
+ * %j = jobid from environment
+ * %p = pid
+ * %u = uid
+ *
+ * Unknown escape strings are dropped. Other characters are copied through,
+ * excluding whitespace (to avoid making jobid parsing difficult).
+ *
+ * Return: -EOVERFLOW if the expanded string does not fit within @joblen
+ * 0 for success
+ */
+static int jobid_interpret_string(const char *jobfmt, char *jobid,
+ ssize_t joblen)
+{
+ char c;
+
+ while ((c = *jobfmt++) && joblen > 1) {
+ char f;
+ int l;
+
+ if (isspace(c)) /* Don't allow embedded spaces */
+ continue;
+
+ if (c != '%') {
+ *jobid = c;
+ joblen--;
+ jobid++;
+ continue;
+ }
+
+ switch ((f = *jobfmt++)) {
+ case 'e': /* executable name */
+ l = snprintf(jobid, joblen, "%s", current->comm);
+ break;
+ case 'g': /* group ID */
+ l = snprintf(jobid, joblen, "%u",
+ from_kgid(&init_user_ns, current_fsgid()));
+ break;
+ case 'h': /* hostname */
+ l = snprintf(jobid, joblen, "%s",
+ init_utsname()->nodename);
+ break;
+ case 'j': /* jobid requested by process
+ * - currently not supported
+ */
+ l = snprintf(jobid, joblen, "%s", "jobid");
+ break;
+ case 'p': /* process ID */
+ l = snprintf(jobid, joblen, "%u", current->pid);
+ break;
+ case 'u': /* user ID */
+ l = snprintf(jobid, joblen, "%u",
+ from_kuid(&init_user_ns, current_fsuid()));
+ break;
+ case '\0': /* '%' at end of format string */
+ l = 0;
+ goto out;
+ default: /* drop unknown %x format strings */
+ l = 0;
+ break;
+ }
+ jobid += l;
+ joblen -= l;
+ }
+ /*
+ * This points at the end of the buffer, so long as jobid is always
+ * incremented the same amount as joblen is decremented.
+ */
+out:
+ jobid[joblen - 1] = '\0';
+
+ return joblen < 0 ? -EOVERFLOW : 0;
+}
+
+int lustre_get_jobid(char *jobid, size_t joblen)
{
- char tmp_jobid[LUSTRE_JOBID_SIZE] = { 0 };
+ char tmp_jobid[LUSTRE_JOBID_SIZE] = "";
/* Jobstats isn't enabled */
if (strcmp(obd_jobid_var, JOBSTATS_DISABLE) == 0)
@@ -70,10 +152,11 @@ int lustre_get_jobid(char *jobid)
/* Whole node dedicated to single job */
if (strcmp(obd_jobid_var, JOBSTATS_NODELOCAL) == 0) {
- strcpy(tmp_jobid, obd_jobid_node);
- goto out_cache_jobid;
+ int rc2 = jobid_interpret_string(obd_jobid_name,
+ tmp_jobid, joblen);
+ if (!rc2)
+ goto out_cache_jobid;
}
-
return -ENOENT;
out_cache_jobid:
@@ -233,7 +233,7 @@ static ssize_t jobid_var_store(struct kobject *kobj, struct attribute *attr,
static ssize_t jobid_name_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%s\n", obd_jobid_node);
+ return snprintf(buf, PAGE_SIZE, "%s\n", obd_jobid_name);
}
static ssize_t jobid_name_store(struct kobject *kobj, struct attribute *attr,
@@ -243,13 +243,13 @@ static ssize_t jobid_name_store(struct kobject *kobj, struct attribute *attr,
if (!count || count > LUSTRE_JOBID_SIZE)
return -EINVAL;
- memcpy(obd_jobid_node, buffer, count);
+ memcpy(obd_jobid_name, buffer, count);
- obd_jobid_node[count] = 0;
+ obd_jobid_name[count] = 0;
/* Trim the trailing '\n' if any */
- if (obd_jobid_node[count - 1] == '\n')
- obd_jobid_node[count - 1] = 0;
+ if (obd_jobid_name[count - 1] == '\n')
+ obd_jobid_name[count - 1] = 0;
return count;
}
@@ -1406,9 +1406,9 @@ void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid)
LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
if (jobid)
- memcpy(pb->pb_jobid, jobid, LUSTRE_JOBID_SIZE);
+ memcpy(pb->pb_jobid, jobid, sizeof(pb->pb_jobid));
else if (pb->pb_jobid[0] == '\0')
- lustre_get_jobid(pb->pb_jobid);
+ lustre_get_jobid(pb->pb_jobid, sizeof(pb->pb_jobid));
return;
}
default:
@@ -635,7 +635,7 @@ struct ptlrpc_body_v3 {
__u64 pb_padding64_0;
__u64 pb_padding64_1;
__u64 pb_padding64_2;
- char pb_jobid[LUSTRE_JOBID_SIZE]; /* req: ASCII MPI jobid from env */
+ char pb_jobid[LUSTRE_JOBID_SIZE]; /* req: ASCII jobid from env + NUL */
};
#define ptlrpc_body ptlrpc_body_v3