-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1830 lines (1415 loc) · 220 KB
/
Copy pathindex.html
File metadata and controls
1830 lines (1415 loc) · 220 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
<script id="hexo-configurations">
var NexT = window.NexT || {};
var CONFIG = {"hostname":"eviltuzki.top","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.json"};
</script>
<meta property="og:type" content="website">
<meta property="og:title" content="Eviltuzki">
<meta property="og:url" content="https://eviltuzki.top/index.html">
<meta property="og:site_name" content="Eviltuzki">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="Eviltuzki">
<meta property="article:tag" content="Java,ElasticSearch,Go">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://eviltuzki.top/">
<script id="page-configurations">
// https://hexo.io/docs/variables.html
CONFIG.page = {
sidebar: "",
isHome : true,
isPost : false,
lang : 'zh-CN'
};
</script>
<title>Eviltuzki</title>
<noscript>
<style>
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-header { opacity: initial; }
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<div class="container use-motion">
<div class="headband"></div>
<header class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="切换导航栏">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<h1 class="site-title">Eviltuzki</h1>
<span class="logo-line-after"><i></i></span>
</a>
<p class="site-subtitle" itemprop="description">一线码农一枚</p>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger">
<i class="fa fa-search fa-fw fa-lg"></i>
</div>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="main-menu menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>
</li>
<li class="menu-item menu-item-schedule">
<a href="/schedule/" rel="section"><i class="fa fa-calendar fa-fw"></i>日程表</a>
</li>
<li class="menu-item menu-item-search">
<a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
</a>
</li>
</ul>
</nav>
<div class="search-pop-overlay">
<div class="popup search-popup">
<div class="search-header">
<span class="search-icon">
<i class="fa fa-search"></i>
</span>
<div class="search-input-container">
<input autocomplete="off" autocapitalize="off"
placeholder="搜索..." spellcheck="false"
type="search" class="search-input">
</div>
<span class="popup-btn-close">
<i class="fa fa-times-circle"></i>
</span>
</div>
<div id="search-result">
<div id="no-result">
<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
</div>
</div>
</div>
</div>
</div>
</header>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
<span>0%</span>
</div>
<main class="main">
<div class="main-inner">
<div class="content-wrap">
<div class="content index posts-expand">
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://eviltuzki.top/2023/02/19/C%E8%AF%AD%E8%A8%80%E5%AE%9E%E7%8E%B0RPC%E8%B0%83%E7%94%A8(Demo)/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Eviltuzki">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Eviltuzki">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2023/02/19/C%E8%AF%AD%E8%A8%80%E5%AE%9E%E7%8E%B0RPC%E8%B0%83%E7%94%A8(Demo)/" class="post-title-link" itemprop="url">C语言实现RPC调用(Demo)</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2023-02-19 00:00:00" itemprop="dateCreated datePublished" datetime="2023-02-19T00:00:00+08:00">2023-02-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/RPC-Thrift-ProtoBuf-C/" itemprop="url" rel="index"><span itemprop="name">RPC, Thrift, ProtoBuf, C</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>简单调研一圈,目前c语言可用的rpc框架有,Thrift,protobuf-c-rpc,rpcgen,这里只是简单记录一下调用demo,C语言用的还是不太熟悉,凑合看了。</p>
<h1 id="Thrift"><a href="#Thrift" class="headerlink" title="Thrift"></a>Thrift</h1><p>这里说一下Thrift的特点</p>
<ul>
<li>同步调用,相对比较容易处理</li>
<li>需要修改request_service.c,也就是服务实现具体的方法,需要修改request_service.c文件(暂时没找到其他办法)</li>
<li>依赖glibc</li>
</ul>
<h2 id="编译安装Thrift"><a href="#编译安装Thrift" class="headerlink" title="编译安装Thrift"></a>编译安装Thrift</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># git clone https://github.com/apache/thrift.git</span><br><span class="line"># cd thrift</span><br><span class="line"># ./bootstrap.sh</span><br><span class="line"># ./configure</span><br><span class="line"># make</span><br><span class="line"># make install</span><br></pre></td></tr></table></figure>
<h2 id="依赖"><a href="#依赖" class="headerlink" title="依赖"></a>依赖</h2><ul>
<li>glibc-2.0</li>
</ul>
<h2 id="编写协议"><a href="#编写协议" class="headerlink" title="编写协议"></a>编写协议</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">namespace cl shared</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">struct Param {</span><br><span class="line"> 1: string key</span><br><span class="line"> 2: i32 value</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">struct Result {</span><br><span class="line"> 1: bool result</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">service RequestService {</span><br><span class="line"> Result sendMessage(1: Param param)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="Server端"><a href="#Server端" class="headerlink" title="Server端"></a>Server端</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line">#include <glib-object.h></span><br><span class="line">#include <signal.h></span><br><span class="line">#include <stdio.h></span><br><span class="line">#include <string.h></span><br><span class="line"></span><br><span class="line">#include <thrift/c_glib/thrift.h></span><br><span class="line">#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h></span><br><span class="line">#include <thrift/c_glib/protocol/thrift_protocol_factory.h></span><br><span class="line">#include <thrift/c_glib/server/thrift_server.h></span><br><span class="line">#include <thrift/c_glib/server/thrift_simple_server.h></span><br><span class="line">#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h></span><br><span class="line">#include <thrift/c_glib/transport/thrift_server_socket.h></span><br><span class="line">#include <thrift/c_glib/transport/thrift_server_transport.h></span><br><span class="line"></span><br><span class="line">#include "gen-c_glib/request_service.h"</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">ThriftServer *server = NULL;</span><br><span class="line">gboolean sigint_received = FALSE;</span><br><span class="line"></span><br><span class="line">/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the</span><br><span class="line"> server */</span><br><span class="line">static void</span><br><span class="line">sigint_handler(int signal_number) {</span><br><span class="line"> THRIFT_UNUSED_VAR (signal_number);</span><br><span class="line"></span><br><span class="line"> /* Take note we were called */</span><br><span class="line"> sigint_received = TRUE;</span><br><span class="line"></span><br><span class="line"> /* Shut down the server gracefully */</span><br><span class="line"> if (server != NULL)</span><br><span class="line"> thrift_server_stop(server);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">int main(void) {</span><br><span class="line"> RequestServiceHandler *handler;</span><br><span class="line"> RequestServiceProcessor *processor;</span><br><span class="line"> ThriftServerTransport *server_transport;</span><br><span class="line"> ThriftTransportFactory *transport_factory;</span><br><span class="line"> ThriftProtocolFactory *protocol_factory;</span><br><span class="line"></span><br><span class="line"> struct sigaction sigint_action;</span><br><span class="line"></span><br><span class="line"> GError *error = NULL;</span><br><span class="line"> int exit_status = 0;</span><br><span class="line"></span><br><span class="line"> handler = g_object_new(TYPE_REQUEST_SERVICE_HANDLER, NULL);</span><br><span class="line"> processor = g_object_new(TYPE_REQUEST_SERVICE_PROCESSOR, "handler", handler, NULL);</span><br><span class="line"> server_transport = g_object_new(THRIFT_TYPE_SERVER_SOCKET, "port", 9090, NULL);</span><br><span class="line"> transport_factory = g_object_new(THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, NULL);</span><br><span class="line"> protocol_factory = g_object_new(THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL);</span><br><span class="line"> server = g_object_new(THRIFT_TYPE_SIMPLE_SERVER,</span><br><span class="line"> "processor", processor,</span><br><span class="line"> "server_transport", server_transport,</span><br><span class="line"> "input_transport_factory", transport_factory,</span><br><span class="line"> "output_transport_factory", transport_factory,</span><br><span class="line"> "input_protocol_factory", protocol_factory,</span><br><span class="line"> "output_protocol_factory", protocol_factory,</span><br><span class="line"> NULL);</span><br><span class="line"> memset(&sigint_action, 0, sizeof(sigint_action));</span><br><span class="line"> sigint_action.sa_handler = sigint_handler;</span><br><span class="line"> sigint_action.sa_flags = SA_RESETHAND;</span><br><span class="line"> sigaction(SIGINT, &sigint_action, NULL);</span><br><span class="line"> printf("Starting the server...\n");</span><br><span class="line"> thrift_server_serve(server, &error);</span><br><span class="line"> printf("server %p error %p\n",server,error);</span><br><span class="line"> if (!sigint_received) {</span><br><span class="line"> g_message ("thrift_server_serve: %s",</span><br><span class="line"> error != NULL ? error->message : "(null)");</span><br><span class="line"> g_clear_error(&error);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> puts("done.");</span><br><span class="line"></span><br><span class="line"> g_object_unref(server);</span><br><span class="line"> g_object_unref(transport_factory);</span><br><span class="line"> g_object_unref(protocol_factory);</span><br><span class="line"> g_object_unref(server_transport);</span><br><span class="line"></span><br><span class="line"> g_object_unref(processor);</span><br><span class="line"> g_object_unref(handler);</span><br><span class="line"></span><br><span class="line"> return exit_status;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="Server业务部分-request-service-c"><a href="#Server业务部分-request-service-c" class="headerlink" title="Server业务部分(request_service.c)"></a>Server业务部分(request_service.c)</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * Autogenerated by Thrift Compiler (0.17.0)</span><br><span class="line"> *</span><br><span class="line"> * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING</span><br><span class="line"> * @generated</span><br><span class="line"> */</span><br><span class="line">#include <string.h></span><br><span class="line">#include <thrift/c_glib/thrift.h></span><br><span class="line">#include <thrift/c_glib/thrift_application_exception.h></span><br><span class="line">#include <stdio.h></span><br><span class="line">#include <stdbool.h></span><br><span class="line">#include "request_service.h"</span><br><span class="line"></span><br><span class="line">gboolean</span><br><span class="line">request_service_if_send_message(RequestServiceIf *iface, Result **_return, const Param *param, GError **error) {</span><br><span class="line"> return REQUEST_SERVICE_IF_GET_INTERFACE (iface)->send_message(iface, _return, param, error);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">GType</span><br><span class="line">request_service_if_get_type(void) {</span><br><span class="line"> static GType type = 0;</span><br><span class="line"> if (type == 0) {</span><br><span class="line"> static const GTypeInfo type_info =</span><br><span class="line"> {</span><br><span class="line"> sizeof(RequestServiceIfInterface),</span><br><span class="line"> NULL, /* base_init */</span><br><span class="line"> NULL, /* base_finalize */</span><br><span class="line"> NULL, /* class_init */</span><br><span class="line"> NULL, /* class_finalize */</span><br><span class="line"> NULL, /* class_data */</span><br><span class="line"> 0, /* instance_size */</span><br><span class="line"> 0, /* n_preallocs */</span><br><span class="line"> NULL, /* instance_init */</span><br><span class="line"> NULL /* value_table */</span><br><span class="line"> };</span><br><span class="line"> type = g_type_register_static(G_TYPE_INTERFACE,</span><br><span class="line"> "RequestServiceIf",</span><br><span class="line"> &type_info, 0);</span><br><span class="line"> }</span><br><span class="line"> return type;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_if_interface_init(RequestServiceIfInterface *iface);</span><br><span class="line"></span><br><span class="line">G_DEFINE_TYPE_WITH_CODE (RequestServiceClient, request_service_client,</span><br><span class="line"> G_TYPE_OBJECT,</span><br><span class="line"> G_IMPLEMENT_INTERFACE(TYPE_REQUEST_SERVICE_IF,</span><br><span class="line"> request_service_if_interface_init))</span><br><span class="line"></span><br><span class="line">enum _RequestServiceClientProperties {</span><br><span class="line"> PROP_0,</span><br><span class="line"> PROP_REQUEST_SERVICE_CLIENT_INPUT_PROTOCOL,</span><br><span class="line"> PROP_REQUEST_SERVICE_CLIENT_OUTPUT_PROTOCOL</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">void</span><br><span class="line">request_service_client_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) {</span><br><span class="line"> RequestServiceClient *client = REQUEST_SERVICE_CLIENT (object);</span><br><span class="line"></span><br><span class="line"> THRIFT_UNUSED_VAR (pspec);</span><br><span class="line"></span><br><span class="line"> switch (property_id) {</span><br><span class="line"> case PROP_REQUEST_SERVICE_CLIENT_INPUT_PROTOCOL:</span><br><span class="line"> client->input_protocol = g_value_get_object(value);</span><br><span class="line"> break;</span><br><span class="line"> case PROP_REQUEST_SERVICE_CLIENT_OUTPUT_PROTOCOL:</span><br><span class="line"> client->output_protocol = g_value_get_object(value);</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">void</span><br><span class="line">request_service_client_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) {</span><br><span class="line"> RequestServiceClient *client = REQUEST_SERVICE_CLIENT (object);</span><br><span class="line"></span><br><span class="line"> THRIFT_UNUSED_VAR (pspec);</span><br><span class="line"></span><br><span class="line"> switch (property_id) {</span><br><span class="line"> case PROP_REQUEST_SERVICE_CLIENT_INPUT_PROTOCOL:</span><br><span class="line"> g_value_set_object(value, client->input_protocol);</span><br><span class="line"> break;</span><br><span class="line"> case PROP_REQUEST_SERVICE_CLIENT_OUTPUT_PROTOCOL:</span><br><span class="line"> g_value_set_object(value, client->output_protocol);</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">gboolean request_service_client_send_send_message(RequestServiceIf *iface, const Param *param, GError **error) {</span><br><span class="line"> gint32 cseqid = 0;</span><br><span class="line"> ThriftProtocol *protocol = REQUEST_SERVICE_CLIENT (iface)->output_protocol;</span><br><span class="line"></span><br><span class="line"> if (thrift_protocol_write_message_begin(protocol, "sendMessage", T_CALL, cseqid, error) < 0)</span><br><span class="line"> return FALSE;</span><br><span class="line"></span><br><span class="line"> {</span><br><span class="line"> gint32 ret;</span><br><span class="line"> gint32 xfer = 0;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> if ((ret = thrift_protocol_write_struct_begin(protocol, "sendMessage_args", error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> if ((ret = thrift_protocol_write_field_begin(protocol, "param", T_STRUCT, 1, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> if ((ret = thrift_struct_write(THRIFT_STRUCT (param), protocol, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"></span><br><span class="line"> if ((ret = thrift_protocol_write_field_end(protocol, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> if ((ret = thrift_protocol_write_field_stop(protocol, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> if ((ret = thrift_protocol_write_struct_end(protocol, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> if (thrift_protocol_write_message_end(protocol, error) < 0)</span><br><span class="line"> return FALSE;</span><br><span class="line"> if (!thrift_transport_flush(protocol->transport, error))</span><br><span class="line"> return FALSE;</span><br><span class="line"> if (!thrift_transport_write_end(protocol->transport, error))</span><br><span class="line"> return FALSE;</span><br><span class="line"></span><br><span class="line"> return TRUE;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">gboolean request_service_client_recv_send_message(RequestServiceIf *iface, Result **_return, GError **error) {</span><br><span class="line"> gint32 rseqid;</span><br><span class="line"> gchar *fname = NULL;</span><br><span class="line"> ThriftMessageType mtype;</span><br><span class="line"> ThriftProtocol *protocol = REQUEST_SERVICE_CLIENT (iface)->input_protocol;</span><br><span class="line"> ThriftApplicationException *xception;</span><br><span class="line"></span><br><span class="line"> if (thrift_protocol_read_message_begin(protocol, &fname, &mtype, &rseqid, error) < 0) {</span><br><span class="line"> if (fname) g_free(fname);</span><br><span class="line"> return FALSE;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> if (mtype == T_EXCEPTION) {</span><br><span class="line"> if (fname) g_free(fname);</span><br><span class="line"> xception = g_object_new(THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);</span><br><span class="line"> thrift_struct_read(THRIFT_STRUCT (xception), protocol, NULL);</span><br><span class="line"> thrift_protocol_read_message_end(protocol, NULL);</span><br><span class="line"> thrift_transport_read_end(protocol->transport, NULL);</span><br><span class="line"> g_set_error(error, THRIFT_APPLICATION_EXCEPTION_ERROR, xception->type, "application error: %s",</span><br><span class="line"> xception->message);</span><br><span class="line"> g_object_unref(xception);</span><br><span class="line"> return FALSE;</span><br><span class="line"> } else if (mtype != T_REPLY) {</span><br><span class="line"> if (fname) g_free(fname);</span><br><span class="line"> thrift_protocol_skip(protocol, T_STRUCT, NULL);</span><br><span class="line"> thrift_protocol_read_message_end(protocol, NULL);</span><br><span class="line"> thrift_transport_read_end(protocol->transport, NULL);</span><br><span class="line"> g_set_error(error, THRIFT_APPLICATION_EXCEPTION_ERROR, THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE,</span><br><span class="line"> "invalid message type %d, expected T_REPLY", mtype);</span><br><span class="line"> return FALSE;</span><br><span class="line"> } else if (strncmp(fname, "sendMessage", 11) != 0) {</span><br><span class="line"> thrift_protocol_skip(protocol, T_STRUCT, NULL);</span><br><span class="line"> thrift_protocol_read_message_end(protocol, error);</span><br><span class="line"> thrift_transport_read_end(protocol->transport, error);</span><br><span class="line"> g_set_error(error, THRIFT_APPLICATION_EXCEPTION_ERROR, THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME,</span><br><span class="line"> "wrong method name %s, expected sendMessage", fname);</span><br><span class="line"> if (fname) g_free(fname);</span><br><span class="line"> return FALSE;</span><br><span class="line"> }</span><br><span class="line"> if (fname) g_free(fname);</span><br><span class="line"></span><br><span class="line"> {</span><br><span class="line"> gint32 ret;</span><br><span class="line"> gint32 xfer = 0;</span><br><span class="line"> gchar *name = NULL;</span><br><span class="line"> ThriftType ftype;</span><br><span class="line"> gint16 fid;</span><br><span class="line"> guint32 len = 0;</span><br><span class="line"> gpointer data = NULL;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> /* satisfy -Wall in case these aren't used */</span><br><span class="line"> THRIFT_UNUSED_VAR (len);</span><br><span class="line"> THRIFT_UNUSED_VAR (data);</span><br><span class="line"></span><br><span class="line"> /* read the struct begin marker */</span><br><span class="line"> if ((ret = thrift_protocol_read_struct_begin(protocol, &name, error)) < 0) {</span><br><span class="line"> if (name) g_free(name);</span><br><span class="line"> return 0;</span><br><span class="line"> }</span><br><span class="line"> xfer += ret;</span><br><span class="line"> if (name) g_free(name);</span><br><span class="line"> name = NULL;</span><br><span class="line"></span><br><span class="line"> /* read the struct fields */</span><br><span class="line"> while (1) {</span><br><span class="line"> /* read the beginning of a field */</span><br><span class="line"> if ((ret = thrift_protocol_read_field_begin(protocol, &name, &ftype, &fid, error)) < 0) {</span><br><span class="line"> if (name) g_free(name);</span><br><span class="line"> return 0;</span><br><span class="line"> }</span><br><span class="line"> xfer += ret;</span><br><span class="line"> if (name) g_free(name);</span><br><span class="line"> name = NULL;</span><br><span class="line"></span><br><span class="line"> /* break if we get a STOP field */</span><br><span class="line"> if (ftype == T_STOP) {</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> switch (fid) {</span><br><span class="line"> case 0:</span><br><span class="line"> if (ftype == T_STRUCT) {</span><br><span class="line"> if ((ret = thrift_struct_read(THRIFT_STRUCT (*_return), protocol, error)) < 0) {</span><br><span class="line"> return 0;</span><br><span class="line"> }</span><br><span class="line"> xfer += ret;</span><br><span class="line"> } else {</span><br><span class="line"> if ((ret = thrift_protocol_skip(protocol, ftype, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> }</span><br><span class="line"> break;</span><br><span class="line"> default:</span><br><span class="line"> if ((ret = thrift_protocol_skip(protocol, ftype, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line"> if ((ret = thrift_protocol_read_field_end(protocol, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> if ((ret = thrift_protocol_read_struct_end(protocol, error)) < 0)</span><br><span class="line"> return 0;</span><br><span class="line"> xfer += ret;</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> if (thrift_protocol_read_message_end(protocol, error) < 0)</span><br><span class="line"> return FALSE;</span><br><span class="line"></span><br><span class="line"> if (!thrift_transport_read_end(protocol->transport, error))</span><br><span class="line"> return FALSE;</span><br><span class="line"></span><br><span class="line"> return TRUE;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">gboolean</span><br><span class="line">request_service_client_send_message(RequestServiceIf *iface, Result **_return, const Param *param, GError **error) {</span><br><span class="line"> if (!request_service_client_send_send_message(iface, param, error))</span><br><span class="line"> return FALSE;</span><br><span class="line"> if (!request_service_client_recv_send_message(iface, _return, error))</span><br><span class="line"> return FALSE;</span><br><span class="line"> return TRUE;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_if_interface_init(RequestServiceIfInterface *iface) {</span><br><span class="line"> iface->send_message = request_service_client_send_message;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_client_init(RequestServiceClient *client) {</span><br><span class="line"> client->input_protocol = NULL;</span><br><span class="line"> client->output_protocol = NULL;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_client_class_init(RequestServiceClientClass *cls) {</span><br><span class="line"> GObjectClass *gobject_class = G_OBJECT_CLASS (cls);</span><br><span class="line"> GParamSpec *param_spec;</span><br><span class="line"></span><br><span class="line"> gobject_class->set_property = request_service_client_set_property;</span><br><span class="line"> gobject_class->get_property = request_service_client_get_property;</span><br><span class="line"></span><br><span class="line"> param_spec = g_param_spec_object("input_protocol",</span><br><span class="line"> "input protocol (construct)",</span><br><span class="line"> "Set the client input protocol",</span><br><span class="line"> THRIFT_TYPE_PROTOCOL,</span><br><span class="line"> G_PARAM_READWRITE);</span><br><span class="line"> g_object_class_install_property(gobject_class,</span><br><span class="line"> PROP_REQUEST_SERVICE_CLIENT_INPUT_PROTOCOL, param_spec);</span><br><span class="line"></span><br><span class="line"> param_spec = g_param_spec_object("output_protocol",</span><br><span class="line"> "output protocol (construct)",</span><br><span class="line"> "Set the client output protocol",</span><br><span class="line"> THRIFT_TYPE_PROTOCOL,</span><br><span class="line"> G_PARAM_READWRITE);</span><br><span class="line"> g_object_class_install_property(gobject_class,</span><br><span class="line"> PROP_REQUEST_SERVICE_CLIENT_OUTPUT_PROTOCOL, param_spec);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_handler_request_service_if_interface_init(RequestServiceIfInterface *iface);</span><br><span class="line"></span><br><span class="line">G_DEFINE_TYPE_WITH_CODE (RequestServiceHandler,</span><br><span class="line"> request_service_handler,</span><br><span class="line"> G_TYPE_OBJECT,</span><br><span class="line"> G_IMPLEMENT_INTERFACE(TYPE_REQUEST_SERVICE_IF,</span><br><span class="line"> request_service_handler_request_service_if_interface_init))</span><br><span class="line"></span><br><span class="line">gboolean</span><br><span class="line">request_service_handler_send_message(RequestServiceIf *iface, Result **_return, const Param *param, GError **error) {</span><br><span class="line"> g_return_val_if_fail (IS_REQUEST_SERVICE_HANDLER(iface), FALSE);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> printf("%p %p \n", param->key, error); // 这里写自己server的业务,有点头大。。。</span><br><span class="line"></span><br><span class="line"> return REQUEST_SERVICE_HANDLER_GET_CLASS (iface)->send_message(iface, _return, param, error);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_handler_request_service_if_interface_init(RequestServiceIfInterface *iface) {</span><br><span class="line"> iface->send_message = request_service_handler_send_message; //这里自己注册</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_handler_init(RequestServiceHandler *self) {</span><br><span class="line"> THRIFT_UNUSED_VAR (self);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static gboolean</span><br><span class="line">request_service_handler_sends_message(RequestServiceIf *iface, Result **_return, const Param *param, GError **error) {</span><br><span class="line"> THRIFT_UNUSED_VAR (iface);</span><br><span class="line"> THRIFT_UNUSED_VAR (error);</span><br><span class="line"> printf("service request_service_handler_sends_message run key-> %s, value -> %d \n",param->key,param->value);</span><br><span class="line"> puts("zip()");</span><br><span class="line"> Result *result = g_object_new(TYPE_RESULT, NULL);</span><br><span class="line"> result->result = true;</span><br><span class="line"> *_return = result;</span><br><span class="line"> return TRUE;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_handler_class_init(RequestServiceHandlerClass *cls) {</span><br><span class="line"> printf("request_service_handler_class_init in request\n");</span><br><span class="line"></span><br><span class="line"> cls->send_message = request_service_handler_sends_message;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">enum _RequestServiceProcessorProperties {</span><br><span class="line"> PROP_REQUEST_SERVICE_PROCESSOR_0,</span><br><span class="line"> PROP_REQUEST_SERVICE_PROCESSOR_HANDLER</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">G_DEFINE_TYPE (RequestServiceProcessor,</span><br><span class="line"> request_service_processor,</span><br><span class="line"> THRIFT_TYPE_DISPATCH_PROCESSOR)</span><br><span class="line"></span><br><span class="line">typedef gboolean (*RequestServiceProcessorProcessFunction)(RequestServiceProcessor *,</span><br><span class="line"> gint32,</span><br><span class="line"> ThriftProtocol *,</span><br><span class="line"> ThriftProtocol *,</span><br><span class="line"> GError **);</span><br><span class="line"></span><br><span class="line">typedef struct {</span><br><span class="line"> gchar *name;</span><br><span class="line"> RequestServiceProcessorProcessFunction function;</span><br><span class="line">} request_service_processor_process_function_def;</span><br><span class="line"></span><br><span class="line">static gboolean</span><br><span class="line">request_service_processor_process_send_message(RequestServiceProcessor *,</span><br><span class="line"> gint32,</span><br><span class="line"> ThriftProtocol *,</span><br><span class="line"> ThriftProtocol *,</span><br><span class="line"> GError **);</span><br><span class="line"></span><br><span class="line">static request_service_processor_process_function_def</span><br><span class="line"> request_service_processor_process_function_defs[1] = {</span><br><span class="line"> {</span><br><span class="line"> "sendMessage",</span><br><span class="line"> request_service_processor_process_send_message</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">static gboolean</span><br><span class="line">request_service_processor_process_send_message(RequestServiceProcessor *self,</span><br><span class="line"> gint32 sequence_id,</span><br><span class="line"> ThriftProtocol *input_protocol,</span><br><span class="line"> ThriftProtocol *output_protocol,</span><br><span class="line"> GError **error) {</span><br><span class="line"> gboolean result = TRUE;</span><br><span class="line"> ThriftTransport *transport;</span><br><span class="line"> ThriftApplicationException *xception;</span><br><span class="line"> RequestServiceSendMessageArgs *args =</span><br><span class="line"> g_object_new(TYPE_REQUEST_SERVICE_SEND_MESSAGE_ARGS, NULL);</span><br><span class="line"></span><br><span class="line"> printf("request_service_processor_process_send_message\n");</span><br><span class="line"> g_object_get(input_protocol, "transport", &transport, NULL);</span><br><span class="line"></span><br><span class="line"> if ((thrift_struct_read(THRIFT_STRUCT (args), input_protocol, error) != -1) &&</span><br><span class="line"> (thrift_protocol_read_message_end(input_protocol, error) != -1) &&</span><br><span class="line"> (thrift_transport_read_end(transport, error) != FALSE)) {</span><br><span class="line"> Param *param;</span><br><span class="line"> Result *return_value;</span><br><span class="line"> RequestServiceSendMessageResult *result_struct;</span><br><span class="line"></span><br><span class="line"> g_object_get(args,</span><br><span class="line"> "param", &param,</span><br><span class="line"> NULL);</span><br><span class="line"></span><br><span class="line"> g_object_unref(transport);</span><br><span class="line"> g_object_get(output_protocol, "transport", &transport, NULL);</span><br><span class="line"></span><br><span class="line"> result_struct = g_object_new(TYPE_REQUEST_SERVICE_SEND_MESSAGE_RESULT, NULL);</span><br><span class="line"> g_object_get(result_struct, "success", &return_value, NULL);</span><br><span class="line"></span><br><span class="line"> if (request_service_handler_send_message(REQUEST_SERVICE_IF (self->handler),</span><br><span class="line"> &return_value,</span><br><span class="line"> param,</span><br><span class="line"> error) == TRUE) {</span><br><span class="line"> g_object_set(result_struct, "success", return_value, NULL);</span><br><span class="line"></span><br><span class="line"> result =</span><br><span class="line"> ((thrift_protocol_write_message_begin(output_protocol,</span><br><span class="line"> "sendMessage",</span><br><span class="line"> T_REPLY,</span><br><span class="line"> sequence_id,</span><br><span class="line"> error) != -1) &&</span><br><span class="line"> (thrift_struct_write(THRIFT_STRUCT (result_struct),</span><br><span class="line"> output_protocol,</span><br><span class="line"> error) != -1));</span><br><span class="line"> } else {</span><br><span class="line"> if (*error == NULL)</span><br><span class="line"> g_warning ("RequestService.sendMessage implementation returned FALSE "</span><br><span class="line"> "but did not set an error");</span><br><span class="line"></span><br><span class="line"> xception =</span><br><span class="line"> g_object_new(THRIFT_TYPE_APPLICATION_EXCEPTION,</span><br><span class="line"> "type", *error != NULL ? (*error)->code :</span><br><span class="line"> THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN,</span><br><span class="line"> "message", *error != NULL ? (*error)->message : NULL,</span><br><span class="line"> NULL);</span><br><span class="line"> g_clear_error(error);</span><br><span class="line"></span><br><span class="line"> result =</span><br><span class="line"> ((thrift_protocol_write_message_begin(output_protocol,</span><br><span class="line"> "sendMessage",</span><br><span class="line"> T_EXCEPTION,</span><br><span class="line"> sequence_id,</span><br><span class="line"> error) != -1) &&</span><br><span class="line"> (thrift_struct_write(THRIFT_STRUCT (xception),</span><br><span class="line"> output_protocol,</span><br><span class="line"> error) != -1));</span><br><span class="line"></span><br><span class="line"> g_object_unref(xception);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> if (param != NULL)</span><br><span class="line"> g_object_unref(param);</span><br><span class="line"> if (return_value != NULL)</span><br><span class="line"> g_object_unref(return_value);</span><br><span class="line"> g_object_unref(result_struct);</span><br><span class="line"></span><br><span class="line"> if (result == TRUE)</span><br><span class="line"> result =</span><br><span class="line"> ((thrift_protocol_write_message_end(output_protocol, error) != -1) &&</span><br><span class="line"> (thrift_transport_write_end(transport, error) != FALSE) &&</span><br><span class="line"> (thrift_transport_flush(transport, error) != FALSE));</span><br><span class="line"> } else</span><br><span class="line"> result = FALSE;</span><br><span class="line"></span><br><span class="line"> g_object_unref(transport);</span><br><span class="line"> g_object_unref(args);</span><br><span class="line"></span><br><span class="line"> return result;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static gboolean</span><br><span class="line">request_service_processor_dispatch_call(ThriftDispatchProcessor *dispatch_processor,</span><br><span class="line"> ThriftProtocol *input_protocol,</span><br><span class="line"> ThriftProtocol *output_protocol,</span><br><span class="line"> gchar *method_name,</span><br><span class="line"> gint32 sequence_id,</span><br><span class="line"> GError **error) {</span><br><span class="line"> request_service_processor_process_function_def *process_function_def;</span><br><span class="line"> gboolean dispatch_result = FALSE;</span><br><span class="line"></span><br><span class="line"> RequestServiceProcessor *self = REQUEST_SERVICE_PROCESSOR (dispatch_processor);</span><br><span class="line"> ThriftDispatchProcessorClass *parent_class =</span><br><span class="line"> g_type_class_peek_parent(REQUEST_SERVICE_PROCESSOR_GET_CLASS (self));</span><br><span class="line"></span><br><span class="line"> process_function_def = g_hash_table_lookup(self->process_map, method_name);</span><br><span class="line"> if (process_function_def != NULL) {</span><br><span class="line"> g_free(method_name);</span><br><span class="line"> dispatch_result = (*process_function_def->function)(self,</span><br><span class="line"> sequence_id,</span><br><span class="line"> input_protocol,</span><br><span class="line"> output_protocol,</span><br><span class="line"> error);</span><br><span class="line"> } else {</span><br><span class="line"> dispatch_result = parent_class->dispatch_call(dispatch_processor,</span><br><span class="line"> input_protocol,</span><br><span class="line"> output_protocol,</span><br><span class="line"> method_name,</span><br><span class="line"> sequence_id,</span><br><span class="line"> error);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> return dispatch_result;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_processor_set_property(GObject *object,</span><br><span class="line"> guint property_id,</span><br><span class="line"> const GValue *value,</span><br><span class="line"> GParamSpec *pspec) {</span><br><span class="line"> RequestServiceProcessor *self = REQUEST_SERVICE_PROCESSOR (object);</span><br><span class="line"></span><br><span class="line"> switch (property_id) {</span><br><span class="line"> case PROP_REQUEST_SERVICE_PROCESSOR_HANDLER:</span><br><span class="line"> if (self->handler != NULL)</span><br><span class="line"> g_object_unref(self->handler);</span><br><span class="line"> self->handler = g_value_get_object(value);</span><br><span class="line"> g_object_ref (self->handler);</span><br><span class="line"> break;</span><br><span class="line"> default:</span><br><span class="line"> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_processor_get_property(GObject *object,</span><br><span class="line"> guint property_id,</span><br><span class="line"> GValue *value,</span><br><span class="line"> GParamSpec *pspec) {</span><br><span class="line"> RequestServiceProcessor *self = REQUEST_SERVICE_PROCESSOR (object);</span><br><span class="line"></span><br><span class="line"> switch (property_id) {</span><br><span class="line"> case PROP_REQUEST_SERVICE_PROCESSOR_HANDLER:</span><br><span class="line"> g_value_set_object(value, self->handler);</span><br><span class="line"> break;</span><br><span class="line"> default:</span><br><span class="line"> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_processor_dispose(GObject *gobject) {</span><br><span class="line"> RequestServiceProcessor *self = REQUEST_SERVICE_PROCESSOR (gobject);</span><br><span class="line"></span><br><span class="line"> if (self->handler != NULL) {</span><br><span class="line"> g_object_unref(self->handler);</span><br><span class="line"> self->handler = NULL;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> G_OBJECT_CLASS (request_service_processor_parent_class)->dispose(gobject);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_processor_finalize(GObject *gobject) {</span><br><span class="line"> RequestServiceProcessor *self = REQUEST_SERVICE_PROCESSOR (gobject);</span><br><span class="line"></span><br><span class="line"> thrift_safe_hash_table_destroy(self->process_map);</span><br><span class="line"></span><br><span class="line"> G_OBJECT_CLASS (request_service_processor_parent_class)->finalize(gobject);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_processor_init(RequestServiceProcessor *self) {</span><br><span class="line"> guint index;</span><br><span class="line"></span><br><span class="line"> self->handler = NULL;</span><br><span class="line"> self->process_map = g_hash_table_new(g_str_hash, g_str_equal);</span><br><span class="line"></span><br><span class="line"> for (index = 0; index < 1; index += 1)</span><br><span class="line"> g_hash_table_insert(self->process_map,</span><br><span class="line"> request_service_processor_process_function_defs[index].name,</span><br><span class="line"> &request_service_processor_process_function_defs[index]);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">request_service_processor_class_init(RequestServiceProcessorClass *cls) {</span><br><span class="line"> GObjectClass *gobject_class = G_OBJECT_CLASS (cls);</span><br><span class="line"> ThriftDispatchProcessorClass *dispatch_processor_class =</span><br><span class="line"> THRIFT_DISPATCH_PROCESSOR_CLASS (cls);</span><br><span class="line"> GParamSpec *param_spec;</span><br><span class="line"></span><br><span class="line"> gobject_class->dispose = request_service_processor_dispose;</span><br><span class="line"> gobject_class->finalize = request_service_processor_finalize;</span><br><span class="line"> gobject_class->set_property = request_service_processor_set_property;</span><br><span class="line"> gobject_class->get_property = request_service_processor_get_property;</span><br><span class="line"></span><br><span class="line"> dispatch_processor_class->dispatch_call = request_service_processor_dispatch_call;</span><br><span class="line"> cls->dispatch_call = request_service_processor_dispatch_call;</span><br><span class="line"></span><br><span class="line"> param_spec = g_param_spec_object("handler",</span><br><span class="line"> "Service handler implementation",</span><br><span class="line"> "The service handler implementation "</span><br><span class="line"> "to which method calls are dispatched.",</span><br><span class="line"> TYPE_REQUEST_SERVICE_HANDLER,</span><br><span class="line"> G_PARAM_READWRITE);</span><br><span class="line"> g_object_class_install_property(gobject_class,</span><br><span class="line"> PROP_REQUEST_SERVICE_PROCESSOR_HANDLER,</span><br><span class="line"> param_spec);</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="Client段"><a href="#Client段" class="headerlink" title="Client段"></a>Client段</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">#include <stdio.h></span><br><span class="line">#include <glib-object.h></span><br><span class="line"></span><br><span class="line">#include <thrift/c_glib/protocol/thrift_binary_protocol.h></span><br><span class="line">#include <thrift/c_glib/transport/thrift_buffered_transport.h></span><br><span class="line">#include <thrift/c_glib/transport/thrift_socket.h></span><br><span class="line"></span><br><span class="line">#include "gen-c_glib/request_service.h"</span><br><span class="line"></span><br><span class="line">int main() {</span><br><span class="line"> ThriftSocket *socket;</span><br><span class="line"> ThriftTransport *transport;</span><br><span class="line"> ThriftProtocol *protocol;</span><br><span class="line"> RequestServiceIf *client;</span><br><span class="line"> socket = g_object_new(THRIFT_TYPE_SOCKET,</span><br><span class="line"> "hostname", "localhost",</span><br><span class="line"> "port", 9090,</span><br><span class="line"> NULL);</span><br><span class="line"> transport = g_object_new(THRIFT_TYPE_BUFFERED_TRANSPORT,</span><br><span class="line"> "transport", socket,</span><br><span class="line"> NULL);</span><br><span class="line"> protocol = g_object_new(THRIFT_TYPE_BINARY_PROTOCOL,</span><br><span class="line"> "transport", transport,</span><br><span class="line"> NULL);</span><br><span class="line"> GError *error = NULL;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> thrift_transport_open(transport, &error);</span><br><span class="line"> printf("open client err %p \n", error);</span><br><span class="line"> client = g_object_new(TYPE_REQUEST_SERVICE_CLIENT,</span><br><span class="line"> "input_protocol", protocol,</span><br><span class="line"> "output_protocol", protocol,</span><br><span class="line"> NULL);</span><br><span class="line"> printf("client init finish %p \n", client);</span><br><span class="line"> Result *result = g_object_new(TYPE_RESULT, NULL);</span><br><span class="line"> Param *param = g_object_new(TYPE_PARAM, NULL);</span><br><span class="line"> param->key = "test";</span><br><span class="line"> param->value = 2;</span><br><span class="line"> printf("param %s %d \n", param->key,param->value);</span><br><span class="line"> gboolean ret = request_service_if_send_message(client, &result, param, &error);</span><br><span class="line"> printf("ret %b \n", ret);</span><br><span class="line"> printf("result %d \n", result->result);</span><br><span class="line"> printf("error %s \n", error->message);</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="CMakeFile-txt"><a href="#CMakeFile-txt" class="headerlink" title="CMakeFile.txt"></a>CMakeFile.txt</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">cmake_minimum_required(VERSION 3.24)</span><br><span class="line">project(thrift_rpc C)</span><br><span class="line"></span><br><span class="line">set(CMAKE_C_STANDARD 11)</span><br><span class="line">include_directories(/usr/include/glib-2.0)</span><br><span class="line">include_directories(/usr/lib/x86_64-linux-gnu/glib-2.0/include)</span><br><span class="line">add_executable(thrift_rpc main.c gen-c_glib/request_service.c gen-c_glib/model_types.c)</span><br><span class="line">target_link_libraries(thrift_rpc /usr/local/lib/libthrift_c_glib.so)</span><br><span class="line">target_link_libraries(thrift_rpc /usr/lib/x86_64-linux-gnu/libgobject-2.0.so)</span><br><span class="line">target_link_libraries(thrift_rpc /usr/lib/x86_64-linux-gnu/libglib-2.0.so)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">project(thrift_rpc_server C)</span><br><span class="line">set(CMAKE_C_STANDARD 11)</span><br><span class="line"></span><br><span class="line">add_executable(thrift_rpc_server server.c gen-c_glib/request_service.c gen-c_glib/model_types.c)</span><br><span class="line"></span><br><span class="line">include_directories(/usr/include/glib-2.0)</span><br><span class="line">include_directories(/usr/lib/x86_64-linux-gnu/glib-2.0/include)</span><br><span class="line"></span><br><span class="line">target_link_libraries(thrift_rpc_server /usr/local/lib/libthrift_c_glib.so)</span><br><span class="line">target_link_libraries(thrift_rpc_server /usr/lib/x86_64-linux-gnu/libgobject-2.0.so)</span><br><span class="line">target_link_libraries(thrift_rpc_server /usr/lib/x86_64-linux-gnu/libglib-2.0.so)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="protobuf-c-rpc"><a href="#protobuf-c-rpc" class="headerlink" title="protobuf-c-rpc"></a>protobuf-c-rpc</h1><p>这里说一下protobuf-c-rpc的特点</p>
<ul>
<li>rpc的函数注册是基于前缀的,示例中的<code>example__</code>就是。</li>
<li>Client只能通过异步回调的方式(至少我没发现有方法可以同步获取结果)</li>
<li>支持多种通信方式,tcp,sock等</li>
</ul>
<h2 id="编译安装protofbuf"><a href="#编译安装protofbuf" class="headerlink" title="编译安装protofbuf"></a>编译安装protofbuf</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># wget https://github.com/protocolbuffers/protobuf/releases/download/v22.0/protobuf-22.0.tar.gz</span><br><span class="line"># tar -zxvf protobuf-22.0.tar.gz</span><br><span class="line"># cd protobuf-22.0</span><br><span class="line"># ./autogen.sh</span><br><span class="line"># ./configure</span><br><span class="line"># make </span><br><span class="line"># make install</span><br></pre></td></tr></table></figure>
<h2 id="编译安装protofbuf-c"><a href="#编译安装protofbuf-c" class="headerlink" title="编译安装protofbuf-c"></a>编译安装protofbuf-c</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># wget https://github.com/protobuf-c/protobuf-c/releases/download/v1.4.1/protobuf-c-1.4.1.tar.gz</span><br><span class="line"># tar -zxvf protobuf-c-1.4.1.tar.gz</span><br><span class="line"># cd protobuf-c</span><br><span class="line"># ./autogen.sh</span><br><span class="line"># ./configure</span><br><span class="line"># make </span><br><span class="line"># make install</span><br></pre></td></tr></table></figure>
<h2 id="编译安装protofbuf-c-rpc"><a href="#编译安装protofbuf-c-rpc" class="headerlink" title="编译安装protofbuf-c-rpc"></a>编译安装protofbuf-c-rpc</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># git clone https://github.com/protobuf-c/protobuf-c-rpc.git</span><br><span class="line"># cd protobuf-c-rpc</span><br><span class="line"># ./autogen.sh</span><br><span class="line"># ./configure</span><br><span class="line"># make </span><br><span class="line"># make install</span><br></pre></td></tr></table></figure>
<h2 id="编写协议-1"><a href="#编写协议-1" class="headerlink" title="编写协议"></a>编写协议</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">syntax = "proto3";</span><br><span class="line"></span><br><span class="line">message Param {</span><br><span class="line"> string message = 1;</span><br><span class="line">}</span><br><span class="line">message Result {</span><br><span class="line"> bool result = 1;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">service RpcSendMsg {</span><br><span class="line"> rpc Send (Param) returns (Result);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="Server端-1"><a href="#Server端-1" class="headerlink" title="Server端"></a>Server端</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">#include "stdio.h"</span><br><span class="line">#include "model.pb-c.h"</span><br><span class="line">#include <string.h></span><br><span class="line">#include <protobuf-c-rpc/protobuf-c-rpc.h></span><br><span class="line">#include <stdbool.h></span><br><span class="line"></span><br><span class="line">static void example__send(RpcSendMsg_Service *service, const Param *param, Result_Closure closure, void *closure_data) {</span><br><span class="line"> printf("example__send run message:%s \n",param->message);</span><br><span class="line"> (void) service;</span><br><span class="line"> Result result = RESULT__INIT;</span><br><span class="line"> if (strcmp(param->message, "hello") != 0) {</span><br><span class="line"> result.result = true;</span><br><span class="line"> } else {</span><br><span class="line"> result.result = false;</span><br><span class="line"> }</span><br><span class="line"> closure(&result, closure_data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static RpcSendMsg_Service rpc_send_msg_service = RPC_SEND_MSG__INIT(example__);</span><br><span class="line"></span><br><span class="line">int main(void) {</span><br><span class="line"> printf("service start \n");</span><br><span class="line"> ProtobufC_RPC_Server *server;</span><br><span class="line"> ProtobufC_RPC_AddressType address_type = PROTOBUF_C_RPC_ADDRESS_TCP;</span><br><span class="line"> server = protobuf_c_rpc_server_new(address_type, "12345", (ProtobufCService *) &rpc_send_msg_service, NULL);</span><br><span class="line"> printf("service start at 12345 port\n");</span><br><span class="line"> for (;;)</span><br><span class="line"> protobuf_c_rpc_dispatch_run(protobuf_c_rpc_dispatch_default());</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="Client段-1"><a href="#Client段-1" class="headerlink" title="Client段"></a>Client段</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">//</span><br><span class="line">// Created by Eviltuzki on 23-2-11.</span><br><span class="line">//</span><br><span class="line">#include "stdio.h"</span><br><span class="line">#include <string.h></span><br><span class="line">#include "model.pb-c.h"</span><br><span class="line">#include <protobuf-c-rpc//protobuf-c-rpc.h></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">static void</span><br><span class="line">handler_result(const Result *result, void *closure_data) {</span><br><span class="line"> printf("rpc result %d\n", result->result);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">int main(void) {</span><br><span class="line"> ProtobufCService *service;</span><br><span class="line"> ProtobufC_RPC_Client *client;</span><br><span class="line"> ProtobufC_RPC_AddressType address_type = PROTOBUF_C_RPC_ADDRESS_TCP;</span><br><span class="line"> const char *name = "localhost:12345";</span><br><span class="line"> service = protobuf_c_rpc_client_new(address_type, name, &rpc_send_msg__descriptor, NULL);</span><br><span class="line"> printf("connenct to server service is %p \n",service);</span><br><span class="line"> if (service == NULL) {</span><br><span class="line"> printf("error creating client \n");</span><br><span class="line"> return 0;</span><br><span class="line"> }</span><br><span class="line"> client = (ProtobufC_RPC_Client *) service;</span><br><span class="line"> while (!protobuf_c_rpc_client_is_connected(client))</span><br><span class="line"> protobuf_c_rpc_dispatch_run(protobuf_c_rpc_dispatch_default());</span><br><span class="line"> protobuf_c_boolean is_done = 0;</span><br><span class="line"> Param param = PARAM__INIT;</span><br><span class="line"> param.message = "hello1";</span><br><span class="line"> rpc_send_msg__send(service, &param, handler_result, &is_done);</span><br><span class="line"> while (!is_done)</span><br><span class="line"> protobuf_c_rpc_dispatch_run(protobuf_c_rpc_dispatch_default());</span><br><span class="line"> return 0;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="CMakeFile-txt-1"><a href="#CMakeFile-txt-1" class="headerlink" title="CMakeFile.txt"></a>CMakeFile.txt</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">cmake_minimum_required(VERSION 3.24)</span><br><span class="line">project(rpc C)</span><br><span class="line"></span><br><span class="line">set(CMAKE_C_STANDARD 17)</span><br><span class="line"></span><br><span class="line">add_executable(rpc main.c model.pb-c.h model.pb-c.c)</span><br><span class="line">target_link_libraries(rpc /usr/local/lib//libprotobuf-c-rpc.so)</span><br><span class="line">target_link_libraries(rpc /usr/local/lib/libprotobuf-c.so)</span><br><span class="line">target_link_libraries(rpc /usr/local/lib/libprotoc.so)</span><br><span class="line">target_link_libraries(rpc /usr/local/lib/libprotobuf-lite.so)</span><br><span class="line">target_link_libraries(rpc /usr/local/lib/libprotobuf.so)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">project(rpc-s C)</span><br><span class="line">add_executable(rpc-s server.c model.pb-c.h model.pb-c.c)</span><br><span class="line">target_link_libraries(rpc-s /usr/local/lib//libprotobuf-c-rpc.so)</span><br><span class="line">target_link_libraries(rpc-s /usr/local/lib/libprotobuf-c.so)</span><br><span class="line">target_link_libraries(rpc-s /usr/local/lib/libprotoc.so)</span><br><span class="line">target_link_libraries(rpc-s /usr/local/lib/libprotobuf-lite.so)</span><br><span class="line">target_link_libraries(rpc-s /usr/local/lib/libprotobuf.so)</span><br></pre></td></tr></table></figure>
<h1 id="rpcgen"><a href="#rpcgen" class="headerlink" title="rpcgen"></a>rpcgen</h1><p>网上例子比较多,这里就不列举了,需要注意的是<br>long long类型对应的是hyper<br>参考:<br><a target="_blank" rel="noopener" href="https://docs.oracle.com/cd/E26502_01/html/E35597/xdrproto-31244.html#xdrproto-18">https://docs.oracle.com/cd/E26502_01/html/E35597/xdrproto-31244.html#xdrproto-18</a><br><a target="_blank" rel="noopener" href="https://docs.oracle.com/cd/E19683-01/816-1435/6m7rrfn7f/index.html">https://docs.oracle.com/cd/E19683-01/816-1435/6m7rrfn7f/index.html</a></p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://eviltuzki.top/2023/01/28/Arm%E5%B9%B3%E5%8F%B0%20Kata%E5%BC%80%E5%90%AFNvdimm(memory%20hotplug)/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Eviltuzki">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Eviltuzki">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2023/01/28/Arm%E5%B9%B3%E5%8F%B0%20Kata%E5%BC%80%E5%90%AFNvdimm(memory%20hotplug)/" class="post-title-link" itemprop="url">Arm平台 Kata开启Nvdimm(memory hotplug)</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2023-01-28 00:00:00" itemprop="dateCreated datePublished" datetime="2023-01-28T00:00:00+08:00">2023-01-28</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/nvdimm-Kata-Arm64/" itemprop="url" rel="index"><span itemprop="name">nvdimm, Kata, Arm64,</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>内存热插拔是容器在部署中动态分配内存的关键特性,在 x86 上,可以使用直接启用 ACPI 的 QEMU 启动 VM,因为它会隐式启动固件。但是对于 arm64,则需要明确指定固件。也就是说,如果准备在 arm64 上运行一个普通的 Kata Container,你需要额外做的是在使用内存热插拔功能之前安装 UEFI ROM。</p>
<h1 id="安装-UEFI-ROM"><a href="#安装-UEFI-ROM" class="headerlink" title="安装 UEFI ROM"></a>安装 UEFI ROM</h1><h2 id="修改脚本适配系统"><a href="#修改脚本适配系统" class="headerlink" title="修改脚本适配系统"></a>修改脚本适配系统</h2><p>需要执行的脚本 </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$GOPATH/src/github.com/kata-containers/tests/.ci/aarch64/install_rom_aarch64.sh</span><br></pre></td></tr></table></figure>
<p>该脚本默认适配的系统是Ubuntu,使用apt源安装相关依赖,适配麒麟系统需要修改为dnf源进行安装,将脚本安装依赖部分修改为 </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dnf install -y python python3 python3-distutils-extra uuid-devel bison flex</span><br></pre></td></tr></table></figure>
<p>其他edk2相关git项,根据网络情况进行适配</p>
<h2 id="执行脚本安装"><a href="#执行脚本安装" class="headerlink" title="执行脚本安装"></a>执行脚本安装</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo .ci/aarch64/install_rom_aarch64.sh</span><br></pre></td></tr></table></figure>
<p>脚本执行安装完成后,默认kata的img路径下(/usr/share/kata-containers)生成2个文件kata-flash0.img和 kata-flash1.img</p>
<h1 id="内核适配"><a href="#内核适配" class="headerlink" title="内核适配"></a>内核适配</h1><p>内核默认不支持nvdimm,需要打社区提供的patch才能开启</p>
<p>目前适配的kernel版本是5.4.160,社区提供了5.4.x版本kernel相应的patch,路径如下:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$GOPATH/src/github.com/kata-containers/kata-containers/tools/packaging/kernel/patches/5.4.x/0006-arm64-mm-Enable-memory-hot-remove.patch</span><br></pre></td></tr></table></figure>
<p>将该文件拷贝至kernel源码下,执行patch</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cd {kernel_path}</span><br><span class="line">cp $GOPATH/src/github.com/kata-containers/kata-containers/tools/packaging/kernel/patches/5.4.x/0006-arm64-mm-Enable-memory-hot-remove.patch ..</span><br><span class="line">patch -p1 <../0006-arm64-mm-Enable-memory-hot-remove.patch</span><br></pre></td></tr></table></figure>
<p>编译内核注意nvdimm相关的config要开启</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">CONFIG_ACPI_NFIT=y</span><br><span class="line">CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y</span><br><span class="line">CONFIG_MEMORY_HOTREMOVE=y</span><br><span class="line">CONFIG_ZONE_DEVICE=y</span><br><span class="line">CONFIG_NVDIMM_PFN=y</span><br><span class="line">CONFIG_NVDIMM_DAX=y</span><br></pre></td></tr></table></figure>
<p>重新编译后,替换编译后的内核文件</p>
<h1 id="配置文件修改"><a href="#配置文件修改" class="headerlink" title="配置文件修改"></a>配置文件修改</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># If false and nvdimm is supported, use nvdimm device to plug guest image.</span><br><span class="line"># Otherwise virtio-block device is used.</span><br><span class="line"># Default is false</span><br><span class="line">#disable_image_nvdimm = true //这里不要打开</span><br><span class="line"> </span><br><span class="line"># -pflash can add image file to VM. The arguments of it should be in format</span><br><span class="line"># of ["/path/to/flash0.img", "/path/to/flash1.img"]</span><br><span class="line">pflashes = ["/usr/share/kata-containers/kata-flash0.img","/usr/share/kata-containers/kata-flash1.img"] //这里指定uefi的rom</span><br></pre></td></tr></table></figure>
<h1 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h1><p>如果基于之前的kernel编译了驱动之类的内容,kernel打了patch需要重新编译驱动,否则出现mod无法加载的情况</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://eviltuzki.top/2022/12/30/Kata%20rootf%E9%80%82%E9%85%8D%E6%98%87%E8%85%BEGPU%E9%A9%B1%E5%8A%A8/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Eviltuzki">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Eviltuzki">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/12/30/Kata%20rootf%E9%80%82%E9%85%8D%E6%98%87%E8%85%BEGPU%E9%A9%B1%E5%8A%A8/" class="post-title-link" itemprop="url">Kata rootfs 适配昇腾GPU驱动(Arm平台)</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-12-30 00:00:00" itemprop="dateCreated datePublished" datetime="2022-12-30T00:00:00+08:00">2022-12-30</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Linux/" itemprop="url" rel="index"><span itemprop="name">Linux</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h2 id="Kata-rootfs-适配昇腾GPU驱动(Arm平台)"><a href="#Kata-rootfs-适配昇腾GPU驱动(Arm平台)" class="headerlink" title="Kata rootfs 适配昇腾GPU驱动(Arm平台)"></a>Kata rootfs 适配昇腾GPU驱动(Arm平台)</h2><h1 id="虚拟机"><a href="#虚拟机" class="headerlink" title="虚拟机"></a>虚拟机</h1><h2 id="选择"><a href="#选择" class="headerlink" title="选择"></a>选择</h2><ul>
<li>系统:驱动适配比较好的系统是CentOS 7.6和8.2,本次制作使用CentOS 8.2.2004 arm 镜像</li>
<li>虚拟机:驱动依赖硬件设备,所以选择在宿主机通过qemu启动虚拟机,在虚拟机内部适配驱动</li>
<li>其他:开启kvm加速,实测arm架构下开启kvm,需要宿主机是L0(不能是虚拟机),且bios使用edk2</li>
<li>宿主机:宿主机系统为银河麒麟v10 arm版</li>
</ul>
<h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><ul>
<li>下载CentOS 8.2.2004 arm 镜像<ul>
<li>下载地址:<a target="_blank" rel="noopener" href="https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.2.2004/isos/aarch64/CentOS-8.2.2004-aarch64-dvd1.iso">https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.2.2004/isos/aarch64/CentOS-8.2.2004-aarch64-dvd1.iso</a></li>
</ul>
</li>
<li>下载bios引导文件,edk2-aarch64的安装包,执行安装<ul>
<li>下载地址:<a target="_blank" rel="noopener" href="https://www.kraxel.org/repos/jenkins/edk2/">https://www.kraxel.org/repos/jenkins/edk2/</a></li>
<li>安装后bios文件位于 /usr/share/edk2.git/aarch64/QEMU_EFI.fd</li>
</ul>
</li>
<li>安装最新的qemu(建议编译安装,可以选择自己依赖的组件,直接从yum源安装的可能缺少组件)<ul>
<li>补充说明:qemu启动虚拟机后,可以通过-net user直接共享宿主机的网络,并可以开启ssh通道,该功能依赖slirp,编译配置的时候需要启用slirp</li>
</ul>
</li>
</ul>
<h2 id="制作虚拟机(宿主机)"><a href="#制作虚拟机(宿主机)" class="headerlink" title="制作虚拟机(宿主机)"></a>制作虚拟机(宿主机)</h2><ul>
<li>制作qcow2文件(相当于是硬盘, 文件名hd.qcow2 , 大小100G)<ul>
<li>qemu-img create -f qcow2 hd.qcow2 100G</li>
</ul>
</li>
<li>安装操作系统<ul>
<li>qemu启动命令:qemu-system-aarch64 -m 24G -cpu host -smp 16 -M virt,accel=kvm -bios QEMU_EFI.fd -nographic -drive if=none,file=hd.qcow2,id=hd0 -device virtio-blk-device,drive=hd0 -drive if=none,file=CentOS-8.2.2004-aarch64-dvd1.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom -net user,hostfwd=tcp::2222-:22 -net nic -device vfio-pci,host=0000:83:00.0</li>
<li>qemu参数说明:<ul>
<li>-m 24G 指定内存大小</li>
<li>-cpu host 指定CPU类型和宿主机一致,注意host类型需要开启kvm加速</li>
<li>-M virt,accel=kvm machineType类型为virt(arm均使用virt),加速器使用kvm</li>
<li>-smp 16 cpu 16核</li>
<li>-bios QEMU_EFI.fd 指定edk2的efi文件</li>
<li>-nographic 因为不是在本地,所以直接通过控制台以基础文本的形式显示</li>
<li>-drive if=none,file=hd.qcow2,id=hd0 -device virtio-blk-device,drive=hd0 指定硬盘设备及驱动</li>
<li>-drive if=none,file=CentOS-8.2.2004-aarch64-dvd1.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom 指定操作系统安装文件,以cdrom方式加载</li>
<li>-net user,hostfwd=tcp::2222-:22 -net nic 开启与宿主机的共享网络,同时将虚拟机的22端口映射到宿主机的2222端口</li>
<li>-device vfio-pci,host=0000:83:00.0 将宿主机的设备vfio直通到虚拟机</li>
</ul>
</li>
<li>如果在宿主机无法正常安装,可以考虑本地启动qemu安装,然后将qcow2文件拷贝至服务器</li>
<li>安装完成后重启系统即可,以后启动qemu cdrom参数不再需要。</li>
</ul>
</li>
<li>注意事项:<ul>
<li>虚拟机启动后,需要开启sshd,否则无法ssh连接到虚拟机</li>
<li>QEMU_EFI.fd一定用edk2的,不要使用<code>https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd</code> 这个版本,这个无法开启kvm加速</li>
<li>全虚拟化的虚拟机慢的要死,开机就要15分钟,一定要开启kvm加速,后面驱动适配在全虚拟化下也会失败(全虚拟化运行太慢,导致驱动执行失败)</li>
<li>vfio宿主机一定要开启,否则虚拟机无法获取设备</li>
<li>设备号可以通过lspci看到</li>
</ul>
</li>
</ul>
<h1 id="内核制作"><a href="#内核制作" class="headerlink" title="内核制作"></a>内核制作</h1><h2 id="修改内核magversion"><a href="#修改内核magversion" class="headerlink" title="修改内核magversion"></a>修改内核magversion</h2><ul>
<li>进入内核源码目录,修改 include/linux/vermagic.h<ul>
<li>修改<code>#define MODULE_VERMAGIC_MODULE_UNLOAD ""</code></li>
<li>为:<code>#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload"</code></li>
<li>修改<code>#define MODULE_VERMAGIC_MODVERSIONS ""</code></li>
<li>为:<code>#define MODULE_VERMAGIC_MODVERSIONS "modversions"</code></li>
</ul>
</li>
</ul>
<h2 id="编译内核获取bzImage(宿主机或虚拟机都可)"><a href="#编译内核获取bzImage(宿主机或虚拟机都可)" class="headerlink" title="编译内核获取bzImage(宿主机或虚拟机都可)"></a>编译内核获取bzImage(宿主机或虚拟机都可)</h2><ul>
<li>直接执行make就行,注意配置和之前保持一致</li>
<li>编译完成后,将arch/aarch64/boot/bzImage拷贝出来,作为kata启动的kernel</li>
</ul>
<h2 id="制作内核rpm安装包(宿主机或虚拟机都可)"><a href="#制作内核rpm安装包(宿主机或虚拟机都可)" class="headerlink" title="制作内核rpm安装包(宿主机或虚拟机都可)"></a>制作内核rpm安装包(宿主机或虚拟机都可)</h2><ul>
<li>保持配置不变,执行make rpm-pkg</li>
<li>然后将kernel,kernel-devel,kernel-headers三个rpm拷贝出来</li>
</ul>
<h2 id="虚拟机安装新内核(虚拟机)"><a href="#虚拟机安装新内核(虚拟机)" class="headerlink" title="虚拟机安装新内核(虚拟机)"></a>虚拟机安装新内核(虚拟机)</h2><ul>
<li>将编译的rpm安装包拷贝至虚拟机(开启ssh后scp -P 2222 xxx xxx@localhost:~即可)</li>
<li>进入虚拟机后,执行rpm -ivh kernel-xxxxx.rpm 安装内核,然后重启虚拟机,用编译版本的内核启动虚拟机,准备后续rootfs制作</li>
</ul>
<h1 id="rootfs制作"><a href="#rootfs制作" class="headerlink" title="rootfs制作"></a>rootfs制作</h1><h2 id="制作rootfs(宿主机或虚拟机都可)"><a href="#制作rootfs(宿主机或虚拟机都可)" class="headerlink" title="制作rootfs(宿主机或虚拟机都可)"></a>制作rootfs(宿主机或虚拟机都可)</h2><ul>
<li>进入kata源码kata-containers/tools/osbuilder/目录下,执行make镜像命令</li>
<li><code>make DISTRO=centos OS_VERSION=8.2.2004 SECCOMP=no DEBUG=true USE_DOCKER=true AGENT_INIT=yes EXTRA_PKGS='net-tools pciutils udev e2fsprogs tar gcc' rootfs</code></li>
<li>net-tools pciutils udev e2fsprogs tar gcc 这几样工具是驱动安装过程中需要的,需要提前打包至rootfs</li>
</ul>
<h2 id="拷贝rootfs至虚拟机"><a href="#拷贝rootfs至虚拟机" class="headerlink" title="拷贝rootfs至虚拟机"></a>拷贝rootfs至虚拟机</h2><ul>
<li>上一步操作完成后,当前目录下会出来centos_rootfs文件夹,将该目录打包,拷贝至虚拟机</li>
<li>tar czvf centos_rootfs.tgz centos_rootfs</li>
<li>scp -P 2222 centos_rootfs.tgz root@localhost:~</li>
</ul>
<h1 id="驱动适配"><a href="#驱动适配" class="headerlink" title="驱动适配"></a>驱动适配</h1><h2 id="补充缺失文件-虚拟机,其实这一步再打包之前操作也可以"><a href="#补充缺失文件-虚拟机,其实这一步再打包之前操作也可以" class="headerlink" title="补充缺失文件(虚拟机,其实这一步再打包之前操作也可以)"></a>补充缺失文件(虚拟机,其实这一步再打包之前操作也可以)</h2><ul>
<li>解压rootfs</li>
<li>/usr/share/zoneinfo文件夹拷贝至 rootfs对应的目录下(centos默认rootfs缺失时区信息,无法安装驱动)</li>
<li>拷贝驱动文件,kernel-devel,kernel-headers到rootfs的某目录下(我拷贝到home目录下),用于后续chroot安装</li>
<li>创建hook脚本<ul>
<li>mkdir -p /usr/share/oci/hooks/prestart</li>
<li>cd /usr/share/oci/hooks/prestart</li>
<li>创建mount_tmpfs.sh脚本,解决/tmp,/var/log 只读问题,内容如下:</li>
</ul>
</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#!/bin/sh</span><br><span class="line">mount -t tmpfs -o size=8192m tmpfs /tmp</span><br><span class="line">mount -t tmpfs -o size=8192m tmpfs /var/log </span><br></pre></td></tr></table></figure>
<h2 id="挂载目录-虚拟机"><a href="#挂载目录-虚拟机" class="headerlink" title="挂载目录(虚拟机)"></a>挂载目录(虚拟机)</h2><ul>
<li><code>export ROOTFS_DIR=/root/centos_rootfs</code></li>
<li><code>mount -t sysfs -o ro none ${ROOTFS_DIR}/sys</code></li>
<li><code>mount -t proc -o ro none ${ROOTFS_DIR}/proc</code></li>
<li><code>mount -o bind,ro /dev ${ROOTFS_DIR}/dev</code></li>
<li><code>mount -t devpts none ${ROOTFS_DIR}/dev/pts</code></li>
<li><code>mount -t tmpfs none ${ROOTFS_DIR}/tmp</code></li>
</ul>
<h2 id="chroot并安装驱动-虚拟机"><a href="#chroot并安装驱动-虚拟机" class="headerlink" title="chroot并安装驱动(虚拟机)"></a>chroot并安装驱动(虚拟机)</h2><ul>
<li>chroot $ROOTFS_DIR</li>
<li>进入home目录(驱动和kernel目录)</li>
<li>安装kernel-devel和kernel-headers (rpm -ivh kernel*.rpm)</li>
<li>创建华为用户组HwHiAiUser 和 用户<ul>
<li><code>groupadd HwHiAiUser</code></li>
<li><code>useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash</code></li>
</ul>
</li>
<li>安装驱动 ./A300-3000-npu-driver_21.0.3.3_linux-aarch64.run –full </li>
<li>驱动安装成功后,执行 /usr/local/sbin/npu-smi info 如果能正常回显,则继续安装驱动,不能正常回显,则重启虚拟机,先exit退出chroot</li>
<li>解除挂载 <code>umount ${ROOTFS_DIR}/sys ${ROOTFS_DIR}/proc ${ROOTFS_DIR}/dev/pts ${ROOTFS_DIR}/tmp ${ROOTFS_DIR}/dev</code></li>
<li>然后reboot重启虚拟机,重启后重新挂载目录,然后执行 /usr/local/sbin/npu-smi info 看是否能正常回显</li>
<li>正常回显后,安装固件 ./A300-3000-npu-firmware_1.81.22.2.220.run –full</li>
<li>然后删除内核源码(/usr/src/kernels下,内核版本的源码删除),删除kernel-devel,kernel-headers,驱动等文件(减少rootfs镜像大小)</li>
<li>exit退出chroot</li>
<li>解除挂载<code> umount ${ROOTFS_DIR}/sys ${ROOTFS_DIR}/proc ${ROOTFS_DIR}/dev/pts ${ROOTFS_DIR}/tmp ${ROOTFS_DIR}/dev</code></li>
<li>将rootfs打包(如果rootfs在虚拟机中制作,则忽略该步骤),并拷贝到宿主机上</li>
</ul>
<h2 id="制作镜像"><a href="#制作镜像" class="headerlink" title="制作镜像"></a>制作镜像</h2><ul>
<li>解压虚拟机中的rootfs文件</li>
<li>切换到kata的image-builder目录(kata-containers/tools/osbuilder/image-builder)</li>
<li>制作镜像./image_builder.sh rootfsDir</li>
<li>得到kata-containers.img</li>
</ul>
<h1 id="其他适配"><a href="#其他适配" class="headerlink" title="其他适配"></a>其他适配</h1><h2 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h2><ul>
<li>kata的config需要进行以下几个修改<ol>
<li><code>guest_hook_path = "/usr/share/oci/hooks"</code></li>
<li><code>kernel_modules=["drv_devdrv_host","drv_davinci_intf_host","drv_tsdrv_platform_host","drv_pcie_vnic_host","drv_pcie_hdc_host","drv_devmm_host"]</code></li>
<li><code>hotplug_vfio_on_root_bus = true</code></li>
<li><code>pcie_root_port = 2</code></li>
</ol>
</li>
<li>说明:<ol>
<li><code>guest_hook_path</code> 执行hook,路径不需要更改,驱动需要挂载tmpfs,通过hook执行</li>
<li><code>kernel_modules</code> 驱动的modules默认不会加载,需要手动加载,配置到这里,vm启动会自动加载</li>
<li><code>hotplug_vfio_on_root_bus</code> 开启root bus,arm平台需要通过pcie_root_port进行设备热插拔</li>
<li><code>pcie_root_port</code> 单个虚拟机最多可以挂载GPU设备数</li>
</ol>
</li>
</ul>
<h2 id="Kata源码"><a href="#Kata源码" class="headerlink" title="Kata源码"></a>Kata源码</h2><ul>
<li>主要修改如下:<ul>
<li>virt模式支持pcieRootPort设备,通过配置进行加载</li>
<li>qmp添加设备指定bus为pcieRootPort设备,arm下只有pcieRootPort支持热插拔</li>
</ul>
</li>
</ul>
<h1 id="Q-amp-A"><a href="#Q-amp-A" class="headerlink" title="Q&A"></a>Q&A</h1><ol>
<li><p>启动后,kata-runtime exec 进入vm后,/dev/loop设备只有1个</p>
<ul>
<li>修改内核配置<ul>
<li><code>CONFIG_BLK_DEV_LOOP=y</code></li>
<li><code>CONFIG_BLK_DEV_LOOP_MIN_COUNT=4</code></li>
</ul>
</li>
</ul>
</li>
<li><p>qemu 使用 -cpu host -M virt,accel=kvm 启动虚拟机黑屏</p>
<ul>
<li>bios的efi启动文件不正确,使用edk2的efi文件即可</li>
</ul>
</li>
<li><p>安装驱动npu-smi info执行后提示 <code>dcmi module initialize failed. ret is -8005</code></p>
<ul>
<li>提示-8005的原因有很多,下面列出来几个适配中遇到过的<ul>
<li>显卡设备被其他驱动占用,去/sys/bus/pci/drivers/devdrv_device_driver目录下重新bind设备即可。</li>
<li>内核模块加载不全,lsmod对比kernel_modules中的配置,是否已经加载全。</li>
<li>同时提示<code>sh: /tmp/pci_get_info_234.tmp: Read-only file system</code>检查Hook脚本是否执行,可以df看下挂载情况。</li>
<li>其他原因,可以通过dmesg查看kernel日志,具体排查</li>
</ul>
</li>
</ul>
</li>
<li><p>chroot后,安装驱动,提示缺少xxxx组件</p>
<ul>
<li>EXTRA_PKGS后面追加缺少的命令的安装包即可,无依赖的,可直接拷贝到rootfs对应目录下</li>
</ul>
</li>
<li><p>kernel-devel和kernel-headers是否可以不安装?</p>
<ul>
<li>需要安装,驱动安装过程中,有部分模块依赖内核,需要通过内核源码进行重编译,安装完成后,删除对应src目录即可。</li>
<li>通过dkms安装会快点,但是依赖过多,不建议</li>
</ul>
</li>
<li><p>内核日志提示:<code>drv_seclib_host: version magic '5.4.160-1.el7.aarch64 SMP mod_unload modversions aarch64' should be '5.4.160-1.el7.aarch64 SMP aarch64'</code></p>
<ul>
<li>内核的version magic和编译的驱动的version magic不一致,参考内核部分修改version magic,重新编译即可</li>
</ul>
</li>
<li><p>qemu启动时加上-net user提示<code> -net user: Parameter 'type' expects a net backend type (maybe it is not compiled into this binary)</code></p>
<ul>
<li>编译qemu缺少slirp,重新config qemu,加上slirp后重新make qemu即可</li>
</ul>
</li>
</ol>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://eviltuzki.top/2022/11/25/Rust%E5%B0%8F%E8%AF%95%E7%89%9B%E5%88%80/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Eviltuzki">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Eviltuzki">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/11/25/Rust%E5%B0%8F%E8%AF%95%E7%89%9B%E5%88%80/" class="post-title-link" itemprop="url">Rust小试牛刀</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-11-25 00:00:00" itemprop="dateCreated datePublished" datetime="2022-11-25T00:00:00+08:00">2022-11-25</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Rust/" itemprop="url" rel="index"><span itemprop="name">Rust</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="Rust小试牛刀"><a href="#Rust小试牛刀" class="headerlink" title="Rust小试牛刀"></a>Rust小试牛刀</h1><p>Rust的书已经看完2本了,看程序基本上能看懂一些了(生命周期这块还是迷迷糊糊),但是觉得多少还是要自己写一下程序,实际应用一下才能学会。正好今天找了一个练手的小项目,初步尝试一下</p>
<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>N年之前给媳妇写过一个小程序,处理Excel数据的,大致就是从A.xlsx读取数据,分组合并并计算,然后追加写入到B.xlsx,但是其中有个字典关系的映射,以前是维护在代码中的,每次修改字典都要重新编译。<br>加上当时程序是.Net写的,WinForm程序,依赖Windows和VisualStudio这个组合,最近今年工作基本就没用过Windows,电脑也换成了M1的Mac,给她处理这个程序要安装个arm版Windows不说,还要安装VisualStudio,本就不富裕的硬盘,又被拖走了几十个G。<br>想着既然学了Rust,加上为了处理这个程序,索性就用Rust重写一份吧。</p>
<h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><ol>
<li>Rust的安装就不多说什么了,按照官网的脚本执行一下就搞定了</li>
<li>编辑器我用的是VisualCode,配合rust-analyzer插件,debug就是直接用CodeLLDB。</li>
<li>因为要解析xlsx文件,在<code>https://lib.rs/search?q=xlsx</code>查了一圈,最后决定用<code>umya-spreadsheet="0.8.3"</code></li>
<li>因为有个需要配置的字典,考虑json和toml,最后决定用toml,因为对我媳妇而已,这个更直接一些,最终选择<code>toml="0.5.0"</code></li>
</ol>
<h2 id="开工"><a href="#开工" class="headerlink" title="开工"></a>开工</h2><p>cargo new一个项目,添加好依赖,开整,只是逻辑的话,其实很简单,按照.Net的逻辑直接迁移过来就行了,不过有一说一,写的过程中还是挺多麻烦的,光看书以为自己掌握的东西,coding的时候却干着急想不起来怎么写,最后还是依赖搜索引擎解决。<br>另外还有一点就是关于mod,直到程序写完了,也没太get这个玩意和目录的关系怎么搞。所以最终的项目还是基于一个main.rs实现的。<br>逻辑啥的,就不具体写这里了,记录一下自己开发过程中记得住记不住的东西吧。</p>
<h3 id="结构体"><a href="#结构体" class="headerlink" title="结构体"></a>结构体</h3><p>读取数据之后肯定不能直接用个元祖或者Map传来传去,怎么也得有个结构体来组装数据,为了隔离开,我这里还是用mod来进行一下简单的区分。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">pub mod model {</span><br><span class="line"> #[derive(Debug, Clone)]</span><br><span class="line"> pub struct ProductModel {</span><br><span class="line"> pub field1: String,</span><br><span class="line"> pub field2: String,</span><br><span class="line"> pub field3: i32,</span><br><span class="line"> pub type_: String,</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>别看就上面几个字段,就这个<code>type_</code>还折腾我一会,因为type是关键字,如果确实要用type做这个字段名称,就要用<code>r#type</code>, 还有就是从mod到struce到field,都要pub,否则访问不了(开始在不同目录,后来放到一个文件了,也没调整了,这块后面再补习一下吧)。</p>
<h3 id="xlsx处理lib-umya-spreadsheet"><a href="#xlsx处理lib-umya-spreadsheet" class="headerlink" title="xlsx处理lib-umya_spreadsheet"></a>xlsx处理lib-umya_spreadsheet</h3><p>rust处理Excel的lib本来就不是很多,还有很多是只支持读取不支持写入或者只支持写入不支持读取的,好不容易找到了这么一个既支持读又支持写入的,搜了一圈,除了官方文档,几乎没有任何资料。我处理xlsx的时候基本上是按照行进行处理,一行封装成一个model,所以需要知道当前xlsx的当前sheet有多少行数据,然后for循环遍历,组合数据。然而就找一共有多少行这个api就一个一个尝试,官方文档并没有说这块内容,网上也没有这个使用教程,饶了一大圈,最终找到了这个api <code>sheet.get_highest_row()</code> , 不管怎么说,兜了一大圈,这个总算是解决了。<br>然后就是下一个问题,写入api需要传一个book对象,因为第二个xlsx实际上是我要追加数据,不是新建一个excel,凭着感觉走,是先用read的api创建mut对象,修改之后吧read的book放到write中,执行回写,验证了一下,hmmm没猜错,这样基本上这个lib的使用问题得到了解决。</p>
<h3 id="for循环"><a href="#for循环" class="headerlink" title="for循环"></a>for循环</h3><p>for循环应该是一门语言中最基本的部分了,依靠代码提示,这个没出太大问题,vec和map的循环,都顺利进行,但是拿到一个sheet有多少行之后,我要遍历的时候发现不会了,然后又是搜索引擎走一圈,找到了这个最简单的语法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">for i in 1..sheet.get_highest_row()+1 {</span><br><span class="line"> ....</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>唉,就如实说,光看书是真的不行,还是得coding才能掌握的说。</p>
<h3 id="集合"><a href="#集合" class="headerlink" title="集合"></a>集合</h3><p>本来以为集合是个简单的东西,没想到这上面也废了不少劲。简单总结一下:</p>
<ul>
<li>Vec 的添加元素用push</li>
<li>HashSet的添加元素用insert</li>
<li>HashMap的添加键值对也用insert</li>
<li>HashMap的遍历调用iter然后for循环,得到的是一个元素,key是.0,value是.1</li>
<li>迭代得到的元素是引用,如果要放入其他集合,我选择的是clone一份,直接解引用,经常出现所有权问题,暂时也没想到更好的办法。</li>
</ul>
<h3 id="字符串-String和-amp-str"><a href="#字符串-String和-amp-str" class="headerlink" title="字符串 (String和&str)"></a>字符串 (String和&str)</h3><p>说真的,字符串这玩意还挺绕的,String和&str,就这两个来来回回的转换,我这也是偷懒了,自己接收也好,使用也罢,基本都用String了,得到了&str基本都转换成String,然后在传递了,最起码没有所有权问题了,偷个懒,后面在慢慢找更好的适配方法。</p>
<h3 id="字符串-字符串拼接"><a href="#字符串-字符串拼接" class="headerlink" title="字符串 (字符串拼接)"></a>字符串 (字符串拼接)</h3><p>我是怎么也没有想到,一个字符串拼接竟然愁住了我。<br>我从HashSet<String>的iter遍历得到的item,类型是&String,我就想直接后面拼接个字符串,然后判断在另外一个集合中是否存在,然后这个追加愁住了我。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">let name =element+"流";</span><br><span class="line">报错:</span><br><span class="line">cannot add `&str` to `&std::string::String`</span><br><span class="line">string concatenation requires an owned `String` on the leftrustcClick for full compiler diagnostic</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> let name = element.add("流");</span><br><span class="line"> 报错:</span><br><span class="line"> cannot move out of `* element ` which is behind a shared reference</span><br><span class="line">move occurs because `* element ` has type `std::string::String`, which does not implement the `Copy` traitrustcClick for full compiler diagnostic</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">let name =*element.add("流");</span><br><span class="line">报错:</span><br><span class="line">the size for values of type `str` cannot be known at compilation time</span><br><span class="line">the trait `Sized` is not implemented for `str`</span><br><span class="line">all local variables must have a statically known size</span><br><span class="line">unsized locals are gated as an unstable feature</span><br></pre></td></tr></table></figure>
<p>我自己尝试出来正确方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">let name = String::from(element).add("流");</span><br></pre></td></tr></table></figure>
<p>再来看另外一个, 对于元组的引用,也是通过clone来解决的。。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> let mut map: HashMap<String, Vec<Model>> = HashMap::new();</span><br><span class="line"> ...</span><br><span class="line"> for entry in map.iter() {</span><br><span class="line"> let sheet_name = entry.0.clone().add("流");</span><br><span class="line"> let sheet = book.get_sheet_by_name_mut(&sheet_name).unwrap();</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="全局配置"><a href="#全局配置" class="headerlink" title="全局配置"></a>全局配置</h3><p>这个程序因为有个配置文件,运行过程中需要使用,开始想着声明一个全局变量就行了,准备放到dict这个mod里面,存储当然就用HashMap,然后就出现了问题</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">pub mod dict {</span><br><span class="line"> static mut map:HashMap<String,String> = HashMap::new();</span><br><span class="line">}</span><br><span class="line">报错:</span><br><span class="line">cannot call non-const fn `HashMap::<std::string::String, std::string::String>::new` in statics</span><br><span class="line">calls in statics are limited to constant functions, tuple structs and tuple variantsrustcClick for full compiler diagnostic</span><br></pre></td></tr></table></figure>
<p>既然需要HashMap必须是const,我就试一下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">const mut map:HashMap<String,String> = HashMap::new();</span><br><span class="line">报错:</span><br><span class="line">const globals cannot be mutable </span><br></pre></td></tr></table></figure>
<p>不可变?那我怎么insert配置文件啊?先试试看非mut的</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">const map:HashMap<String,String> = HashMap::new();</span><br><span class="line">报错:</span><br><span class="line">cannot call non-const fn `HashMap::<std::string::String, std::string::String>::new` in constants</span><br><span class="line">calls in constants are limited to constant functions, tuple structs and tuple variantsrustcClick for full compiler diagnostic</span><br></pre></td></tr></table></figure>
<p>给我整不会了,看来HashMap不能全局使用了,从网上又查了一圈,hmm找到方法了,用lazy_static,具体原理还没看,但是尝试了一下,确实解决了我的问题。最终代码如下:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">pub mod dict {</span><br><span class="line"> use std::{collections::HashMap, fs::File, io::Read, sync::Mutex};</span><br><span class="line"></span><br><span class="line"> pub fn get_product_name(product_name: String) -> String {</span><br><span class="line"> if let Some(value) = CONFIG_MAP.lock().unwrap().get(&product_name) {</span><br><span class="line"> return value.to_owned();</span><br><span class="line"> }</span><br><span class="line"> return product_name;</span><br><span class="line"> }</span><br><span class="line"> lazy_static! {</span><br><span class="line"> static ref CONFIG_MAP: Mutex<HashMap<String, String>> = {</span><br><span class="line"> let mut file = File::open("./data/cfg.toml").unwrap();</span><br><span class="line"> let mut data = String::new();</span><br><span class="line"> file.read_to_string(&mut data).unwrap();</span><br><span class="line"> let obj: HashMap<String, HashMap<String, String>> = toml::from_str(&data).unwrap();</span><br><span class="line"> let dict_map = obj.get("product_dict").unwrap();</span><br><span class="line"> Mutex::new(dict_map.clone())</span><br><span class="line"> };</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="数据类型转换"><a href="#数据类型转换" class="headerlink" title="数据类型转换"></a>数据类型转换</h3><ul>
<li>f64-> i32 (引申一下,应该数字类型转换都可以这么搞)<ul>
<li><code> let a = num as i32</code></li>
</ul>
</li>
<li>String -> i32 (引申一下,字符串到数字类型)<ul>
<li><code>let a = String::from("13").parse::<i32>().unwrap();</code></li>
</ul>
</li>
</ul>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这个程序算是第一次正式用rust实现一个完整的功能的程序,说简单吧,也用到不少东西,说复杂吧,实际上就是数据格式转换+xlsx基本操作,后面还会继续用rust实现一些小的功能之类的,主要还是方便一下自己吧,这次代码量也就150+行,不过嘞,写了快一天。<br>编程这东西,还是不能停留在看,要实际coding才能掌握,后面如果要写一些系统底层的东西,相比现在可要复杂太多了,自己给自己加加油打打气吧~</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://eviltuzki.top/2022/11/19/Arm64%20%E9%BA%92%E9%BA%9FV10%E5%AE%89%E8%A3%85Kata/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Eviltuzki">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Eviltuzki">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/11/19/Arm64%20%E9%BA%92%E9%BA%9FV10%E5%AE%89%E8%A3%85Kata/" class="post-title-link" itemprop="url">Arm64麒麟V10安装Kata</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-11-19 00:00:00" itemprop="dateCreated datePublished" datetime="2022-11-19T00:00:00+08:00">2022-11-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E8%99%9A%E6%8B%9F%E5%8C%96-Kata-Arm64/" itemprop="url" rel="index"><span itemprop="name">虚拟化, Kata, Arm64</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="前置条件检查是否支持虚拟化"><a href="#前置条件检查是否支持虚拟化" class="headerlink" title="前置条件检查是否支持虚拟化"></a>前置条件检查是否支持虚拟化</h1><ul>
<li>通过dmesg查看是否支持虚拟化,arm不同于x86,lscpu看不出来<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># dmesg |grep kvm</span><br><span class="line">[ 0.499391] kvm [1]: Hisi ncsnp: enabled</span><br><span class="line">[ 0.499605] kvm [1]: 16-bit VMID</span><br><span class="line">[ 0.499606] kvm [1]: IPA Size Limit: 48bits</span><br><span class="line">[ 0.499644] kvm [1]: GICv4 support disabled</span><br><span class="line">[ 0.499645] kvm [1]: vgic-v2@9b020000</span><br><span class="line">[ 0.499647] kvm [1]: GIC system register CPU interface enabled</span><br><span class="line">[ 0.500407] kvm [1]: vgic interrupt IRQ1</span><br><span class="line">[ 0.501131] kvm [1]: VHE mode initialized successfully</span><br></pre></td></tr></table></figure></li>
<li>如果是下面这样,就不用继续了,浪费时间<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># dmesg |grep kvm</span><br><span class="line">[ 0.136111] kvm [1]: HYP mode not available</span><br></pre></td></tr></table></figure></li>
<li>注意:Arm架构不支持嵌套虚拟化,也就是说只能在物理机下运行kata,无法在虚拟机下运行</li>
</ul>
<h1 id="下载-amp-编译-amp-安装"><a href="#下载-amp-编译-amp-安装" class="headerlink" title="下载&编译&安装"></a>下载&编译&安装</h1><h2 id="gcc-yum源7以上无需编译"><a href="#gcc-yum源7以上无需编译" class="headerlink" title="gcc (yum源7以上无需编译)"></a>gcc (yum源7以上无需编译)</h2><ul>
<li>编译qemu需要</li>
<li>下载源码 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget https://github.com/gcc-mirror/gcc/archive/refs/tags/releases/gcc-8.5.0.zip</span><br></pre></td></tr></table></figure></li>
<li>解压后,检查依赖项<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./contrib/download_prerequisites</span><br></pre></td></tr></table></figure></li>
<li>yum安装依赖<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"># yum -y install bzip2 gcc gcc-c++ gmp-devel mpfr-devel libmpc-devel make zlib-devel flex bison-devel</span><br></pre></td></tr></table></figure></li>
<li>进入gcc8.5.0目录进行编译安装, make -j 后面的数字是编译的并行数,可适当调整<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># mkdir build && cd build</span><br><span class="line"># ../configure --prefix=/opt/gcc-8.5.0 --enable-languages=c,c++ --disable-multilib</span><br><span class="line"># make -j8 && sudo make install</span><br></pre></td></tr></table></figure></li>
<li>进行软链接,软链前删除/usr/bin/下的cc和c++<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># ln -s /opt/gcc-8.5.0/bin/gcc /usr/bin/cc</span><br><span class="line"># ln -s /opt/gcc-8.5.0/bin/c++ /usr/bin/c++</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="rust"><a href="#rust" class="headerlink" title="rust"></a>rust</h2><ul>
<li>编译kata需要</li>
<li>直接在线安装<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl --proto '=https' --tlsv1.2 -sSf sh.rustup.rs | sh</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="golang"><a href="#golang" class="headerlink" title="golang"></a>golang</h2><ul>
<li>编译kata需要</li>
<li>直接下载二进制<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget https://studygolang.com/dl/golang/go1.19.3.linux-arm64.tar.gz</span><br></pre></td></tr></table></figure></li>
<li>解压后将bin目录添加至PATH即可</li>
</ul>
<h2 id="kata"><a href="#kata" class="headerlink" title="kata"></a>kata</h2><ul>
<li>下载源码 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/kata-containers/kata-containers.git</span><br></pre></td></tr></table></figure></li>
<li>在kata-containers目录编译安装<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ pushd kata-containers/src/runtime</span><br><span class="line">$ make && sudo -E "PATH=$PATH" make install</span><br><span class="line">$ sudo mkdir -p /etc/kata-containers/</span><br><span class="line">$ sudo install -o root -g root -m 0640 /usr/share/defaults/kata-containers/configuration.toml /etc/kata-containers</span><br><span class="line">$ popd</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="containerd"><a href="#containerd" class="headerlink" title="containerd"></a>containerd</h2><ul>
<li>直接下载对应的rpm包<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># yum install http://mirror.centos.org/altarch/7/extras/aarch64/Packages/container-selinux-2.107-1.el7_6.noarch.rpm</span><br><span class="line"># yum install https://download.docker.com/linux/centos/7/aarch64/stable/Packages/containerd.io-1.5.11-3.1.el7.aarch64.rpm</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="python3-7-(yum源3-7以上无需编译)"><a href="#python3-7-(yum源3-7以上无需编译)" class="headerlink" title="python3.7 (yum源3.7以上无需编译)"></a>python3.7 (yum源3.7以上无需编译)</h2><ul>
<li><p>编译re2c需要</p>
</li>
<li><p>下载源码</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"># wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz</span><br></pre></td></tr></table></figure></li>
<li><p>安装依赖</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"># yum install libffi-devel </span><br></pre></td></tr></table></figure>
</li>
<li><p>解压并编译</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># tar -zxvf Python-3.7.0.tgz</span><br><span class="line"># mv Python-3.7.0 /usr/local</span><br><span class="line"># rm -rf /usr/bin/python</span><br><span class="line"># cd /usr/local/Python-3.7.0/</span><br><span class="line"># ./configure</span><br><span class="line"># make</span><br><span class="line"># make install</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="re2c"><a href="#re2c" class="headerlink" title="re2c"></a>re2c</h2><ul>
<li>编译ninja需要</li>
<li>下载源码 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/skvadrik/re2c.git</span><br></pre></td></tr></table></figure></li>
<li>安装依赖 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"># yum install automake libtool gcc gcc-c++</span><br></pre></td></tr></table></figure></li>
<li>编译安装,进入re2c目录 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># autoreconf -i -W all</span><br><span class="line"># ./configure && make && make install</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="ninja"><a href="#ninja" class="headerlink" title="ninja"></a>ninja</h2><ul>
<li>编译qemu需要</li>
<li>下载源码<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/ninja-build/ninja.git</span><br></pre></td></tr></table></figure></li>
<li>编译,进入ninja目录<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./configure.py --bootstrap</span><br></pre></td></tr></table></figure></li>
<li>将ninja拷贝至PATH<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mv ninja /usr/bin/</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="yq"><a href="#yq" class="headerlink" title="yq"></a>yq</h2><ul>
<li>直接下载二进制就行<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/mikefarah/yq/releases</span><br><span class="line">https://github.com/mikefarah/yq/releases/download/v4.30.4/yq_darwin_arm64</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="qemu"><a href="#qemu" class="headerlink" title="qemu"></a>qemu</h2><ul>
<li>可以通过tests脚本下载(是网络情况决定)</li>
<li>提前下载源码,后续直接进行编译<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">git clone https://gitlab.com/qemu-project/qemu.git</span><br><span class="line">git clone https://gitlab.com/qemu-project/dtc.git</span><br><span class="line">git clone https://gitlab.com/qemu-project/meson.git</span><br><span class="line">https://gitlab.com/qemu-project/keycodemapdb.git</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li>这里采用kata-tests的脚本进行编译安装,具体见[<a href="#kata-tests">kata-tests</a>]</li>
</ul>
<h2 id="kata-tests"><a href="#kata-tests" class="headerlink" title="kata-tests"></a><a id="kata-tests">kata-tests</a></h2><ul>
<li><p>进入kata-containers目录,下载源码tests</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/kata-containers/tests.git</span><br></pre></td></tr></table></figure></li>
<li><p>调整目录结构(方便执行install_qemu脚本)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">将kata-containers移动到/opt/kata/src/github.com/kata-containers</span><br><span class="line"></span><br><span class="line">/opt/kata/src/github.com/kata-containers/</span><br><span class="line"> - tests</span><br><span class="line"> - kata-containers (软连接至当前目录ln -s /opt/kata/src/github.com/kata-containers kata-containers)</span><br><span class="line"> - 其他kata-containsers文件</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">将上面下载的qemu目录mv到/opt/kata/src/github.com/qemu</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/opt/kata (下面的GOPATH)路径下增加bin目录</span><br><span class="line">将yq二进制文件拷贝至bin目录下(跳过install_yq)</span><br></pre></td></tr></table></figure></li>
<li><p>修改脚本(必须)</p>
<ul>
<li>修改./kata-containers/tests/.ci/lib.sh, 增加如下</li>
<li><code>export GOPATH=上面调整的目录,我这里是/opt/kata</code></li>
</ul>
</li>
<li><p>修改脚本(可选,网速不好参考)</p>
<ul>
<li>./kata-containers/tests/.ci/install_qemu.sh<ul>
<li>方便调试增加<code>set -x</code></li>
</ul>
</li>
<li>./kata-containers/tests/.ci/lib.sh</li>
<li>./kata-containers/tests/.ci/aarch64/lib_install_qemu_aarch64.sh<ul>
<li>如果上面已经移动了qemu目录,执行下面的注释,否则不用执行</li>
<li>注释掉<code>clone_qemu_repo</code></li>
<li>注释掉 <code>sudo -E git fetch</code></li>
</ul>
</li>
<li>./kata-containers/tools/packaging/scripts/configure-hypervisor.sh<ul>
<li>如果提前clone了目录,增加如下,这样可以在config qemu的时候忽略子模块校验 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">qemu_options+=' --with-git-submodules=ignore'</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
<li><p>执行安装</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"># ./kata-containers/tests/.ci/install_qemu.sh</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="kata-agent-可选"><a href="#kata-agent-可选" class="headerlink" title="kata-agent(可选)"></a>kata-agent(可选)</h2><ul>
<li>需要跨平台编译组件,下载地址<ul>
<li><a target="_blank" rel="noopener" href="https://musl.cc/#binaries">https://musl.cc/#binaries</a></li>
<li><a target="_blank" rel="noopener" href="https://musl.cc/aarch64-linux-musl-native.tgz">https://musl.cc/aarch64-linux-musl-native.tgz</a></li>
<li>aarch64-linux-musl-native解压后,bin目录加到path中</li>
</ul>
</li>
<li>执行编译 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make -C kata-containers/src/agent SECCOMP=no</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="kernel-除非你有arm内核,否则还是需要编译"><a href="#kernel-除非你有arm内核,否则还是需要编译" class="headerlink" title="kernel (除非你有arm内核,否则还是需要编译)"></a>kernel (除非你有arm内核,否则还是需要编译)</h2><ul>
<li>下载对应版本的内核并解压</li>
<li>进入内核目录执行<br> <code>make -j 8</code></li>
<li>编译完成后拷贝<code>./arch/arm64/boot/Image</code>至对应目录<ul>
<li>可软链,默认<code>/usr/share/kata-containers/vmlinux.container</code></li>
</ul>
</li>
<li>编译模块部分(需要内核开启模块,自己根据版本调整,如果guestImage需要使用则需要编译) <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">修改makefile的EXTRAVERSION 适配自己的版本,然后执行编译</span><br><span class="line">mkdir -p ../build/lib/modules/5.4.160-1.el7.aarch64</span><br><span class="line">make modules -j64</span><br><span class="line">make modules_install INSTALL_MOD_PATH=../build</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="guest-Image-同kernel,如果有则无需编译"><a href="#guest-Image-同kernel,如果有则无需编译" class="headerlink" title="guest Image (同kernel,如果有则无需编译)"></a>guest Image (同kernel,如果有则无需编译)</h2><ul>
<li><p>进入kata-containers/tools/osbuilder/rootfs-builder/centos, 根据自己rootfs选择</p>
</li>
<li><p>copy kernel modules (按需)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cp -r -d ${kernel}/../build/lib/modules/5.4.160-1.el7.aarch64/ lib/modules/5.4.160-1.el7.aarch64</span><br></pre></td></tr></table></figure></li>
<li><p>修改 config.sh(主要将yum或者dnf源修改为适配aarch64的,如果使用官方无需修改)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">BASE_URL="https://mirrors.aliyun.com/centos/8-stream/BaseOS/aarch64/os/"</span><br></pre></td></tr></table></figure></li>
<li><p>增加rust加速config, 打到Docker镜像中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[source.crates-io]</span><br><span class="line">registry = "https://github.com/rust-lang/crates.io-index"</span><br><span class="line">replace-with = 'ustc'</span><br><span class="line">[source.ustc]</span><br><span class="line">registry = "git://mirrors.ustc.edu.cn/crates.io-index"</span><br></pre></td></tr></table></figure></li>
<li><p>修改Dockerfile(我这里rust加速,copy了config)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">增加</span><br><span class="line">COPY config /root/.cargo/config</span><br></pre></td></tr></table></figure>
</li>
<li><p>回到进入kata-containers/tools/osbuilder,执行编译(如果哪一步有超时,自己修改dns或者修改代理)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make DISTRO=centos OS_VERSION=stream8 SECCOMP=no DEBUG=true USE_DOCKER=true AGENT_INIT=yes rootfs</span><br><span class="line">make USE_DOCKER=true image-centos -j 16</span><br></pre></td></tr></table></figure></li>
<li><p>拷贝编译好的Image(我这里是kata-containers-image-centos.img)</p>
</li>
</ul>
<h1 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h1><h2 id="kata-1"><a href="#kata-1" class="headerlink" title="kata"></a>kata</h2><ul>
<li>/etc/kata-containers/configuration.toml //过滤空行和注释后,我这里开启了debug模式 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line">[hypervisor.qemu]</span><br><span class="line">path = "/usr/bin/qemu-system-aarch64"</span><br><span class="line">kernel = "/usr/share/kata-containers/vmlinux.container"</span><br><span class="line">image = "/usr/share/kata-containers/kata-containers.img"</span><br><span class="line">machine_type = "virt"</span><br><span class="line">enable_annotations = []</span><br><span class="line">valid_hypervisor_paths = ["/usr/bin/qemu-system-aarch64"]</span><br><span class="line">kernel_params = " initcall_debug"</span><br><span class="line">firmware = ""</span><br><span class="line">machine_accelerators=""</span><br><span class="line">cpu_features="pmu=off"</span><br><span class="line">default_vcpus = 1</span><br><span class="line">default_maxvcpus = 1</span><br><span class="line">default_bridges = 1</span><br><span class="line">default_memory = 2048</span><br><span class="line">disable_block_device_use = false</span><br><span class="line">shared_fs = "virtio-9p"</span><br><span class="line">virtio_fs_daemon = "/usr/libexec/kata-qemu/virtiofsd"</span><br><span class="line">valid_virtio_fs_daemon_paths = ["/usr/libexec/kata-qemu/virtiofsd"]</span><br><span class="line">virtio_fs_cache_size = 0</span><br><span class="line">virtio_fs_extra_args = ["--thread-pool-size=1"]</span><br><span class="line">virtio_fs_cache = "auto"</span><br><span class="line">block_device_driver = "virtio-blk"</span><br><span class="line">enable_iothreads = false</span><br><span class="line">enable_vhost_user_store = false</span><br><span class="line">vhost_user_store_path = "/var/run/kata-containers/vhost-user"</span><br><span class="line">valid_vhost_user_store_paths = ["/var/run/kata-containers/vhost-user"]</span><br><span class="line">valid_file_mem_backends = [""]</span><br><span class="line">pflashes = []</span><br><span class="line">enable_debug = true</span><br><span class="line">disable_image_nvdimm = true</span><br><span class="line">valid_entropy_sources = ["/dev/urandom","/dev/random",""]</span><br><span class="line">[factory]</span><br><span class="line">[agent.kata]</span><br><span class="line">enable_debug = true</span><br><span class="line">enable_tracing = true</span><br><span class="line">kernel_modules=[]</span><br><span class="line">debug_console_enabled = true</span><br><span class="line">[netmon]</span><br><span class="line">path = "/usr/libexec/kata-containers/kata-netmon"</span><br><span class="line">enable_debug = true</span><br><span class="line">[runtime]</span><br><span class="line">enable_debug = true</span><br><span class="line">internetworking_model="tcfilter"</span><br><span class="line">disable_guest_seccomp=true</span><br><span class="line">disable_selinux=false</span><br><span class="line">sandbox_cgroup_only=false</span><br><span class="line">sandbox_bind_mounts=[]</span><br><span class="line">vfio_mode="guest-kernel"</span><br><span class="line">experimental=[]</span><br><span class="line">[image]</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="containerd-1"><a href="#containerd-1" class="headerlink" title="containerd"></a>containerd</h2><ul>
<li>/etc/containerd/config.toml <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">disabled_plugins = []</span><br><span class="line"></span><br><span class="line">[debug]</span><br><span class="line"># address = "/run/containerd/debug.sock"</span><br><span class="line"># uid = 0</span><br><span class="line"># gid = 0</span><br><span class="line">level = "debug" # 我这里为了debug观察用</span><br><span class="line"></span><br><span class="line">[plugins]</span><br><span class="line">[plugins.cri.cni]</span><br><span class="line"> conf_dir = "/etc/cni/net.d"</span><br><span class="line">[plugins.linux]</span><br><span class="line"> shim_debug = true</span><br><span class="line">[plugins.cri]</span><br><span class="line"> [plugins.cri.containerd]</span><br><span class="line"> [plugins.cri.containerd.runtimes]</span><br><span class="line"> [plugins.cri.containerd.runtimes.kata]</span><br><span class="line"> runtime_type = "io.containerd.kata.v2"</span><br><span class="line"> privileged_without_host_devices = true</span><br><span class="line"> [plugins.cri.containerd.runtimes.kata.options]</span><br><span class="line"> ConfigPath = "/etc/kata-containers/configuration.toml" # 指定kata配置文件</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="cni"><a href="#cni" class="headerlink" title="cni"></a>cni</h2><ul>
<li>/etc/containerd/config.toml <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> "cniVersion": "0.2.0",</span><br><span class="line"> "name": "mynet",</span><br><span class="line"> "type": "bridge",</span><br><span class="line"> "bridge": "cni0",</span><br><span class="line"> "isGateway": true,</span><br><span class="line"> "ipMasq": true,</span><br><span class="line"> "ipam": {</span><br><span class="line"> "type": "host-local",</span><br><span class="line"> "subnet": "172.19.0.0/24",</span><br><span class="line"> "routes": [</span><br><span class="line"> { "dst": "0.0.0.0/0" }</span><br><span class="line"> ]</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
</ul>
<h1 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h1><h2 id="check"><a href="#check" class="headerlink" title="check"></a>check</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># kata-runtime check</span><br><span class="line">INFO[0000] IOMMUPlatform is disabled by default.</span><br><span class="line">System is capable of running Kata Containers</span><br><span class="line">System can currently create Kata Containers</span><br></pre></td></tr></table></figure>
<h2 id="启动容器"><a href="#启动容器" class="headerlink" title="启动容器"></a>启动容器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ctr image pull docker.io/library/busybox:latest</span><br><span class="line">$ sudo ctr run --cni --runtime io.containerd.run.kata.v2 -t --rm docker.io/library/busybox:latest hello sh</span><br></pre></td></tr></table></figure>
<h1 id="Q-amp-A-编译阶段"><a href="#Q-amp-A-编译阶段" class="headerlink" title="Q&A 编译阶段"></a>Q&A 编译阶段</h1><h2 id="python"><a href="#python" class="headerlink" title="python"></a>python</h2><ol>
<li>ModuleNotFoundError: No module named ‘_ctypes’ <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">yum install libffi-devel </span><br><span class="line">然后重新configure make make install</span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="gcc"><a href="#gcc" class="headerlink" title="gcc"></a>gcc</h2><ol>
<li>g++: 错误:gengtype-lex.c:没有那个文件或目录 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install flex</span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="qemu-1"><a href="#qemu-1" class="headerlink" title="qemu"></a>qemu</h2><ol>
<li>ERROR: glib-2.56 gthread-2.0 is required to compile QEMU <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install glib2-devel</span><br></pre></td></tr></table></figure></li>
<li>ERROR: Dependency “pixman-1” not found, tried pkgconfig <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install pixman-devel</span><br></pre></td></tr></table></figure></li>
<li>ERROR: Dependency “libseccomp” not found, tried pkgconfig <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install libseccomp-devel</span><br></pre></td></tr></table></figure></li>
<li>ERROR: C header ‘cap-ng.h’ not found <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install libcap-ng-devel</span><br></pre></td></tr></table></figure></li>
<li>ERROR: C shared or static library ‘rados’ not found <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install libcephfs-devel librbd-devel librados-devel</span><br></pre></td></tr></table></figure></li>
</ol>
<h1 id="Q-amp-A-运行阶段"><a href="#Q-amp-A-运行阶段" class="headerlink" title="Q&A 运行阶段"></a>Q&A 运行阶段</h1><ol>
<li><p>ctr: failed to create shim: failed to launch qemu: exit status 1, error messages from qemu log: qemu-system-aarch64: -device nvdimm,id=nv0,memdev=mem0: memory hotplug is not enabled: missing acpi-ged device : unknown </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">修改kata-container的configuration.toml</span><br><span class="line">disable_image_nvdimm = true </span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">或者qemu应用下面补丁</span><br><span class="line">https://patchwork.kernel.org/project/qemu-devel/cover/20181018143042.29588-1-eric.auger@redhat.com/</span><br></pre></td></tr></table></figure>
</li>
<li><p>ctr: failed to create shim: Failed to Check if grpc server is working: rpc error: code = DeadlineExceeded desc = timed out connecting to vsock 2680247850:1024: unknown</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">内核文件问题,参考上面内核文件编译</span><br></pre></td></tr></table></figure>
</li>
<li><p>Err:Could not create the sandbox resource controller cgroups: cgroup mountpoint does not exist</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo mkdir /sys/fs/cgroup/systemd</span><br><span class="line">sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd</span><br></pre></td></tr></table></figure></li>
</ol>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>