1 /*
2  * qemu_namespace.c: QEMU domain namespace helpers
3  *
4  * Copyright (C) 2006-2020 Red Hat, Inc.
5  * Copyright (C) 2006 Daniel P. Berrange
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <config.h>
23 
24 #ifdef __linux__
25 # include <sys/sysmacros.h>
26 #endif
27 #if defined(WITH_SYS_MOUNT_H)
28 # include <sys/mount.h>
29 #endif
30 #ifdef WITH_SELINUX
31 # include <selinux/selinux.h>
32 #endif
33 
34 #include "qemu_namespace.h"
35 #include "qemu_domain.h"
36 #include "qemu_cgroup.h"
37 #include "qemu_security.h"
38 #include "qemu_hostdev.h"
39 #include "viralloc.h"
40 #include "virlog.h"
41 #include "virstring.h"
42 #include "virdevmapper.h"
43 #include "virglibutil.h"
44 
45 #define VIR_FROM_THIS VIR_FROM_QEMU
46 
47 VIR_LOG_INIT("qemu.qemu_domain");
48 
49 
50 VIR_ENUM_IMPL(qemuDomainNamespace,
51               QEMU_DOMAIN_NS_LAST,
52               "mount",
53 );
54 
55 
56 /**
57  * qemuDomainGetPreservedMountPath:
58  * @cfg: driver configuration data
59  * @vm: domain object
60  * @mountpoint: mount point path to convert
61  *
62  * For given @mountpoint return new path where the mount point
63  * should be moved temporarily whilst building the namespace.
64  *
65  * Returns: allocated string on success which the caller must free,
66  *          NULL on failure.
67  */
68 static char *
qemuDomainGetPreservedMountPath(virQEMUDriverConfig * cfg,virDomainObj * vm,const char * mountpoint)69 qemuDomainGetPreservedMountPath(virQEMUDriverConfig *cfg,
70                                 virDomainObj *vm,
71                                 const char *mountpoint)
72 {
73     char *path = NULL;
74     char *tmp;
75     const char *suffix = mountpoint + strlen(QEMU_DEVPREFIX);
76     g_autofree char *domname = virDomainDefGetShortName(vm->def);
77     size_t off;
78 
79     if (!domname)
80         return NULL;
81 
82     if (STREQ(mountpoint, "/dev"))
83         suffix = "dev";
84 
85     path = g_strdup_printf("%s/%s.%s", cfg->stateDir, domname, suffix);
86 
87     /* Now consider that @mountpoint is "/dev/blah/blah2".
88      * @suffix then points to "blah/blah2". However, caller
89      * expects all the @paths to be the same depth. The
90      * caller doesn't always do `mkdir -p` but sometimes bare
91      * `touch`. Therefore fix all the suffixes. */
92     off = strlen(path) - strlen(suffix);
93 
94     tmp = path + off;
95     while (*tmp) {
96         if (*tmp == '/')
97             *tmp = '.';
98         tmp++;
99     }
100 
101     return path;
102 }
103 
104 
105 /**
106  * qemuDomainGetPreservedMounts:
107  *
108  * Process list of mounted filesystems and:
109  * a) save all FSs mounted under /dev to @devPath
110  * b) generate backup path for all the entries in a)
111  *
112  * Any of the return pointers can be NULL. Both arrays are NULL-terminated.
113  *
114  * Returns 0 on success, -1 otherwise (with error reported)
115  */
116 static int
qemuDomainGetPreservedMounts(virQEMUDriverConfig * cfg,virDomainObj * vm,char *** devPath,char *** devSavePath,size_t * ndevPath)117 qemuDomainGetPreservedMounts(virQEMUDriverConfig *cfg,
118                              virDomainObj *vm,
119                              char ***devPath,
120                              char ***devSavePath,
121                              size_t *ndevPath)
122 {
123     g_auto(GStrv) mounts = NULL;
124     size_t nmounts = 0;
125     g_auto(GStrv) paths = NULL;
126     g_auto(GStrv) savePaths = NULL;
127     size_t i;
128 
129     if (ndevPath)
130         *ndevPath = 0;
131 
132     if (virFileGetMountSubtree(QEMU_PROC_MOUNTS, "/dev", &mounts, &nmounts) < 0)
133         return -1;
134 
135     if (nmounts == 0)
136         return 0;
137 
138     /* There can be nested mount points. For instance
139      * /dev/shm/blah can be a mount point and /dev/shm too. It
140      * doesn't make much sense to return the former path because
141      * caller preserves the latter (and with that the former
142      * too). Therefore prune nested mount points.
143      * NB mounts[0] is "/dev". Should we start the outer loop
144      * from the beginning of the array all we'd be left with is
145      * just the first element. Think about it.
146      */
147     for (i = 1; i < nmounts; i++) {
148         size_t j = i + 1;
149 
150         while (j < nmounts) {
151             char *c = STRSKIP(mounts[j], mounts[i]);
152 
153             if (c && (*c == '/' || *c == '\0')) {
154                 VIR_DEBUG("Dropping path %s because of %s", mounts[j], mounts[i]);
155                 VIR_DELETE_ELEMENT(mounts, j, nmounts);
156             } else {
157                 j++;
158             }
159         }
160     }
161 
162     /* mounts may not be NULL-terminated at this point, but we convert it into
163      * 'paths' which is NULL-terminated */
164 
165     paths = g_new0(char *, nmounts + 1);
166 
167     for (i = 0; i < nmounts; i++)
168         paths[i] = g_steal_pointer(&mounts[i]);
169 
170     if (devSavePath) {
171         savePaths = g_new0(char *, nmounts + 1);
172 
173         for (i = 0; i < nmounts; i++) {
174             if (!(savePaths[i] = qemuDomainGetPreservedMountPath(cfg, vm, paths[i])))
175                 return -1;
176         }
177     }
178 
179     if (devPath)
180         *devPath = g_steal_pointer(&paths);
181 
182     if (devSavePath)
183         *devSavePath = g_steal_pointer(&savePaths);
184 
185     if (ndevPath)
186         *ndevPath = nmounts;
187 
188     return 0;
189 }
190 
191 
192 static int
qemuDomainPopulateDevices(virQEMUDriverConfig * cfg,GSList ** paths)193 qemuDomainPopulateDevices(virQEMUDriverConfig *cfg,
194                           GSList **paths)
195 {
196     const char *const *devices = (const char *const *) cfg->cgroupDeviceACL;
197     size_t i;
198 
199     if (!devices)
200         devices = defaultDeviceACL;
201 
202     for (i = 0; devices[i]; i++) {
203         *paths = g_slist_prepend(*paths, g_strdup(devices[i]));
204     }
205 
206     return 0;
207 }
208 
209 
210 static int
qemuDomainSetupDev(virSecurityManager * mgr,virDomainObj * vm,const char * path)211 qemuDomainSetupDev(virSecurityManager *mgr,
212                    virDomainObj *vm,
213                    const char *path)
214 {
215     g_autofree char *mount_options = NULL;
216     g_autofree char *opts = NULL;
217 
218     VIR_DEBUG("Setting up /dev/ for domain %s", vm->def->name);
219 
220     mount_options = qemuSecurityGetMountOptions(mgr, vm->def);
221 
222     if (!mount_options)
223         mount_options = g_strdup("");
224 
225     /*
226      * tmpfs is limited to 64kb, since we only have device nodes in there
227      * and don't want to DOS the entire OS RAM usage
228      */
229     opts = g_strdup_printf("mode=755,size=65536%s", mount_options);
230 
231     if (virFileSetupDev(path, opts) < 0)
232         return -1;
233 
234     return 0;
235 }
236 
237 
238 static int
qemuDomainSetupDisk(virStorageSource * src,GSList ** paths)239 qemuDomainSetupDisk(virStorageSource *src,
240                     GSList **paths)
241 {
242     virStorageSource *next;
243     bool hasNVMe = false;
244 
245     for (next = src; virStorageSourceIsBacking(next); next = next->backingStore) {
246         g_autofree char *tmpPath = NULL;
247 
248         if (next->type == VIR_STORAGE_TYPE_NVME) {
249             hasNVMe = true;
250 
251             if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&next->nvme->pciAddr)))
252                 return -1;
253         } else {
254             GSList *targetPaths;
255 
256             if (virStorageSourceIsEmpty(next) ||
257                 !virStorageSourceIsLocalStorage(next)) {
258                 /* Not creating device. Just continue. */
259                 continue;
260             }
261 
262             tmpPath = g_strdup(next->path);
263 
264             if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
265                 errno != ENOSYS) {
266                 virReportSystemError(errno,
267                                      _("Unable to get devmapper targets for %s"),
268                                      next->path);
269                 return -1;
270             }
271 
272             if (targetPaths)
273                 *paths = g_slist_concat(g_slist_reverse(targetPaths), *paths);
274         }
275 
276         *paths = g_slist_prepend(*paths, g_steal_pointer(&tmpPath));
277     }
278 
279     /* qemu-pr-helper might require access to /dev/mapper/control. */
280     if (src->pr)
281         *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEVICE_MAPPER_CONTROL_PATH));
282 
283     if (hasNVMe)
284         *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_VFIO));
285 
286     return 0;
287 }
288 
289 
290 static int
qemuDomainSetupAllDisks(virDomainObj * vm,GSList ** paths)291 qemuDomainSetupAllDisks(virDomainObj *vm,
292                         GSList **paths)
293 {
294     size_t i;
295 
296     VIR_DEBUG("Setting up disks");
297 
298     for (i = 0; i < vm->def->ndisks; i++) {
299         if (qemuDomainSetupDisk(vm->def->disks[i]->src,
300                                 paths) < 0)
301             return -1;
302     }
303 
304     VIR_DEBUG("Setup all disks");
305     return 0;
306 }
307 
308 
309 static int
qemuDomainSetupHostdev(virDomainObj * vm,virDomainHostdevDef * hostdev,bool hotplug,GSList ** paths)310 qemuDomainSetupHostdev(virDomainObj *vm,
311                        virDomainHostdevDef *hostdev,
312                        bool hotplug,
313                        GSList **paths)
314 {
315     g_autofree char *path = NULL;
316 
317     if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0)
318         return -1;
319 
320     if (path)
321         *paths = g_slist_prepend(*paths, g_steal_pointer(&path));
322 
323     if (qemuHostdevNeedsVFIO(hostdev) &&
324         (!hotplug || !qemuDomainNeedsVFIO(vm->def)))
325         *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_VFIO));
326 
327     return 0;
328 }
329 
330 
331 static int
qemuDomainSetupAllHostdevs(virDomainObj * vm,GSList ** paths)332 qemuDomainSetupAllHostdevs(virDomainObj *vm,
333                            GSList **paths)
334 {
335     size_t i;
336 
337     VIR_DEBUG("Setting up hostdevs");
338     for (i = 0; i < vm->def->nhostdevs; i++) {
339         if (qemuDomainSetupHostdev(vm,
340                                    vm->def->hostdevs[i],
341                                    false,
342                                    paths) < 0)
343             return -1;
344     }
345     VIR_DEBUG("Setup all hostdevs");
346     return 0;
347 }
348 
349 
350 static int
qemuDomainSetupMemory(virDomainMemoryDef * mem,GSList ** paths)351 qemuDomainSetupMemory(virDomainMemoryDef *mem,
352                       GSList **paths)
353 {
354     if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
355         mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM)
356         return 0;
357 
358     *paths = g_slist_prepend(*paths, g_strdup(mem->nvdimmPath));
359 
360     return 0;
361 }
362 
363 
364 static int
qemuDomainSetupAllMemories(virDomainObj * vm,GSList ** paths)365 qemuDomainSetupAllMemories(virDomainObj *vm,
366                            GSList **paths)
367 {
368     size_t i;
369 
370     VIR_DEBUG("Setting up memories");
371     for (i = 0; i < vm->def->nmems; i++) {
372         if (qemuDomainSetupMemory(vm->def->mems[i],
373                                   paths) < 0)
374             return -1;
375     }
376     VIR_DEBUG("Setup all memories");
377     return 0;
378 }
379 
380 
381 static int
qemuDomainSetupChardev(virDomainDef * def G_GNUC_UNUSED,virDomainChrDef * dev,void * opaque)382 qemuDomainSetupChardev(virDomainDef *def G_GNUC_UNUSED,
383                        virDomainChrDef *dev,
384                        void *opaque)
385 {
386     GSList **paths = opaque;
387     const char *path = NULL;
388 
389     if (!(path = virDomainChrSourceDefGetPath(dev->source)))
390         return 0;
391 
392     /* Socket created by qemu. It doesn't exist upfront. */
393     if (dev->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
394         dev->source->data.nix.listen)
395         return 0;
396 
397     *paths = g_slist_prepend(*paths, g_strdup(path));
398     return 0;
399 }
400 
401 
402 static int
qemuDomainSetupAllChardevs(virDomainObj * vm,GSList ** paths)403 qemuDomainSetupAllChardevs(virDomainObj *vm,
404                            GSList **paths)
405 {
406     VIR_DEBUG("Setting up chardevs");
407 
408     if (virDomainChrDefForeach(vm->def,
409                                true,
410                                qemuDomainSetupChardev,
411                                paths) < 0)
412         return -1;
413 
414     VIR_DEBUG("Setup all chardevs");
415     return 0;
416 }
417 
418 
419 static int
qemuDomainSetupTPM(virDomainTPMDef * dev,GSList ** paths)420 qemuDomainSetupTPM(virDomainTPMDef *dev,
421                    GSList **paths)
422 {
423     switch (dev->type) {
424     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
425         *paths = g_slist_prepend(*paths, g_strdup(dev->data.passthrough.source->data.file.path));
426         break;
427 
428     case VIR_DOMAIN_TPM_TYPE_EMULATOR:
429     case VIR_DOMAIN_TPM_TYPE_LAST:
430         /* nada */
431         break;
432     }
433 
434     return 0;
435 }
436 
437 
438 static int
qemuDomainSetupAllTPMs(virDomainObj * vm,GSList ** paths)439 qemuDomainSetupAllTPMs(virDomainObj *vm,
440                        GSList **paths)
441 {
442     size_t i;
443 
444     VIR_DEBUG("Setting up TPMs");
445 
446     for (i = 0; i < vm->def->ntpms; i++) {
447         if (qemuDomainSetupTPM(vm->def->tpms[i], paths) < 0)
448             return -1;
449     }
450 
451     VIR_DEBUG("Setup all TPMs");
452     return 0;
453 }
454 
455 
456 static int
qemuDomainSetupGraphics(virDomainGraphicsDef * gfx,GSList ** paths)457 qemuDomainSetupGraphics(virDomainGraphicsDef *gfx,
458                         GSList **paths)
459 {
460     const char *rendernode = virDomainGraphicsGetRenderNode(gfx);
461 
462     if (!rendernode)
463         return 0;
464 
465     *paths = g_slist_prepend(*paths, g_strdup(rendernode));
466     return 0;
467 }
468 
469 
470 static int
qemuDomainSetupAllGraphics(virDomainObj * vm,GSList ** paths)471 qemuDomainSetupAllGraphics(virDomainObj *vm,
472                            GSList **paths)
473 {
474     size_t i;
475 
476     VIR_DEBUG("Setting up graphics");
477     for (i = 0; i < vm->def->ngraphics; i++) {
478         if (qemuDomainSetupGraphics(vm->def->graphics[i],
479                                     paths) < 0)
480             return -1;
481     }
482 
483     VIR_DEBUG("Setup all graphics");
484     return 0;
485 }
486 
487 
488 static int
qemuDomainSetupInput(virDomainInputDef * input,GSList ** paths)489 qemuDomainSetupInput(virDomainInputDef *input,
490                      GSList **paths)
491 {
492     const char *path = virDomainInputDefGetPath(input);
493 
494     if (!path)
495         return 0;
496 
497     *paths = g_slist_prepend(*paths, g_strdup(path));
498 
499     return 0;
500 }
501 
502 
503 static int
qemuDomainSetupAllInputs(virDomainObj * vm,GSList ** paths)504 qemuDomainSetupAllInputs(virDomainObj *vm,
505                          GSList **paths)
506 {
507     size_t i;
508 
509     VIR_DEBUG("Setting up inputs");
510     for (i = 0; i < vm->def->ninputs; i++) {
511         if (qemuDomainSetupInput(vm->def->inputs[i],
512                                  paths) < 0)
513             return -1;
514     }
515     VIR_DEBUG("Setup all inputs");
516     return 0;
517 }
518 
519 
520 static int
qemuDomainSetupRNG(virDomainRNGDef * rng,GSList ** paths)521 qemuDomainSetupRNG(virDomainRNGDef *rng,
522                    GSList **paths)
523 {
524     switch ((virDomainRNGBackend) rng->backend) {
525     case VIR_DOMAIN_RNG_BACKEND_RANDOM:
526         *paths = g_slist_prepend(*paths, g_strdup(rng->source.file));
527         break;
528 
529     case VIR_DOMAIN_RNG_BACKEND_EGD:
530     case VIR_DOMAIN_RNG_BACKEND_BUILTIN:
531     case VIR_DOMAIN_RNG_BACKEND_LAST:
532         /* nada */
533         break;
534     }
535 
536     return 0;
537 }
538 
539 
540 static int
qemuDomainSetupAllRNGs(virDomainObj * vm,GSList ** paths)541 qemuDomainSetupAllRNGs(virDomainObj *vm,
542                        GSList **paths)
543 {
544     size_t i;
545 
546     VIR_DEBUG("Setting up RNGs");
547     for (i = 0; i < vm->def->nrngs; i++) {
548         if (qemuDomainSetupRNG(vm->def->rngs[i],
549                                paths) < 0)
550             return -1;
551     }
552 
553     VIR_DEBUG("Setup all RNGs");
554     return 0;
555 }
556 
557 
558 static int
qemuDomainSetupLoader(virDomainObj * vm,GSList ** paths)559 qemuDomainSetupLoader(virDomainObj *vm,
560                       GSList **paths)
561 {
562     virDomainLoaderDef *loader = vm->def->os.loader;
563 
564     VIR_DEBUG("Setting up loader");
565 
566     if (loader) {
567         switch ((virDomainLoader) loader->type) {
568         case VIR_DOMAIN_LOADER_TYPE_ROM:
569             *paths = g_slist_prepend(*paths, g_strdup(loader->path));
570             break;
571 
572         case VIR_DOMAIN_LOADER_TYPE_PFLASH:
573             *paths = g_slist_prepend(*paths, g_strdup(loader->path));
574 
575             if (loader->nvram)
576                 *paths = g_slist_prepend(*paths, g_strdup(loader->nvram));
577             break;
578 
579         case VIR_DOMAIN_LOADER_TYPE_NONE:
580         case VIR_DOMAIN_LOADER_TYPE_LAST:
581             break;
582         }
583     }
584 
585     VIR_DEBUG("Setup loader");
586     return 0;
587 }
588 
589 
590 static int
qemuDomainSetupLaunchSecurity(virDomainObj * vm,GSList ** paths)591 qemuDomainSetupLaunchSecurity(virDomainObj *vm,
592                               GSList **paths)
593 {
594     virDomainSecDef *sec = vm->def->sec;
595 
596     if (!sec)
597         return 0;
598 
599     switch ((virDomainLaunchSecurity) sec->sectype) {
600     case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
601         VIR_DEBUG("Setting up launch security for SEV");
602 
603         *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_SEV));
604 
605         VIR_DEBUG("Set up launch security for SEV");
606         break;
607     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
608         break;
609     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
610     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
611         virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
612         return -1;
613     }
614 
615     return 0;
616 }
617 
618 
619 static int
620 qemuNamespaceMknodPaths(virDomainObj *vm,
621                         GSList *paths,
622                         bool *created);
623 
624 
625 int
qemuDomainBuildNamespace(virQEMUDriverConfig * cfg,virDomainObj * vm)626 qemuDomainBuildNamespace(virQEMUDriverConfig *cfg,
627                          virDomainObj *vm)
628 {
629     g_autoptr(virGSListString) paths = NULL;
630 
631     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
632         VIR_DEBUG("namespaces disabled for domain %s", vm->def->name);
633         return 0;
634     }
635 
636     if (qemuDomainPopulateDevices(cfg, &paths) < 0)
637         return -1;
638 
639     if (qemuDomainSetupAllDisks(vm, &paths) < 0)
640         return -1;
641 
642     if (qemuDomainSetupAllHostdevs(vm, &paths) < 0)
643         return -1;
644 
645     if (qemuDomainSetupAllMemories(vm, &paths) < 0)
646         return -1;
647 
648     if (qemuDomainSetupAllChardevs(vm, &paths) < 0)
649         return -1;
650 
651     if (qemuDomainSetupAllTPMs(vm, &paths) < 0)
652         return -1;
653 
654     if (qemuDomainSetupAllGraphics(vm, &paths) < 0)
655         return -1;
656 
657     if (qemuDomainSetupAllInputs(vm, &paths) < 0)
658         return -1;
659 
660     if (qemuDomainSetupAllRNGs(vm, &paths) < 0)
661         return -1;
662 
663     if (qemuDomainSetupLoader(vm, &paths) < 0)
664         return -1;
665 
666     if (qemuDomainSetupLaunchSecurity(vm, &paths) < 0)
667         return -1;
668 
669     if (qemuNamespaceMknodPaths(vm, paths, NULL) < 0)
670         return -1;
671 
672     return 0;
673 }
674 
675 
676 int
qemuDomainUnshareNamespace(virQEMUDriverConfig * cfg,virSecurityManager * mgr,virDomainObj * vm)677 qemuDomainUnshareNamespace(virQEMUDriverConfig *cfg,
678                            virSecurityManager *mgr,
679                            virDomainObj *vm)
680 {
681     const char *devPath = NULL;
682     g_auto(GStrv) devMountsPath = NULL;
683     g_auto(GStrv) devMountsSavePath = NULL;
684     size_t ndevMountsPath = 0, i;
685     int ret = -1;
686 
687     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
688         ret = 0;
689         goto cleanup;
690     }
691 
692     if (qemuDomainGetPreservedMounts(cfg, vm,
693                                      &devMountsPath, &devMountsSavePath,
694                                      &ndevMountsPath) < 0)
695         goto cleanup;
696 
697     for (i = 0; i < ndevMountsPath; i++) {
698         if (STREQ(devMountsPath[i], "/dev")) {
699             devPath = devMountsSavePath[i];
700             break;
701         }
702     }
703 
704     if (!devPath) {
705         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
706                        _("Unable to find any /dev mount"));
707         goto cleanup;
708     }
709 
710     if (virProcessSetupPrivateMountNS() < 0)
711         goto cleanup;
712 
713     if (qemuDomainSetupDev(mgr, vm, devPath) < 0)
714         goto cleanup;
715 
716     /* Save some mount points because we want to share them with the host */
717     for (i = 0; i < ndevMountsPath; i++) {
718         struct stat sb;
719 
720         if (devMountsSavePath[i] == devPath)
721             continue;
722 
723         if (stat(devMountsPath[i], &sb) < 0) {
724             virReportSystemError(errno,
725                                  _("Unable to stat: %s"),
726                                  devMountsPath[i]);
727             goto cleanup;
728         }
729 
730         /* At this point, devMountsPath is either:
731          * a file (regular or special), or
732          * a directory. */
733         if ((S_ISDIR(sb.st_mode) && g_mkdir_with_parents(devMountsSavePath[i], 0777) < 0) ||
734             (!S_ISDIR(sb.st_mode) && virFileTouch(devMountsSavePath[i], sb.st_mode) < 0)) {
735             virReportSystemError(errno,
736                                  _("Failed to create %s"),
737                                  devMountsSavePath[i]);
738             goto cleanup;
739         }
740 
741         if (virFileMoveMount(devMountsPath[i], devMountsSavePath[i]) < 0)
742             goto cleanup;
743     }
744 
745     if (virFileMoveMount(devPath, "/dev") < 0)
746         goto cleanup;
747 
748     for (i = 0; i < ndevMountsPath; i++) {
749         struct stat sb;
750 
751         if (devMountsSavePath[i] == devPath)
752             continue;
753 
754         if (stat(devMountsSavePath[i], &sb) < 0) {
755             virReportSystemError(errno,
756                                  _("Unable to stat: %s"),
757                                  devMountsSavePath[i]);
758             goto cleanup;
759         }
760 
761         if (S_ISDIR(sb.st_mode)) {
762             if (g_mkdir_with_parents(devMountsPath[i], 0777) < 0) {
763                 virReportSystemError(errno, _("Cannot create %s"),
764                                      devMountsPath[i]);
765                 goto cleanup;
766             }
767         } else {
768             if (virFileMakeParentPath(devMountsPath[i]) < 0 ||
769                 virFileTouch(devMountsPath[i], sb.st_mode) < 0) {
770                 virReportSystemError(errno, _("Cannot create %s"),
771                                      devMountsPath[i]);
772                 goto cleanup;
773             }
774         }
775 
776         if (virFileMoveMount(devMountsSavePath[i], devMountsPath[i]) < 0)
777             goto cleanup;
778     }
779 
780     ret = 0;
781  cleanup:
782     for (i = 0; i < ndevMountsPath; i++) {
783 #if defined(__linux__)
784         umount(devMountsSavePath[i]);
785 #endif /* defined(__linux__) */
786         /* The path can be either a regular file or a dir. */
787         if (virFileIsDir(devMountsSavePath[i]))
788             virFileDeleteTree(devMountsSavePath[i]);
789         else
790             unlink(devMountsSavePath[i]);
791     }
792     return ret;
793 }
794 
795 
796 bool
qemuDomainNamespaceEnabled(virDomainObj * vm,qemuDomainNamespace ns)797 qemuDomainNamespaceEnabled(virDomainObj *vm,
798                            qemuDomainNamespace ns)
799 {
800     qemuDomainObjPrivate *priv = vm->privateData;
801 
802     return priv->namespaces &&
803         virBitmapIsBitSet(priv->namespaces, ns);
804 }
805 
806 
807 int
qemuDomainEnableNamespace(virDomainObj * vm,qemuDomainNamespace ns)808 qemuDomainEnableNamespace(virDomainObj *vm,
809                           qemuDomainNamespace ns)
810 {
811     qemuDomainObjPrivate *priv = vm->privateData;
812 
813     if (!priv->namespaces)
814         priv->namespaces = virBitmapNew(QEMU_DOMAIN_NS_LAST);
815 
816     if (virBitmapSetBit(priv->namespaces, ns) < 0) {
817         virReportError(VIR_ERR_INTERNAL_ERROR,
818                        _("Unable to enable namespace: %s"),
819                        qemuDomainNamespaceTypeToString(ns));
820         return -1;
821     }
822 
823     return 0;
824 }
825 
826 
827 static void
qemuDomainDisableNamespace(virDomainObj * vm,qemuDomainNamespace ns)828 qemuDomainDisableNamespace(virDomainObj *vm,
829                            qemuDomainNamespace ns)
830 {
831     qemuDomainObjPrivate *priv = vm->privateData;
832 
833     if (priv->namespaces) {
834         ignore_value(virBitmapClearBit(priv->namespaces, ns));
835         if (virBitmapIsAllClear(priv->namespaces)) {
836             virBitmapFree(priv->namespaces);
837             priv->namespaces = NULL;
838         }
839     }
840 }
841 
842 
843 void
qemuDomainDestroyNamespace(virQEMUDriver * driver G_GNUC_UNUSED,virDomainObj * vm)844 qemuDomainDestroyNamespace(virQEMUDriver *driver G_GNUC_UNUSED,
845                            virDomainObj *vm)
846 {
847     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
848         qemuDomainDisableNamespace(vm, QEMU_DOMAIN_NS_MOUNT);
849 }
850 
851 
852 bool
qemuDomainNamespaceAvailable(qemuDomainNamespace ns G_GNUC_UNUSED)853 qemuDomainNamespaceAvailable(qemuDomainNamespace ns G_GNUC_UNUSED)
854 {
855 #if !defined(__linux__)
856     /* Namespaces are Linux specific. */
857     return false;
858 
859 #else /* defined(__linux__) */
860 
861     switch (ns) {
862     case QEMU_DOMAIN_NS_MOUNT:
863 # if !defined(WITH_LIBACL) || !defined(WITH_SELINUX)
864         /* We can't create the exact copy of paths if either of
865          * these is not available. */
866         return false;
867 # else
868         if (virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_MNT) < 0)
869             return false;
870 # endif
871         break;
872     case QEMU_DOMAIN_NS_LAST:
873         break;
874     }
875 
876     return true;
877 #endif /* defined(__linux__) */
878 }
879 
880 
881 typedef struct _qemuNamespaceMknodItem qemuNamespaceMknodItem;
882 struct _qemuNamespaceMknodItem {
883     char *file;
884     char *target;
885     bool bindmounted;
886     GStatBuf sb;
887     void *acl;
888     char *tcon;
889 };
890 
891 typedef struct _qemuNamespaceMknodData qemuNamespaceMknodData;
892 struct _qemuNamespaceMknodData {
893     virQEMUDriver *driver;
894     virDomainObj *vm;
895     qemuNamespaceMknodItem *items;
896     size_t nitems;
897 };
898 
899 
900 static void
qemuNamespaceMknodItemClear(qemuNamespaceMknodItem * item)901 qemuNamespaceMknodItemClear(qemuNamespaceMknodItem *item)
902 {
903     VIR_FREE(item->file);
904     VIR_FREE(item->target);
905     virFileFreeACLs(&item->acl);
906 #ifdef WITH_SELINUX
907     freecon(item->tcon);
908 #endif
909 }
910 
911 
912 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(qemuNamespaceMknodItem, qemuNamespaceMknodItemClear);
913 
914 static void
qemuNamespaceMknodDataClear(qemuNamespaceMknodData * data)915 qemuNamespaceMknodDataClear(qemuNamespaceMknodData *data)
916 {
917     size_t i;
918 
919     for (i = 0; i < data->nitems; i++) {
920         qemuNamespaceMknodItem *item = &data->items[i];
921 
922         qemuNamespaceMknodItemClear(item);
923     }
924 
925     VIR_FREE(data->items);
926 }
927 
928 
929 /* Our way of creating devices is highly linux specific */
930 #if defined(__linux__)
931 static int
qemuNamespaceMknodOne(qemuNamespaceMknodItem * data)932 qemuNamespaceMknodOne(qemuNamespaceMknodItem *data)
933 {
934     int ret = -1;
935     bool delDevice = false;
936     bool isLink = S_ISLNK(data->sb.st_mode);
937     bool isDev = S_ISCHR(data->sb.st_mode) || S_ISBLK(data->sb.st_mode);
938     bool isReg = S_ISREG(data->sb.st_mode) || S_ISFIFO(data->sb.st_mode) || S_ISSOCK(data->sb.st_mode);
939     bool isDir = S_ISDIR(data->sb.st_mode);
940     bool exists = false;
941 
942     if (virFileExists(data->file))
943         exists = true;
944 
945     if (virFileMakeParentPath(data->file) < 0) {
946         virReportSystemError(errno,
947                              _("Unable to create %s"), data->file);
948         goto cleanup;
949     }
950 
951     if (isLink) {
952         VIR_DEBUG("Creating symlink %s -> %s", data->file, data->target);
953 
954         /* First, unlink the symlink target. Symlinks change and
955          * therefore we have no guarantees that pre-existing
956          * symlink is still valid. */
957         if (unlink(data->file) < 0 &&
958             errno != ENOENT) {
959             virReportSystemError(errno,
960                                  _("Unable to remove symlink %s"),
961                                  data->file);
962             goto cleanup;
963         }
964 
965         if (symlink(data->target, data->file) < 0) {
966             virReportSystemError(errno,
967                                  _("Unable to create symlink %s (pointing to %s)"),
968                                  data->file, data->target);
969             goto cleanup;
970         } else {
971             delDevice = true;
972         }
973     } else if (isDev) {
974         VIR_DEBUG("Creating dev %s (%d,%d)",
975                   data->file, major(data->sb.st_rdev), minor(data->sb.st_rdev));
976         unlink(data->file);
977         if (mknod(data->file, data->sb.st_mode, data->sb.st_rdev) < 0) {
978             virReportSystemError(errno,
979                                  _("Unable to create device %s"),
980                                  data->file);
981             goto cleanup;
982         } else {
983             delDevice = true;
984         }
985     } else if (isReg || isDir) {
986         /* We are not cleaning up disks on virDomainDetachDevice
987          * because disk might be still in use by different disk
988          * as its backing chain. This might however clash here.
989          * Therefore do the cleanup here. */
990         if (umount(data->file) < 0 &&
991             errno != ENOENT && errno != EINVAL) {
992             virReportSystemError(errno,
993                                  _("Unable to umount %s"),
994                                  data->file);
995             goto cleanup;
996         }
997         if ((isReg && virFileTouch(data->file, data->sb.st_mode) < 0) ||
998             (isDir && g_mkdir_with_parents(data->file, data->sb.st_mode) < 0))
999             goto cleanup;
1000         delDevice = true;
1001         /* Just create the file here so that code below sets
1002          * proper owner and mode. Move the mount only after that. */
1003     } else {
1004         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1005                        _("unsupported device type %s 0%o"),
1006                        data->file, data->sb.st_mode);
1007         goto cleanup;
1008     }
1009 
1010     if (lchown(data->file, data->sb.st_uid, data->sb.st_gid) < 0) {
1011         virReportSystemError(errno,
1012                              _("Failed to chown device %s"),
1013                              data->file);
1014         goto cleanup;
1015     }
1016 
1017     /* Symlinks don't have mode */
1018     if (!isLink &&
1019         chmod(data->file, data->sb.st_mode) < 0) {
1020         virReportSystemError(errno,
1021                              _("Failed to set permissions for device %s"),
1022                              data->file);
1023         goto cleanup;
1024     }
1025 
1026     /* Symlinks don't have ACLs. */
1027     if (!isLink &&
1028         virFileSetACLs(data->file, data->acl) < 0 &&
1029         errno != ENOTSUP) {
1030         virReportSystemError(errno,
1031                              _("Unable to set ACLs on %s"), data->file);
1032         goto cleanup;
1033     }
1034 
1035 # ifdef WITH_SELINUX
1036     if (data->tcon &&
1037         lsetfilecon_raw(data->file, (const char *)data->tcon) < 0) {
1038         VIR_WARNINGS_NO_WLOGICALOP_EQUAL_EXPR
1039         if (errno != EOPNOTSUPP && errno != ENOTSUP) {
1040         VIR_WARNINGS_RESET
1041             virReportSystemError(errno,
1042                                  _("Unable to set SELinux label on %s"),
1043                                  data->file);
1044             goto cleanup;
1045         }
1046     }
1047 # endif
1048 
1049     /* Finish mount process started earlier. */
1050     if ((isReg || isDir) &&
1051         virFileMoveMount(data->target, data->file) < 0)
1052         goto cleanup;
1053 
1054     ret = exists;
1055  cleanup:
1056     if (ret < 0 && delDevice) {
1057         if (isDir)
1058             virFileDeleteTree(data->file);
1059         else
1060             unlink(data->file);
1061     }
1062     return ret;
1063 }
1064 
1065 
1066 static bool
qemuNamespaceMknodItemNeedsBindMount(mode_t st_mode)1067 qemuNamespaceMknodItemNeedsBindMount(mode_t st_mode)
1068 {
1069     /* A block device S_ISBLK() or a chardev S_ISCHR() is intentionally not
1070      * handled.  We want to mknod() it instead of passing in through bind
1071      * mounting. */
1072     return S_ISREG(st_mode) || S_ISFIFO(st_mode) ||
1073            S_ISSOCK(st_mode) || S_ISDIR(st_mode);
1074 }
1075 
1076 
1077 static int
qemuNamespaceMknodHelper(pid_t pid G_GNUC_UNUSED,void * opaque)1078 qemuNamespaceMknodHelper(pid_t pid G_GNUC_UNUSED,
1079                          void *opaque)
1080 {
1081     qemuNamespaceMknodData *data = opaque;
1082     size_t i;
1083     int ret = -1;
1084     bool exists = false;
1085 
1086     qemuSecurityPostFork(data->driver->securityManager);
1087 
1088     for (i = 0; i < data->nitems; i++) {
1089         int rc = 0;
1090 
1091         if ((rc = qemuNamespaceMknodOne(&data->items[i])) < 0)
1092             goto cleanup;
1093 
1094         if (rc > 0)
1095             exists = true;
1096     }
1097 
1098     ret = exists;
1099  cleanup:
1100     qemuNamespaceMknodDataClear(data);
1101     return ret;
1102 }
1103 
1104 
1105 static int
qemuNamespaceMknodItemInit(qemuNamespaceMknodItem * item,virQEMUDriverConfig * cfg,virDomainObj * vm,const char * file)1106 qemuNamespaceMknodItemInit(qemuNamespaceMknodItem *item,
1107                            virQEMUDriverConfig *cfg,
1108                            virDomainObj *vm,
1109                            const char *file)
1110 {
1111     g_autofree char *target = NULL;
1112     bool isLink;
1113     bool needsBindMount;
1114 
1115     item->file = g_strdup(file);
1116 
1117     if (g_lstat(file, &item->sb) < 0) {
1118         if (errno == ENOENT)
1119             return -2;
1120 
1121         virReportSystemError(errno,
1122                              _("Unable to access %s"), file);
1123         return -1;
1124     }
1125 
1126     isLink = S_ISLNK(item->sb.st_mode);
1127     needsBindMount = qemuNamespaceMknodItemNeedsBindMount(item->sb.st_mode);
1128 
1129     if (needsBindMount && STRPREFIX(file, QEMU_DEVPREFIX)) {
1130         if (!(target = qemuDomainGetPreservedMountPath(cfg, vm, file)))
1131             return -1;
1132 
1133         item->target = g_steal_pointer(&target);
1134     } else if (isLink) {
1135         g_autoptr(GError) gerr = NULL;
1136 
1137         if (!(target = g_file_read_link(file, &gerr))) {
1138             virReportError(VIR_ERR_SYSTEM_ERROR,
1139                            _("failed to resolve symlink %s: %s"), file, gerr->message);
1140             return -1;
1141         }
1142 
1143         if (!g_path_is_absolute(target)) {
1144             g_autofree char *fileTmp = g_strdup(file);
1145             char *c = NULL;
1146             char *tmp = NULL;
1147 
1148             if ((c = strrchr(fileTmp, '/')))
1149                 *(c + 1) = '\0';
1150 
1151             tmp = g_strdup_printf("%s%s", fileTmp, target);
1152             VIR_FREE(target);
1153             target = g_steal_pointer(&tmp);
1154         }
1155 
1156         item->target = g_steal_pointer(&target);
1157     }
1158 
1159     /* Symlinks don't have ACLs. */
1160     if (!isLink &&
1161         virFileGetACLs(file, &item->acl) < 0 &&
1162         errno != ENOTSUP) {
1163         virReportSystemError(errno,
1164                              _("Unable to get ACLs on %s"), file);
1165         return -1;
1166     }
1167 
1168 # ifdef WITH_SELINUX
1169     if (lgetfilecon_raw(file, &item->tcon) < 0 &&
1170         (errno != ENOTSUP && errno != ENODATA)) {
1171         virReportSystemError(errno,
1172                              _("Unable to get SELinux label from %s"), file);
1173         return -1;
1174     }
1175 # endif
1176 
1177     return 0;
1178 }
1179 
1180 
1181 static int
qemuNamespacePrepareOneItem(qemuNamespaceMknodData * data,virQEMUDriverConfig * cfg,virDomainObj * vm,const char * file,GStrv devMountsPath)1182 qemuNamespacePrepareOneItem(qemuNamespaceMknodData *data,
1183                             virQEMUDriverConfig *cfg,
1184                             virDomainObj *vm,
1185                             const char *file,
1186                             GStrv devMountsPath)
1187 {
1188     long ttl = sysconf(_SC_SYMLOOP_MAX);
1189     g_autofree char *next = g_strdup(file);
1190 
1191     while (1) {
1192         g_auto(qemuNamespaceMknodItem) item = { 0 };
1193         bool isLink;
1194         int rc;
1195 
1196         rc = qemuNamespaceMknodItemInit(&item, cfg, vm, next);
1197         if (rc == -2) {
1198             /* @file doesn't exist. We can break here. */
1199             break;
1200         } else if (rc < 0) {
1201             /* Some other (critical) error. */
1202             return -1;
1203         }
1204 
1205         isLink = S_ISLNK(item.sb.st_mode);
1206         g_free(next);
1207         next = g_strdup(item.target);
1208 
1209         if (STRPREFIX(item.file, QEMU_DEVPREFIX)) {
1210             GStrv n;
1211             bool found = false;
1212 
1213             for (n = devMountsPath; n && *n; n++) {
1214                 if (STREQ(*n, "/dev"))
1215                     continue;
1216                 if (STRPREFIX(item.file, *n)) {
1217                     found = true;
1218                     break;
1219                 }
1220             }
1221 
1222             if (!found)
1223                 VIR_APPEND_ELEMENT(data->items, data->nitems, item);
1224         }
1225 
1226         if (!isLink)
1227             break;
1228 
1229         if (ttl-- == 0) {
1230             virReportSystemError(ELOOP,
1231                                  _("Too many levels of symbolic links: %s"),
1232                                  next);
1233             return -1;
1234         }
1235     }
1236 
1237     return 0;
1238 }
1239 
1240 
1241 static int
qemuNamespaceMknodPaths(virDomainObj * vm,GSList * paths,bool * created)1242 qemuNamespaceMknodPaths(virDomainObj *vm,
1243                         GSList *paths,
1244                         bool *created)
1245 {
1246     qemuDomainObjPrivate *priv = vm->privateData;
1247     virQEMUDriver *driver = priv->driver;
1248     g_autoptr(virQEMUDriverConfig) cfg = NULL;
1249     g_auto(GStrv) devMountsPath = NULL;
1250     qemuNamespaceMknodData data = { 0 };
1251     size_t i;
1252     int ret = -1;
1253     GSList *next;
1254 
1255     if (!paths)
1256         return 0;
1257 
1258     cfg = virQEMUDriverGetConfig(driver);
1259     if (qemuDomainGetPreservedMounts(cfg, vm, &devMountsPath, NULL, NULL) < 0)
1260         return -1;
1261 
1262     data.driver = driver;
1263     data.vm = vm;
1264 
1265     for (next = paths; next; next = next->next) {
1266         const char *path = next->data;
1267 
1268         if (qemuNamespacePrepareOneItem(&data, cfg, vm, path, devMountsPath) < 0)
1269             goto cleanup;
1270     }
1271 
1272     for (i = 0; i < data.nitems; i++) {
1273         qemuNamespaceMknodItem *item = &data.items[i];
1274         if (item->target &&
1275             qemuNamespaceMknodItemNeedsBindMount(item->sb.st_mode)) {
1276             if (virFileBindMountDevice(item->file, item->target) < 0)
1277                 goto cleanup;
1278             item->bindmounted = true;
1279         }
1280     }
1281 
1282     if (qemuSecurityPreFork(driver->securityManager) < 0)
1283         goto cleanup;
1284 
1285     ret = virProcessRunInMountNamespace(vm->pid, qemuNamespaceMknodHelper,
1286                                         &data);
1287     qemuSecurityPostFork(driver->securityManager);
1288 
1289     if (ret == 0 && created != NULL)
1290         *created = true;
1291 
1292  cleanup:
1293     for (i = 0; i < data.nitems; i++) {
1294         if (data.items[i].bindmounted &&
1295             umount(data.items[i].target) < 0) {
1296             VIR_WARN("Unable to unmount %s", data.items[i].target);
1297         }
1298     }
1299     qemuNamespaceMknodDataClear(&data);
1300     return ret;
1301 }
1302 
1303 
1304 #else /* !defined(__linux__) */
1305 
1306 
1307 static int
qemuNamespaceMknodPaths(virDomainObj * vm G_GNUC_UNUSED,GSList * paths G_GNUC_UNUSED,bool * created G_GNUC_UNUSED)1308 qemuNamespaceMknodPaths(virDomainObj *vm G_GNUC_UNUSED,
1309                         GSList *paths G_GNUC_UNUSED,
1310                         bool *created G_GNUC_UNUSED)
1311 {
1312     virReportSystemError(ENOSYS, "%s",
1313                          _("Namespaces are not supported on this platform."));
1314     return -1;
1315 }
1316 
1317 
1318 #endif /* !defined(__linux__) */
1319 
1320 
1321 static int
qemuNamespaceUnlinkHelper(pid_t pid G_GNUC_UNUSED,void * opaque)1322 qemuNamespaceUnlinkHelper(pid_t pid G_GNUC_UNUSED,
1323                           void *opaque)
1324 {
1325     g_autoptr(virGSListString) paths = opaque;
1326     GSList *next;
1327 
1328     for (next = paths; next; next = next->next) {
1329         const char *path = next->data;
1330 
1331         VIR_DEBUG("Unlinking %s", path);
1332         if (unlink(path) < 0 && errno != ENOENT) {
1333             virReportSystemError(errno,
1334                                  _("Unable to remove device %s"), path);
1335             return -1;
1336         }
1337     }
1338 
1339     return 0;
1340 }
1341 
1342 
1343 static int
qemuNamespaceUnlinkPaths(virDomainObj * vm,GSList * paths)1344 qemuNamespaceUnlinkPaths(virDomainObj *vm,
1345                          GSList *paths)
1346 {
1347     qemuDomainObjPrivate *priv = vm->privateData;
1348     virQEMUDriver *driver = priv->driver;
1349     g_autoptr(virQEMUDriverConfig) cfg = NULL;
1350     g_auto(GStrv) devMountsPath = NULL;
1351     g_autoptr(virGSListString) unlinkPaths = NULL;
1352     GSList *next;
1353 
1354     if (!paths)
1355         return 0;
1356 
1357     cfg = virQEMUDriverGetConfig(driver);
1358 
1359     if (qemuDomainGetPreservedMounts(cfg, vm, &devMountsPath, NULL, NULL) < 0)
1360         return -1;
1361 
1362     for (next = paths; next; next = next->next) {
1363         const char *path = next->data;
1364 
1365         if (STRPREFIX(path, QEMU_DEVPREFIX)) {
1366             GStrv mount;
1367             bool inSubmount = false;
1368 
1369             for (mount = devMountsPath; *mount; mount++) {
1370                 if (STREQ(*mount, "/dev"))
1371                     continue;
1372 
1373                 if (STRPREFIX(path, *mount)) {
1374                     inSubmount = true;
1375                     break;
1376                 }
1377             }
1378 
1379             if (!inSubmount)
1380                 unlinkPaths = g_slist_prepend(unlinkPaths, g_strdup(path));
1381         }
1382     }
1383 
1384     if (unlinkPaths &&
1385         virProcessRunInMountNamespace(vm->pid,
1386                                       qemuNamespaceUnlinkHelper,
1387                                       unlinkPaths) < 0)
1388         return -1;
1389 
1390     return 0;
1391 }
1392 
1393 
1394 int
qemuDomainNamespaceSetupDisk(virDomainObj * vm,virStorageSource * src,bool * created)1395 qemuDomainNamespaceSetupDisk(virDomainObj *vm,
1396                              virStorageSource *src,
1397                              bool *created)
1398 {
1399     g_autoptr(virGSListString) paths = NULL;
1400 
1401     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1402         return 0;
1403 
1404     if (qemuDomainSetupDisk(src, &paths) < 0)
1405         return -1;
1406 
1407     if (qemuNamespaceMknodPaths(vm, paths, created) < 0)
1408         return -1;
1409 
1410     return 0;
1411 }
1412 
1413 
1414 int
qemuDomainNamespaceTeardownDisk(virDomainObj * vm G_GNUC_UNUSED,virStorageSource * src G_GNUC_UNUSED)1415 qemuDomainNamespaceTeardownDisk(virDomainObj *vm G_GNUC_UNUSED,
1416                                 virStorageSource *src G_GNUC_UNUSED)
1417 {
1418     /* While in hotplug case we create the whole backing chain,
1419      * here we must limit ourselves. The disk we want to remove
1420      * might be a part of backing chain of another disk.
1421      * If you are reading these lines and have some spare time
1422      * you can come up with and algorithm that checks for that.
1423      * I don't, therefore: */
1424     return 0;
1425 }
1426 
1427 
1428 /**
1429  * qemuDomainNamespaceSetupHostdev:
1430  * @vm: domain object
1431  * @hostdev: hostdev to create in @vm's namespace
1432  *
1433  * For given @hostdev, create its devfs representation (if it has one) in
1434  * domain namespace. Note, @hostdev must not be in @vm's definition.
1435  *
1436  * Returns: 0 on success,
1437  *         -1 otherwise.
1438  */
1439 int
qemuDomainNamespaceSetupHostdev(virDomainObj * vm,virDomainHostdevDef * hostdev,bool * created)1440 qemuDomainNamespaceSetupHostdev(virDomainObj *vm,
1441                                 virDomainHostdevDef *hostdev,
1442                                 bool *created)
1443 {
1444     g_autoptr(virGSListString) paths = NULL;
1445 
1446     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1447         return 0;
1448 
1449     if (qemuDomainSetupHostdev(vm,
1450                                hostdev,
1451                                true,
1452                                &paths) < 0)
1453         return -1;
1454 
1455     if (qemuNamespaceMknodPaths(vm, paths, created) < 0)
1456         return -1;
1457 
1458     return 0;
1459 }
1460 
1461 
1462 /**
1463  * qemuDomainNamespaceTeardownHostdev:
1464  * @vm: domain object
1465  * @hostdev: hostdev to remove in @vm's namespace
1466  *
1467  * For given @hostdev, remove its devfs representation (if it has one) in
1468  * domain namespace. Note, @hostdev must not be in @vm's definition.
1469  *
1470  * Returns: 0 on success,
1471  *         -1 otherwise.
1472  */
1473 int
qemuDomainNamespaceTeardownHostdev(virDomainObj * vm,virDomainHostdevDef * hostdev)1474 qemuDomainNamespaceTeardownHostdev(virDomainObj *vm,
1475                                    virDomainHostdevDef *hostdev)
1476 {
1477     g_autoptr(virGSListString) paths = NULL;
1478 
1479     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1480         return 0;
1481 
1482     if (qemuDomainSetupHostdev(vm,
1483                                hostdev,
1484                                true,
1485                                &paths) < 0)
1486         return -1;
1487 
1488     if (qemuNamespaceUnlinkPaths(vm, paths) < 0)
1489         return -1;
1490 
1491     return 0;
1492 }
1493 
1494 
1495 int
qemuDomainNamespaceSetupMemory(virDomainObj * vm,virDomainMemoryDef * mem,bool * created)1496 qemuDomainNamespaceSetupMemory(virDomainObj *vm,
1497                                virDomainMemoryDef *mem,
1498                                bool *created)
1499 {
1500     g_autoptr(virGSListString) paths = NULL;
1501 
1502     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1503         return 0;
1504 
1505     if (qemuDomainSetupMemory(mem, &paths) < 0)
1506         return -1;
1507 
1508     if (qemuNamespaceMknodPaths(vm, paths, created) < 0)
1509         return -1;
1510 
1511     return 0;
1512 }
1513 
1514 
1515 int
qemuDomainNamespaceTeardownMemory(virDomainObj * vm,virDomainMemoryDef * mem)1516 qemuDomainNamespaceTeardownMemory(virDomainObj *vm,
1517                                   virDomainMemoryDef *mem)
1518 {
1519     g_autoptr(virGSListString) paths = NULL;
1520 
1521     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1522         return 0;
1523 
1524     if (qemuDomainSetupMemory(mem, &paths) < 0)
1525         return -1;
1526 
1527     if (qemuNamespaceUnlinkPaths(vm, paths) < 0)
1528         return -1;
1529 
1530     return 0;
1531 }
1532 
1533 
1534 int
qemuDomainNamespaceSetupChardev(virDomainObj * vm,virDomainChrDef * chr,bool * created)1535 qemuDomainNamespaceSetupChardev(virDomainObj *vm,
1536                                 virDomainChrDef *chr,
1537                                 bool *created)
1538 {
1539     g_autoptr(virGSListString) paths = NULL;
1540 
1541     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1542         return 0;
1543 
1544     if (qemuDomainSetupChardev(vm->def, chr, &paths) < 0)
1545         return -1;
1546 
1547     if (qemuNamespaceMknodPaths(vm, paths, created) < 0)
1548         return -1;
1549 
1550     return 0;
1551 }
1552 
1553 
1554 int
qemuDomainNamespaceTeardownChardev(virDomainObj * vm,virDomainChrDef * chr)1555 qemuDomainNamespaceTeardownChardev(virDomainObj *vm,
1556                                    virDomainChrDef *chr)
1557 {
1558     g_autoptr(virGSListString) paths = NULL;
1559 
1560     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1561         return 0;
1562 
1563     if (qemuDomainSetupChardev(vm->def, chr, &paths) < 0)
1564         return -1;
1565 
1566     if (qemuNamespaceUnlinkPaths(vm, paths) < 0)
1567         return -1;
1568 
1569     return 0;
1570 }
1571 
1572 
1573 int
qemuDomainNamespaceSetupRNG(virDomainObj * vm,virDomainRNGDef * rng,bool * created)1574 qemuDomainNamespaceSetupRNG(virDomainObj *vm,
1575                             virDomainRNGDef *rng,
1576                             bool *created)
1577 {
1578     g_autoptr(virGSListString) paths = NULL;
1579 
1580     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1581         return 0;
1582 
1583     if (qemuDomainSetupRNG(rng, &paths) < 0)
1584         return -1;
1585 
1586     if (qemuNamespaceMknodPaths(vm, paths, created) < 0)
1587         return -1;
1588 
1589     return 0;
1590 }
1591 
1592 
1593 int
qemuDomainNamespaceTeardownRNG(virDomainObj * vm,virDomainRNGDef * rng)1594 qemuDomainNamespaceTeardownRNG(virDomainObj *vm,
1595                                virDomainRNGDef *rng)
1596 {
1597     g_autoptr(virGSListString) paths = NULL;
1598 
1599     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1600         return 0;
1601 
1602     if (qemuDomainSetupRNG(rng, &paths) < 0)
1603         return -1;
1604 
1605     if (qemuNamespaceUnlinkPaths(vm, paths) < 0)
1606         return -1;
1607 
1608     return 0;
1609 }
1610 
1611 
1612 int
qemuDomainNamespaceSetupInput(virDomainObj * vm,virDomainInputDef * input,bool * created)1613 qemuDomainNamespaceSetupInput(virDomainObj *vm,
1614                               virDomainInputDef *input,
1615                               bool *created)
1616 {
1617     g_autoptr(virGSListString) paths = NULL;
1618     int ret = 0;
1619 
1620     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1621         return 0;
1622 
1623     if (qemuDomainSetupInput(input, &paths) < 0)
1624         return -1;
1625 
1626     if ((ret = qemuNamespaceMknodPaths(vm, paths, created)) < 0)
1627         return -1;
1628 
1629     return 0;
1630 }
1631 
1632 
1633 int
qemuDomainNamespaceTeardownInput(virDomainObj * vm,virDomainInputDef * input)1634 qemuDomainNamespaceTeardownInput(virDomainObj *vm,
1635                                  virDomainInputDef *input)
1636 {
1637     g_autoptr(virGSListString) paths = NULL;
1638 
1639     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
1640         return 0;
1641 
1642     if (qemuDomainSetupInput(input, &paths) < 0)
1643         return -1;
1644 
1645     if (qemuNamespaceUnlinkPaths(vm, paths) < 0)
1646         return -1;
1647 
1648     return 0;
1649 }
1650