~ubuntu-branches/ubuntu/maverick/libvirt/maverick

« back to all changes in this revision

Viewing changes to src/lxc_conf.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2008-06-25 18:51:21 UTC
  • mto: (3.1.1 lenny) (1.2.1 upstream) (0.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 27.
  • Revision ID: james.westby@ubuntu.com-20080625185121-8dku38gpoluks1bx
Tags: upstream-0.4.4
ImportĀ upstreamĀ versionĀ 0.4.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
#include "util.h"
43
43
#include "uuid.h"
44
44
#include "xml.h"
45
 
 
 
45
#include "memory.h"
46
46
#include "lxc_conf.h"
47
47
 
48
48
/* debug macros */
183
183
        if (virUUIDParse(res, uuid) < 0) {
184
184
            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
185
185
                     _("invalid uuid element"));
186
 
            free(res);
 
186
            VIR_FREE(res);
187
187
            return(-1);
188
188
        }
189
 
        free(res);
 
189
        VIR_FREE(res);
190
190
    }
191
191
    return(0);
192
192
}
206
206
    res = virXPathNodeSet("/domain/devices/filesystem", contextPtr, &list);
207
207
    if (res > 0) {
208
208
        for (i = 0; i < res; ++i) {
209
 
            mountObj = calloc(1, sizeof(lxc_mount_t));
210
 
            if (NULL == mountObj) {
 
209
            if (VIR_ALLOC(mountObj) < 0) {
211
210
                lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "mount");
212
211
                goto parse_complete;
213
212
            }
214
213
 
215
214
            rc = lxcParseMountXML(conn, list[i], mountObj);
216
215
            if (0 > rc) {
217
 
                free(mountObj);
 
216
                VIR_FREE(mountObj);
218
217
                goto parse_complete;
219
218
            }
220
219
 
228
227
            }
229
228
            prevObj = mountObj;
230
229
        }
231
 
        free(list);
 
230
        VIR_FREE(list);
232
231
    }
233
232
 
234
233
    rc = nmounts;
252
251
    if (strlen(res) >= PATH_MAX - 1) {
253
252
        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
254
253
                 _("init string too long"));
255
 
        free(res);
256
 
        return(-1);
 
254
        VIR_FREE(res);
 
255
        return(-1);
257
256
    }
258
257
 
259
258
    *init = res;
270
269
    if (res == NULL) {
271
270
        /* make sure the tty string is empty */
272
271
        *tty = strdup("");
273
 
        if (*tty == NULL) {
274
 
            lxcError(conn, NULL, VIR_ERR_NO_MEMORY, NULL);
275
 
            return(-1);
276
 
        }
 
272
        if (*tty == NULL) {
 
273
            lxcError(conn, NULL, VIR_ERR_NO_MEMORY, NULL);
 
274
            return(-1);
 
275
        }
277
276
    } else {
278
277
        *tty = res;
279
278
    }
288
287
 
289
288
    rc = virXPathLong("string(/domain/memory[1])", contextPtr, &res);
290
289
    if ((rc == -2) || ((rc == 0) && (res <= 0))) {
291
 
        *memory = -1;
292
 
        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
293
 
                 _("invalid memory value"));
 
290
        *memory = -1;
 
291
        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
 
292
                 _("invalid memory value"));
294
293
    } else if (rc < 0) {
295
294
        /* not an error, default to an invalid value so it's not used */
296
 
        *memory = -1;
 
295
        *memory = -1;
297
296
    } else {
298
 
        *memory = (int) res;
 
297
        *memory = (int) res;
299
298
    }
300
299
    return(0);
301
300
}
307
306
    xmlChar *xmlProp = NULL;
308
307
    lxc_vm_def_t *containerDef;
309
308
 
310
 
    if (!(containerDef = calloc(1, sizeof(*containerDef)))) {
 
309
    if (VIR_ALLOC(containerDef) < 0) {
311
310
        lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "containerDef");
312
311
        return NULL;
313
312
    }
339
338
                 _("invalid domain type"));
340
339
        goto error;
341
340
    }
342
 
    free(xmlProp);
343
 
    xmlProp = NULL;
 
341
    VIR_FREE(xmlProp);
344
342
 
345
343
    if ((xmlProp = xmlGetProp(rootNodePtr, BAD_CAST "id"))) {
346
344
        if (0 > virStrToLong_i((char*)xmlProp, NULL, 10, &(containerDef->id))) {
348
346
                     _("invalid domain id"));
349
347
            goto error;
350
348
        }
 
