Skip to content

Commit c2f85dd

Browse files
committed
modules/content: simplify content.mmap-add RPC
Problem: the content.mmap-add RPC includes parameters that are no longer needed given its reduced role in supporting archives. Drop 'disable_mmap'. Drop 'small_file_threshold'. Drop 'fullpath' and drop the fullpath parameter from fileref_create_ex() Accept only one tag, not an array of them. Fail the mmap request if the path is not fully qualified or not a regular file. Change content.mmap-remove to only accept one tag also. Update flux-archive.
1 parent ccb601c commit c2f85dd

File tree

5 files changed

+50
-82
lines changed

5 files changed

+50
-82
lines changed

src/cmd/builtin/archive.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,25 @@ struct create_ctx {
7272
*/
7373
static void mmap_fileref_data (struct create_ctx *ctx, const char *path)
7474
{
75+
char *fullpath;
7576
flux_future_t *f;
76-
char *fpath;
7777

7878
// relative path is preserved in the archive, but broker needs full path
79-
if (!(fpath = realpath (path, NULL)))
79+
if (!(fullpath = realpath (path, NULL)))
8080
log_err_exit ("%s", path);
8181

8282
if (!(f = flux_rpc_pack (ctx->h,
8383
"content.mmap-add",
8484
0,
8585
0,
86-
"{s:s s:s s:b s:i s:i s:[s]}",
87-
"path", path,
88-
"fullpath", fpath,
89-
"disable_mmap", 0,
90-
"threshold", 0, // disable small file handling
86+
"{s:s s:i s:s}",
87+
"path", fullpath,
9188
"chunksize", ctx->param.chunksize,
92-
"tags", ctx->name))
89+
"tag", ctx->name))
9390
|| flux_rpc_get (f, NULL))
9491
log_msg_exit ("%s: %s", path, future_strerror (f, errno));
9592
flux_future_destroy (f);
96-
free (fpath);
93+
free (fullpath);
9794
}
9895

