/** Read a message from the link.
 * Allocates memory, returns handle
 *
 * @param link Private descriptor for pipe/socket.
 * @param buf Buffer to read into, must include size for kuc_hdr
 * @param maxsize Maximum message size allowed
 * @param transport Only listen to messages on this transport
 *      (and the generic transport)
 */
int libcfs_ukuc_msg_get(struct lustre_kernelcomm *link, char *buf, int maxsize,
			int transport)
{
	struct kuc_hdr *kuch;
	int rc = 0;

	memset(buf, 0, maxsize);

	while (1) {
		/* Read header first to get message size */
		rc = read(link->lk_rfd, buf, lhsz);
		if (rc <= 0) {
			rc = -errno;
			break;
		}
		kuch = (struct kuc_hdr *)buf;

		if (kuch->kuc_magic != KUC_MAGIC) {
			llapi_err_noerrno(LLAPI_MSG_ERROR,
					  "bad message magic %x != %x\n",
					  kuch->kuc_magic, KUC_MAGIC);
			rc = -EPROTO;
			break;
		}

		if (kuch->kuc_msglen > maxsize) {
			rc = -EMSGSIZE;
			break;
		}

		/* Read payload */
		rc = read(link->lk_rfd, buf + lhsz, kuch->kuc_msglen - lhsz);
		if (rc < 0) {
			rc = -errno;
			break;
		}
		if (rc < (kuch->kuc_msglen - lhsz)) {
			llapi_err_noerrno(LLAPI_MSG_ERROR,
					  "short read: got %d of %d bytes\n",
					  rc, kuch->kuc_msglen);
			rc = -EPROTO;
			break;
		}

		if (kuch->kuc_transport == transport ||
		    kuch->kuc_transport == KUC_TRANSPORT_GENERIC) {
			return 0;
		}
		/* Drop messages for other transports */
	}
	return rc;
}
Пример #2
0
/* Returns bytes read on success and a negative value on failure.
 * If zero bytes are read it will be treated as failure as such
 * zero cannot be returned from this function.
 */
int read_proc_entry(char *proc_path, char *buf, int len)
{
	int rc, fd;

	memset(buf, 0, len);

	fd = open(proc_path, O_RDONLY);
	if (fd < 0) {
		llapi_error(LLAPI_MSG_ERROR, -errno, "cannot open '%s'",
			    proc_path);
		return -2;
	}

	rc = read(fd, buf, len - 1);
	if (rc < 0) {
		llapi_error(LLAPI_MSG_ERROR, -errno,
			    "error reading from '%s'", proc_path);
		rc = -3;
	} else if (rc == 0) {
		llapi_err_noerrno(LLAPI_MSG_ERROR,
				  "read zero bytes from '%s'", proc_path);
		rc = -4;
	} else if (buf[rc - 1] == '\n') {
		buf[rc - 1] = '\0'; /* Remove trailing newline */
	}

	close(fd);

	return rc;
}
Пример #3
0
int compare_lum(struct obd_uuid *puuid, struct lov_user_md *lum_dir,
		struct lov_user_md *lum_file1, struct lov_user_md *lum_file2)
{
	struct lov_comp_md_v1 *comp_dir, *comp_file1;
	struct lov_user_md *sub_dir, *sub_file1;
	int i, rc = 0;

	if (lum_dir == NULL || lum_dir->lmm_magic != LOV_MAGIC_COMP_V1)
		return compare(puuid, lum_dir, lum_file1, lum_file2);

	comp_dir = (struct lov_comp_md_v1 *)lum_dir;
	comp_file1 = (struct lov_comp_md_v1 *)lum_file1;

	if (lum_file1->lmm_magic != lum_dir->lmm_magic) {
		llapi_err_noerrno(LLAPI_MSG_ERROR, "file1 magic %#x != %#x\n",
				  lum_file1->lmm_magic, lum_dir->lmm_magic);
		return 10;
	}

