~n-muench/ubuntu/precise/open-vm-tools/open-vm-tools.raring-precise.backport

« back to all changes in this revision

Viewing changes to modules/linux/vmci/common/vmciDatagram.c

  • Committer: Package Import Robot
  • Author(s): Nate Muench
  • Date: 2012-01-23 16:09:45 UTC
  • mfrom: (1.4.6) (2.4.26 sid)
  • Revision ID: package-import@ubuntu.com-20120123160945-b6s0r1vkcovucpf3
Tags: 2011.12.20-562307-0ubuntu1
* Merge latest upstream git tag. Fixes building on Precise
  (LP: #898289, LP: #905612)

* Items merged from Debian unstable:
  - debian/control:
    + open-vm-tools recommends open-vm-dkms. (LP: #598933)
    + open-vm-tools now suggests open-vm-toolbox. (LP: #604998)
  (From 2011.08.21-471295-1 release)
  - Updating maintainer and uploaders fields.
  - Removing vcs fields.
  - Removing references to Daniel's old email address.
  - Updating years in copyright file.
  - Updating to standards version 3.9.2.
  - Updating to debhelper version 8.
  - Switching to source format 3.0 (quilt).
  - Removing manual chrpath setting.
  - Removing exclusion from plugins from debhelper shlibs.
  - Rediffing kvers.patch.
  (From 2011.09.23-491607-1 release)
  - Marking binary architecture-dependend packages as linux and kfreebsd
  only.
  - Removing liburiparser-dev from build-depends as upstream dropped
  unity support.
  - Building with libproc-dev on amd64 again.
  - Dropping disabling of dnet support.
  (From 2011.09.23-491607-2 release)
  - Adding doxygen to build-depends for api documentation.
  - Adding libcunit1-dev to build-depends for test suites.
  - Minimizing rules file.
  - Adding open-vm-tools-dev package, containing only the api
    documentation for now.
  (From 2011.09.23-491607-3 release)
  - Sorting overrides in rules alphabetically.
  - Compacting copyright file.
  - Adding udev rule to set timeout for vmware scsi devices
  (From 2011.12.20-562307-1 release)
  - Adding patch to correct typo in upstreams dkms configuration

* Remaining Changes:
  - Remove Stable part of version numbering.
  - debian folder:
    + Re-added open-vm-dkms.postinst & open-vm-dkms.prerm.
      * Allows dkms modules to compile upon installation.
  - debian/control:
    + Re-add open-vm-source and make into a transitional package
      for open-vm-toolbox.
    + Return dependancies that were moved to open-vm-tools back to
      open-vm-toolbox.
  - debian/rules and debian/open-vm-toolbox.lintian-overrides:
    + Make vmware-user-suid-wrapper suid-root
  - debian/rules:
    + Added CFLAGS field with -Wno-deprecated-declarations
      * Will suppress issues with glib 2.31 or later.
    + Add line to copy vmware-xdg-detect-de into place.
    + Install vmware-user.desktop through toolbox package.
  - debian/open-vm-tools.init:
    + Re-add 'modprobe [-r] vmblock'.
    + Add 'modprobe [-r] vmxnet'.
      * Incase it's not loaded during boot.
    + Remove and re-add pcnet32 module
      * Will be done before (remove) and after (readd) vmxnet module
        is added.
      * If vmxnet doesn't exist (aka modules fail to build), pcnet32 can be
        still used for network connectivity.
      * Workaround until a better fix can be done.
  - Re-add gnome-session to debian/local/xautostart.conf
  - Manpages removed (from debian/manpages):
    + vmmemctl.9
    + vmxnet3.9
    + Remove references to manpages that have been removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*********************************************************
2
 
 * Copyright (C) 2006 VMware, Inc. All rights reserved.
 
2
 * Copyright (C) 2006-2011 VMware, Inc. All rights reserved.
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify it
5
5
 * under the terms of the GNU General Public License as published by the
58
58
   VMCIPrivilegeFlags  privFlags;
59
59
} DatagramEntry;
60
60
 
61
 
/* Mapping between wellknown resource and context. */
62
 
typedef struct DatagramWKMapping {
63
 
   VMCIHashEntry entry;
64
 
   VMCIId        contextID;
65
 
} DatagramWKMapping;
66
 
 
67
61
typedef struct VMCIDelayedDatagramInfo {
68
62
   Bool inDGHostQueue;
69
63
   DatagramEntry *entry;
71
65
} VMCIDelayedDatagramInfo;
72
66
 
73
67
 
74
 
/* Wellknown mapping hashtable. */
75
 
static VMCIHashTable *wellKnownTable = NULL;
76
 
 
77
68
static Atomic_uint32 delayedDGHostQueueSize;
78
69
 
79
70
static int VMCIDatagramGetPrivFlagsInt(VMCIId contextID, VMCIHandle handle,
81
72
static void DatagramFreeCB(void *resource);
82
73
static int DatagramReleaseCB(void *clientData);
83
74
 
84
 
static DatagramWKMapping *DatagramGetWellKnownMap(VMCIId wellKnownID);
85
 
static void DatagramReleaseWellKnownMap(DatagramWKMapping *wkMap);
86
 
 
87
75
 
88
76
/*------------------------------ Helper functions ----------------------------*/
89
77
 
254
242
int
255
243
VMCIDatagram_Init(void)
256
244
{
257
 
   /* Create hash table for wellknown mappings. */
258
 
   wellKnownTable = VMCIHashTable_Create(32);
259
 
   if (wellKnownTable == NULL) {
260
 
      return VMCI_ERROR_NO_RESOURCES;
261
 
   }
262
 
 
263
245
   Atomic_Write(&delayedDGHostQueueSize, 0);
264
246
   return VMCI_SUCCESS;
265
247
}
284
266
void
285
267
VMCIDatagram_Exit(void)
286
268
{
287
 
   if (wellKnownTable != NULL) {
288
 
      VMCIHashTable_Destroy(wellKnownTable);
289
 
      wellKnownTable = NULL;
290
 
   }
291
269
}
292
270
 
293
271
 
416
394
    */
417
395
   VMCI_WaitOnEvent(&entry->destroyEvent, DatagramReleaseCB, entry);
418
396
 
419
 
   if ((entry->flags & VMCI_FLAG_WELLKNOWN_DG_HND) != 0) {
420
 
      VMCIDatagramRemoveWellKnownMap(handle.resource, VMCI_HOST_CONTEXT_ID);
421
 
   }
422
 
 
423
397
   /*
424
398
    * We know that we are now the only reference to the above entry so
425
399
     * can safely free it.
570
544
{
571
545
   int retval;
572
546
   size_t dgSize;
573
 
   VMCIId dstContext;
574
547
   VMCIPrivilegeFlags srcPrivFlags;
575
 
   char srcDomain[VMCI_DOMAIN_NAME_MAXLEN]; /* Not used on hosted. */
576
 
   char dstDomain[VMCI_DOMAIN_NAME_MAXLEN]; /* Not used on hosted. */
577
548
 
578
549
   ASSERT(dg);
579
550
   ASSERT(VMCI_HostPersonalityActive());
597
568
    * Check that source handle matches sending context.
598
569
    */
599
570
   if (dg->src.context != contextID) {
600
 
      if (dg->src.context == VMCI_WELL_KNOWN_CONTEXT_ID) {
601
 
         /* Determine mapping. */
602
 
         DatagramWKMapping *wkMap = DatagramGetWellKnownMap(dg->src.resource);
603
 
         if (wkMap == NULL) {
604
 
            VMCI_DEBUG_LOG(4, (LGPFX"Sending from invalid well-known resource "
605
 
                               "(handle=0x%x:0x%x).\n",
606
 
                               dg->src.context, dg->src.resource));
607
 
            return VMCI_ERROR_INVALID_RESOURCE;
608
 
         }
609
 
         if (wkMap->contextID != contextID) {
610
 
            VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of "
611
 
                               "well-known src datagram entry "
612
 
                               "(handle=0x%x:0x%x).\n",
613
 
                               contextID, dg->src.context, dg->src.resource));
614
 
            DatagramReleaseWellKnownMap(wkMap);
615
 
            return VMCI_ERROR_NO_ACCESS;
616
 
         }
617
 
         DatagramReleaseWellKnownMap(wkMap);
618
 
      } else {
619
 
         VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of src "
620
 
                            "datagram entry (handle=0x%x:0x%x).\n",
621
 
                            contextID, dg->src.context, dg->src.resource));
622
 
         return VMCI_ERROR_NO_ACCESS;
623
 
      }