9996
/* Store the blobs of an RFC 37 blobvec-encoded fileref to the content store.
@@ -168,7 +165,6 @@ static void add_archive_file (struct create_ctx *ctx, const char *path)
168165
json_t *fileref;
169166

170167
if (!(fileref = fileref_create_ex (path,
171-
NULL,
172168
&ctx->param,
173169
&mapinfo,
174170
&error)))
@@ -394,8 +390,8 @@ static void unmap_archive (flux_t *h, const char *name)
394390
"content.mmap-remove",
395391
0,
396392
0,
397-
"{s:[s]}",
398-
"tags", name))
393+
"{s:s}",
394+
"tag", name))
399395
|| flux_rpc_get (f, NULL) < 0) {
400396
log_msg ("unmap %s: %s", name, future_strerror (f, errno));
401397
}

src/common/libfilemap/fileref.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,6 @@ static json_t *fileref_create_symlink (const char *path,
324324
}
325325

326326
json_t *fileref_create_ex (const char *path,
327-
const char *fullpath,
328327
struct blobvec_param *param,
329328
struct blobvec_mapinfo *mapinfop,
330329
flux_error_t *error)
@@ -344,8 +343,6 @@ json_t *fileref_create_ex (const char *path,
344343
goto inval;
345344
}
346345
}
347-
if (!fullpath)
348-
fullpath = path;
349346
/* Store a relative path in the object so that extraction can specify a
350347
* destination directory, like tar(1) default behavior.
351348
*/
@@ -359,8 +356,8 @@ json_t *fileref_create_ex (const char *path,
359356
* Avoid open(2) blocking on a FIFO with O_NONBLOCK, but restore blocking
360357
* behavior after open(2) succeeds.
361358
*/
362-
if ((fd = open (fullpath, O_RDONLY | O_NOFOLLOW | O_NONBLOCK)) < 0) {
363-
if (errno != ELOOP || lstat (fullpath, &sb) < 0) {
359+
if ((fd = open (path, O_RDONLY | O_NOFOLLOW | O_NONBLOCK)) < 0) {
360+
if (errno != ELOOP || lstat (path, &sb) < 0) {
364361
errprintf (error, "%s: %s", path, strerror (errno));
365362
goto error;
366363
}
@@ -419,7 +416,7 @@ json_t *fileref_create_ex (const char *path,
419416
/* symlink
420417
*/
421418
else if (S_ISLNK (sb.st_mode)) {
422-
if (!(o = fileref_create_symlink (relative_path, fullpath, &sb, error)))
419+
if (!(o = fileref_create_symlink (relative_path, path, &sb, error)))
423420
goto error;
424421
}
425422
/* directory
@@ -454,7 +451,7 @@ json_t *fileref_create_ex (const char *path,
454451

455452
json_t *fileref_create (const char *path, flux_error_t *error)
456453
{
457-
return fileref_create_ex (path, NULL, NULL, NULL, error);
454+
return fileref_create_ex (path, NULL, NULL, error);
458455
}
459456

460457
void fileref_pretty_print (json_t *fileref,

src/common/libfilemap/fileref.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,13 @@ struct blobvec_mapinfo {
3030

3131

3232
/* Variant of fileref_create() with extra parameters to allow for 'blobvec'
33-
* encoding. This is intended to be called from the broker.
34-
* - If non-NULL 'fullpath' is used in place of 'path' for open/stat/mmap.
33+
* encoding.
3534
* - If 'param' is non-NULL, blobvec encoding is enabled with the specified
3635
* params.
3736
* - If 'mapinfo' is non-NULL, and the file meets conditions for blobvec
3837
* encoding, the file remains mapped in memory and its address is returned.
3938
*/
4039
json_t *fileref_create_ex (const char *path,
41-
const char *fullpath,
4240
struct blobvec_param *param,
4341
struct blobvec_mapinfo *mapinfo,
4442
flux_error_t *error);

src/common/libfilemap/test/fileref.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static json_t *xfileref_create_vec (const char *path,
4545
.small_file_threshold = 4096,
4646
};
4747

48-
o = fileref_create_ex (path, NULL, &blobvec_param, NULL, &error);
48+
o = fileref_create_ex (path, &blobvec_param, NULL, &error);
4949
if (!o)
5050
diag ("%s", error.text);
5151
return o;
@@ -650,7 +650,7 @@ void test_expfail (void)
650650
param.chunksize = 1024;
651651
param.hashtype = "smurfette";
652652
param.small_file_threshold = 0;
653-
o = fileref_create_ex (mkpath ("test"), NULL, &param, NULL, &error);
653+
o = fileref_create_ex (mkpath ("test"), &param, NULL, &error);
654654
if (!o)
655655
diag ("%s", error.text);
656656
ok (o == NULL && errno == EINVAL,
@@ -660,7 +660,7 @@ void test_expfail (void)
660660
param.chunksize = -1;
661661
param.hashtype = "sha1";
662662
param.small_file_threshold = 0;
663-
o = fileref_create_ex (mkpath ("test"), NULL, &param, NULL, &error);
663+
o = fileref_create_ex (mkpath ("test"), &param, NULL, &error);
664664
if (!o)
665665
diag ("%s", error.text);
666666
ok (o == NULL && errno == EINVAL,
@@ -670,7 +670,7 @@ void test_expfail (void)
670670
param.chunksize = 1024;
671671
param.hashtype = "sha1";
672672
param.small_file_threshold = -1;
673-
o = fileref_create_ex (mkpath ("test"), NULL, &param, NULL, &error);
673+
o = fileref_create_ex (mkpath ("test"), &param, NULL, &error);
674674
if (!o)
675675
diag ("%s", error.text);
676676
ok (o == NULL && errno == EINVAL,

src/modules/content/mmap.c

Lines changed: 33 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,14 @@ struct content_region *content_mmap_region_lookup (struct content_mmap *mm,
380380
static struct content_region *content_mmap_region_create (
381381
struct content_mmap *mm,
382382
const char *path,
383-
const char *fpath,
384-
struct blobvec_param *param,
383+
int chunksize,
385384
flux_error_t *error)
386385
{
386+
struct blobvec_param param = {
387+
.hashtype = mm->hash_name,
388+
.chunksize = chunksize,
389+
.small_file_threshold = 0, // always choose blobvec encoding here
390+
};
387391
struct content_region *reg;
388392

389393
if (!(reg = calloc (1, sizeof (*reg)))) {
@@ -393,15 +397,22 @@ static struct content_region *content_mmap_region_create (
393397
reg->refcount = 1;
394398
reg->mm = mm;
395399
reg->mapinfo.base = MAP_FAILED;
396-
if (!(reg->fullpath = strdup (fpath)))
400+
if (!(reg->fullpath = strdup (path)))
397401
goto error;
398402

399403
if (!(reg->fileref = fileref_create_ex (path,
400-
fpath,
401-
param,
404+
&param,
402405
&reg->mapinfo,
403406
error)))
404407
goto error;
408+
/* fileref_create_ex() accepts all file types, but flux-archive(1) should
409+
* not be requesting that files be mapped which do not meet criteria.
410+
*/
411+
if (reg->mapinfo.base == MAP_FAILED) {
412+
errprintf (error, "%s: not suitable for mapping", path);
413+
errno = EINVAL;
414+
goto error;
415+
}
405416
if (region_cache_add (reg) < 0) {
406417
errprintf (error,
407418
"%s: error caching region blobrefs: %s",
@@ -415,70 +426,41 @@ static struct content_region *content_mmap_region_create (
415426
return NULL;
416427
}
417428

418-
static int check_string_array (json_t *o, int min_count)
419-
{
420-
size_t index;
421-
json_t *entry;
422-
423-
if (!json_is_array (o)
424-
|| json_array_size (o) < min_count)
425-
goto error;
426-
json_array_foreach (o, index, entry) {
427-
if (!json_is_string (entry))
428-
goto error;
429-
}
430-
return 0;
431-
error:
432-
errno = EPROTO;
433-
return -1;
434-
}
435-
436429
static void content_mmap_add_cb (flux_t *h,
437430
flux_msg_handler_t *mh,
438431
const flux_msg_t *msg,
439432
void *arg)
440433
{
441434
struct content_mmap *mm = arg;
442435
const char *path;
443-
const char *fpath = NULL;
444-
int disable_mmap;
445-
struct blobvec_param param;
446-
json_t *tags;
436+
int chunksize;
437+
const char *tag;
447438
struct content_region *reg = NULL;
448439
flux_error_t error;
449440
const char *errmsg = NULL;
450-
size_t index;
451-
json_t *entry;
452441

453442
if (flux_request_unpack (msg,
454443
NULL,
455-
"{s:s s?s s:b s:i s:i s:o}",
444+
"{s:s s:i s:s}",
456445
"path", &path,
457-
"fullpath", &fpath,
458-
"disable_mmap", &disable_mmap,
459-
"chunksize", &param.chunksize,
460-
"threshold", &param.small_file_threshold,
461-
"tags", &tags) < 0
462-
|| check_string_array (tags, 1) < 0)
446+
"chunksize", &chunksize,
447+
"tag", &tag) < 0)
463448
goto error;
464449
if (mm->rank != 0) {
465450
errmsg = "content may only be mmapped on rank 0";
466451
goto inval;
467452
}
468-
param.hashtype = mm->hash_name;
469-
if (!(reg = content_mmap_region_create (mm,
470-
path,
471-
fpath,
472-
disable_mmap ? NULL : &param,
473-
&error))) {
453+
if (path[0] != '/') {
454+
errmsg = "path must be fully qualified";
455+
goto inval;
456+
}
457+
if (!(reg = content_mmap_region_create (mm, path, chunksize, &error))) {
474458
errmsg = error.text;
475459
goto error;
476460
}
477-
json_array_foreach (tags, index, entry) {
478-
// takes a reference on region
479-
if (!hola_list_add_end (mm->tags, json_string_value (entry), reg))
480-
goto error;
481-
}
461+
// takes a reference on region
462+
if (!hola_list_add_end (mm->tags, tag, reg))
463+
goto error;
482464
if (flux_respond (h, msg, NULL) < 0)
483465
flux_log_error (h, "error responding to content.mmap-add request");
484466
content_mmap_region_decref (reg);
@@ -498,22 +480,17 @@ static void content_mmap_remove_cb (flux_t *h,
498480
{
499481
struct content_mmap *mm = arg;
500482
const char *errmsg = NULL;
501-
json_t *tags;
502-
size_t index;
503-
json_t *entry;
483+
const char *tag;
504484
int unmap_count = 0;
505485

506-
if (flux_request_unpack (msg, NULL, "{s:o}", "tags", &tags) < 0
507-
|| check_string_array (tags, 1) < 0)
486+
if (flux_request_unpack (msg, NULL, "{s:s}", "tag", &tag) < 0)
508487
goto error;
509488
if (mm->rank != 0) {
510489
errmsg = "content can only be mmapped on rank 0";
511490
goto inval;
512491
}
513-
json_array_foreach (tags, index, entry) {
514-
if (hola_hash_delete (mm->tags, json_string_value (entry)) == 0)
515-
unmap_count++;
516-
}
492+
if (hola_hash_delete (mm->tags, tag) == 0)
493+
unmap_count++;
517494
if (unmap_count > 0) {
518495
if (plug_cache_holes (mm) < 0) {
519496
errmsg = "error filling missing cache entries after unmap";

0 commit comments

Comments
 (0)