	if (comp_file1->lcm_entry_count != comp_dir->lcm_entry_count) {
		llapi_err_noerrno(LLAPI_MSG_ERROR, "file1 comp cnt %d != %d\n",
				  comp_file1->lcm_entry_count,
				  comp_dir->lcm_entry_count);
		return 11;
	}

	for (i = 0; i < comp_dir->lcm_entry_count; i++) {
		sub_dir = (struct lov_user_md *)((char *)comp_dir +
				comp_dir->lcm_entries[i].lcme_offset);
		sub_file1 = (struct lov_user_md *)((char *)comp_file1 +
				comp_file1->lcm_entries[i].lcme_offset);

		rc = compare(puuid, sub_dir, sub_file1, NULL);
		if (rc)
			break;
	}

	return rc;
}
Пример #4
0
static inline const char *llapi_hsm_ct_ev2str(int type)
{
	switch (type) {
	case CT_REGISTER:
		return "REGISTER";
	case CT_UNREGISTER:
		return "UNREGISTER";
	case CT_ARCHIVE_START:
		return "ARCHIVE_START";
	case CT_ARCHIVE_RUNNING:
		return "ARCHIVE_RUNNING";
	case CT_ARCHIVE_FINISH:
		return "ARCHIVE_FINISH";
	case CT_ARCHIVE_CANCEL:
		return "ARCHIVE_CANCEL";
	case CT_ARCHIVE_ERROR:
		return "ARCHIVE_ERROR";
	case CT_RESTORE_START:
		return "RESTORE_START";
	case CT_RESTORE_RUNNING:
		return "RESTORE_RUNNING";
	case CT_RESTORE_FINISH:
		return "RESTORE_FINISH";
	case CT_RESTORE_CANCEL:
		return "RESTORE_CANCEL";
	case CT_RESTORE_ERROR:
		return "RESTORE_ERROR";
	case CT_REMOVE_START:
		return "REMOVE_START";
	case CT_REMOVE_RUNNING:
		return "REMOVE_RUNNING";
	case CT_REMOVE_FINISH:
		return "REMOVE_FINISH";
	case CT_REMOVE_CANCEL:
		return "REMOVE_CANCEL";
	case CT_REMOVE_ERROR:
		return "REMOVE_ERROR";
	default:
		llapi_err_noerrno(LLAPI_MSG_ERROR,
				  "Unknown event type: %d", type);
		return NULL;
	}
}
Пример #5
0
/** Wait for the next hsm_action_list
 * \param ct Opaque private control structure
 * \param halh Action list handle, will be allocated here
 * \param msgsize Number of bytes in the message, will be set here
 * \return 0 valid message received; halh and msgsize are set
 *	   <0 error code
 * Note: The application must not call llapi_hsm_copytool_recv until it has
 * cleared the data in ct->kuch from the previous call.
 */
int llapi_hsm_copytool_recv(struct hsm_copytool_private *ct,
			    struct hsm_action_list **halh, int *msgsize)
{
	struct kuc_hdr		*kuch;
	struct hsm_action_list	*hal;
	int			 rc = 0;

	if (ct == NULL || ct->magic != CT_PRIV_MAGIC)
		return -EINVAL;

	if (halh == NULL || msgsize == NULL)
		return -EINVAL;

	kuch = ct->kuch;

repeat:
	rc = libcfs_ukuc_msg_get(&ct->kuc, (char *)kuch,
				 HAL_MAXSIZE + sizeof(*kuch),
				 KUC_TRANSPORT_HSM);
	if (rc < 0)
		goto out_err;

	/* Handle generic messages */
	if (kuch->kuc_transport == KUC_TRANSPORT_GENERIC &&
	    kuch->kuc_msgtype == KUC_MSG_SHUTDOWN) {
		rc = -ESHUTDOWN;
		goto out_err;
	}

	if (kuch->kuc_transport != KUC_TRANSPORT_HSM ||
	    kuch->kuc_msgtype != HMT_ACTION_LIST) {
		llapi_err_noerrno(LLAPI_MSG_ERROR,
				  "Unknown HSM message type %d:%d\n",
				  kuch->kuc_transport, kuch->kuc_msgtype);
		rc = -EPROTO;
		goto out_err;
	}

