/** Get parent path from mount point and fid. * * \param mnt Filesystem root path. * \param fid Object FID. * \param parent Destination buffer. * \param parent_len Destination buffer size. * \return 0 on success. */ static int fid_parent(const char *mnt, const lustre_fid *fid, char *parent, size_t parent_len) { int rc; int linkno = 0; long long recno = -1; char file[PATH_MAX]; char strfid[FID_NOBRACE_LEN + 1]; char *ptr; snprintf(strfid, sizeof(strfid), DFID_NOBRACE, PFID(fid)); rc = llapi_fid2path(mnt, strfid, file, sizeof(file), &recno, &linkno); if (rc < 0) return rc; /* fid2path returns a relative path */ rc = snprintf(parent, parent_len, "%s/%s", mnt, file); if (rc >= parent_len) return -ENAMETOOLONG; /* remove file name */ ptr = strrchr(parent, '/'); if (ptr == NULL || ptr == parent) { rc = -EINVAL; } else { *ptr = '\0'; rc = 0; } return rc; }
/* Get POSIX path from fid (fid2path wrapper) */ int Lustre_GetFullPath( const entry_id_t * p_id, char *fullpath, unsigned int len ) { char *curr = fullpath; int rc; long long recno = -1; int linkno = 0; char fid[256]; const char *mpath = NULL; unsigned int mlen = 0; mpath = get_mount_point(&mlen); /* set mountpoint at the beginning of the path */ strcpy( fullpath, mpath ); curr += mlen; /* add the slash only if fid2path doesn't */ #ifndef _FID2PATH_LEADING_SLASH /* add slash */ *curr = '/'; curr ++; #endif /* just in case fid2path returns nothing */ *curr = '\0'; /* fid string */ sprintf( fid, DFID, PFID(p_id) ); /* MDT device */ /* ask the path to lustre */ rc = llapi_fid2path( mpath, fid, curr, len - mlen - 2, &recno, &linkno ); if ( (rc != 0) && (rc != -ENOENT) && (rc != -ESTALE) ) DisplayLog( LVL_CRIT, "Fid2Path", "Error %d calling llapi_fid2path(%s,%s,%lld,%d), errno=%d." " Cannot retrieve full path for %s", rc, mpath, fid, recno, linkno, errno, fid ); /* curr == fullpath => fullpath is root: '/' * so don't remove final slash */ else if (curr != fullpath) { while (FINAL_SLASH(fullpath)) REMOVE_FINAL_SLASH(fullpath); } return rc; }
/** * Given a copytool progress update, construct a JSON event suitable for * consumption by a copytool monitoring process. * * Examples of various events generated here and written by * llapi_hsm_write_json_event: * * Copytool registration and deregistration: * {"event_time": "2014-02-26 14:58:01 -0500", "event_type": "REGISTER", * "archive": 0, "mount_point": "/mnt/lustre", * "uuid": "80379a60-1f8a-743f-daf2-307cde793ec2"} * {"event_time": "2014-02-26 14:58:01 -0500", "event_type": "UNREGISTER", * "archive": 0, "mount_point": "/mnt/lustre", * "uuid": "80379a60-1f8a-743f-daf2-307cde793ec2"} * * An archive action, start to completion: * {"event_time": "2014-02-26 14:50:13 -0500", "event_type": "ARCHIVE_START", * "total_bytes": 0, "lustre_path": "d71.sanity-hsm/f71.sanity-hsm", * "source_fid": "0x2000013a1:0x2:0x0", "data_fid": "0x2000013a1:0x2:0x0"} * {"event_time": "2014-02-26 14:50:18 -0500", "event_type": "ARCHIVE_RUNNING", * "current_bytes": 5242880, "total_bytes": 39000000, * "lustre_path": "d71.sanity-hsm/f71.sanity-hsm", * "source_fid": "0x2000013a1:0x2:0x0", "data_fid": "0x2000013a1:0x2:0x0"} * {"event_time": "2014-02-26 14:50:50 -0500", "event_type": "ARCHIVE_FINISH", * "source_fid": "0x2000013a1:0x2:0x0", "data_fid": "0x2000013a1:0x2:0x0"} * * A log message: * {"event_time": "2014-02-26 14:50:13 -0500", "event_type": "LOGGED_MESSAGE", * "level": "INFO", * "message": "lhsmtool_posix[42]: copytool fs=lustre archive#=2 item_count=1"} * * \param hcp Opaque action handle returned by * llapi_hsm_action_start. * \param hai The hsm_action_item describing the request. * \param progress_type The ct_progress_type describing the update. * \param total The total expected bytes for the request. * \param current The current copied byte count for the request. * * \retval 0 on success. * \retval -errno on error. */ static int llapi_hsm_log_ct_progress(struct hsm_copyaction_private **phcp, const struct hsm_action_item *hai, __u32 progress_type, __u64 total, __u64 current) { int rc; int linkno = 0; long long recno = -1; char lustre_path[PATH_MAX]; char strfid[FID_NOBRACE_LEN + 1]; struct hsm_copyaction_private *hcp; struct llapi_json_item_list *json_items; /* Noop unless the event fd was initialized */ if (llapi_hsm_event_fd < 0) return 0; if (phcp == NULL || *phcp == NULL) return -EINVAL; hcp = *phcp; rc = llapi_json_init_list(&json_items); if (rc < 0) goto err; snprintf(strfid, sizeof(strfid), DFID_NOBRACE, PFID(&hai->hai_dfid)); rc = llapi_json_add_item(&json_items, "data_fid", LLAPI_JSON_STRING, strfid); if (rc < 0) goto err; snprintf(strfid, sizeof(strfid), DFID_NOBRACE, PFID(&hai->hai_fid)); rc = llapi_json_add_item(&json_items, "source_fid", LLAPI_JSON_STRING, strfid); if (rc < 0) goto err; if (hcp->copy.hc_errval == ECANCELED) { progress_type = CT_CANCEL; goto cancel; } if (hcp->copy.hc_errval != 0) { progress_type = CT_ERROR; rc = llapi_json_add_item(&json_items, "errno", LLAPI_JSON_INTEGER, &hcp->copy.hc_errval); if (rc < 0) goto err; rc = llapi_json_add_item(&json_items, "error", LLAPI_JSON_STRING, strerror(hcp->copy.hc_errval)); if (rc < 0) goto err; goto cancel; } /* lustre_path isn't available after a restore completes */ /* total_bytes isn't available after a restore or archive completes */ if (progress_type != CT_FINISH) { rc = llapi_fid2path(hcp->ct_priv->mnt, strfid, lustre_path, sizeof(lustre_path), &recno, &linkno); if (rc < 0) goto err; rc = llapi_json_add_item(&json_items, "lustre_path", LLAPI_JSON_STRING, lustre_path); if (rc < 0) goto err; rc = llapi_json_add_item(&json_items, "total_bytes", LLAPI_JSON_BIGNUM, &total); if (rc < 0) goto err; } if (progress_type == CT_RUNNING) rc = llapi_json_add_item(&json_items, "current_bytes", LLAPI_JSON_BIGNUM, ¤t); if (rc < 0) goto err; cancel: rc = llapi_json_add_item(&json_items, "event_type", LLAPI_JSON_STRING, (char *)llapi_hsm_ct_ev2str(hai->hai_action + progress_type)); if (rc < 0) goto err; rc = llapi_hsm_write_json_event(&json_items); if (rc < 0) goto err; goto out_free; err: llapi_error(LLAPI_MSG_ERROR, rc, "error in " "llapi_hsm_log_ct_progress()"); out_free: if (json_items != NULL) llapi_json_destroy_list(&json_items); return rc; }