extern int libcfs_ukuc_start(lustre_kernelcomm *l, int groups);
extern int libcfs_ukuc_stop(lustre_kernelcomm *l);
extern int libcfs_ukuc_msg_get(lustre_kernelcomm *l, char *buf, int maxsize,
extern int libcfs_ukuc_start(lustre_kernelcomm *l, int groups);
extern int libcfs_ukuc_stop(lustre_kernelcomm *l);
extern int libcfs_ukuc_msg_get(lustre_kernelcomm *l, char *buf, int maxsize,
#endif /* __LIBCFS_KERNELCOMM_H__ */
#endif /* __LIBCFS_KERNELCOMM_H__ */
if (pipe(pfd) < 0)
return -errno;
if (pipe(pfd) < 0)
return -errno;
+ memset(link, 0, sizeof(*link));
link->lk_rfd = pfd[0];
link->lk_wfd = pfd[1];
link->lk_group = group;
link->lk_rfd = pfd[0];
link->lk_wfd = pfd[1];
link->lk_group = group;
* Allocates memory, returns handle
*
* @param link Private descriptor for pipe/socket.
* Allocates memory, returns handle
*
* @param link Private descriptor for pipe/socket.
- * @param buf Buffer to read into
+ * @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)
* @param maxsize Maximum message size allowed
* @param transport Only listen to messages on this transport
* (and the generic transport)
#ifdef __KERNEL__
{
loff_t offset = 0;
#ifdef __KERNEL__
{
loff_t offset = 0;
- rc = cfs_user_write(filp, (char *)payload, kuch->kuc_msglen,
+ rc = cfs_user_write(filp, (char *)payload, kuch->kuc_msglen,
time_t secs;
struct tm ts;
time_t secs;
struct tm ts;
- if (endrec && rec->cr_index > endrec)
+ if (endrec && rec->cr_index > endrec) {
+ llapi_changelog_free(&rec);
- if (rec->cr_index < startrec)
+ }
+ if (rec->cr_index < startrec) {
+ llapi_changelog_free(&rec);
secs = rec->cr_time >> 30;
gmtime_r(&secs, &ts);
secs = rec->cr_time >> 30;
gmtime_r(&secs, &ts);
int magic;
int flags;
lustre_kernelcomm kuc;
int magic;
int flags;
lustre_kernelcomm kuc;
};
/** Start reading from a changelog
};
/** Start reading from a changelog
int rc;
/* Set up the receiver control struct */
int rc;
/* Set up the receiver control struct */
- cp = malloc(sizeof(*cp));
+ cp = calloc(1, sizeof(*cp));
if (cp == NULL)
return -ENOMEM;
if (cp == NULL)
return -ENOMEM;
- cp->buf = malloc(CR_MAXSIZE);
- if (cp->buf == NULL) {
- rc = -ENOMEM;
- goto out_free;
- }
-
cp->magic = CHANGELOG_PRIV_MAGIC;
cp->flags = flags;
cp->magic = CHANGELOG_PRIV_MAGIC;
cp->flags = flags;
- if (cp->buf)
- free(cp->buf);
return -EINVAL;
libcfs_ukuc_stop(&cp->kuc);
return -EINVAL;
libcfs_ukuc_stop(&cp->kuc);
free(cp);
*priv = NULL;
return 0;
free(cp);
*priv = NULL;
return 0;
return -EINVAL;
if (rech == NULL)
return -EINVAL;
return -EINVAL;
if (rech == NULL)
return -EINVAL;
+ kuch = malloc(CR_MAXSIZE + sizeof(*kuch));
+ if (kuch == NULL)
+ return -ENOMEM;
- rc = libcfs_ukuc_msg_get(&cp->kuc, cp->buf, CR_MAXSIZE,
+ rc = libcfs_ukuc_msg_get(&cp->kuc, (char *)kuch,
+ CR_MAXSIZE + sizeof(*kuch),
KUC_TRANSPORT_CHANGELOG);
if (rc < 0)
KUC_TRANSPORT_CHANGELOG);
if (rc < 0)
- kuch = (struct kuc_hdr *)cp->buf;
if ((kuch->kuc_transport != KUC_TRANSPORT_CHANGELOG) ||
((kuch->kuc_msgtype != CL_RECORD) &&
(kuch->kuc_msgtype != CL_EOF))) {
if ((kuch->kuc_transport != KUC_TRANSPORT_CHANGELOG) ||
((kuch->kuc_msgtype != CL_RECORD) &&
(kuch->kuc_msgtype != CL_EOF))) {
- /* Our message is a changelog_rec */
+ /* Our message is a changelog_rec. Use pointer math to skip
+ * kuch_hdr and point directly to the message payload.
+ */
*rech = (struct changelog_rec *)(kuch + 1);
return 0;
out_free:
*rech = NULL;
*rech = (struct changelog_rec *)(kuch + 1);
return 0;
out_free:
*rech = NULL;
return rc;
}
/** Release the changelog record when done with it. */
int llapi_changelog_free(struct changelog_rec **rech)
{
return rc;
}
/** Release the changelog record when done with it. */
int llapi_changelog_free(struct changelog_rec **rech)
{
+ if (*rech) {
+ /* We allocated memory starting at the kuc_hdr, but passed
+ * the consumer a pointer to the payload.
+ * Use pointer math to get back to the header.
+ */
+ struct kuc_hdr *kuch = (struct kuc_hdr *)*rech - 1;
+ free(kuch);
+ }
*rech = NULL;
return 0;
}
*rech = NULL;
return 0;
}
#define CT_PRIV_MAGIC 0xC0BE2001
struct copytool_private {
int magic;
#define CT_PRIV_MAGIC 0xC0BE2001
struct copytool_private {
int magic;
char *fsname;
lustre_kernelcomm kuc;
__u32 archives;
char *fsname;
lustre_kernelcomm kuc;
__u32 archives;
- ct = malloc(sizeof(*ct));
+ ct = calloc(1, sizeof(*ct));
if (ct == NULL)
return -ENOMEM;
if (ct == NULL)
return -ENOMEM;
- ct->buf = malloc(HAL_MAXSIZE);
ct->fsname = malloc(strlen(fsname) + 1);
ct->fsname = malloc(strlen(fsname) + 1);
- if (ct->buf == NULL || ct->fsname == NULL) {
+ if (ct->fsname == NULL) {
rc = -ENOMEM;
goto out_err;
}
rc = -ENOMEM;
goto out_err;
}
- if (ct->buf)
- free(ct->buf);
if (ct->fsname)
free(ct->fsname);
free(ct);
if (ct->fsname)
free(ct->fsname);
free(ct);
/* Shut down the kernelcomms */
libcfs_ukuc_stop(&ct->kuc);
/* Shut down the kernelcomms */
libcfs_ukuc_stop(&ct->kuc);
free(ct->fsname);
free(ct);
*priv = NULL;
free(ct->fsname);
free(ct);
*priv = NULL;
if (halh == NULL || msgsize == NULL)
return -EINVAL;
if (halh == NULL || msgsize == NULL)
return -EINVAL;
- rc = libcfs_ukuc_msg_get(&ct->kuc, ct->buf, HAL_MAXSIZE,
+ kuch = malloc(HAL_MAXSIZE + sizeof(*kuch));
+ if (kuch == NULL)
+ return -ENOMEM;
+
+ rc = libcfs_ukuc_msg_get(&ct->kuc, (char *)kuch,
+ HAL_MAXSIZE + sizeof(*kuch),
KUC_TRANSPORT_HSM);
if (rc < 0)
KUC_TRANSPORT_HSM);
if (rc < 0)
/* Handle generic messages */
/* Handle generic messages */
- kuch = (struct kuc_hdr *)ct->buf;
if (kuch->kuc_transport == KUC_TRANSPORT_GENERIC &&
kuch->kuc_msgtype == KUC_MSG_SHUTDOWN) {
rc = -ESHUTDOWN;
if (kuch->kuc_transport == KUC_TRANSPORT_GENERIC &&
kuch->kuc_msgtype == KUC_MSG_SHUTDOWN) {
rc = -ESHUTDOWN;
- /* Our message is an hsm_action_list */
-
+ /* 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 # */
hal = (struct hsm_action_list *)(kuch + 1);
/* Check that we have registered for this archive # */
out_free:
*halh = NULL;
*msgsize = 0;
out_free:
*halh = NULL;
*msgsize = 0;
return rc;
}
/** Release the action list when done with it. */
int llapi_copytool_free(struct hsm_action_list **hal)
{
return rc;
}
/** Release the action list when done with it. */
int llapi_copytool_free(struct hsm_action_list **hal)
{
- *hal = NULL;
- return 0;
+ /* Reuse the llapi_changelog_free function */
+ return llapi_changelog_free((struct changelog_rec **)hal);
}
int llapi_get_connect_flags(const char *mnt, __u64 *flags)
}
int llapi_get_connect_flags(const char *mnt, __u64 *flags)