{"action":"created","comment":{"url":"https://api.github.com/repos/openthread/openthread/pulls/comments/222547987","pull_request_review_id":161459570,"id":222547987,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMjU0Nzk4Nw==","diff_hunk":"@@ -32,429 +32,442 @@\n  *\n  */\n \n+#include \"platform-posix.h\"\n+\n #include <assert.h>\n+#include <inttypes.h>\n #include <stddef.h>\n-#include <stdlib.h>\n-#include \"utils/wrap_string.h\"\n-\n-#include <openthread-core-config.h>\n+#include <sys/stat.h>\n \n+#include <openthread/platform/misc.h>\n #include <openthread/platform/settings.h>\n \n-#include <code_utils.h>\n+#include \"common/code_utils.hpp\"\n \n-#include \"flash.h\"\n+#define VerifyOrDie(aCondition) \\\n+    do                          \\\n+    {                           \\\n+        if (!(aCondition))      \\\n+        {                       \\\n+            perror(__func__);   \\\n+            exit(EXIT_FAILURE); \\\n+        }                       \\\n+    } while (false)\n \n-#ifdef __cplusplus\n-extern \"C\" {\n-#endif\n+static const size_t kMaxFileNameSize = sizeof(OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH) + 32;\n \n-enum\n-{\n-    kBlockAddBeginFlag    = 0x1,\n-    kBlockAddCompleteFlag = 0x02,\n-    kBlockDeleteFlag      = 0x04,\n-    kBlockIndex0Flag      = 0x08,\n-};\n+static int sFd = -1;\n \n-enum\n+static void getSettingsFileName(char aFileName[kMaxFileNameSize], bool aSwap)\n {\n-    kSettingsFlagSize      = 4,\n-    kSettingsBlockDataSize = 255,\n+    const char *offset = getenv(\"PORT_OFFSET\");\n \n-    kSettingsInSwap = 0xbe5cc5ef,\n-    kSettingsInUse  = 0xbe5cc5ee,\n-    kSettingsNotUse = 0xbe5cc5ec,\n-};\n+    snprintf(aFileName, kMaxFileNameSize, OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH \"/%s_%\" PRIx64 \".%s\",\n+             offset == NULL ? \"0\" : offset, NODE_ID, (aSwap ? \"swap\" : \"data\"));\n+}\n \n-OT_TOOL_PACKED_BEGIN\n-struct settingsBlock\n+static int swapOpen(void)\n {\n-    uint16_t key;\n-    uint16_t flag;\n-    uint16_t length;\n-    uint16_t reserved;\n-} OT_TOOL_PACKED_END;\n+    char fileName[kMaxFileNameSize];\n+    int  fd;\n \n-/**\n- * @def SETTINGS_CONFIG_BASE_ADDRESS\n- *\n- * The base address of settings.\n- *\n- */\n-#ifndef SETTINGS_CONFIG_BASE_ADDRESS\n-#define SETTINGS_CONFIG_BASE_ADDRESS 0x39000\n-#endif // SETTINGS_CONFIG_BASE_ADDRESS\n+    getSettingsFileName(fileName, true);\n+    fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0600);\n+    VerifyOrDie(fd != -1);\n \n-/**\n- * @def SETTINGS_CONFIG_PAGE_SIZE\n- *\n- * The page size of settings.\n- *\n- */\n-#ifndef SETTINGS_CONFIG_PAGE_SIZE\n-#define SETTINGS_CONFIG_PAGE_SIZE 0x800\n-#endif // SETTINGS_CONFIG_PAGE_SIZE\n+    return fd;\n+}\n \n /**\n- * @def SETTINGS_CONFIG_PAGE_NUM\n+ * This function reads @p aLength bytes from the data file and appends to the swap file.\n  *\n- * The page number of settings.\n+ * @param[in]   aFd     The file descriptor of the current swap file.\n+ * @param[in]   aLength Number of bytes to copy.\n  *\n  */\n-#ifndef SETTINGS_CONFIG_PAGE_NUM\n-#define SETTINGS_CONFIG_PAGE_NUM 2\n-#endif // SETTINGS_CONFIG_PAGE_NUM\n+static void swapWrite(int aFd, uint16_t aLength)\n+{\n+    const size_t kBlockSize = 512;\n+    uint8_t      buffer[kBlockSize];\n \n-static uint32_t sSettingsBaseAddress;\n-static uint32_t sSettingsUsedSize;\n+    while (aLength > 0)\n+    {\n+        uint16_t count = aLength >= sizeof(buffer) ? sizeof(buffer) : aLength;\n+        ssize_t  rval  = read(sFd, buffer, count);\n+\n+        VerifyOrDie(rval > 0);\n+        count = static_cast<uint16_t>(rval);\n+        rval  = write(aFd, buffer, count);\n+        assert(rval == count);\n+        VerifyOrDie(rval == count);\n+        aLength -= count;\n+    }\n+}\n \n-static uint16_t getAlignLength(uint16_t length)\n+static void swapPersist(int aFd)\n {\n-    return (length + 3) & 0xfffc;\n+    char swapFile[kMaxFileNameSize];\n+    char dataFile[kMaxFileNameSize];\n+\n+    getSettingsFileName(swapFile, true);\n+    getSettingsFileName(dataFile, false);\n+\n+    VerifyOrDie(0 == rename(swapFile, dataFile));","path":"src/posix/platform/settings.cpp","position":141,"original_position":141,"commit_id":"0a3796bbd111bdf8ec68ce154d3bdb4dd6e5e8a4","original_commit_id":"0a3796bbd111bdf8ec68ce154d3bdb4dd6e5e8a4","user":{"login":"jwhui","id":16142208,"node_id":"MDQ6VXNlcjE2MTQyMjA4","avatar_url":"https://avatars3.githubusercontent.com/u/16142208?v=4","gravatar_id":"","url":"https://api.github.com/users/jwhui","html_url":"https://github.com/jwhui","followers_url":"https://api.github.com/users/jwhui/followers","following_url":"https://api.github.com/users/jwhui/following{/other_user}","gists_url":"https://api.github.com/users/jwhui/gists{/gist_id}","starred_url":"https://api.github.com/users/jwhui/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jwhui/subscriptions","organizations_url":"https://api.github.com/users/jwhui/orgs","repos_url":"https://api.github.com/users/jwhui/repos","events_url":"https://api.github.com/users/jwhui/events{/privacy}","received_events_url":"https://api.github.com/users/jwhui/received_events","type":"User","site_admin":false},"body":"Yes, `rename()` is an atomic operation. However, I think we should have an `fsync()` call after `rename()` to ensure that the change is committed to disk before moving forward. While `rename()` is atomic, it is possible to roll back to the old version if the system crashes before it is committed to disk.","created_at":"2018-10-04T06:19:11Z","updated_at":"2018-10-04T06:19:11Z","html_url":"https://github.com/openthread/openthread/pull/3108#discussion_r222547987","pull_request_url":"https://api.github.com/repos/openthread/openthread/pulls/3108","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/openthread/openthread/pulls/comments/222547987"},"html":{"href":"https://github.com/openthread/openthread/pull/3108#discussion_r222547987"},"pull_request":{"href":"https://api.github.com/repos/openthread/openthread/pulls/3108"}},"in_reply_to_id":222545508},"pull_request":{"url":"https://api.github.com/repos/openthread/openthread/pulls/3108","id":219125586,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE5MTI1NTg2","html_url":"https://github.com/openthread/openthread/pull/3108","diff_url":"https://github.com/openthread/openthread/pull/3108.diff","patch_url":"https://github.com/openthread/openthread/pull/3108.patch","issue_url":"https://api.github.com/repos/openthread/openthread/issues/3108","number":3108,"state":"open","locked":false,"title":"[posix-app] simplify saving settings","user":{"login":"bukepo","id":2240212,"node_id":"MDQ6VXNlcjIyNDAyMTI=","avatar_url":"https://avatars3.githubusercontent.com/u/2240212?v=4","gravatar_id":"","url":"https://api.github.com/users/bukepo","html_url":"https://github.com/bukepo","followers_url":"https://api.github.com/users/bukepo/followers","following_url":"https://api.github.com/users/bukepo/following{/other_user}","gists_url":"https://api.github.com/users/bukepo/gists{/gist_id}","starred_url":"https://api.github.com/users/bukepo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bukepo/subscriptions","organizations_url":"https://api.github.com/users/bukepo/orgs","repos_url":"https://api.github.com/users/bukepo/repos","events_url":"https://api.github.com/users/bukepo/events{/privacy}","received_events_url":"https://api.github.com/users/bukepo/received_events","type":"User","site_admin":false},"body":"save as key-length-value.","created_at":"2018-09-29T04:56:20Z","updated_at":"2018-10-04T06:19:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fed38ac13dafa6e1b50c412f788ab46d7501e7ab","assignee":null,"assignees":[],"requested_reviewers":[{"login":"jwhui","id":16142208,"node_id":"MDQ6VXNlcjE2MTQyMjA4","avatar_url":"https://avatars3.githubusercontent.com/u/16142208?v=4","gravatar_id":"","url":"https://api.github.com/users/jwhui","html_url":"https://github.com/jwhui","followers_url":"https://api.github.com/users/jwhui/followers","following_url":"https://api.github.com/users/jwhui/following{/other_user}","gists_url":"https://api.github.com/users/jwhui/gists{/gist_id}","starred_url":"https://api.github.com/users/jwhui/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jwhui/subscriptions","organizations_url":"https://api.github.com/users/jwhui/orgs","repos_url":"https://api.github.com/users/jwhui/repos","events_url":"https://api.github.com/users/jwhui/events{/privacy}","received_events_url":"https://api.github.com/users/jwhui/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":397568980,"node_id":"MDU6TGFiZWwzOTc1Njg5ODA=","url":"https://api.github.com/repos/openthread/openthread/labels/P4","name":"P4","color":"AFDF00","default":false},{"id":355043113,"node_id":"MDU6TGFiZWwzNTUwNDMxMTM=","url":"https://api.github.com/repos/openthread/openthread/labels/enhancement","name":"enhancement","color":"84b6eb","default":true}],"milestone":null,"commits_url":"https://api.github.com/repos/openthread/openthread/pulls/3108/commits","review_comments_url":"https://api.github.com/repos/openthread/openthread/pulls/3108/comments","review_comment_url":"https://api.github.com/repos/openthread/openthread/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openthread/openthread/issues/3108/comments","statuses_url":"https://api.github.com/repos/openthread/openthread/statuses/0a3796bbd111bdf8ec68ce154d3bdb4dd6e5e8a4","head":{"label":"bukepo:remove-flash","ref":"remove-flash","sha":"0a3796bbd111bdf8ec68ce154d3bdb4dd6e5e8a4","user":{"login":"bukepo","id":2240212,"node_id":"MDQ6VXNlcjIyNDAyMTI=","avatar_url":"https://avatars3.githubusercontent.com/u/2240212?v=4","gravatar_id":"","url":"https://api.github.com/users/bukepo","html_url":"https://github.com/bukepo","followers_url":"https://api.github.com/users/bukepo/followers","following_url":"https://api.github.com/users/bukepo/following{/other_user}","gists_url":"https://api.github.com/users/bukepo/gists{/gist_id}","starred_url":"https://api.github.com/users/bukepo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bukepo/subscriptions","organizations_url":"https://api.github.com/users/bukepo/orgs","repos_url":"https://api.github.com/users/bukepo/repos","events_url":"https://api.github.com/users/bukepo/events{/privacy}","received_events_url":"https://api.github.com/users/bukepo/received_events","type":"User","site_admin":false},"repo":{"id":64895344,"node_id":"MDEwOlJlcG9zaXRvcnk2NDg5NTM0NA==","name":"openthread","full_name":"bukepo/openthread","private":false,"owner":{"login":"bukepo","id":2240212,"node_id":"MDQ6VXNlcjIyNDAyMTI=","avatar_url":"https://avatars3.githubusercontent.com/u/2240212?v=4","gravatar_id":"","url":"https://api.github.com/users/bukepo","html_url":"https://github.com/bukepo","followers_url":"https://api.github.com/users/bukepo/followers","following_url":"https://api.github.com/users/bukepo/following{/other_user}","gists_url":"https://api.github.com/users/bukepo/gists{/gist_id}","starred_url":"https://api.github.com/users/bukepo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bukepo/subscriptions","organizations_url":"https://api.github.com/users/bukepo/orgs","repos_url":"https://api.github.com/users/bukepo/repos","events_url":"https://api.github.com/users/bukepo/events{/privacy}","received_events_url":"https://api.github.com/users/bukepo/received_events","type":"User","site_admin":false},"html_url":"https://github.com/bukepo/openthread","description":"OpenThread released by Nest is an open-source implementation of the Thread networking protocol","fork":true,"url":"https://api.github.com/repos/bukepo/openthread","forks_url":"https://api.github.com/repos/bukepo/openthread/forks","keys_url":"https://api.github.com/repos/bukepo/openthread/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bukepo/openthread/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bukepo/openthread/teams","hooks_url":"https://api.github.com/repos/bukepo/openthread/hooks","issue_events_url":"https://api.github.com/repos/bukepo/openthread/issues/events{/number}","events_url":"https://api.github.com/repos/bukepo/openthread/events","assignees_url":"https://api.github.com/repos/bukepo/openthread/assignees{/user}","branches_url":"https://api.github.com/repos/bukepo/openthread/branches{/branch}","tags_url":"https://api.github.com/repos/bukepo/openthread/tags","blobs_url":"https://api.github.com/repos/bukepo/openthread/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bukepo/openthread/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bukepo/openthread/git/refs{/sha}","trees_url":"https://api.github.com/repos/bukepo/openthread/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bukepo/openthread/statuses/{sha}","languages_url":"https://api.github.com/repos/bukepo/openthread/languages","stargazers_url":"https://api.github.com/repos/bukepo/openthread/stargazers","contributors_url":"https://api.github.com/repos/bukepo/openthread/contributors","subscribers_url":"https://api.github.com/repos/bukepo/openthread/subscribers","subscription_url":"https://api.github.com/repos/bukepo/openthread/subscription","commits_url":"https://api.github.com/repos/bukepo/openthread/commits{/sha}","git_commits_url":"https://api.github.com/repos/bukepo/openthread/git/commits{/sha}","comments_url":"https://api.github.com/repos/bukepo/openthread/comments{/number}","issue_comment_url":"https://api.github.com/repos/bukepo/openthread/issues/comments{/number}","contents_url":"https://api.github.com/repos/bukepo/openthread/contents/{+path}","compare_url":"https://api.github.com/repos/bukepo/openthread/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bukepo/openthread/merges","archive_url":"https://api.github.com/repos/bukepo/openthread/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bukepo/openthread/downloads","issues_url":"https://api.github.com/repos/bukepo/openthread/issues{/number}","pulls_url":"https://api.github.com/repos/bukepo/openthread/pulls{/number}","milestones_url":"https://api.github.com/repos/bukepo/openthread/milestones{/number}","notifications_url":"https://api.github.com/repos/bukepo/openthread/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bukepo/openthread/labels{/name}","releases_url":"https://api.github.com/repos/bukepo/openthread/releases{/id}","deployments_url":"https://api.github.com/repos/bukepo/openthread/deployments","created_at":"2016-08-04T02:28:44Z","updated_at":"2018-08-16T09:28:16Z","pushed_at":"2018-10-04T02:08:39Z","git_url":"git://github.com/bukepo/openthread.git","ssh_url":"git@github.com:bukepo/openthread.git","clone_url":"https://github.com/bukepo/openthread.git","svn_url":"https://github.com/bukepo/openthread","homepage":"","size":297856,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":3,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause","node_id":"MDc6TGljZW5zZTU="},"forks":0,"open_issues":3,"watchers":0,"default_branch":"master"}},"base":{"label":"openthread:master","ref":"master","sha":"1b200be5456532e0e9b0afb15caa3b5bdc734f78","user":{"login":"openthread","id":16142269,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2MTQyMjY5","avatar_url":"https://avatars2.githubusercontent.com/u/16142269?v=4","gravatar_id":"","url":"https://api.github.com/users/openthread","html_url":"https://github.com/openthread","followers_url":"https://api.github.com/users/openthread/followers","following_url":"https://api.github.com/users/openthread/following{/other_user}","gists_url":"https://api.github.com/users/openthread/gists{/gist_id}","starred_url":"https://api.github.com/users/openthread/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openthread/subscriptions","organizations_url":"https://api.github.com/users/openthread/orgs","repos_url":"https://api.github.com/users/openthread/repos","events_url":"https://api.github.com/users/openthread/events{/privacy}","received_events_url":"https://api.github.com/users/openthread/received_events","type":"Organization","site_admin":false},"repo":{"id":55808787,"node_id":"MDEwOlJlcG9zaXRvcnk1NTgwODc4Nw==","name":"openthread","full_name":"openthread/openthread","private":false,"owner":{"login":"openthread","id":16142269,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2MTQyMjY5","avatar_url":"https://avatars2.githubusercontent.com/u/16142269?v=4","gravatar_id":"","url":"https://api.github.com/users/openthread","html_url":"https://github.com/openthread","followers_url":"https://api.github.com/users/openthread/followers","following_url":"https://api.github.com/users/openthread/following{/other_user}","gists_url":"https://api.github.com/users/openthread/gists{/gist_id}","starred_url":"https://api.github.com/users/openthread/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openthread/subscriptions","organizations_url":"https://api.github.com/users/openthread/orgs","repos_url":"https://api.github.com/users/openthread/repos","events_url":"https://api.github.com/users/openthread/events{/privacy}","received_events_url":"https://api.github.com/users/openthread/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/openthread/openthread","description":"OpenThread released by Nest is an open-source implementation of the Thread networking protocol","fork":false,"url":"https://api.github.com/repos/openthread/openthread","forks_url":"https://api.github.com/repos/openthread/openthread/forks","keys_url":"https://api.github.com/repos/openthread/openthread/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openthread/openthread/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openthread/openthread/teams","hooks_url":"https://api.github.com/repos/openthread/openthread/hooks","issue_events_url":"https://api.github.com/repos/openthread/openthread/issues/events{/number}","events_url":"https://api.github.com/repos/openthread/openthread/events","assignees_url":"https://api.github.com/repos/openthread/openthread/assignees{/user}","branches_url":"https://api.github.com/repos/openthread/openthread/branches{/branch}","tags_url":"https://api.github.com/repos/openthread/openthread/tags","blobs_url":"https://api.github.com/repos/openthread/openthread/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openthread/openthread/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openthread/openthread/git/refs{/sha}","trees_url":"https://api.github.com/repos/openthread/openthread/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openthread/openthread/statuses/{sha}","languages_url":"https://api.github.com/repos/openthread/openthread/languages","stargazers_url":"https://api.github.com/repos/openthread/openthread/stargazers","contributors_url":"https://api.github.com/repos/openthread/openthread/contributors","subscribers_url":"https://api.github.com/repos/openthread/openthread/subscribers","subscription_url":"https://api.github.com/repos/openthread/openthread/subscription","commits_url":"https://api.github.com/repos/openthread/openthread/commits{/sha}","git_commits_url":"https://api.github.com/repos/openthread/openthread/git/commits{/sha}","comments_url":"https://api.github.com/repos/openthread/openthread/comments{/number}","issue_comment_url":"https://api.github.com/repos/openthread/openthread/issues/comments{/number}","contents_url":"https://api.github.com/repos/openthread/openthread/contents/{+path}","compare_url":"https://api.github.com/repos/openthread/openthread/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openthread/openthread/merges","archive_url":"https://api.github.com/repos/openthread/openthread/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openthread/openthread/downloads","issues_url":"https://api.github.com/repos/openthread/openthread/issues{/number}","pulls_url":"https://api.github.com/repos/openthread/openthread/pulls{/number}","milestones_url":"https://api.github.com/repos/openthread/openthread/milestones{/number}","notifications_url":"https://api.github.com/repos/openthread/openthread/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openthread/openthread/labels{/name}","releases_url":"https://api.github.com/repos/openthread/openthread/releases{/id}","deployments_url":"https://api.github.com/repos/openthread/openthread/deployments","created_at":"2016-04-08T20:47:41Z","updated_at":"2018-10-03T06:12:44Z","pushed_at":"2018-10-04T02:08:40Z","git_url":"git://github.com/openthread/openthread.git","ssh_url":"git@github.com:openthread/openthread.git","clone_url":"https://github.com/openthread/openthread.git","svn_url":"https://github.com/openthread/openthread","homepage":"","size":53285,"stargazers_count":1671,"watchers_count":1671,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":491,"mirror_url":null,"archived":false,"open_issues_count":46,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause","node_id":"MDc6TGljZW5zZTU="},"forks":491,"open_issues":46,"watchers":1671,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openthread/openthread/pulls/3108"},"html":{"href":"https://github.com/openthread/openthread/pull/3108"},"issue":{"href":"https://api.github.com/repos/openthread/openthread/issues/3108"},"comments":{"href":"https://api.github.com/repos/openthread/openthread/issues/3108/comments"},"review_comments":{"href":"https://api.github.com/repos/openthread/openthread/pulls/3108/comments"},"review_comment":{"href":"https://api.github.com/repos/openthread/openthread/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openthread/openthread/pulls/3108/commits"},"statuses":{"href":"https://api.github.com/repos/openthread/openthread/statuses/0a3796bbd111bdf8ec68ce154d3bdb4dd6e5e8a4"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"jwhui"}}