624
 
   }
625
 
 
626
 
   if (dg->dst.context == VMCI_WELL_KNOWN_CONTEXT_ID) {
627
 
      /* Determine mapping. */
628
 
      DatagramWKMapping *wkMap = DatagramGetWellKnownMap(dg->dst.resource);
629
 
      if (wkMap == NULL) {
630
 
         VMCI_DEBUG_LOG(4, (LGPFX"Sending to invalid wellknown destination "
631
 
                            "(handle=0x%x:0x%x).\n",
632
 
                            dg->dst.context, dg->dst.resource));
633
 
         return VMCI_ERROR_DST_UNREACHABLE;
634
 
      }
635
 
      dstContext = wkMap->contextID;
636
 
      DatagramReleaseWellKnownMap(wkMap);
637
 
   } else {
638
 
      dstContext = dg->dst.context;
 
571
      VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of src "
 
572
                         "datagram entry (handle=0x%x:0x%x).\n",
 
573
                         contextID, dg->src.context, dg->src.resource));
 
574
      return VMCI_ERROR_NO_ACCESS;
639
575
   }
640
576
 
641
577
   /*
649
585
      return retval;
650
586
   }
651
587
 
652
 
#ifdef VMKERNEL
653
 
   /*
654
 
    * In the vmkernel, all communicating contexts except the
655
 
    * hypervisor context must belong to the same domain. If the
656
 
    * hypervisor is the source, the domain doesn't matter.
657
 
    */
