{"id":26045,"date":"2019-07-23T16:41:49","date_gmt":"2019-07-23T20:41:49","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=26045"},"modified":"2019-12-19T14:57:15","modified_gmt":"2019-12-19T19:57:15","slug":"xattr-flags-and-icloud-drive","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2019\/07\/23\/xattr-flags-and-icloud-drive\/","title":{"rendered":"xattr Flags and iCloud Drive"},"content":{"rendered":"<p><a href=\"https:\/\/eclecticlight.co\/2019\/07\/23\/how-to-save-file-metadata-in-icloud-and-new-info-on-extended-attributes\/\">Howard Oakley<\/a>:<\/p>\n<blockquote cite=\"https:\/\/eclecticlight.co\/2019\/07\/23\/how-to-save-file-metadata-in-icloud-and-new-info-on-extended-attributes\/\">\n<p>If you work with xattrs, you&rsquo;ve probably already seen this in xattrs whose name ends with a hash # then one or more characters: that&rsquo;s actually the flags, not part of the name, what Apple refers to as a &lsquo;property list&rsquo;. To avoid confusion I won&rsquo;t use that term here, but refer to them as xattr flags. A common example of this is <code>com.apple.lastuseddate#PS<\/code>, which is seen quite widely.<\/p>\n<p>Flags can be upper or lower case letters C, N, P and S, and invariably follow the # separator, which is presumably otherwise forbidden from use in a xattr&rsquo;s name. Upper case sets (enables) that property, whilst lower case clears (disables) that property.<\/p>\n<p>[&#8230;]<\/p>\n<p>The sought-for &lsquo;whitelist&rsquo; is actually baked into the xattr flag code, where as of 2013 the following default flags are set for different types of xattr[&#8230;]<\/p>\n<p>[&#8230;]<\/p>\n<p>If you want a xattr preserved when it passes through iCloud, you therefore need to give it a name which ends in the xattr flag <strong>S<\/strong>, such as <code>co.eclecticlight.MyTest#S<\/code>.<\/p>\n<\/blockquote>\n<p>This is like filename extensions all over again, cramming two pieces of data into the same field. If you have an app that uses xattrs (maybe even from before iCloud Drive was introduced), you need to migrate all your metadata (and forever check the old xattrs when reading a file) if you want to set the &ldquo;flags&rdquo; for proper iCloud treatment.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2018\/01\/08\/icloud-drive-can-strip-metadata-from-your-documents\/\">iCloud Drive Can Strip Metadata From Your Documents<\/a><\/li>\n<\/ul>\n\n<p id=\"xattr-flags-and-icloud-drive-update-2019-07-24\">Update (2019-07-24): <a href=\"https:\/\/eclecticlight.co\/2019\/07\/23\/how-to-save-your-file-metadata-implementation-isnt-simple\/\">Howard Oakley<\/a>:<\/p>\n<blockquote cite=\"https:\/\/eclecticlight.co\/2019\/07\/23\/how-to-save-your-file-metadata-implementation-isnt-simple\/\">\n<p>Thus the <strong>S<\/strong> flag preserved all the xattrs containing Skim&rsquo;s annotations, but when that file was opened in Skim, it was unable to read them because it doesn&rsquo;t strip the xattr flags from their names when reading xattrs. And that is the problem with this technique: although the xattrs are, in general, preserved, because most apps don&rsquo;t expect to have to handle xattr flags appended to their names, the preserved xattrs aren&rsquo;t used &#x2013; after all that.<\/p>\n<p>The solution therefore is for all apps which access xattrs by name to drop any xattr flags from the names before using them. This demonstrates the cost of this elegant kludge. As this isn&rsquo;t handled transparently in calls such as <code>getxattr()<\/code> which access xattrs, every app is left to its own devices to handle xattr flags appended to xattr names, which is inefficient and encourages inconsistencies between apps.<\/p>\n<\/blockquote>\n\n<p id=\"xattr-flags-and-icloud-drive-update-2019-07-25\">Update (2019-07-25): <a href=\"https:\/\/twitter.com\/pedantcoder\/status\/1154136908789764096\">Pierre Habouzit<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/pedantcoder\/status\/1154136908789764096\">\n<p>In general xattrs are a difficult challenge to sync because of the fact that it&rsquo;s a thing that has no meaning for the end user, and the problem it&rsquo;s trying to solve is that xattr serve very different purposes, some are metadata for the document (<code>XATTR_FLAG_SYNCABLE<\/code>), some are about metadata tied to the machine you&rsquo;re on and make no sense on another machine (<code>XATTR_FLAG_NO_EXPORT<\/code>), or is privacy sensitive.<\/p>\n<p>The two motivations FWIW are completely for good user experience for 3 reasons:<\/p>\n<ul><li>privacy<\/li>\n<li>not blowing up your data plan because you have an xattr used for indexing e.g. that keeps being updated<\/li>\n<li>avoiding fake &ldquo;conflicts&rdquo; in the sync UI that would be extremely confusing.<\/li><\/ul>\n<p>is it more work for developers? yes.<\/p>\n<p>but this is to eventually get a better user experience. syncing everything by default, because the sync engine cannot understand what is a meaningful change and what isn&rsquo;t, would pop up the user due to conflicts on xattrs ALL THE F-ing time.<\/p>\n<p>so instead we rely on developers to tell us what is really important to sync for the document to be whole (and in general we prefer packages with metadata in a plist inside the document or in a Resource\/ subdir of the bundle).<\/p>\n<\/blockquote>\n<p>To be clear, I think the flags seem to do a good job of solving real problems. I <a href=\"https:\/\/twitter.com\/pedantcoder\/status\/1154183361746726912\">just<\/a> don&rsquo;t think their existence was communicated very well, and the implementation&mdash;combining them with the name&mdash;is not very friendly to pre-existing data (or xattrs that need to change flags later).<\/p>\n\n<p id=\"xattr-flags-and-icloud-drive-update-2019-07-26\">Update (2019-07-26): <a href=\"https:\/\/eclecticlight.co\/2019\/07\/26\/how-do-the-finder-terminal-and-spotlight-handle-extended-attribute-flags\/\">Howard Oakley<\/a>:<\/p>\n<blockquote cite=\"https:\/\/eclecticlight.co\/2019\/07\/26\/how-do-the-finder-terminal-and-spotlight-handle-extended-attribute-flags\/\">\n<p>Jonathan Levin &#x2013; who of course does know all about these, and has now added <a href=\"http:\/\/newosxbook.com\/ChangeLog.html#v1v131\">a short section<\/a> about them to volume I of his reference books on Apple&rsquo;s operating systems &#x2013; points out that xattr flags only affect copy behaviour under the <code>copyfile(3)<\/code> API. That means that copies made using the Finder <em>will<\/em> respect them, and will strip xattrs where so instructed, but <code>cp<\/code> in Terminal doesn&rsquo;t, and preserves all xattrs regardless of their flags. That can of course be a mixed blessing.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Howard Oakley: If you work with xattrs, you&rsquo;ve probably already seen this in xattrs whose name ends with a hash # then one or more characters: that&rsquo;s actually the flags, not part of the name, what Apple refers to as a &lsquo;property list&rsquo;. To avoid confusion I won&rsquo;t use that term here, but refer to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2019-07-23T20:41:51Z","apple_news_api_id":"e2ca4224-942b-4c14-b4d5-f27c2b13c35d","apple_news_api_modified_at":"2019-12-19T19:57:19Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAABQ==","apple_news_api_share_url":"https:\/\/apple.news\/A4spCJJQrTBS01fJ8KxPDXQ","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[2],"tags":[1902,913,30,1609,608,71,269],"class_list":["post-26045","post","type-post","status-publish","format-standard","hentry","category-technology","tag-extended-attributes","tag-icloud-drive","tag-mac","tag-macos-10-14","tag-metadata","tag-programming","tag-syncing"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/26045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=26045"}],"version-history":[{"count":5,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/26045\/revisions"}],"predecessor-version":[{"id":26080,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/26045\/revisions\/26080"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=26045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=26045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=26045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}