349
 
 
350
        /* verify the container process still exists */
 
351
        if (1 != lxcCheckContainerProcess(containerDef)) {
 
352
            containerDef->id = -1;
 
353
        }
 
354
 
351
355
    } else {
352
356
        containerDef->id = -1;
353
357
    }
354
 
    free(xmlProp);
355
 
    xmlProp = NULL;
 
358
    VIR_FREE(xmlProp);
356
359
 
357
360
    if (lxcParseDomainName(conn, &(containerDef->name), contextPtr) < 0) {
358
361
        goto error;
385
388
    return containerDef;
386
389
 
387
390
 error:
388
 
    free(xmlProp);
 
391
    VIR_FREE(xmlProp);
389
392
    xmlXPathFreeContext(contextPtr);
390
393
    lxcFreeVMDef(containerDef);
391
394
 
436
439
        return vm;
437
440
    }
438
441
 
439
 
    if (!(vm = calloc(1, sizeof(lxc_vm_t)))) {
 
442
    if (VIR_ALLOC(vm) < 0) {
440
443
        lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "vm");
441
444
        return NULL;
442
445
    }
458
461
    return vm;
459
462
}
460
463
 
 
464
/**
 
465
 * lxcCheckContainerProcess:
 
466
 * @def: Ptr to VM definition
 
467
 *
 
468
 * Checks if the container process (stored at def->id is running
 
469
 *
 
470
 * Returns on success or -1 in case of error
 
471
 * 0  - no process with id vm->def->id
 
472
 * 1  - container process exists
 
473
 * -1 - error
 
474
 */
 
475
int lxcCheckContainerProcess(lxc_vm_def_t *def)
 
476
{
 
477
    int rc = -1;
 
478
 
 
479
    if (1 < def->id) {
 
480
        if (-1 == kill(def->id, 0)) {
 
481
            if (ESRCH == errno) {
 
482
                rc = 0;
 
483
                DEBUG("pid %d no longer exists", def->id);
 
484
                goto done;
 
485
            }
 
486
 
 
487
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
488
                     _("error checking container process: %d %s"),
 
489
                     def->id, strerror(errno));
 
490
            goto done;
 
491
        }
 
492
 
 
493
        DEBUG("pid %d still exists", def->id);
 
494
        rc = 1;
 
495
        goto done;
 
496
    }
 
497
 
 
498
    rc = 0;
 
499
 
 
500
done:
 
501
    return rc;
 
502
}
 
503
 
461
504
void lxcRemoveInactiveVM(lxc_driver_t *driver,
462
505
                         lxc_vm_t *vm)
463
506
{
529
572
        close(fd);
530
573
    }
531
574
 
532
 
    free(xmlDef);
 
575
    VIR_FREE(xmlDef);
533
576
 
534
577
    return rc;
535
578
}
602
645
    strncpy(vm->configFileBase, file, PATH_MAX);
603
646
    vm->configFile[PATH_MAX-1] = '\0';
604
647
 
 
648
    if (lxcLoadTtyPid(driver, vm) < 0) {
 
649
        DEBUG0("failed to load tty pid");
 
650
    }
 
651
 
605
652
    return vm;
606
653
}
607
654
 
614
661
        return -1;
615
662
    }
616
663
 
 
664
    driver->stateDir = strdup(LOCAL_STATE_DIR "/run/libvirt/lxc");
 
665
 
617
666
    return 0;
618
667
}
619
668
 
637
686
 
638
687
    lxcLoadConfig(driver, file, tempPath, xmlData);
639
688
 
640
 
    free(xmlData);
 
689
    VIR_FREE(xmlData);
641
690
 
642
691
load_complete:
643
692
    return rc;
656
705
        } else {
657
706
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
658
707
                     _("failed to open config directory %s: %s"),
659
 
                     driver->configDir, strerror(errno));
 
708
                     driver->configDir, strerror(errno));
660
709
        }
661
710
 
662
711
        goto load_complete;
688
737
                     lxc_vm_t *vm,
689
738
                     lxc_vm_def_t *def)