	if (kuch->kuc_msglen < sizeof(*kuch) + sizeof(*hal)) {
		llapi_err_noerrno(LLAPI_MSG_ERROR, "Short HSM message %d",
				  kuch->kuc_msglen);
		rc = -EPROTO;
		goto out_err;
	}

	/* Our message is a hsm_action_list. Use pointer math to skip
	* kuch_hdr and point directly to the message payload.
	*/
	hal = (struct hsm_action_list *)(kuch + 1);

	/* Check that we have registered for this archive #
	 * if 0 registered, we serve any archive */
	if (ct->archives &&
	    ((1 << (hal->hal_archive_id - 1)) & ct->archives) == 0) {
		llapi_err_noerrno(LLAPI_MSG_INFO,
				  "This copytool does not service archive #%d,"
				  " ignoring this request."
				  " Mask of served archive is 0x%.8X",
				  hal->hal_archive_id, ct->archives);

		goto repeat;
	}

	*halh = hal;
	*msgsize = kuch->kuc_msglen - sizeof(*kuch);
	return 0;

out_err:
	*halh = NULL;
	*msgsize = 0;
	return rc;
}
Пример #6
0
/** Register a copytool
 * \param[out] priv		Opaque private control structure
 * \param mnt			Lustre filesystem mount point
 * \param archive_count		Number of valid archive IDs in \a archives
 * \param archives		Which archive numbers this copytool is
 *				responsible for
 * \param rfd_flags		flags applied to read fd of pipe
 *				(e.g. O_NONBLOCK)
 *
 * \retval 0 on success.
 * \retval -errno on error.
 */
int llapi_hsm_copytool_register(struct hsm_copytool_private **priv,
				const char *mnt, int archive_count,
				int *archives, int rfd_flags)
{
	struct hsm_copytool_private	*ct;
	int				 rc;

	if (archive_count > 0 && archives == NULL) {
		llapi_err_noerrno(LLAPI_MSG_ERROR,
				  "NULL archive numbers");
		return -EINVAL;
	}

	if (archive_count > LL_HSM_MAX_ARCHIVE) {
		llapi_err_noerrno(LLAPI_MSG_ERROR, "%d requested when maximum "
				  "of %zu archives supported", archive_count,
				  LL_HSM_MAX_ARCHIVE);
		return -EINVAL;
	}

	ct = calloc(1, sizeof(*ct));
	if (ct == NULL)
		return -ENOMEM;

	ct->magic = CT_PRIV_MAGIC;
	ct->mnt_fd = -1;
	ct->open_by_fid_fd = -1;
	ct->kuc.lk_rfd = LK_NOFD;
	ct->kuc.lk_wfd = LK_NOFD;

	ct->mnt = strdup(mnt);
	if (ct->mnt == NULL) {
		rc = -ENOMEM;
		goto out_err;
	}

	ct->kuch = malloc(HAL_MAXSIZE + sizeof(*ct->kuch));
	if (ct->kuch == NULL) {
		rc = -ENOMEM;
		goto out_err;
	}

	ct->mnt_fd = open(ct->mnt, O_RDONLY);
	if (ct->mnt_fd < 0) {
		rc = -errno;
		goto out_err;
	}

	ct->open_by_fid_fd = openat(ct->mnt_fd, OPEN_BY_FID_PATH, O_RDONLY);
	if (ct->open_by_fid_fd < 0) {
		rc = -errno;
		goto out_err;
	}

	/* no archives specified means "match all". */
	ct->archives = 0;
	for (rc = 0; rc < archive_count; rc++) {
		if ((archives[rc] > LL_HSM_MAX_ARCHIVE) || (archives[rc] < 0)) {
			llapi_err_noerrno(LLAPI_MSG_ERROR, "%d requested when "
					  "archive id [0 - %zu] is supported",
					  archives[rc], LL_HSM_MAX_ARCHIVE);
			rc = -EINVAL;
			goto out_err;
		}
		/* in the list we have an all archive wildcard
		 * so move to all archives mode
		 */
		if (archives[rc] == 0) {
			ct->archives = 0;
			archive_count = 0;
			break;
		}
		ct->archives |= (1 << (archives[rc] - 1));
	}

	rc = libcfs_ukuc_start(&ct->kuc, KUC_GRP_HSM, rfd_flags);
	if (rc < 0)
		goto out_err;

	/* Storing archive(s) in lk_data; see mdc_ioc_hsm_ct_start */
	ct->kuc.lk_data = ct->archives;
	rc = ioctl(ct->mnt_fd, LL_IOC_HSM_CT_START, &ct->kuc);
	if (rc < 0) {
		rc = -errno;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "cannot start copytool on '%s'", mnt);
		goto out_kuc;
	}

	llapi_hsm_log_ct_registration(&ct, CT_REGISTER);

	/* Only the kernel reference keeps the write side open */
	close(ct->kuc.lk_wfd);
	ct->kuc.lk_wfd = LK_NOFD;
	*priv = ct;

	return 0;