658
 
 
659
 
   if (contextID != VMCI_HYPERVISOR_CONTEXT_ID) {
660
 
      retval = VMCIContext_GetDomainName(contextID, srcDomain,
661
 
                                         sizeof srcDomain);
662
 
      if (retval < VMCI_SUCCESS) {
663
 
         VMCI_WARNING((LGPFX"Failed to get domain name for context (ID=0x%x).\n",
664
 
                       contextID));
665
 
         return retval;
666
 
      }
667
 
   }
668
 
#endif
669
 
 
670
588
   /* Determine if we should route to host or guest destination. */
671
 
   if (dstContext == VMCI_HOST_CONTEXT_ID) {
 
589
   if (dg->dst.context == VMCI_HOST_CONTEXT_ID) {
672
590
      /* Route to host datagram entry. */
673
591
      DatagramEntry *dstEntry;
674
592
      VMCIResource *resource;
686
604
         return VMCI_ERROR_INVALID_RESOURCE;
687
605
      }
688
606
      dstEntry = RESOURCE_CONTAINER(resource, DatagramEntry, resource);
689
 
#ifdef VMKERNEL
690
 
      retval = VMCIContext_GetDomainName(VMCI_HOST_CONTEXT_ID, dstDomain,
691
 
                                         sizeof dstDomain);
692
 
      if (retval < VMCI_SUCCESS) {
693
 
         VMCI_WARNING((LGPFX"Failed to get domain name for context (ID=0x%x).\n",
694
 
                       VMCI_HOST_CONTEXT_ID));
695
 
         VMCIResource_Release(resource);
696
 
         return retval;
697
 
      }
698
 
#endif
699
 
      if (VMCIDenyInteraction(srcPrivFlags, dstEntry->privFlags, srcDomain,
700
 
                              dstDomain)) {
 
607
      if (VMCIDenyInteraction(srcPrivFlags, dstEntry->privFlags)) {
701
608
         VMCIResource_Release(resource);
702
609
         return VMCI_ERROR_NO_ACCESS;
703
610
      }
751
658
         }
752
659
      }