690
739
{
691
 
    virBufferPtr buf = 0;
 
740
    virBuffer buf = VIR_BUFFER_INITIALIZER;
692
741
    unsigned char *uuid;
693
742
    char uuidstr[VIR_UUID_STRING_BUFLEN];
694
743
    lxc_mount_t *mount;
695
744
 
696
 
    buf = virBufferNew(LXC_MAX_XML_LENGTH);
697
 
    if (!buf) {
698
 
        goto no_memory;
699
 
    }
700
 
 
701
 
    if (lxcIsActiveVM(vm)) {
702
 
        if (virBufferVSprintf(buf, "<domain type='%s' id='%d'>\n",
703
 
                              LXC_DOMAIN_TYPE, vm->def->id) < 0) {
704
 
            goto no_memory;
705
 
        }
706
 
    } else {
707
 
        if (virBufferVSprintf(buf, "<domain type='%s'>\n",
708
 
                              LXC_DOMAIN_TYPE) < 0) {
709
 
            goto no_memory;
710
 
        }
711
 
    }
712
 
 
713
 
    if (virBufferVSprintf(buf, "    <name>%s</name>\n", def->name) < 0) {
714
 
        goto no_memory;
715
 
    }
 
745
    if (lxcIsActiveVM(vm))
 
746
        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n",
 
747
                          LXC_DOMAIN_TYPE, vm->def->id);
 
748
    else
 
749
        virBufferVSprintf(&buf, "<domain type='%s'>\n",
 
750
                          LXC_DOMAIN_TYPE);
 
751
 
 
752
    virBufferVSprintf(&buf, "    <name>%s</name>\n", def->name);
716
753
 
717
754
    uuid = def->uuid;
718
755
    virUUIDFormat(uuid, uuidstr);
719
 
    if (virBufferVSprintf(buf, "    <uuid>%s</uuid>\n", uuidstr) < 0) {
720
 
        goto no_memory;
721
 
    }
722
 
 
723
 
    if (virBufferAddLit(buf, "    <os>\n") < 0) {
724
 
        goto no_memory;
725
 
    }
726
 
 
727
 
    if (virBufferVSprintf(buf, "        <init>%s</init>\n", def->init) < 0) {
728
 
        goto no_memory;
729
 
    }
730
 
 
731
 
    if (virBufferAddLit(buf, "    </os>\n") < 0) {
732
 
        goto no_memory;
733
 
    }
734
 
 
735
 
    if (virBufferVSprintf(buf, "    <memory>%d</memory>\n", def->maxMemory) < 0) {
736
 
        goto no_memory;
737
 
    }
738
 
 
739
 
    if (virBufferAddLit(buf, "    <devices>\n") < 0) {
740
 
        goto no_memory;
741
 
    }
 
756
    virBufferVSprintf(&buf, "    <uuid>%s</uuid>\n", uuidstr);
 
757
    virBufferAddLit(&buf, "    <os>\n");
 
758
    virBufferVSprintf(&buf, "        <init>%s</init>\n", def->init);
 
759
    virBufferAddLit(&buf, "    </os>\n");
 
760
    virBufferVSprintf(&buf, "    <memory>%d</memory>\n", def->maxMemory);
 
761
    virBufferAddLit(&buf, "    <devices>\n");
742
762
 
743
763
    /* loop adding mounts */
744
764
    for (mount = def->mounts; mount; mount = mount->next) {
745
 
        if (virBufferAddLit(buf, "        <filesystem type='mount'>\n") < 0) {
746
 
            goto no_memory;
747
 
        }
748
 
 
749
 
        if (virBufferVSprintf(buf, "            <source dir='%s'/>\n",
750
 
                              mount->source) < 0) {
751
 
            goto no_memory;
752
 
        }
753
 
 
754
 
        if (virBufferVSprintf(buf, "            <target dir='%s'/>\n",
755
 
                              mount->target) < 0) {
756
 
            goto no_memory;
757
 
        }
758
 
 
759
 
        if (virBufferAddLit(buf, "        </filesystem>\n") < 0) {
760
 
            goto no_memory;
761
 
        }
762
 
 
763
 
    }
764
 
 
765
 
    if (virBufferVSprintf(buf, "        <console tty='%s'/>\n", def->tty) < 0) {
766
 
        goto no_memory;
767
 
    }
768
 
 
769
 
    if (virBufferAddLit(buf, "    </devices>\n") < 0) {
770
 
        goto no_memory;
771
 
    }
772
 
 
773
 
    if (virBufferAddLit(buf, "</domain>\n") < 0) {
774
 
        goto no_memory;
775
 
    }
776
 
 
777
 
    return virBufferContentAndFree(buf);
778
 
 
779
 
no_memory:
780
 
    lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "generateXml");
781
 
    virBufferFree(buf);
782
 
 
783
 
    return NULL;
 
765
        virBufferAddLit(&buf, "        <filesystem type='mount'>\n");
 
766
        virBufferVSprintf(&buf, "            <source dir='%s'/>\n",
 
767
                          mount->source);
 
