4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
24 * Copyright 2014, 2015 Cray Inc, all rights reserved.
26 * Copyright (c) 2015, Intel Corporation.
28 /* Some portions are extracted from llapi_layout_test.c */
30 /* The purpose of this test is to check some HSM functions. HSM must
31 * be enabled before running it:
32 * lctl set_param mdt.$FSNAME-MDT0000.hsm_control=enabled
35 /* All tests return 0 on success and non zero on error. The program will
36 * exit as soon a non zero error is returned. */
46 #include <lustre/lustreapi.h>
48 static char fsmountdir[PATH_MAX]; /* Lustre mountpoint */
49 static char *lustre_dir; /* Test directory inside Lustre */
51 #define ERROR(fmt, ...) \
52 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
53 program_invocation_short_name, __FILE__, __LINE__, \
54 __func__, ## __VA_ARGS__);
56 #define DIE(fmt, ...) \
58 ERROR(fmt, ## __VA_ARGS__); \
62 #define ASSERTF(cond, fmt, ...) \
65 DIE("assertion '%s' failed: "fmt, \
66 #cond, ## __VA_ARGS__); \
69 #define PERFORM(testfn) \
71 fprintf(stderr, "Starting test " #testfn " at %llu\n", \
72 (unsigned long long)time(NULL)); \
74 fprintf(stderr, "Finishing test " #testfn " at %llu\n", \
75 (unsigned long long)time(NULL)); \
78 /* Register and unregister 2000 times. Ensures there is no fd leak
79 * since there is usually 1024 fd per process. */
84 struct hsm_copytool_private *ctdata;
86 for (i = 0; i < 2000; i++) {
87 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
90 "llapi_hsm_copytool_register failed: %s, loop=%d",
93 rc = llapi_hsm_copytool_unregister(&ctdata);
95 "llapi_hsm_copytool_unregister failed: %s, loop=%d",
106 struct hsm_copytool_private *ctdata1;
107 struct hsm_copytool_private *ctdata2;
109 rc = llapi_hsm_copytool_register(&ctdata1, fsmountdir, 0, NULL, 0);
110 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
113 rc = llapi_hsm_copytool_register(&ctdata2, fsmountdir, 0, NULL, 0);
114 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
117 rc = llapi_hsm_copytool_unregister(&ctdata2);
118 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
121 rc = llapi_hsm_copytool_unregister(&ctdata1);
122 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
128 /* Bad parameters to llapi_hsm_copytool_register(). */
132 struct hsm_copytool_private *ctdata;
135 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 1, NULL, 0);
136 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
139 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 33, NULL, 0);
140 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
143 memset(archives, 1, sizeof(archives));
144 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 34, archives, 0);
145 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
149 /* BUG? Should that fail or not? */
150 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, -1, NULL, 0);
151 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
155 memset(archives, -1, sizeof(archives));
156 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 1, archives, 0);
157 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
160 rc = llapi_hsm_copytool_register(&ctdata, "/tmp", 0, NULL, 0);
161 ASSERTF(rc == -ENOENT, "llapi_hsm_copytool_register error: %s",
167 /* Bad parameters to llapi_hsm_copytool_unregister(). */
172 rc = llapi_hsm_copytool_unregister(NULL);
173 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_unregister error: %s",
179 /* Test llapi_hsm_copytool_recv in non blocking mode */
184 struct hsm_copytool_private *ctdata;
185 struct hsm_action_list *hal;
188 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
189 0, NULL, O_NONBLOCK);
190 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
193 /* Hopefully there is nothing lingering */
194 for (i = 0; i < 1000; i++) {
195 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
196 ASSERTF(rc == -EWOULDBLOCK, "llapi_hsm_copytool_recv error: %s",
200 rc = llapi_hsm_copytool_unregister(&ctdata);
201 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
207 /* Test llapi_hsm_copytool_recv with bogus parameters */
210 struct hsm_copytool_private *ctdata;
211 struct hsm_action_list *hal;
215 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 0, NULL, 0);
216 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
219 rc = llapi_hsm_copytool_recv(NULL, &hal, &msgsize);
220 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
223 rc = llapi_hsm_copytool_recv(ctdata, NULL, &msgsize);
224 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
227 rc = llapi_hsm_copytool_recv(ctdata, &hal, NULL);
228 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
231 rc = llapi_hsm_copytool_recv(ctdata, NULL, NULL);
232 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
235 rc = llapi_hsm_copytool_unregister(&ctdata);
236 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
242 /* Test polling (without actual traffic) */
246 struct hsm_copytool_private *ctdata;
247 struct hsm_action_list *hal;
250 struct pollfd fds[1];
252 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
253 0, NULL, O_NONBLOCK);
254 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
257 fd = llapi_hsm_copytool_get_fd(ctdata);
258 ASSERTF(fd >= 0, "llapi_hsm_copytool_get_fd failed: %s",
261 /* Ensure it's read-only */
262 rc = write(fd, &rc, 1);
263 ASSERTF(rc == -1 && errno == EBADF, "write error: %d, %s",
264 rc, strerror(errno));
266 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
267 ASSERTF(rc == -EWOULDBLOCK, "llapi_hsm_copytool_recv error: %s",
271 fds[0].events = POLLIN;
272 rc = poll(fds, 1, 10);
273 ASSERTF(rc == 0, "poll failed: %d, %s",
274 rc, strerror(errno)); /* no event */
276 rc = llapi_hsm_copytool_unregister(&ctdata);
277 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
283 /* Create the testfile of a given length. It returns a valid file
285 static char testfile[PATH_MAX];
286 static int create_testfile(size_t length)
291 rc = snprintf(testfile, sizeof(testfile), "%s/hsm_check_test",
293 ASSERTF((rc > 0 && rc < sizeof(testfile)), "invalid name for testfile");
295 /* Remove old test file, if any. */
298 /* Use truncate so we can create a file (almost) as big as we
299 * want, while taking 0 bytes of data. */
300 fd = creat(testfile, S_IRWXU);
301 ASSERTF(fd >= 0, "create failed for '%s': %s",
302 testfile, strerror(errno));
304 rc = ftruncate(fd, length);
305 ASSERTF(rc == 0, "ftruncate failed for '%s': %s",
306 testfile, strerror(errno));
311 /* Test llapi_hsm_state_get. */
314 struct hsm_user_state hus;
318 fd = create_testfile(100);
320 /* With fd variant */
321 rc = llapi_hsm_state_get_fd(fd, &hus);
322 ASSERTF(rc == 0, "llapi_hsm_state_get_fd failed: %s", strerror(-rc));
323 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
325 rc = llapi_hsm_state_get_fd(fd, NULL);
326 ASSERTF(rc == -EFAULT, "llapi_hsm_state_get_fd error: %s",
330 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
333 rc = llapi_hsm_state_get(testfile, &hus);
334 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
335 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
337 rc = llapi_hsm_state_get(testfile, NULL);
338 ASSERTF(rc == -EFAULT, "llapi_hsm_state_get error: %s",
341 memset(&hus, 0xaa, sizeof(hus));
342 rc = llapi_hsm_state_get(testfile, &hus);
343 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
344 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
345 ASSERTF(hus.hus_archive_id == 0, "archive_id=%u", hus.hus_archive_id);
346 ASSERTF(hus.hus_in_progress_state == 0, "hus_in_progress_state=%u",
347 hus.hus_in_progress_state);
348 ASSERTF(hus.hus_in_progress_action == 0, "hus_in_progress_action=%u",
349 hus.hus_in_progress_action);
352 /* Test llapi_hsm_state_set. */
358 struct hsm_user_state hus;
360 fd = create_testfile(100);
362 rc = llapi_hsm_state_set_fd(fd, 0, 0, 0);
363 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
366 for (i = 0; i <= 32; i++) {
367 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, i);
368 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s",
371 rc = llapi_hsm_state_get_fd(fd, &hus);
372 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s",
374 ASSERTF(hus.hus_states == HS_EXISTS, "state=%u",
376 ASSERTF(hus.hus_archive_id == i, "archive_id=%u, i=%d",
377 hus.hus_archive_id, i);
380 /* Invalid archive numbers */
381 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, 33);
382 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
384 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, 151);
385 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
387 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, -1789);
388 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
390 /* Settable flags, with respect of the HSM file state transition rules:
391 * DIRTY without EXISTS: no dirty if no archive was created
392 * DIRTY and RELEASED: a dirty file could not be released
393 * RELEASED without ARCHIVED: do not release a non-archived file
394 * LOST without ARCHIVED: cannot lost a non-archived file.
396 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY, 0, 0);
397 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
399 rc = llapi_hsm_state_set_fd(fd, 0, HS_EXISTS, 0);
400 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
403 rc = llapi_hsm_state_set_fd(fd, 0, HS_DIRTY, 0);
404 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
406 rc = llapi_hsm_state_set_fd(fd, 0, HS_EXISTS, 0);
407 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
409 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY, 0, 0);
410 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
413 rc = llapi_hsm_state_set_fd(fd, HS_RELEASED, 0, 0);
414 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
417 rc = llapi_hsm_state_set_fd(fd, HS_LOST, 0, 0);
418 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
421 rc = llapi_hsm_state_set_fd(fd, HS_ARCHIVED, 0, 0);
422 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
424 rc = llapi_hsm_state_set_fd(fd, HS_RELEASED, 0, 0);
425 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
427 rc = llapi_hsm_state_set_fd(fd, HS_LOST, 0, 0);
428 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
430 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY|HS_EXISTS, 0, 0);
431 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
434 rc = llapi_hsm_state_set_fd(fd, 0, HS_RELEASED, 0);
435 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
437 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY|HS_EXISTS, 0, 0);
438 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
440 rc = llapi_hsm_state_set_fd(fd, 0, HS_ARCHIVED, 0);
441 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
444 rc = llapi_hsm_state_set_fd(fd, 0, HS_LOST, 0);
445 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
447 rc = llapi_hsm_state_set_fd(fd, 0, HS_ARCHIVED, 0);
448 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
450 rc = llapi_hsm_state_set_fd(fd, HS_NORELEASE, 0, 0);
451 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
453 rc = llapi_hsm_state_set_fd(fd, 0, HS_NORELEASE, 0);
454 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
456 rc = llapi_hsm_state_set_fd(fd, HS_NOARCHIVE, 0, 0);
457 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
459 rc = llapi_hsm_state_set_fd(fd, 0, HS_NOARCHIVE, 0);
460 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
462 /* Bogus flags for good measure. */
463 rc = llapi_hsm_state_set_fd(fd, 0x00080000, 0, 0);
464 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
466 rc = llapi_hsm_state_set_fd(fd, 0x80000000, 0, 0);
467 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
472 /* Test llapi_hsm_current_action */
477 struct hsm_current_action hca;
479 /* No fd equivalent, so close it. */
480 fd = create_testfile(100);
483 rc = llapi_hsm_current_action(testfile, &hca);
484 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s", strerror(-rc));
485 ASSERTF(hca.hca_state, "hca_state=%u", hca.hca_state);
486 ASSERTF(hca.hca_action, "hca_state=%u", hca.hca_action);
488 rc = llapi_hsm_current_action(testfile, NULL);
489 ASSERTF(rc == -EFAULT, "llapi_hsm_current_action failed: %s",
493 /* Helper to simulate archiving a file. No actual data movement
495 void helper_archiving(void (*progress)
496 (struct hsm_copyaction_private *hcp, size_t length),
501 struct hsm_copytool_private *ctdata;
502 struct hsm_user_request *hur;
503 struct hsm_action_list *hal;
504 struct hsm_action_item *hai;
506 struct hsm_copyaction_private *hcp;
507 struct hsm_user_state hus;
509 fd = create_testfile(length);
511 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
513 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
516 /* Create and send the archive request. */
517 hur = llapi_hsm_user_request_alloc(1, 0);
518 ASSERTF(hur != NULL, "llapi_hsm_user_request_alloc returned NULL");
520 hur->hur_request.hr_action = HUA_ARCHIVE;
521 hur->hur_request.hr_archive_id = 1;
522 hur->hur_request.hr_flags = 0;
523 hur->hur_request.hr_itemcount = 1;
524 hur->hur_request.hr_data_len = 0;
525 hur->hur_user_item[0].hui_extent.offset = 0;
526 hur->hur_user_item[0].hui_extent.length = -1;
528 rc = llapi_fd2fid(fd, &hur->hur_user_item[0].hui_fid);
529 ASSERTF(rc == 0, "llapi_fd2fid failed: %s", strerror(-rc));
533 rc = llapi_hsm_request(testfile, hur);
534 ASSERTF(rc == 0, "llapi_hsm_request failed: %s", strerror(-rc));
538 /* Read the request */
539 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
540 ASSERTF(rc == 0, "llapi_hsm_copytool_recv failed: %s", strerror(-rc));
541 ASSERTF(hal->hal_count == 1, "hal_count=%d", hal->hal_count);
543 hai = hai_first(hal);
544 ASSERTF(hai != NULL, "hai_first returned NULL");
545 ASSERTF(hai->hai_action == HSMA_ARCHIVE,
546 "hai_action=%d", hai->hai_action);
548 /* "Begin" archiving */
550 rc = llapi_hsm_action_begin(&hcp, ctdata, hai, -1, 0, false);
551 ASSERTF(rc == 0, "llapi_hsm_action_begin failed: %s", strerror(-rc));
552 ASSERTF(hcp != NULL, "hcp is NULL");
555 progress(hcp, length);
558 rc = llapi_hsm_action_end(&hcp, &hai->hai_extent, 0, 0);
559 ASSERTF(rc == 0, "llapi_hsm_action_end failed: %s", strerror(-rc));
560 ASSERTF(hcp == NULL, "hcp is NULL");
562 /* Close HSM client */
563 rc = llapi_hsm_copytool_unregister(&ctdata);
564 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
568 rc = llapi_hsm_state_get(testfile, &hus);
569 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
570 ASSERTF(hus.hus_states == (HS_EXISTS | HS_ARCHIVED),
571 "state=%u", hus.hus_states);
574 /* Simple archive. No progress. */
577 const size_t length = 100;
579 helper_archiving(NULL, length);
582 /* Archive, with a report every byte. */
583 static void test101_progress(struct hsm_copyaction_private *hcp, size_t length)
587 struct hsm_extent he;
588 struct hsm_current_action hca;
590 /* Report progress. 1 byte at a time :) */
591 for (i = 0; i < length; i++) {
594 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
595 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
599 rc = llapi_hsm_current_action(testfile, &hca);
600 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
602 ASSERTF(hca.hca_state == HPS_RUNNING,
603 "hca_state=%u", hca.hca_state);
604 ASSERTF(hca.hca_action == HUA_ARCHIVE,
605 "hca_state=%u", hca.hca_action);
606 ASSERTF(hca.hca_location.length == length,
607 "length=%llu", (unsigned long long)hca.hca_location.length);
612 const size_t length = 1000;
614 helper_archiving(test101_progress, length);
617 /* Archive, with a report every byte, backwards. */
618 static void test102_progress(struct hsm_copyaction_private *hcp, size_t length)
622 struct hsm_extent he;
623 struct hsm_current_action hca;
625 /* Report progress. 1 byte at a time :) */
626 for (i = length-1; i >= 0; i--) {
629 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
630 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
634 rc = llapi_hsm_current_action(testfile, &hca);
635 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
637 ASSERTF(hca.hca_state == HPS_RUNNING,
638 "hca_state=%u", hca.hca_state);
639 ASSERTF(hca.hca_action == HUA_ARCHIVE,
640 "hca_state=%u", hca.hca_action);
641 ASSERTF(hca.hca_location.length == length,
642 "length=%llu", (unsigned long long)hca.hca_location.length);
647 const size_t length = 1000;
649 helper_archiving(test102_progress, length);
652 /* Archive, with a single report. */
653 static void test103_progress(struct hsm_copyaction_private *hcp, size_t length)
656 struct hsm_extent he;
657 struct hsm_current_action hca;
661 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
662 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
665 rc = llapi_hsm_current_action(testfile, &hca);
666 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
668 ASSERTF(hca.hca_state == HPS_RUNNING,
669 "hca_state=%u", hca.hca_state);
670 ASSERTF(hca.hca_action == HUA_ARCHIVE,
671 "hca_state=%u", hca.hca_action);
672 ASSERTF(hca.hca_location.length == length,
673 "length=%llu", (unsigned long long)hca.hca_location.length);
678 const size_t length = 1000;
680 helper_archiving(test103_progress, length);
683 /* Archive, with 2 reports. */
684 static void test104_progress(struct hsm_copyaction_private *hcp, size_t length)
687 struct hsm_extent he;
688 struct hsm_current_action hca;
691 he.length = length/2;
692 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
693 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
696 he.offset = length/2;
697 he.length = length/2;
698 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
699 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
702 rc = llapi_hsm_current_action(testfile, &hca);
703 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
705 ASSERTF(hca.hca_state == HPS_RUNNING,
706 "hca_state=%u", hca.hca_state);
707 ASSERTF(hca.hca_action == HUA_ARCHIVE,
708 "hca_state=%u", hca.hca_action);
709 ASSERTF(hca.hca_location.length == length,
710 "length=%llu", (unsigned long long)hca.hca_location.length);
715 const size_t length = 1000;
717 helper_archiving(test104_progress, length);
720 /* Archive, with 1 bogus report. */
721 static void test105_progress(struct hsm_copyaction_private *hcp, size_t length)
724 struct hsm_extent he;
725 struct hsm_current_action hca;
727 he.offset = 2*length;
728 he.length = 10*length;
729 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
730 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
733 rc = llapi_hsm_current_action(testfile, &hca);
734 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
736 ASSERTF(hca.hca_state == HPS_RUNNING,
737 "hca_state=%u", hca.hca_state);
738 ASSERTF(hca.hca_action == HUA_ARCHIVE,
739 "hca_state=%u", hca.hca_action);
741 /* BUG - offset should be 2*length, or length should
743 ASSERTF(hca.hca_location.length == 10*length,
744 "length=%llu", (unsigned long long)hca.hca_location.length);
749 const size_t length = 1000;
751 helper_archiving(test105_progress, length);
754 /* Archive, with 1 empty report. */
755 static void test106_progress(struct hsm_copyaction_private *hcp, size_t length)
758 struct hsm_extent he;
759 struct hsm_current_action hca;
763 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
764 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
767 rc = llapi_hsm_current_action(testfile, &hca);
768 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
770 ASSERTF(hca.hca_state == HPS_RUNNING,
771 "hca_state=%u", hca.hca_state);
772 ASSERTF(hca.hca_action == HUA_ARCHIVE,
773 "hca_state=%u", hca.hca_action);
774 ASSERTF(hca.hca_location.length == 0,
775 "length=%llu", (unsigned long long)hca.hca_location.length);
780 const size_t length = 1000;
782 helper_archiving(test106_progress, length);
785 /* Archive, with 1 bogus report. */
786 static void test107_progress(struct hsm_copyaction_private *hcp, size_t length)
789 struct hsm_extent he;
790 struct hsm_current_action hca;
794 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
795 ASSERTF(rc == -EINVAL, "llapi_hsm_action_progress error: %s",
798 rc = llapi_hsm_current_action(testfile, &hca);
799 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
801 ASSERTF(hca.hca_state == HPS_RUNNING,
802 "hca_state=%u", hca.hca_state);
803 ASSERTF(hca.hca_action == HUA_ARCHIVE,
804 "hca_state=%u", hca.hca_action);
805 ASSERTF(hca.hca_location.length == 0,
806 "length=%llu", (unsigned long long)hca.hca_location.length);
811 const size_t length = 1000;
813 helper_archiving(test107_progress, length);
816 /* Archive, with same report, many times. */
817 static void test108_progress(struct hsm_copyaction_private *hcp, size_t length)
820 struct hsm_extent he;
822 struct hsm_current_action hca;
824 for (i = 0; i < 1000; i++) {
827 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
828 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
832 rc = llapi_hsm_current_action(testfile, &hca);
833 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
835 ASSERTF(hca.hca_state == HPS_RUNNING,
836 "hca_state=%u", hca.hca_state);
837 ASSERTF(hca.hca_action == HUA_ARCHIVE,
838 "hca_state=%u", hca.hca_action);
839 ASSERTF(hca.hca_location.length == length,
840 "length=%llu", (unsigned long long)hca.hca_location.length);
845 const size_t length = 1000;
847 helper_archiving(test108_progress, length);
850 /* Archive, 1 report, with large number. */
851 static void test109_progress(struct hsm_copyaction_private *hcp, size_t length)
854 struct hsm_extent he;
855 struct hsm_current_action hca;
858 he.length = 0xffffffffffffffffULL;
859 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
860 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
863 rc = llapi_hsm_current_action(testfile, &hca);
864 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
866 ASSERTF(hca.hca_state == HPS_RUNNING,
867 "hca_state=%u", hca.hca_state);
868 ASSERTF(hca.hca_action == HUA_ARCHIVE,
869 "hca_state=%u", hca.hca_action);
870 ASSERTF(hca.hca_location.length == 0xffffffffffffffffULL,
871 "length=%llu", (unsigned long long)hca.hca_location.length);
876 const size_t length = 1000;
878 helper_archiving(test109_progress, length);
881 /* Archive, with 10 reports, checking progress. */
882 static void test110_progress(struct hsm_copyaction_private *hcp, size_t length)
886 struct hsm_extent he;
887 struct hsm_current_action hca;
889 for (i = 0; i < 10; i++) {
890 he.offset = i*length/10;
891 he.length = length/10;
892 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
893 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
896 rc = llapi_hsm_current_action(testfile, &hca);
897 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
899 ASSERTF(hca.hca_state == HPS_RUNNING,
900 "hca_state=%u", hca.hca_state);
901 ASSERTF(hca.hca_action == HUA_ARCHIVE,
902 "hca_state=%u", hca.hca_action);
903 ASSERTF(hca.hca_location.length == (i+1)*length/10,
905 i, (unsigned long long)hca.hca_location.length);
911 const size_t length = 1000;
913 helper_archiving(test110_progress, length);
916 /* Archive, with 10 reports in reverse order, checking progress. */
917 static void test111_progress(struct hsm_copyaction_private *hcp, size_t length)
921 struct hsm_extent he;
922 struct hsm_current_action hca;
924 for (i = 0; i < 10; i++) {
925 he.offset = (9-i)*length/10;
926 he.length = length/10;
927 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
928 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
931 rc = llapi_hsm_current_action(testfile, &hca);
932 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
934 ASSERTF(hca.hca_state == HPS_RUNNING,
935 "hca_state=%u", hca.hca_state);
936 ASSERTF(hca.hca_action == HUA_ARCHIVE,
937 "hca_state=%u", hca.hca_action);
938 ASSERTF(hca.hca_location.length == (i+1)*length/10,
940 i, (unsigned long long)hca.hca_location.length);
946 const size_t length = 1000;
948 helper_archiving(test111_progress, length);
951 /* Archive, with 10 reports, and duplicating them, checking
953 static void test112_progress(struct hsm_copyaction_private *hcp, size_t length)
957 struct hsm_extent he;
958 struct hsm_current_action hca;
960 for (i = 0; i < 10; i++) {
961 he.offset = i*length/10;
962 he.length = length/10;
963 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
964 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
967 rc = llapi_hsm_current_action(testfile, &hca);
968 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
970 ASSERTF(hca.hca_state == HPS_RUNNING,
971 "hca_state=%u", hca.hca_state);
972 ASSERTF(hca.hca_action == HUA_ARCHIVE,
973 "hca_state=%u", hca.hca_action);
974 ASSERTF(hca.hca_location.length == (i+1)*length/10,
976 i, (unsigned long long)hca.hca_location.length);
979 for (i = 0; i < 10; i++) {
980 he.offset = i*length/10;
981 he.length = length/10;
982 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
983 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
986 rc = llapi_hsm_current_action(testfile, &hca);
987 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
989 ASSERTF(hca.hca_state == HPS_RUNNING,
990 "hca_state=%u", hca.hca_state);
991 ASSERTF(hca.hca_action == HUA_ARCHIVE,
992 "hca_state=%u", hca.hca_action);
993 ASSERTF(hca.hca_location.length == length,
995 i, (unsigned long long)hca.hca_location.length);
1001 const size_t length = 1000;
1003 helper_archiving(test112_progress, length);
1006 static void usage(char *prog)
1008 fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1012 static void process_args(int argc, char *argv[])
1016 while ((c = getopt(argc, argv, "d:")) != -1) {
1019 lustre_dir = optarg;
1023 fprintf(stderr, "Unknown option '%c'\n", optopt);
1030 int main(int argc, char *argv[])
1035 process_args(argc, argv);
1036 if (lustre_dir == NULL)
1037 lustre_dir = "/mnt/lustre";
1039 rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1041 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
1043 return EXIT_FAILURE;
1046 /* Play nice with Lustre test scripts. Non-line buffered output
1047 * stream under I/O redirection may appear incorrectly. */
1048 setvbuf(stdout, NULL, _IOLBF, 0);
1074 return EXIT_SUCCESS;