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
23 /* Copyright 2014, 2015 Cray Inc, all rights reserved. */
24 /* Some portions are extracted from llapi_layout_test.c */
26 /* The purpose of this test is to check some HSM functions. HSM must
27 * be enabled before running it:
28 * echo enabled > /proc/fs/lustre/mdt/lustre-MDT0000/hsm_control
31 /* All tests return 0 on success and non zero on error. The program will
32 * exit as soon a non zero error is returned. */
42 #include <lustre/lustreapi.h>
44 static char fsmountdir[PATH_MAX]; /* Lustre mountpoint */
45 static char *lustre_dir; /* Test directory inside Lustre */
47 #define ERROR(fmt, ...) \
48 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
49 program_invocation_short_name, __FILE__, __LINE__, \
50 __func__, ## __VA_ARGS__);
52 #define DIE(fmt, ...) \
54 ERROR(fmt, ## __VA_ARGS__); \
58 #define ASSERTF(cond, fmt, ...) \
61 DIE("assertion '%s' failed: "fmt, \
62 #cond, ## __VA_ARGS__); \
65 #define PERFORM(testfn) \
67 fprintf(stderr, "Starting test " #testfn " at %llu\n", \
68 (unsigned long long)time(NULL)); \
70 fprintf(stderr, "Finishing test " #testfn " at %llu\n", \
71 (unsigned long long)time(NULL)); \
74 /* Register and unregister 2000 times. Ensures there is no fd leak
75 * since there is usually 1024 fd per process. */
80 struct hsm_copytool_private *ctdata;
82 for (i = 0; i < 2000; i++) {
83 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
86 "llapi_hsm_copytool_register failed: %s, loop=%d",
89 rc = llapi_hsm_copytool_unregister(&ctdata);
91 "llapi_hsm_copytool_unregister failed: %s, loop=%d",
102 struct hsm_copytool_private *ctdata1;
103 struct hsm_copytool_private *ctdata2;
105 rc = llapi_hsm_copytool_register(&ctdata1, fsmountdir, 0, NULL, 0);
106 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
109 rc = llapi_hsm_copytool_register(&ctdata2, fsmountdir, 0, NULL, 0);
110 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
113 rc = llapi_hsm_copytool_unregister(&ctdata2);
114 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
117 rc = llapi_hsm_copytool_unregister(&ctdata1);
118 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
124 /* Bad parameters to llapi_hsm_copytool_register(). */
128 struct hsm_copytool_private *ctdata;
131 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 1, NULL, 0);
132 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
135 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 33, NULL, 0);
136 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
139 memset(archives, 1, sizeof(archives));
140 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 34, archives, 0);
141 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
145 /* BUG? Should that fail or not? */
146 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, -1, NULL, 0);
147 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
151 memset(archives, -1, sizeof(archives));
152 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 1, archives, 0);
153 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
156 rc = llapi_hsm_copytool_register(&ctdata, "/tmp", 0, NULL, 0);
157 ASSERTF(rc == -ENOENT, "llapi_hsm_copytool_register error: %s",
163 /* Bad parameters to llapi_hsm_copytool_unregister(). */
168 rc = llapi_hsm_copytool_unregister(NULL);
169 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_unregister error: %s",
175 /* Test llapi_hsm_copytool_recv in non blocking mode */
180 struct hsm_copytool_private *ctdata;
181 struct hsm_action_list *hal;
184 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
185 0, NULL, O_NONBLOCK);
186 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
189 /* Hopefully there is nothing lingering */
190 for (i = 0; i < 1000; i++) {
191 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
192 ASSERTF(rc == -EWOULDBLOCK, "llapi_hsm_copytool_recv error: %s",
196 rc = llapi_hsm_copytool_unregister(&ctdata);
197 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
203 /* Test llapi_hsm_copytool_recv with bogus parameters */
206 struct hsm_copytool_private *ctdata;
207 struct hsm_action_list *hal;
211 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 0, NULL, 0);
212 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
215 rc = llapi_hsm_copytool_recv(NULL, &hal, &msgsize);
216 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
219 rc = llapi_hsm_copytool_recv(ctdata, NULL, &msgsize);
220 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
223 rc = llapi_hsm_copytool_recv(ctdata, &hal, NULL);
224 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
227 rc = llapi_hsm_copytool_recv(ctdata, NULL, NULL);
228 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
231 rc = llapi_hsm_copytool_unregister(&ctdata);
232 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
238 /* Test polling (without actual traffic) */
242 struct hsm_copytool_private *ctdata;
243 struct hsm_action_list *hal;
246 struct pollfd fds[1];
248 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
249 0, NULL, O_NONBLOCK);
250 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
253 fd = llapi_hsm_copytool_get_fd(ctdata);
254 ASSERTF(fd >= 0, "llapi_hsm_copytool_get_fd failed: %s",
257 /* Ensure it's read-only */
258 rc = write(fd, &rc, 1);
259 ASSERTF(rc == -1 && errno == EBADF, "write error: %d, %s",
260 rc, strerror(errno));
262 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
263 ASSERTF(rc == -EWOULDBLOCK, "llapi_hsm_copytool_recv error: %s",
267 fds[0].events = POLLIN;
268 rc = poll(fds, 1, 10);
269 ASSERTF(rc == 0, "poll failed: %d, %s",
270 rc, strerror(errno)); /* no event */
272 rc = llapi_hsm_copytool_unregister(&ctdata);
273 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
279 /* Create the testfile of a given length. It returns a valid file
281 static char testfile[PATH_MAX];
282 static int create_testfile(size_t length)
287 rc = snprintf(testfile, sizeof(testfile), "%s/hsm_check_test",
289 ASSERTF((rc > 0 && rc < sizeof(testfile)), "invalid name for testfile");
291 /* Remove old test file, if any. */
294 /* Use truncate so we can create a file (almost) as big as we
295 * want, while taking 0 bytes of data. */
296 fd = creat(testfile, S_IRWXU);
297 ASSERTF(fd >= 0, "create failed for '%s': %s",
298 testfile, strerror(errno));
300 rc = ftruncate(fd, length);
301 ASSERTF(rc == 0, "ftruncate failed for '%s': %s",
302 testfile, strerror(errno));
307 /* Test llapi_hsm_state_get. */
310 struct hsm_user_state hus;
314 fd = create_testfile(100);
316 /* With fd variant */
317 rc = llapi_hsm_state_get_fd(fd, &hus);
318 ASSERTF(rc == 0, "llapi_hsm_state_get_fd failed: %s", strerror(-rc));
319 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
321 rc = llapi_hsm_state_get_fd(fd, NULL);
322 ASSERTF(rc == -EFAULT, "llapi_hsm_state_get_fd error: %s",
326 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
329 rc = llapi_hsm_state_get(testfile, &hus);
330 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
331 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
333 rc = llapi_hsm_state_get(testfile, NULL);
334 ASSERTF(rc == -EFAULT, "llapi_hsm_state_get error: %s",
337 memset(&hus, 0xaa, sizeof(hus));
338 rc = llapi_hsm_state_get(testfile, &hus);
339 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
340 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
341 ASSERTF(hus.hus_archive_id == 0, "archive_id=%u", hus.hus_archive_id);
342 ASSERTF(hus.hus_in_progress_state == 0, "hus_in_progress_state=%u",
343 hus.hus_in_progress_state);
344 ASSERTF(hus.hus_in_progress_action == 0, "hus_in_progress_action=%u",
345 hus.hus_in_progress_action);
348 /* Test llapi_hsm_state_set. */
354 struct hsm_user_state hus;
356 fd = create_testfile(100);
358 rc = llapi_hsm_state_set_fd(fd, 0, 0, 0);
359 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
362 for (i = 0; i <= 32; i++) {
363 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, i);
364 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s",
367 rc = llapi_hsm_state_get_fd(fd, &hus);
368 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s",
370 ASSERTF(hus.hus_states == HS_EXISTS, "state=%u",
372 ASSERTF(hus.hus_archive_id == i, "archive_id=%u, i=%d",
373 hus.hus_archive_id, i);
376 /* Invalid archive numbers */
377 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, 33);
378 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
380 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, 151);
381 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
383 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, -1789);
384 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
386 /* Settable flags, with respect of the HSM file state transition rules:
387 * DIRTY without EXISTS: no dirty if no archive was created
388 * DIRTY and RELEASED: a dirty file could not be released
389 * RELEASED without ARCHIVED: do not release a non-archived file
390 * LOST without ARCHIVED: cannot lost a non-archived file.
392 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY, 0, 0);
393 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
395 rc = llapi_hsm_state_set_fd(fd, 0, HS_EXISTS, 0);
396 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
399 rc = llapi_hsm_state_set_fd(fd, 0, HS_DIRTY, 0);
400 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
402 rc = llapi_hsm_state_set_fd(fd, 0, HS_EXISTS, 0);
403 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
405 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY, 0, 0);
406 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
409 rc = llapi_hsm_state_set_fd(fd, HS_RELEASED, 0, 0);
410 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
413 rc = llapi_hsm_state_set_fd(fd, HS_LOST, 0, 0);
414 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
417 rc = llapi_hsm_state_set_fd(fd, HS_ARCHIVED, 0, 0);
418 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
420 rc = llapi_hsm_state_set_fd(fd, HS_RELEASED, 0, 0);
421 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
423 rc = llapi_hsm_state_set_fd(fd, HS_LOST, 0, 0);
424 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
426 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY|HS_EXISTS, 0, 0);
427 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
430 rc = llapi_hsm_state_set_fd(fd, 0, HS_RELEASED, 0);
431 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
433 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY|HS_EXISTS, 0, 0);
434 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
436 rc = llapi_hsm_state_set_fd(fd, 0, HS_ARCHIVED, 0);
437 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
440 rc = llapi_hsm_state_set_fd(fd, 0, HS_LOST, 0);
441 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
443 rc = llapi_hsm_state_set_fd(fd, 0, HS_ARCHIVED, 0);
444 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
446 rc = llapi_hsm_state_set_fd(fd, HS_NORELEASE, 0, 0);
447 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
449 rc = llapi_hsm_state_set_fd(fd, 0, HS_NORELEASE, 0);
450 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
452 rc = llapi_hsm_state_set_fd(fd, HS_NOARCHIVE, 0, 0);
453 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
455 rc = llapi_hsm_state_set_fd(fd, 0, HS_NOARCHIVE, 0);
456 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
458 /* Bogus flags for good measure. */
459 rc = llapi_hsm_state_set_fd(fd, 0x00080000, 0, 0);
460 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
462 rc = llapi_hsm_state_set_fd(fd, 0x80000000, 0, 0);
463 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
468 /* Test llapi_hsm_current_action */
473 struct hsm_current_action hca;
475 /* No fd equivalent, so close it. */
476 fd = create_testfile(100);
479 rc = llapi_hsm_current_action(testfile, &hca);
480 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s", strerror(-rc));
481 ASSERTF(hca.hca_state, "hca_state=%u", hca.hca_state);
482 ASSERTF(hca.hca_action, "hca_state=%u", hca.hca_action);
484 rc = llapi_hsm_current_action(testfile, NULL);
485 ASSERTF(rc == -EFAULT, "llapi_hsm_current_action failed: %s",
489 /* Helper to simulate archiving a file. No actual data movement
491 void helper_archiving(void (*progress)
492 (struct hsm_copyaction_private *hcp, size_t length),
497 struct hsm_copytool_private *ctdata;
498 struct hsm_user_request *hur;
499 struct hsm_action_list *hal;
500 struct hsm_action_item *hai;
502 struct hsm_copyaction_private *hcp;
503 struct hsm_user_state hus;
505 fd = create_testfile(length);
507 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
509 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
512 /* Create and send the archive request. */
513 hur = llapi_hsm_user_request_alloc(1, 0);
514 ASSERTF(hur != NULL, "llapi_hsm_user_request_alloc returned NULL");
516 hur->hur_request.hr_action = HUA_ARCHIVE;
517 hur->hur_request.hr_archive_id = 1;
518 hur->hur_request.hr_flags = 0;
519 hur->hur_request.hr_itemcount = 1;
520 hur->hur_request.hr_data_len = 0;
521 hur->hur_user_item[0].hui_extent.length = -1;
523 rc = llapi_fd2fid(fd, &hur->hur_user_item[0].hui_fid);
524 ASSERTF(rc == 0, "llapi_fd2fid failed: %s", strerror(-rc));
528 rc = llapi_hsm_request(testfile, hur);
529 ASSERTF(rc == 0, "llapi_hsm_request failed: %s", strerror(-rc));
533 /* Read the request */
534 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
535 ASSERTF(rc == 0, "llapi_hsm_copytool_recv failed: %s", strerror(-rc));
536 ASSERTF(hal->hal_count == 1, "hal_count=%d", hal->hal_count);
538 hai = hai_first(hal);
539 ASSERTF(hai != NULL, "hai_first returned NULL");
540 ASSERTF(hai->hai_action == HSMA_ARCHIVE,
541 "hai_action=%d", hai->hai_action);
543 /* "Begin" archiving */
545 rc = llapi_hsm_action_begin(&hcp, ctdata, hai, -1, 0, false);
546 ASSERTF(rc == 0, "llapi_hsm_action_begin failed: %s", strerror(-rc));
547 ASSERTF(hcp != NULL, "hcp is NULL");
550 progress(hcp, length);
553 rc = llapi_hsm_action_end(&hcp, &hai->hai_extent, 0, 0);
554 ASSERTF(rc == 0, "llapi_hsm_action_end failed: %s", strerror(-rc));
555 ASSERTF(hcp == NULL, "hcp is NULL");
557 /* Close HSM client */
558 rc = llapi_hsm_copytool_unregister(&ctdata);
559 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
563 rc = llapi_hsm_state_get(testfile, &hus);
564 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
565 ASSERTF(hus.hus_states == (HS_EXISTS | HS_ARCHIVED),
566 "state=%u", hus.hus_states);
569 /* Simple archive. No progress. */
572 const size_t length = 100;
574 helper_archiving(NULL, length);
577 /* Archive, with a report every byte. */
578 static void test101_progress(struct hsm_copyaction_private *hcp, size_t length)
582 struct hsm_extent he;
583 struct hsm_current_action hca;
585 /* Report progress. 1 byte at a time :) */
586 for (i = 0; i < length; i++) {
589 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
590 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
594 rc = llapi_hsm_current_action(testfile, &hca);
595 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
597 ASSERTF(hca.hca_state == HPS_RUNNING,
598 "hca_state=%u", hca.hca_state);
599 ASSERTF(hca.hca_action == HUA_ARCHIVE,
600 "hca_state=%u", hca.hca_action);
601 ASSERTF(hca.hca_location.length == length,
602 "length=%llu", (unsigned long long)hca.hca_location.length);
607 const size_t length = 1000;
609 helper_archiving(test101_progress, length);
612 /* Archive, with a report every byte, backwards. */
613 static void test102_progress(struct hsm_copyaction_private *hcp, size_t length)
617 struct hsm_extent he;
618 struct hsm_current_action hca;
620 /* Report progress. 1 byte at a time :) */
621 for (i = length-1; i >= 0; i--) {
624 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
625 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
629 rc = llapi_hsm_current_action(testfile, &hca);
630 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
632 ASSERTF(hca.hca_state == HPS_RUNNING,
633 "hca_state=%u", hca.hca_state);
634 ASSERTF(hca.hca_action == HUA_ARCHIVE,
635 "hca_state=%u", hca.hca_action);
636 ASSERTF(hca.hca_location.length == length,
637 "length=%llu", (unsigned long long)hca.hca_location.length);
642 const size_t length = 1000;
644 helper_archiving(test102_progress, length);
647 /* Archive, with a single report. */
648 static void test103_progress(struct hsm_copyaction_private *hcp, size_t length)
651 struct hsm_extent he;
652 struct hsm_current_action hca;
656 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
657 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
660 rc = llapi_hsm_current_action(testfile, &hca);
661 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
663 ASSERTF(hca.hca_state == HPS_RUNNING,
664 "hca_state=%u", hca.hca_state);
665 ASSERTF(hca.hca_action == HUA_ARCHIVE,
666 "hca_state=%u", hca.hca_action);
667 ASSERTF(hca.hca_location.length == length,
668 "length=%llu", (unsigned long long)hca.hca_location.length);
673 const size_t length = 1000;
675 helper_archiving(test103_progress, length);
678 /* Archive, with 2 reports. */
679 static void test104_progress(struct hsm_copyaction_private *hcp, size_t length)
682 struct hsm_extent he;
683 struct hsm_current_action hca;
686 he.length = length/2;
687 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
688 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
691 he.offset = length/2;
692 he.length = length/2;
693 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
694 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
697 rc = llapi_hsm_current_action(testfile, &hca);
698 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
700 ASSERTF(hca.hca_state == HPS_RUNNING,
701 "hca_state=%u", hca.hca_state);
702 ASSERTF(hca.hca_action == HUA_ARCHIVE,
703 "hca_state=%u", hca.hca_action);
704 ASSERTF(hca.hca_location.length == length,
705 "length=%llu", (unsigned long long)hca.hca_location.length);
710 const size_t length = 1000;
712 helper_archiving(test104_progress, length);
715 /* Archive, with 1 bogus report. */
716 static void test105_progress(struct hsm_copyaction_private *hcp, size_t length)
719 struct hsm_extent he;
720 struct hsm_current_action hca;
722 he.offset = 2*length;
723 he.length = 10*length;
724 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
725 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
728 rc = llapi_hsm_current_action(testfile, &hca);
729 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
731 ASSERTF(hca.hca_state == HPS_RUNNING,
732 "hca_state=%u", hca.hca_state);
733 ASSERTF(hca.hca_action == HUA_ARCHIVE,
734 "hca_state=%u", hca.hca_action);
736 /* BUG - offset should be 2*length, or length should
738 ASSERTF(hca.hca_location.length == 10*length,
739 "length=%llu", (unsigned long long)hca.hca_location.length);
744 const size_t length = 1000;
746 helper_archiving(test105_progress, length);
749 /* Archive, with 1 empty report. */
750 static void test106_progress(struct hsm_copyaction_private *hcp, size_t length)
753 struct hsm_extent he;
754 struct hsm_current_action hca;
758 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
759 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
762 rc = llapi_hsm_current_action(testfile, &hca);
763 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
765 ASSERTF(hca.hca_state == HPS_RUNNING,
766 "hca_state=%u", hca.hca_state);
767 ASSERTF(hca.hca_action == HUA_ARCHIVE,
768 "hca_state=%u", hca.hca_action);
769 ASSERTF(hca.hca_location.length == 0,
770 "length=%llu", (unsigned long long)hca.hca_location.length);
775 const size_t length = 1000;
777 helper_archiving(test106_progress, length);
780 /* Archive, with 1 bogus report. */
781 static void test107_progress(struct hsm_copyaction_private *hcp, size_t length)
784 struct hsm_extent he;
785 struct hsm_current_action hca;
789 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
790 ASSERTF(rc == -EINVAL, "llapi_hsm_action_progress error: %s",
793 rc = llapi_hsm_current_action(testfile, &hca);
794 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
796 ASSERTF(hca.hca_state == HPS_RUNNING,
797 "hca_state=%u", hca.hca_state);
798 ASSERTF(hca.hca_action == HUA_ARCHIVE,
799 "hca_state=%u", hca.hca_action);
800 ASSERTF(hca.hca_location.length == 0,
801 "length=%llu", (unsigned long long)hca.hca_location.length);
806 const size_t length = 1000;
808 helper_archiving(test107_progress, length);
811 /* Archive, with same report, many times. */
812 static void test108_progress(struct hsm_copyaction_private *hcp, size_t length)
815 struct hsm_extent he;
817 struct hsm_current_action hca;
819 for (i = 0; i < 1000; i++) {
822 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
823 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
827 rc = llapi_hsm_current_action(testfile, &hca);
828 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
830 ASSERTF(hca.hca_state == HPS_RUNNING,
831 "hca_state=%u", hca.hca_state);
832 ASSERTF(hca.hca_action == HUA_ARCHIVE,
833 "hca_state=%u", hca.hca_action);
834 ASSERTF(hca.hca_location.length == length,
835 "length=%llu", (unsigned long long)hca.hca_location.length);
840 const size_t length = 1000;
842 helper_archiving(test108_progress, length);
845 /* Archive, 1 report, with large number. */
846 static void test109_progress(struct hsm_copyaction_private *hcp, size_t length)
849 struct hsm_extent he;
850 struct hsm_current_action hca;
853 he.length = 0xffffffffffffffffULL;
854 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
855 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
858 rc = llapi_hsm_current_action(testfile, &hca);
859 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
861 ASSERTF(hca.hca_state == HPS_RUNNING,
862 "hca_state=%u", hca.hca_state);
863 ASSERTF(hca.hca_action == HUA_ARCHIVE,
864 "hca_state=%u", hca.hca_action);
865 ASSERTF(hca.hca_location.length == 0xffffffffffffffffULL,
866 "length=%llu", (unsigned long long)hca.hca_location.length);
871 const size_t length = 1000;
873 helper_archiving(test109_progress, length);
876 /* Archive, with 10 reports, checking progress. */
877 static void test110_progress(struct hsm_copyaction_private *hcp, size_t length)
881 struct hsm_extent he;
882 struct hsm_current_action hca;
884 for (i = 0; i < 10; i++) {
885 he.offset = i*length/10;
886 he.length = length/10;
887 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
888 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
891 rc = llapi_hsm_current_action(testfile, &hca);
892 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
894 ASSERTF(hca.hca_state == HPS_RUNNING,
895 "hca_state=%u", hca.hca_state);
896 ASSERTF(hca.hca_action == HUA_ARCHIVE,
897 "hca_state=%u", hca.hca_action);
898 ASSERTF(hca.hca_location.length == (i+1)*length/10,
900 i, (unsigned long long)hca.hca_location.length);
906 const size_t length = 1000;
908 helper_archiving(test110_progress, length);
911 /* Archive, with 10 reports in reverse order, checking progress. */
912 static void test111_progress(struct hsm_copyaction_private *hcp, size_t length)
916 struct hsm_extent he;
917 struct hsm_current_action hca;
919 for (i = 0; i < 10; i++) {
920 he.offset = (9-i)*length/10;
921 he.length = length/10;
922 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
923 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
926 rc = llapi_hsm_current_action(testfile, &hca);
927 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
929 ASSERTF(hca.hca_state == HPS_RUNNING,
930 "hca_state=%u", hca.hca_state);
931 ASSERTF(hca.hca_action == HUA_ARCHIVE,
932 "hca_state=%u", hca.hca_action);
933 ASSERTF(hca.hca_location.length == (i+1)*length/10,
935 i, (unsigned long long)hca.hca_location.length);
941 const size_t length = 1000;
943 helper_archiving(test111_progress, length);
946 /* Archive, with 10 reports, and duplicating them, checking
948 static void test112_progress(struct hsm_copyaction_private *hcp, size_t length)
952 struct hsm_extent he;
953 struct hsm_current_action hca;
955 for (i = 0; i < 10; i++) {
956 he.offset = i*length/10;
957 he.length = length/10;
958 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
959 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
962 rc = llapi_hsm_current_action(testfile, &hca);
963 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
965 ASSERTF(hca.hca_state == HPS_RUNNING,
966 "hca_state=%u", hca.hca_state);
967 ASSERTF(hca.hca_action == HUA_ARCHIVE,
968 "hca_state=%u", hca.hca_action);
969 ASSERTF(hca.hca_location.length == (i+1)*length/10,
971 i, (unsigned long long)hca.hca_location.length);
974 for (i = 0; i < 10; i++) {
975 he.offset = i*length/10;
976 he.length = length/10;
977 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
978 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
981 rc = llapi_hsm_current_action(testfile, &hca);
982 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
984 ASSERTF(hca.hca_state == HPS_RUNNING,
985 "hca_state=%u", hca.hca_state);
986 ASSERTF(hca.hca_action == HUA_ARCHIVE,
987 "hca_state=%u", hca.hca_action);
988 ASSERTF(hca.hca_location.length == length,
990 i, (unsigned long long)hca.hca_location.length);
996 const size_t length = 1000;
998 helper_archiving(test112_progress, length);
1001 static void usage(char *prog)
1003 fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1007 static void process_args(int argc, char *argv[])
1011 while ((c = getopt(argc, argv, "d:")) != -1) {
1014 lustre_dir = optarg;
1018 fprintf(stderr, "Unknown option '%c'\n", optopt);
1025 int main(int argc, char *argv[])
1030 process_args(argc, argv);
1031 if (lustre_dir == NULL)
1032 lustre_dir = "/mnt/lustre";
1034 rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1036 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
1038 return EXIT_FAILURE;
1041 /* Play nice with Lustre test scripts. Non-line buffered output
1042 * stream under I/O redirection may appear incorrectly. */
1043 setvbuf(stdout, NULL, _IOLBF, 0);
1069 return EXIT_SUCCESS;