768
        virBufferVSprintf(&buf, "            <target dir='%s'/>\n",
 
769
                          mount->target);
 
770
        virBufferAddLit(&buf, "        </filesystem>\n");
 
771
    }
 
772
 
 
773
    virBufferVSprintf(&buf, "        <console tty='%s'/>\n", def->tty);
 
774
    virBufferAddLit(&buf, "    </devices>\n");
 
775
    virBufferAddLit(&buf, "</domain>\n");
 
776
 
 
777
    if (virBufferError(&buf)) {
 
778
        lxcError(conn, NULL, VIR_ERR_NO_MEMORY,_("allocate buffer"));
 
779
        return NULL;
 
780
    }
 
781
 
 
782
    return virBufferContentAndReset(&buf);
784
783
}
785
784
 
786
785
void lxcFreeVMDef(lxc_vm_def_t *vmdef)
794
793
    curMount = vmdef->mounts;
795
794
    while (curMount) {
796
795
        nextMount = curMount->next;
797
 
        free(curMount);
 
796
        VIR_FREE(curMount);
798
797
        curMount = nextMount;
799
798
    }
800
799
 
801
 
    free(vmdef->name);
802
 
    free(vmdef->init);
803
 
    free(vmdef->tty);
804
 
    free(vmdef);
 
800
    VIR_FREE(vmdef->name);
 
801
    VIR_FREE(vmdef->init);
 
802
    VIR_FREE(vmdef->tty);
 
803
    VIR_FREE(vmdef);
805
804
}
806
805
 
807
806
void lxcFreeVMs(lxc_vm_t *vms)
819
818
void lxcFreeVM(lxc_vm_t *vm)
820
819
{
821
820
    lxcFreeVMDef(vm->def);
822
 
    free(vm);
 
821
    VIR_FREE(vm->containerTty);
 
822
    VIR_FREE(vm);
823
823
}
824
824
 
825
825
lxc_vm_t *lxcFindVMByID(const lxc_driver_t *driver, int id)
884
884
    return 0;
885
885
}
886
886
 
 
887
/**
 
888
 * lxcStoreTtyPid:
 
889
 * @driver: pointer to driver
 
890
 * @vm: Ptr to VM
 
891
 *
 
892
 * Stores the pid of the tty forward process contained in vm->pid
 
893
 * LOCAL_STATE_DIR/run/libvirt/lxc/{container_name}.pid
 
894
 *
 
895
 * Returns 0 on success or -1 in case of error
 
896
 */
 
897
int lxcStoreTtyPid(const lxc_driver_t *driver, lxc_vm_t *vm)
 
898
{
 
899
    int rc = -1;
 
900
    int fd;
 
901
    FILE *file = NULL;
 
902
 
 
903
    if (vm->ttyPidFile[0] == 0x00) {
 
904
        if ((rc = virFileMakePath(driver->stateDir))) {
 
905
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
906
                     _("cannot create lxc state directory %s: %s"),
 
907
                     driver->stateDir, strerror(rc));
 
908
            goto error_out;
 
909
        }
 
910
 
 
911
        if (virFileBuildPath(driver->stateDir, vm->def->name, ".pid",
 
912
                             vm->ttyPidFile, PATH_MAX) < 0) {
 
913
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
914
                     _("cannot construct tty pid file path"));
 
915
            goto error_out;
 
916
        }
 
917
    }
 
918
 
 
919
    if ((fd = open(vm->ttyPidFile,
 
920
                   O_WRONLY | O_CREAT | O_TRUNC,
 
921
                   S_IRUSR | S_IWUSR)) < 0) {
 
922
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
923
                 _("cannot create tty pid file %s: %s"),
 
924
                 vm->ttyPidFile, strerror(errno));
 
925
        goto error_out;
 
926
    }
 
927
 
 
928
    if (!(file = fdopen(fd, "w"))) {
 
929
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
930
                 _("cannot fdopen tty pid file %s: %s"),
 
931
                 vm->ttyPidFile, strerror(errno));
 
932
 
 
933
        if (close(fd) < 0) {
 
934
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
935
                     _("failed to close tty pid file %s: %s"),
 
936
                     vm->ttyPidFile, strerror(errno));
 
937
        }
 
938
 
 
939
        goto error_out;
 
940
    }
 
941
 
 
942
    if (fprintf(file, "%d", vm->pid) < 0) {
 
943
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
944
                 _("cannot write tty pid file %s: %s"),
 
945
                 vm->ttyPidFile, strerror(errno));
 
