3
3
* Copyright © 2009-2023 Inria. All rights reserved.
4
4
* Copyright © 2009-2012 Université Bordeaux
5
5
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6
+ * Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
6
7
* See COPYING in top-level directory.
7
8
*/
8
9
26
27
#ifdef HAVE_DIRENT_H
27
28
#include <dirent.h>
28
29
#endif
30
+ #include <fcntl.h>
29
31
#include <assert.h>
30
32
31
33
extern void usage (const char * name , FILE * where );
@@ -80,15 +82,19 @@ hwloc_utils_input_format_usage(FILE *where, int addspaces)
80
82
addspaces , " " );
81
83
}
82
84
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 ;
91
96
};
97
+ #define HWLOC_UTILS_INPUT_FORMAT_DEFAULT (struct hwloc_utils_input_format_s) { HWLOC_UTILS_INPUT_DEFAULT, -1 }
92
98
93
99
static __hwloc_inline enum hwloc_utils_input_format
94
100
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)
115
121
116
122
static __hwloc_inline int
117
123
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 ,
119
125
const char * callname )
120
126
{
121
127
if (!strcmp (argv [0 ], "--input" )
@@ -137,7 +143,8 @@ hwloc_utils_lookup_input_option(char *argv[], int argc, int *consumed_opts,
137
143
usage (callname , stderr );
138
144
exit (EXIT_FAILURE );
139
145
}
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 );
141
148
* consumed_opts = 1 ;
142
149
return 1 ;
143
150
}
@@ -202,9 +209,10 @@ hwloc_utils_autodetect_input_format(const char *input, int verbose)
202
209
static __hwloc_inline int
203
210
hwloc_utils_enable_input_format (struct hwloc_topology * topology , unsigned long flags ,
204
211
const char * input ,
205
- enum hwloc_utils_input_format * input_format ,
212
+ struct hwloc_utils_input_format_s * input_formatp ,
206
213
int verbose , const char * callname )
207
214
{
215
+ enum hwloc_utils_input_format * input_format = & input_formatp -> format ;
208
216
if (* input_format == HWLOC_UTILS_INPUT_DEFAULT && !strcmp (input , "-.xml" )) {
209
217
* input_format = HWLOC_UTILS_INPUT_XML ;
210
218
input = "-" ;
@@ -283,19 +291,31 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
283
291
char umntcmd [512 ];
284
292
DIR * dir ;
285
293
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 ;
287
296
char * subdir = NULL ;
288
297
int err ;
289
298
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
290
308
if (!mkdtemp (mntpath )) {
291
309
perror ("Creating archivemount directory" );
310
+ close (sub_input_format .oldworkdir );
292
311
return EXIT_FAILURE ;
293
312
}
294
313
snprintf (mntcmd , sizeof (mntcmd ), "archivemount -o ro %s %s" , input , mntpath );
295
314
err = system (mntcmd );
296
315
if (err ) {
297
316
perror ("Archivemount'ing the archive" );
298
317
rmdir (mntpath );
318
+ close (sub_input_format .oldworkdir );
299
319
return EXIT_FAILURE ;
300
320
}
301
321
snprintf (umntcmd , sizeof (umntcmd ), "umount -l %s" , mntpath );
@@ -317,16 +337,18 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
317
337
318
338
if (!subdir ) {
319
339
perror ("No subdirectory in archivemount directory" );
340
+ close (sub_input_format .oldworkdir );
320
341
return EXIT_FAILURE ;
321
342
}
322
343
323
344
/* call ourself recursively on subdir, it should be either a fsroot or a cpuid directory */
324
- sub_input_format = HWLOC_UTILS_INPUT_DEFAULT ;
325
345
err = hwloc_utils_enable_input_format (topology , flags , subdir , & sub_input_format , verbose , callname );
326
346
if (!err )
327
- * input_format = sub_input_format ;
328
- else
347
+ * input_formatp = sub_input_format ;
348
+ else {
349
+ close (sub_input_format .oldworkdir );
329
350
return err ;
351
+ }
330
352
#else
331
353
fprintf (stderr , "This installation of hwloc does not support loading from an archive, sorry.\n" );
332
354
exit (EXIT_FAILURE );
@@ -351,6 +373,28 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
351
373
return 0 ;
352
374
}
353
375
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
+
354
398
static __hwloc_inline void
355
399
hwloc_utils_print_distance_matrix (FILE * output , unsigned nbobjs , hwloc_obj_t * objs , hwloc_uint64_t * matrix , int logical , int show_types )
356
400
{
0 commit comments