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 */
50 static bool is_bitmap;
52 #define ERROR(fmt, ...) \
53 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
54 program_invocation_short_name, __FILE__, __LINE__, \
55 __func__, ## __VA_ARGS__);
57 #define DIE(fmt, ...) \
59 ERROR(fmt, ## __VA_ARGS__); \
63 #define ASSERTF(cond, fmt, ...) \
66 DIE("assertion '%s' failed: "fmt, \
67 #cond, ## __VA_ARGS__); \
70 #define PERFORM(testfn) \
72 fprintf(stderr, "Starting test " #testfn " at %llu\n", \
73 (unsigned long long)time(NULL)); \
75 fprintf(stderr, "Finishing test " #testfn " at %llu\n", \
76 (unsigned long long)time(NULL)); \
79 /* Register and unregister 2000 times. Ensures there is no fd leak
80 * since there is usually 1024 fd per process.
82 static int test1(void)
86 struct hsm_copytool_private *ctdata;
88 for (i = 0; i < 2000; i++) {
89 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
92 "llapi_hsm_copytool_register failed: %s, loop=%d",
95 rc = llapi_hsm_copytool_unregister(&ctdata);
97 "llapi_hsm_copytool_unregister failed: %s, loop=%d",
105 static int test2(void)
108 struct hsm_copytool_private *ctdata1;
109 struct hsm_copytool_private *ctdata2;
111 rc = llapi_hsm_copytool_register(&ctdata1, fsmountdir, 0, NULL, 0);
112 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
115 rc = llapi_hsm_copytool_register(&ctdata2, fsmountdir, 0, NULL, 0);
116 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
119 rc = llapi_hsm_copytool_unregister(&ctdata2);
120 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
123 rc = llapi_hsm_copytool_unregister(&ctdata1);
124 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
130 /* Bad parameters to llapi_hsm_copytool_register(). */
131 static int test3(void)
134 struct hsm_copytool_private *ctdata;
136 int count = sizeof(archives) / sizeof(*archives);
138 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 1, NULL, 0);
139 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
142 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, count, NULL, 0);
143 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
149 for (i = 0; i < count; i++)
151 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
153 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
158 /* BUG? Should that fail or not? */
159 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, -1, NULL, 0);
160 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
164 memset(archives, -1, sizeof(archives));
165 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 1, archives, 0);
166 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_register error: %s",
169 rc = llapi_hsm_copytool_register(&ctdata, "/tmp", 0, NULL, 0);
170 ASSERTF(rc == -ENOENT, "llapi_hsm_copytool_register error: %s",
176 /* Bad parameters to llapi_hsm_copytool_unregister(). */
177 static int test4(void)
181 rc = llapi_hsm_copytool_unregister(NULL);
182 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_unregister error: %s",
188 /* Test llapi_hsm_copytool_recv in non blocking mode */
189 static int test5(void)
193 struct hsm_copytool_private *ctdata;
194 struct hsm_action_list *hal;
197 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
198 0, NULL, O_NONBLOCK);
199 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
202 /* Hopefully there is nothing lingering */
203 for (i = 0; i < 1000; i++) {
204 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
205 ASSERTF(rc == -EAGAIN, "llapi_hsm_copytool_recv error: %s",
209 rc = llapi_hsm_copytool_unregister(&ctdata);
210 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
216 /* Test llapi_hsm_copytool_recv with bogus parameters */
217 static int test6(void)
219 struct hsm_copytool_private *ctdata;
220 struct hsm_action_list *hal;
224 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir, 0, NULL, 0);
225 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
228 rc = llapi_hsm_copytool_recv(NULL, &hal, &msgsize);
229 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
232 rc = llapi_hsm_copytool_recv(ctdata, NULL, &msgsize);
233 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
236 rc = llapi_hsm_copytool_recv(ctdata, &hal, NULL);
237 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
240 rc = llapi_hsm_copytool_recv(ctdata, NULL, NULL);
241 ASSERTF(rc == -EINVAL, "llapi_hsm_copytool_recv error: %s",
244 rc = llapi_hsm_copytool_unregister(&ctdata);
245 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
251 /* Test polling (without actual traffic) */
252 static int test7(void)
255 struct hsm_copytool_private *ctdata;
256 struct hsm_action_list *hal;
259 struct pollfd fds[1];
261 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
262 0, NULL, O_NONBLOCK);
263 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
266 fd = llapi_hsm_copytool_get_fd(ctdata);
267 ASSERTF(fd >= 0, "llapi_hsm_copytool_get_fd failed: %s",
270 /* Ensure it's read-only */
271 rc = write(fd, &rc, 1);
272 ASSERTF(rc == -1 && errno == EBADF, "write error: %d, %s",
273 rc, strerror(errno));
275 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
276 ASSERTF(rc == -EAGAIN, "llapi_hsm_copytool_recv error: %s",
280 fds[0].events = POLLIN;
281 rc = poll(fds, 1, 10);
282 ASSERTF(rc == 0, "poll failed: %d, %s",
283 rc, strerror(errno)); /* no event */
285 rc = llapi_hsm_copytool_unregister(&ctdata);
286 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
292 /* Create the testfile of a given length. It returns a valid file descriptor. */
293 static char testfile[PATH_MAX];
294 static int create_testfile(size_t length)
299 rc = snprintf(testfile, sizeof(testfile), "%s/hsm_check_test",
301 ASSERTF((rc > 0 && rc < sizeof(testfile)), "invalid name for testfile");
303 /* Remove old test file, if any. */
306 /* Use truncate so we can create a file (almost) as big as we
307 * want, while taking 0 bytes of data.
309 fd = creat(testfile, 0700);
310 ASSERTF(fd >= 0, "create failed for '%s': %s",
311 testfile, strerror(errno));
313 rc = ftruncate(fd, length);
314 ASSERTF(rc == 0, "ftruncate failed for '%s': %s",
315 testfile, strerror(errno));
320 /* Test llapi_hsm_state_get. */
321 static void test50(void)
323 struct hsm_user_state hus;
327 fd = create_testfile(100);
329 /* With fd variant */
330 rc = llapi_hsm_state_get_fd(fd, &hus);
331 ASSERTF(rc == 0, "llapi_hsm_state_get_fd failed: %s", strerror(-rc));
332 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
334 rc = llapi_hsm_state_get_fd(fd, NULL);
335 ASSERTF(rc == -EFAULT, "llapi_hsm_state_get_fd error: %s",
339 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
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);
346 rc = llapi_hsm_state_get(testfile, NULL);
347 ASSERTF(rc == -EFAULT, "llapi_hsm_state_get error: %s",
350 memset(&hus, 0xaa, sizeof(hus));
351 rc = llapi_hsm_state_get(testfile, &hus);
352 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
353 ASSERTF(hus.hus_states == 0, "state=%u", hus.hus_states);
354 ASSERTF(hus.hus_archive_id == 0, "archive_id=%u", hus.hus_archive_id);
355 ASSERTF(hus.hus_in_progress_state == 0, "hus_in_progress_state=%u",
356 hus.hus_in_progress_state);
357 ASSERTF(hus.hus_in_progress_action == 0, "hus_in_progress_action=%u",
358 hus.hus_in_progress_action);
361 /* Test llapi_hsm_state_set. */
362 static void test51(void)
368 struct hsm_user_state hus;
370 fd = create_testfile(100);
372 rc = llapi_hsm_state_set_fd(fd, 0, 0, 0);
373 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
380 for (i = 0; i <= test_count; i++) {
381 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, i);
382 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s",
385 rc = llapi_hsm_state_get_fd(fd, &hus);
386 ASSERTF(rc == 0, "llapi_hsm_state_get_fd failed: %s",
388 ASSERTF(hus.hus_states == HS_EXISTS, "state=%u",
390 ASSERTF(hus.hus_archive_id == i, "archive_id=%u, i=%d",
391 hus.hus_archive_id, i);
395 /* Invalid archive numbers */
396 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, 33);
397 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s",
400 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, 151);
401 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s",
404 rc = llapi_hsm_state_set_fd(fd, HS_EXISTS, 0, -1789);
405 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s",
409 /* Settable flags, with respect of the HSM file state transition rules:
410 * DIRTY without EXISTS: no dirty if no archive was created
411 * DIRTY and RELEASED: a dirty file could not be released
412 * RELEASED without ARCHIVED: do not release a non-archived file
413 * LOST without ARCHIVED: cannot lost a non-archived file.
415 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY, 0, 0);
416 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
418 rc = llapi_hsm_state_set_fd(fd, 0, HS_EXISTS, 0);
419 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
422 rc = llapi_hsm_state_set_fd(fd, 0, HS_DIRTY, 0);
423 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
425 rc = llapi_hsm_state_set_fd(fd, 0, HS_EXISTS, 0);
426 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
428 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY, 0, 0);
429 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
432 rc = llapi_hsm_state_set_fd(fd, HS_RELEASED, 0, 0);
433 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
436 rc = llapi_hsm_state_set_fd(fd, HS_LOST, 0, 0);
437 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
440 rc = llapi_hsm_state_set_fd(fd, HS_ARCHIVED, 0, 0);
441 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
443 rc = llapi_hsm_state_set_fd(fd, HS_RELEASED, 0, 0);
444 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
446 rc = llapi_hsm_state_set_fd(fd, HS_LOST, 0, 0);
447 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
449 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY|HS_EXISTS, 0, 0);
450 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
453 rc = llapi_hsm_state_set_fd(fd, 0, HS_RELEASED, 0);
454 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
456 rc = llapi_hsm_state_set_fd(fd, HS_DIRTY|HS_EXISTS, 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_ARCHIVED, 0);
460 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd failed: %s",
463 rc = llapi_hsm_state_set_fd(fd, 0, HS_LOST, 0);
464 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
466 rc = llapi_hsm_state_set_fd(fd, 0, HS_ARCHIVED, 0);
467 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
469 rc = llapi_hsm_state_set_fd(fd, HS_NORELEASE, 0, 0);
470 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
472 rc = llapi_hsm_state_set_fd(fd, 0, HS_NORELEASE, 0);
473 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
475 rc = llapi_hsm_state_set_fd(fd, HS_NOARCHIVE, 0, 0);
476 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
478 rc = llapi_hsm_state_set_fd(fd, 0, HS_NOARCHIVE, 0);
479 ASSERTF(rc == 0, "llapi_hsm_state_set_fd failed: %s", strerror(-rc));
481 /* Bogus flags for good measure. */
482 rc = llapi_hsm_state_set_fd(fd, 0x00080000, 0, 0);
483 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
485 rc = llapi_hsm_state_set_fd(fd, 0x80000000, 0, 0);
486 ASSERTF(rc == -EINVAL, "llapi_hsm_state_set_fd: %s", strerror(-rc));
491 /* Test llapi_hsm_current_action */
492 static void test52(void)
496 struct hsm_current_action hca;
498 /* No fd equivalent, so close it. */
499 fd = create_testfile(100);
502 rc = llapi_hsm_current_action(testfile, &hca);
503 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s", strerror(-rc));
504 ASSERTF(hca.hca_state, "hca_state=%u", hca.hca_state);
505 ASSERTF(hca.hca_action, "hca_state=%u", hca.hca_action);
507 rc = llapi_hsm_current_action(testfile, NULL);
508 ASSERTF(rc == -EFAULT, "llapi_hsm_current_action failed: %s",
512 /* Helper to simulate archiving a file. No actual data movement happens. */
513 static void helper_archiving(void (*progress)
514 (struct hsm_copyaction_private *hcp, size_t length),
519 struct hsm_copytool_private *ctdata;
520 struct hsm_user_request *hur;
521 struct hsm_action_list *hal;
522 struct hsm_action_item *hai;
524 struct hsm_copyaction_private *hcp;
525 struct hsm_user_state hus;
527 fd = create_testfile(length);
529 rc = llapi_hsm_copytool_register(&ctdata, fsmountdir,
531 ASSERTF(rc == 0, "llapi_hsm_copytool_register failed: %s",
534 /* Create and send the archive request. */
535 hur = llapi_hsm_user_request_alloc(1, 0);
536 ASSERTF(hur != NULL, "llapi_hsm_user_request_alloc returned NULL");
538 hur->hur_request.hr_action = HUA_ARCHIVE;
539 hur->hur_request.hr_archive_id = 1;
540 hur->hur_request.hr_flags = 0;
541 hur->hur_request.hr_itemcount = 1;
542 hur->hur_request.hr_data_len = 0;
543 hur->hur_user_item[0].hui_extent.offset = 0;
544 hur->hur_user_item[0].hui_extent.length = -1;
546 rc = llapi_fd2fid(fd, &hur->hur_user_item[0].hui_fid);
547 ASSERTF(rc == 0, "llapi_fd2fid failed: %s", strerror(-rc));
551 rc = llapi_hsm_request(testfile, hur);
552 ASSERTF(rc == 0, "llapi_hsm_request failed: %s", strerror(-rc));
556 /* Read the request */
557 rc = llapi_hsm_copytool_recv(ctdata, &hal, &msgsize);
558 ASSERTF(rc == 0, "llapi_hsm_copytool_recv failed: %s", strerror(-rc));
559 ASSERTF(hal->hal_count == 1, "hal_count=%d", hal->hal_count);
561 hai = hai_first(hal);
562 ASSERTF(hai != NULL, "hai_first returned NULL");
563 ASSERTF(hai->hai_action == HSMA_ARCHIVE,
564 "hai_action=%d", hai->hai_action);
566 /* "Begin" archiving */
568 rc = llapi_hsm_action_begin(&hcp, ctdata, hai, -1, 0, false);
569 ASSERTF(rc == 0, "llapi_hsm_action_begin failed: %s", strerror(-rc));
570 ASSERTF(hcp != NULL, "hcp is NULL");
573 progress(hcp, length);
576 rc = llapi_hsm_action_end(&hcp, &hai->hai_extent, 0, 0);
577 ASSERTF(rc == 0, "llapi_hsm_action_end failed: %s", strerror(-rc));
578 ASSERTF(hcp == NULL, "hcp is NULL");
580 /* Close HSM client */
581 rc = llapi_hsm_copytool_unregister(&ctdata);
582 ASSERTF(rc == 0, "llapi_hsm_copytool_unregister failed: %s",
586 rc = llapi_hsm_state_get(testfile, &hus);
587 ASSERTF(rc == 0, "llapi_hsm_state_get failed: %s", strerror(-rc));
588 ASSERTF(hus.hus_states == (HS_EXISTS | HS_ARCHIVED),
589 "state=%u", hus.hus_states);
592 /* Simple archive. No progress. */
593 static void test100(void)
595 const size_t length = 100;
597 helper_archiving(NULL, length);
600 /* Archive, with a report every byte. */
601 static void test101_progress(struct hsm_copyaction_private *hcp, size_t length)
605 struct hsm_extent he;
606 struct hsm_current_action hca;
608 /* Report progress. 1 byte at a time :) */
609 for (i = 0; i < length; i++) {
612 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
613 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
617 rc = llapi_hsm_current_action(testfile, &hca);
618 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
620 ASSERTF(hca.hca_state == HPS_RUNNING,
621 "hca_state=%u", hca.hca_state);
622 ASSERTF(hca.hca_action == HUA_ARCHIVE,
623 "hca_state=%u", hca.hca_action);
624 ASSERTF(hca.hca_location.length == length,
625 "length=%llu", (unsigned long long)hca.hca_location.length);
628 static void test101(void)
630 const size_t length = 1000;
632 helper_archiving(test101_progress, length);
635 /* Archive, with a report every byte, backwards. */
636 static void test102_progress(struct hsm_copyaction_private *hcp, size_t length)
640 struct hsm_extent he;
641 struct hsm_current_action hca;
643 /* Report progress. 1 byte at a time :) */
644 for (i = length-1; i >= 0; i--) {
647 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
648 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
652 rc = llapi_hsm_current_action(testfile, &hca);
653 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
655 ASSERTF(hca.hca_state == HPS_RUNNING,
656 "hca_state=%u", hca.hca_state);
657 ASSERTF(hca.hca_action == HUA_ARCHIVE,
658 "hca_state=%u", hca.hca_action);
659 ASSERTF(hca.hca_location.length == length,
660 "length=%llu", (unsigned long long)hca.hca_location.length);
663 static void test102(void)
665 const size_t length = 1000;
667 helper_archiving(test102_progress, length);
670 /* Archive, with a single report. */
671 static void test103_progress(struct hsm_copyaction_private *hcp, size_t length)
674 struct hsm_extent he;
675 struct hsm_current_action hca;
679 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
680 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
683 rc = llapi_hsm_current_action(testfile, &hca);
684 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
686 ASSERTF(hca.hca_state == HPS_RUNNING,
687 "hca_state=%u", hca.hca_state);
688 ASSERTF(hca.hca_action == HUA_ARCHIVE,
689 "hca_state=%u", hca.hca_action);
690 ASSERTF(hca.hca_location.length == length,
691 "length=%llu", (unsigned long long)hca.hca_location.length);
694 static void test103(void)
696 const size_t length = 1000;
698 helper_archiving(test103_progress, length);
701 /* Archive, with 2 reports. */
702 static void test104_progress(struct hsm_copyaction_private *hcp, size_t length)
705 struct hsm_extent he;
706 struct hsm_current_action hca;
709 he.length = length/2;
710 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
711 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
714 he.offset = length/2;
715 he.length = length/2;
716 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
717 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
720 rc = llapi_hsm_current_action(testfile, &hca);
721 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
723 ASSERTF(hca.hca_state == HPS_RUNNING,
724 "hca_state=%u", hca.hca_state);
725 ASSERTF(hca.hca_action == HUA_ARCHIVE,
726 "hca_state=%u", hca.hca_action);
727 ASSERTF(hca.hca_location.length == length,
728 "length=%llu", (unsigned long long)hca.hca_location.length);
731 static void test104(void)
733 const size_t length = 1000;
735 helper_archiving(test104_progress, length);
738 /* Archive, with 1 bogus report. */
739 static void test105_progress(struct hsm_copyaction_private *hcp, size_t length)
742 struct hsm_extent he;
743 struct hsm_current_action hca;
745 he.offset = 2*length;
746 he.length = 10*length;
747 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
748 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
751 rc = llapi_hsm_current_action(testfile, &hca);
752 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
754 ASSERTF(hca.hca_state == HPS_RUNNING,
755 "hca_state=%u", hca.hca_state);
756 ASSERTF(hca.hca_action == HUA_ARCHIVE,
757 "hca_state=%u", hca.hca_action);
759 /* BUG - offset should be 2*length, or length should be 8*length */
760 ASSERTF(hca.hca_location.length == 10*length,
761 "length=%llu", (unsigned long long)hca.hca_location.length);
764 static void test105(void)
766 const size_t length = 1000;
768 helper_archiving(test105_progress, length);
771 /* Archive, with 1 empty report. */
772 static void test106_progress(struct hsm_copyaction_private *hcp, size_t length)
775 struct hsm_extent he;
776 struct hsm_current_action hca;
780 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
781 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
784 rc = llapi_hsm_current_action(testfile, &hca);
785 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
787 ASSERTF(hca.hca_state == HPS_RUNNING,
788 "hca_state=%u", hca.hca_state);
789 ASSERTF(hca.hca_action == HUA_ARCHIVE,
790 "hca_state=%u", hca.hca_action);
791 ASSERTF(hca.hca_location.length == 0,
792 "length=%llu", (unsigned long long)hca.hca_location.length);
795 static void test106(void)
797 const size_t length = 1000;
799 helper_archiving(test106_progress, length);
802 /* Archive, with 1 bogus report. */
803 static void test107_progress(struct hsm_copyaction_private *hcp, size_t length)
806 struct hsm_extent he;
807 struct hsm_current_action hca;
811 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
812 ASSERTF(rc == -EINVAL, "llapi_hsm_action_progress error: %s",
815 rc = llapi_hsm_current_action(testfile, &hca);
816 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
818 ASSERTF(hca.hca_state == HPS_RUNNING,
819 "hca_state=%u", hca.hca_state);
820 ASSERTF(hca.hca_action == HUA_ARCHIVE,
821 "hca_state=%u", hca.hca_action);
822 ASSERTF(hca.hca_location.length == 0,
823 "length=%llu", (unsigned long long)hca.hca_location.length);
826 static void test107(void)
828 const size_t length = 1000;
830 helper_archiving(test107_progress, length);
833 /* Archive, with same report, many times. */
834 static void test108_progress(struct hsm_copyaction_private *hcp, size_t length)
837 struct hsm_extent he;
839 struct hsm_current_action hca;
841 for (i = 0; i < 1000; i++) {
844 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
845 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
849 rc = llapi_hsm_current_action(testfile, &hca);
850 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
852 ASSERTF(hca.hca_state == HPS_RUNNING,
853 "hca_state=%u", hca.hca_state);
854 ASSERTF(hca.hca_action == HUA_ARCHIVE,
855 "hca_state=%u", hca.hca_action);
856 ASSERTF(hca.hca_location.length == length,
857 "length=%llu", (unsigned long long)hca.hca_location.length);
860 static void test108(void)
862 const size_t length = 1000;
864 helper_archiving(test108_progress, length);
867 /* Archive, 1 report, with large number. */
868 static void test109_progress(struct hsm_copyaction_private *hcp, size_t length)
871 struct hsm_extent he;
872 struct hsm_current_action hca;
875 he.length = 0xffffffffffffffffULL;
876 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
877 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
880 rc = llapi_hsm_current_action(testfile, &hca);
881 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
883 ASSERTF(hca.hca_state == HPS_RUNNING,
884 "hca_state=%u", hca.hca_state);
885 ASSERTF(hca.hca_action == HUA_ARCHIVE,
886 "hca_state=%u", hca.hca_action);
887 ASSERTF(hca.hca_location.length == 0xffffffffffffffffULL,
888 "length=%llu", (unsigned long long)hca.hca_location.length);
891 static void test109(void)
893 const size_t length = 1000;
895 helper_archiving(test109_progress, length);
898 /* Archive, with 10 reports, checking progress. */
899 static void test110_progress(struct hsm_copyaction_private *hcp, size_t length)
903 struct hsm_extent he;
904 struct hsm_current_action hca;
906 for (i = 0; i < 10; i++) {
907 he.offset = i*length/10;
908 he.length = length/10;
909 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
910 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
913 rc = llapi_hsm_current_action(testfile, &hca);
914 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
916 ASSERTF(hca.hca_state == HPS_RUNNING,
917 "hca_state=%u", hca.hca_state);
918 ASSERTF(hca.hca_action == HUA_ARCHIVE,
919 "hca_state=%u", hca.hca_action);
920 ASSERTF(hca.hca_location.length == (i+1)*length/10,
922 i, (unsigned long long)hca.hca_location.length);
926 static void test110(void)
928 const size_t length = 1000;
930 helper_archiving(test110_progress, length);
933 /* Archive, with 10 reports in reverse order, checking progress. */
934 static void test111_progress(struct hsm_copyaction_private *hcp, size_t length)
938 struct hsm_extent he;
939 struct hsm_current_action hca;
941 for (i = 0; i < 10; i++) {
942 he.offset = (9-i)*length/10;
943 he.length = length/10;
944 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
945 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
948 rc = llapi_hsm_current_action(testfile, &hca);
949 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
951 ASSERTF(hca.hca_state == HPS_RUNNING,
952 "hca_state=%u", hca.hca_state);
953 ASSERTF(hca.hca_action == HUA_ARCHIVE,
954 "hca_state=%u", hca.hca_action);
955 ASSERTF(hca.hca_location.length == (i+1)*length/10,
957 i, (unsigned long long)hca.hca_location.length);
961 static void test111(void)
963 const size_t length = 1000;
965 helper_archiving(test111_progress, length);
968 /* Archive, with 10 reports, and duplicating them, checking progress. */
969 static void test112_progress(struct hsm_copyaction_private *hcp, size_t length)
973 struct hsm_extent he;
974 struct hsm_current_action hca;
976 for (i = 0; i < 10; i++) {
977 he.offset = i*length/10;
978 he.length = length/10;
979 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
980 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
983 rc = llapi_hsm_current_action(testfile, &hca);
984 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
986 ASSERTF(hca.hca_state == HPS_RUNNING,
987 "hca_state=%u", hca.hca_state);
988 ASSERTF(hca.hca_action == HUA_ARCHIVE,
989 "hca_state=%u", hca.hca_action);
990 ASSERTF(hca.hca_location.length == (i+1)*length/10,
992 i, (unsigned long long)hca.hca_location.length);
995 for (i = 0; i < 10; i++) {
996 he.offset = i*length/10;
997 he.length = length/10;
998 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
999 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
1002 rc = llapi_hsm_current_action(testfile, &hca);
1003 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
1005 ASSERTF(hca.hca_state == HPS_RUNNING,
1006 "hca_state=%u", hca.hca_state);
1007 ASSERTF(hca.hca_action == HUA_ARCHIVE,
1008 "hca_state=%u", hca.hca_action);
1009 ASSERTF(hca.hca_location.length == length,
1010 "i=%d, length=%llu",
1011 i, (unsigned long long)hca.hca_location.length);
1015 static void test112(void)
1017 const size_t length = 1000;
1019 helper_archiving(test112_progress, length);
1022 /* Archive, with 9 reports, each covering 20%, so many overlap. */
1023 static void test113_progress(struct hsm_copyaction_private *hcp, size_t length)
1027 struct hsm_extent he;
1028 struct hsm_current_action hca;
1030 for (i = 0; i < 9; i++) {
1031 he.offset = i*length/10;
1032 he.length = 2*length/10;
1033 rc = llapi_hsm_action_progress(hcp, &he, length, 0);
1034 ASSERTF(rc == 0, "llapi_hsm_action_progress failed: %s",
1037 rc = llapi_hsm_current_action(testfile, &hca);
1038 ASSERTF(rc == 0, "llapi_hsm_current_action failed: %s",
1040 ASSERTF(hca.hca_state == HPS_RUNNING,
1041 "hca_state=%u", hca.hca_state);
1042 ASSERTF(hca.hca_action == HUA_ARCHIVE,
1043 "hca_state=%u", hca.hca_action);
1044 ASSERTF(hca.hca_location.length == (i+2)*length/10,
1045 "i=%d, length=%llu",
1046 i, (unsigned long long)hca.hca_location.length);
1050 static void test113(void)
1052 const size_t length = 1000;
1054 helper_archiving(test113_progress, length);
1057 static void usage(char *prog)
1059 fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1063 static void process_args(int argc, char *argv[])
1067 while ((c = getopt(argc, argv, "bd:")) != -1) {
1070 lustre_dir = optarg;
1077 fprintf(stderr, "Unknown option '%c'\n", optopt);
1084 int main(int argc, char *argv[])
1089 process_args(argc, argv);
1090 if (lustre_dir == NULL)
1091 lustre_dir = "/mnt/lustre";
1093 rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1095 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
1097 return EXIT_FAILURE;
1100 /* Play nice with Lustre test scripts. Non-line buffered output
1101 * stream under I/O redirection may appear incorrectly.
1103 setvbuf(stdout, NULL, _IOLBF, 0);
1130 return EXIT_SUCCESS;