final: Minimum versions of nbd & kernel.
[libguestfs-talks.git] / 2019-fosdem / 6100-plugins-c.html
1 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
2 <link rel="stylesheet" href="style.css" type="text/css"/>
3 <script src="code.js" type="text/javascript"></script>
4
5 <h1>Writing plugins in C?</h1>
6
7 <style>
8 pre {
9     column-count: 3;
10     font-size: 50%;
11 }
12 </style>
13
14 <pre>
15 /* The size of disk in bytes (initialized by
16    size=&lt;SIZE&gt; parameter). */
17 static int64_t size = 0;
18
19 /* Debug directory operations
20    (-D memory.dir=1). */
21 int memory_debug_dir;
22
23 static struct sparse_array *sa;
24
25 static void
26 memory_load (void)
27 {
28   sa = alloc_sparse_array (memory_debug_dir);
29   if (sa == NULL) {
30     perror ("malloc");
31     exit (EXIT_FAILURE);
32   }
33 }
34
35 static void
36 memory_unload (void)
37 {
38   free_sparse_array (sa);
39 }
40
41 static int
42 memory_config (const char *key,
43                const char *value)
44 {
45   if (strcmp (key, "size") == 0) {
46     size = nbdkit_parse_size (value);
47     if (size == -1)
48       return -1;
49   }
50   else {
51     nbdkit_error
52       ("unknown parameter '%s'", key);
53     return -1;
54   }
55
56   return 0;
57 }
58
59 static int
60 memory_config_complete (void)
61 {
62   if (size == 0) {
63     nbdkit_error ("you must specify "
64       "size=&lt;SIZE&gt; on the "
65       "command line");
66     return -1;
67   }
68   return 0;
69 }
70
71 #define memory_config_help \
72   "size=&lt;SIZE&gt;  (required)"
73   " Size of the backing disk"
74
75 /* Create the per-connection handle. */
76 static void *
77 memory_open (int readonly)
78 {
79   /* Used only as a handle pointer. */
80   static int mh;
81
82   return &amp;mh;
83 }
84
85 #define THREAD_MODEL \
86 NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
87
88 /* Get the disk size. */
89 static int64_t
90 memory_get_size (void *handle)
91 {
92   return (int64_t) size;
93 }
94
95 /* Read data. */
96 static int
97 memory_pread (void *handle, void *buf,
98               uint32_t count, uint64_t offset)
99 {
100   sparse_array_read (sa, buf, count, offset);
101   return 0;
102 }
103
104 /* Write data. */
105 static int
106 memory_pwrite (void *handle,
107                const void *buf,
108                uint32_t count, uint64_t offset)
109 {
110   return sparse_array_write (sa,
111     buf, count, offset);
112 }
113
114 /* Zero. */
115 static int
116 memory_zero (void *handle,
117              uint32_t count,
118              uint64_t offset, int may_trim)
119 {
120   sparse_array_zero (sa, count, offset);
121   return 0;
122 }
123
124 /* Trim (same as zero). */
125 static int
126 memory_trim (void *handle,
127              uint32_t count, uint64_t offset)
128 {
129   sparse_array_zero (sa, count, offset);
130   return 0;
131 }
132
133 static struct nbdkit_plugin plugin = {
134   .name              = "memory",
135   .version           = PACKAGE_VERSION,
136   .load              = memory_load,
137   .unload            = memory_unload,
138   .config            = memory_config,
139   .config_complete   = memory_config_complete,
140   .config_help       = memory_config_help,
141   .open              = memory_open,
142   .get_size          = memory_get_size,
143   .pread             = memory_pread,
144   .pwrite            = memory_pwrite,
145   .zero              = memory_zero,
146   .trim              = memory_trim,
147   /* In this plugin, errno is preserved
148    * properly along error return
149    * paths from failed system calls.
150    */
151   .errno_is_preserved = 1,
152 };
153
154 NBDKIT_REGISTER_PLUGIN(plugin)
155 </pre>