Skip to content

Commit a676363

Browse files
clementFoyerbgoglin
authored andcommitted
utils/archivemount: Restore working directory
* After loading the topology in the directory mounted with archivemount, we restore the original working directory. * Add hwloc_utils_disable_input_format() to free the file descriptor. Solves #577 Signed-off-by: Clément Foyer <[email protected]>
1 parent b2238c8 commit a676363

File tree

5 files changed

+92
-22
lines changed

5 files changed

+92
-22
lines changed

utils/hwloc/hwloc-calc.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © 2009-2023 Inria. All rights reserved.
44
* Copyright © 2009-2011 Université Bordeaux
55
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
6+
* Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
67
* See COPYING in top-level directory.
78
*/
89

@@ -316,7 +317,7 @@ int main(int argc, char *argv[])
316317
unsigned long flags = HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT;
317318
unsigned long restrict_flags = 0;
318319
char *input = NULL;
319-
enum hwloc_utils_input_format input_format = HWLOC_UTILS_INPUT_DEFAULT;
320+
struct hwloc_utils_input_format_s input_format = HWLOC_UTILS_INPUT_FORMAT_DEFAULT;
320321
int depth = 0;
321322
hwloc_bitmap_t set;
322323
int cmdline_args = 0;
@@ -463,6 +464,9 @@ int main(int argc, char *argv[])
463464
/* FALLTHRU */
464465
}
465466
}
467+
if (input) {
468+
hwloc_utils_disable_input_format(&input_format);
469+
}
466470

467471
while (argc >= 1) {
468472
opt = 0;

utils/hwloc/hwloc-distrib.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © 2009-2022 Inria. All rights reserved.
44
* Copyright © 2009-2010 Université Bordeaux
55
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6+
* Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
67
* See COPYING in top-level directory.
78
*/
89

@@ -43,7 +44,7 @@ int main(int argc, char *argv[])
4344
long n = -1;
4445
char *callname;
4546
char *input = NULL;
46-
enum hwloc_utils_input_format input_format = HWLOC_UTILS_INPUT_DEFAULT;
47+
struct hwloc_utils_input_format_s input_format = HWLOC_UTILS_INPUT_FORMAT_DEFAULT;
4748
int taskset = 0;
4849
int singlify = 0;
4950
int verbose = 0;
@@ -229,8 +230,12 @@ int main(int argc, char *argv[])
229230
err = hwloc_topology_load(topology);
230231
if (err < 0) {
231232
free(cpuset);
233+
if (input) hwloc_utils_disable_input_format(&input_format);
232234
return EXIT_FAILURE;
233235
}
236+
if (input) {
237+
hwloc_utils_disable_input_format(&input_format);
238+
}
234239

235240
if (restrictstring) {
236241
hwloc_bitmap_t restrictset = hwloc_bitmap_alloc();

utils/hwloc/hwloc-info.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © 2009-2022 Inria. All rights reserved.
44
* Copyright © 2009-2012 Université Bordeaux
55
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6+
* Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
67
* See COPYING in top-level directory.
78
*/
89

@@ -495,7 +496,7 @@ main (int argc, char *argv[])
495496
unsigned long restrict_flags = 0;
496497
char * callname;
497498
char * input = NULL;
498-
enum hwloc_utils_input_format input_format = HWLOC_UTILS_INPUT_DEFAULT;
499+
struct hwloc_utils_input_format_s input_format = HWLOC_UTILS_INPUT_FORMAT_DEFAULT;
499500
const char *show_ancestor_type = NULL;
500501
const char *show_descendants_type = NULL;
501502
const char *best_memattr_str = NULL;
@@ -721,16 +722,22 @@ main (int argc, char *argv[])
721722
if (hwloc_pid_from_number(&pid, pid_number, 0, 1 /* verbose */) < 0
722723
|| hwloc_topology_set_pid(topology, pid)) {
723724
perror("Setting target pid");
725+
if (input) hwloc_utils_disable_input_format(&input_format);
724726
return EXIT_FAILURE;
725727
}
726728
}
727729

728730
err = hwloc_topology_load (topology);
729731
if (err) {
730732
perror("hwloc_topology_load");
733+
if (input) hwloc_utils_disable_input_format(&input_format);
731734
return EXIT_FAILURE;
732735
}
733736

737+
if (input) {
738+
hwloc_utils_disable_input_format(&input_format);
739+
}
740+
734741
topodepth = hwloc_topology_get_depth(topology);
735742

736743
if (show_ancestor_type) {

utils/hwloc/misc.h

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © 2009-2023 Inria. All rights reserved.
44
* Copyright © 2009-2012 Université Bordeaux
55
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6+
* Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
67
* See COPYING in top-level directory.
78
*/
89

@@ -26,6 +27,7 @@
2627
#ifdef HAVE_DIRENT_H
2728
#include <dirent.h>
2829
#endif
30+
#include <fcntl.h>
2931
#include <assert.h>
3032

3133
extern void usage(const char *name, FILE *where);
@@ -80,15 +82,19 @@ hwloc_utils_input_format_usage(FILE *where, int addspaces)
8082
addspaces, " ");
8183
}
8284