753
660
   } else {
754
 
      /* Route to destination VM context. */
 
661
      /*
 
662
       * Route to destination VM context.
 
663
       */
 
664
 
755
665
      VMCIDatagram *newDG;
756
666
 
757
 
#ifdef VMKERNEL
758
 
      retval = VMCIContext_GetDomainName(dstContext, dstDomain,
759
 
                                         sizeof dstDomain);
760
 
      if (retval < VMCI_SUCCESS) {
761
 
         VMCI_DEBUG_LOG(4, (LGPFX"Failed to get domain name for context "
762
 
                            "(ID=0x%x).\n", dstContext));
763
 
         return retval;
764
 
      }
765
 
#endif
766
 
      if (contextID != dstContext &&
767
 
         VMCIDenyInteraction(srcPrivFlags, VMCIContext_GetPrivFlags(dstContext),
768
 
                             srcDomain, dstDomain)) {
769
 
         return VMCI_ERROR_NO_ACCESS;
 
667
      if (contextID != dg->dst.context) {
 
668
         if (VMCIDenyInteraction(srcPrivFlags,
 
669
                                 VMCIContext_GetPrivFlags(dg->dst.context))) {
 
670
            return VMCI_ERROR_NO_ACCESS;
 
671
         } else if (VMCI_CONTEXT_IS_VM(contextID)) {
 
672
            /*
 
673
             * If the sending context is a VM, it cannot reach another VM.
 
674
             */
 
675
 
 
676
            VMCI_DEBUG_LOG(4, (LGPFX"Datagram communication between VMs not"
 
677
                               "supported (src=0x%x, dst=0x%x).\n",
 
678
                               contextID, dg->dst.context));
 
679
            return VMCI_ERROR_DST_UNREACHABLE;
 
680
         }
770
681
      }
771
682
 
772
683
      /* We make a copy to enqueue. */
775
686
         return VMCI_ERROR_NO_MEM;
776
687
      }
777
688
      memcpy(newDG, dg, dgSize);
778
 
      retval = VMCIContext_EnqueueDatagram(dstContext, newDG);
 
689
      retval = VMCIContext_EnqueueDatagram(dg->dst.context, newDG);
779
690
      if (retval < VMCI_SUCCESS) {
780
691
         VMCI_FreeKernelMem(newDG, dgSize);
781
692
         return retval;
873
784
 
874
785
   retval = VMCI_Route(&dg->src, &dg->dst, fromGuest, &route);
875
786
   if (retval < VMCI_SUCCESS) {
 
787
      VMCI_DEBUG_LOG(4, (LGPFX"Failed to route datagram (src=0x%x, dst=0x%x, "
 
788
                         "err=%d)\n.", dg->src.context, dg->dst.context,
 
789
                         retval));
876
790
      return retval;
877
791
   }
878
792
 
996
910
 
997
911
 
998
912
/*
999
 
 *------------------------------------------------------------------------------
1000
 
 *
1001
 
 * DatagramGetWellKnownMap --
1002
 
 *
1003
 
 *      Gets a mapping between handle and wellknown resource.
1004
 
 *
1005
 
 * Results:
1006
 
 *      DatagramWKMapping * if found, NULL if not.
1007
 
 *
1008
 
 * Side effects:
1009
 
 *      None.
1010
 
 *
1011
 
 *------------------------------------------------------------------------------
1012
 
 */
1013
 
 
1014
 
static DatagramWKMapping *
1015
 
DatagramGetWellKnownMap(VMCIId wellKnownID)  // IN:
1016
 
{
1017
 
   VMCIHashEntry *entry;
1018
 
   DatagramWKMapping *wkMap = NULL;
1019
 
   VMCIHandle wkHandle = VMCI_MAKE_HANDLE(VMCI_WELL_KNOWN_CONTEXT_ID,
1020
 
                                          wellKnownID);
1021
 
   entry = VMCIHashTable_GetEntry(wellKnownTable, wkHandle);
1022
 
   if (entry != NULL) {
1023
 
      wkMap = RESOURCE_CONTAINER(entry, DatagramWKMapping, entry);
1024
 
   }
1025
 
   return wkMap;
1026
 
}
1027
 
 
1028
 
 
1029
 
/*
1030
 
 *------------------------------------------------------------------------------
1031
 
 *
1032
 
 * DatagramReleaseWellKnownMap --
1033
 
 *
1034
 
 *      Releases a wellknown mapping.
1035
 
 *
1036
 
 * Results:
1037
 
 *      None.
1038
 
 *
1039
 
 * Side effects:
1040
 
 *      None.
1041
 
 *
1042
 
 *------------------------------------------------------------------------------
1043
 
 */
1044
 
 
1045
 
static void
1046
 
DatagramReleaseWellKnownMap(DatagramWKMapping *wkMap)  // IN:
1047
 
{
1048
 
   if (VMCIHashTable_ReleaseEntry(wellKnownTable, &wkMap->entry) ==
1049
 
       VMCI_SUCCESS_ENTRY_DEAD) {
1050
 
      VMCI_FreeKernelMem(wkMap, sizeof *wkMap);
1051
 
   }
1052
 
}
1053
 
 
1054
 
 
1055
 
/*
1056
 
 *------------------------------------------------------------------------------
1057
 
 *
1058
 
 * VMCIDatagramRequestWellKnownMap --
1059
 
 *
1060
 
 *      Creates a mapping between handle and wellknown resource. If resource
1061
 
 *      is already used we fail the request.
1062
 
 *
1063
 
 * Results:
1064
 
 *      VMCI_SUCCESS if created, negative errno value otherwise.
1065
 
 *
1066
 
 * Side effects:
1067
 
 *      None.
1068
 
 *
1069
 
 *------------------------------------------------------------------------------
1070
 
 */
1071
 
 
1072
 
int
1073
 
VMCIDatagramRequestWellKnownMap(VMCIId wellKnownID,           // IN:
1074
 
                                VMCIId contextID,             // IN:
1075
 
                                VMCIPrivilegeFlags privFlags) // IN:
1076
 
{
1077
 
   int result;
1078
 
   DatagramWKMapping *wkMap;
1079
 
   VMCIHandle wkHandle = VMCI_MAKE_HANDLE(VMCI_WELL_KNOWN_CONTEXT_ID,
1080
 
                                          wellKnownID);
1081
 
 
1082
 
   if (privFlags & VMCI_PRIVILEGE_FLAG_RESTRICTED ||
1083
 
       !VMCIWellKnownID_AllowMap(wellKnownID, privFlags)) {
1084
 
      return VMCI_ERROR_NO_ACCESS;
1085
 
   }
1086
 
 
1087
 
   wkMap = VMCI_AllocKernelMem(sizeof *wkMap, VMCI_MEMORY_NONPAGED);
1088
 
   if (wkMap == NULL) {
1089
 
      return VMCI_ERROR_NO_MEM;
1090
 
   }
1091
 
 
1092
 
   VMCIHashTable_InitEntry(&wkMap->entry, wkHandle);
1093
 
   wkMap->contextID = contextID;
1094
 
 
1095
 
   /* Fails if wkHandle (wellKnownID) already exists. */
1096
 
   result = VMCIHashTable_AddEntry(wellKnownTable, &wkMap->entry);
1097
 
   if (result != VMCI_SUCCESS) {
1098
 
      VMCI_FreeKernelMem(wkMap, sizeof *wkMap);
1099
 
      return result;
1100
 
   }
1101
 
   result = VMCIContext_AddWellKnown(contextID, wellKnownID);
1102
 
   if (UNLIKELY(result < VMCI_SUCCESS)) {
1103
 
      VMCIHashTable_RemoveEntry(wellKnownTable, &wkMap->entry);
1104
 
      VMCI_FreeKernelMem(wkMap, sizeof *wkMap);
1105
 
   }
1106
 
   return result;
1107
 
}
1108
 
 
1109
 
 
1110
 
/*
1111
 
 *------------------------------------------------------------------------------
1112
 
 *
1113
 
 * VMCIDatagramRemoveWellKnownMap --
1114
 
 *
1115
 
 *      Removes a mapping between handle and wellknown resource. Checks if
1116
 
 *      mapping belongs to calling context.
1117
 
 *
1118
 
 * Results:
1119
 
 *      VMCI_SUCCESS if removed, negative errno value otherwise.
1120
 
 *
1121
 
 * Side effects:
1122
 
 *      None.
1123
 
 *
1124
 
 *------------------------------------------------------------------------------
1125
 
 */
1126
 
 
1127
 
int
1128
 
VMCIDatagramRemoveWellKnownMap(VMCIId wellKnownID,  // IN:
1129
 
                               VMCIId contextID)    // IN:
1130
 
{
1131
 
   int result = VMCI_ERROR_NO_ACCESS;
1132
 
   DatagramWKMapping *wkMap = DatagramGetWellKnownMap(wellKnownID);
1133
 
   if (wkMap == NULL) {
1134
 
      VMCI_DEBUG_LOG(4, (LGPFX"Failed to remove well-known mapping between "
1135
 
                         "resource (ID=0x%x) and context (ID=0x%x).\n",
1136
 
                         wellKnownID, contextID));
1137
 
      return VMCI_ERROR_NOT_FOUND;
1138
 
   }
1139
 
 
1140
 
   if (contextID == wkMap->contextID) {
1141
 
      VMCIHashTable_RemoveEntry(wellKnownTable, &wkMap->entry);
1142
 
      VMCIContext_RemoveWellKnown(contextID, wellKnownID);
1143
 
      result = VMCI_SUCCESS;
1144
 
   }
1145
 
   DatagramReleaseWellKnownMap(wkMap);
1146
 
   return result;
1147
 
}
1148
 
 
1149
 
 
1150
 
/*
1151
913
 *-----------------------------------------------------------------------------
1152
914
 *
1153
915
 * VMCIDatagram_Sync --