out_kuc:
	/* cleanup the kuc channel */
	libcfs_ukuc_stop(&ct->kuc);

out_err:
	if (!(ct->mnt_fd < 0))
		close(ct->mnt_fd);

	if (!(ct->open_by_fid_fd < 0))
		close(ct->open_by_fid_fd);

	free(ct->mnt);

	free(ct->kuch);

	free(ct);

	return rc;
}
Пример #7
0
int compare(struct obd_uuid *puuid, struct lov_user_md *lum_dir,
	    struct lov_user_md *lum_file1, struct lov_user_md *lum_file2)
{
	int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
	int stripe_size = 0;
	int stripe_offset = -1;
	int ost_count;
	char buf[128];
	glob_t path;
	int i;

	if (cfs_get_param_paths(&path, "lov/%s/stripecount", puuid->uuid) != 0)
		return 2;
	if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
		cfs_free_param_data(&path);
                return 5;
	}
	cfs_free_param_data(&path);
	def_stripe_count = (short)atoi(buf);

	if (cfs_get_param_paths(&path, "lov/%s/numobd", puuid->uuid) != 0)
		return 2;
	if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
		cfs_free_param_data(&path);
                return 6;
	}
	cfs_free_param_data(&path);
        ost_count = atoi(buf);

        if (lum_dir == NULL) {
                stripe_count = def_stripe_count;
                min_stripe_count = -1;
        } else {
                stripe_count = (signed short)lum_dir->lmm_stripe_count;
                printf("dir stripe %d, ", stripe_count);
                min_stripe_count = 1;
        }

        printf("default stripe %d, ost count %d\n",
               def_stripe_count, ost_count);

        if (stripe_count == 0) {
                min_stripe_count = -1;
                stripe_count = 1;
        }

        stripe_count = (stripe_count > 0 && stripe_count <= ost_count) ?
                                                stripe_count : ost_count;
        min_stripe_count = min_stripe_count > 0 ? stripe_count :
                                                ((stripe_count + 1) / 2);

        if (lum_file1->lmm_stripe_count != stripe_count ||
            lum_file1->lmm_stripe_count < min_stripe_count) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "file1 stripe count %d != dir %d\n",
                                  lum_file1->lmm_stripe_count, stripe_count);
                return 7;
        }

        if (lum_file1->lmm_stripe_count < stripe_count)
                llapi_err_noerrno(LLAPI_MSG_WARN,
                                  "warning: file1 used fewer stripes"
                                  " %d < dir %d (likely due to bug 4900)\n",
                                  lum_file1->lmm_stripe_count, stripe_count);

        if (lum_dir != NULL)
                stripe_size = (int)lum_dir->lmm_stripe_size;
        if (stripe_size == 0) {
		if (cfs_get_param_paths(&path, "lov/%s/stripesize",
					puuid->uuid) != 0)
			return 2;
		if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
			cfs_free_param_data(&path);
			return 5;
		}
		cfs_free_param_data(&path);

                stripe_size = atoi(buf);
        }

        if (lum_file1->lmm_stripe_size != stripe_size) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "file1 stripe size %d != dir %d\n",
                                  lum_file1->lmm_stripe_size, stripe_size);
                return 8;
        }

        if (lum_dir != NULL)
                stripe_offset = (short int)lum_dir->lmm_stripe_offset;
        if (stripe_offset != -1) {
                for (i = 0; i < stripe_count; i++)
                        if (lum_file1->lmm_objects[i].l_ost_idx !=
                            (stripe_offset + i) % ost_count) {
                                llapi_err_noerrno(LLAPI_MSG_WARN,
                                          "warning: file1 non-sequential "
                                          "stripe[%d] %d != %d\n", i,
                                          lum_file1->lmm_objects[i].l_ost_idx,
                                          (stripe_offset + i) % ost_count);
                        }
        } else if (lum_file2 != NULL) {
                int next, idx, stripe = stripe_count - 1;
                next = (lum_file1->lmm_objects[stripe].l_ost_idx + 1) %
                       ost_count;
                idx = lum_file2->lmm_objects[0].l_ost_idx;
                if (idx != next) {
                        llapi_err_noerrno(LLAPI_MSG_WARN,
                                  "warning: non-sequential "
                                  "file1 stripe[%d] %d != file2 stripe[0] %d\n",
                                  stripe, lum_file1->lmm_objects[stripe].l_ost_idx,
                                  idx);
                }
        }

        return 0;
}
Пример #8
0
int main(int argc, char **argv)
{
	struct lov_user_md *lum_dir, *lum_file1 = NULL, *lum_file2 = NULL;
	struct obd_uuid uuid;
	int lum_size, rc;
	DIR *dir;

	if (argc < 3) {
		llapi_err_noerrno(LLAPI_MSG_ERROR,
				  "Usage: %s <dirname> <filename1> [filename2]\n",
				  argv[0]);
		return 1;
	}

	dir = opendir(argv[1]);
	if (dir == NULL) {
		rc = -errno;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: %s opendir failed", argv[1]);
		return rc;
	}

	lum_size = lov_user_md_size(MAX_LOV_UUID_COUNT, LOV_USER_MAGIC);
	lum_dir = (struct lov_user_md *)malloc(lum_size);
	if (lum_dir == NULL) {
		rc = -ENOMEM;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: can't allocate %d bytes "
			    "for dir EA", lum_size);
		goto cleanup;
	}

	rc = llapi_file_get_stripe(argv[1], lum_dir);
	if (rc == -ENODATA) {
		char root[PATH_MAX], path[PATH_MAX + 2];

		rc = llapi_search_mounts(argv[1], 0, root, NULL);
		if (rc) {
			llapi_error(LLAPI_MSG_ERROR, rc, "error: can't get "
				    "root path for %s\n", argv[1]);
			goto cleanup;
		}

		snprintf(path, sizeof(path), "%s/.", root);
		rc = llapi_file_get_stripe(path, lum_dir);
		if (rc == -ENODATA) {
			free(lum_dir);
			lum_dir = NULL;
		} else if (rc) {
			llapi_error(LLAPI_MSG_ERROR, rc, "error: cant't get "
				    "root's LOVEA for %s\n", path);
			goto cleanup;
		}
	} else if (rc) {
		llapi_error(LLAPI_MSG_ERROR, rc, "error: can't get LOVEA for "
			    "%s", argv[1]);
		goto cleanup;
	}

	/* XXX should be llapi_lov_getname() */
	rc = llapi_file_get_lov_uuid(argv[1], &uuid);
	if (rc) {
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: can't get lov name for %s",
			    argv[1]);
		return rc;
	}

	lum_file1 = malloc(lum_size);
	if (lum_file1 == NULL) {
		rc = -ENOMEM;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: can't allocate %d bytes for EA",
			    lum_size);
		goto cleanup;
	}

	rc = llapi_file_get_stripe(argv[2], lum_file1);
	if (rc) {
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: unable to get EA for %s", argv[2]);
		goto cleanup;
	}

	if (argc == 4) {
		lum_file2 = (struct lov_user_md *)malloc(lum_size);
		if (lum_file2 == NULL) {
			rc = -ENOMEM;
			llapi_error(LLAPI_MSG_ERROR, rc,
				    "error: can't allocate %d "
				    "bytes for file2 EA", lum_size);
			goto cleanup;
		}

		rc = llapi_file_get_stripe(argv[3], lum_file2);
		if (rc) {
			llapi_error(LLAPI_MSG_ERROR, rc,
				    "error: can't get EA for %s", argv[3]);
			goto cleanup;
		}
	}

	rc = compare_lum(&uuid, lum_dir, lum_file1, lum_file2);

