zkfuse.cc 142 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #define FUSE_USE_VERSION 26
  19. #ifdef HAVE_CONFIG_H
  20. #include <config.h>
  21. #endif
  22. #undef _GNU_SOURCE
  23. #define _GNU_SOURCE
  24. extern "C" {
  25. #include <fuse.h>
  26. #include <ulockmgr.h>
  27. }
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include <fcntl.h>
  32. #include <dirent.h>
  33. #include <errno.h>
  34. #include <sys/time.h>
  35. #ifdef HAVE_SETXATTR
  36. #include <sys/xattr.h>
  37. #endif
  38. #include <getopt.h>
  39. #include <iostream>
  40. #include <sstream>
  41. #include <map>
  42. #include <string>
  43. #include <boost/utility.hpp>
  44. #include <boost/weak_ptr.hpp>
  45. #include "log.h"
  46. #include "mutex.h"
  47. #include "zkadapter.h"
  48. #define ZOOKEEPER_ROOT_CHILDREN_WATCH_BUG
  49. /**
  50. Typedef for ZooKeeperAdapter::Data.
  51. */
  52. typedef std::string Data;
  53. /**
  54. Typedef for ZooKeeperAdapter::NodeNames.
  55. */
  56. typedef vector<std::string> NodeNames;
  57. #define MAX_DATA_SIZE 1024;
  58. DEFINE_LOGGER(LOG, "zkfuse");
  59. inline
  60. uint64_t millisecsToSecs(uint64_t millisecs)
  61. {
  62. return millisecs / 1000;
  63. }
  64. inline
  65. uint64_t secsToMillisecs(uint64_t secs)
  66. {
  67. return secs * 1000;
  68. }
  69. inline
  70. uint64_t nanosecsToMillisecs(uint64_t nanosecs)
  71. {
  72. return nanosecs / 1000000;
  73. }
  74. inline
  75. uint64_t timespecToMillisecs(const struct timespec & ts)
  76. {
  77. return secsToMillisecs(ts.tv_sec) + nanosecsToMillisecs(ts.tv_nsec);
  78. }
  79. typedef boost::shared_ptr<ZooKeeperAdapter> ZooKeeperAdapterSharedPtr;
  80. /**
  81. * ZkFuseCommon - holds immutable configuration objects.
  82. *
  83. * No locks are required to access these objects.
  84. * A ZkFuseCommon instance is considered to be a data object and may be copied.
  85. */
  86. class ZkFuseCommon
  87. {
  88. private:
  89. /**
  90. References the ZooKeeperAdapter instance to be used.
  91. */
  92. ZooKeeperAdapterSharedPtr _zkAdapter;
  93. /**
  94. Path to the ZooKeeper root node.
  95. */
  96. std::string _rootPathName;
  97. /**
  98. Name used to access data "file" when the ZK node has
  99. children.
  100. */
  101. std::string _dataFileName;
  102. /**
  103. Suffix added to path components to force interpretation of
  104. path components as directory. This is usually only required
  105. for the last component. For example, ZkFuse may consider
  106. a leaf node a regular file, e.g. /a/b/c/leaf. The suffix
  107. can be used to create child under this node, e.g.
  108. mkdir /a/b/c/leaf{forceDirSuffix}/new_leaf.
  109. */
  110. std::string _forceDirSuffix;
  111. /**
  112. Prefix common to all metadata nodes created by ZkFuse.
  113. */
  114. std::string _metadataNamePrefix;
  115. /**
  116. Path component name that identifies a directory metadata node.
  117. A directory metadata node is currently empty. It is used by ZkFuse
  118. to create a child when mkdir is used. This prevents ZkFuse
  119. from interpreting the new child as a regular file.
  120. */
  121. std::string _dirMetadataName;
  122. /**
  123. Path component name that identifies a regular file metadata node.
  124. A regular metadata node holds metadata required to implement
  125. Posix regular file semantics, such as setting mtime.
  126. */
  127. std::string _regMetadataName;
  128. /**
  129. Number of not-in-use nodes to cache.
  130. */
  131. unsigned _cacheSize;
  132. /**
  133. Assume this userid owns all nodes.
  134. */
  135. const uid_t _uid;
  136. /**
  137. Assume this groupid owns all nodes.
  138. */
  139. const gid_t _gid;
  140. /**
  141. Blocksize used to calculate number of blocks used for stat.
  142. */
  143. const unsigned _blkSize;
  144. public:
  145. /**
  146. Constructor.
  147. */
  148. ZkFuseCommon()
  149. : _zkAdapter(),
  150. _rootPathName("/"),
  151. _dataFileName(),
  152. _forceDirSuffix(),
  153. _metadataNamePrefix(".zkfuse."),
  154. _dirMetadataName(_metadataNamePrefix + "dir"),
  155. _regMetadataName(_metadataNamePrefix + "file"),
  156. _cacheSize(256),
  157. _uid(geteuid()),
  158. _gid(getegid()),
  159. _blkSize(8192)
  160. {
  161. }
  162. /**
  163. Get root path name. Always "/".
  164. \see _rootPathName
  165. */
  166. const std::string & getRootPathName() const
  167. {
  168. return _rootPathName;
  169. }
  170. /**
  171. Get dataFileName - the name for synthesized files to access
  172. ZooKeeper node data.
  173. \see _dataFileName
  174. */
  175. const std::string & getDataFileName() const
  176. {
  177. return _dataFileName;
  178. }
  179. /**
  180. Set dataFileName.
  181. \see getDataFileName
  182. \see _dataFileName
  183. */
  184. void setDataFileName(const std::string & dataFileName)
  185. {
  186. _dataFileName = dataFileName;
  187. }
  188. /**
  189. Get metadataNamePrefix - the common prefix for all ZkFuse created
  190. metadata ZooKeeper nodes.
  191. \see _metadataNamePrefix
  192. */
  193. const std::string & getMetadataNamePrefix() const
  194. {
  195. return _metadataNamePrefix;
  196. }
  197. /**
  198. Get forceDirSuffix - the suffix added to a path component to force
  199. the path component to be treated like a directory.
  200. \see _forceDirSuffix
  201. */
  202. const std::string & getForceDirSuffix() const
  203. {
  204. return _forceDirSuffix;
  205. }
  206. /**
  207. Set forceDirSuffix.
  208. \see getForceDirSuffix
  209. \see _forceDirSuffix
  210. */
  211. void setForceDirSuffix(const std::string & forceDirSuffix)
  212. {
  213. _forceDirSuffix = forceDirSuffix;
  214. }
  215. /**
  216. Get dirMetadataName - path component name of all directory
  217. metadata ZooKeeper nodes.
  218. \see _dirMetadataname
  219. */
  220. const std::string & getDirMetadataName() const
  221. {
  222. return _dirMetadataName;
  223. }
  224. /**
  225. Get regMetadataName - path component name of all regular file
  226. metadata ZooKeeper nodes.
  227. \see _regMetadataname
  228. */
  229. const std::string & getRegMetadataName() const
  230. {
  231. return _regMetadataName;
  232. }
  233. /**
  234. Get number of not-in-use ZkFuseFile instances to to cache.
  235. \see _cacheSize
  236. */
  237. unsigned getCacheSize() const
  238. {
  239. return _cacheSize;
  240. }
  241. /**
  242. Set cache size.
  243. \see getCacheSize
  244. \see _cacheSize
  245. */
  246. void setCacheSize(unsigned v)
  247. {
  248. _cacheSize = v;
  249. }
  250. /**
  251. Get userid.
  252. \see _uid
  253. */
  254. uid_t getUid() const
  255. {
  256. return _uid;
  257. }
  258. /**
  259. Get groupid.
  260. \see _gid
  261. */
  262. gid_t getGid() const
  263. {
  264. return _gid;
  265. }
  266. /**
  267. Get block size.
  268. \see _blkSize
  269. */
  270. unsigned getBlkSize() const
  271. {
  272. return _blkSize;
  273. }
  274. /**
  275. Get ZooKeeperAdapter.
  276. \see _zkAdapter.
  277. */
  278. const ZooKeeperAdapterSharedPtr & getZkAdapter() const
  279. {
  280. return _zkAdapter;
  281. }
  282. /**
  283. Set ZooKeeperAdapter.
  284. \see _zkAdaptor
  285. */
  286. void setZkAdapter(const ZooKeeperAdapterSharedPtr & zkAdapter)
  287. {
  288. _zkAdapter = zkAdapter;
  289. }
  290. };
  291. /**
  292. ZkFuseNameType - identifies the type of the ZkFuse path.
  293. */
  294. enum ZkFuseNameType {
  295. /**
  296. ZkFuse path is not syntheiszed.
  297. ZkFuse should use its default rules to determine the Posix representation
  298. of the path.
  299. */
  300. ZkFuseNameDefaultType = 0,
  301. /**
  302. ZkFuse path is synthesized and identifies the data part of a
  303. ZooKeeper node, i.e. Posix regular file semantics is expected.
  304. */
  305. ZkFuseNameRegType = 1,
  306. /**
  307. ZkFuse path is synthesized and identifies the chidlren part of a
  308. ZooKeeper node, i.e. Posix directory semantics is expected.
  309. */
  310. ZkFuseNameDirType = 2
  311. };
  312. class ZkFuseFile;
  313. typedef ZkFuseFile * ZkFuseFilePtr;
  314. class ZkFuseHandleManagerFactory;
  315. /**
  316. ZkFuseHandleManager - keeps track of all the ZkFuseFile instances
  317. allocated by a ZkFuseHandleManager instance and provides them
  318. with a handle that can be used by FUSE.
  319. It maps a ZooKeeper path to a handle and a handle to a ZkFuse instance.
  320. It also implements the methods that takes path names as arguments, such
  321. as open, mknod, rmdir, and rename.
  322. Memory management
  323. - References ZkFuseFile instances using regular pointers
  324. Smart pointer is not used because reference counts are needed to
  325. determine how many time a node is opened as a regular file or
  326. directory. This also avoids circular smart pointer references.
  327. - Each ZkFuseFile instance holds a reference to its ZkFuseHandleManager
  328. using a boost::shared_ptr. This ensures that the ZkFuseHandleManager
  329. instance that has the handle for the ZkFuseFile instance does not
  330. get garbage collected while the ZkFuseFile instance exists.
  331. Concurrency control
  332. - Except for the immutable ZkFuseCommon, all other member variables
  333. are protected by _mutex.
  334. - A method in this class can hold _mutex when it directly or
  335. indirectly invokes ZkFuseFile methods. A ZkFuseFile method that holds
  336. a ZkFuseFile instance _mutex cannot invoke a ZkFuseHandleManager
  337. method that acquires the ZkFuseHandleManager instance's _mutex.
  338. Otherwise, this may cause a dead lock.
  339. - Methods that with names that begin with "_" do not acquire _mutex.
  340. They are usually called by public methods that acquire and hold _mutex.
  341. */
  342. class ZkFuseHandleManager : boost::noncopyable
  343. {
  344. private:
  345. /**
  346. Typedef of handle, which is an int.
  347. */
  348. typedef int Handle;
  349. /**
  350. Typedef of std::map used to map path to handle.
  351. */
  352. typedef std::map<std::string, Handle> Map;
  353. /**
  354. Typedef of std::vector used to map handle to ZkFuseFile instances.
  355. */
  356. typedef std::vector<ZkFuseFilePtr> Files;
  357. /**
  358. Typedef of std::vector used to hold unused handles.
  359. */
  360. typedef std::vector<Handle> FreeList;
  361. /**
  362. Typedef of boost::weak_ptr to the ZkFuseHandleManager instance.
  363. */
  364. typedef boost::weak_ptr<ZkFuseHandleManager> WeakPtr;
  365. /* Only ZkFuseHandleManagerFactory can create instances of this class */
  366. friend class ZkFuseHandleManagerFactory;
  367. /**
  368. Contains common configuration.
  369. Immutable so that it can be accessed without locks.
  370. */
  371. const ZkFuseCommon _common;
  372. /**
  373. Maps a path name to a Handle.
  374. */
  375. Map _map;
  376. /**
  377. Maps a handle to a ZkFuseFile instances.
  378. Also holds pointers to all known ZkFuseFile instances.
  379. An element may point to an allocated ZkFuseFile instance or be NULL.
  380. An allocated ZkFuseFile instance may be in one of the following states:
  381. - in-use
  382. Currently open, i.e. the ZkFuseFile instance's reference count
  383. greater than 0.
  384. - in-cache
  385. Not currently open, i.e. the ZkFuseFile instances's
  386. reference count is 0.
  387. */
  388. Files _files;
  389. /**
  390. List of free'ed handles.
  391. */
  392. FreeList _freeList;
  393. /**
  394. Mutex used to protect this instance.
  395. */
  396. mutable zkfuse::Mutex _mutex;
  397. /**
  398. Count of number of in-use entries.
  399. It used to calculate number of cached nodes.
  400. Number cached nodes is (_files.size() - _numInUse).
  401. */
  402. unsigned _numInUse;
  403. /**
  404. WeakPtr to myself.
  405. */
  406. WeakPtr _thisWeakPtr;
  407. /**
  408. Obtain a handle for the given path.
  409. - If path is not known, then allocate a new handle and increment
  410. _numInUse, and set newFile to true. The allocated
  411. ZkFuseFile instance's reference count should be 1.
  412. - If path is known, increase the corresponding
  413. ZkFuseFile instance's reference count.
  414. \return the allocated handle.
  415. \param path the path to lookup.
  416. \param newFile indicates whether a new handle has been allocated.
  417. */
  418. Handle allocate(const std::string & path, bool & newFile);
  419. /**
  420. Constructor.
  421. \param common the immutable common configuration.
  422. \param reserve number of elements to pre-allocate for
  423. _files and _freeList.
  424. */
  425. ZkFuseHandleManager(
  426. const ZkFuseCommon & common,
  427. const unsigned reserve)
  428. : _common(common),
  429. _files(),
  430. _freeList(),
  431. _mutex(),
  432. _numInUse(0)
  433. {
  434. _files.reserve(reserve);
  435. _files[0] = NULL; /* 0 never allocated */
  436. _files.resize(1);
  437. _freeList.reserve(reserve);
  438. }
  439. public:
  440. /**
  441. Typedef for boost::shared_ptr for this ZkFuseHandleManager class.
  442. */
  443. typedef boost::shared_ptr<ZkFuseHandleManager> SharedPtr;
  444. /**
  445. Destructor.
  446. */
  447. ~ZkFuseHandleManager()
  448. {
  449. }
  450. /**
  451. Get the ZkFuseFile instance for a handle.
  452. \return the ZkFuseFile instance identified by the handle.
  453. \param handle get ZkFuseFile instance for this handle.
  454. */
  455. ZkFuseFilePtr getFile(Handle handle) const
  456. {
  457. AutoLock lock(_mutex);
  458. return _files[handle];
  459. }
  460. /**
  461. Get the immutable common configuration.
  462. \return the common configuration instance.
  463. */
  464. const ZkFuseCommon & getCommon() const
  465. {
  466. return _common;
  467. }
  468. /**
  469. Deallocate a previously allocated handle.
  470. This decrements the reference count of the corresponding
  471. ZkFuseFile instance. If the reference count becomes zero,
  472. decrement _numInUse. It may also cause the ZkFuseFile instance
  473. to be reclaimed if there are too many cached ZkFuseFile instances.
  474. The ZkFuseFile instance should be reclaimed if the number of
  475. unused ZkFuseFile instances exceeds the configured cache size, i.e.
  476. (_files.size() - _numInUse) > _common.getCacheSize()
  477. and the ZkFuseFile instance has a reference count of zero.
  478. Reclaiming a ZkFuseFile instance involves removing the ZkFuseFile
  479. instance's path to handle mapping from _map and the handle to the
  480. ZkFuseFile instance mapping from _files, adding the handle to
  481. the _freeList, and finally deleting the ZkFuseFile instance.
  482. \param handle the handle that should be deallocated.
  483. */
  484. void deallocate(Handle handle);
  485. /**
  486. Handles ZooKeeper session events.
  487. It invokes the known ZkFuseFile instances to let them know
  488. that their watches will no longer be valid.
  489. */
  490. void eventReceived(const ZKWatcherEvent & event);
  491. /**
  492. Get data from the specified the ZooKeeper path.
  493. \return 0 if successful, otherwise return negative errno.
  494. \param path the path of the ZooKeeper node.
  495. \param data return data read.
  496. */
  497. int getData(const std::string & path, Data & data);
  498. /**
  499. Set data into the specified ZooKeeper path.
  500. \return 0 if successful, otherwise return negative errno.
  501. \param path the path of the ZooKeeper node.
  502. \param data the data to be written.
  503. \param exists set to true if this path exists.
  504. \param doFlush set to true if new data should be flushed to ZooKeeper.
  505. */
  506. int setData(const std::string & path,
  507. const Data & data,
  508. bool exists,
  509. bool doFlush);
  510. /**
  511. Create a ZooKeeper node to represent a ZkFuse file or directory.
  512. \return handle if successful, otherwise return negative errno.
  513. \param path to create.
  514. \param mode should be either S_IFDIR for directory or
  515. S_IFREG for regular file.
  516. \param mayExist if set and the ZooKeeper node already exist, return
  517. valid handle instead of -EEXIST.
  518. \param created returns whether a new ZooKeeper node had been created.
  519. */
  520. int mknod(const std::string & path,
  521. mode_t mode,
  522. bool mayExist,
  523. bool & created);
  524. /**
  525. Open a ZooKeeper node.
  526. The justCreated argument is used to differentiate if the _deleted flag
  527. of the ZkFuseFile instance is to be trusted (i.e. the path
  528. does not exist in ZooKeeper.) The _deleted flag is trusted
  529. if the ZkFuseFile instance is known to exist in ZooKeeper after
  530. invoking ZooKeeper with the path.
  531. If justCreated is true, then the ZkFuseFile instance was just created.
  532. The ZkFuseFile constructor sets the _deleted flag to true because
  533. path is not known to exist and hence should not be accessed.
  534. The justCreated flag will force the ZkFuseFile instance to invoke
  535. ZooKeeper to determine if the path exists.
  536. \return handle if successful, otherwise return negative errno.
  537. \param path the path to open.
  538. \param justCreated indicates if this is newly created ZkFuseFile instance.
  539. */
  540. int open(const std::string & path, bool justCreated);
  541. /**
  542. Remove a ZkFuse directory.
  543. If force is not set, then the ZooKeeper node will be removed only
  544. if it has no data and no child nodes except ZkFuse metadata nodes.
  545. \return 0 if successful, otherwise return negative errno.
  546. \param path the path to remove.
  547. \param force force removal, i.e. bypass checks.
  548. */
  549. int rmdir(const char * path, bool force = false);
  550. /**
  551. Make a ZkFuse directory.
  552. ZkFuse represents a ZooKeeper node with no data and no children
  553. as a regular file. In order to differentiate a newly created
  554. directory from an empty regular file, mkdir will create a directory
  555. metadata node as a child of the directory.
  556. \return 0 if successful, otherwise return negative errno.
  557. \param path the path of the directory to create.
  558. \param mode create directory with this mode
  559. (mode currently not implemented).
  560. */
  561. int mkdir(const char * path, mode_t mode);
  562. /**
  563. Remove a ZkFuse regular file.
  564. A file is the abstraction for the data part of a ZooKeeper node.
  565. - If ZkFuse represents a ZooKeeper node as a directory, the data part
  566. of the node is represented by synthesizing a name for this file. This
  567. synthesized name is visible through readdir if the ZooKeeper node's
  568. data is not empty. Removing such a file is done by truncating
  569. the ZooKeeper node's data to 0 length.
  570. - If ZkFuse represents a ZooKeeper node as a file, then removing the
  571. is done by removing the ZooKeeper node (and its metadata).
  572. \return 0 if successful, otherwise return negative errno.
  573. \param path the path of the file to remove.
  574. */
  575. int unlink(const char * path);
  576. /**
  577. Get attributes of a ZkFuse regular file or directory.
  578. \return 0 if successful, otherwise return negative errno.
  579. \param path get attributes for this path
  580. \param stbuf store attributes here.
  581. */
  582. int getattr(const char * path, struct stat & stbuf);
  583. /**
  584. Rename a ZkFuse regular file.
  585. It creates a new ZooKeeper node at toPath, copies data and file
  586. metadata from the ZooKeeper node at fromPath to the new node,
  587. and deletes the current ZooKeeper node. If the current ZooKeeper
  588. node is not deleted if the new ZooKeeper node cannot be created
  589. or the data copy fails.
  590. It cannot be used to rename a directory.
  591. \return 0 if successful, otherwise return negative errno.
  592. \param fromPath the current path.
  593. \param toPath rename to this path.
  594. */
  595. int rename(const char * fromPath, const char * toPath);
  596. /**
  597. Add a child ZooKeeper path to the children information cache
  598. of the ZkFuseFile instance that caches the parent ZooKeeper node.
  599. This is used to add a child path after a new ZooKeeper node has
  600. been created to the children information cache of the parent
  601. ZooKeeper node. This is needed because waiting for the children
  602. changed event to update the cache may result in inconsistent local
  603. views of the changes.
  604. \see removeChildFromParent
  605. \parama childPath the path of the child ZooKeeper node.
  606. */
  607. void addChildToParent(const std::string & childPath) const;
  608. /**
  609. Remove a child ZooKeeper path from the children information cache
  610. of the ZkFuseFile instance that caches the parent ZooKeeper node.
  611. For example, this should happen whenever a path is deleted.
  612. This child information cache of the parent will eventually be
  613. invalidated by watches. However, the delivery of the children
  614. change event may come after the next access and thus provide
  615. the client with an inconsistent view. One example is that
  616. client deletes the last file in a directory, but the children
  617. changed event is not delivered before the client invokes rmdir.
  618. to remove the parent. In this case, the rmdir fails because
  619. the cached children information of the parent indicates the
  620. "directory" is not empty.
  621. \param childPath the path of the child ZooKeeper node.
  622. */
  623. void removeChildFromParent(const std::string & childPath) const;
  624. /**
  625. Return the path for the parent of the specified ZooKeeper path.
  626. \return the parent path.
  627. \param childPath the child path.
  628. */
  629. std::string getParentPath(const std::string & childPath) const;
  630. /**
  631. Return the ZooKeeper path from a ZkFuse path.
  632. The ZkFuse path may be a synthesized path. For example, a synthesized
  633. path is required to access the data part of a ZooKeeper node's
  634. data when ZkFuse represents the ZooKeeper node as directory.
  635. A synthesized path is also required to create a child ZooKeeper node
  636. under a ZooKeeper node that is represented by a regular file.
  637. \return the ZooKeeper path for path.
  638. \param path the ZkFuse path, which may be a synthesized path.
  639. \param nameType indicate whether the ZkFuse path is synthesized and
  640. whether the synthesized ZkFuse path identifies a
  641. directory or a regular file.
  642. */
  643. std::string getZkPath(const char * path, ZkFuseNameType & nameType) const;
  644. };
  645. /**
  646. ZkFuseHandleManagerFactory - factory for ZkFuseHandleManager.
  647. This is the only way to create a ZkFuseHandleManager instance.
  648. to make sure that _thisWeakPtr of the instance is intialized
  649. after the instance is created.
  650. */
  651. class ZkFuseHandleManagerFactory
  652. {
  653. public:
  654. /**
  655. Create an instance of ZkFuseHandleManager.
  656. \return the created ZkFuseHandleManager instance.
  657. \param common the common configuration.
  658. \param reserve initially reserve space for this number of handles.
  659. */
  660. static ZkFuseHandleManager::SharedPtr create(
  661. const ZkFuseCommon & common,
  662. unsigned reserve = 1000)
  663. {
  664. ZkFuseHandleManager::SharedPtr manager
  665. (new ZkFuseHandleManager(common, reserve));
  666. manager->_thisWeakPtr = manager;
  667. return manager;
  668. }
  669. };
  670. /**
  671. ZkFuseAutoHandle - automatically closes handle.
  672. It holds an opened handle and automatically closes this handle
  673. when it is destroyed. This enables code that open a handle
  674. to be exception safe.
  675. */
  676. class ZkFuseAutoHandle
  677. {
  678. private:
  679. /**
  680. Typedef for Handle which is an int.
  681. */
  682. typedef int Handle;
  683. /**
  684. Holds a reference to the ZkFuseHandlerManager instance that
  685. allocated the handle.
  686. */
  687. ZkFuseHandleManager::SharedPtr _manager;
  688. /**
  689. The handle that should be closed when this instance is destroyed.
  690. A valid handle has value that is equal or greater than 0.
  691. A negative value indicates an error condition, usually the value
  692. is a negative errno.
  693. */
  694. Handle _handle;
  695. /**
  696. Caches a reference to the ZkFuseFile instance with this handle.
  697. This is a performance optimization so that _manager.getFile(_handle)
  698. is only called once when the handle is initialized.
  699. */
  700. ZkFuseFilePtr _file;
  701. /**
  702. Initialize reference to the ZkFuseFile instance with this handle.
  703. */
  704. void _initFile()
  705. {
  706. if (_handle >= 0) {
  707. _file = _manager->getFile(_handle);
  708. } else {
  709. _file = NULL;
  710. }
  711. }
  712. public:
  713. /**
  714. Constructor - takes an previously opened handle.
  715. \param manager the ZkFuseHandleManager instance who allocated the handle.
  716. \param handle the handle.
  717. */
  718. ZkFuseAutoHandle(
  719. const ZkFuseHandleManager::SharedPtr & manager,
  720. int handle)
  721. : _manager(manager),
  722. _handle(handle),
  723. _file()
  724. {
  725. _initFile();
  726. }
  727. /**
  728. Constructor - open path and remember handle.
  729. \param manager the ZkFuseHandleManager instance who allocated the handle.
  730. \param path open this path and remember its handle in this instance.
  731. */
  732. ZkFuseAutoHandle(
  733. const ZkFuseHandleManager::SharedPtr & manager,
  734. const std::string & path)
  735. : _manager(manager),
  736. _handle(_manager->open(path, false)),
  737. _file()
  738. {
  739. _initFile();
  740. }
  741. /**
  742. Constructor - create path and remember handle.
  743. The creation mode indicates whether the path identifies a regular file
  744. or a directory.
  745. \param manager the ZkFuseHandleManager instance who allocated the handle.
  746. \param path create this path and remember its handle in this instance.
  747. \param mode the creation mode for the path, should be either
  748. S_IFDIR or S_IFDIR.
  749. \param mayExist, if set and the path already exists,
  750. then the ZkFuseAutoHandle will hold the handle
  751. for the path instead of -EEXIST.
  752. If not set and the path does not exist, then the handle
  753. be -EEXIST.
  754. */
  755. ZkFuseAutoHandle(
  756. const ZkFuseHandleManager::SharedPtr & manager,
  757. const std::string & path,
  758. mode_t mode,
  759. bool mayExist)
  760. : _manager(manager),
  761. _handle(-1),
  762. _file()
  763. {
  764. bool created;
  765. _handle = _manager->mknod(path, mode, mayExist, created);
  766. _initFile();
  767. }
  768. /**
  769. Destructor - closes the handle.
  770. */
  771. ~ZkFuseAutoHandle()
  772. {
  773. reset();
  774. }
  775. /**
  776. Get the handle.
  777. \see _handle
  778. */
  779. int get() const
  780. {
  781. return _handle;
  782. }
  783. /**
  784. Get the ZkFuseFile instance of the handle.
  785. \see _file
  786. */
  787. ZkFuseFilePtr getFile() const
  788. {
  789. return _file;
  790. }
  791. /**
  792. Forget the handle, don't close the handle.
  793. */
  794. void release()
  795. {
  796. _handle = -1;
  797. _file = NULL;
  798. }
  799. /**
  800. Change the remembered handle.
  801. It will close the current handle (if valid).
  802. */
  803. void reset(int handle = -1);
  804. };
  805. /**
  806. ZkFuseStat - C++ wrapper for ZooKeeper Stat.
  807. This wrapper provides ZooKeeper Stat will constructors that
  808. initializes the instance variables of Stat.
  809. */
  810. class ZkFuseStat : public Stat
  811. {
  812. public:
  813. /**
  814. Constructor - clear instance variables.
  815. */
  816. ZkFuseStat()
  817. {
  818. clear();
  819. }
  820. /**
  821. Destructor - do nothing.
  822. */
  823. ~ZkFuseStat()
  824. {
  825. }
  826. /**
  827. Clear instance variables.
  828. */
  829. void clear()
  830. {
  831. czxid = 0;
  832. mzxid = 0;
  833. ctime = 0;
  834. mtime = 0;
  835. version = 0;
  836. cversion = 0;
  837. aversion = 0;
  838. }
  839. };
  840. /**
  841. ZkFuseFile - an instance encapsulates the runtime state of an allocated
  842. ZooKeeper node.
  843. Memory management
  844. - Referenced by the ZkFuseHandleManager that created this instance.
  845. - Uses boost::shared_ptr to reference the ZkFuseHandleManager that
  846. created this instance. This makes sure that this ZkFuseHandleManager
  847. instance cannot be deleted when it has allocated ZkFuseFile instances.
  848. - A ZkFuseHandleManager deletes itself if it can be reclaimed.
  849. It can be reclaimed if it has no watches, its reference count is zero,
  850. and the ZkFuseHandleManager instance would have more than the
  851. configured number of cached ZkFuseFile instances.
  852. - A ZkFuseFile instance cannot be deleted if it has active watches on
  853. its ZooKeeper node. When one of its watches fires, the ZkFuseFile
  854. instance must exist because one of its methods will be invoked
  855. to process the event. If the ZkFuseFile instance has been deleted,
  856. the method will access previously freed memory.
  857. Concurrency control
  858. - _mutex protects the instance variables of an instance.
  859. - Callers should assume that a public method will acquire _mutex.
  860. - Methods of this class may not hold _mutex while invoking an
  861. ZkFuseHandleManager instance.
  862. - Methods that with names that begin with "_" do not acquire _mutex.
  863. They are usually called by public methods that acquire and hold _mutex.
  864. */
  865. class ZkFuseFile : boost::noncopyable
  866. {
  867. public:
  868. /**
  869. Maximum size for the data part of a ZooKeeper node.
  870. */
  871. static const unsigned maxDataFileSize = MAX_DATA_SIZE;
  872. private:
  873. /**
  874. Mode returned by getattr for a ZkFuse directory.
  875. */
  876. static const mode_t dirMode = (S_IFDIR | 0777);
  877. /**
  878. Mode returned by getattr for a ZkFuse regular file.
  879. */
  880. static const mode_t regMode = (S_IFREG | 0777);
  881. /**
  882. References the ZkFuseHandleManager that created this instance.
  883. */
  884. ZkFuseHandleManager::SharedPtr _manager;
  885. /**
  886. Handle for this instance.
  887. */
  888. const int _handle;
  889. /**
  890. Path of the ZooKeeper node represented by this instance.
  891. */
  892. const std::string _path;
  893. /**
  894. Mutex that protects the instance variables of this instance.
  895. */
  896. mutable zkfuse::Mutex _mutex;
  897. /**
  898. Reference count for this instance, i.e. the number of opens
  899. minus the number of closes.
  900. */
  901. int _refCount;
  902. /**
  903. Indicates whether the ZooKeeper node exist.
  904. This flag allows caching of deleted ZooKeeper node to avoid
  905. repeated ZooKeeper lookups for a non-existent path, and avoid
  906. using cached information.
  907. Its value is true if
  908. - it is verified to exist (by calling ZooKeeper), or
  909. - it is existence is unknown because ZooKeeper has not been
  910. invoked to verify its path's existence.
  911. */
  912. bool _deleted;
  913. /**
  914. Count of current number directory opens minus directory closes.
  915. */
  916. int _openDirCount;
  917. /**
  918. Indicates whether cached children information is valid.
  919. It is true if the cached children information is valid.
  920. */
  921. bool _initializedChildren;
  922. /**
  923. Indicates whether there is an outstanding children watch.
  924. It is true if it has an outstanding children watch.
  925. */
  926. bool _hasChildrenListener;
  927. /**
  928. Cached children information.
  929. The cache is valid if _initializedChildren is true.
  930. */
  931. NodeNames _children;
  932. /**
  933. Indicates whether the cached data is valid.
  934. It is true if the cached data and ZooKeeper Stat are valid.
  935. */
  936. bool _initializedData;
  937. /**
  938. Indicates whether there is an outstanding data watch.
  939. It is true if it has an outstanding data watch.
  940. */
  941. bool _hasDataListener;
  942. /**
  943. Indicates whether the cached data (_activeData) has been modified.
  944. It is true if the cached data has been modified.
  945. */
  946. bool _dirtyData;
  947. /**
  948. Currently active data.
  949. To maintain atomicity of updates and emulate Posix semantics,
  950. when a ZkFuse file remains open, the same data will be accessed
  951. by the file's clients. The data will be flushed to ZooKeeper when
  952. the flush method is called. The flush method may be called
  953. explicitly by a client or implicitly when the ZkFuse file is no
  954. longer currently open.
  955. _activeData and _activeStat stores the data and ZooKeeper Stat
  956. that will be accessed by the file's clients.
  957. If there are changes when the ZkFuse file is open, new data is
  958. cached as latest data (by _latestData and _latestStat).
  959. */
  960. Data _activeData;
  961. /**
  962. Currently active ZooKeeper Stat.
  963. \see _activeData
  964. */
  965. ZkFuseStat _activeStat;
  966. /**
  967. Latest data.
  968. This is either the same as _activeData or it is newer. It is newer
  969. is it has been updated by event triggered by a data watch.
  970. */
  971. Data _latestData;
  972. /**
  973. Latest ZooKeeper data.
  974. This is either the same as _activeStat or it is newer. It is newer
  975. is it has been updated by event triggered by a data watch.
  976. */
  977. ZkFuseStat _latestStat;
  978. /**
  979. Get userid.
  980. \return the userid.
  981. */
  982. uid_t _getUid() const
  983. {
  984. return _manager->getCommon().getUid();
  985. }
  986. /**
  987. Get groupid.
  988. \return the groupid.
  989. */
  990. gid_t _getGid() const
  991. {
  992. return _manager->getCommon().getGid();
  993. }
  994. /**
  995. Get block size.
  996. \return the block size.
  997. */
  998. unsigned _getBlkSize() const
  999. {
  1000. return _manager->getCommon().getBlkSize();
  1001. }
  1002. /**
  1003. Get number of children, include metadata children in the count.
  1004. \return the number of children including metadata children.
  1005. */
  1006. unsigned _numChildrenIncludeMeta() const
  1007. {
  1008. unsigned count = _children.size();
  1009. LOG_DEBUG(LOG, "numChildrenIncludeMeta() returns %u", count);
  1010. return count;
  1011. }
  1012. /**
  1013. Get number of children, exclude metadata children in the count.
  1014. \return the number of children excluding metadata children.
  1015. */
  1016. unsigned _numChildrenExcludeMeta() const
  1017. {
  1018. unsigned count = 0;
  1019. for (NodeNames::const_iterator it = _children.begin();
  1020. it != _children.end();
  1021. it++) {
  1022. if (!_isMeta(*it)) {
  1023. count++;
  1024. }
  1025. }
  1026. LOG_DEBUG(LOG, "numChildrenExcludeMeta() returns %u", count);
  1027. return count;
  1028. }
  1029. /**
  1030. Whether the ZooKeeper node has children, include metadata
  1031. children.
  1032. \return true if it has children including metadata children.
  1033. */
  1034. bool _hasChildrenIncludeMeta() const
  1035. {
  1036. return _numChildrenIncludeMeta() != 0;
  1037. }
  1038. /**
  1039. Return true if the ZooKeeper node has children, include metadata
  1040. children.
  1041. \return true if it has children excluding metadata children.
  1042. */
  1043. bool _hasChildrenExcludeMeta() const
  1044. {
  1045. return _numChildrenExcludeMeta() != 0;
  1046. }
  1047. /**
  1048. Whether the ZooKeeper node has data.
  1049. \return true if _activeData is not empty.
  1050. */
  1051. bool _hasData() const
  1052. {
  1053. return _activeData.empty() == false;
  1054. }
  1055. /**
  1056. Whether the ZooKeeper node has child with the specified path.
  1057. \return true if the ZooKeeper node has a child with the specified path.
  1058. \param childPath the path of the child.
  1059. */
  1060. bool _hasChildPath(const std::string & childPath) const
  1061. {
  1062. bool hasChild =
  1063. std::find(_children.begin(), _children.end(), childPath)
  1064. != _children.end();
  1065. LOG_DEBUG(LOG, "hasChild(childPath %s) returns %d",
  1066. childPath.c_str(), hasChild);
  1067. return hasChild;
  1068. }
  1069. /**
  1070. Whether the given path component is a ZkFuse synthesized path
  1071. component.
  1072. A ZkFuse synthesized path component will begin with
  1073. the metadataNamePrefix obtained from the common configuration.
  1074. \see _metadataNamePrefix
  1075. \return true if the path component is a ZkFuse synthesized path
  1076. component.
  1077. \param childName the path component to check if it is synthesized by
  1078. ZkFuse.
  1079. */
  1080. bool _isMeta(const std::string & childName) const
  1081. {
  1082. bool isMeta;
  1083. const std::string & prefix =
  1084. _manager->getCommon().getMetadataNamePrefix();
  1085. unsigned offset =
  1086. (_path.length() > 1 ?
  1087. _path.length() + 1 :
  1088. 1 /* special case for root dir */ );
  1089. unsigned minLength = offset + prefix.length();
  1090. if (childName.length() < minLength ||
  1091. childName.compare(offset, prefix.length(), prefix) != 0) {
  1092. isMeta = false;
  1093. } else {
  1094. isMeta = true;
  1095. }
  1096. LOG_DEBUG(LOG, "isMeta(childName %s) returns %d",
  1097. childName.c_str(), isMeta);
  1098. return isMeta;
  1099. }
  1100. /**
  1101. Build a path for a specific child of the ZooKeeper node.
  1102. This is done by appending "/" (unless it is the ZooKeeper node
  1103. is the root node) and the name of the child.
  1104. \return the path for the specified child of the ZooKeeper node.
  1105. \param name the name of the child.
  1106. */
  1107. std::string _getChildPath(const std::string & name) const
  1108. {
  1109. return buildChildPath(_path, name);
  1110. }
  1111. /**
  1112. Whether the ZooKeeper node has a regular file metadata child node.
  1113. \return true if the ZooKeeper node has a regular file metadata child
  1114. node.
  1115. */
  1116. bool _hasRegMetadata() const
  1117. {
  1118. bool res = _hasChildPath(
  1119. _getChildPath(_manager->getCommon().getRegMetadataName()));
  1120. LOG_DEBUG(LOG, "hasRegMetadata() returns %d", res);
  1121. return res;
  1122. }
  1123. /**
  1124. Whether the ZooKeeper node has a directory metadata child node.
  1125. \return true if the ZooKeeper node has a directory metadata child
  1126. node.
  1127. */
  1128. bool _hasDirMetadata() const
  1129. {
  1130. bool res = _hasChildPath(
  1131. _getChildPath(_manager->getCommon().getDirMetadataName()));
  1132. LOG_DEBUG(LOG, "hasDirMetadata() returns %d", res);
  1133. return res;
  1134. }
  1135. /**
  1136. Whether ZkFuse should present the ZooKeeper node as a ZkFuse regular
  1137. file.
  1138. It should be a ZkFuse regular file it has no children or its
  1139. only children is its regular file metadata child node.
  1140. \return true if the Zookeeper node should be presented as a ZkFuse
  1141. regular file.
  1142. */
  1143. bool _isReg() const
  1144. {
  1145. unsigned numChildrenIncludeMeta = _numChildrenIncludeMeta();
  1146. bool res =
  1147. (numChildrenIncludeMeta == 0) ||
  1148. (numChildrenIncludeMeta == 1 && _hasRegMetadata() == true);
  1149. LOG_DEBUG(LOG, "isReg() returns %d", res);
  1150. return res;
  1151. }
  1152. /**
  1153. Whether ZkFuse should present the ZooKeeper node as a ZkFuse directory.
  1154. It should be a ZkFuse directory if it should not be presented as
  1155. a ZkFuse regular directory.
  1156. \see _isReg
  1157. \return true if the Zookeeper node should be presented as a ZkFuse
  1158. directory.
  1159. */
  1160. bool _isDir() const
  1161. {
  1162. return !_isReg();
  1163. }
  1164. /**
  1165. Whether ZkFuse should present the ZooKeeper node as a ZkFuse regular
  1166. file by taking into account the specified ZkFuseNameType.
  1167. The ZkFuseNameType may override the default ZkFuse presentation of
  1168. a ZooKeeper node.
  1169. \return true if ZkFuse should present the ZooKeeper node as a ZkFuse
  1170. regular file.
  1171. \param nameType specifies the ZkFuseNameType.
  1172. \param doLock whether _mutex should be acquired, it should be true
  1173. if the caller did not acquire _mutex.
  1174. */
  1175. bool _isRegNameType(ZkFuseNameType nameType, bool doLock = false) const
  1176. {
  1177. bool res;
  1178. switch (nameType) {
  1179. case ZkFuseNameRegType:
  1180. res = true;
  1181. break;
  1182. case ZkFuseNameDirType:
  1183. res = false;
  1184. break;
  1185. case ZkFuseNameDefaultType:
  1186. default:
  1187. if (doLock) {
  1188. AutoLock lock(_mutex);
  1189. res = _isReg();
  1190. } else {
  1191. res = _isReg();
  1192. }
  1193. break;
  1194. }
  1195. LOG_DEBUG(LOG, "isRegNameType(nameType %d) returns %d",
  1196. int(nameType), res);
  1197. return res;
  1198. }
  1199. /**
  1200. Whether ZkFuse should present the ZooKeeper node as a ZkFuse
  1201. directory by taking into account the specified ZkFuseNameType.
  1202. The ZkFuseNameType may override the default ZkFuse presentation of
  1203. a ZooKeeper node.
  1204. \return true if ZkFuse should present the ZooKeeper node as a ZkFuse
  1205. directory.
  1206. \param nameType specifies the ZkFuseNameType.
  1207. \param doLock whether _mutex should be acquired, it should be true
  1208. if the caller did not acquire _mutex.
  1209. */
  1210. bool _isDirNameType(ZkFuseNameType nameType, bool doLock = false) const
  1211. {
  1212. bool res;
  1213. switch (nameType) {
  1214. case ZkFuseNameRegType:
  1215. res = false;
  1216. break;
  1217. case ZkFuseNameDirType:
  1218. res = true;
  1219. break;
  1220. case ZkFuseNameDefaultType:
  1221. default:
  1222. if (doLock) {
  1223. AutoLock lock(_mutex);
  1224. res = _isDir();
  1225. } else {
  1226. res = _isDir();
  1227. }
  1228. break;
  1229. }
  1230. LOG_DEBUG(LOG, "isDirNameType(nameType %d) returns %d",
  1231. int(nameType), res);
  1232. return res;
  1233. }
  1234. /**
  1235. ZkFuse regular file metadata.
  1236. */
  1237. struct Metadata {
  1238. /**
  1239. Version of the ZooKeeper node data that this metadata is good for.
  1240. */
  1241. uint32_t version;
  1242. /**
  1243. Acces time in milliseconds.
  1244. */
  1245. uint64_t atime;
  1246. /**
  1247. Modified time in milliseconds.
  1248. */
  1249. uint64_t mtime;
  1250. /**
  1251. Constructor.
  1252. */
  1253. Metadata()
  1254. : version(0),
  1255. atime(0),
  1256. mtime(0)
  1257. {
  1258. }
  1259. };
  1260. /**
  1261. Encode Metadata into Data so that it can be stored in a metadata
  1262. ZooKeeper node.
  1263. Each Metadata attribute is encoded as "<key>: <value>" on single line
  1264. terminated by newline.
  1265. \param meta the input Metadata.
  1266. \param data the output Data after encoding.
  1267. */
  1268. void _encodeMetadata(const Metadata & meta, Data & data) const
  1269. {
  1270. LOG_DEBUG(LOG, "encodeMetadata()");
  1271. std::ostringstream oss;
  1272. oss << "version: " << meta.version << endl
  1273. << "atime: " << meta.atime << endl
  1274. << "mtime: " << meta.mtime << endl;
  1275. data = oss.str();
  1276. }
  1277. /**
  1278. Decode Data from a metadata child ZooKeeper node into Metadata.
  1279. Data is a stream of "<key>: <value>" records separated by newline.
  1280. \param data the input Data.
  1281. \param meta the output Metadata after decoding.
  1282. */
  1283. void _decodeMetadata(const Data & data, Metadata & meta) const
  1284. {
  1285. LOG_DEBUG(LOG, "decodeMetadata(data %s)", data.c_str());
  1286. std::istringstream iss(data);
  1287. char key[128];
  1288. char value[1024];
  1289. while (!iss.eof()) {
  1290. key[0] = 0;
  1291. value[0] = 0;
  1292. iss.get(key, sizeof(key), ' ');
  1293. if (iss.eof()) {
  1294. break;
  1295. }
  1296. iss.ignore(32, ' ');
  1297. iss.getline(value, sizeof(value));
  1298. LOG_DEBUG(LOG, "key %s value %s", key, value);
  1299. if (strcmp(key, "version:") == 0) {
  1300. unsigned long long v = strtoull(value, NULL, 0);
  1301. LOG_DEBUG(LOG, "version: %llu", v);
  1302. meta.version = v;
  1303. }
  1304. else if (strcmp(key, "atime:") == 0) {
  1305. unsigned long long v = strtoull(value, NULL, 0);
  1306. LOG_DEBUG(LOG, "atime: %llu", v);
  1307. meta.atime = v;
  1308. }
  1309. else if (strcmp(key, "mtime:") == 0) {
  1310. unsigned long long v = strtoull(value, NULL, 0);
  1311. LOG_DEBUG(LOG, "mtime: %llu", v);
  1312. meta.mtime = v;
  1313. }
  1314. else {
  1315. LOG_WARN(LOG, "decodeMetadata: path %s unknown key %s %s\n",
  1316. _path.c_str(), key, value);
  1317. }
  1318. }
  1319. LOG_DEBUG(LOG, "decodeMetadata done");
  1320. }
  1321. /**
  1322. Flush data to the ZooKeeper node.
  1323. If cached active data has been modified, flush it to the ZooKeeper node.
  1324. Returns -EIO if the data cannot be written because the cached active
  1325. data is not the expected version, i.e. ZooKeeper returns ZBADVERSION.
  1326. -EIO may also indicate a more general failure, such as unable to
  1327. communicate with ZooKeeper.
  1328. \return 0 if successful, otherwise negative errno.
  1329. */
  1330. int _flush()
  1331. {
  1332. LOG_DEBUG(LOG, "flush() path %s", _path.c_str());
  1333. int res = 0;
  1334. try {
  1335. if (_dirtyData) {
  1336. LOG_DEBUG(LOG, "is dirty, active version %d",
  1337. _activeStat.version);
  1338. _manager->getCommon().getZkAdapter()->
  1339. setNodeData(_path, _activeData, _activeStat.version);
  1340. /* assumes version always increments by one if successful */
  1341. _deleted = false;
  1342. _activeStat.version++;
  1343. _dirtyData = false;
  1344. res = 0;
  1345. }
  1346. else {
  1347. LOG_DEBUG(LOG, "not dirty");
  1348. res = 0;
  1349. }
  1350. } catch (const ZooKeeperException & e) {
  1351. if (e.getZKErrorCode() == ZBADVERSION) {
  1352. LOG_ERROR(LOG, "flush %s bad version, was %d",
  1353. _path.c_str(), _activeStat.version);
  1354. res = -EIO;
  1355. }
  1356. else {
  1357. LOG_ERROR(LOG, "flush %s exception %s",
  1358. _path.c_str(), e.what());
  1359. res = -EIO;
  1360. }
  1361. }
  1362. LOG_DEBUG(LOG, "flush returns %d", res);
  1363. return res;
  1364. }
  1365. /**
  1366. Truncate or expand the size of the cached active data.
  1367. This method only changes the size of the cached active data.
  1368. This change is committed to ZooKeeper when the cached data
  1369. is written to the ZooKeeper node by flush().
  1370. Return -EFBIG is the requested size exceeds the maximum.
  1371. \return 0 if successful, otherwise negative errno.
  1372. \param size the requested size.
  1373. */
  1374. int _truncate(off_t size)
  1375. {
  1376. LOG_DEBUG(LOG, "truncate(size %zu) path %s", size, _path.c_str());
  1377. int res = 0;
  1378. if (!_isInitialized()) {
  1379. LOG_DEBUG(LOG, "not initialized");
  1380. res = -EIO;
  1381. }
  1382. else if (size > _activeData.size()) {
  1383. if (size > maxDataFileSize) {
  1384. LOG_DEBUG(LOG, "size > maxDataFileSize");
  1385. res = -EFBIG;
  1386. } else {
  1387. LOG_DEBUG(LOG, "increase to size");
  1388. _activeData.insert(_activeData.begin() +
  1389. (size - _activeData.size()), 0);
  1390. _dirtyData = true;
  1391. res = 0;
  1392. }
  1393. }
  1394. else if (size < _activeData.size()) {
  1395. LOG_DEBUG(LOG, "decrease to size");
  1396. _activeData.resize(size);
  1397. _dirtyData = true;
  1398. res = 0;
  1399. }
  1400. else {
  1401. LOG_DEBUG(LOG, "do nothing, same size");
  1402. }
  1403. LOG_DEBUG(LOG, "truncate returns %d", res);
  1404. return res;
  1405. }
  1406. /**
  1407. Remove a ZkFuse directory.
  1408. If force is true, then the ZooKeeper node and its decendants
  1409. will be deleted.
  1410. If force is false, then this method implements the semantics
  1411. of removing a ZkFuse directory. It will delete the ZooKeeper node
  1412. only if the ZooKeeper node have no data and no non-metadata
  1413. children.
  1414. - Return -ENOTDIR if the ZooKeeper node is not considered
  1415. to be a directory (after taking into consideration the specified
  1416. ZkFuseNameType).
  1417. - Return -ENOTEMPTY if the ZooKeeper node has data or it has
  1418. non-metadata children.
  1419. - Return -ENOENT if the ZooKeeper cannot be deleted, usually this
  1420. is because it does not exist.
  1421. \return 0 if successful, otherwise negative errno.
  1422. \param nameType the ZkFuseNameType of the path used to specify the
  1423. directory to be removed. It influences whether ZkFuse
  1424. considers the ZooKeeper node to be a regular file or
  1425. directory. \see ZkFuseNameType
  1426. \param force set to true to bypass ZkFuse rmdir semantic check.
  1427. */
  1428. int _rmdir(ZkFuseNameType nameType, bool force)
  1429. {
  1430. LOG_DEBUG(LOG, "rmdir(nameType %d, force %d) path %s",
  1431. int(nameType), force, _path.c_str());
  1432. int res = 0;
  1433. try {
  1434. if (!force && !_isDirNameType(nameType)) {
  1435. LOG_DEBUG(LOG, "failed because not directory");
  1436. res = -ENOTDIR;
  1437. }
  1438. else if (!force && _hasData()) {
  1439. /* rmdir cannot occur if there non-empty "data file" */
  1440. LOG_DEBUG(LOG, "failed because node has data");
  1441. res = -ENOTEMPTY;
  1442. }
  1443. else if (!force && _hasChildrenExcludeMeta()) {
  1444. /* rmdir cannot occur if there are "subdirs" */
  1445. LOG_DEBUG(LOG, "failed because node has children");
  1446. res = -ENOTEMPTY;
  1447. }
  1448. else {
  1449. LOG_DEBUG(LOG, "delete node");
  1450. bool deleted = _manager->getCommon().getZkAdapter()->
  1451. deleteNode(_path, true);
  1452. if (deleted) {
  1453. _deleted = true;
  1454. _clearChildren();
  1455. res = 0;
  1456. } else {
  1457. /* TODO: differentiate delete error conditions,
  1458. * e.g. access permission, not exists, ... ?
  1459. */
  1460. LOG_DEBUG(LOG, "delete failed");
  1461. res = -ENOENT;
  1462. }
  1463. }
  1464. } catch (const std::exception & e) {
  1465. LOG_ERROR(LOG, "rmdir %s exception %s", _path.c_str(), e.what());
  1466. res = -EIO;
  1467. }
  1468. LOG_DEBUG(LOG, "rmdir returns %d", res);
  1469. return res;
  1470. }
  1471. /**
  1472. Remove a ZkFuse regular file.
  1473. This method implements the semantics of removing a ZkFuse regular file.
  1474. - If the ZkFuse regular file represents the data part of the
  1475. ZooKeeper node which is presented as a ZkFuse directory,
  1476. the regular file is virtually deleted by truncating the
  1477. ZooKeeper node's data. Readdir will not synthesize a regular
  1478. file entry for the data part of a ZooKeeper node if
  1479. the ZooKeeper node has no data.
  1480. - If the ZkFuse regular file represents the data part of the
  1481. ZooKeeper node which is presented as a ZkFuse regular file,
  1482. the ZooKeeper node and its decendants are deleted.
  1483. Returns -EISDIR if the ZkFuse regular file cannot be deleted
  1484. because ZkFuse consider it to be a directory.
  1485. \return 0 if successful, otherwise negative errno.
  1486. \param nameType the ZkFuseNameType of the path used to specify the
  1487. directory to be removed. It influences whether ZkFuse
  1488. considers the ZooKeeper node to be a regular file or
  1489. directory. \see ZkFuseNameType
  1490. */
  1491. int _unlink(ZkFuseNameType nameType)
  1492. {
  1493. LOG_DEBUG(LOG, "unlink(nameType %d) path %s",
  1494. int(nameType), _path.c_str());
  1495. int res = 0;
  1496. switch (nameType) {
  1497. case ZkFuseNameRegType:
  1498. if (_isDir()) {
  1499. res = _truncate(0);
  1500. } else {
  1501. res = _rmdir(nameType, true);
  1502. }
  1503. break;
  1504. case ZkFuseNameDirType:
  1505. res = -EISDIR;
  1506. break;
  1507. case ZkFuseNameDefaultType:
  1508. default:
  1509. if (_isReg()) {
  1510. res = _rmdir(nameType, true);
  1511. } else {
  1512. res = -EISDIR;
  1513. }
  1514. break;
  1515. }
  1516. LOG_DEBUG(LOG, "unlink returns %d", res);
  1517. return res;
  1518. }
  1519. /**
  1520. Whether cached children and data are valid.
  1521. \return true if cached children and data are valid.
  1522. */
  1523. bool _isInitialized() const
  1524. {
  1525. return _initializedChildren && _initializedData;
  1526. }
  1527. /**
  1528. Clear and invalidate cached children information.
  1529. */
  1530. void _clearChildren()
  1531. {
  1532. _initializedChildren = false;
  1533. _children.clear();
  1534. }
  1535. /**
  1536. Clear and invalidate cached data.
  1537. */
  1538. void _clearData()
  1539. {
  1540. _initializedData = false;
  1541. _dirtyData = false;
  1542. _activeData.clear();
  1543. _activeStat.clear();
  1544. _latestData.clear();
  1545. _latestStat.clear();
  1546. }
  1547. /**
  1548. Whether the ZkFuseFile instance is a zombie.
  1549. It is a zombie if it is not currently open, i.e. its reference count
  1550. is 0.
  1551. */
  1552. bool _isZombie() const
  1553. {
  1554. return (_refCount == 0);
  1555. }
  1556. /**
  1557. Whether the ZkFuseFile instance is currently opened as a regular file
  1558. only once.
  1559. It is used to determine when the cached data can be replaced with
  1560. the latest data. \see _activeData.
  1561. \return true if its currently opened as a regular file only once.
  1562. */
  1563. bool _isOnlyRegOpen() const
  1564. {
  1565. return ((_refCount - _openDirCount) == 1);
  1566. }
  1567. /**
  1568. Get attributes without accessing metadata.
  1569. The atime and mtime returned does not take into consideration
  1570. overrides present in a matadata file.
  1571. \return 0 if successful, otherwise negative errno.
  1572. \param stbuf return attributes here.
  1573. \param nameType specifies the ZkFuseNameType of the ZkFuse path used
  1574. to get attributes. It influences whether the directory
  1575. or regular file attributes are returned.
  1576. */
  1577. int _getattrNoMetaAccess(struct stat & stbuf, ZkFuseNameType nameType) const
  1578. {
  1579. int res = 0;
  1580. if (_deleted) {
  1581. LOG_DEBUG(LOG, "deleted");
  1582. res = -ENOENT;
  1583. }
  1584. else if (!_isInitialized()) {
  1585. LOG_DEBUG(LOG, "not initialized");
  1586. res = -EIO;
  1587. }
  1588. else {
  1589. assert(_isInitialized());
  1590. bool isRegular = _isRegNameType(nameType);
  1591. if (isRegular) {
  1592. LOG_DEBUG(LOG, "regular");
  1593. stbuf.st_mode = regMode;
  1594. stbuf.st_nlink = 1;
  1595. stbuf.st_size = _activeData.size();
  1596. } else {
  1597. LOG_DEBUG(LOG, "directory");
  1598. stbuf.st_mode = dirMode;
  1599. stbuf.st_nlink =
  1600. _children.size() + (_activeData.empty() ? 0 : 1);
  1601. stbuf.st_size = stbuf.st_nlink;
  1602. }
  1603. stbuf.st_uid = _getUid();
  1604. stbuf.st_gid = _getGid();
  1605. /* IMPORTANT:
  1606. * Conversion to secs from millisecs must occur before
  1607. * assigning to st_atime, st_mtime, and st_ctime. Otherwise
  1608. * truncating from 64-bit to 32-bit will cause lost of
  1609. * most significant 32-bits before converting to secs.
  1610. */
  1611. stbuf.st_atime = millisecsToSecs(_activeStat.mtime);
  1612. stbuf.st_mtime = millisecsToSecs(_activeStat.mtime);
  1613. stbuf.st_ctime = millisecsToSecs(_activeStat.ctime);
  1614. stbuf.st_blksize = _getBlkSize();
  1615. stbuf.st_blocks =
  1616. (stbuf.st_size + stbuf.st_blksize - 1) / stbuf.st_blksize;
  1617. res = 0;
  1618. }
  1619. return res;
  1620. }
  1621. /**
  1622. Get the context that should be registered with the data and
  1623. children watches.
  1624. The returned context is a pointer to the ZkFuseFile instance
  1625. cast to the desired ContextType.
  1626. \return the context.
  1627. */
  1628. ZooKeeperAdapter::ContextType _getZkContext() const
  1629. {
  1630. return (ZooKeeperAdapter::ContextType) NULL;
  1631. }
  1632. /**
  1633. DataListener - listener that listens for ZooKeeper data events
  1634. and calls dataEventReceived on the ZkFuseFile instance
  1635. identified by the event context.
  1636. \see dataEventReceived
  1637. */
  1638. class DataListener : public ZKEventListener {
  1639. public:
  1640. /**
  1641. Received a data event and invoke ZkFuseFile instance obtained from
  1642. event context to handle the event.
  1643. */
  1644. virtual void eventReceived(const ZKEventSource & source,
  1645. const ZKWatcherEvent & event)
  1646. {
  1647. assert(event.getContext() != 0);
  1648. ZkFuseFile * file = static_cast<ZkFuseFile *>(event.getContext());
  1649. file->dataEventReceived(event);
  1650. }
  1651. };
  1652. /**
  1653. DataListener - listener that listens for ZooKeeper children events
  1654. and calls childrenEventReceived on the ZkFuseFile instance
  1655. identified by the event context.
  1656. \see childrenEventReceived
  1657. */
  1658. class ChildrenListener : public ZKEventListener {
  1659. public:
  1660. /**
  1661. Received a children event and invoke ZkFuseFile instance obtained from
  1662. event context to handle the event.
  1663. */
  1664. virtual void eventReceived(const ZKEventSource & source,
  1665. const ZKWatcherEvent & event)
  1666. {
  1667. assert(event.getContext() != 0);
  1668. ZkFuseFile * file = static_cast<ZkFuseFile *>(event.getContext());
  1669. file->childrenEventReceived(event);
  1670. }
  1671. };
  1672. /**
  1673. Globally shared DataListener.
  1674. */
  1675. static DataListener _dataListener;
  1676. /**
  1677. Globally shared ChildrenListener.
  1678. */
  1679. static ChildrenListener _childrenListener;
  1680. public:
  1681. /**
  1682. Constructor.
  1683. Sets reference count to one, i.e. it has been constructed because
  1684. a client is trying to open the path. \see _refCount.
  1685. Sets deleted to true. \see _deleted.
  1686. Sets number of currently directory opens to zero. \see _openDirCount.
  1687. Invalidate cach for children information and data.
  1688. \param manager the ZkFuseHandleManager instance who is creating this
  1689. ZkFuseFile instance.
  1690. \param handle the handle assigned by the ZkFuseHandleManager instance
  1691. for this ZkFuseFile instance.
  1692. \param path the ZooKeeper path represented by this ZkFuseFile instance.
  1693. */
  1694. ZkFuseFile(const ZkFuseHandleManager::SharedPtr & manager,
  1695. const int handle,
  1696. const std::string & path)
  1697. : _manager(manager),
  1698. _handle(handle),
  1699. _path(path),
  1700. _mutex(),
  1701. _refCount(1),
  1702. _deleted(true),
  1703. /* children stuff */
  1704. _openDirCount(0),
  1705. _initializedChildren(false),
  1706. _hasChildrenListener(false),
  1707. _children(),
  1708. /* data stuff */
  1709. _initializedData(false),
  1710. _hasDataListener(false),
  1711. _dirtyData(false),
  1712. _activeData(),
  1713. _activeStat(),
  1714. _latestData(),
  1715. _latestStat()
  1716. {
  1717. LOG_DEBUG(LOG, "constructor() path %s", _path.c_str());
  1718. }
  1719. /**
  1720. Destructor.
  1721. */
  1722. ~ZkFuseFile()
  1723. {
  1724. LOG_DEBUG(LOG, "destructor() path %s", _path.c_str());
  1725. assert(_isZombie());
  1726. _clearChildren();
  1727. _clearData();
  1728. }
  1729. /**
  1730. Whether the ZooKeeper node represented by this ZkFuseFile instance
  1731. has been deleted.
  1732. \see _deleted
  1733. \return true if it is deleted.
  1734. */
  1735. bool isDeleted() const
  1736. {
  1737. AutoLock lock(_mutex);
  1738. return _deleted;
  1739. }
  1740. /**
  1741. Return the path of the ZooKeeper node represented by this ZkFuseFile
  1742. instance.
  1743. \see _path.
  1744. \return the ZooKeeper node's path.
  1745. */
  1746. const string & getPath() const
  1747. {
  1748. return _path;
  1749. }
  1750. /**
  1751. Add a childPath to the children information cache.
  1752. \return 0 if successful, otherwise return negative errno.
  1753. \param childPath the ZooKeeper path of the child.
  1754. */
  1755. int addChild(const std::string & childPath)
  1756. {
  1757. LOG_DEBUG(LOG, "addChild(childPath %s) path %s",
  1758. childPath.c_str(), _path.c_str());
  1759. int res = 0;
  1760. {
  1761. AutoLock lock(_mutex);
  1762. if (_initializedChildren) {
  1763. NodeNames::iterator it =
  1764. std::find(_children.begin(), _children.end(), childPath);
  1765. if (it == _children.end()) {
  1766. LOG_DEBUG(LOG, "child not found, adding child path");
  1767. _children.push_back(childPath);
  1768. res = 0;
  1769. }
  1770. else {
  1771. LOG_DEBUG(LOG, "child found");
  1772. res = -EEXIST;
  1773. }
  1774. }
  1775. }
  1776. LOG_DEBUG(LOG, "addChild returns %d", res);
  1777. return res;
  1778. }
  1779. /**
  1780. Remove a childPath from the children information cache.
  1781. \return 0 if successful, otherwise return negative errno.
  1782. \param childPath the ZooKeeper path of the child.
  1783. */
  1784. int removeChild(const std::string & childPath)
  1785. {
  1786. LOG_DEBUG(LOG, "removeChild(childPath %s) path %s",
  1787. childPath.c_str(), _path.c_str());
  1788. int res = 0;
  1789. {
  1790. AutoLock lock(_mutex);
  1791. if (_initializedChildren) {
  1792. NodeNames::iterator it =
  1793. std::find(_children.begin(), _children.end(), childPath);
  1794. if (it != _children.end()) {
  1795. LOG_DEBUG(LOG, "child found");
  1796. _children.erase(it);
  1797. res = 0;
  1798. }
  1799. else {
  1800. LOG_DEBUG(LOG, "child not found");
  1801. res = -ENOENT;
  1802. }
  1803. }
  1804. }
  1805. LOG_DEBUG(LOG, "removeChild returns %d", res);
  1806. return res;
  1807. }
  1808. /**
  1809. Invalidate the cached children information and cached data.
  1810. \see _clearChildren
  1811. \see _clearData
  1812. \param clearChildren set to true to invalidate children information cache.
  1813. \param clearData set to true to invalidate data cache.
  1814. */
  1815. void clear(bool clearChildren = true, bool clearData = true)
  1816. {
  1817. LOG_DEBUG(LOG, "clear(clearChildren %d, clearData %d) path %s",
  1818. clearChildren, clearData, _path.c_str());
  1819. {
  1820. AutoLock lock(_mutex);
  1821. if (clearChildren) {
  1822. _clearChildren();
  1823. }
  1824. if (clearData) {
  1825. _clearData();
  1826. }
  1827. }
  1828. }
  1829. /**
  1830. Whether reference count is zero.
  1831. \see _refCount
  1832. \return true if reference count is zero.
  1833. */
  1834. bool isZombie() const
  1835. {
  1836. AutoLock lock(_mutex);
  1837. return (_refCount == 0);
  1838. }
  1839. /**
  1840. Increment the reference count of the ZkFuseFile instance.
  1841. This method may be called by a ZkFuseFileManager instance while
  1842. holding the ZkFuseFileManager's _mutex. To avoid deadlocks,
  1843. this methods must never invoke a ZkFuseFileManager instance
  1844. directly or indirectly while holding the ZkFuseFile instance's
  1845. _mutex.
  1846. \see _refCount
  1847. \return the post-increment reference count.
  1848. \param count value to increment the reference count by.
  1849. */
  1850. int incRefCount(int count = 1)
  1851. {
  1852. LOG_DEBUG(LOG, "incRefCount(count %d) path %s", count, _path.c_str());
  1853. int res = 0;
  1854. {
  1855. AutoLock lock(_mutex);
  1856. _refCount += count;
  1857. assert(_refCount >= 0);
  1858. res = _refCount;
  1859. }
  1860. LOG_DEBUG(LOG, "incRefCount returns %d", res);
  1861. return res;
  1862. }
  1863. /**
  1864. Decrement the reference count of the ZkFuseFile instance.
  1865. This method may be called by a ZkFuseFileManager instance while
  1866. holding the ZkFuseFileManager's _mutex. To avoid deadlocks,
  1867. this methods must never invoke a ZkFuseFileManager instance
  1868. directly or indirectly while holding the ZkFuseFile instance's
  1869. _mutex.
  1870. \see _refCount
  1871. \return the post-decrement reference count.
  1872. \param count value to decrement the reference count by.
  1873. */
  1874. int decRefCount(int count = 1)
  1875. {
  1876. return incRefCount(-count);
  1877. }
  1878. /**
  1879. Increment the count of number times the ZkFuseFile instance has
  1880. been opened as a directory.
  1881. This count is incremented by opendir and decremented by releasedir.
  1882. \see _openDirCount.
  1883. \return the post-increment count.
  1884. \param count the value to increment the count by.
  1885. */
  1886. int incOpenDirCount(int count = 1)
  1887. {
  1888. LOG_DEBUG(LOG, "incOpenDirCount(count %d) path %s",
  1889. count, _path.c_str());
  1890. int res = 0;
  1891. {
  1892. AutoLock lock(_mutex);
  1893. _openDirCount += count;
  1894. assert(_openDirCount >= 0);
  1895. res = _openDirCount;
  1896. assert(_openDirCount <= _refCount);
  1897. }
  1898. LOG_DEBUG(LOG, "incOpenDirCount returns %d", res);
  1899. return res;
  1900. }
  1901. /**
  1902. Decrement the count of number times the ZkFuseFile instance has
  1903. been opened as a directory.
  1904. This count is incremented by opendir and decremented by releasedir.
  1905. \see _openDirCount.
  1906. \return the post-decrement count.
  1907. \param count the value to decrement the count by.
  1908. */
  1909. int decOpenDirCount(int count = 1)
  1910. {
  1911. return incOpenDirCount(-count);
  1912. }
  1913. /**
  1914. Whether ZkFuse should present the ZooKeeper node as a ZkFuse
  1915. directory by taking into account the specified ZkFuseNameType.
  1916. The ZkFuseNameType may override the default ZkFuse presentation of
  1917. a ZooKeeper node.
  1918. \see _isDirNameType
  1919. \return true if ZkFuse should present the ZooKeeper node as a ZkFuse
  1920. directory.
  1921. \param nameType specifies the ZkFuseNameType.
  1922. */
  1923. bool isDirNameType(ZkFuseNameType nameType) const
  1924. {
  1925. return _isDirNameType(nameType, true);
  1926. }
  1927. /**
  1928. Whether ZkFuse should present the ZooKeeper node as a ZkFuse
  1929. regular file by taking into account the specified ZkFuseNameType.
  1930. The ZkFuseNameType may override the default ZkFuse presentation of
  1931. a ZooKeeper node.
  1932. \see _isRegNameType
  1933. \return true if ZkFuse should present the ZooKeeper node as a ZkFuse
  1934. regular file.
  1935. \param nameType specifies the ZkFuseNameType.
  1936. */
  1937. bool isRegNameType(ZkFuseNameType nameType) const
  1938. {
  1939. return _isRegNameType(nameType, true);
  1940. }
  1941. /**
  1942. Get the active data.
  1943. \see _activeData
  1944. \param data return data here.
  1945. */
  1946. void getData(Data & data) const
  1947. {
  1948. AutoLock lock(_mutex);
  1949. data = _activeData;
  1950. }
  1951. /**
  1952. Set the active data.
  1953. \see _activeData
  1954. Return -EFBIG is the data to be written is bigger than the maximum
  1955. permitted size (and no data is written).
  1956. \return 0 if successful, otherwise return negative errno.
  1957. \param data set to this data.
  1958. \param doFlush whether to flush the data to the ZooKeeper node.
  1959. */
  1960. int setData(const Data & data, bool doFlush)
  1961. {
  1962. LOG_DEBUG(LOG, "setData(doFlush %d) path %s", doFlush, _path.c_str());
  1963. int res = 0;
  1964. if (data.size() > maxDataFileSize) {
  1965. res = -EFBIG;
  1966. }
  1967. else {
  1968. AutoLock lock(_mutex);
  1969. _activeData = data;
  1970. _dirtyData = true;
  1971. if (doFlush) {
  1972. res = _flush();
  1973. }
  1974. }
  1975. LOG_DEBUG(LOG, "setData() returns %d", res);
  1976. return res;
  1977. }
  1978. /**
  1979. Update the children information and the data caches as needed.
  1980. This method is invoked when a ZkFuse regular file or directory
  1981. implemented by this ZkFuseFile instance is opened, e.g.
  1982. using open or opendir. It attempts to:
  1983. - make sure that the cache has valid children information
  1984. - register for watches for changes if no previous watches have
  1985. been registered.
  1986. The newFile flag indicates if the ZkFuseFile instance has just
  1987. been constructed and that ZooKeeper has not been contacted to
  1988. determine if the ZooKeeper path for this file really exist.
  1989. When a ZkFuseFile instance is created, the _deleted flag is set to
  1990. true because it is safer to assume that the ZooKeeper node does
  1991. not exist. The newFile flag causes the _deleted flag to be
  1992. ignored and ZooKeeper to be contacted to update the caches.
  1993. If the newFile flag is false, then the ZkFuseFile instance is
  1994. currently open and have been opened before. Hence, these previous
  1995. opens should have contacted ZooKeeper and would like learned from
  1996. ZooKeeper whether the ZooKeeper path exists. Therefore,
  1997. the _deleted flag should be trustworthy, i.e. it has accurate
  1998. information on whether the ZooKeeper path actually exists.
  1999. \return 0 if successful, otherwise return negative errno.
  2000. \param newFile set to true if the ZkFuseFile instance is newly created.
  2001. */
  2002. int update(bool newFile)
  2003. {
  2004. LOG_DEBUG(LOG, "update(newFile %d) path %s", newFile, _path.c_str());
  2005. int res = 0;
  2006. {
  2007. AutoLock lock(_mutex);
  2008. /* At this point, cannot be zombie.
  2009. */
  2010. assert(!_isZombie());
  2011. if (!newFile && _deleted) {
  2012. /* Deleted file, don't bother to update caches */
  2013. LOG_DEBUG(LOG, "deleted, not new file");
  2014. res = -ENOENT;
  2015. }
  2016. else {
  2017. try {
  2018. LOG_DEBUG(LOG, "initialized children %d, data %d",
  2019. _initializedChildren, _initializedData);
  2020. LOG_DEBUG(LOG, "has children watch %d, data watch %d",
  2021. _hasChildrenListener, _hasDataListener);
  2022. /*
  2023. * Children handling starts here.
  2024. * If don't have children listener,
  2025. * then must establish listener.
  2026. * If don't have cached children information,
  2027. * then must get children information.
  2028. * It just happens, that the same ZooKeeper API
  2029. * is used for both.
  2030. */
  2031. if (_initializedChildren == false ||
  2032. _hasChildrenListener == false
  2033. #ifdef ZOOKEEPER_ROOT_CHILDREN_WATCH_BUG
  2034. /* HACK for root node because changes to children
  2035. * on a root node does not cause children watches to
  2036. * fire.
  2037. */
  2038. || _path.length() == 1
  2039. #endif // ZOOKEEPER_ROOT_CHILDREN_WATCH_BUG
  2040. ) {
  2041. LOG_DEBUG(LOG, "update children");
  2042. NodeNames children;
  2043. _manager->getCommon().getZkAdapter()->
  2044. getNodeChildren( children, _path,
  2045. &_childrenListener, _getZkContext());
  2046. _hasChildrenListener = true;
  2047. LOG_DEBUG(LOG, "update children done");
  2048. _children.swap(children);
  2049. _initializedChildren = true;
  2050. /* Since getNodeChildren is successful, the
  2051. * path must exist */
  2052. _deleted = false;
  2053. }
  2054. else {
  2055. /* Children information is fresh since
  2056. * it is initialized and and have been
  2057. * updated by listener.
  2058. */
  2059. }
  2060. /*
  2061. * Data handling starts here.
  2062. */
  2063. assert(newFile == false || _isOnlyRegOpen());
  2064. if (!_isOnlyRegOpen()) {
  2065. /* If is already currently opened by someone,
  2066. * then don't update data with latest from ZooKeeper,
  2067. * use current active data (which may be initialized
  2068. * or not).
  2069. * \see _activeData
  2070. */
  2071. LOG_DEBUG(LOG, "node currently in-use, no data update");
  2072. }
  2073. else {
  2074. /* If not opened/reopened by someone else,
  2075. * then perform more comprehensive checks of
  2076. * to make data and listener is setup correctly.
  2077. * If don't have data listener,
  2078. * then must establish listener.
  2079. * If don't have cached data,
  2080. * then must get data.
  2081. * It just happens, that the same ZooKeeper API
  2082. * is used for both.
  2083. */
  2084. LOG_DEBUG(LOG, "node first use or reuse");
  2085. if (_initializedData == false ||
  2086. _hasDataListener == false) {
  2087. /* Don't have any data for now or need to register
  2088. * for callback */
  2089. LOG_DEBUG(LOG, "update data");
  2090. _latestData =
  2091. _manager->getCommon().getZkAdapter()->
  2092. getNodeData(_path, &_dataListener,
  2093. _getZkContext(),
  2094. &_latestStat);
  2095. _hasDataListener = true;
  2096. LOG_DEBUG(LOG,
  2097. "update data done, latest version %d",
  2098. _latestStat.version);
  2099. /* Since getNodeData is successful, the
  2100. * path must exist. */
  2101. _deleted = false;
  2102. }
  2103. else {
  2104. /* Data is fresh since it is initialized and
  2105. * and have been updated by listener.
  2106. */
  2107. }
  2108. /* Update active data to the same as the most
  2109. * recently acquire data.
  2110. */
  2111. _activeData = _latestData;
  2112. _activeStat = _latestStat;
  2113. _initializedData = true;
  2114. _dirtyData = false;
  2115. LOG_DEBUG(LOG, "update set active version %d",
  2116. _activeStat.version);
  2117. }
  2118. res = 0;
  2119. } catch (const ZooKeeperException & e) {
  2120. /* May have ZNONODE exception if path does exist. */
  2121. if (e.getZKErrorCode() == ZNONODE) {
  2122. LOG_DEBUG(LOG, "update %s exception %s",
  2123. _path.c_str(), e.what());
  2124. /* Path does not exist, set _deleted,
  2125. * clear children information cache
  2126. */
  2127. _deleted = true;
  2128. _clearChildren();
  2129. res = -ENOENT;
  2130. } else {
  2131. LOG_ERROR(LOG, "update %s exception %s",
  2132. _path.c_str(), e.what());
  2133. res = -EIO;
  2134. }
  2135. }
  2136. }
  2137. }
  2138. LOG_DEBUG(LOG, "update returns %d", res);
  2139. return res;
  2140. }
  2141. /**
  2142. Process a data event.
  2143. This method may:
  2144. - Invalidate the data cache.
  2145. - Invoke ZooKeeper to update the data cache and register a new
  2146. data watch so that the cache can be kept in-sync with the
  2147. ZooKeeper node's data.
  2148. This method does not change the active data. Active data will be
  2149. changed to a later version by update() at the appropriate time.
  2150. \see update.
  2151. */
  2152. void dataEventReceived(const ZKWatcherEvent & event)
  2153. {
  2154. bool reclaim = false;
  2155. int eventType = event.getType();
  2156. int eventState = event.getState();
  2157. /*
  2158. IMPORTANT:
  2159. Do not mark ZkFuseFile instance as deleted when a ZOO_DELETED_EVENT
  2160. is received without checking with ZooKeeper. An example of
  2161. problematic sequence would be:
  2162. 1. Create node.
  2163. 2. Set data and watch.
  2164. 3. Delete node.
  2165. 4. Create node.
  2166. 5. Deleted event received.
  2167. It is a bug to mark the ZkFuseFile instance as deleted after
  2168. step 5 because the node exists.
  2169. Therefore, this method should always contact ZooKeeper to keep the
  2170. data cache (and deleted status) up-to-date if necessary.
  2171. */
  2172. LOG_DEBUG(LOG, "dataEventReceived() path %s, type %d, state %d",
  2173. _path.c_str(), eventType, eventState);
  2174. {
  2175. AutoLock lock(_mutex);
  2176. _hasDataListener = false;
  2177. /* If zombie, then invalidate cached data.
  2178. * This clears _initializedData and eliminate
  2179. * the need to get the latest data from ZooKeeper and
  2180. * re-register data watch.
  2181. */
  2182. if (_isZombie() && _initializedData) {
  2183. LOG_DEBUG(LOG, "invalidate data");
  2184. _clearData();
  2185. }
  2186. else if ((_refCount - _openDirCount) > 0) {
  2187. /* Don't invalidate cached data because clients of currently
  2188. * open files don't expect the data to change from under them.
  2189. * If data acted upon by these clients have become stale,
  2190. * then the clients will get an error when ZkFuse attempts to
  2191. * flush dirty data. The clients will not get error
  2192. * notification if they don't modify the stale data.
  2193. *
  2194. * If data cache is cleared here, then the following code
  2195. * to update data cache and re-register data watch will not
  2196. * be executed and may result in the cached data being
  2197. * out-of-sync with ZooKeeper.
  2198. */
  2199. LOG_WARN(LOG,
  2200. "%s data has changed while in-use, "
  2201. "type %d, state %d, refCount %d",
  2202. _path.c_str(), eventType, eventState, _refCount);
  2203. }
  2204. /* If cache was valid and still connected
  2205. * then get the latest data from ZooKeeper
  2206. * and re-register data watch. This is required to keep
  2207. * the data cache in-sync with ZooKeeper.
  2208. */
  2209. if (_initializedData &&
  2210. eventState == ZOO_CONNECTED_STATE
  2211. ) {
  2212. try {
  2213. LOG_DEBUG(LOG, "register data watcher");
  2214. _latestData =
  2215. _manager->getCommon().getZkAdapter()->
  2216. getNodeData(_path, &_dataListener, _getZkContext(),
  2217. &_latestStat);
  2218. _hasDataListener = true;
  2219. LOG_DEBUG(LOG,
  2220. "get data done, version %u, cversion %u done",
  2221. _latestStat.version, _latestStat.cversion);
  2222. _deleted = false;
  2223. } catch (const ZooKeeperException & e) {
  2224. if (e.getZKErrorCode() == ZNONODE) {
  2225. _deleted = true;
  2226. _clearChildren();
  2227. }
  2228. LOG_ERROR(LOG, "dataEventReceived %s exception %s",
  2229. _path.c_str(), e.what());
  2230. }
  2231. }
  2232. }
  2233. LOG_DEBUG(LOG, "dataEventReceived return %d", reclaim);
  2234. }
  2235. /**
  2236. Process a children event.
  2237. This method may:
  2238. - Invalidate the children information cache.
  2239. - Invoke ZooKeeper to update the children cache and register a new
  2240. data watch so that the cache can be kept in-sync with the
  2241. ZooKeeper node's children information.
  2242. */
  2243. void childrenEventReceived(const ZKWatcherEvent & event)
  2244. {
  2245. bool reclaim = false;
  2246. int eventType = event.getType();
  2247. int eventState = event.getState();
  2248. LOG_DEBUG(LOG, "childrenEventReceived() path %s, type %d, state %d",
  2249. _path.c_str(), eventType, eventState);
  2250. {
  2251. AutoLock lock(_mutex);
  2252. _hasChildrenListener = false;
  2253. /* If zombie or disconnected, then invalidate cached children
  2254. * information. This clears _initializedChildren and eliminate
  2255. * the need to get the latest children information and
  2256. * re-register children watch.
  2257. */
  2258. if (_initializedChildren &&
  2259. (_isZombie() || eventState != ZOO_CONNECTED_STATE)) {
  2260. LOG_DEBUG(LOG, "invalidate children");
  2261. _clearChildren();
  2262. }
  2263. else if (_initializedChildren) {
  2264. /* Keep cached children information so that we have some
  2265. * children information if get new children information
  2266. * fails. If there is failure, then on next open,
  2267. * update() will attempt again to get children information
  2268. * again because _hasChildrenListener will be false.
  2269. *
  2270. * If children information cache is cleared here, then
  2271. * the following code to update children information cache
  2272. * and re-register children watch will not be executed
  2273. * and may result in the cached children information being
  2274. * out-of-sync with ZooKeeper.
  2275. *
  2276. * The children cache will be cleared if unable to
  2277. * get children and re-establish watch.
  2278. */
  2279. LOG_WARN(LOG,
  2280. "%s children has changed while in-use, "
  2281. "type %d, state %d, refCount %d",
  2282. _path.c_str(), eventType, eventState, _refCount);
  2283. }
  2284. /* If children cache was valid and still connected,
  2285. * then get the latest children information from ZooKeeper
  2286. * and re-register children watch. This is required to
  2287. * keep the children information cache in-sync with ZooKeeper.
  2288. */
  2289. if (_initializedChildren &&
  2290. eventState == ZOO_CONNECTED_STATE
  2291. ) {
  2292. /* Should try to keep the cache in-sync, register call
  2293. * callback again and get current children.
  2294. */
  2295. try {
  2296. LOG_DEBUG(LOG, "update children");
  2297. NodeNames children;
  2298. _manager->getCommon().getZkAdapter()->
  2299. getNodeChildren(children, _path,
  2300. &_childrenListener, _getZkContext());
  2301. _hasChildrenListener = true;
  2302. LOG_DEBUG(LOG, "update children done");
  2303. _children.swap(children);
  2304. _deleted = false;
  2305. } catch (const ZooKeeperException & e) {
  2306. if (e.getZKErrorCode() == ZNONODE) {
  2307. _deleted = true;
  2308. _clearChildren();
  2309. }
  2310. LOG_ERROR(LOG, "childrenEventReceived %s exception %s",
  2311. _path.c_str(), e.what());
  2312. _children.clear();
  2313. }
  2314. }
  2315. }
  2316. LOG_DEBUG(LOG, "childrenEventReceived returns %d", reclaim);
  2317. }
  2318. /**
  2319. Truncate or expand the size of the cached active data.
  2320. This method only changes the size of the cached active data.
  2321. This change is committed to ZooKeeper when the cached data
  2322. is written to the ZooKeeper node by flush().
  2323. Return -EFBIG is the requested size exceeds the maximum.
  2324. \return 0 if successful, otherwise negative errno.
  2325. \param size the requested size.
  2326. */
  2327. int truncate(off_t size)
  2328. {
  2329. int res = 0;
  2330. {
  2331. AutoLock lock(_mutex);
  2332. res = _truncate(size);
  2333. }
  2334. return res;
  2335. }
  2336. /**
  2337. Copy range of active data into specified output buffer.
  2338. \return if successful, return number of bytes copied, otherwise
  2339. return negative errno.
  2340. \param buf address of the output buffer.
  2341. \param size size of the output buffer and desired number of bytes to copy.
  2342. \param offset offset into active data to start copying from.
  2343. */
  2344. int read(char *buf, size_t size, off_t offset) const
  2345. {
  2346. LOG_DEBUG(LOG, "read(size %zu, off_t %zu) path %s",
  2347. size, offset, _path.c_str());
  2348. int res = 0;
  2349. {
  2350. AutoLock lock(_mutex);
  2351. if (!_initializedData) {
  2352. LOG_DEBUG(LOG, "not initialized");
  2353. res = -EIO;
  2354. }
  2355. else {
  2356. off_t fileSize = _activeData.size();
  2357. if (offset > fileSize) {
  2358. LOG_DEBUG(LOG, "offset > fileSize %zu", fileSize);
  2359. res = 0;
  2360. }
  2361. else {
  2362. if (offset + size > fileSize) {
  2363. size = fileSize - offset;
  2364. LOG_DEBUG(LOG,
  2365. "reducing read size to %zu for fileSize %zu",
  2366. size, fileSize);
  2367. }
  2368. copy(_activeData.begin() + offset,
  2369. _activeData.begin() + offset + size,
  2370. buf);
  2371. res = size;
  2372. }
  2373. }
  2374. }
  2375. LOG_DEBUG(LOG, "read returns %d", res);
  2376. return res;
  2377. }
  2378. /**
  2379. Copy buffer content to active data.
  2380. \return if successful, return number of bytes copied, otherwise
  2381. return negative errno.
  2382. \param buf address of the buffer.
  2383. \param size size of the input buffer and desired number of bytes to copy.
  2384. \param offset offset into active data to start copying to.
  2385. */
  2386. int write(const char *buf, size_t size, off_t offset)
  2387. {
  2388. LOG_DEBUG(LOG, "write(size %zu, off_t %zu) path %s",
  2389. size, offset, _path.c_str());
  2390. int res = 0;
  2391. {
  2392. AutoLock lock(_mutex);
  2393. if (!_initializedData) {
  2394. LOG_DEBUG(LOG, "not initialized");
  2395. res = -EIO;
  2396. }
  2397. else if (offset >= maxDataFileSize) {
  2398. LOG_DEBUG(LOG, "offset > maxDataFileSize %u", maxDataFileSize);
  2399. res = -ENOSPC;
  2400. }
  2401. else {
  2402. if (offset + size > maxDataFileSize) {
  2403. LOG_DEBUG(LOG,
  2404. "reducing write size to %zu "
  2405. "for maxDataFileSize %u",
  2406. size, maxDataFileSize);
  2407. size = maxDataFileSize - offset;
  2408. }
  2409. off_t fileSize = _activeData.size();
  2410. if (offset + size > fileSize) {
  2411. LOG_DEBUG(LOG, "resizing to %zu", offset + size);
  2412. _activeData.resize(offset + size);
  2413. }
  2414. copy(buf, buf + size, _activeData.begin() + offset);
  2415. memcpy(&_activeData[offset], buf, size);
  2416. _dirtyData = true;
  2417. res = size;
  2418. }
  2419. }
  2420. LOG_DEBUG(LOG, "write returns %d", res);
  2421. return res;
  2422. }
  2423. /**
  2424. Flush data to the ZooKeeper node.
  2425. If cached active data has been modified, flush it to the ZooKeeper node.
  2426. Returns -EIO if the data cannot be written because the cached active
  2427. data is not the expected version, i.e. ZooKeeper returns ZBADVERSION.
  2428. -EIO may also indicate a more general failure, such as unable to
  2429. communicate with ZooKeeper.
  2430. \return 0 if successful, otherwise negative errno.
  2431. */
  2432. int flush()
  2433. {
  2434. int res = 0;
  2435. {
  2436. AutoLock lock(_mutex);
  2437. res = _flush();
  2438. }
  2439. return res;
  2440. }
  2441. /**
  2442. Close of the ZkFuse regular file represented by the ZkFuseFile instance.
  2443. This may:
  2444. - Flush dirty data to the ZooKeeper node, and return the result of the
  2445. flush operation.
  2446. - Reclaim the ZkFuseFile instance.
  2447. \see ZkFuseHandleManaer::reclaimIfNecessary
  2448. \return result of flush operation - 0 if successful,
  2449. otherwise negative errno.
  2450. */
  2451. int close()
  2452. {
  2453. LOG_DEBUG(LOG, "close() path %s", _path.c_str());
  2454. int res = 0;
  2455. bool reclaim = false;
  2456. {
  2457. AutoLock lock(_mutex);
  2458. res = _flush();
  2459. if (_deleted) {
  2460. _clearData();
  2461. _clearChildren();
  2462. }
  2463. }
  2464. _manager->deallocate(_handle);
  2465. LOG_DEBUG(LOG, "close returns %d", res);
  2466. return res;
  2467. }
  2468. /**
  2469. Get ZkFuse regular file or directory attributes.
  2470. \return 0 if successful, otherwise negative errno.
  2471. \param stbuf return attributes here.
  2472. \param nameType specifies the ZkFuseNameType of the ZkFuse path used
  2473. to get attributes. It influences whether the directory
  2474. or regular file attributes are returned.
  2475. */
  2476. int getattr(struct stat & stbuf, ZkFuseNameType nameType) const
  2477. {
  2478. LOG_DEBUG(LOG, "getattr(nameType %d) path %s",
  2479. int(nameType), _path.c_str());
  2480. int res = 0;
  2481. int version = 0;
  2482. std::string metaPath;
  2483. {
  2484. AutoLock lock(_mutex);
  2485. res = _getattrNoMetaAccess(stbuf, nameType);
  2486. if (res == 0) {
  2487. version = _activeStat.version;
  2488. metaPath = _getChildPath(
  2489. ((stbuf.st_mode & S_IFMT) == S_IFREG) ?
  2490. _manager->getCommon().getRegMetadataName() :
  2491. _manager->getCommon().getDirMetadataName());
  2492. if (_hasChildPath(metaPath) == false) {
  2493. metaPath.clear();
  2494. }
  2495. }
  2496. }
  2497. if (res == 0 && metaPath.empty() == false) {
  2498. Data data;
  2499. int metaRes = _manager->getData(metaPath, data);
  2500. LOG_DEBUG(LOG, "metaRes %d dataSize %zu",
  2501. metaRes, data.size());
  2502. if (metaRes == 0 && data.empty() == false) {
  2503. Metadata metadata;
  2504. _decodeMetadata(data, metadata);
  2505. LOG_DEBUG(LOG, "metadata version %u active version %u",
  2506. metadata.version, version);
  2507. if (metadata.version == version) {
  2508. /* IMPORTANT:
  2509. * Must convert from millisecs to secs before setting
  2510. * st_atime and st_mtime to avoid truncation error
  2511. * due to 64-bit to 32-bit conversion.
  2512. */
  2513. stbuf.st_atime = millisecsToSecs(metadata.atime);
  2514. stbuf.st_mtime = millisecsToSecs(metadata.mtime);
  2515. }
  2516. }
  2517. }
  2518. LOG_DEBUG(LOG, "getattr returns %d", res);
  2519. return res;
  2520. }
  2521. /**
  2522. Read directory entries.
  2523. This interface is defined by FUSE.
  2524. \return 0 if successful, otherwise negative errno.
  2525. \param buf output buffer to store output directory entries.
  2526. \param filler function used to fill the output buffer.
  2527. \param offset start filling from a specific offset.
  2528. */
  2529. int readdir(void *buf, fuse_fill_dir_t filler, off_t offset) const
  2530. {
  2531. LOG_DEBUG(LOG, "readdir(offset %zu) path %s", offset, _path.c_str());
  2532. int res = 0;
  2533. int dataFileIndex = -1;
  2534. unsigned leftTrim = 0;
  2535. typedef std::pair<std::string, int> DirEntry;
  2536. typedef std::vector<DirEntry> DirEntries;
  2537. DirEntries dirEntries;
  2538. /* Get directory entries in two phase to avoid invoking
  2539. * ZkFuseHandleManager while holding _mutex.
  2540. * In first phase, get all the names of child nodes starting
  2541. * at offset. Also remember their index for use in second phase.
  2542. * The first phase hold _mutex.
  2543. */
  2544. {
  2545. AutoLock lock(_mutex);
  2546. if (!_isInitialized()) {
  2547. LOG_DEBUG(LOG, "not initialized");
  2548. res = -EIO;
  2549. }
  2550. else {
  2551. leftTrim = (_path.length() == 1 ? 1 : _path.length() + 1);
  2552. unsigned start = offset;
  2553. unsigned i;
  2554. for (i = start; i < _children.size(); i++) {
  2555. const std::string & childName = _children[i];
  2556. if (_isMeta(childName)) {
  2557. continue;
  2558. }
  2559. dirEntries.push_back(DirEntry(childName, i));
  2560. }
  2561. if (i == _children.size() && !_activeData.empty()) {
  2562. dataFileIndex = i + 1;
  2563. }
  2564. res = 0;
  2565. }
  2566. }
  2567. /* Second phase starts here.
  2568. * DONOT hold _mutex as this phase invokes ZkFuseHandleManager to
  2569. * get attributes for the directory entries.
  2570. */
  2571. if (res == 0) {
  2572. bool full = false;
  2573. for (DirEntries::const_iterator it = dirEntries.begin();
  2574. it != dirEntries.end();
  2575. it++) {
  2576. ZkFuseAutoHandle childAutoHandle(_manager, it->first);
  2577. int childRes = childAutoHandle.get();
  2578. if (childRes >= 0) {
  2579. struct stat stbuf;
  2580. int attrRes = childAutoHandle.getFile()->
  2581. getattr(stbuf, ZkFuseNameDefaultType);
  2582. if (attrRes == 0) {
  2583. if (filler(buf, it->first.c_str() + leftTrim,
  2584. &stbuf, it->second + 1)) {
  2585. LOG_DEBUG(LOG, "filler full");
  2586. full = true;
  2587. break;
  2588. }
  2589. }
  2590. }
  2591. }
  2592. if (full == false && dataFileIndex != -1) {
  2593. LOG_DEBUG(LOG, "include data file name");
  2594. struct stat stbuf;
  2595. int attrRes = getattr(stbuf, ZkFuseNameRegType);
  2596. if (attrRes == 0) {
  2597. filler(buf,
  2598. _manager->getCommon().getDataFileName().c_str(),
  2599. &stbuf, dataFileIndex + 1);
  2600. }
  2601. }
  2602. }
  2603. LOG_DEBUG(LOG, "readdir returns %d", res);
  2604. return res;
  2605. }
  2606. /**
  2607. Set the access time and modified time.
  2608. Set the access and modifieds times on the ZkFuse regular file
  2609. or directory represented by this ZkFuseFile instance.
  2610. Since there is no interface to change these times on a
  2611. ZooKeeper node, ZkFuse simulates this by writing to a
  2612. metadata node which is a child node of the ZooKeeper node.
  2613. ZkFuse writes the current version, the specified access
  2614. and modified times to the metadata node.
  2615. When get attributes is invoked, get attributes will check
  2616. for the presence of this metadata node and if the version
  2617. number matches the current data version, then get attributes
  2618. will return the access and modified times stored in the
  2619. metadata node.
  2620. \return 0 if successful, otherwise negative errno.
  2621. \param atime access time in milliseconds.
  2622. \param mtime modified time in milliseconds.
  2623. \param nameType specifies the ZkFuseNameType of the ZkFuse path used
  2624. to set access and modified times. It influences
  2625. whether the directory or regular file access and
  2626. modified times are set.
  2627. */
  2628. int utime(uint64_t atime, uint64_t mtime, ZkFuseNameType nameType)
  2629. {
  2630. LOG_DEBUG(LOG,
  2631. "utime(atime %llu, mtime %llu, nameType %d) path %s",
  2632. (unsigned long long) atime,
  2633. (unsigned long long) mtime,
  2634. (int) nameType, _path.c_str());
  2635. int res = 0;
  2636. std::string metaPath;
  2637. bool exists = false;
  2638. Data data;
  2639. {
  2640. AutoLock lock(_mutex);
  2641. if (!_isInitialized()) {
  2642. LOG_DEBUG(LOG, "not initialized");
  2643. res = -EIO;
  2644. }
  2645. else {
  2646. bool isRegular = _isRegNameType(nameType);
  2647. Metadata metadata;
  2648. metadata.version = _activeStat.version;
  2649. metadata.atime = atime;
  2650. metadata.mtime = mtime;
  2651. metaPath = _getChildPath(
  2652. isRegular ?
  2653. _manager->getCommon().getRegMetadataName() :
  2654. _manager->getCommon().getDirMetadataName());
  2655. exists = _hasChildPath(metaPath);
  2656. _encodeMetadata(metadata, data);
  2657. res = 0;
  2658. }
  2659. }
  2660. if (res == 0 && metaPath.empty() == false) {
  2661. res = _manager->setData(metaPath, data, exists, true);
  2662. }
  2663. LOG_DEBUG(LOG, "utime returns %d", res);
  2664. return res;
  2665. }
  2666. /**
  2667. Remove a ZkFuse directory.
  2668. If force is true, then the ZooKeeper node and its decendants
  2669. will be deleted.
  2670. If force is false, then this method implements the semantics
  2671. of removing a ZkFuse directory. It will delete the ZooKeeper node
  2672. only if the ZooKeeper node have no data and no non-metadata
  2673. children.
  2674. - Return -ENOTDIR if the ZooKeeper node is not considered
  2675. to be a directory (after taking into consideration the specified
  2676. ZkFuseNameType).
  2677. - Return -ENOTEMPTY if the ZooKeeper node has data or it has
  2678. non-metadata children.
  2679. - Return -ENOENT if the ZooKeeper cannot be deleted, usually this
  2680. is because it does not exist.
  2681. \return 0 if successful, otherwise negative errno.
  2682. \param nameType the ZkFuseNameType of the path used to specify the
  2683. directory to be removed. It influences whether ZkFuse
  2684. considers the ZooKeeper node to be a regular file or
  2685. directory. \see ZkFuseNameType
  2686. \param force set to true to bypass ZkFuse rmdir semantic check.
  2687. */
  2688. int rmdir(ZkFuseNameType nameType, bool force)
  2689. {
  2690. int res = 0;
  2691. {
  2692. AutoLock lock(_mutex);
  2693. res = _rmdir(nameType, force);
  2694. }
  2695. if (res == 0) {
  2696. _manager->removeChildFromParent(_path);
  2697. }
  2698. return res;
  2699. }
  2700. /**
  2701. Remove a ZkFuse regular file.
  2702. This method implements the semantics of removing a ZkFuse regular file.
  2703. - If the ZkFuse regular file represents the data part of the
  2704. ZooKeeper node which is presented as a ZkFuse directory,
  2705. the regular file is virtually deleted by truncating the
  2706. ZooKeeper node's data. Readdir will not synthesize a regular
  2707. file entry for the data part of a ZooKeeper node if
  2708. the ZooKeeper node has no data.
  2709. - If the ZkFuse regular file represents the data part of the
  2710. ZooKeeper node which is presented as a ZkFuse regular file,
  2711. the ZooKeeper node and its decendants are deleted.
  2712. Returns -EISDIR if the ZkFuse regular file cannot be deleted
  2713. because ZkFuse consider it to be a directory.
  2714. \return 0 if successful, otherwise negative errno.
  2715. \param nameType the ZkFuseNameType of the path used to specify the
  2716. directory to be removed. It influences whether ZkFuse
  2717. considers the ZooKeeper node to be a regular file or
  2718. directory. \see ZkFuseNameType
  2719. */
  2720. int unlink(ZkFuseNameType nameType)
  2721. {
  2722. int res = 0;
  2723. {
  2724. AutoLock lock(_mutex);
  2725. res = _unlink(nameType);
  2726. }
  2727. if (res == 0) {
  2728. _manager->removeChildFromParent(_path);
  2729. }
  2730. return res;
  2731. }
  2732. /**
  2733. Utility function to construct a ZooKeeper path for a child
  2734. of a ZooKeeper node.
  2735. \return the full path of the child.
  2736. \param parent the parent's full path.
  2737. \param child the child's parent component.
  2738. */
  2739. static std::string buildChildPath(const std::string & parent,
  2740. const std::string & child)
  2741. {
  2742. std::string s;
  2743. s.reserve(parent.length() + child.length() + 32);
  2744. if (parent.length() > 1) {
  2745. // special case for root dir
  2746. s += parent;
  2747. }
  2748. s += "/";
  2749. s += child;
  2750. return s;
  2751. }
  2752. };
  2753. ZkFuseFile::DataListener ZkFuseFile::_dataListener;
  2754. ZkFuseFile::ChildrenListener ZkFuseFile::_childrenListener;
  2755. void ZkFuseAutoHandle::reset(int handle)
  2756. {
  2757. int old = _handle;
  2758. ZkFuseFilePtr oldFile = _file;
  2759. _handle = handle;
  2760. _initFile();
  2761. if (old >= 0) {
  2762. assert(oldFile != NULL);
  2763. oldFile->close();
  2764. }
  2765. }
  2766. ZkFuseHandleManager::Handle
  2767. ZkFuseHandleManager::allocate(const std::string & path, bool & newFile)
  2768. {
  2769. LOG_DEBUG(LOG, "allocate(path %s)", path.c_str());
  2770. Handle handle;
  2771. {
  2772. AutoLock lock(_mutex);
  2773. Map::iterator it = _map.find(path);
  2774. if (it == _map.end()) {
  2775. LOG_DEBUG(LOG, "not found");
  2776. if (_freeList.empty()) {
  2777. handle = _files.size();
  2778. _files.resize(handle + 1);
  2779. LOG_DEBUG(LOG, "free list empty, resize handle %d", handle);
  2780. } else {
  2781. handle = _freeList.back();
  2782. _freeList.pop_back();
  2783. LOG_DEBUG(LOG, "get from free list, handle %d", handle);
  2784. }
  2785. assert(_files[handle] == NULL);
  2786. _files[handle] =
  2787. new ZkFuseFile(SharedPtr(_thisWeakPtr), handle, path);
  2788. /* Not really supposed to invoke the new ZkFuseFile instance
  2789. * because this method is not supposed to invoke ZkFuseFile
  2790. * methods that while holding _mutex. However, it is safe
  2791. * to do without casuing deadlock because these methods
  2792. * are known not to invoke other methods, especially one
  2793. * that invoke this ZkFuseHandleManager instance.
  2794. */
  2795. assert(_files[handle]->incRefCount(0) == 1);
  2796. _map[path] = handle;
  2797. _numInUse++;
  2798. LOG_DEBUG(LOG, "numInUse %u", _numInUse);
  2799. newFile = true;
  2800. } else {
  2801. LOG_DEBUG(LOG, "found");
  2802. handle = it->second;
  2803. assert(_files[handle] != NULL);
  2804. int refCount = _files[handle]->incRefCount();
  2805. if (refCount == 1) {
  2806. _numInUse++;
  2807. LOG_DEBUG(LOG, "resurrecting zombie, numInUse %u", _numInUse);
  2808. }
  2809. newFile = false;
  2810. }
  2811. }
  2812. LOG_DEBUG(LOG, "allocate returns %d, newFile %d", handle, newFile);
  2813. return handle;
  2814. }
  2815. void ZkFuseHandleManager::deallocate(Handle handle)
  2816. {
  2817. LOG_DEBUG(LOG, "deallocate(handle %d)", handle);
  2818. if (handle >= 0) {
  2819. bool reclaim = false;
  2820. ZkFuseFilePtr file;
  2821. {
  2822. AutoLock lock(_mutex);
  2823. file = _files[handle];
  2824. assert(file != NULL);
  2825. int refCount = file->decRefCount();
  2826. const std::string & path = file->getPath();
  2827. LOG_DEBUG(LOG, "path %s ref count %d", path.c_str(), refCount);
  2828. if (refCount == 0) {
  2829. _numInUse--;
  2830. unsigned numCached = _files.size() - _numInUse;
  2831. if (numCached > _common.getCacheSize()) {
  2832. LOG_TRACE(LOG,
  2833. "reclaim path %s, cacheSize %u, filesSize %zu, "
  2834. "numInUse %u",
  2835. path.c_str(),
  2836. _common.getCacheSize(), _files.size(), _numInUse);
  2837. _map.erase(path);
  2838. _files[handle] = NULL;
  2839. _freeList.push_back(handle);
  2840. reclaim = true;
  2841. }
  2842. }
  2843. }
  2844. if (reclaim) {
  2845. delete file;
  2846. }
  2847. }
  2848. else {
  2849. LOG_DEBUG(LOG, "handle invalid");
  2850. }
  2851. LOG_DEBUG(LOG, "deallocate done");
  2852. }
  2853. void ZkFuseHandleManager::eventReceived(const ZKWatcherEvent & event)
  2854. {
  2855. int eventType = event.getType();
  2856. int eventState = event.getState();
  2857. const std::string & path = event.getPath();
  2858. LOG_DEBUG(LOG, "eventReceived() eventType %d, eventState %d, path %s",
  2859. eventType, eventState, path.c_str());
  2860. if (eventType == ZOO_DELETED_EVENT ||
  2861. eventType == ZOO_CHANGED_EVENT ||
  2862. eventType == ZOO_CHILD_EVENT) {
  2863. {
  2864. AutoLock lock(_mutex);
  2865. Map::iterator it = _map.find(path);
  2866. if (it != _map.end()) {
  2867. LOG_DEBUG(LOG, "path found");
  2868. Handle handle = it->second;
  2869. ZkFuseFilePtr file = _files[handle];
  2870. assert(file != NULL);
  2871. /* Prevent the ZkFuseFile instance from being
  2872. * deleted while handling the event.
  2873. */
  2874. int refCount = file->incRefCount();
  2875. if (refCount == 1) {
  2876. _numInUse++;
  2877. }
  2878. /* Pretent to be dir open.
  2879. */
  2880. int dirCount = file->incOpenDirCount();
  2881. {
  2882. /* _mutex is unlocked in this scope */
  2883. AutoUnlockTemp autoUnlockTemp(lock);
  2884. if (eventType == ZOO_CHILD_EVENT) {
  2885. file->childrenEventReceived(event);
  2886. }
  2887. else if (eventType == ZOO_CHANGED_EVENT) {
  2888. file->dataEventReceived(event);
  2889. }
  2890. else {
  2891. assert(eventType == ZOO_DELETED_EVENT);
  2892. file->dataEventReceived(event);
  2893. // file->childrenEventReceived(event);
  2894. }
  2895. file->decOpenDirCount();
  2896. deallocate(handle);
  2897. }
  2898. }
  2899. else {
  2900. LOG_WARN(LOG,
  2901. "path %s not found for event type %d, event state %d",
  2902. path.c_str(), eventType, eventState);
  2903. }
  2904. }
  2905. }
  2906. else if (eventType == ZOO_SESSION_EVENT) {
  2907. if (eventState == ZOO_CONNECTING_STATE) {
  2908. LOG_TRACE(LOG, "*** CONNECTING ***");
  2909. {
  2910. AutoLock lock(_mutex);
  2911. for (int handle = 0; handle < _files.size(); handle++) {
  2912. ZkFuseFilePtr file = _files[handle];
  2913. if (file != NULL) {
  2914. /* prevent the ZkFuseFile instance from being
  2915. * deleted while handling the event.
  2916. */
  2917. int refCount = file->incRefCount();
  2918. if (refCount == 1) {
  2919. _numInUse++;
  2920. }
  2921. /* Pretent to be dir open.
  2922. */
  2923. int dirCount = file->incOpenDirCount();
  2924. {
  2925. /* _mutex is unlocked in this scope */
  2926. AutoUnlockTemp autoUnlockTemp(lock);
  2927. file->dataEventReceived(event);
  2928. file->childrenEventReceived(event);
  2929. file->decOpenDirCount();
  2930. deallocate(handle);
  2931. }
  2932. /* this will eventually call decrement ref count */
  2933. }
  2934. }
  2935. }
  2936. }
  2937. else if (eventState == ZOO_CONNECTED_STATE) {
  2938. LOG_TRACE(LOG, "*** CONNECTED ***");
  2939. }
  2940. }
  2941. else {
  2942. LOG_WARN(LOG,
  2943. "eventReceived ignoring event type %d, event state %d, "
  2944. "path %s", eventType, eventState, path.c_str());
  2945. }
  2946. }
  2947. int ZkFuseHandleManager::getData(const std::string & path,
  2948. Data & data)
  2949. {
  2950. LOG_DEBUG(LOG, "getData(path %s)", path.c_str());
  2951. int res = 0;
  2952. data.clear();
  2953. ZkFuseAutoHandle autoHandle(SharedPtr(_thisWeakPtr), path);
  2954. res = autoHandle.get();
  2955. if (res >= 0) {
  2956. autoHandle.getFile()->getData(data);
  2957. res = 0;
  2958. }
  2959. LOG_DEBUG(LOG, "getData returns %d", res);
  2960. return res;
  2961. }
  2962. int ZkFuseHandleManager::setData(const std::string & path,
  2963. const Data & data,
  2964. bool exists,
  2965. bool doFlush)
  2966. {
  2967. LOG_DEBUG(LOG, "setData(path %s, exists %d)\n%s",
  2968. path.c_str(), exists, data.c_str());
  2969. int res = 0;
  2970. if (exists) {
  2971. res = open(path, false);
  2972. } else {
  2973. bool created;
  2974. res = mknod(path, S_IFREG, true, created);
  2975. }
  2976. if (res >= 0) {
  2977. ZkFuseAutoHandle autoHandle(SharedPtr(_thisWeakPtr), res);
  2978. res = autoHandle.getFile()->setData(data, doFlush);
  2979. }
  2980. LOG_DEBUG(LOG, "setData returns %d", res);
  2981. return res;
  2982. }
  2983. int ZkFuseHandleManager::mknod(const std::string & path,
  2984. mode_t mode,
  2985. bool mayExist,
  2986. bool & created)
  2987. {
  2988. LOG_DEBUG(LOG, "mknod(path %s, mode %o, mayExist %d)",
  2989. path.c_str(), mode, mayExist);
  2990. int res = 0;
  2991. created = false;
  2992. try {
  2993. if (S_ISREG(mode) == false && S_ISDIR(mode) == false) {
  2994. LOG_DEBUG(LOG, "bad mode %o", mode);
  2995. res = -EINVAL;
  2996. }
  2997. else {
  2998. Data data;
  2999. LOG_DEBUG(LOG, "create %s", path.c_str());
  3000. created =
  3001. _common.getZkAdapter()->createNode(path, data, 0, false);
  3002. if (created) {
  3003. LOG_DEBUG(LOG, "created");
  3004. if (S_ISDIR(mode)) {
  3005. /* is mkdir - create directory marker */
  3006. std::string dirMetaPath = ZkFuseFile::buildChildPath
  3007. (path, _common.getDirMetadataName());
  3008. LOG_DEBUG(LOG, "create %s", dirMetaPath.c_str());
  3009. bool created;
  3010. int metaRes = mknod(dirMetaPath, S_IFREG, true, created);
  3011. if (metaRes >= 0) {
  3012. getFile(metaRes)->close();
  3013. }
  3014. }
  3015. addChildToParent(path);
  3016. LOG_DEBUG(LOG, "open after create");
  3017. res = open(path, true);
  3018. } else {
  3019. LOG_DEBUG(LOG, "create failed");
  3020. int openRes = open(path, false);
  3021. if (openRes >= 0) {
  3022. if (mayExist == false) {
  3023. LOG_DEBUG(LOG, "create failed because already exist");
  3024. getFile(openRes)->close();
  3025. res = -EEXIST;
  3026. } else {
  3027. res = openRes;
  3028. }
  3029. } else {
  3030. LOG_DEBUG(LOG, "create failed but does not exist");
  3031. res = -ENOENT;
  3032. }
  3033. }
  3034. }
  3035. } catch (const ZooKeeperException & e) {
  3036. LOG_ERROR(LOG, "mknod %s exception %s", path.c_str(), e.what());
  3037. res = -EIO;
  3038. }
  3039. LOG_DEBUG(LOG, "mknod returns %d created %d", res, created);
  3040. return res;
  3041. }
  3042. int ZkFuseHandleManager::mkdir(const char * path, mode_t mode)
  3043. {
  3044. LOG_DEBUG(LOG, "mkdir(path %s, mode %o)", path, mode);
  3045. int res = 0;
  3046. try {
  3047. ZkFuseNameType nameType;
  3048. std::string zkPath = getZkPath(path, nameType);
  3049. mode = (mode & ~S_IFMT) | S_IFDIR;
  3050. ZkFuseAutoHandle autoHandle
  3051. (SharedPtr(_thisWeakPtr), zkPath, mode, false);
  3052. res = autoHandle.get();
  3053. if (res >= 0) {
  3054. res = 0;
  3055. }
  3056. } catch (const std::exception & e) {
  3057. LOG_ERROR(LOG, "mkdir %s exception %s", path, e.what());
  3058. res = -EIO;
  3059. }
  3060. LOG_DEBUG(LOG, "mkdir returns %d", res);
  3061. return res;
  3062. }
  3063. int ZkFuseHandleManager::open(const std::string & path, bool justCreated)
  3064. {
  3065. LOG_DEBUG(LOG, "open(path %s, justCreated %d)",
  3066. path.c_str(), justCreated);
  3067. int res = 0;
  3068. try {
  3069. bool newFile;
  3070. Handle handle = allocate(path, newFile);
  3071. ZkFuseAutoHandle autoHandle(SharedPtr(_thisWeakPtr), handle);
  3072. res = getFile(handle)->update(newFile || justCreated);
  3073. if (res == 0) {
  3074. res = handle;
  3075. autoHandle.release();
  3076. }
  3077. } catch (const ZooKeeperException & e) {
  3078. LOG_ERROR(LOG, "open %s exception %s", path.c_str(), e.what());
  3079. res = -EIO;
  3080. }
  3081. LOG_DEBUG(LOG, "open returns %d", res);
  3082. return res;
  3083. }
  3084. int ZkFuseHandleManager::rmdir(const char * path, bool force)
  3085. {
  3086. LOG_DEBUG(LOG, "rmdir(path %s, force %d)", path, force);
  3087. int res = 0;
  3088. try {
  3089. ZkFuseNameType nameType;
  3090. std::string zkPath = getZkPath(path, nameType);
  3091. ZkFuseAutoHandle autoHandle(SharedPtr(_thisWeakPtr), zkPath);
  3092. res = autoHandle.get();
  3093. if (res >= 0) {
  3094. res = autoHandle.getFile()->rmdir(nameType, force);
  3095. }
  3096. } catch (const std::exception & e) {
  3097. LOG_ERROR(LOG, "rmdir %s exception %s", path, e.what());
  3098. res = -EIO;
  3099. }
  3100. LOG_DEBUG(LOG, "rmdir returns %d", res);
  3101. return res;
  3102. }
  3103. int
  3104. ZkFuseHandleManager::unlink(const char * path)
  3105. {
  3106. LOG_DEBUG(LOG, "unlink(path %s)", path);
  3107. ZkFuseNameType nameType;
  3108. std::string zkPath = getZkPath(path, nameType);
  3109. ZkFuseAutoHandle autoHandle(SharedPtr(_thisWeakPtr), zkPath);
  3110. int res = autoHandle.get();
  3111. if (res >= 0) {
  3112. res = autoHandle.getFile()->unlink(nameType);
  3113. }
  3114. LOG_DEBUG(LOG, "unlink returns %d", res);
  3115. return res;
  3116. }
  3117. int ZkFuseHandleManager::getattr(const char *path, struct stat &stbuf)
  3118. {
  3119. LOG_DEBUG(LOG, "getattr(path %s)", path);
  3120. int res = 0;
  3121. try {
  3122. ZkFuseNameType nameType;
  3123. std::string zkPath = getZkPath(path, nameType);
  3124. ZkFuseAutoHandle autoHandle(SharedPtr(_thisWeakPtr), zkPath);
  3125. res = autoHandle.get();
  3126. if (res >= 0) {
  3127. res = autoHandle.getFile()->getattr(stbuf, nameType);
  3128. }
  3129. } catch (const std::exception & e) {
  3130. LOG_ERROR(LOG, "getattr %s exception %s", path, e.what());
  3131. res = -EIO;
  3132. }
  3133. LOG_DEBUG(LOG, "getattr returns %d", res);
  3134. return res;
  3135. }
  3136. int
  3137. ZkFuseHandleManager::rename(const char * fromPath, const char * toPath)
  3138. {
  3139. LOG_DEBUG(LOG, "rename(fromPath %s, toPath %s)", fromPath, toPath);
  3140. ZkFuseNameType fromNameType;
  3141. std::string fromZkPath = getZkPath(fromPath, fromNameType);
  3142. ZkFuseAutoHandle fromAutoHandle(SharedPtr(_thisWeakPtr), fromZkPath);
  3143. int res = fromAutoHandle.get();
  3144. if (res >= 0) {
  3145. LOG_DEBUG(LOG, "good fromPath");
  3146. if (fromAutoHandle.getFile()->isDirNameType(fromNameType)) {
  3147. LOG_DEBUG(LOG, "fromPath is directory");
  3148. res = -EISDIR;
  3149. }
  3150. }
  3151. if (res >= 0) {
  3152. ZkFuseNameType toNameType;
  3153. std::string toZkPath = getZkPath(toPath, toNameType);
  3154. bool created;
  3155. res = mknod(toZkPath.c_str(), S_IFREG, true, created);
  3156. if (res >= 0) {
  3157. ZkFuseAutoHandle toAutoHandle(SharedPtr(_thisWeakPtr), res);
  3158. if (toAutoHandle.getFile()->isDirNameType(toNameType)) {
  3159. LOG_DEBUG(LOG, "toPath is directory");
  3160. res = -EISDIR;
  3161. }
  3162. if (res >= 0) {
  3163. LOG_DEBUG(LOG, "copy data");
  3164. Data data;
  3165. fromAutoHandle.getFile()->getData(data);
  3166. toAutoHandle.getFile()->setData(data, true);
  3167. LOG_DEBUG(LOG, "copy metadata");
  3168. struct stat stbuf;
  3169. int metaRes =
  3170. fromAutoHandle.getFile()->getattr(stbuf, fromNameType);
  3171. if (metaRes < 0) {
  3172. LOG_DEBUG(LOG, "get metadata failed");
  3173. }
  3174. else {
  3175. metaRes = toAutoHandle.getFile()->
  3176. utime(secsToMillisecs(stbuf.st_atime),
  3177. secsToMillisecs(stbuf.st_mtime),
  3178. toNameType);
  3179. if (metaRes < 0) {
  3180. LOG_DEBUG(LOG, "set metadata failed");
  3181. }
  3182. }
  3183. }
  3184. if (created && res < 0) {
  3185. LOG_DEBUG(LOG, "undo create because copy data failed");
  3186. int rmRes = toAutoHandle.getFile()->rmdir(toNameType, true);
  3187. }
  3188. }
  3189. }
  3190. if (res >= 0) {
  3191. LOG_DEBUG(LOG, "copy successful, unlink fromPath");
  3192. res = fromAutoHandle.getFile()->unlink(fromNameType);
  3193. }
  3194. LOG_DEBUG(LOG, "rename returns %d", res);
  3195. return res;
  3196. }
  3197. void
  3198. ZkFuseHandleManager::addChildToParent(const std::string & childPath) const
  3199. {
  3200. LOG_DEBUG(LOG, "addChildToParent(childPath %s)", childPath.c_str());
  3201. std::string parentPath = getParentPath(childPath);
  3202. if (!parentPath.empty()) {
  3203. AutoLock lock(_mutex);
  3204. Map::const_iterator it = _map.find(parentPath);
  3205. if (it != _map.end()) {
  3206. Handle handle = it->second;
  3207. assert(_files[handle] != NULL);
  3208. _files[handle]->addChild(childPath);
  3209. }
  3210. }
  3211. LOG_DEBUG(LOG, "addChildToParent done");
  3212. }
  3213. void
  3214. ZkFuseHandleManager::removeChildFromParent(const std::string & childPath) const
  3215. {
  3216. LOG_DEBUG(LOG, "removeChildFromParent(childPath %s)", childPath.c_str());
  3217. std::string parentPath = getParentPath(childPath);
  3218. if (!parentPath.empty()) {
  3219. AutoLock lock(_mutex);
  3220. Map::const_iterator it = _map.find(parentPath);
  3221. if (it != _map.end()) {
  3222. Handle handle = it->second;
  3223. assert(_files[handle] != NULL);
  3224. _files[handle]->removeChild(childPath);
  3225. }
  3226. }
  3227. LOG_DEBUG(LOG, "removeChildFromParent done");
  3228. }
  3229. std::string
  3230. ZkFuseHandleManager::getParentPath(const std::string & childPath) const
  3231. {
  3232. std::string::size_type lastPos = childPath.rfind('/');
  3233. if (lastPos > 0) {
  3234. return std::string(childPath, 0, lastPos);
  3235. }
  3236. else {
  3237. assert(childPath[0] == '/');
  3238. return std::string();
  3239. }
  3240. }
  3241. std::string
  3242. ZkFuseHandleManager::getZkPath(const char * path, ZkFuseNameType & nameType)
  3243. const
  3244. {
  3245. LOG_DEBUG(LOG, "getZkPath(path %s)", path);
  3246. std::string res;
  3247. unsigned pathLen = strlen(path);
  3248. const std::string & dataFileName = _common.getDataFileName();
  3249. unsigned dataSuffixLen = dataFileName.length();
  3250. const char * dataSuffix = dataFileName.c_str();
  3251. unsigned dataSuffixIncludeSlashLen = dataSuffixLen + 1;
  3252. const std::string & forceDirSuffix = _common.getForceDirSuffix();
  3253. unsigned forceDirSuffixLen = _common.getForceDirSuffix().length();
  3254. /* Check if path is "/". If so, it is always a directory.
  3255. */
  3256. if (pathLen == 1) {
  3257. assert(path[0] == '/');
  3258. res = _common.getRootPathName();
  3259. nameType = ZkFuseNameDirType;
  3260. }
  3261. /* Check if path ends of /{dataSuffix}, e.g. /foo/bar/{dataSuffix}.
  3262. * If so remove dataSuffix and nameType is ZkFuseNameRegType.
  3263. */
  3264. else if (
  3265. (pathLen >= dataSuffixIncludeSlashLen) &&
  3266. (path[pathLen - dataSuffixIncludeSlashLen] == '/') &&
  3267. (strncmp(path + (pathLen - dataSuffixLen),
  3268. dataSuffix, dataSuffixLen) == 0)
  3269. ) {
  3270. if ((pathLen - dataSuffixIncludeSlashLen) == 0) {
  3271. res = _common.getRootPathName();
  3272. } else {
  3273. res.assign(path, pathLen - dataSuffixIncludeSlashLen);
  3274. }
  3275. nameType = ZkFuseNameRegType;
  3276. }
  3277. /* If not ZkFuseNameRegType, then check if path ends of
  3278. * {forceDirSuffix}, e.g. /foo/bar{forceDirSuffix}.
  3279. * If so remove forceDirSuffix and nameType is ZkFuseNameDirType.
  3280. */
  3281. else if (forceDirSuffixLen > 0 &&
  3282. pathLen >= forceDirSuffixLen &&
  3283. strncmp(path + (pathLen - forceDirSuffixLen),
  3284. forceDirSuffix.c_str(), forceDirSuffixLen) == 0) {
  3285. res.assign(path, pathLen - forceDirSuffixLen);
  3286. nameType = ZkFuseNameDirType;
  3287. }
  3288. /* If not ZkFuseNameRegType and not ZkFuseNameDirType, then
  3289. * it is ZkFuseNameDefaultType. ZkFuse will infer type from
  3290. * ZooKeeper node's content.
  3291. */
  3292. else {
  3293. res = path;
  3294. nameType = ZkFuseNameDefaultType;
  3295. }
  3296. /* Intermediate components of the path name may have
  3297. * forceDirSuffix, e.g. /foo/bar{forceDirSuffix}/baz.
  3298. * If so, remove the intermediate {forceDirSuffix}es.
  3299. */
  3300. if (forceDirSuffixLen > 0) {
  3301. /* pos is an optimization to avoid always scanning from
  3302. * beginning of path
  3303. */
  3304. unsigned pos = 0;
  3305. while ((res.length() - pos) > forceDirSuffixLen + 1) {
  3306. const char * found =
  3307. strstr(res.c_str() + pos, forceDirSuffix.c_str());
  3308. if (found == NULL) {
  3309. break;
  3310. }
  3311. if (found[forceDirSuffixLen] == '/' ||
  3312. found[forceDirSuffixLen] == '\0') {
  3313. pos = found - res.c_str();
  3314. res.erase(pos, forceDirSuffixLen);
  3315. }
  3316. else {
  3317. pos += forceDirSuffixLen;
  3318. }
  3319. }
  3320. }
  3321. LOG_DEBUG(LOG, "getZkPath returns %s, nameType %d",
  3322. res.c_str(), int(nameType));
  3323. return res;
  3324. }
  3325. static ZkFuseHandleManager::SharedPtr singletonZkFuseHandleManager;
  3326. inline const ZkFuseHandleManager::SharedPtr & zkFuseHandleManager()
  3327. {
  3328. return singletonZkFuseHandleManager;
  3329. }
  3330. static
  3331. int zkfuse_getattr(const char *path, struct stat *stbuf)
  3332. {
  3333. LOG_DEBUG(LOG, "zkfuse_getattr(path %s)", path);
  3334. int res = 0;
  3335. try {
  3336. res = zkFuseHandleManager()->getattr(path, *stbuf);
  3337. } catch (const std::exception & e) {
  3338. LOG_ERROR(LOG, "zkfuse_getattr %s exception %s", path, e.what());
  3339. res = -EIO;
  3340. }
  3341. LOG_DEBUG(LOG, "zkfuse_getattr returns %d", res);
  3342. return res;
  3343. }
  3344. static
  3345. int zkfuse_fgetattr(const char *path, struct stat *stbuf,
  3346. struct fuse_file_info *fi)
  3347. {
  3348. LOG_DEBUG(LOG, "zkfuse_fgetattr(path %s)", path);
  3349. int res = 0;
  3350. int handle = fi->fh;
  3351. try {
  3352. if (handle <= 0) {
  3353. res = -EINVAL;
  3354. }
  3355. else {
  3356. res = zkFuseHandleManager()->getFile(handle)->
  3357. getattr(*stbuf, ZkFuseNameDefaultType);
  3358. }
  3359. } catch (const std::exception & e) {
  3360. LOG_ERROR(LOG, "zkfuse_fgetattr %s exception %s", path, e.what());
  3361. res = -EIO;
  3362. }
  3363. LOG_DEBUG(LOG, "zkfuse_fgetattr returns %d", res);
  3364. return res;
  3365. }
  3366. static
  3367. int zkfuse_access(const char *path, int mask)
  3368. {
  3369. /* not implemented */
  3370. return -1;
  3371. }
  3372. static
  3373. int zkfuse_readlink(const char *path, char *buf, size_t size)
  3374. {
  3375. /* not implemented */
  3376. return -1;
  3377. }
  3378. static
  3379. int zkfuse_opendir(const char *path, struct fuse_file_info *fi)
  3380. {
  3381. LOG_DEBUG(LOG, "zkfuse_opendir(path %s)", path);
  3382. int res = 0;
  3383. try {
  3384. ZkFuseNameType nameType;
  3385. std::string zkPath = zkFuseHandleManager()->getZkPath(path, nameType);
  3386. if (nameType == ZkFuseNameRegType) {
  3387. res = -ENOENT;
  3388. }
  3389. else {
  3390. ZkFuseAutoHandle autoHandle(zkFuseHandleManager(), zkPath);
  3391. res = autoHandle.get();
  3392. if (res >= 0) {
  3393. autoHandle.getFile()->incOpenDirCount();
  3394. autoHandle.release();
  3395. fi->fh = res;
  3396. res = 0;
  3397. }
  3398. }
  3399. } catch (const std::exception & e) {
  3400. LOG_ERROR(LOG, "zkfuse_opendir %s exception %s", path, e.what());
  3401. res = -EIO;
  3402. }
  3403. LOG_DEBUG(LOG, "zkfuse_opendir returns %d", res);
  3404. return res;
  3405. }
  3406. static int
  3407. zkfuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
  3408. off_t offset, struct fuse_file_info *fi)
  3409. {
  3410. LOG_DEBUG(LOG, "zkfuse_readdir(path %s, offset %zu)", path, offset);
  3411. int res = 0;
  3412. int handle = fi->fh;
  3413. try {
  3414. if (handle <= 0) {
  3415. res = -EINVAL;
  3416. }
  3417. else {
  3418. res = zkFuseHandleManager()->getFile(handle)->
  3419. readdir(buf, filler, offset);
  3420. }
  3421. } catch (const std::exception & e) {
  3422. LOG_ERROR(LOG, "zkfuse_readdir %s exception %s", path, e.what());
  3423. res = -EIO;
  3424. }
  3425. LOG_DEBUG(LOG, "zkfuse_readdir returns %d", res);
  3426. return res;
  3427. }
  3428. static
  3429. int zkfuse_releasedir(const char *path, struct fuse_file_info *fi)
  3430. {
  3431. LOG_DEBUG(LOG, "zkfuse_releasedir(path %s)", path);
  3432. int res = 0;
  3433. unsigned handle = fi->fh;
  3434. try {
  3435. if (handle <= 0) {
  3436. res = -EINVAL;
  3437. }
  3438. else {
  3439. zkFuseHandleManager()->getFile(handle)->decOpenDirCount();
  3440. zkFuseHandleManager()->getFile(handle)->close();
  3441. }
  3442. } catch (const std::exception & e) {
  3443. LOG_ERROR(LOG, "zkfuse_releasedir %s exception %s", path, e.what());
  3444. res = -EIO;
  3445. }
  3446. LOG_DEBUG(LOG, "zkfuse_releasedir returns %d", res);
  3447. return res;
  3448. }
  3449. static
  3450. int zkfuse_mknod(const char *path, mode_t mode, dev_t rdev)
  3451. {
  3452. LOG_DEBUG(LOG, "zkfuse_mknod(path %s, mode %o)", path, mode);
  3453. int res = 0;
  3454. try {
  3455. ZkFuseNameType nameType;
  3456. std::string zkPath = zkFuseHandleManager()->getZkPath(path, nameType);
  3457. ZkFuseAutoHandle autoHandle(zkFuseHandleManager(), zkPath, mode, false);
  3458. res = autoHandle.get();
  3459. if (res >= 0) {
  3460. res = 0;
  3461. }
  3462. } catch (const std::exception & e) {
  3463. LOG_ERROR(LOG, "zkfuse_mknod %s exception %s", path, e.what());
  3464. res = -EIO;
  3465. }
  3466. LOG_DEBUG(LOG, "zkfuse_mknod returns %d", res);
  3467. return res;
  3468. }
  3469. static int zkfuse_mkdir(const char *path, mode_t mode)
  3470. {
  3471. LOG_DEBUG(LOG, "zkfuse_mkdir(path %s, mode %o", path, mode);
  3472. int res = 0;
  3473. try {
  3474. res = zkFuseHandleManager()->mkdir(path, mode);
  3475. } catch (const std::exception & e) {
  3476. LOG_ERROR(LOG, "zkfuse_mkdir %s exception %s", path, e.what());
  3477. res = -EIO;
  3478. }
  3479. LOG_DEBUG(LOG, "zkfuse_mkdir returns %d", res);
  3480. return res;
  3481. }
  3482. static int zkfuse_unlink(const char *path)
  3483. {
  3484. LOG_DEBUG(LOG, "zkfuse_unlink(path %s)", path);
  3485. int res = 0;
  3486. try {
  3487. res = zkFuseHandleManager()->unlink(path);
  3488. } catch (const std::exception & e) {
  3489. LOG_ERROR(LOG, "zkfuse_unlink %s exception %s", path, e.what());
  3490. res = -EIO;
  3491. }
  3492. LOG_DEBUG(LOG, "zkfuse_unlink returns %d", res);
  3493. return res;
  3494. }
  3495. static int zkfuse_rmdir(const char *path)
  3496. {
  3497. LOG_DEBUG(LOG, "zkfuse_rmdir(path %s)", path);
  3498. int res = 0;
  3499. try {
  3500. res = zkFuseHandleManager()->rmdir(path);
  3501. } catch (const std::exception & e) {
  3502. LOG_ERROR(LOG, "zkfuse_rmdir %s exception %s", path, e.what());
  3503. res = -EIO;
  3504. }
  3505. LOG_DEBUG(LOG, "zkfuse_rmdir returns %d", res);
  3506. return res;
  3507. }
  3508. static int zkfuse_symlink(const char *from, const char *to)
  3509. {
  3510. /* not implemented */
  3511. return -1;
  3512. }
  3513. static int zkfuse_rename(const char *from, const char *to)
  3514. {
  3515. LOG_DEBUG(LOG, "zkfuse_rename(from %s, to %s)", from, to);
  3516. int res = 0;
  3517. try {
  3518. res = zkFuseHandleManager()->rename(from, to);
  3519. } catch (const std::exception & e) {
  3520. LOG_ERROR(LOG, "zkfuse_rename %s %s exception %s", from, to, e.what());
  3521. res = -EIO;
  3522. }
  3523. LOG_DEBUG(LOG, "zkfuse_rename returns %d", res);
  3524. return res;
  3525. }
  3526. static int zkfuse_link(const char *from, const char *to)
  3527. {
  3528. /* not implemented */
  3529. return -1;
  3530. }
  3531. static int zkfuse_chmod(const char *path, mode_t mode)
  3532. {
  3533. LOG_DEBUG(LOG, "zkfuse_chmod(path %s, mode %o)", path, mode);
  3534. int res = 0;
  3535. LOG_DEBUG(LOG, "zkfuse_chmod returns %d", res);
  3536. return res;
  3537. }
  3538. static int zkfuse_chown(const char *path, uid_t uid, gid_t gid)
  3539. {
  3540. LOG_DEBUG(LOG, "zkfuse_chown(path %s, uid %d, gid %d)", path, uid, gid);
  3541. int res = 0;
  3542. if (zkFuseHandleManager()->getCommon().getUid() == uid &&
  3543. zkFuseHandleManager()->getCommon().getGid() == gid) {
  3544. res = 0;
  3545. }
  3546. else {
  3547. res = -EPERM;
  3548. }
  3549. LOG_DEBUG(LOG, "zkfuse_chown returns %d", res);
  3550. return 0;
  3551. }
  3552. static int zkfuse_truncate(const char *path, off_t size)
  3553. {
  3554. LOG_DEBUG(LOG, "zkfuse_truncate(path %s, size %zu)", path, size);
  3555. int res = 0;
  3556. try {
  3557. ZkFuseNameType nameType;
  3558. std::string zkPath = zkFuseHandleManager()->getZkPath(path, nameType);
  3559. ZkFuseAutoHandle autoHandle(zkFuseHandleManager(), zkPath);
  3560. res = autoHandle.get();
  3561. if (res >= 0) {
  3562. res = autoHandle.getFile()->truncate(size);
  3563. }
  3564. } catch (const std::exception & e) {
  3565. LOG_ERROR(LOG, "zkfuse_truncate %s exception %s", path, e.what());
  3566. res = -EIO;
  3567. }
  3568. LOG_DEBUG(LOG, "zkfuse_truncate returns %d", res);
  3569. return res;
  3570. }
  3571. static
  3572. int zkfuse_ftruncate(const char *path, off_t size, struct fuse_file_info *fi)
  3573. {
  3574. LOG_DEBUG(LOG, "zkfuse_ftruncate(path %s, size %zu)", path, size);
  3575. int res = 0;
  3576. unsigned handle = fi->fh;
  3577. try {
  3578. if (handle <= 0) {
  3579. res = -EINVAL;
  3580. }
  3581. else {
  3582. res = zkFuseHandleManager()->getFile(handle)->truncate(size);
  3583. }
  3584. } catch (const std::exception & e) {
  3585. LOG_ERROR(LOG, "zkfuse_ftruncate %s exception %s", path, e.what());
  3586. res = -EIO;
  3587. }
  3588. LOG_DEBUG(LOG, "zkfuse_ftruncate returns %d", res);
  3589. return res;
  3590. }
  3591. static
  3592. int zkfuse_utimens(const char *path, const struct timespec ts[2])
  3593. {
  3594. LOG_DEBUG(LOG, "zkfuse_utimens(path %s)", path);
  3595. int res = 0;
  3596. try {
  3597. uint64_t atime = timespecToMillisecs(ts[0]);
  3598. uint64_t mtime = timespecToMillisecs(ts[1]);
  3599. ZkFuseNameType nameType;
  3600. std::string zkPath = zkFuseHandleManager()->getZkPath(path, nameType);
  3601. ZkFuseAutoHandle autoHandle(zkFuseHandleManager(), zkPath);
  3602. res = autoHandle.get();
  3603. if (res >= 0) {
  3604. res = autoHandle.getFile()->utime(atime, mtime, nameType);
  3605. }
  3606. } catch (const std::exception & e) {
  3607. LOG_ERROR(LOG, "zkfuse_utimens %s exception %s", path, e.what());
  3608. res = -EIO;
  3609. }
  3610. LOG_DEBUG(LOG, "zkfuse_utimens returns %d", res);
  3611. return res;
  3612. }
  3613. static
  3614. int zkfuse_create(const char *path, mode_t mode, struct fuse_file_info *fi)
  3615. {
  3616. int fd;
  3617. fd = open(path, fi->flags, mode);
  3618. if (fd == -1)
  3619. return -errno;
  3620. fi->fh = fd;
  3621. return 0;
  3622. }
  3623. static
  3624. int zkfuse_open(const char *path, struct fuse_file_info *fi)
  3625. {
  3626. LOG_DEBUG(LOG, "zkfuse_open(path %s, flags %o)", path, fi->flags);
  3627. int res = 0;
  3628. try {
  3629. ZkFuseNameType nameType;
  3630. std::string zkPath = zkFuseHandleManager()->getZkPath(path, nameType);
  3631. ZkFuseAutoHandle autoHandle(zkFuseHandleManager(), zkPath);
  3632. res = autoHandle.get();
  3633. if (res >= 0) {
  3634. if (autoHandle.getFile()->isDirNameType(nameType)) {
  3635. res = -ENOENT;
  3636. }
  3637. }
  3638. if (res >= 0) {
  3639. autoHandle.release();
  3640. fi->fh = res;
  3641. res = 0;
  3642. }
  3643. } catch (const std::exception & e) {
  3644. LOG_ERROR(LOG, "zkfuse_open %s exception %s", path, e.what());
  3645. res = -EIO;
  3646. }
  3647. LOG_DEBUG(LOG, "zkfuse_open returns %d", res);
  3648. return res;
  3649. }
  3650. static
  3651. int zkfuse_read(const char *path, char *buf, size_t size, off_t offset,
  3652. struct fuse_file_info *fi)
  3653. {
  3654. LOG_DEBUG(LOG, "zkfuse_read(path %s, size %zu, offset %zu)",
  3655. path, size, offset);
  3656. int res = 0;
  3657. unsigned handle = fi->fh;
  3658. try {
  3659. if (handle <= 0) {
  3660. res = -EINVAL;
  3661. }
  3662. else {
  3663. res = zkFuseHandleManager()->getFile(handle)->
  3664. read(buf, size, offset);
  3665. }
  3666. } catch (const std::exception & e) {
  3667. LOG_ERROR(LOG, "zkfuse_read %s exception %s", path, e.what());
  3668. res = -EIO;
  3669. }
  3670. LOG_DEBUG(LOG, "zkfuse_read returns %d", res);
  3671. return res;
  3672. }
  3673. static
  3674. int zkfuse_write(const char *path, const char *buf, size_t size,
  3675. off_t offset, struct fuse_file_info *fi)
  3676. {
  3677. LOG_DEBUG(LOG, "zkfuse_write(path %s, size %zu, offset %zu)",
  3678. path, size, offset);
  3679. int res = 0;
  3680. unsigned handle = fi->fh;
  3681. try {
  3682. if (handle <= 0) {
  3683. res = -EINVAL;
  3684. }
  3685. else {
  3686. res = zkFuseHandleManager()->getFile(handle)->
  3687. write(buf, size, offset);
  3688. }
  3689. } catch (const std::exception & e) {
  3690. LOG_ERROR(LOG, "zkfuse_write %s exception %s", path, e.what());
  3691. res = -EIO;
  3692. }
  3693. LOG_DEBUG(LOG, "zkfuse_write returns %d", res);
  3694. return res;
  3695. }
  3696. static int zkfuse_statfs(const char *path, struct statvfs *stbuf)
  3697. {
  3698. /* not implemented */
  3699. return -1;
  3700. }
  3701. static
  3702. int zkfuse_flush(const char *path, struct fuse_file_info *fi)
  3703. {
  3704. /* This is called from every close on an open file, so call the
  3705. close on the underlying filesystem. But since flush may be
  3706. called multiple times for an open file, this must not really
  3707. close the file. This is important if used on a network
  3708. filesystem like NFS which flush the data/metadata on close() */
  3709. LOG_DEBUG(LOG, "zkfuse_flush(path %s)", path);
  3710. int res = 0;
  3711. unsigned handle = fi->fh;
  3712. try {
  3713. if (handle <= 0) {
  3714. res = -EINVAL;
  3715. }
  3716. else {
  3717. res = zkFuseHandleManager()->getFile(handle)->flush();
  3718. }
  3719. } catch (const std::exception & e) {
  3720. LOG_ERROR(LOG, "zkfuse_flush %s exception %s", path, e.what());
  3721. res = -EIO;
  3722. }
  3723. LOG_DEBUG(LOG, "zkfuse_flush returns %d", res);
  3724. return res;
  3725. }
  3726. static
  3727. int zkfuse_release(const char *path, struct fuse_file_info *fi)
  3728. {
  3729. LOG_DEBUG(LOG, "zkfuse_release(path %s)", path);
  3730. int res = 0;
  3731. unsigned handle = fi->fh;
  3732. try {
  3733. if (handle <= 0) {
  3734. res = -EINVAL;
  3735. }
  3736. else {
  3737. zkFuseHandleManager()->getFile(handle)->close();
  3738. }
  3739. } catch (const std::exception & e) {
  3740. LOG_ERROR(LOG, "zkfuse_release %s exception %s", path, e.what());
  3741. res = -EIO;
  3742. }
  3743. LOG_DEBUG(LOG, "zkfuse_release returns %d", res);
  3744. return res;
  3745. }
  3746. static
  3747. int zkfuse_fsync(const char *path, int isdatasync,
  3748. struct fuse_file_info *fi)
  3749. {
  3750. LOG_DEBUG(LOG, "zkfuse_fsync(path %s, isdatasync %d)", path, isdatasync);
  3751. (void) isdatasync;
  3752. int res = zkfuse_flush(path, fi);
  3753. LOG_DEBUG(LOG, "zkfuse_fsync returns %d", res);
  3754. return res;
  3755. }
  3756. #ifdef HAVE_SETXATTR
  3757. /* xattr operations are optional and can safely be left unimplemented */
  3758. static int zkfuse_setxattr(const char *path, const char *name, const char *value,
  3759. size_t size, int flags)
  3760. {
  3761. int res = lsetxattr(path, name, value, size, flags);
  3762. if (res == -1)
  3763. return -errno;
  3764. return 0;
  3765. }
  3766. static int zkfuse_getxattr(const char *path, const char *name, char *value,
  3767. size_t size)
  3768. {
  3769. int res = lgetxattr(path, name, value, size);
  3770. if (res == -1)
  3771. return -errno;
  3772. return res;
  3773. }
  3774. static int zkfuse_listxattr(const char *path, char *list, size_t size)
  3775. {
  3776. int res = llistxattr(path, list, size);
  3777. if (res == -1)
  3778. return -errno;
  3779. return res;
  3780. }
  3781. static int zkfuse_removexattr(const char *path, const char *name)
  3782. {
  3783. int res = lremovexattr(path, name);
  3784. if (res == -1)
  3785. return -errno;
  3786. return 0;
  3787. }
  3788. #endif /* HAVE_SETXATTR */
  3789. static
  3790. int zkfuse_lock(const char *path, struct fuse_file_info *fi, int cmd,
  3791. struct flock *lock)
  3792. {
  3793. (void) path;
  3794. return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
  3795. sizeof(fi->lock_owner));
  3796. }
  3797. static
  3798. void init_zkfuse_oper(fuse_operations & fo)
  3799. {
  3800. memset(&fo, 0, sizeof(fuse_operations));
  3801. fo.getattr = zkfuse_getattr;
  3802. fo.fgetattr = zkfuse_fgetattr;
  3803. // fo.access = zkfuse_access;
  3804. // fo.readlink = zkfuse_readlink;
  3805. fo.opendir = zkfuse_opendir;
  3806. fo.readdir = zkfuse_readdir;
  3807. fo.releasedir = zkfuse_releasedir;
  3808. fo.mknod = zkfuse_mknod;
  3809. fo.mkdir = zkfuse_mkdir;
  3810. // fo.symlink = zkfuse_symlink;
  3811. fo.unlink = zkfuse_unlink;
  3812. fo.rmdir = zkfuse_rmdir;
  3813. fo.rename = zkfuse_rename;
  3814. // fo.link = zkfuse_link;
  3815. fo.chmod = zkfuse_chmod;
  3816. fo.chown = zkfuse_chown;
  3817. fo.truncate = zkfuse_truncate;
  3818. fo.ftruncate = zkfuse_ftruncate;
  3819. fo.utimens = zkfuse_utimens;
  3820. // fo.create = zkfuse_create;
  3821. fo.open = zkfuse_open;
  3822. fo.read = zkfuse_read;
  3823. fo.write = zkfuse_write;
  3824. fo.statfs = zkfuse_statfs;
  3825. fo.flush = zkfuse_flush;
  3826. fo.release = zkfuse_release;
  3827. fo.fsync = zkfuse_fsync;
  3828. #ifdef HAVE_SETXATTR
  3829. // fo.setxattr = zkfuse_setxattr;
  3830. // fo.getxattr = zkfuse_getxattr;
  3831. // fo.listxattr = zkfuse_listxattr;
  3832. // fo.removexattr = zkfuse_removexattr;
  3833. #endif
  3834. fo.lock = zkfuse_lock;
  3835. };
  3836. /**
  3837. * The listener of ZK events.
  3838. */
  3839. class SessionEventListener : public ZKEventListener
  3840. {
  3841. private:
  3842. /**
  3843. References the ZkFuseHandleManager instance that should be
  3844. invoked to service events.
  3845. */
  3846. ZkFuseHandleManager::SharedPtr _manager;
  3847. public:
  3848. /**
  3849. Sets the ZkFuseHandleManager instance that should be invoked
  3850. to service events.
  3851. */
  3852. void setManager(const ZkFuseHandleManager::SharedPtr & manager)
  3853. {
  3854. _manager = manager;
  3855. }
  3856. /**
  3857. Received an event and invoke ZkFuseHandleManager instance to handle
  3858. received event.
  3859. */
  3860. virtual void eventReceived(const ZKEventSource & source,
  3861. const ZKWatcherEvent & event)
  3862. {
  3863. _manager->eventReceived(event);
  3864. }
  3865. };
  3866. void
  3867. usage(int argc, char *argv[])
  3868. {
  3869. cout
  3870. << argv[0]
  3871. << " usage: "
  3872. << argv[0]
  3873. << " [args-and-values]+" << endl
  3874. << "nodepath == a complete path to a ZooKeeper node" << endl
  3875. << "\t--cachesize=<cachesize> or -c <cachesize>:" << endl
  3876. << " number of ZooKeeper nodes to cache." << endl
  3877. << "\t--debug or -d: " << endl
  3878. << "\t enable fuse debug mode." << endl
  3879. << "\t--help or -h: " << endl
  3880. << "\t print this message." << endl
  3881. << "\t--mount=<mountpoint> or -m <mountpoint>: " << endl
  3882. << "\t specifies where to mount the zkfuse filesystem." << endl
  3883. << "\t--name or -n: " << endl
  3884. << "\t name of file for accessing node data." << endl
  3885. << "\t--zookeeper=<hostspec> or -z <hostspec>: " << endl
  3886. << "\t specifies information needed to connect to zeekeeper." << endl;
  3887. }
  3888. int
  3889. main(int argc, char *argv[])
  3890. {
  3891. /**
  3892. * Initialize log4cxx
  3893. */
  3894. const std::string file("log4cxx.properties");
  3895. PropertyConfigurator::configureAndWatch( file, 5000 );
  3896. LOG_INFO(LOG, "Starting zkfuse");
  3897. /**
  3898. * Supported operations.
  3899. */
  3900. enum ZkOption {
  3901. ZkOptionCacheSize = 1000,
  3902. ZkOptionDebug = 1001,
  3903. ZkOptionForceDirSuffix = 1002,
  3904. ZkOptionHelp = 1003,
  3905. ZkOptionMount = 1004,
  3906. ZkOptionName = 1005,
  3907. ZkOptionZookeeper = 1006,
  3908. ZkOptionInvalid = -1
  3909. };
  3910. static const char *shortOptions = "c:df:hm:n:z:";
  3911. static struct option longOptions[] = {
  3912. { "cachesize", 1, 0, ZkOptionCacheSize },
  3913. { "debug", 0, 0, ZkOptionDebug },
  3914. { "forcedirsuffix", 1, 0, ZkOptionForceDirSuffix },
  3915. { "help", 0, 0, ZkOptionHelp },
  3916. { "mount", 1, 0, ZkOptionMount },
  3917. { "name", 1, 0, ZkOptionName },
  3918. { "zookeeper", 1, 0, ZkOptionZookeeper },
  3919. { 0, 0, 0, 0 }
  3920. };
  3921. /**
  3922. * Parse arguments
  3923. */
  3924. bool debugFlag = false;
  3925. std::string mountPoint = "/tmp/zkfuse";
  3926. std::string nameOfFile = "_data_";
  3927. std::string forceDirSuffix = "._dir_";
  3928. std::string zkHost;
  3929. unsigned cacheSize = 256;
  3930. while (true) {
  3931. int c;
  3932. c = getopt_long(argc, argv, shortOptions, longOptions, 0);
  3933. if (c == -1) {
  3934. break;
  3935. }
  3936. switch (c) {
  3937. case ZkOptionInvalid:
  3938. cerr
  3939. << argv[0]
  3940. << ": ERROR: Did not specify legal argument!"
  3941. << endl;
  3942. return 99;
  3943. case 'c':
  3944. case ZkOptionCacheSize:
  3945. cacheSize = strtoul(optarg, NULL, 0);
  3946. break;
  3947. case 'd':
  3948. case ZkOptionDebug:
  3949. debugFlag = true;
  3950. break;
  3951. case 'f':
  3952. case ZkOptionForceDirSuffix:
  3953. forceDirSuffix = optarg;
  3954. break;
  3955. case 'h':
  3956. case ZkOptionHelp:
  3957. usage(argc, argv);
  3958. return 0;
  3959. case 'm':
  3960. case ZkOptionMount:
  3961. mountPoint = optarg;
  3962. break;
  3963. case 'n':
  3964. case ZkOptionName:
  3965. nameOfFile = optarg;
  3966. break;
  3967. case 'z':
  3968. case ZkOptionZookeeper:
  3969. zkHost = optarg;
  3970. break;
  3971. }
  3972. }
  3973. /**
  3974. * Check that zkHost has a value, otherwise abort.
  3975. */
  3976. if (zkHost.empty()) {
  3977. cerr
  3978. << argv[0]
  3979. << ": ERROR: "
  3980. << "required argument \"--zookeeper <hostspec>\" was not given!"
  3981. << endl;
  3982. return 99;
  3983. }
  3984. /**
  3985. * Check that zkHost has a value, otherwise abort.
  3986. */
  3987. if (forceDirSuffix.empty()) {
  3988. cerr
  3989. << argv[0]
  3990. << ": ERROR: "
  3991. << "required argument \"--forcedirsuffix <suffix>\" "
  3992. "not cannot be empty!"
  3993. << endl;
  3994. return 99;
  3995. }
  3996. /**
  3997. * Check nameOfFile has no forward slash
  3998. */
  3999. if (nameOfFile.find_first_of('/') != std::string::npos) {
  4000. cerr
  4001. << argv[0]
  4002. << ": ERROR: "
  4003. << "'/' present in name which is not allowed"
  4004. << endl;
  4005. return 99;
  4006. }
  4007. if (debugFlag) {
  4008. cout
  4009. << "cacheSize = "
  4010. << cacheSize
  4011. << ", debug = "
  4012. << debugFlag
  4013. << ", forceDirSuffix = \""
  4014. << forceDirSuffix
  4015. << "\", mount = \""
  4016. << mountPoint
  4017. << "\", name = \""
  4018. << nameOfFile
  4019. << "\", zookeeper = \""
  4020. << zkHost
  4021. << "\", optind = "
  4022. << optind
  4023. << ", argc = "
  4024. << argc
  4025. << ", current arg = \""
  4026. << (optind >= argc ? "NULL" : argv[optind])
  4027. << "\""
  4028. << endl;
  4029. }
  4030. SessionEventListener listener;
  4031. SynchronousEventAdapter<ZKWatcherEvent> eventAdapter;
  4032. LOG_INFO(LOG, "Create ZK adapter");
  4033. try {
  4034. /**
  4035. * Create an instance of ZK adapter.
  4036. */
  4037. std::string h(zkHost);
  4038. ZooKeeperConfig config(h, 1000, true, 10000);
  4039. ZkFuseCommon zkFuseCommon;
  4040. ZooKeeperAdapterSharedPtr zkPtr(
  4041. new ZooKeeperAdapter(
  4042. config,
  4043. &listener,
  4044. false
  4045. )
  4046. );
  4047. zkFuseCommon.setZkAdapter(zkPtr);
  4048. zkFuseCommon.setDataFileName(nameOfFile);
  4049. zkFuseCommon.setForceDirSuffix(forceDirSuffix);
  4050. zkFuseCommon.setCacheSize(cacheSize);
  4051. singletonZkFuseHandleManager =
  4052. ZkFuseHandleManagerFactory::create(zkFuseCommon);
  4053. listener.setManager(singletonZkFuseHandleManager);
  4054. zkPtr->reconnect();
  4055. } catch (const ZooKeeperException & e) {
  4056. cerr
  4057. << argv[0]
  4058. << ": ERROR: ZookKeeperException caught: "
  4059. << e.what()
  4060. << endl;
  4061. } catch (std::exception & e) {
  4062. cerr
  4063. << argv[0]
  4064. << ": ERROR: std::exception caught: "
  4065. << e.what()
  4066. << endl;
  4067. }
  4068. #ifdef ZOOKEEPER_ROOT_CHILDREN_WATCH_BUG
  4069. cerr << "ZOOKEEPER_ROOT_CHILDREN_WATCH_BUG enabled" << endl;
  4070. #endif
  4071. /**
  4072. * Initialize fuse
  4073. */
  4074. LOG_INFO(LOG, "Initialize fuse");
  4075. umask(0);
  4076. fuse_operations zkfuse_oper;
  4077. init_zkfuse_oper(zkfuse_oper);
  4078. int fakeArgc = debugFlag ? 3 : 2;
  4079. char * fakeArgv[] = {
  4080. argv[0],
  4081. strdup(mountPoint.c_str()),
  4082. debugFlag ? strdup("-d") : NULL,
  4083. NULL
  4084. };
  4085. int res = fuse_main(fakeArgc, fakeArgv, &zkfuse_oper, NULL);
  4086. for (unsigned i = 1; i <= 2; i++) {
  4087. if (fakeArgv[i] != NULL) {
  4088. free(fakeArgv[i]);
  4089. }
  4090. }
  4091. return res;
  4092. }