@@ -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
269302struct 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
291361struct drgn_error * task_iter_init (struct drgn_program * prog ,
0 commit comments