{"action":"created","issue":{"url":"https://api.github.com/repos/cooperative-computing-lab/cctools/issues/669","labels_url":"https://api.github.com/repos/cooperative-computing-lab/cctools/issues/669/labels{/name}","comments_url":"https://api.github.com/repos/cooperative-computing-lab/cctools/issues/669/comments","events_url":"https://api.github.com/repos/cooperative-computing-lab/cctools/issues/669/events","html_url":"https://github.com/cooperative-computing-lab/cctools/issues/669","id":57644231,"number":669,"title":"putfile retry fails if client only has put permission","user":{"login":"batrick","id":548304,"avatar_url":"https://avatars.githubusercontent.com/u/548304?v=3","gravatar_id":"","url":"https://api.github.com/users/batrick","html_url":"https://github.com/batrick","followers_url":"https://api.github.com/users/batrick/followers","following_url":"https://api.github.com/users/batrick/following{/other_user}","gists_url":"https://api.github.com/users/batrick/gists{/gist_id}","starred_url":"https://api.github.com/users/batrick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/batrick/subscriptions","organizations_url":"https://api.github.com/users/batrick/orgs","repos_url":"https://api.github.com/users/batrick/repos","events_url":"https://api.github.com/users/batrick/events{/privacy}","received_events_url":"https://api.github.com/users/batrick/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/cooperative-computing-lab/cctools/labels/Chirp","name":"Chirp","color":"fef2c0"},{"url":"https://api.github.com/repos/cooperative-computing-lab/cctools/labels/question","name":"question","color":"cc317c"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-02-13T19:42:16Z","updated_at":"2015-02-13T20:40:42Z","closed_at":null,"body":"So I ran into an interesting bug in Confuga where a transfer job is trying a `chirp_reli_putfile` operation. The issue it ran into was the first putfile attempt failing due to connection failures. Subsequent attempts failed because a file was partially written and the storage node (transfer job) only had put permission for the containing directory.\r\n\r\nThe problem put succinctly: a put operation cannot be retried on failure if the client only has put permissions.\r\n\r\nI see a few potential solutions:\r\n\r\n* Write your application in a way that it is not sensitive to this failure. [This one is hard because you can leave behind a lot of partially written files...]\r\n\r\n* Don't give a client only put permission.\r\n\r\n* Since the `putfile` RPC gives the length of the file being put, it's possible for the Chirp server to check if the operation did not put the entire file. If so, we could delete the partially written file.\r\n\r\n* Another (very non-portable) option is to have an anonymous file that is linked in after it is fully written. From `open(2)`:\r\n\r\n````\r\n       O_TMPFILE (since Linux 3.11)\r\n              Create  an  unnamed  temporary file.  The pathname argument specifies a\r\n              directory; an  unnamed  inode  will  be  created  in  that  directory's\r\n              filesystem.   Anything  written to the resulting file will be lost when\r\n              the last file descriptor is closed, unless the file is given a name.\r\n\r\n              O_TMPFILE must be specified with one of O_RDWR or O_WRONLY and, option‐\r\n              ally,  O_EXCL.   If O_EXCL is not specified, then linkat(2) can be used\r\n              to link the temporary file into the filesystem,  making  it  permanent,\r\n              using code like the following:\r\n\r\n                  char path[PATH_MAX];\r\n                  fd = open(\"/path/to/dir\", O_TMPFILE | O_RDWR,\r\n                                          S_IRUSR | S_IWUSR);\r\n\r\n                  /* File I/O on 'fd'... */\r\n\r\n                  snprintf(path, PATH_MAX,  \"/proc/self/fd/%d\", fd);\r\n                  linkat(AT_FDCWD, path, AT_FDCWD, \"/path/for/file\",\r\n                                          AT_SYMLINK_FOLLOW);\r\n````\r\n\r\nI'm marking this as question since I'm not sure this can be reasonably fixed.\r\n\r\nThe fix I have now is to add write permission in addition to put permission."},"comment":{"url":"https://api.github.com/repos/cooperative-computing-lab/cctools/issues/comments/74323218","html_url":"https://github.com/cooperative-computing-lab/cctools/issues/669#issuecomment-74323218","issue_url":"https://api.github.com/repos/cooperative-computing-lab/cctools/issues/669","id":74323218,"user":{"login":"btovar","id":3081826,"avatar_url":"https://avatars.githubusercontent.com/u/3081826?v=3","gravatar_id":"","url":"https://api.github.com/users/btovar","html_url":"https://github.com/btovar","followers_url":"https://api.github.com/users/btovar/followers","following_url":"https://api.github.com/users/btovar/following{/other_user}","gists_url":"https://api.github.com/users/btovar/gists{/gist_id}","starred_url":"https://api.github.com/users/btovar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/btovar/subscriptions","organizations_url":"https://api.github.com/users/btovar/orgs","repos_url":"https://api.github.com/users/btovar/repos","events_url":"https://api.github.com/users/btovar/events{/privacy}","received_events_url":"https://api.github.com/users/btovar/received_events","type":"User","site_admin":false},"created_at":"2015-02-13T20:40:42Z","updated_at":"2015-02-13T20:40:42Z","body":"What's wrong with option 3?\n\nSince the putfile RPC gives the length of the file being put, it's possible\nfor the Chirp server to check if the operation did not put the entire file.\nIf so, we could delete the partially written file.\n\nOn Fri, Feb 13, 2015 at 2:42 PM, Patrick Donnelly <notifications@github.com>\nwrote:\n\n> So I ran into an interesting bug in Confuga where a transfer job is trying\n> a chirp_reli_putfile operation. The issue it ran into was the first\n> putfile attempt failing due to connection failures. Subsequent attempts\n> failed because a file was partially written and the storage node (transfer\n> job) only had put permission for the containing directory.\n>\n> The problem put succinctly: a put operation cannot be retried on failure\n> if the client only has put permissions.\n>\n> I see a few potential solutions:\n>\n>    -\n>\n>    Write your application in a way that it is not sensitive to this\n>    failure. [This one is hard because you can leave behind a lot of partially\n>    written files...]\n>    -\n>\n>    Don't give a client only put permission.\n>    -\n>\n>    Since the putfile RPC gives the length of the file being put, it's\n>    possible for the Chirp server to check if the operation did not put the\n>    entire file. If so, we could delete the partially written file.\n>    -\n>\n>    Another (very non-portable) option is to have an anonymous file that\n>    is linked in after it is fully written. From open(2):\n>\n>        O_TMPFILE (since Linux 3.11)\n>               Create  an  unnamed  temporary file.  The pathname argument specifies a\n>               directory; an  unnamed  inode  will  be  created  in  that  directory's\n>               filesystem.   Anything  written to the resulting file will be lost when\n>               the last file descriptor is closed, unless the file is given a name.\n>\n>               O_TMPFILE must be specified with one of O_RDWR or O_WRONLY and, option‐\n>               ally,  O_EXCL.   If O_EXCL is not specified, then linkat(2) can be used\n>               to link the temporary file into the filesystem,  making  it  permanent,\n>               using code like the following:\n>\n>                   char path[PATH_MAX];\n>                   fd = open(\"/path/to/dir\", O_TMPFILE | O_RDWR,\n>                                           S_IRUSR | S_IWUSR);\n>\n>                   /* File I/O on 'fd'... */\n>\n>                   snprintf(path, PATH_MAX,  \"/proc/self/fd/%d\", fd);\n>                   linkat(AT_FDCWD, path, AT_FDCWD, \"/path/for/file\",\n>                                           AT_SYMLINK_FOLLOW);\n>\n> I'm marking this as question since I'm not sure this can be reasonably\n> fixed.\n>\n> The fix I have now is to add write permission in addition to put\n> permission.\n>\n> —\n> Reply to this email directly or view it on GitHub\n> <https://github.com/cooperative-computing-lab/cctools/issues/669>.\n>\n"}}