cleanup:
	closedir(dir);
	if (lum_dir != NULL)
		free(lum_dir);
	if (lum_file1 != NULL)
		free(lum_file1);
	if (lum_file2 != NULL)
		free(lum_file2);

	return rc;
}
Пример #9
0
int compare(struct lov_user_md *lum_dir, struct lov_user_md *lum_file1,
            struct lov_user_md *lum_file2)
{
        int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
        int stripe_size = 0;
        int stripe_offset = -1;
        int ost_count;
        char buf[128];
        char lov_path[PATH_MAX];
        char tmp_path[PATH_MAX];
        int i;
        FILE *fp;

	fp = popen("\\ls -d  /proc/fs/lustre/lov/*clilov* | head -1", "r");
	if (fp == NULL) {
		llapi_error(LLAPI_MSG_ERROR, -errno,
			    "open(lustre/lov/*clilov*) failed");
		return 2;
        }

	if (fscanf(fp, "%s", lov_path) < 1) {
		llapi_error(LLAPI_MSG_ERROR, -EINVAL,
			    "read(lustre/lov/*clilov*) failed");
		pclose(fp);
		return 3;
	}

        pclose(fp);

        snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/stripecount",
                 lov_path);
        if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
                return 5;
        def_stripe_count = (short)atoi(buf);

        snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/numobd", lov_path);
        if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
                return 6;
        ost_count = atoi(buf);

        if (lum_dir == NULL) {
                stripe_count = def_stripe_count;
                min_stripe_count = -1;
        } else {
                stripe_count = (signed short)lum_dir->lmm_stripe_count;
                printf("dir stripe %d, ", stripe_count);
                min_stripe_count = 1;
        }

        printf("default stripe %d, ost count %d\n",
               def_stripe_count, ost_count);

        if (stripe_count == 0) {
                min_stripe_count = -1;
                stripe_count = 1;
        }

        stripe_count = (stripe_count > 0 && stripe_count <= ost_count) ?
                                                stripe_count : ost_count;
        min_stripe_count = min_stripe_count > 0 ? stripe_count :
                                                ((stripe_count + 1) / 2);

        if (lum_file1->lmm_stripe_count != stripe_count ||
            lum_file1->lmm_stripe_count < min_stripe_count) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "file1 stripe count %d != dir %d\n",
                                  lum_file1->lmm_stripe_count, stripe_count);
                return 7;
        }

        if (lum_file1->lmm_stripe_count < stripe_count)
                llapi_err_noerrno(LLAPI_MSG_WARN,
                                  "warning: file1 used fewer stripes"
                                  " %d < dir %d (likely due to bug 4900)\n",
                                  lum_file1->lmm_stripe_count, stripe_count);

        if (lum_dir != NULL)
                stripe_size = (int)lum_dir->lmm_stripe_size;
        if (stripe_size == 0) {
                snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/stripesize",
                         lov_path);
                if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
                        return 5;

                stripe_size = atoi(buf);
        }

        if (lum_file1->lmm_stripe_size != stripe_size) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "file1 stripe size %d != dir %d\n",
                                  lum_file1->lmm_stripe_size, stripe_size);
                return 8;
        }

        if (lum_dir != NULL)
                stripe_offset = (short int)lum_dir->lmm_stripe_offset;
        if (stripe_offset != -1) {
                for (i = 0; i < stripe_count; i++)
                        if (lum_file1->lmm_objects[i].l_ost_idx !=
                            (stripe_offset + i) % ost_count) {
                                llapi_err_noerrno(LLAPI_MSG_WARN,
                                          "warning: file1 non-sequential "
                                          "stripe[%d] %d != %d\n", i,
                                          lum_file1->lmm_objects[i].l_ost_idx,
                                          (stripe_offset + i) % ost_count);
                        }
        } else if (lum_file2 != NULL) {
                int next, idx, stripe = stripe_count - 1;
                next = (lum_file1->lmm_objects[stripe].l_ost_idx + 1) %
                       ost_count;
                idx = lum_file2->lmm_objects[0].l_ost_idx;
                if (idx != next) {
                        llapi_err_noerrno(LLAPI_MSG_WARN,
                                  "warning: non-sequential "
                                  "file1 stripe[%d] %d != file2 stripe[0] %d\n",
                                  stripe, lum_file1->lmm_objects[stripe].l_ost_idx,
                                  idx);
                }
        }

        return 0;
}
Пример #10
0
int main(int argc, char **argv)
{
        DIR * dir;
        struct lov_user_md *lum_dir, *lum_file1 = NULL, *lum_file2 = NULL;
        int rc;
        int lum_size;

        if (argc < 3) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                "Usage: %s <dirname> <filename1> [filename2]\n",
                                argv[0]);
                return 1;
        }

	dir = opendir(argv[1]);
	if (dir == NULL) {
		rc = -errno;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: %s opendir failed", argv[1]);
		return rc;
	}

	lum_size = lov_user_md_size(MAX_LOV_UUID_COUNT, LOV_USER_MAGIC);
	lum_dir = (struct lov_user_md *)malloc(lum_size);
	if (lum_dir == NULL) {
		rc = -ENOMEM;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: can't allocate %d bytes "
			    "for dir EA", lum_size);
		goto cleanup;
	}

	rc = llapi_file_get_stripe(argv[1], lum_dir);
	if (rc) {
		if (rc == -ENODATA) {
			free(lum_dir);
			lum_dir = NULL;
		} else {
			llapi_error(LLAPI_MSG_ERROR, rc,
				    "error: can't get EA for %s", argv[1]);
			goto cleanup;
		}
	}

	/* XXX should be llapi_lov_getname() */
	rc = llapi_file_get_lov_uuid(argv[1], &lov_uuid);
	if (rc) {
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: can't get lov name for %s",
			    argv[1]);
		return rc;
	}

	lum_file1 = malloc(lum_size);
	if (lum_file1 == NULL) {
		rc = -ENOMEM;
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: can't allocate %d bytes for EA",
			    lum_size);
		goto cleanup;
	}

	rc = llapi_file_get_stripe(argv[2], lum_file1);
	if (rc) {
		llapi_error(LLAPI_MSG_ERROR, rc,
			    "error: unable to get EA for %s", argv[2]);
		goto cleanup;
	}

	if (argc == 4) {
		lum_file2 = (struct lov_user_md *)malloc(lum_size);
		if (lum_file2 == NULL) {
			rc = -ENOMEM;
			llapi_error(LLAPI_MSG_ERROR, rc,
				    "error: can't allocate %d "
				    "bytes for file2 EA", lum_size);
			goto cleanup;
		}

		rc = llapi_file_get_stripe(argv[3], lum_file2);
		if (rc) {
			llapi_error(LLAPI_MSG_ERROR, rc,
				    "error: can't get EA for %s", argv[3]);
			goto cleanup;
		}
	}

	rc = compare(lum_dir, lum_file1, lum_file2);

cleanup:
        closedir(dir);
        if (lum_dir != NULL)
                free(lum_dir);
        if (lum_file1 != NULL)
                free(lum_file1);
        if (lum_file2 != NULL)
                free(lum_file2);

        return rc;
}