946
 
 
947
        goto fclose_error_out;
 
948
    }
 
949
 
 
950
    rc = 0;
 
951
 
 
952
fclose_error_out:
 
953
    if (fclose(file) < 0) {
 
954
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
955
                 _("failed to close tty pid file %s: %s"),
 
956
                 vm->ttyPidFile, strerror(errno));
 
957
    }
 
958
 
 
959
error_out:
 
960
    return rc;
 
961
}
 
962
 
 
963
/**
 
964
 * lxcLoadTtyPid:
 
965
 * @driver: pointer to driver
 
966
 * @vm: Ptr to VM
 
967
 *
 
968
 * Loads the pid of the tty forward process from the pid file.
 
969
 * LOCAL_STATE_DIR/run/libvirt/lxc/{container_name}.pid
 
970
 *
 
971
 * Returns
 
972
 * > 0 - pid of tty process
 
973
 *   0 - no tty pid file
 
974
 *  -1 - error
 
975
 */
 
976
int lxcLoadTtyPid(const lxc_driver_t *driver, lxc_vm_t *vm)
 
977
{
 
978
    int rc = -1;
 
979
    FILE *file;
 
980
 
 
981
    if (vm->ttyPidFile[0] == 0x00) {
 
982
        if ((rc = virFileMakePath(driver->stateDir))) {
 
983
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
984
                     _("cannot create lxc state directory %s: %s"),
 
985
                     driver->stateDir, strerror(rc));
 
986
            goto cleanup;
 
987
        }
 
988
 
 
989
        if (virFileBuildPath(driver->stateDir, vm->def->name, ".pid",
 
990
                             vm->ttyPidFile, PATH_MAX) < 0) {
 
991
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
992
                     _("cannot construct tty pid file path"));
 
993
            goto cleanup;
 
994
        }
 
995
    }
 
996
 
 
997
    if (!(file = fopen(vm->ttyPidFile, "r"))) {
 
998
        if (ENOENT == errno) {
 
999
            rc = 0;
 
1000
            goto cleanup;
 
1001
        }
 
1002
 
 
1003
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1004
                 _("cannot open tty pid file %s: %s"),
 
1005
                 vm->ttyPidFile, strerror(errno));
 
1006
        goto cleanup;
 
1007
    }
 
1008
 
 
1009
    if (fscanf(file, "%d", &(vm->pid)) < 0) {
 
1010
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1011
                 _("cannot read tty pid file %s: %s"),
 
1012
                 vm->ttyPidFile, strerror(errno));
 
1013
        goto cleanup;
 
1014
    }
 
1015
 
 
1016
    if (fclose(file) < 0) {
 
1017
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1018
                 _("failed to close tty pid file %s: %s"),
 
1019
                 vm->ttyPidFile, strerror(errno));
 
1020
        goto cleanup;
 
1021
    }
 
1022
 
 
1023
    rc = vm->pid;
 
1024
 
 
1025
 cleanup:
 
1026
    return rc;
 
1027
}
 
1028
 
 
1029
/**
 
1030
 * lxcDeleteTtyPid:
 
1031
 * @vm: Ptr to VM
 
1032
 *
 
1033
 * Unlinks the tty pid file for the vm
 
1034
 * LOCAL_STATE_DIR/run/libvirt/lxc/{container_name}.pid
 
1035
 *
 
1036
 * Returns on 0 success or -1 in case of error
 
1037
 */
 
1038
int lxcDeleteTtyPidFile(const lxc_vm_t *vm)
 
1039
{
 
1040
    if (vm->ttyPidFile[0] == 0x00) {
 
1041
        goto no_file;
 
1042
    }
 
1043
 
 
1044
    if (unlink(vm->ttyPidFile) < 0) {
 
1045
        if (errno == ENOENT) {
 
1046
            goto no_file;
 
1047
        }
 
1048
 
 
1049
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1050
                 _("cannot remove ttyPidFile %s: %s"), vm->ttyPidFile,
 
1051
                 strerror(errno));
 
1052
        return -1;
 
1053
    }
 
1054
 
 
1055
no_file:
 
1056
    return 0;
 
1057
}
 
1058
 
887
1059
#endif /* WITH_LXC */
888
 
 
889
 
 
890
 
/*
891
 
 * Local variables:
892
 
 *  indent-tabs-mode: nil
893
 
 *  c-indent-level: 4
894
 
 *  c-basic-offset: 4
895
 
 *  tab-width: 4
896
 
 * End:
897
 
 */