Commit 7af5729474b5b8ad385adadab78d6e723e7655a3

Authored by Pavel Emelyanov
Committed by Linus Torvalds
1 parent 8ef047aaae

pid namespaces: helpers to obtain pid numbers

When showing pid to user or getting the pid numerical id for in-kernel use the
value of this id may differ depending on the namespace.

This set of helpers is used to get the global pid nr, the virtual (i.e.  seen
by task in its namespace) nr and the nr as it is seen from the specified
namespace.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Sukadev Bhattiprolu <sukadev@us.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 134 additions and 11 deletions Side-by-side Diff

... ... @@ -114,11 +114,33 @@
114 114 extern struct pid *alloc_pid(struct pid_namespace *ns);
115 115 extern void FASTCALL(free_pid(struct pid *pid));
116 116  
  117 +/*
  118 + * the helpers to get the pid's id seen from different namespaces
  119 + *
  120 + * pid_nr() : global id, i.e. the id seen from the init namespace;
  121 + * pid_vnr() : virtual id, i.e. the id seen from the namespace this pid
  122 + * belongs to. this only makes sence when called in the
  123 + * context of the task that belongs to the same namespace;
  124 + * pid_nr_ns() : id seen from the ns specified.
  125 + *
  126 + * see also task_xid_nr() etc in include/linux/sched.h
  127 + */
  128 +
117 129 static inline pid_t pid_nr(struct pid *pid)
118 130 {
119 131 pid_t nr = 0;
120 132 if (pid)
121   - nr = pid->nr;
  133 + nr = pid->numbers[0].nr;
  134 + return nr;
  135 +}
  136 +
  137 +pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
  138 +
  139 +static inline pid_t pid_vnr(struct pid *pid)
  140 +{
  141 + pid_t nr = 0;
  142 + if (pid)
  143 + nr = pid->numbers[pid->level].nr;
122 144 return nr;
123 145 }
124 146  
include/linux/sched.h
... ... @@ -1188,16 +1188,6 @@
1188 1188 return rt_prio(p->prio);
1189 1189 }
1190 1190  
1191   -static inline pid_t task_pgrp_nr(struct task_struct *tsk)
1192   -{
1193   - return tsk->signal->pgrp;
1194   -}
1195   -
1196   -static inline pid_t task_session_nr(struct task_struct *tsk)
1197   -{
1198   - return tsk->signal->__session;
1199   -}
1200   -
1201 1191 static inline void set_task_session(struct task_struct *tsk, pid_t session)
1202 1192 {
1203 1193 tsk->signal->__session = session;
... ... @@ -1221,6 +1211,104 @@
1221 1211 static inline struct pid *task_session(struct task_struct *task)
1222 1212 {
1223 1213 return task->group_leader->pids[PIDTYPE_SID].pid;
  1214 +}
  1215 +
  1216 +struct pid_namespace;
  1217 +
  1218 +/*
  1219 + * the helpers to get the task's different pids as they are seen
  1220 + * from various namespaces
  1221 + *
  1222 + * task_xid_nr() : global id, i.e. the id seen from the init namespace;
  1223 + * task_xid_vnr() : virtual id, i.e. the id seen from the namespace the task
  1224 + * belongs to. this only makes sence when called in the
  1225 + * context of the task that belongs to the same namespace;
  1226 + * task_xid_nr_ns() : id seen from the ns specified;
  1227 + *
  1228 + * set_task_vxid() : assigns a virtual id to a task;
  1229 + *
  1230 + * task_ppid_nr_ns() : the parent's id as seen from the namespace specified.
  1231 + * the result depends on the namespace and whether the
  1232 + * task in question is the namespace's init. e.g. for the
  1233 + * namespace's init this will return 0 when called from
  1234 + * the namespace of this init, or appropriate id otherwise.
  1235 + *
  1236 + *
  1237 + * see also pid_nr() etc in include/linux/pid.h
  1238 + */
  1239 +
  1240 +static inline pid_t task_pid_nr(struct task_struct *tsk)
  1241 +{
  1242 + return tsk->pid;
  1243 +}
  1244 +
  1245 +static inline pid_t task_pid_nr_ns(struct task_struct *tsk,
  1246 + struct pid_namespace *ns)
  1247 +{
  1248 + return pid_nr_ns(task_pid(tsk), ns);
  1249 +}
  1250 +
  1251 +static inline pid_t task_pid_vnr(struct task_struct *tsk)
  1252 +{
  1253 + return pid_vnr(task_pid(tsk));
  1254 +}
  1255 +
  1256 +
  1257 +static inline pid_t task_tgid_nr(struct task_struct *tsk)
  1258 +{
  1259 + return tsk->tgid;
  1260 +}
  1261 +
  1262 +static inline pid_t task_tgid_nr_ns(struct task_struct *tsk,
  1263 + struct pid_namespace *ns)
  1264 +{
  1265 + return pid_nr_ns(task_tgid(tsk), ns);
  1266 +}
  1267 +
  1268 +static inline pid_t task_tgid_vnr(struct task_struct *tsk)
  1269 +{
  1270 + return pid_vnr(task_tgid(tsk));
  1271 +}
  1272 +
  1273 +
  1274 +static inline pid_t task_pgrp_nr(struct task_struct *tsk)
  1275 +{
  1276 + return tsk->signal->pgrp;
  1277 +}
  1278 +
  1279 +static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk,
  1280 + struct pid_namespace *ns)
  1281 +{
  1282 + return pid_nr_ns(task_pgrp(tsk), ns);
  1283 +}
  1284 +
  1285 +static inline pid_t task_pgrp_vnr(struct task_struct *tsk)
  1286 +{
  1287 + return pid_vnr(task_pgrp(tsk));
  1288 +}
  1289 +
  1290 +
  1291 +static inline pid_t task_session_nr(struct task_struct *tsk)
  1292 +{
  1293 + return tsk->signal->__session;
  1294 +}
  1295 +
  1296 +static inline pid_t task_session_nr_ns(struct task_struct *tsk,
  1297 + struct pid_namespace *ns)
  1298 +{
  1299 + return pid_nr_ns(task_session(tsk), ns);
  1300 +}
  1301 +
  1302 +static inline pid_t task_session_vnr(struct task_struct *tsk)
  1303 +{
  1304 + return pid_vnr(task_session(tsk));
  1305 +}
  1306 +
  1307 +
  1308 +static inline pid_t task_ppid_nr_ns(struct task_struct *tsk,
  1309 + struct pid_namespace *ns)
  1310 +{
  1311 + return pid_nr_ns(task_pid(rcu_dereference(tsk->real_parent)), ns);
1224 1312 }
1225 1313  
1226 1314 /**
... ... @@ -376,6 +376,19 @@
376 376 return pid;
377 377 }
378 378  
  379 +pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
  380 +{
  381 + struct upid *upid;
  382 + pid_t nr = 0;
  383 +
  384 + if (pid && ns->level <= pid->level) {
  385 + upid = &pid->numbers[ns->level];
  386 + if (upid->ns == ns)
  387 + nr = upid->nr;
  388 + }
  389 + return nr;
  390 +}
  391 +
379 392 /*
380 393 * Used by proc to find the first pid that is greater then or equal to nr.
381 394 *