83-
enum hwloc_utils_input_format {
84-
HWLOC_UTILS_INPUT_DEFAULT,
85-
HWLOC_UTILS_INPUT_XML,
86-
HWLOC_UTILS_INPUT_FSROOT,
87-
HWLOC_UTILS_INPUT_SYNTHETIC,
88-
HWLOC_UTILS_INPUT_CPUID,
89-
HWLOC_UTILS_INPUT_SHMEM,
90-
HWLOC_UTILS_INPUT_ARCHIVE
85+
struct hwloc_utils_input_format_s {
86+
enum hwloc_utils_input_format {
87+
HWLOC_UTILS_INPUT_DEFAULT,
88+
HWLOC_UTILS_INPUT_XML,
89+
HWLOC_UTILS_INPUT_FSROOT,
90+
HWLOC_UTILS_INPUT_SYNTHETIC,
91+
HWLOC_UTILS_INPUT_CPUID,
92+
HWLOC_UTILS_INPUT_SHMEM,
93+
HWLOC_UTILS_INPUT_ARCHIVE
94+
} format;
95+
int oldworkdir;
9196
};
97+
#define HWLOC_UTILS_INPUT_FORMAT_DEFAULT (struct hwloc_utils_input_format_s) { HWLOC_UTILS_INPUT_DEFAULT, -1 }
9298

9399
static __hwloc_inline enum hwloc_utils_input_format
94100
hwloc_utils_parse_input_format(const char *name, const char *callname)
@@ -115,7 +121,7 @@ hwloc_utils_parse_input_format(const char *name, const char *callname)
115121

116122
static __hwloc_inline int
117123
hwloc_utils_lookup_input_option(char *argv[], int argc, int *consumed_opts,
118-
char **inputp, enum hwloc_utils_input_format *input_formatp,
124+
char **inputp, struct hwloc_utils_input_format_s *input_formatp,
119125
const char *callname)
120126
{
121127
if (!strcmp (argv[0], "--input")
@@ -137,7 +143,8 @@ hwloc_utils_lookup_input_option(char *argv[], int argc, int *consumed_opts,
137143
usage (callname, stderr);
138144
exit(EXIT_FAILURE);
139145
}
140-
*input_formatp = hwloc_utils_parse_input_format (argv[1], callname);
146+
*input_formatp = HWLOC_UTILS_INPUT_FORMAT_DEFAULT;
147+
input_formatp->format = hwloc_utils_parse_input_format (argv[1], callname);
141148
*consumed_opts = 1;
142149
return 1;
143150
}
@@ -202,9 +209,10 @@ hwloc_utils_autodetect_input_format(const char *input, int verbose)
202209
static __hwloc_inline int
203210
hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long flags,
204211
const char *input,
205-
enum hwloc_utils_input_format *input_format,
212+
struct hwloc_utils_input_format_s *input_formatp,
206213
int verbose, const char *callname)
207214
{
215+
enum hwloc_utils_input_format *input_format = &input_formatp->format;
208216
if (*input_format == HWLOC_UTILS_INPUT_DEFAULT && !strcmp(input, "-.xml")) {
209217
*input_format = HWLOC_UTILS_INPUT_XML;
210218
input = "-";
@@ -283,19 +291,31 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
283291
char umntcmd[512];
284292
DIR *dir;
285293
struct dirent *dirent;
286-
enum hwloc_utils_input_format sub_input_format;
294+
/* oldworkdir == -1 -> close would fail if !defined(O_PATH), but we don't care */
295+
struct hwloc_utils_input_format_s sub_input_format = HWLOC_UTILS_INPUT_FORMAT_DEFAULT;
287296
char *subdir = NULL;
288297
int err;
289298

299+
#ifdef O_PATH
300+
if (-1 == input_formatp->oldworkdir) { /* if archivemount'ed recursively, only keep the first oldworkdir */
301+
sub_input_format.oldworkdir = open(".", O_DIRECTORY|O_PATH); /* more efficient than getcwd(3) */
302+
if (sub_input_format.oldworkdir < 0) {
303+
perror("Saving current working directory");
304+
return EXIT_FAILURE;
305+
}
306+
}
307+
#endif
290308
if (!mkdtemp(mntpath)) {
291309
perror("Creating archivemount directory");
310+
close(sub_input_format.oldworkdir);
292311
return EXIT_FAILURE;
293312
}
294313
snprintf(mntcmd, sizeof(mntcmd), "archivemount -o ro %s %s", input, mntpath);
295314
err = system(mntcmd);
296315
if (err) {
297316
perror("Archivemount'ing the archive");
298317
rmdir(mntpath);
318+
close(sub_input_format.oldworkdir);
299319
return EXIT_FAILURE;
300320
}
301321
snprintf(umntcmd, sizeof(umntcmd), "umount -l %s", mntpath);
@@ -317,16 +337,18 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
317337

318338
if (!subdir) {
319339
perror("No subdirectory in archivemount directory");
340+
close(sub_input_format.oldworkdir);
320341
return EXIT_FAILURE;
321342
}
322343

323344
/* call ourself recursively on subdir, it should be either a fsroot or a cpuid directory */
324-
sub_input_format = HWLOC_UTILS_INPUT_DEFAULT;
325345
err = hwloc_utils_enable_input_format(topology, flags, subdir, &sub_input_format, verbose, callname);
326346
if (!err)
327-
*input_format = sub_input_format;
328-
else
347+
*input_formatp = sub_input_format;
348+
else {
349+
close(sub_input_format.oldworkdir);
329350
return err;
351+
}
330352
#else
331353
fprintf(stderr, "This installation of hwloc does not support loading from an archive, sorry.\n");
332354
exit(EXIT_FAILURE);
@@ -351,6 +373,28 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
351373
return 0;
352374
}
353375

376+
static __hwloc_inline void
377+
hwloc_utils_disable_input_format(struct hwloc_utils_input_format_s *input_format)
378+
{
379+
if (-1 < input_format->oldworkdir) {
380+
#ifdef HWLOC_LINUX_SYS
381+
#ifdef O_PATH
382+
int err = fchdir(input_format->oldworkdir);
383+
if (err) {
384+
perror("Restoring current working directory");
385+
}
386+
#else
387+
fprintf(stderr, "Couldn't restore working directory. Errors may arise.\n");
388+
#endif
389+
close(input_format->oldworkdir);
390+
input_format->oldworkdir = -1;
391+
#else
392+
fprintf(stderr, "oldworkdir should not have been changed. You should not have reached this execution branch.\n");
393+
exit(EXIT_FAILURE);
394+
#endif
395+
}
396+
}
397+
354398
static __hwloc_inline void
355399
hwloc_utils_print_distance_matrix(FILE *output, unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *matrix, int logical, int show_types)
356400
{

utils/lstopo/lstopo.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright © 2009-2012, 2015, 2017 Université Bordeaux
55
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
66
* Copyright © 2020 Hewlett Packard Enterprise. All rights reserved.
7+
* Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
78
* See COPYING in top-level directory.
89
*/
910

@@ -816,7 +817,7 @@ main (int argc, char *argv[])
816817
hwloc_bitmap_t allow_cpuset = NULL, allow_nodeset = NULL;
817818
char * callname;
818819
char * input = NULL;
819-
enum hwloc_utils_input_format input_format = HWLOC_UTILS_INPUT_DEFAULT;
820+
struct hwloc_utils_input_format_s input_format = HWLOC_UTILS_INPUT_FORMAT_DEFAULT;
820821
enum output_format output_format = LSTOPO_OUTPUT_DEFAULT;
821822
struct lstopo_type_filter type_filter[HWLOC_OBJ_TYPE_MAX];
822823
char *restrictstring = NULL;
@@ -1684,7 +1685,7 @@ main (int argc, char *argv[])
16841685
if (err)
16851686
goto out_with_topology;
16861687

1687-
if (input_format != HWLOC_UTILS_INPUT_DEFAULT) {
1688+
if (input_format.format != HWLOC_UTILS_INPUT_DEFAULT) {
16881689
/* add the input path to the window title */
16891690
snprintf(loutput.title, sizeof(loutput.title), "lstopo - %s", input);
16901691

@@ -1717,7 +1718,7 @@ main (int argc, char *argv[])
17171718
}
17181719
}
17191720

1720-
if (input_format == HWLOC_UTILS_INPUT_XML
1721+
if (input_format.format == HWLOC_UTILS_INPUT_XML
17211722
&& output_format == LSTOPO_OUTPUT_XML) {
17221723
/* must be after parsing output format and before loading the topology */
17231724
putenv((char *) "HWLOC_XML_USERDATA_NOT_DECODED=1");
@@ -1736,7 +1737,7 @@ main (int argc, char *argv[])
17361737
clock_gettime(CLOCK_MONOTONIC, &ts1);
17371738
#endif
17381739

1739-
if (input_format == HWLOC_UTILS_INPUT_SHMEM) {
1740+
if (input_format.format == HWLOC_UTILS_INPUT_SHMEM) {
17401741
#ifdef HWLOC_WIN_SYS
17411742
fprintf(stderr, "shmem topology not supported\n"); /* this line must match the grep line in test-lstopo-shmem */
17421743
goto out_with_topology;
@@ -1766,6 +1767,14 @@ main (int argc, char *argv[])
17661767
}
17671768
#endif
17681769

1770+
/********************************
1771+
* Clean input format's internal variables
1772+
*/
1773+
1774+
if (input) {
1775+
hwloc_utils_disable_input_format(&input_format);
1776+
}
1777+
17691778
/********************************
17701779
* Tweak the topology and output
17711780
*/
@@ -1880,6 +1889,7 @@ main (int argc, char *argv[])
18801889
lstopo_destroy_userdata(hwloc_get_root_obj(topology));
18811890
hwloc_topology_destroy(topology);
18821891
out:
1892+
if (input) hwloc_utils_disable_input_format(&input_format);
18831893
hwloc_bitmap_free(allow_cpuset);
18841894
hwloc_bitmap_free(allow_nodeset);
18851895
hwloc_bitmap_free(loutput.cpubind_set);

0 commit comments

Comments
 (0)