Whamcloud - gitweb
LU-3508 test: small fix for sanity.sh test_101c
[fs/lustre-release.git] / lustre / utils / lhsmtool_posix.c
index 8b7c426..dd496f1 100644 (file)
@@ -60,11 +60,11 @@ enum ct_action {
        CA_IMPORT = 1,
        CA_REBIND,
        CA_MAXSEQ,
-       CA_DAEMON,
 };
 
 struct options {
        int                      o_copy_attrs;
+       int                      o_daemonize;
        int                      o_dry_run;
        int                      o_abort_on_error;
        int                      o_shadow_tree;
@@ -125,7 +125,7 @@ static void usage(const char *name, int rc)
        "to copy files to and from an HSM archive system.\n"
        "This POSIX-flavored daemon makes regular POSIX filesystem calls\n"
        "to an HSM mounted at a given hsm_root.\n"
-       "   -d, --daemon        Daemon mode, run in background\n"
+       "   --daemon            Daemon mode, run in background\n"
        " Options:\n"
        "   --no-attr           Don't copy file attributes\n"
        "   --no-shadow         Don't create shadow namespace in archive\n"
@@ -172,7 +172,7 @@ static int ct_parseopts(int argc, char * const *argv)
                {"bandwidth",      required_argument, NULL,                'b'},
                {"chunk-size",     required_argument, NULL,                'c'},
                {"chunk_size",     required_argument, NULL,                'c'},
-               {"daemon",         no_argument,       NULL,                'd'},
+               {"daemon",         no_argument,       &opt.o_daemonize,     1},
                {"dry-run",        no_argument,       &opt.o_dry_run,       1},
                {"help",           no_argument,       NULL,                'h'},
                {"hsm-root",       required_argument, NULL,                'p'},
@@ -197,7 +197,7 @@ static int ct_parseopts(int argc, char * const *argv)
        unsigned long long       unit;
 
        optind = 0;
-       while ((c = getopt_long(argc, argv, "A:b:c:dhiMp:qruv",
+       while ((c = getopt_long(argc, argv, "A:b:c:hiMp:qrv",
                                long_opts, NULL)) != -1) {
                switch (c) {
                case 'A':
@@ -222,9 +222,6 @@ static int ct_parseopts(int argc, char * const *argv)
                        else
                                opt.o_bandwidth = value;
                        break;
-               case 'd':
-                       opt.o_action = CA_DAEMON;
-                       break;
                case 'h':
                        usage(argv[0], 0);
                case 'i':
@@ -329,10 +326,11 @@ static int ct_mkdir_p(const char *path)
                rc = mkdir(saved, DIR_PERM);
                *ptr = '/';
                if (rc < 0 && errno != EEXIST) {
+                       rc = -errno;
                        CT_ERROR("'%s' mkdir failed (%s)\n", path,
-                                strerror(errno));
+                                strerror(-rc));
                        free(saved);
-                       return -errno;
+                       return rc;
                }
                ptr++;
        }
@@ -357,9 +355,10 @@ static int ct_save_stripe(int src_fd, const char *src, const char *dst)
        xattr_size = fgetxattr(src_fd, XATTR_LUSTRE_LOV, lov_buf,
                               sizeof(lov_buf));
        if (xattr_size < 0) {
+               rc = -errno;
                CT_ERROR("'%s' cannot get stripe info on (%s)\n", src,
-                        strerror(errno));
-               return -errno;
+                        strerror(-rc));
+               return rc;
        }
 
        lum = (struct lov_user_md *)lov_buf;
@@ -373,29 +372,36 @@ static int ct_save_stripe(int src_fd, const char *src, const char *dst)
 
        fd = open(lov_file, O_TRUNC | O_CREAT | O_WRONLY, FILE_PERM);
        if (fd < 0) {
-               CT_ERROR("'%s' cannot open (%s)\n", lov_file, strerror(errno));
-               return -errno;
+               rc = -errno;
+               CT_ERROR("'%s' cannot open (%s)\n", lov_file, strerror(-rc));
+               goto err_cleanup;
        }
 
        rc = write(fd, lum, xattr_size);
        if (rc < 0) {
-               CT_ERROR("'%s' cannot write %d bytes (%s)\n",
-                        lov_file, xattr_size, strerror(errno));
+               rc = -errno;
+               CT_ERROR("'%s' cannot write %zd bytes (%s)\n",
+                        lov_file, xattr_size, strerror(-rc));
                close(fd);
-               return -errno;
+               goto err_cleanup;
        }
 
        rc = close(fd);
        if (rc < 0) {
-               CT_ERROR("'%s' cannot close (%s)\n", lov_file, strerror(errno));
-               return -errno;
+               rc = -errno;
+               CT_ERROR("'%s' cannot close (%s)\n", lov_file, strerror(-rc));
+               goto err_cleanup;
        }
 
        return 0;
+
+err_cleanup:
+       unlink(lov_file);
+
+       return rc;
 }
 
-static int ct_load_stripe(const char *src, struct lov_user_md_v3 *lum,
-                         size_t *lum_size)
+static int ct_load_stripe(const char *src, void *lovea, size_t *lovea_size)
 {
        char     lov_file[PATH_MAX];
        int      rc;
@@ -410,41 +416,34 @@ static int ct_load_stripe(const char *src, struct lov_user_md_v3 *lum,
                return -ENODATA;
        }
 
-       rc = read(fd, lum, *lum_size);
+       rc = read(fd, lovea, *lovea_size);
        if (rc < 0) {
-               CT_ERROR("'%s' cannot read %lu bytes (%s)\n", lov_file,
-                        lum_size, strerror(errno));
+               CT_ERROR("'%s' cannot read %zu bytes (%s)\n", lov_file,
+                        *lovea_size, strerror(errno));
                close(fd);
                return -ENODATA;
        }
 
-       *lum_size = (size_t)rc;
+       *lovea_size = rc;
        close(fd);
 
        return 0;
 }
 
-static int ct_restore_stripe(const char *src, const char *dst, int dst_fd)
+static int ct_restore_stripe(const char *src, const char *dst, int dst_fd,
+                            const void *lovea, size_t lovea_size)
 {
-       int                      rc;
-       char                     lov_buf[XATTR_SIZE_MAX];
-       size_t                   lum_size = sizeof(lov_buf);
-
-       rc = ct_load_stripe(src, (struct lov_user_md_v3 *)lov_buf, &lum_size);
-       if (rc) {
-               CT_WARN("'%s' cannot get stripe rules (%s), use default\n",
-                       src, strerror(-rc));
-               return 0;
-       }
+       int     rc;
 
-       rc = fsetxattr(dst_fd, XATTR_LUSTRE_LOV, lov_buf, lum_size, XATTR_CREATE);
+       rc = fsetxattr(dst_fd, XATTR_LUSTRE_LOV, lovea, lovea_size,
+                      XATTR_CREATE);
        if (rc < 0) {
                CT_ERROR("'%s' cannot set striping (%s)\n",
                         dst, strerror(errno));
-               return -errno;
+               rc = -errno;
        }
 
-       return 0;
+       return rc;
 }
 
 /* non-blocking read or write */
@@ -552,7 +551,7 @@ static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src,
        he.offset = hai->hai_extent.offset;
        he.length = 0;
        rc = llapi_hsm_action_progress(hcp, &he, 0);
-       if (rc) {
+       if (rc < 0) {
                /* Action has been canceled or something wrong
                 * is happening. Stop copying data. */
                CT_ERROR("%s->'%s' progress returned err %d\n", src, dst, rc);
@@ -648,7 +647,7 @@ static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src,
                        CT_TRACE("%%"LPU64" ", 100 * wpos / rlen);
                        he.length = wpos;
                        rc = llapi_hsm_action_progress(hcp, &he, 0);
-                       if (rc) {
+                       if (rc < 0) {
                                /* Action has been canceled or something wrong
                                 * is happening. Stop copying data. */
                                CT_ERROR("%s->'%s' progress returned err %d\n",
@@ -715,10 +714,12 @@ static int ct_copy_attr(const char *src, const char *dst, int src_fd,
        times[1].tv_usec = 0;
        if (fchmod(dst_fd, st.st_mode) < 0 ||
            fchown(dst_fd, st.st_uid, st.st_gid) < 0 ||
-           futimes(dst_fd, times) < 0)
+           futimes(dst_fd, times) < 0) {
                CT_ERROR("'%s' fchmod fchown or futimes failed (%s)\n", src,
                         strerror(errno));
                return -errno;
+       }
+
        return 0;
 }
 
@@ -787,13 +788,15 @@ static bool ct_is_retryable(int err)
        return err == -ETIMEDOUT;
 }
 
-static int ct_begin(struct hsm_copyaction_private **phcp,
-                   const struct hsm_action_item *hai)
+static int ct_begin_restore(struct hsm_copyaction_private **phcp,
+                           const struct hsm_action_item *hai,
+                           int mdt_index, int open_flags)
 {
        char     src[PATH_MAX];
        int      rc;
 
-       rc = llapi_hsm_action_begin(phcp, ctdata, hai, false);
+       rc = llapi_hsm_action_begin(phcp, ctdata, hai, mdt_index, open_flags,
+                                   false);
        if (rc < 0) {
                ct_path_lustre(src, sizeof(src), opt.o_mnt, &hai->hai_fid);
                CT_ERROR("'%s' copy start failed (%s)\n", src, strerror(-rc));
@@ -802,6 +805,14 @@ static int ct_begin(struct hsm_copyaction_private **phcp,
        return rc;
 }
 
+static int ct_begin(struct hsm_copyaction_private **phcp,
+                   const struct hsm_action_item *hai)
+{
+       /* Restore takes specific parameters. Call the same function w/ default
+        * values for all other operations. */
+       return ct_begin_restore(phcp, hai, -1, 0);
+}
+
 static int ct_fini(struct hsm_copyaction_private **phcp,
                   const struct hsm_action_item *hai, int flags, int ct_rc)
 {
@@ -1064,16 +1075,17 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags)
        struct hsm_copyaction_private   *hcp = NULL;
        char                             src[PATH_MAX];
        char                             dst[PATH_MAX];
+       char                             lov_buf[XATTR_SIZE_MAX];
+       size_t                           lov_size = sizeof(lov_buf);
        int                              rc;
        int                              flags = 0;
        int                              src_fd = -1;
        int                              dst_fd = -1;
+       int                              mdt_index = -1; /* Not implemented */
+       int                              open_flags = 0;
+       bool                             set_lovea;
        lustre_fid                       dfid;
 
-       rc = ct_begin(&hcp, hai);
-       if (rc)
-               goto fini;
-
        /* we fill lustre so:
         * source = lustre FID in the backend
         * destination = data FID = volatile file
@@ -1082,6 +1094,22 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags)
        /* build backend file name from released file FID */
        ct_path_archive(src, sizeof(src), opt.o_hsm_root, &hai->hai_fid);
 
+       /* restore loads and sets the LOVEA w/o interpreting it to avoid
+        * dependency on the structure format. */
+       rc = ct_load_stripe(src, lov_buf, &lov_size);
+       if (rc < 0) {
+               CT_WARN("'%s' cannot get stripe rules (%s), use default\n",
+                       src, strerror(-rc));
+               set_lovea = false;
+       } else {
+               open_flags |= O_LOV_DELAY_CREATE;
+               set_lovea = true;
+       }
+
+       rc = ct_begin_restore(&hcp, hai, mdt_index, open_flags);
+       if (rc < 0)
+               goto fini;
+
        /* get the FID of the volatile file */
        rc = llapi_hsm_action_get_dfid(hcp, &dfid);
        if (rc < 0) {
@@ -1110,14 +1138,16 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags)
 
        dst_fd = llapi_hsm_action_get_fd(hcp);
 
-       /* the layout cannot be allocated through .fid so we have to
-        * restore a layout */
-       rc = ct_restore_stripe(src, dst, dst_fd);
-       if (rc) {
-               CT_ERROR("'%s' cannot restore file striping info from '%s'"
-                        " (%s)\n", dst, src, strerror(-rc));
-               err_major++;
-               goto fini;
+       if (set_lovea) {
+               /* the layout cannot be allocated through .fid so we have to
+                * restore a layout */
+               rc = ct_restore_stripe(src, dst, dst_fd, lov_buf, lov_size);
+               if (rc < 0) {
+                       CT_ERROR("'%s' cannot restore file striping info from "
+                                "'%s' (%s)\n", dst, src, strerror(-rc));
+                       err_major++;
+                       goto fini;
+               }
        }
 
        rc = ct_copy_data(hcp, src, dst, src_fd, dst_fd, hai, hal_flags);
@@ -1174,6 +1204,15 @@ static int ct_remove(const struct hsm_action_item *hai, const long hal_flags)
                goto fini;
        }
 
+       strncat(dst, ".lov", sizeof(dst) - strlen(dst) - 1);
+       rc = unlink(dst);
+       if (rc < 0) {
+               rc = -errno;
+               CT_ERROR("'%s' unlink failed (%s)\n", dst, strerror(-rc));
+               err_minor++;
+               goto fini;
+       }
+
 fini:
        if (hcp != NULL)
                rc = ct_fini(&hcp, hai, 0, rc);
@@ -1187,8 +1226,8 @@ static int ct_report_error(const struct hsm_action_item *hai, int flags,
        struct hsm_copyaction_private   *hcp;
        int                              rc;
 
-       rc = llapi_hsm_action_begin(&hcp, ctdata, hai, true);
-       if (rc)
+       rc = llapi_hsm_action_begin(&hcp, ctdata, hai, -1, 0, true);
+       if (rc < 0)
                return rc;
 
        rc = llapi_hsm_action_end(&hcp, &hai->hai_extent, flags, abs(errval));
@@ -1677,15 +1716,17 @@ static void handler(int signal)
 }
 
 /* Daemon waits for messages from the kernel; run it in the background. */
-static int ct_daemon(void)
+static int ct_run(void)
 {
        int     rc;
 
-       rc = daemon(1, 1);
-       if (rc < 0) {
-               CT_ERROR("%d: cannot start as daemon (%s)", getpid(),
-                        strerror(errno));
-               return -errno;
+       if (opt.o_daemonize) {
+               rc = daemon(1, 1);
+               if (rc < 0) {
+                       CT_ERROR("%d: cannot start as daemon (%s)", getpid(),
+                                strerror(errno));
+                       return -errno;
+               }
        }
 
        rc = llapi_hsm_copytool_register(&ctdata, opt.o_mnt, 0,
@@ -1737,7 +1778,7 @@ static int ct_daemon(void)
                                continue;
                }
 
-               hai = hai_zero(hal);
+               hai = hai_first(hal);
                while (++i <= hal->hal_count) {
                        if ((char *)hai - (char *)hal > msgsize) {
                                CT_ERROR("'%s' item %d past end of message!\n",
@@ -1781,7 +1822,7 @@ static int ct_setup(void)
        }
 
        rc = llapi_search_fsname(opt.o_mnt, fs_name);
-       if (rc) {
+       if (rc < 0) {
                CT_ERROR("cannot find a Lustre filesystem mounted at: %s\n",
                         opt.o_mnt);
                return -rc;
@@ -1809,7 +1850,7 @@ int main(int argc, char **argv)
 
        strncpy(cmd_name, basename(argv[0]), sizeof(cmd_name));
        rc = ct_parseopts(argc, argv);
-       if (rc) {
+       if (rc < 0) {
                CT_ERROR("try '%s --help' for more information.\n", cmd_name);
                return -rc;
        }
@@ -1826,13 +1867,8 @@ int main(int argc, char **argv)
        case CA_MAXSEQ:
                rc = ct_max_sequence();
                break;
-       case CA_DAEMON:
-               rc = ct_daemon();
-               break;
        default:
-               CT_ERROR("no action specified. Try '%s --help' for more "
-                        "information.\n", cmd_name);
-               rc = -EINVAL;
+               rc = ct_run();
                break;
        }