diff options
-rw-r--r-- | mof/60_LMI_Journald.mof | 18 | ||||
-rw-r--r-- | src/journald/LMI_JournalMessageLogProvider.c | 29 | ||||
-rw-r--r-- | src/journald/instutil.c | 65 | ||||
-rw-r--r-- | src/journald/instutil.h | 4 |
4 files changed, 95 insertions, 21 deletions
diff --git a/mof/60_LMI_Journald.mof b/mof/60_LMI_Journald.mof index 9f59581..22f726a 100644 --- a/mof/60_LMI_Journald.mof +++ b/mof/60_LMI_Journald.mof @@ -63,6 +63,24 @@ class LMI_JournalMessageLog: CIM_MessageLog [ Implemented(true), Description ( + "Requests that an iteration of the MessageLog be " + "established and that the iterator be set to the last " + "entry in the Log. An identifier for the iterator is " + "returned as an output parameter of the method. \n" + "\n" + "The return value from PositionToFirstRecord is 0 " + "if the request was successfully executed, 1 if the " + "request is not supported and some other value if an " + "error occurred." ), + ValueMap { "0", "1", "2" }, + Values { "Success", "Not supported", "Failed" } ] + uint32 PositionToLastRecord( + [IN ( false ), OUT, Description ( + "An identifier for the iterator." )] + string IterationIdentifier); + + + [ Implemented(true), Description ( "Requests that the Log\'s iteration identifier be " "advanced or retreated a specific number of records, or " "set to the entry at a specified numeric location. These " diff --git a/src/journald/LMI_JournalMessageLogProvider.c b/src/journald/LMI_JournalMessageLogProvider.c index 2332f83..297a775 100644 --- a/src/journald/LMI_JournalMessageLogProvider.c +++ b/src/journald/LMI_JournalMessageLogProvider.c @@ -228,7 +228,32 @@ KUint32 LMI_JournalMessageLog_PositionToFirstRecord( KSetStatus(status, OK); - if ((iter_id = journal_iter_new(NULL, NULL)) == NULL) { + if ((iter_id = journal_iter_new(NULL, FALSE, NULL)) == NULL) { + KUint32_Set(&result, CIM_MESSAGELOG_ITERATOR_RESULT_FAILED); + return result; + } + + KString_Set(IterationIdentifier, _cb, iter_id); + KUint32_Set(&result, CIM_MESSAGELOG_ITERATOR_RESULT_SUCCESS); + g_free(iter_id); + + return result; +} + +KUint32 LMI_JournalMessageLog_PositionToLastRecord( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_JournalMessageLogRef* self, + KString* IterationIdentifier, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + gchar *iter_id; + + KSetStatus(status, OK); + + if ((iter_id = journal_iter_new(NULL, TRUE, NULL)) == NULL) { KUint32_Set(&result, CIM_MESSAGELOG_ITERATOR_RESULT_FAILED); return result; } @@ -393,7 +418,7 @@ KUint32 LMI_JournalMessageLog_CancelIteration( return result; } - if (! journal_iter_parse_iterator_string(IterationIdentifier->chars, &iter_id_short, NULL, NULL)) { + if (! journal_iter_parse_iterator_string(IterationIdentifier->chars, &iter_id_short, NULL, NULL, NULL)) { KSetStatus2(_cb, status, ERR_INVALID_PARAMETER, "Malformed IterationIdentifier argument"); KUint32_Set(&result, CIM_MESSAGELOG_ITERATOR_RESULT_FAILED); return result; diff --git a/src/journald/instutil.c b/src/journald/instutil.c index be11610..413a8b1 100644 --- a/src/journald/instutil.c +++ b/src/journald/instutil.c @@ -44,6 +44,7 @@ static sig_atomic_t cmpi_iters_count = 0; #define JOURNAL_ITER_PREFIX "LMI_JournalMessageLog_CMPI_Iter_" #define JOURNAL_ITER_SEPARATOR "#" +#define JOURNAL_ITER_EOF "<EOF>" int create_LMI_JournalLogRecordRef(sd_journal *j, @@ -398,22 +399,26 @@ bool ind_gather(const IMManager *manager, CMPIInstance **old, CMPIInstance **new } static gchar * -make_iterator_string(sd_journal *journal, const char *cursor, gchar *iter_id_short) +make_iterator_string(sd_journal *journal, const char *cursor, gchar *iter_id_short, gboolean eof_set) { - return g_strdup_printf("%s%s%p%s%s", iter_id_short, JOURNAL_ITER_SEPARATOR, (void *)journal, JOURNAL_ITER_SEPARATOR, cursor); + return g_strdup_printf("%s%s%p%s%s%s%s", iter_id_short, JOURNAL_ITER_SEPARATOR, (void *)journal, JOURNAL_ITER_SEPARATOR, cursor, + eof_set ? JOURNAL_ITER_SEPARATOR : "", eof_set ? JOURNAL_ITER_EOF : ""); } bool -journal_iter_parse_iterator_string(const char *iter_id, gchar **out_iter_id_short, gpointer *out_iter_ptr, gchar **out_iter_cursor) +journal_iter_parse_iterator_string(const char *iter_id, gchar **out_iter_id_short, gpointer *out_iter_ptr, gchar **out_iter_cursor, gboolean *out_eof_set) { gchar **s = NULL; bool res; gpointer valid_p; + if (out_eof_set) + *out_eof_set = FALSE; + res = (iter_id && strlen(iter_id) > 0); if (res) - s = g_strsplit(iter_id, JOURNAL_ITER_SEPARATOR, 3); - res = res && s && g_strv_length(s) == 3 && strlen(s[0]) > 0 && strlen(s[1]) > 0 && strlen(s[2]) > 0; + s = g_strsplit(iter_id, JOURNAL_ITER_SEPARATOR, 4); + res = res && s && (g_strv_length(s) == 3 || g_strv_length(s) == 4) && strlen(s[0]) > 0 && strlen(s[1]) > 0 && strlen(s[2]) > 0 && (g_strv_length(s) == 3 || strlen(s[3]) > 0); valid_p = NULL; res = res && (sscanf(s[1], "%p", &valid_p) == 1); if (res && out_iter_id_short) @@ -422,13 +427,18 @@ journal_iter_parse_iterator_string(const char *iter_id, gchar **out_iter_id_shor *out_iter_ptr = valid_p; if (res && out_iter_cursor) res = res && ((*out_iter_cursor = g_strdup(s[2])) != NULL); + if (res && out_eof_set && g_strv_length(s) == 4) { + *out_eof_set = g_strcmp0(s[3], JOURNAL_ITER_EOF) == 0; + /* the fourth part should only be present with valid string */ + res = res && *out_eof_set; + } g_strfreev(s); return res; } gchar * -journal_iter_new(const gchar *req_cursor, sd_journal **journal_out) +journal_iter_new(const gchar *req_cursor, gboolean seek_tail, sd_journal **journal_out) { gchar *iter_id = NULL; gchar *iter_id_full = NULL; @@ -436,6 +446,7 @@ journal_iter_new(const gchar *req_cursor, sd_journal **journal_out) sd_journal *journal; int r; char errbuf[STRERROR_BUF_LEN]; + gboolean eof_set; if (journal_out) *journal_out = NULL; @@ -448,8 +459,12 @@ journal_iter_new(const gchar *req_cursor, sd_journal **journal_out) if (req_cursor) r = sd_journal_seek_cursor(journal, req_cursor); - else - r = sd_journal_seek_head(journal); + else { + if (seek_tail) + r = sd_journal_seek_tail(journal); + else + r = sd_journal_seek_head(journal); + } if (r < 0) { error("Error seeking to the requested journal position: %s\n", strerror_r(-r, errbuf, sizeof(errbuf))); @@ -457,12 +472,16 @@ journal_iter_new(const gchar *req_cursor, sd_journal **journal_out) return NULL; } - r = sd_journal_next(journal); + if (seek_tail) + r = sd_journal_previous(journal); + else + r = sd_journal_next(journal); if (r < 0) { error("Error stepping next in the journal: %s\n", strerror_r(-r, errbuf, sizeof(errbuf))); sd_journal_close(journal); return NULL; } + eof_set = r == 0; r = sd_journal_get_cursor(journal, &cursor); if (r < 0) { @@ -482,7 +501,7 @@ journal_iter_new(const gchar *req_cursor, sd_journal **journal_out) } iter_id = g_strdup_printf("%s%d", JOURNAL_ITER_PREFIX, cmpi_iters_count++); if (iter_id) - iter_id_full = make_iterator_string(journal, cursor, iter_id); + iter_id_full = make_iterator_string(journal, cursor, iter_id, eof_set); if (iter_id == NULL || iter_id_full == NULL) { error("Memory allocation failure\n"); sd_journal_close(journal); @@ -503,6 +522,7 @@ journal_iter_validate_id(gchar **iter_id, sd_journal **journal_out, gchar **pref gboolean res; gchar *iter_id_short, *iter_cursor; gpointer iter_ptr; + gboolean eof_set; res = TRUE; if (journal_out) @@ -510,7 +530,7 @@ journal_iter_validate_id(gchar **iter_id, sd_journal **journal_out, gchar **pref if (prefix_out) *prefix_out = NULL; - if (! journal_iter_parse_iterator_string(*iter_id, &iter_id_short, &iter_ptr, &iter_cursor)) { + if (! journal_iter_parse_iterator_string(*iter_id, &iter_id_short, &iter_ptr, &iter_cursor, &eof_set)) { set_cmpi_status_fmt(_cb, status, ERR_INVALID_PARAMETER, "Malformed IterationIdentifier argument: \'%s\'\n", *iter_id); return false; } @@ -525,7 +545,7 @@ journal_iter_validate_id(gchar **iter_id, sd_journal **journal_out, gchar **pref /* Assume stale iterator ID, reopen journal and try to find the position by the cursor */ warn("journal_iter_validate_id(): iterator pointer %p doesn't match with hashtable %p, reopening journal...\n", iter_ptr, *journal_out); g_free(*iter_id); - *iter_id = journal_iter_new(iter_cursor, journal_out); + *iter_id = journal_iter_new(iter_cursor, FALSE, journal_out); if (*iter_id == NULL) { error("The IterationIdentifier is not valid anymore: \'%s\'\n", *iter_id); res = FALSE; @@ -563,12 +583,13 @@ journal_iter_cancel(const char *iter_id) } static bool -update_iter(gchar **iter_id, sd_journal *journal) +update_iter(gchar **iter_id, gboolean explicit_eof, sd_journal *journal) { gchar *iter_id_short; char *cursor; int r; char errbuf[STRERROR_BUF_LEN]; + gboolean eof_set; r = sd_journal_get_cursor(journal, &cursor); if (r < 0) { @@ -576,9 +597,9 @@ update_iter(gchar **iter_id, sd_journal *journal) return false; } - if (! journal_iter_parse_iterator_string(*iter_id, &iter_id_short, NULL, NULL)) + if (! journal_iter_parse_iterator_string(*iter_id, &iter_id_short, NULL, NULL, &eof_set)) return false; - *iter_id = make_iterator_string(journal, cursor, iter_id_short); + *iter_id = make_iterator_string(journal, cursor, iter_id_short, explicit_eof); return *iter_id != NULL; } @@ -606,7 +627,7 @@ journal_iter_seek(gchar **iter_id, sd_journal *journal, gint64 position) return false; } - if (! update_iter(iter_id, journal)) { + if (! update_iter(iter_id, r == 0, journal)) { error("Error seeking to the requested position\n"); return false; } @@ -620,9 +641,19 @@ journal_iter_get_data(gchar **iter_id, sd_journal *journal, gboolean step_next) gchar *d; int r; char errbuf[STRERROR_BUF_LEN]; + gboolean eof_set; g_return_val_if_fail(journal != NULL, false); + /* In case of EOF was reached previously, try to seek again to see if new record arrived */ + if (! journal_iter_parse_iterator_string(*iter_id, FALSE, NULL, NULL, &eof_set)) + return false; + if (eof_set) { + r = sd_journal_next(journal); + if (r <= 0) + return false; + } + /* Construct the message */ r = get_record_message(journal, TRUE, &d); if (r < 0) { @@ -639,7 +670,7 @@ journal_iter_get_data(gchar **iter_id, sd_journal *journal, gboolean step_next) } } - if (! update_iter(iter_id, journal)) { + if (! update_iter(iter_id, r == 0, journal)) { error("Error getting record message\n"); return NULL; } diff --git a/src/journald/instutil.h b/src/journald/instutil.h index 2e4ad0b..88572c5 100644 --- a/src/journald/instutil.h +++ b/src/journald/instutil.h @@ -42,8 +42,8 @@ bool ind_watcher(void **data); bool ind_gather(const IMManager *manager, CMPIInstance **old, CMPIInstance **new, void *data); void ind_destroy(); -gchar * journal_iter_new(const gchar *req_cursor, sd_journal **journal_out); -bool journal_iter_parse_iterator_string(const char *iter_id, gchar **out_iter_id_short, gpointer *out_iter_ptr, gchar **out_iter_cursor); +gchar * journal_iter_new(const gchar *req_cursor, gboolean seek_tail, sd_journal **journal_out); +bool journal_iter_parse_iterator_string(const char *iter_id, gchar **out_iter_id_short, gpointer *out_iter_ptr, gchar **out_iter_cursor, gboolean *out_eof_set); bool journal_iter_validate_id(gchar **iter_id, sd_journal **journal_out, gchar **prefix_out, const CMPIBroker *_cb, CMPIStatus *status); bool journal_iter_cancel(const gchar *iter_id); bool journal_iter_seek(gchar **iter_id, sd_journal *journal, gint64 position); |