Skip to content

Commit cadd964

Browse files
committed
Made some progress on the pid hash case, code is still a mess, have fixed many bugs but still not 100% working
1 parent 3d41960 commit cadd964

File tree

2 files changed

+81
-6
lines changed

2 files changed

+81
-6
lines changed

libdrgn/iterators.c

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,40 @@ struct drgn_error *pid_iter_init(struct drgn_program *prog,
256256
goto out;
257257
} else if (err->code == DRGN_ERROR_LOOKUP) {
258258
ret->has_idr = false;
259-
// TODO: pid_hash case
259+
ret->index = -1;
260+
ret->ns = ns;
261+
drgn_object_init(&ret->hlist_node, prog);
262+
ret->hlist_node.value.bufp = NULL;
263+
drgn_object_init(&ret->pid_hash, prog);
264+
drgn_object_init(&ret->entry, prog);
265+
err = drgn_program_find_object(prog, "pid_hash", NULL, DRGN_FIND_OBJECT_VARIABLE, &ret->pid_hash);
266+
if (err)
267+
goto out;
268+
err = drgn_program_find_type(prog, "struct pid", NULL,
269+
&ret->pid_type);
270+
if (err)
271+
goto out;
272+
err = drgn_program_find_type(prog, "struct upid", NULL,
273+
&ret->upid_type);
274+
if (err)
275+
goto out;
276+
struct drgn_object ns_level;
277+
drgn_object_init(&ns_level, prog);
278+
err = drgn_object_member_dereference(&ns_level, ns, "level");
279+
if (err)
280+
goto out;
281+
err = drgn_object_read_unsigned(&ns_level, &ret->ns_level);
282+
if (err)
283+
goto out;
284+
struct drgn_object pidhash_shift;
285+
drgn_object_init(&pidhash_shift, prog);
286+
err = drgn_program_find_object(prog, "pidhash_shift", NULL, DRGN_FIND_OBJECT_VARIABLE, &pidhash_shift);
287+
if (err)
288+
goto out;
289+
err = drgn_object_read_unsigned(&pidhash_shift, &ret->hash_length);
290+
if (err)
291+
goto out;
292+
ret->hash_length = 1 << ret->hash_length;
260293
} else {
261294
goto out;
262295
}
@@ -268,9 +301,10 @@ struct drgn_error *pid_iter_init(struct drgn_program *prog,
268301

269302
struct drgn_error *pid_iter_next(struct pid_iter *iter, pid_iter_entry_t **ret)
270303
{
304+
struct drgn_error *err;
271305
if (iter->has_idr) {
272306
idr_iter_entry_t *entry;
273-
struct drgn_error *err = idr_iter_next(&iter->iter, &entry);
307+
err = idr_iter_next(&iter->iter, &entry);
274308
if (err)
275309
return err;
276310
if (!entry) {
@@ -283,9 +317,45 @@ struct drgn_error *pid_iter_next(struct pid_iter *iter, pid_iter_entry_t **ret)
283317
*ret = &entry->node;
284318
return err;
285319
} else {
286-
//TODO
287-
return NULL;
320+
while (true) {
321+
if (iter->index != -1 && iter->index >= iter->hash_length) {
322+
*ret = NULL;
323+
return NULL;
324+
}
325+
if (!iter->hlist_node.value.bufp) {
326+
err = drgn_object_subscript(&iter->hlist_node, &iter->pid_hash, ++iter->index);
327+
if (err)
328+
return err;
329+
err = drgn_object_member(&iter->hlist_node, &iter->hlist_node, "first");
330+
if (err)
331+
return err;
332+
} else {
333+
err = drgn_object_member(&iter->hlist_node, &iter->hlist_node, "next");
334+
if (err)
335+
return err;
336+
}
337+
err = drgn_object_container_of(&iter->entry, &iter->hlist_node, iter->upid_type, "pid_chain");
338+
if (err)
339+
return err;
340+
struct drgn_object upid_ns;
341+
drgn_object_init(&upid_ns, drgn_object_program(&iter->entry));
342+
err = drgn_object_member_dereference(&upid_ns, &iter->entry, "ns");
343+
if (err)
344+
return err;
345+
// TODO: if upid.ns == ns
346+
if (upid_ns.value.bufp != iter->ns->value.bufp)
347+
continue;
348+
char* member;
349+
// TODO do this at init and save it to iter->member or something
350+
asprintf(&member, "numbers[%lu]", iter->ns_level);
351+
err = drgn_object_container_of(&iter->entry, &iter->entry, iter->pid_type, member);
352+
if (err)
353+
return err;
354+
*ret = &iter->entry;
355+
break;
356+
}
288357
}
358+
return NULL;
289359
}
290360

291361
struct drgn_error *task_iter_init(struct drgn_program *prog,

libdrgn/iterators.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,20 @@ typedef struct drgn_object pid_iter_entry_t;
5757

5858
struct pid_iter {
5959
bool has_idr;
60+
struct drgn_qualified_type pid_type;
6061
union {
6162
struct {
6263
struct idr_iter iter;
63-
struct drgn_qualified_type pid_type;
6464
};
6565
struct {
66+
struct drgn_object* ns;
6667
pid_iter_entry_t entry;
6768
struct drgn_object pid_hash;
68-
uint64_t pid_hash_shift;
69+
struct drgn_object hlist_node;
70+
struct drgn_qualified_type upid_type;
71+
size_t hash_length;
72+
int index;
73+
uint64_t ns_level;
6974
};
7075
};
7176
};

0 commit comments

Comments
 (0)